From 15e9f4a38366e3139c3f3f548c4b8527be63d0e7 Mon Sep 17 00:00:00 2001 From: Chris Taylor Date: Sun, 2 Oct 2016 14:32:30 +0800 Subject: [PATCH 1/3] Allow dcx::window struct to be subclassed - step 1 Allow dcx::window struct to be subclassed step 1. This step moves the definition for the window struct into window.h, keeping all member variables private and declaring the window related functions as 'friends'. This avoids changes to source files that use the window struct at this stage. Also moving some of the simpler functions in window.cpp into the struct definition to inline them. I would prefer to use class methods, so changing some of these to class methods as well. --- common/arch/sdl/window.cpp | 51 +------------------- common/include/fwd-window.h | 2 - common/include/window.h | 94 ++++++++++++++++++++++++++++++++----- 3 files changed, 82 insertions(+), 65 deletions(-) diff --git a/common/arch/sdl/window.cpp b/common/arch/sdl/window.cpp index cb54fe1aa..7670bb70b 100644 --- a/common/arch/sdl/window.cpp +++ b/common/arch/sdl/window.cpp @@ -22,17 +22,6 @@ namespace dcx { -struct window -{ - grs_canvas w_canv; // the window's canvas to draw to - window_event_result (*w_callback)(window *wind,const d_event &event, void *data); // the event handler - int w_visible; // whether it's visible - int w_modal; // modal = accept all user input exclusively - void *data; // whatever the user wants (eg menu data for 'newmenu' menus) - struct window *prev; // the previous window in the doubly linked list - struct window *next; // the next window in the doubly linked list -}; - static window *FrontWindow = NULL; static window *FirstWindow = NULL; @@ -127,16 +116,6 @@ window *window_get_first(void) return FirstWindow; } -window *window_get_next(window &wind) -{ - return wind.next; -} - -window *window_get_prev(window &wind) -{ - return wind.prev; -} - // Make wind the front window void window_select(window &wind) { @@ -156,7 +135,7 @@ void window_select(window &wind) wind.next = nullptr; FrontWindow = &wind; - if (window_is_visible(wind)) + if (wind.is_visible()) { if (prev) WINDOW_SEND_EVENT(prev, EVENT_WINDOW_DEACTIVATED); @@ -181,16 +160,6 @@ window *window_set_visible(window &w, int visible) return wind; } -int window_is_visible(window &wind) -{ - return wind.w_visible; -} - -grs_canvas &window_get_canvas(window &wind) -{ - return wind.w_canv; -} - #if !DXX_USE_OGL void window_update_canvases() { @@ -206,22 +175,4 @@ void window_update_canvases() } #endif -window_event_result window_send_event(window &wind, const d_event &event) -{ - auto r = wind.w_callback(&wind, event, wind.data); - if (r == window_event_result::close) - window_close(&wind); - return r; -} - -void window_set_modal(window &wind, int modal) -{ - wind.w_modal = modal; -} - -int window_is_modal(window &wind) -{ - return wind.w_modal; -} - } diff --git a/common/include/fwd-window.h b/common/include/fwd-window.h index 8ad761f9d..9bbebc02e 100644 --- a/common/include/fwd-window.h +++ b/common/include/fwd-window.h @@ -40,13 +40,11 @@ window *window_get_next(window &wind); window *window_get_prev(window &wind); void window_select(window &wind); window *window_set_visible(window &wind, int visible); -int window_is_visible(window &wind); grs_canvas &window_get_canvas(window &wind); #if !DXX_USE_OGL void window_update_canvases(); #endif window_event_result window_send_event(window &wind,const d_event &event); -void window_set_modal(window &wind, int modal); int window_is_modal(window &wind); #define WINDOW_SEND_EVENT(w, e) (event.type = e, (WINDOW_SEND_EVENT)(*w, event, __FILE__, __LINE__, #e)) diff --git a/common/include/window.h b/common/include/window.h index 002e45340..11807f440 100644 --- a/common/include/window.h +++ b/common/include/window.h @@ -50,6 +50,87 @@ static inline void set_embedded_window_pointer(embed_window_pointer_t *wp, windo static inline void set_embedded_window_pointer(ignore_window_pointer_t *, window *) {} +struct window +{ +private: + grs_canvas w_canv; // the window's canvas to draw to + window_subfunction w_callback; // the event handler + int w_visible; // whether it's visible + int w_modal; // modal = accept all user input exclusively + void *data; // whatever the user wants (eg menu data for 'newmenu' menus) + struct window *prev; // the previous window in the doubly linked list + struct window *next; // the next window in the doubly linked list + +public: + // Declaring as friends to keep function syntax, for historical reasons (for now at least) + // Intended to transition to the class method form + friend window *window_create(grs_canvas *src, int x, int y, int w, int h, window_subfunction event_callback, void *userdata, const void *createdata); + + friend int window_close(window *wind); + friend int window_exists(window *wind); + friend window *window_get_front(); + friend window *window_get_first(); + friend void window_select(window &wind); + friend window *window_set_visible(window &wind, int visible); +#if !DXX_USE_OGL + friend void window_update_canvases(); +#endif + + friend grs_canvas &window_get_canvas(window &wind) + { + return wind.w_canv; + } + + friend window *window_set_visible(window *wind, int visible) + { + return window_set_visible(*wind, visible); + } + + int is_visible() + { + return w_visible; + } + + friend int window_is_visible(window *wind) + { + return wind->is_visible(); + } + + void set_modal(int modal) + { + w_modal = modal; + } + + friend void window_set_modal(window *wind, int modal) + { + wind->set_modal(modal); + } + + friend int window_is_modal(window &wind) + { + return wind.w_modal; + } + + friend window_event_result window_send_event(window &wind, const d_event &event) + { + auto r = wind.w_callback(&wind, event, wind.data); + if (r == window_event_result::close) + window_close(&wind); + return r; + } + + friend window *window_get_next(window &wind) + { + return wind.next; + } + + friend window *window_get_prev(window &wind) + { + return wind.prev; + } + +}; + template static inline window *window_create(grs_canvas *src, int x, int y, int w, int h, window_subfunction event_callback, T1 *data, T2 *createdata = nullptr) { @@ -64,19 +145,6 @@ static inline window *window_create(grs_canvas *src, int x, int y, int w, int h, return window_create(src, x, y, w, h, reinterpret_cast>(event_callback), static_cast(const_cast(userdata)), static_cast(createdata)); } -static inline window *window_set_visible(window *wind, int visible) -{ - return window_set_visible(*wind, visible); -} -static inline int window_is_visible(window *wind) -{ - return window_is_visible(*wind); -} -static inline void window_set_modal(window *wind, int modal) -{ - window_set_modal(*wind, modal); -} - static inline window_event_result (WINDOW_SEND_EVENT)(window &w, const d_event &event, const char *file, unsigned line, const char *e) { auto &c = window_get_canvas(w); From f117df9eeedd8b42d02b8224f1ce45e5e996452f Mon Sep 17 00:00:00 2001 From: Chris Taylor Date: Sun, 2 Oct 2016 14:49:22 +0800 Subject: [PATCH 2/3] Allow dcx::window struct to be subclassed - step 2 Allow dcx::window struct to be subclassed step 2. This step renames and reconfigures window_create in window.cpp to be the main constructor. Also add a template constructor that allows an event handler that takes a subclass of window. --- common/arch/sdl/window.cpp | 14 ++++++-------- common/include/fwd-window.h | 5 +++-- common/include/window.h | 16 ++++++++++++---- 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/common/arch/sdl/window.cpp b/common/arch/sdl/window.cpp index 7670bb70b..de904cef6 100644 --- a/common/arch/sdl/window.cpp +++ b/common/arch/sdl/window.cpp @@ -25,18 +25,18 @@ namespace dcx { static window *FrontWindow = NULL; static window *FirstWindow = NULL; -window *window_create(grs_canvas *src, int x, int y, int w, int h, window_subfunction event_callback, void *data, const void *createdata) +window::window(grs_canvas *src, int x, int y, int w, int h, window_subfunction event_callback, void *data, const void *createdata) { - window *prev = window_get_front(); + window *prev_front = window_get_front(); d_create_event event; - window *wind = new window; + window *wind = this; Assert(src != NULL); Assert(event_callback != NULL); gr_init_sub_canvas(wind->w_canv, *src, x, y, w, h); wind->w_callback = event_callback; wind->w_visible = 1; // default to visible wind->w_modal = 1; // default to modal - wind->data = data; + wind->w_data = data; if (FirstWindow == NULL) FirstWindow = wind; @@ -45,14 +45,12 @@ window *window_create(grs_canvas *src, int x, int y, int w, int h, window_subfun FrontWindow->next = wind; wind->next = NULL; FrontWindow = wind; - if (prev) - WINDOW_SEND_EVENT(prev, EVENT_WINDOW_DEACTIVATED); + if (prev_front) + WINDOW_SEND_EVENT(prev_front, EVENT_WINDOW_DEACTIVATED); event.createdata = createdata; WINDOW_SEND_EVENT(wind, EVENT_WINDOW_CREATED); WINDOW_SEND_EVENT(wind, EVENT_WINDOW_ACTIVATED); - - return wind; } int window_close(window *wind) diff --git a/common/include/fwd-window.h b/common/include/fwd-window.h index 9bbebc02e..ffdf870ad 100644 --- a/common/include/fwd-window.h +++ b/common/include/fwd-window.h @@ -24,14 +24,15 @@ enum class window_event_result : uint8_t; template using window_subfunction = window_event_result (*)(window *menu,const d_event &event, T *userdata); +template +using window_subclass_subfunction = window_event_result (*)(T *menu,const d_event &event, void*); + class unused_window_userdata_t; /* No declaration for embed_window_pointer_t or ignore_window_pointer_t * since every user needs the full definition. */ -window *window_create(grs_canvas *src, int x, int y, int w, int h, window_subfunction event_callback, void *userdata, const void *createdata); - int window_close(window *wind); int window_exists(window *wind); window *window_get_front(); diff --git a/common/include/window.h b/common/include/window.h index 11807f440..61c84dda3 100644 --- a/common/include/window.h +++ b/common/include/window.h @@ -57,11 +57,19 @@ private: window_subfunction w_callback; // the event handler int w_visible; // whether it's visible int w_modal; // modal = accept all user input exclusively - void *data; // whatever the user wants (eg menu data for 'newmenu' menus) + void *w_data; // whatever the user wants (eg menu data for 'newmenu' menus) struct window *prev; // the previous window in the doubly linked list struct window *next; // the next window in the doubly linked list public: + // For creating the window, there are two ways - using the (older) window_create function + // or using the constructor, passing an event handler that takes a subclass of window. + explicit window(grs_canvas *src, int x, int y, int w, int h, window_subfunction event_callback, void *data, const void *createdata); + + template + window(grs_canvas *src, int x, int y, int w, int h, window_subclass_subfunction event_callback) : + window(src, x, y, w, h, reinterpret_cast>(event_callback), nullptr, nullptr) {} + // Declaring as friends to keep function syntax, for historical reasons (for now at least) // Intended to transition to the class method form friend window *window_create(grs_canvas *src, int x, int y, int w, int h, window_subfunction event_callback, void *userdata, const void *createdata); @@ -113,7 +121,7 @@ public: friend window_event_result window_send_event(window &wind, const d_event &event) { - auto r = wind.w_callback(&wind, event, wind.data); + auto r = wind.w_callback(&wind, event, wind.w_data); if (r == window_event_result::close) window_close(&wind); return r; @@ -134,7 +142,7 @@ public: template static inline window *window_create(grs_canvas *src, int x, int y, int w, int h, window_subfunction event_callback, T1 *data, T2 *createdata = nullptr) { - auto win = window_create(src, x, y, w, h, reinterpret_cast>(event_callback), static_cast(data), static_cast(createdata)); + auto win = new window(src, x, y, w, h, reinterpret_cast>(event_callback), static_cast(data), static_cast(createdata)); set_embedded_window_pointer(data, win); return win; } @@ -142,7 +150,7 @@ static inline window *window_create(grs_canvas *src, int x, int y, int w, int h, template static inline window *window_create(grs_canvas *src, int x, int y, int w, int h, window_subfunction event_callback, const T1 *userdata, T2 *createdata = nullptr) { - return window_create(src, x, y, w, h, reinterpret_cast>(event_callback), static_cast(const_cast(userdata)), static_cast(createdata)); + return new window(src, x, y, w, h, reinterpret_cast>(event_callback), static_cast(const_cast(userdata)), static_cast(createdata)); } static inline window_event_result (WINDOW_SEND_EVENT)(window &w, const d_event &event, const char *file, unsigned line, const char *e) From 87617e8ac9ca663de6428698f1ace927f072bf6d Mon Sep 17 00:00:00 2001 From: Chris Taylor Date: Sun, 2 Oct 2016 17:49:19 +0800 Subject: [PATCH 3/3] Allow dcx::window struct to be subclassed - step 3 Allow dcx::window struct to be subclassed step 3. This step adds the window destructor and both requires and implements the window to be deleted by the event handler/client in all cases. --- common/arch/sdl/window.cpp | 25 ++++++++++++++----------- common/include/window.h | 6 ++++-- common/ui/dialog.cpp | 1 + common/ui/menubar.cpp | 10 ++++++---- d2x-rebirth/main/escort.cpp | 1 + d2x-rebirth/main/movie.cpp | 9 +++++++-- similar/editor/info.cpp | 1 + similar/main/automap.cpp | 1 + similar/main/console.cpp | 1 + similar/main/credits.cpp | 4 +++- similar/main/game.cpp | 1 + similar/main/gamecntl.cpp | 3 ++- similar/main/kconfig.cpp | 1 + similar/main/kmatrix.cpp | 3 ++- similar/main/menu.cpp | 8 ++++++-- similar/main/newmenu.cpp | 2 ++ similar/main/scores.cpp | 1 + similar/main/titles.cpp | 6 ++++-- 18 files changed, 58 insertions(+), 26 deletions(-) diff --git a/common/arch/sdl/window.cpp b/common/arch/sdl/window.cpp index de904cef6..34ecca813 100644 --- a/common/arch/sdl/window.cpp +++ b/common/arch/sdl/window.cpp @@ -53,6 +53,18 @@ window::window(grs_canvas *src, int x, int y, int w, int h, window_subfunctionprev; + if (this == FirstWindow) + FirstWindow = this->next; + if (this->next) + this->next->prev = this->prev; + if (this->prev) + this->prev->next = this->next; +} + int window_close(window *wind) { window *prev; @@ -72,21 +84,12 @@ int window_close(window *wind) return 0; } - if (wind == FrontWindow) - FrontWindow = wind->prev; - if (wind == FirstWindow) - FirstWindow = wind->next; - if (wind->next) - wind->next->prev = wind->prev; - if (wind->prev) - wind->prev->next = wind->next; - if ((prev = window_get_front())) WINDOW_SEND_EVENT(prev, EVENT_WINDOW_ACTIVATED); event.type = EVENT_WINDOW_CLOSED; - w_callback(wind, event, NULL); // callback needs to recognise this is a NULL pointer! - delete wind; + w_callback(nullptr, event, nullptr); // callback needs to recognise nullptr is being passed! + return 1; } diff --git a/common/include/window.h b/common/include/window.h index 61c84dda3..1a795cc93 100644 --- a/common/include/window.h +++ b/common/include/window.h @@ -57,7 +57,7 @@ private: window_subfunction w_callback; // the event handler int w_visible; // whether it's visible int w_modal; // modal = accept all user input exclusively - void *w_data; // whatever the user wants (eg menu data for 'newmenu' menus) + void *w_data; // whatever the user wants (eg menu data for 'newmenu' menus) struct window *prev; // the previous window in the doubly linked list struct window *next; // the next window in the doubly linked list @@ -69,7 +69,9 @@ public: template window(grs_canvas *src, int x, int y, int w, int h, window_subclass_subfunction event_callback) : window(src, x, y, w, h, reinterpret_cast>(event_callback), nullptr, nullptr) {} - + + ~window(); + // Declaring as friends to keep function syntax, for historical reasons (for now at least) // Intended to transition to the class method form friend window *window_create(grs_canvas *src, int x, int y, int w, int h, window_subfunction event_callback, void *userdata, const void *createdata); diff --git a/common/ui/dialog.cpp b/common/ui/dialog.cpp index bb92f4119..e92809c15 100644 --- a/common/ui/dialog.cpp +++ b/common/ui/dialog.cpp @@ -137,6 +137,7 @@ static window_event_result ui_dialog_handler(window *wind,const d_event &event, ui_gadget_delete_all(dlg); selected_gadget = NULL; delete dlg; + delete wind; return window_event_result::ignored; default: return window_event_result::ignored; diff --git a/common/ui/menubar.cpp b/common/ui/menubar.cpp index 2bab7964e..f18b75f12 100644 --- a/common/ui/menubar.cpp +++ b/common/ui/menubar.cpp @@ -510,7 +510,7 @@ static window_event_result do_state_2(const d_event &event) -static window_event_result menu_handler(window *, const d_event &event, MENU *menu) +static window_event_result menu_handler(window *wind, const d_event &event, MENU *menu) { int i; int keypress = 0; @@ -524,7 +524,8 @@ static window_event_result menu_handler(window *, const d_event &event, MENU *me { state = 0; menu_hide_all(); - menu->wind = NULL; + delete wind; + menu->wind = nullptr; return window_event_result::ignored; } window_event_result rval = window_event_result::ignored; @@ -664,7 +665,7 @@ static window_event_result menu_handler(window *, const d_event &event, MENU *me return rval; } -static window_event_result menubar_handler(window *, const d_event &event, MENU *) +static window_event_result menubar_handler(window *wind, const d_event &event, MENU *) { if (event.type == EVENT_WINDOW_DRAW) { @@ -684,7 +685,8 @@ static window_event_result menubar_handler(window *, const d_event &event, MENU } } - Menu[0].wind = NULL; + delete wind; + Menu[0].wind = nullptr; } switch (state) diff --git a/d2x-rebirth/main/escort.cpp b/d2x-rebirth/main/escort.cpp index 2c88c1fde..e9481a6d1 100644 --- a/d2x-rebirth/main/escort.cpp +++ b/d2x-rebirth/main/escort.cpp @@ -1691,6 +1691,7 @@ static window_event_result escort_menu_handler(window *wind,const d_event &event case EVENT_WINDOW_CLOSE: d_free(menu); + delete wind; return window_event_result::ignored; // continue closing default: return window_event_result::ignored; diff --git a/d2x-rebirth/main/movie.cpp b/d2x-rebirth/main/movie.cpp index d6936513c..dfea251b8 100644 --- a/d2x-rebirth/main/movie.cpp +++ b/d2x-rebirth/main/movie.cpp @@ -274,7 +274,7 @@ struct movie : ignore_window_pointer_t } -static window_event_result show_pause_message(window *, const d_event &event, const unused_window_userdata_t *) +static window_event_result show_pause_message(window *wind, const d_event &event, const unused_window_userdata_t *) { switch (event.type) { @@ -309,13 +309,17 @@ static window_event_result show_pause_message(window *, const d_event &event, co break; } + case EVENT_WINDOW_CLOSE: + delete wind; + break; + default: break; } return window_event_result::ignored; } -static window_event_result MovieHandler(window *, const d_event &event, movie *m) +static window_event_result MovieHandler(window *wind, const d_event &event, movie *m) { int key; @@ -369,6 +373,7 @@ static window_event_result MovieHandler(window *, const d_event &event, movie *m case EVENT_WINDOW_CLOSE: if (Quitting) m->result = m->aborted = 1; + delete wind; break; default: diff --git a/similar/editor/info.cpp b/similar/editor/info.cpp index c023a38eb..ec82a184a 100644 --- a/similar/editor/info.cpp +++ b/similar/editor/info.cpp @@ -334,6 +334,7 @@ static window_event_result info_display_all(window *wind,const d_event &event, c return window_event_result::handled; case EVENT_WINDOW_CLOSE: Pad_info = NULL; + delete wind; break; default: diff --git a/similar/main/automap.cpp b/similar/main/automap.cpp index aa3fbec82..39e49b0da 100644 --- a/similar/main/automap.cpp +++ b/similar/main/automap.cpp @@ -951,6 +951,7 @@ static window_event_result automap_handler(window *wind,const d_event &event, au window_set_visible(Game_wind, 1); Automap_active = 0; multi_send_msgsend_state(msgsend_none); + delete wind; return window_event_result::ignored; // continue closing break; diff --git a/similar/main/console.cpp b/similar/main/console.cpp index 831842070..710f3385f 100644 --- a/similar/main/console.cpp +++ b/similar/main/console.cpp @@ -287,6 +287,7 @@ static window_event_result con_handler(window *wind,const d_event &event, const } break; case EVENT_WINDOW_CLOSE: + delete wind; break; default: break; diff --git a/similar/main/credits.cpp b/similar/main/credits.cpp index ba5984280..390cf33cf 100644 --- a/similar/main/credits.cpp +++ b/similar/main/credits.cpp @@ -94,7 +94,7 @@ struct credits : ignore_window_pointer_t } namespace dsx { -static window_event_result credits_handler(window *, const d_event &event, credits *cr) +static window_event_result credits_handler(window *wind, const d_event &event, credits *cr) { int l, y; switch (event.type) @@ -217,6 +217,8 @@ static window_event_result credits_handler(window *, const d_event &event, credi songs_set_volume(GameCfg.MusicVolume); songs_play_song( SONG_TITLE, 1 ); std::default_delete()(cr); + if (wind) + delete wind; break; default: break; diff --git a/similar/main/game.cpp b/similar/main/game.cpp index 11b16e9a8..8103ba9f6 100644 --- a/similar/main/game.cpp +++ b/similar/main/game.cpp @@ -1304,6 +1304,7 @@ window_event_result game_handler(window *,const d_event &event, const unused_win if (!EditorWindow) // have to do it this way because of the necessary longjmp. Yuck. #endif show_menus(); + delete Game_wind; Game_wind = NULL; event_toggle_focus(0); key_toggle_repeat(1); diff --git a/similar/main/gamecntl.cpp b/similar/main/gamecntl.cpp index 72ccdeb0a..b9f994210 100644 --- a/similar/main/gamecntl.cpp +++ b/similar/main/gamecntl.cpp @@ -340,7 +340,7 @@ struct pause_window : ignore_window_pointer_t }; //Process selected keys until game unpaused -static window_event_result pause_handler(window *, const d_event &event, pause_window *p) +static window_event_result pause_handler(window *wind, const d_event &event, pause_window *p) { int key; @@ -380,6 +380,7 @@ static window_event_result pause_handler(window *, const d_event &event, pause_w case EVENT_WINDOW_CLOSE: songs_resume(); delete p; + delete wind; break; default: diff --git a/similar/main/kconfig.cpp b/similar/main/kconfig.cpp index d69e69855..cbd014227 100644 --- a/similar/main/kconfig.cpp +++ b/similar/main/kconfig.cpp @@ -1286,6 +1286,7 @@ static window_event_result kconfig_handler(window *wind,const d_event &event, kc case EVENT_WINDOW_CLOSE: delete menu; + delete wind; // Update save values... diff --git a/similar/main/kmatrix.cpp b/similar/main/kmatrix.cpp index 13fae06de..8f0692cff 100644 --- a/similar/main/kmatrix.cpp +++ b/similar/main/kmatrix.cpp @@ -279,7 +279,7 @@ static void kmatrix_redraw_coop() } namespace dsx { -static window_event_result kmatrix_handler(window *, const d_event &event, kmatrix_screen *km) +static window_event_result kmatrix_handler(window *wind, const d_event &event, kmatrix_screen *km) { int k = 0, choice = 0; @@ -377,6 +377,7 @@ static window_event_result kmatrix_handler(window *, const d_event &event, kmatr case EVENT_WINDOW_CLOSE: game_flush_inputs(); newmenu_free_background(); + delete wind; break; default: diff --git a/similar/main/menu.cpp b/similar/main/menu.cpp index 149f0cfcf..c15bd8cfd 100644 --- a/similar/main/menu.cpp +++ b/similar/main/menu.cpp @@ -2285,7 +2285,7 @@ void do_options_menu() #ifndef RELEASE namespace dsx { -static window_event_result polygon_models_viewer_handler(window *, const d_event &event, const unused_window_userdata_t *) +static window_event_result polygon_models_viewer_handler(window *wind, const d_event &event, const unused_window_userdata_t *) { static unsigned view_idx; int key = 0; @@ -2354,6 +2354,8 @@ static window_event_result polygon_models_viewer_handler(window *, const d_event case EVENT_WINDOW_CLOSE: load_palette(MENU_PALETTE,0,1); key_toggle_repeat(0); + if (wind) + delete wind; break; default: break; @@ -2377,7 +2379,7 @@ static void polygon_models_viewer() } namespace dsx { -static window_event_result gamebitmaps_viewer_handler(window *, const d_event &event, const unused_window_userdata_t *) +static window_event_result gamebitmaps_viewer_handler(window *wind, const d_event &event, const unused_window_userdata_t *) { static int view_idx = 0; int key = 0; @@ -2433,6 +2435,8 @@ static window_event_result gamebitmaps_viewer_handler(window *, const d_event &e case EVENT_WINDOW_CLOSE: load_palette(MENU_PALETTE,0,1); key_toggle_repeat(0); + if (wind) + delete wind; break; default: break; diff --git a/similar/main/newmenu.cpp b/similar/main/newmenu.cpp index 943705b10..1d8dc9d0f 100644 --- a/similar/main/newmenu.cpp +++ b/similar/main/newmenu.cpp @@ -1567,6 +1567,7 @@ static window_event_result newmenu_handler(window *wind,const d_event &event, ne return newmenu_draw(wind, menu); case EVENT_WINDOW_CLOSE: delete menu; + delete wind; break; default: @@ -2074,6 +2075,7 @@ static window_event_result listbox_handler(window *wind,const d_event &event, li return listbox_draw(wind, lb); case EVENT_WINDOW_CLOSE: std::default_delete()(lb); + delete wind; break; default: break; diff --git a/similar/main/scores.cpp b/similar/main/scores.cpp index 9ff0a5802..5126470b3 100644 --- a/similar/main/scores.cpp +++ b/similar/main/scores.cpp @@ -446,6 +446,7 @@ static window_event_result scores_handler(window *wind,const d_event &event, sco case EVENT_WINDOW_CLOSE: d_free(menu); + delete wind; break; default: diff --git a/similar/main/titles.cpp b/similar/main/titles.cpp index 96236db52..afbbbd17e 100644 --- a/similar/main/titles.cpp +++ b/similar/main/titles.cpp @@ -109,7 +109,7 @@ struct title_screen : ignore_window_pointer_t } -static window_event_result title_handler(window *, const d_event &event, title_screen *ts) +static window_event_result title_handler(window *wind, const d_event &event, title_screen *ts) { switch (event.type) { @@ -146,6 +146,7 @@ static window_event_result title_handler(window *, const d_event &event, title_s case EVENT_WINDOW_CLOSE: gr_free_bitmap_data(ts->title_bm); + delete wind; break; default: @@ -1443,7 +1444,7 @@ static int new_briefing_screen(briefing *br, int first) //----------------------------------------------------------------------------- namespace dsx { -static window_event_result briefing_handler(window *, const d_event &event, briefing *br) +static window_event_result briefing_handler(window *wind, const d_event &event, briefing *br) { switch (event.type) { @@ -1553,6 +1554,7 @@ static window_event_result briefing_handler(window *, const d_event &event, brie #if defined(DXX_BUILD_DESCENT_II) br->hum_channel.reset(); #endif + delete wind; break; default: