summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2021-11-12 18:38:18 +1100
committer Vas Crabb <vas@vastheman.com>2021-11-12 18:38:18 +1100
commit5c8e06be77c7d7ee72b8eaa3d2dc2bfee427ea1c (patch)
tree3dd17d2a193bdddc5c682a9e75d4c1b0153f0b4b /src/osd
parentdc6ddf122cfbf98c1bf9d2ba705c6adfec98d847 (diff)
-osd/windows: Show error message box on a separate thread (see MT08118).
-emu/emuopts.cpp: Default to built-in UI language rather than English. * The external English message catalog is a placeholder anyway. -cpu/mcs48: Corrected comments - D87xxH have UVEPROM, not EEPROM.
Diffstat (limited to 'src/osd')
-rw-r--r--src/osd/windows/winmain.cpp67
1 files changed, 64 insertions, 3 deletions
diff --git a/src/osd/windows/winmain.cpp b/src/osd/windows/winmain.cpp
index 09315e5ca84..b24d2980c19 100644
--- a/src/osd/windows/winmain.cpp
+++ b/src/osd/windows/winmain.cpp
@@ -25,6 +25,10 @@
#include <clocale>
#include <cstdarg>
#include <cstdio>
+#include <mutex>
+#include <optional>
+#include <sstream>
+#include <thread>
// standard windows headers
#include <windows.h>
@@ -55,6 +59,28 @@
class winui_output_error : public osd_output
{
+private:
+ struct ui_state
+ {
+ ~ui_state()
+ {
+ std::lock_guard guard(mutex);
+ if (thread)
+ thread->join();
+ }
+
+ std::ostringstream buffer;
+ std::optional<std::thread> thread;
+ std::mutex mutex;
+ bool active;
+ };
+
+ static ui_state &get_state()
+ {
+ static ui_state state;
+ return state;
+ }
+
public:
virtual void output_callback(osd_output_channel channel, const util::format_argument_pack<std::ostream> &args) override
{
@@ -64,12 +90,47 @@ public:
if ((video_config.windowed == 0) && !osd_common_t::s_window_list.empty())
winwindow_toggle_full_screen();
- std::ostringstream buffer;
- util::stream_format(buffer, args);
- win_message_box_utf8(!osd_common_t::s_window_list.empty() ? std::static_pointer_cast<win_window_info>(osd_common_t::s_window_list.front())->platform_window() : nullptr, buffer.str().c_str(), emulator_info::get_appname(), MB_OK);
+ auto &state(get_state());
+ std::lock_guard<std::mutex> guard(state.mutex);
+ util::stream_format(state.buffer, args);
+ if (!state.active)
+ {
+ if (state.thread)
+ {
+ state.thread->join();
+ state.thread = std::nullopt;
+ }
+ auto const parent = !osd_common_t::s_window_list.empty()
+ ? std::static_pointer_cast<win_window_info>(osd_common_t::s_window_list.front())->platform_window()
+ : nullptr;
+ state.thread.emplace(
+ [parent] ()
+ {
+ auto &state(get_state());
+ std::string message;
+ while (true)
+ {
+ {
+ std::lock_guard<std::mutex> guard(state.mutex);
+ message = std::move(state.buffer).str();
+ if (message.empty())
+ {
+ state.active = false;
+ return;
+ }
+ state.buffer.str(std::string());
+ }
+ // don't hold any locks lock while calling MessageBox
+ win_message_box_utf8(parent, message.c_str(), emulator_info::get_appname(), MB_OK);
+ }
+ });
+ state.active = true;
+ }
}
else
+ {
chain_output(channel, args);
+ }
}
};