diff --git a/include/frontend.hpp b/include/frontend.hpp index 92bc2f4..9e1fc4c 100755 --- a/include/frontend.hpp +++ b/include/frontend.hpp @@ -67,6 +67,7 @@ public: int save_data(); bool open_capture(); bool close_capture(); + int get_ret_val(); private: struct ScreenOperations { @@ -87,6 +88,7 @@ private: bool last_connected_status; bool m_prepare_open; bool m_prepare_quit; + int ret_val; bool font_load_success; double frame_time; DisplayData* display_data; @@ -172,6 +174,7 @@ private: int get_screen_corner_modifier_y(int rotation, int height); void print_notification_on_off(std::string base_text, bool value); void print_notification_float(std::string base_text, float value, int decimals); + void set_close(int ret_val); void split_change(); void fullscreen_change(); void async_change(); diff --git a/source/Menus/MainMenu.cpp b/source/Menus/MainMenu.cpp index 4f1af84..bfabdc9 100755 --- a/source/Menus/MainMenu.cpp +++ b/source/Menus/MainMenu.cpp @@ -106,6 +106,13 @@ static const MainMenuOptionInfo extra_settings_option = { .enabled_normal_mode = false, .enabled_mono_mode = true, .out_action = MAIN_MENU_EXTRA_SETTINGS}; +static const MainMenuOptionInfo shutdown_option = { +.base_name = "Shutdown", .false_name = "", +.active_fullscreen = true, .active_windowed_screen = true, +.active_joint_screen = true, .active_top_screen = true, .active_bottom_screen = true, +.enabled_normal_mode = false, .enabled_mono_mode = true, +.out_action = MAIN_MENU_SHUTDOWN}; + static const MainMenuOptionInfo* pollable_options[] = { &connect_option, &windowed_option, @@ -120,6 +127,7 @@ static const MainMenuOptionInfo* pollable_options[] = { &licenses_option, &extra_settings_option, &quit_option, +&shutdown_option, }; MainMenu::MainMenu(bool font_load_success, sf::Font &text_font) : OptionSelectionMenu(){ diff --git a/source/WindowScreen.cpp b/source/WindowScreen.cpp index dca4ec1..83cc0ed 100755 --- a/source/WindowScreen.cpp +++ b/source/WindowScreen.cpp @@ -20,6 +20,7 @@ WindowScreen::WindowScreen(ScreenType stype, CaptureStatus* capture_status, Disp this->m_prepare_load = 0; this->m_prepare_open = false; this->m_prepare_quit = false; + this->ret_val = 0; reset_screen_info(this->m_info); this->font_load_success = this->text_font.loadFromMemory(font_ttf, font_ttf_len); this->notification = new TextRectangle(this->font_load_success, this->text_font); diff --git a/source/WindowScreen_Menu.cpp b/source/WindowScreen_Menu.cpp index 9d4d868..f46fbbd 100755 --- a/source/WindowScreen_Menu.cpp +++ b/source/WindowScreen_Menu.cpp @@ -110,6 +110,11 @@ void WindowScreen::destroy_menus() { delete this->license_menu; } +void WindowScreen::set_close(int ret_val) { + this->m_prepare_quit = true; + this->ret_val = ret_val; +} + void WindowScreen::split_change() { if(this->curr_menu != CONNECT_MENU_TYPE) this->curr_menu = DEFAULT_MENU_TYPE; @@ -274,7 +279,7 @@ bool WindowScreen::common_poll(SFEvent &event_data) { bool consumed = true; switch(event_data.type) { case sf::Event::Closed: - this->m_prepare_quit = true; + this->set_close(0); break; case sf::Event::TextEntered: @@ -321,7 +326,7 @@ bool WindowScreen::common_poll(SFEvent &event_data) { case sf::Event::KeyPressed: switch(event_data.code) { case sf::Keyboard::Escape: - this->m_prepare_quit = true; + this->set_close(0); break; case sf::Keyboard::Enter: check_held_reset_key(true, this->enter_action); @@ -802,7 +807,7 @@ void WindowScreen::poll() { SFEvent event_data = events_queue.front(); events_queue.pop(); if((event_data.type == sf::Event::KeyPressed) && event_data.poweroff_cmd) { - this->m_prepare_quit = true; + this->set_close(1); done = true; continue; } @@ -844,7 +849,7 @@ void WindowScreen::poll() { done = true; break; case MAIN_MENU_QUIT_APPLICATION: - this->m_prepare_quit = true; + this->set_close(0); this->curr_menu = DEFAULT_MENU_TYPE; done = true; break; @@ -885,6 +890,8 @@ void WindowScreen::poll() { done = true; break; case MAIN_MENU_SHUTDOWN: + this->set_close(1); + this->curr_menu = DEFAULT_MENU_TYPE; done = true; break; default: @@ -1277,7 +1284,7 @@ void WindowScreen::poll() { case EXTRA_SETTINGS_MENU_NO_ACTION: break; case EXTRA_SETTINGS_MENU_QUIT_APPLICATION: - this->m_prepare_quit = true; + this->set_close(0); this->curr_menu = DEFAULT_MENU_TYPE; done = true; break; @@ -1373,6 +1380,12 @@ bool WindowScreen::close_capture() { return this->m_prepare_quit; } +int WindowScreen::get_ret_val() { + if(!this->m_prepare_quit) + return -1; + return this->ret_val; +} + bool WindowScreen::query_reset_request() { auto curr_time = std::chrono::high_resolution_clock::now(); if(check_held_diff(curr_time, this->right_click_action) > this->bad_resolution_timeout) diff --git a/source/cc3dsfs.cpp b/source/cc3dsfs.cpp index 29db3f6..3fd1a0c 100755 --- a/source/cc3dsfs.cpp +++ b/source/cc3dsfs.cpp @@ -238,7 +238,14 @@ static void soundCall(AudioData *audio_data, CaptureData* capture_data) { audio.stop(); } -static void mainVideoOutputCall(AudioData* audio_data, CaptureData* capture_data, bool mono_app) { +static void check_close_application(WindowScreen &screen, CaptureData* capture_data, int &ret_val) { + if(screen.close_capture() && capture_data->status.running) { + capture_data->status.running = false; + ret_val = screen.get_ret_val(); + } +} + +static int mainVideoOutputCall(AudioData* audio_data, CaptureData* capture_data, bool mono_app) { VideoOutputData *out_buf; double last_frame_time = 0.0; int num_elements_fps_array = 0; @@ -252,6 +259,7 @@ static void mainVideoOutputCall(AudioData* audio_data, CaptureData* capture_data std::mutex events_access; OutTextData out_text_data; out_text_data.consumed = true; + int ret_val = 0; out_buf = new VideoOutputData; memset(out_buf, 0, sizeof(VideoOutputData)); @@ -330,9 +338,9 @@ static void mainVideoOutputCall(AudioData* audio_data, CaptureData* capture_data SuccessConnectionOutTextGenerator(out_text_data, capture_data); } - if(top_screen.close_capture() || bot_screen.close_capture() || joint_screen.close_capture()) { - capture_data->status.running = false; - } + check_close_application(top_screen, capture_data, ret_val); + check_close_application(bot_screen, capture_data, ret_val); + check_close_application(joint_screen, capture_data, ret_val); if((load_index = top_screen.load_data()) || (load_index = bot_screen.load_data()) || (load_index = joint_screen.load_data())) load_layout_file(load_index, &frontend_data, audio_data, out_text_data, skip_io, true); @@ -382,6 +390,7 @@ static void mainVideoOutputCall(AudioData* audio_data, CaptureData* capture_data } delete out_buf; + return ret_val; } static bool parse_existence_arg(int &index, char **argv, bool &target, bool existence_value, std::string to_check) { @@ -446,11 +455,11 @@ int main(int argc, char **argv) { std::thread capture_thread(captureCall, capture_data); std::thread audio_thread(soundCall, &audio_data, capture_data); - mainVideoOutputCall(&audio_data, capture_data, mono_app); + int ret_val = mainVideoOutputCall(&audio_data, capture_data, mono_app); audio_thread.join(); capture_thread.join(); delete capture_data; end_extra_buttons_poll(); - return 0; + return ret_val; }