summaryrefslogtreecommitdiffstats
path: root/platform
diff options
context:
space:
mode:
Diffstat (limited to 'platform')
-rw-r--r--platform/linuxbsd/freedesktop_portal_desktop.cpp11
-rw-r--r--platform/linuxbsd/freedesktop_screensaver.cpp11
-rw-r--r--platform/linuxbsd/joypad_linux.cpp8
-rw-r--r--platform/linuxbsd/os_linuxbsd.cpp10
-rw-r--r--platform/linuxbsd/tts_linux.cpp5
-rw-r--r--platform/linuxbsd/x11/display_server_x11.cpp99
-rw-r--r--platform/linuxbsd/x11/display_server_x11.h3
-rw-r--r--platform/windows/crash_handler_windows.cpp3
-rw-r--r--platform/windows/detect.py6
-rw-r--r--platform/windows/display_server_windows.cpp1
-rw-r--r--platform/windows/os_windows.cpp107
-rw-r--r--platform/windows/tts_windows.cpp3
12 files changed, 244 insertions, 23 deletions
diff --git a/platform/linuxbsd/freedesktop_portal_desktop.cpp b/platform/linuxbsd/freedesktop_portal_desktop.cpp
index ec1fcf6698..b45b7e676d 100644
--- a/platform/linuxbsd/freedesktop_portal_desktop.cpp
+++ b/platform/linuxbsd/freedesktop_portal_desktop.cpp
@@ -138,6 +138,17 @@ FreeDesktopPortalDesktop::FreeDesktopPortalDesktop() {
#else
unsupported = false;
#endif
+ bool ver_ok = false;
+ int version_major = 0;
+ int version_minor = 0;
+ int version_rev = 0;
+ dbus_get_version(&version_major, &version_minor, &version_rev);
+ ver_ok = (version_major == 1 && version_minor >= 10) || (version_major > 1); // 1.10.0
+ print_verbose(vformat("PortalDesktop: DBus %d.%d.%d detected.", version_major, version_minor, version_rev));
+ if (!ver_ok) {
+ print_verbose("PortalDesktop: Unsupported DBus library version!");
+ unsupported = true;
+ }
}
#endif // DBUS_ENABLED
diff --git a/platform/linuxbsd/freedesktop_screensaver.cpp b/platform/linuxbsd/freedesktop_screensaver.cpp
index d07e781a5f..78f2337599 100644
--- a/platform/linuxbsd/freedesktop_screensaver.cpp
+++ b/platform/linuxbsd/freedesktop_screensaver.cpp
@@ -141,6 +141,17 @@ FreeDesktopScreenSaver::FreeDesktopScreenSaver() {
#else
unsupported = false;
#endif
+ bool ver_ok = false;
+ int version_major = 0;
+ int version_minor = 0;
+ int version_rev = 0;
+ dbus_get_version(&version_major, &version_minor, &version_rev);
+ ver_ok = (version_major == 1 && version_minor >= 10) || (version_major > 1); // 1.10.0
+ print_verbose(vformat("ScreenSaver: DBus %d.%d.%d detected.", version_major, version_minor, version_rev));
+ if (!ver_ok) {
+ print_verbose("ScreenSaver:: Unsupported DBus library version!");
+ unsupported = true;
+ }
}
#endif // DBUS_ENABLED
diff --git a/platform/linuxbsd/joypad_linux.cpp b/platform/linuxbsd/joypad_linux.cpp
index 0256af0a59..5c623b8ba2 100644
--- a/platform/linuxbsd/joypad_linux.cpp
+++ b/platform/linuxbsd/joypad_linux.cpp
@@ -82,7 +82,13 @@ JoypadLinux::JoypadLinux(Input *in) {
#endif
use_udev = initialize_libudev(dylibloader_verbose) == 0;
if (use_udev) {
- print_verbose("JoypadLinux: udev enabled and loaded successfully.");
+ if (!udev_new || !udev_unref || !udev_enumerate_new || !udev_enumerate_add_match_subsystem || !udev_enumerate_scan_devices || !udev_enumerate_get_list_entry || !udev_list_entry_get_next || !udev_list_entry_get_name || !udev_device_new_from_syspath || !udev_device_get_devnode || !udev_device_get_action || !udev_device_unref || !udev_enumerate_unref || !udev_monitor_new_from_netlink || !udev_monitor_filter_add_match_subsystem_devtype || !udev_monitor_enable_receiving || !udev_monitor_get_fd || !udev_monitor_receive_device || !udev_monitor_unref) {
+ // There's no API to check version, check if functions are available instead.
+ use_udev = false;
+ print_verbose("JoypadLinux: Unsupported udev library version!");
+ } else {
+ print_verbose("JoypadLinux: udev enabled and loaded successfully.");
+ }
} else {
print_verbose("JoypadLinux: udev enabled, but couldn't be loaded. Falling back to /dev/input to detect joypads.");
}
diff --git a/platform/linuxbsd/os_linuxbsd.cpp b/platform/linuxbsd/os_linuxbsd.cpp
index 88c3d2cc14..11c81be4a9 100644
--- a/platform/linuxbsd/os_linuxbsd.cpp
+++ b/platform/linuxbsd/os_linuxbsd.cpp
@@ -1103,6 +1103,16 @@ OS_LinuxBSD::OS_LinuxBSD() {
font_config_initialized = true;
#endif
if (font_config_initialized) {
+ bool ver_ok = false;
+ int version = FcGetVersion();
+ ver_ok = ((version / 100 / 100) == 2 && (version / 100 % 100) >= 11) || ((version / 100 / 100) > 2); // 2.11.0
+ print_verbose(vformat("FontConfig %d.%d.%d detected.", version / 100 / 100, version / 100 % 100, version % 100));
+ if (!ver_ok) {
+ font_config_initialized = false;
+ }
+ }
+
+ if (font_config_initialized) {
config = FcInitLoadConfigAndFonts();
if (!config) {
font_config_initialized = false;
diff --git a/platform/linuxbsd/tts_linux.cpp b/platform/linuxbsd/tts_linux.cpp
index ce0199e87f..a0cb4f5c6c 100644
--- a/platform/linuxbsd/tts_linux.cpp
+++ b/platform/linuxbsd/tts_linux.cpp
@@ -48,6 +48,11 @@ void TTS_Linux::speech_init_thread_func(void *p_userdata) {
if (initialize_speechd(dylibloader_verbose) != 0) {
print_verbose("Text-to-Speech: Cannot load Speech Dispatcher library!");
} else {
+ if (!spd_open || !spd_set_notification_on || !spd_list_synthesis_voices || !free_spd_voices || !spd_set_synthesis_voice || !spd_set_volume || !spd_set_voice_pitch || !spd_set_voice_rate || !spd_set_data_mode || !spd_say || !spd_pause || !spd_resume || !spd_cancel) {
+ // There's no API to check version, check if functions are available instead.
+ print_verbose("Text-to-Speech: Unsupported Speech Dispatcher library version!");
+ return;
+ }
#else
{
#endif
diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp
index 52ee9e8e6f..48d4e078df 100644
--- a/platform/linuxbsd/x11/display_server_x11.cpp
+++ b/platform/linuxbsd/x11/display_server_x11.cpp
@@ -1354,7 +1354,7 @@ void DisplayServerX11::delete_sub_window(WindowID p_id) {
}
XDestroyWindow(x11_display, wd.x11_xim_window);
#ifdef XKB_ENABLED
- if (xkb_loaded) {
+ if (xkb_loaded_v05p) {
if (wd.xkb_state) {
xkb_compose_state_unref(wd.xkb_state);
wd.xkb_state = nullptr;
@@ -2982,7 +2982,7 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event,
String keysym;
#ifdef XKB_ENABLED
- if (xkb_loaded) {
+ if (xkb_loaded_v08p) {
KeySym keysym_unicode_nm = 0; // keysym used to find unicode
XLookupString(&xkeyevent_no_mod, nullptr, 0, &keysym_unicode_nm, nullptr);
keysym = String::chr(xkb_keysym_to_utf32(xkb_keysym_to_upper(keysym_unicode_nm)));
@@ -3077,7 +3077,7 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event,
} while (status == XBufferOverflow);
#endif
#ifdef XKB_ENABLED
- } else if (xkeyevent->type == KeyPress && wd.xkb_state && xkb_loaded) {
+ } else if (xkeyevent->type == KeyPress && wd.xkb_state && xkb_loaded_v05p) {
xkb_compose_feed_result res = xkb_compose_state_feed(wd.xkb_state, keysym_unicode);
if (res == XKB_COMPOSE_FEED_ACCEPTED) {
if (xkb_compose_state_get_status(wd.xkb_state) == XKB_COMPOSE_COMPOSED) {
@@ -5004,7 +5004,7 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, V
wd.x11_xim_window = XCreateWindow(x11_display, wd.x11_window, 0, 0, 1, 1, 0, CopyFromParent, InputOnly, CopyFromParent, CWEventMask, &window_attributes_ime);
#ifdef XKB_ENABLED
- if (dead_tbl && xkb_loaded) {
+ if (dead_tbl && xkb_loaded_v05p) {
wd.xkb_state = xkb_compose_state_new(dead_tbl, XKB_COMPOSE_STATE_NO_FLAGS);
}
#endif
@@ -5288,9 +5288,16 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
ERR_FAIL_MSG("Can't load XCursor dynamically.");
}
#ifdef XKB_ENABLED
- xkb_loaded = (initialize_xkbcommon(dylibloader_verbose) == 0);
- if (!xkb_context_new || !xkb_compose_table_new_from_locale || !xkb_compose_table_unref || !xkb_context_unref || !xkb_compose_state_feed || !xkb_compose_state_unref || !xkb_compose_state_new || !xkb_compose_state_get_status || !xkb_compose_state_get_utf8 || !xkb_keysym_to_utf32 || !xkb_keysym_to_upper) {
- xkb_loaded = false;
+ bool xkb_loaded = (initialize_xkbcommon(dylibloader_verbose) == 0);
+ xkb_loaded_v05p = xkb_loaded;
+ if (!xkb_context_new || !xkb_compose_table_new_from_locale || !xkb_compose_table_unref || !xkb_context_unref || !xkb_compose_state_feed || !xkb_compose_state_unref || !xkb_compose_state_new || !xkb_compose_state_get_status || !xkb_compose_state_get_utf8) {
+ xkb_loaded_v05p = false;
+ print_verbose("Detected XKBcommon library version older than 0.5, dead key composition and Unicode key labels disabled.");
+ }
+ xkb_loaded_v08p = xkb_loaded;
+ if (!xkb_keysym_to_utf32 || !xkb_keysym_to_upper) {
+ xkb_loaded_v08p = false;
+ print_verbose("Detected XKBcommon library version older than 0.8, Unicode key labels disabled.");
}
#endif
if (initialize_xext(dylibloader_verbose) != 0) {
@@ -5346,6 +5353,15 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
r_error = OK;
+ {
+ if (!XcursorImageCreate || !XcursorImageLoadCursor || !XcursorImageDestroy || !XcursorGetDefaultSize || !XcursorGetTheme || !XcursorLibraryLoadImage) {
+ // There's no API to check version, check if functions are available instead.
+ ERR_PRINT("Unsupported Xcursor library version.");
+ r_error = ERR_UNAVAILABLE;
+ return;
+ }
+ }
+
for (int i = 0; i < CURSOR_MAX; i++) {
cursors[i] = None;
img[i] = nullptr;
@@ -5362,6 +5378,71 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
return;
}
+ {
+ int version_major = 0;
+ int version_minor = 0;
+ int rc = XShapeQueryVersion(x11_display, &version_major, &version_minor);
+ print_verbose(vformat("Xshape %d.%d detected.", version_major, version_minor));
+ if (rc != 1 || version_major < 1) {
+ ERR_PRINT("Unsupported Xshape library version.");
+ r_error = ERR_UNAVAILABLE;
+ XCloseDisplay(x11_display);
+ return;
+ }
+ }
+
+ {
+ int version_major = 0;
+ int version_minor = 0;
+ int rc = XineramaQueryVersion(x11_display, &version_major, &version_minor);
+ print_verbose(vformat("Xinerama %d.%d detected.", version_major, version_minor));
+ if (rc != 1 || version_major < 1) {
+ ERR_PRINT("Unsupported Xinerama library version.");
+ r_error = ERR_UNAVAILABLE;
+ XCloseDisplay(x11_display);
+ return;
+ }
+ }
+
+ {
+ int version_major = 0;
+ int version_minor = 0;
+ int rc = XRRQueryVersion(x11_display, &version_major, &version_minor);
+ print_verbose(vformat("Xrandr %d.%d detected.", version_major, version_minor));
+ if (rc != 1 || (version_major == 1 && version_minor < 3) || (version_major < 1)) {
+ ERR_PRINT("Unsupported Xrandr library version.");
+ r_error = ERR_UNAVAILABLE;
+ XCloseDisplay(x11_display);
+ return;
+ }
+ }
+
+ {
+ int version_major = 0;
+ int version_minor = 0;
+ int rc = XRenderQueryVersion(x11_display, &version_major, &version_minor);
+ print_verbose(vformat("Xrender %d.%d detected.", version_major, version_minor));
+ if (rc != 1 || (version_major == 0 && version_minor < 11)) {
+ ERR_PRINT("Unsupported Xrender library version.");
+ r_error = ERR_UNAVAILABLE;
+ XCloseDisplay(x11_display);
+ return;
+ }
+ }
+
+ {
+ int version_major = 2; // Report 2.2 as supported by engine, but should work with 2.1 or 2.0 library as well.
+ int version_minor = 2;
+ int rc = XIQueryVersion(x11_display, &version_major, &version_minor);
+ print_verbose(vformat("Xinput %d.%d detected.", version_major, version_minor));
+ if (rc != Success || (version_major < 2)) {
+ ERR_PRINT("Unsupported Xinput2 library version.");
+ r_error = ERR_UNAVAILABLE;
+ XCloseDisplay(x11_display);
+ return;
+ }
+ }
+
char *modifiers = nullptr;
Bool xkb_dar = False;
XAutoRepeatOn(x11_display);
@@ -5784,7 +5865,7 @@ DisplayServerX11::~DisplayServerX11() {
}
XDestroyWindow(x11_display, wd.x11_xim_window);
#ifdef XKB_ENABLED
- if (xkb_loaded) {
+ if (xkb_loaded_v05p) {
if (wd.xkb_state) {
xkb_compose_state_unref(wd.xkb_state);
wd.xkb_state = nullptr;
@@ -5796,7 +5877,7 @@ DisplayServerX11::~DisplayServerX11() {
}
#ifdef XKB_ENABLED
- if (xkb_loaded) {
+ if (xkb_loaded_v05p) {
if (dead_tbl) {
xkb_compose_table_unref(dead_tbl);
}
diff --git a/platform/linuxbsd/x11/display_server_x11.h b/platform/linuxbsd/x11/display_server_x11.h
index c19d2f441a..f6a1bc8012 100644
--- a/platform/linuxbsd/x11/display_server_x11.h
+++ b/platform/linuxbsd/x11/display_server_x11.h
@@ -212,7 +212,8 @@ class DisplayServerX11 : public DisplayServer {
String im_text;
#ifdef XKB_ENABLED
- bool xkb_loaded = false;
+ bool xkb_loaded_v05p = false;
+ bool xkb_loaded_v08p = false;
xkb_context *xkb_ctx = nullptr;
xkb_compose_table *dead_tbl = nullptr;
#endif
diff --git a/platform/windows/crash_handler_windows.cpp b/platform/windows/crash_handler_windows.cpp
index 867f1d537c..e32fbd47dd 100644
--- a/platform/windows/crash_handler_windows.cpp
+++ b/platform/windows/crash_handler_windows.cpp
@@ -47,9 +47,6 @@
#include <psapi.h>
-#pragma comment(lib, "psapi.lib")
-#pragma comment(lib, "dbghelp.lib")
-
// Some versions of imagehlp.dll lack the proper packing directives themselves
// so we need to do it.
#pragma pack(push, before_imagehlp, 8)
diff --git a/platform/windows/detect.py b/platform/windows/detect.py
index 1b55574b19..ba8d27bba5 100644
--- a/platform/windows/detect.py
+++ b/platform/windows/detect.py
@@ -409,6 +409,9 @@ def configure_msvc(env, vcvars_msvc_config):
"wbemuuid",
]
+ if env.debug_features:
+ LIBS += ["psapi", "dbghelp"]
+
if env["vulkan"]:
env.AppendUnique(CPPDEFINES=["VULKAN_ENABLED"])
if not env["use_volk"]:
@@ -587,6 +590,9 @@ def configure_mingw(env):
]
)
+ if env.debug_features:
+ env.Append(LIBS=["psapi", "dbghelp"])
+
if env["vulkan"]:
env.Append(CPPDEFINES=["VULKAN_ENABLED"])
if not env["use_volk"]:
diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp
index 6ff928580a..4c2d7ee5cc 100644
--- a/platform/windows/display_server_windows.cpp
+++ b/platform/windows/display_server_windows.cpp
@@ -4406,5 +4406,4 @@ DisplayServerWindows::~DisplayServerWindows() {
if (tts) {
memdelete(tts);
}
- CoUninitialize();
}
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index 6e219fb929..456240ba2d 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -55,6 +55,12 @@
#include <shlobj.h>
#include <wbemcli.h>
+#ifdef DEBUG_ENABLED
+#pragma pack(push, before_imagehlp, 8)
+#include <imagehlp.h>
+#pragma pack(pop, before_imagehlp)
+#endif
+
extern "C" {
__declspec(dllexport) DWORD NvOptimusEnablement = 1;
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
@@ -88,7 +94,7 @@ static String format_error_message(DWORD id) {
LocalFree(messageBuffer);
- return msg;
+ return msg.replace("\r", "").replace("\n", "");
}
void RedirectStream(const char *p_file_name, const char *p_mode, FILE *p_cpp_stream, const DWORD p_std_handle) {
@@ -195,7 +201,6 @@ void OS_Windows::initialize() {
IPUnix::make_default();
main_loop = nullptr;
- CoInitialize(nullptr);
HRESULT hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), reinterpret_cast<IUnknown **>(&dwrite_factory));
if (SUCCEEDED(hr)) {
hr = dwrite_factory->GetSystemFontCollection(&font_collection, false);
@@ -277,6 +282,73 @@ Error OS_Windows::get_entropy(uint8_t *r_buffer, int p_bytes) {
return OK;
}
+#ifdef DEBUG_ENABLED
+void debug_dynamic_library_check_dependencies(const String &p_root_path, const String &p_path, HashSet<String> &r_checked, HashSet<String> &r_missing) {
+ if (r_checked.has(p_path)) {
+ return;
+ }
+ r_checked.insert(p_path);
+
+ LOADED_IMAGE loaded_image;
+ HANDLE file = CreateFileW((LPCWSTR)p_path.utf16().get_data(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr);
+ if (file != INVALID_HANDLE_VALUE) {
+ HANDLE file_mapping = CreateFileMappingW(file, nullptr, PAGE_READONLY | SEC_COMMIT, 0, 0, nullptr);
+ if (file_mapping != INVALID_HANDLE_VALUE) {
+ PVOID mapping = MapViewOfFile(file_mapping, FILE_MAP_READ, 0, 0, 0);
+ if (mapping) {
+ PIMAGE_DOS_HEADER dos_header = (PIMAGE_DOS_HEADER)mapping;
+ PIMAGE_NT_HEADERS nt_header = nullptr;
+ if (dos_header->e_magic == IMAGE_DOS_SIGNATURE) {
+ PCHAR nt_header_ptr;
+ nt_header_ptr = ((PCHAR)mapping) + dos_header->e_lfanew;
+ nt_header = (PIMAGE_NT_HEADERS)nt_header_ptr;
+ if (nt_header->Signature != IMAGE_NT_SIGNATURE) {
+ nt_header = nullptr;
+ }
+ }
+ if (nt_header) {
+ loaded_image.ModuleName = nullptr;
+ loaded_image.hFile = file;
+ loaded_image.MappedAddress = (PUCHAR)mapping;
+ loaded_image.FileHeader = nt_header;
+ loaded_image.Sections = (PIMAGE_SECTION_HEADER)((LPBYTE)&nt_header->OptionalHeader + nt_header->FileHeader.SizeOfOptionalHeader);
+ loaded_image.NumberOfSections = nt_header->FileHeader.NumberOfSections;
+ loaded_image.SizeOfImage = GetFileSize(file, nullptr);
+ loaded_image.Characteristics = nt_header->FileHeader.Characteristics;
+ loaded_image.LastRvaSection = loaded_image.Sections;
+ loaded_image.fSystemImage = false;
+ loaded_image.fDOSImage = false;
+ loaded_image.Links.Flink = &loaded_image.Links;
+ loaded_image.Links.Blink = &loaded_image.Links;
+
+ ULONG size = 0;
+ const IMAGE_IMPORT_DESCRIPTOR *import_desc = (const IMAGE_IMPORT_DESCRIPTOR *)ImageDirectoryEntryToData((HMODULE)loaded_image.MappedAddress, false, IMAGE_DIRECTORY_ENTRY_IMPORT, &size);
+ if (import_desc) {
+ for (; import_desc->Name && import_desc->FirstThunk; import_desc++) {
+ char16_t full_name_wc[MAX_PATH];
+ const char *name_cs = (const char *)ImageRvaToVa(loaded_image.FileHeader, loaded_image.MappedAddress, import_desc->Name, 0);
+ String name = String(name_cs);
+ if (name.begins_with("api-ms-win-")) {
+ r_checked.insert(name);
+ } else if (SearchPathW(nullptr, (LPCWSTR)name.utf16().get_data(), nullptr, MAX_PATH, (LPWSTR)full_name_wc, nullptr)) {
+ debug_dynamic_library_check_dependencies(p_root_path, String::utf16(full_name_wc), r_checked, r_missing);
+ } else if (SearchPathW((LPCWSTR)(p_path.get_base_dir().utf16().get_data()), (LPCWSTR)name.utf16().get_data(), nullptr, MAX_PATH, (LPWSTR)full_name_wc, nullptr)) {
+ debug_dynamic_library_check_dependencies(p_root_path, String::utf16(full_name_wc), r_checked, r_missing);
+ } else {
+ r_missing.insert(name);
+ }
+ }
+ }
+ }
+ UnmapViewOfFile(mapping);
+ }
+ CloseHandle(file_mapping);
+ }
+ CloseHandle(file);
+ }
+}
+#endif
+
Error OS_Windows::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path, String *r_resolved_path) {
String path = p_path.replace("/", "\\");
@@ -299,7 +371,29 @@ Error OS_Windows::open_dynamic_library(const String p_path, void *&p_library_han
}
p_library_handle = (void *)LoadLibraryExW((LPCWSTR)(path.utf16().get_data()), nullptr, (p_also_set_library_path && has_dll_directory_api) ? LOAD_LIBRARY_SEARCH_DEFAULT_DIRS : 0);
- ERR_FAIL_COND_V_MSG(!p_library_handle, ERR_CANT_OPEN, "Can't open dynamic library: " + p_path + ", error: " + format_error_message(GetLastError()) + ".");
+#ifdef DEBUG_ENABLED
+ if (!p_library_handle) {
+ DWORD err_code = GetLastError();
+
+ HashSet<String> checekd_libs;
+ HashSet<String> missing_libs;
+ debug_dynamic_library_check_dependencies(path, path, checekd_libs, missing_libs);
+ if (!missing_libs.is_empty()) {
+ String missing;
+ for (const String &E : missing_libs) {
+ if (!missing.is_empty()) {
+ missing += ", ";
+ }
+ missing += E;
+ }
+ ERR_FAIL_V_MSG(ERR_CANT_OPEN, vformat("Can't open dynamic library: %s, missing dependencies: (%s), error: \"%s\".", p_path, missing, format_error_message(err_code)));
+ } else {
+ ERR_FAIL_V_MSG(ERR_CANT_OPEN, vformat("Can't open dynamic library: %s, error: \"%s\"." + p_path, format_error_message(err_code)));
+ }
+ }
+#else
+ ERR_FAIL_COND_V_MSG(!p_library_handle, ERR_CANT_OPEN, vformat("Can't open dynamic library: %s, error: \"%s\"." + p_path, format_error_message(GetLastError())));
+#endif
if (cookie) {
remove_dll_directory(cookie);
@@ -323,7 +417,7 @@ Error OS_Windows::get_dynamic_library_symbol_handle(void *p_library_handle, cons
p_symbol_handle = (void *)GetProcAddress((HMODULE)p_library_handle, p_name.utf8().get_data());
if (!p_symbol_handle) {
if (!p_optional) {
- ERR_FAIL_V_MSG(ERR_CANT_RESOLVE, "Can't resolve symbol " + p_name + ", error: " + String::num(GetLastError()) + ".");
+ ERR_FAIL_V_MSG(ERR_CANT_RESOLVE, vformat("Can't resolve symbol %s, error: \"%s\".", p_name, format_error_message(GetLastError())));
} else {
return ERR_CANT_RESOLVE;
}
@@ -373,8 +467,6 @@ Vector<String> OS_Windows::get_video_adapter_driver_info() const {
return Vector<String>();
}
- CoInitialize(nullptr);
-
HRESULT hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, uuid, (LPVOID *)&wbemLocator);
if (hr != S_OK) {
return Vector<String>();
@@ -1505,6 +1597,8 @@ Error OS_Windows::move_to_trash(const String &p_path) {
OS_Windows::OS_Windows(HINSTANCE _hInstance) {
hInstance = _hInstance;
+ CoInitializeEx(nullptr, COINIT_MULTITHREADED);
+
#ifdef WASAPI_ENABLED
AudioDriverManager::add_driver(&driver_wasapi);
#endif
@@ -1532,4 +1626,5 @@ OS_Windows::OS_Windows(HINSTANCE _hInstance) {
}
OS_Windows::~OS_Windows() {
+ CoUninitialize();
}
diff --git a/platform/windows/tts_windows.cpp b/platform/windows/tts_windows.cpp
index 54ab93ee01..907096d890 100644
--- a/platform/windows/tts_windows.cpp
+++ b/platform/windows/tts_windows.cpp
@@ -118,7 +118,7 @@ bool TTS_Windows::is_speaking() const {
SPVOICESTATUS status;
synth->GetStatus(&status, nullptr);
- return (status.dwRunningState == SPRS_IS_SPEAKING);
+ return (status.dwRunningState == SPRS_IS_SPEAKING || status.dwRunningState == 0 /* Waiting To Speak */);
}
bool TTS_Windows::is_paused() const {
@@ -251,7 +251,6 @@ TTS_Windows *TTS_Windows::get_singleton() {
TTS_Windows::TTS_Windows() {
singleton = this;
- CoInitialize(nullptr);
if (SUCCEEDED(CoCreateInstance(CLSID_SpVoice, nullptr, CLSCTX_ALL, IID_ISpVoice, (void **)&synth))) {
ULONGLONG event_mask = SPFEI(SPEI_END_INPUT_STREAM) | SPFEI(SPEI_START_INPUT_STREAM) | SPFEI(SPEI_WORD_BOUNDARY);