diff options
Diffstat (limited to 'platform/linuxbsd')
-rw-r--r-- | platform/linuxbsd/os_linuxbsd.cpp | 53 | ||||
-rw-r--r-- | platform/linuxbsd/tts_linux.cpp | 57 | ||||
-rw-r--r-- | platform/linuxbsd/tts_linux.h | 8 | ||||
-rw-r--r-- | platform/linuxbsd/x11/display_server_x11.cpp | 21 |
4 files changed, 90 insertions, 49 deletions
diff --git a/platform/linuxbsd/os_linuxbsd.cpp b/platform/linuxbsd/os_linuxbsd.cpp index 8d8c8ce27b..b843becfe0 100644 --- a/platform/linuxbsd/os_linuxbsd.cpp +++ b/platform/linuxbsd/os_linuxbsd.cpp @@ -215,48 +215,54 @@ String OS_LinuxBSD::get_name() const { } String OS_LinuxBSD::get_systemd_os_release_info_value(const String &key) const { - static String info; - if (info.is_empty()) { - Ref<FileAccess> f = FileAccess::open("/etc/os-release", FileAccess::READ); - if (f.is_valid()) { - while (!f->eof_reached()) { - const String line = f->get_line(); - if (line.find(key) != -1) { - return line.split("=")[1].strip_edges(); - } + Ref<FileAccess> f = FileAccess::open("/etc/os-release", FileAccess::READ); + if (f.is_valid()) { + while (!f->eof_reached()) { + const String line = f->get_line(); + if (line.find(key) != -1) { + String value = line.split("=")[1].strip_edges(); + value = value.trim_prefix("\""); + return value.trim_suffix("\""); } } } - return info; + return ""; } String OS_LinuxBSD::get_distribution_name() const { - static String systemd_name = get_systemd_os_release_info_value("NAME"); // returns a value for systemd users, otherwise an empty string. - if (!systemd_name.is_empty()) { - return systemd_name; + static String distribution_name = get_systemd_os_release_info_value("NAME"); // returns a value for systemd users, otherwise an empty string. + if (!distribution_name.is_empty()) { + return distribution_name; } struct utsname uts; // returns a decent value for BSD family. uname(&uts); - return uts.sysname; + distribution_name = uts.sysname; + return distribution_name; } String OS_LinuxBSD::get_version() const { - static String systemd_version = get_systemd_os_release_info_value("VERSION"); // returns a value for systemd users, otherwise an empty string. - if (!systemd_version.is_empty()) { - return systemd_version; + static String release_version = get_systemd_os_release_info_value("VERSION"); // returns a value for systemd users, otherwise an empty string. + if (!release_version.is_empty()) { + return release_version; } struct utsname uts; // returns a decent value for BSD family. uname(&uts); - return uts.version; + release_version = uts.version; + return release_version; } Vector<String> OS_LinuxBSD::get_video_adapter_driver_info() const { - if (RenderingServer::get_singleton()->get_rendering_device() == nullptr) { + if (RenderingServer::get_singleton() == nullptr) { return Vector<String>(); } - const String rendering_device_name = RenderingServer::get_singleton()->get_rendering_device()->get_device_name(); // e.g. `NVIDIA GeForce GTX 970` - const String rendering_device_vendor = RenderingServer::get_singleton()->get_rendering_device()->get_device_vendor_name(); // e.g. `NVIDIA` + static Vector<String> info; + if (!info.is_empty()) { + return info; + } + + const String rendering_device_name = RenderingServer::get_singleton()->get_video_adapter_name(); // e.g. `NVIDIA GeForce GTX 970` + const String rendering_device_vendor = RenderingServer::get_singleton()->get_video_adapter_vendor(); // e.g. `NVIDIA` const String card_name = rendering_device_name.trim_prefix(rendering_device_vendor).strip_edges(); // -> `GeForce GTX 970` String vendor_device_id_mappings; @@ -320,8 +326,8 @@ Vector<String> OS_LinuxBSD::get_video_adapter_driver_info() const { Vector<String> class_display_device_drivers = OS_LinuxBSD::lspci_get_device_value(class_display_device_candidates, kernel_lit, dummys); Vector<String> class_3d_device_drivers = OS_LinuxBSD::lspci_get_device_value(class_3d_device_candidates, kernel_lit, dummys); - static String driver_name; - static String driver_version; + String driver_name; + String driver_version; // Use first valid value: for (const String &driver : class_3d_device_drivers) { @@ -341,7 +347,6 @@ Vector<String> OS_LinuxBSD::get_video_adapter_driver_info() const { } } - Vector<String> info; info.push_back(driver_name); String modinfo; diff --git a/platform/linuxbsd/tts_linux.cpp b/platform/linuxbsd/tts_linux.cpp index a0cb4f5c6c..8bc83f5b9c 100644 --- a/platform/linuxbsd/tts_linux.cpp +++ b/platform/linuxbsd/tts_linux.cpp @@ -101,6 +101,24 @@ void TTS_Linux::speech_event_callback(size_t p_msg_id, size_t p_client_id, SPDNo } } +void TTS_Linux::_load_voices() { + if (!voices_loaded) { + SPDVoice **spd_voices = spd_list_synthesis_voices(synth); + if (spd_voices != nullptr) { + SPDVoice **voices_ptr = spd_voices; + while (*voices_ptr != nullptr) { + VoiceInfo vi; + vi.language = String::utf8((*voices_ptr)->language); + vi.variant = String::utf8((*voices_ptr)->variant); + voices[String::utf8((*voices_ptr)->name)] = vi; + voices_ptr++; + } + free_spd_voices(spd_voices); + } + voices_loaded = true; + } +} + void TTS_Linux::_speech_event(size_t p_msg_id, size_t p_client_id, int p_type) { _THREAD_SAFE_METHOD_ @@ -123,18 +141,13 @@ void TTS_Linux::_speech_event(size_t p_msg_id, size_t p_client_id, int p_type) { // Inject index mark after each word. String text; String language; - SPDVoice **voices = spd_list_synthesis_voices(synth); - if (voices != nullptr) { - SPDVoice **voices_ptr = voices; - while (*voices_ptr != nullptr) { - if (String::utf8((*voices_ptr)->name) == message.voice) { - language = String::utf8((*voices_ptr)->language); - break; - } - voices_ptr++; - } - free_spd_voices(voices); + + _load_voices(); + const VoiceInfo *voice = voices.getptr(message.voice); + if (voice) { + language = voice->language; } + PackedInt32Array breaks = TS->string_get_word_breaks(message.text, language); for (int i = 0; i < breaks.size(); i += 2) { const int start = breaks[i]; @@ -174,21 +187,17 @@ Array TTS_Linux::get_voices() const { _THREAD_SAFE_METHOD_ ERR_FAIL_COND_V(!synth, Array()); + const_cast<TTS_Linux *>(this)->_load_voices(); + Array list; - SPDVoice **voices = spd_list_synthesis_voices(synth); - if (voices != nullptr) { - SPDVoice **voices_ptr = voices; - while (*voices_ptr != nullptr) { - Dictionary voice_d; - voice_d["name"] = String::utf8((*voices_ptr)->name); - voice_d["id"] = String::utf8((*voices_ptr)->name); - voice_d["language"] = String::utf8((*voices_ptr)->language) + "_" + String::utf8((*voices_ptr)->variant); - list.push_back(voice_d); - - voices_ptr++; - } - free_spd_voices(voices); + for (const KeyValue<String, VoiceInfo> &E : voices) { + Dictionary voice_d; + voice_d["name"] = E.key; + voice_d["id"] = E.key; + voice_d["language"] = E.value.language + "_" + E.value.variant; + list.push_back(voice_d); } + return list; } diff --git a/platform/linuxbsd/tts_linux.h b/platform/linuxbsd/tts_linux.h index 651a64d9d6..ec68219689 100644 --- a/platform/linuxbsd/tts_linux.h +++ b/platform/linuxbsd/tts_linux.h @@ -55,6 +55,13 @@ class TTS_Linux : public Object { int last_msg_id = -1; HashMap<int, int> ids; + struct VoiceInfo { + String language; + String variant; + }; + bool voices_loaded = false; + HashMap<String, VoiceInfo> voices; + Thread init_thread; static void speech_init_thread_func(void *p_userdata); @@ -64,6 +71,7 @@ class TTS_Linux : public Object { static TTS_Linux *singleton; protected: + void _load_voices(); void _speech_event(size_t p_msg_id, size_t p_client_id, int p_type); void _speech_index_mark(size_t p_msg_id, size_t p_client_id, int p_type, const String &p_index_mark); diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp index 507acfcf34..fa35340ebb 100644 --- a/platform/linuxbsd/x11/display_server_x11.cpp +++ b/platform/linuxbsd/x11/display_server_x11.cpp @@ -855,12 +855,30 @@ Size2i DisplayServerX11::screen_get_size(int p_screen) const { return _screen_get_rect(p_screen).size; } +// A Handler to avoid crashing on non-fatal X errors by default. +// +// The original X11 error formatter `_XPrintDefaultError` is defined here: +// https://gitlab.freedesktop.org/xorg/lib/libx11/-/blob/e45ca7b41dcd3ace7681d6897505f85d374640f2/src/XlibInt.c#L1322 +// It is not exposed through the API, accesses X11 internals, +// and is much more complex, so this is a less complete simplified error X11 printer. +int default_window_error_handler(Display *display, XErrorEvent *error) { + static char message[1024]; + XGetErrorText(display, error->error_code, message, sizeof(message)); + + ERR_PRINT(vformat("Unhandled XServer error: %s" + "\n Major opcode of failed request: %d" + "\n Serial number of failed request: %d" + "\n Current serial number in output stream: %d", + String::utf8(message), error->request_code, error->minor_code, error->serial)); + return 0; +} + bool g_bad_window = false; int bad_window_error_handler(Display *display, XErrorEvent *error) { if (error->error_code == BadWindow) { g_bad_window = true; } else { - ERR_PRINT("Unhandled XServer error code: " + itos(error->error_code)); + return default_window_error_handler(display, error); } return 0; } @@ -5930,6 +5948,7 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode portal_desktop = memnew(FreeDesktopPortalDesktop); #endif + XSetErrorHandler(&default_window_error_handler); r_error = OK; } |