summaryrefslogtreecommitdiffstats
path: root/platform
diff options
context:
space:
mode:
Diffstat (limited to 'platform')
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/Godot.java5
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/utils/GodotNetUtils.java38
-rw-r--r--platform/android/java_godot_wrapper.cpp12
-rw-r--r--platform/android/java_godot_wrapper.h2
-rw-r--r--platform/android/os_android.cpp4
-rw-r--r--platform/android/os_android.h1
-rw-r--r--platform/ios/ios.mm18
-rw-r--r--platform/linuxbsd/freedesktop_portal_desktop.cpp5
-rw-r--r--platform/linuxbsd/freedesktop_screensaver.cpp5
-rw-r--r--platform/linuxbsd/joypad_linux.cpp48
-rw-r--r--platform/linuxbsd/os_linuxbsd.cpp40
-rw-r--r--platform/linuxbsd/os_linuxbsd.h2
-rw-r--r--platform/linuxbsd/x11/detect_prime_x11.cpp3
-rw-r--r--platform/linuxbsd/x11/display_server_x11.cpp22
-rw-r--r--platform/linuxbsd/x11/display_server_x11.h2
-rw-r--r--platform/linuxbsd/x11/gl_manager_x11.cpp3
-rw-r--r--platform/macos/detect.py2
-rw-r--r--platform/macos/display_server_macos.mm10
-rw-r--r--platform/macos/os_macos.h2
-rw-r--r--platform/macos/os_macos.mm29
-rw-r--r--platform/windows/detect.py2
-rw-r--r--platform/windows/os_windows.cpp45
-rw-r--r--platform/windows/os_windows.h2
23 files changed, 258 insertions, 44 deletions
diff --git a/platform/android/java/lib/src/org/godotengine/godot/Godot.java b/platform/android/java/lib/src/org/godotengine/godot/Godot.java
index e111bd18ca..99527ccf3a 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/Godot.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.java
@@ -1044,6 +1044,11 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
return PermissionsUtil.getGrantedPermissions(getActivity());
}
+ @Keep
+ private String getCACertificates() {
+ return GodotNetUtils.getCACertificates();
+ }
+
/**
* The download state should trigger changes in the UI --- it may be useful
* to show the state as being indeterminate at times. This sample can be
diff --git a/platform/android/java/lib/src/org/godotengine/godot/utils/GodotNetUtils.java b/platform/android/java/lib/src/org/godotengine/godot/utils/GodotNetUtils.java
index 401c105cd7..c31d56a3e1 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/utils/GodotNetUtils.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/utils/GodotNetUtils.java
@@ -33,11 +33,17 @@ package org.godotengine.godot.utils;
import android.app.Activity;
import android.content.Context;
import android.net.wifi.WifiManager;
+import android.util.Base64;
import android.util.Log;
+import java.io.StringWriter;
+import java.security.KeyStore;
+import java.security.cert.X509Certificate;
+import java.util.Enumeration;
+
/**
* This class handles Android-specific networking functions.
- * For now, it only provides access to WifiManager.MulticastLock, which is needed on some devices
+ * It provides access to the CA certificates KeyStore, and the WifiManager.MulticastLock, which is needed on some devices
* to receive broadcast and multicast packets.
*/
public class GodotNetUtils {
@@ -79,4 +85,34 @@ public class GodotNetUtils {
Log.e("Godot", "Exception during multicast lock release: " + e);
}
}
+
+ /**
+ * Retrieves the list of trusted CA certificates from the "AndroidCAStore" and returns them in PRM format.
+ * @see https://developer.android.com/reference/java/security/KeyStore .
+ * @return A string of concatenated X509 certificates in PEM format.
+ */
+ public static String getCACertificates() {
+ try {
+ KeyStore ks = KeyStore.getInstance("AndroidCAStore");
+ StringBuilder writer = new StringBuilder();
+
+ if (ks != null) {
+ ks.load(null, null);
+ Enumeration<String> aliases = ks.aliases();
+
+ while (aliases.hasMoreElements()) {
+ String alias = (String)aliases.nextElement();
+
+ X509Certificate cert = (X509Certificate)ks.getCertificate(alias);
+ writer.append("-----BEGIN CERTIFICATE-----\n");
+ writer.append(Base64.encodeToString(cert.getEncoded(), Base64.DEFAULT));
+ writer.append("-----END CERTIFICATE-----\n");
+ }
+ }
+ return writer.toString();
+ } catch (Exception e) {
+ Log.e("Godot", "Exception while reading CA certificates: " + e);
+ return "";
+ }
+ }
}
diff --git a/platform/android/java_godot_wrapper.cpp b/platform/android/java_godot_wrapper.cpp
index 9d9d087896..2b504ad69b 100644
--- a/platform/android/java_godot_wrapper.cpp
+++ b/platform/android/java_godot_wrapper.cpp
@@ -70,6 +70,7 @@ GodotJavaWrapper::GodotJavaWrapper(JNIEnv *p_env, jobject p_activity, jobject p_
_request_permission = p_env->GetMethodID(godot_class, "requestPermission", "(Ljava/lang/String;)Z");
_request_permissions = p_env->GetMethodID(godot_class, "requestPermissions", "()Z");
_get_granted_permissions = p_env->GetMethodID(godot_class, "getGrantedPermissions", "()[Ljava/lang/String;");
+ _get_ca_certificates = p_env->GetMethodID(godot_class, "getCACertificates", "()Ljava/lang/String;");
_init_input_devices = p_env->GetMethodID(godot_class, "initInputDevices", "()V");
_get_surface = p_env->GetMethodID(godot_class, "getSurface", "()Landroid/view/Surface;");
_is_activity_resumed = p_env->GetMethodID(godot_class, "isActivityResumed", "()Z");
@@ -310,6 +311,17 @@ Vector<String> GodotJavaWrapper::get_granted_permissions() const {
return permissions_list;
}
+String GodotJavaWrapper::get_ca_certificates() const {
+ if (_get_ca_certificates) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_NULL_V(env, String());
+ jstring s = (jstring)env->CallObjectMethod(godot_instance, _get_ca_certificates);
+ return jstring_to_string(s, env);
+ } else {
+ return String();
+ }
+}
+
void GodotJavaWrapper::init_input_devices() {
if (_init_input_devices) {
JNIEnv *env = get_jni_env();
diff --git a/platform/android/java_godot_wrapper.h b/platform/android/java_godot_wrapper.h
index 1bd79584d8..05144380e6 100644
--- a/platform/android/java_godot_wrapper.h
+++ b/platform/android/java_godot_wrapper.h
@@ -60,6 +60,7 @@ private:
jmethodID _request_permission = nullptr;
jmethodID _request_permissions = nullptr;
jmethodID _get_granted_permissions = nullptr;
+ jmethodID _get_ca_certificates = nullptr;
jmethodID _init_input_devices = nullptr;
jmethodID _get_surface = nullptr;
jmethodID _is_activity_resumed = nullptr;
@@ -98,6 +99,7 @@ public:
bool request_permission(const String &p_name);
bool request_permissions();
Vector<String> get_granted_permissions() const;
+ String get_ca_certificates() const;
void init_input_devices();
jobject get_surface();
bool is_activity_resumed();
diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp
index 1ea742dc6d..73081e35e7 100644
--- a/platform/android/os_android.cpp
+++ b/platform/android/os_android.cpp
@@ -757,6 +757,10 @@ Error OS_Android::kill(const ProcessID &p_pid) {
return OS_Unix::kill(p_pid);
}
+String OS_Android::get_system_ca_certificates() {
+ return godot_java->get_ca_certificates();
+}
+
Error OS_Android::setup_remote_filesystem(const String &p_server_host, int p_port, const String &p_password, String &r_project_path) {
r_project_path = get_user_data_dir();
Error err = OS_Unix::setup_remote_filesystem(p_server_host, p_port, p_password, r_project_path);
diff --git a/platform/android/os_android.h b/platform/android/os_android.h
index 902712d69e..f1d08b7cfe 100644
--- a/platform/android/os_android.h
+++ b/platform/android/os_android.h
@@ -160,6 +160,7 @@ public:
virtual Error create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id = nullptr, bool p_open_console = false) override;
virtual Error create_instance(const List<String> &p_arguments, ProcessID *r_child_id = nullptr) override;
virtual Error kill(const ProcessID &p_pid) override;
+ virtual String get_system_ca_certificates() override;
virtual Error setup_remote_filesystem(const String &p_server_host, int p_port, const String &p_password, String &r_project_path) override;
diff --git a/platform/ios/ios.mm b/platform/ios/ios.mm
index 1065f5fd2a..c911a512a5 100644
--- a/platform/ios/ios.mm
+++ b/platform/ios/ios.mm
@@ -72,8 +72,8 @@ CHHapticEngine *iOS::get_haptic_engine_instance() API_AVAILABLE(ios(13)) {
void iOS::vibrate_haptic_engine(float p_duration_seconds) API_AVAILABLE(ios(13)) {
if (@available(iOS 13, *)) { // We need the @available check every time to make the compiler happy...
if (supports_haptic_engine()) {
- CHHapticEngine *haptic_engine = get_haptic_engine_instance();
- if (haptic_engine) {
+ CHHapticEngine *cur_haptic_engine = get_haptic_engine_instance();
+ if (cur_haptic_engine) {
NSDictionary *hapticDict = @{
CHHapticPatternKeyPattern : @[
@{CHHapticPatternKeyEvent : @{
@@ -88,7 +88,7 @@ void iOS::vibrate_haptic_engine(float p_duration_seconds) API_AVAILABLE(ios(13))
NSError *error;
CHHapticPattern *pattern = [[CHHapticPattern alloc] initWithDictionary:hapticDict error:&error];
- [[haptic_engine createPlayerWithPattern:pattern error:&error] startAtTime:0 error:&error];
+ [[cur_haptic_engine createPlayerWithPattern:pattern error:&error] startAtTime:0 error:&error];
NSLog(@"Could not vibrate using haptic engine: %@", error);
}
@@ -103,9 +103,9 @@ void iOS::vibrate_haptic_engine(float p_duration_seconds) API_AVAILABLE(ios(13))
void iOS::start_haptic_engine() {
if (@available(iOS 13, *)) {
if (supports_haptic_engine()) {
- CHHapticEngine *haptic_engine = get_haptic_engine_instance();
- if (haptic_engine) {
- [haptic_engine startWithCompletionHandler:^(NSError *returnedError) {
+ CHHapticEngine *cur_haptic_engine = get_haptic_engine_instance();
+ if (cur_haptic_engine) {
+ [cur_haptic_engine startWithCompletionHandler:^(NSError *returnedError) {
if (returnedError) {
NSLog(@"Could not start haptic engine: %@", returnedError);
}
@@ -122,9 +122,9 @@ void iOS::start_haptic_engine() {
void iOS::stop_haptic_engine() {
if (@available(iOS 13, *)) {
if (supports_haptic_engine()) {
- CHHapticEngine *haptic_engine = get_haptic_engine_instance();
- if (haptic_engine) {
- [haptic_engine stopWithCompletionHandler:^(NSError *returnedError) {
+ CHHapticEngine *cur_haptic_engine = get_haptic_engine_instance();
+ if (cur_haptic_engine) {
+ [cur_haptic_engine stopWithCompletionHandler:^(NSError *returnedError) {
if (returnedError) {
NSLog(@"Could not stop haptic engine: %@", returnedError);
}
diff --git a/platform/linuxbsd/freedesktop_portal_desktop.cpp b/platform/linuxbsd/freedesktop_portal_desktop.cpp
index b45b7e676d..6dfa8ed93c 100644
--- a/platform/linuxbsd/freedesktop_portal_desktop.cpp
+++ b/platform/linuxbsd/freedesktop_portal_desktop.cpp
@@ -138,6 +138,11 @@ FreeDesktopPortalDesktop::FreeDesktopPortalDesktop() {
#else
unsupported = false;
#endif
+
+ if (unsupported) {
+ return;
+ }
+
bool ver_ok = false;
int version_major = 0;
int version_minor = 0;
diff --git a/platform/linuxbsd/freedesktop_screensaver.cpp b/platform/linuxbsd/freedesktop_screensaver.cpp
index 78f2337599..cf179b5735 100644
--- a/platform/linuxbsd/freedesktop_screensaver.cpp
+++ b/platform/linuxbsd/freedesktop_screensaver.cpp
@@ -141,6 +141,11 @@ FreeDesktopScreenSaver::FreeDesktopScreenSaver() {
#else
unsupported = false;
#endif
+
+ if (unsupported) {
+ return;
+ }
+
bool ver_ok = false;
int version_major = 0;
int version_minor = 0;
diff --git a/platform/linuxbsd/joypad_linux.cpp b/platform/linuxbsd/joypad_linux.cpp
index 5c623b8ba2..a9725fff2e 100644
--- a/platform/linuxbsd/joypad_linux.cpp
+++ b/platform/linuxbsd/joypad_linux.cpp
@@ -32,6 +32,8 @@
#include "joypad_linux.h"
+#include "core/os/os.h"
+
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
@@ -72,6 +74,26 @@ void JoypadLinux::Joypad::reset() {
events.clear();
}
+// This function is derived from SDL:
+// https://github.com/libsdl-org/SDL/blob/main/src/core/linux/SDL_sandbox.c#L28-L45
+static bool detect_sandbox() {
+ if (access("/.flatpak-info", F_OK) == 0) {
+ return true;
+ }
+
+ // For Snap, we check multiple variables because they might be set for
+ // unrelated reasons. This is the same thing WebKitGTK does.
+ if (OS::get_singleton()->has_environment("SNAP") && OS::get_singleton()->has_environment("SNAP_NAME") && OS::get_singleton()->has_environment("SNAP_REVISION")) {
+ return true;
+ }
+
+ if (access("/run/host/container-manager", F_OK) == 0) {
+ return true;
+ }
+
+ return false;
+}
+
JoypadLinux::JoypadLinux(Input *in) {
#ifdef UDEV_ENABLED
#ifdef SOWRAP_ENABLED
@@ -80,17 +102,25 @@ JoypadLinux::JoypadLinux(Input *in) {
#else
int dylibloader_verbose = 0;
#endif
- use_udev = initialize_libudev(dylibloader_verbose) == 0;
- if (use_udev) {
- 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!");
+ if (detect_sandbox()) {
+ // Linux binaries in sandboxes / containers need special handling because
+ // libudev doesn't work there. So we need to fallback to manual parsing
+ // of /dev/input in such case.
+ use_udev = false;
+ print_verbose("JoypadLinux: udev enabled, but detected incompatible sandboxed mode. Falling back to /dev/input to detect joypads.");
+ } else {
+ use_udev = initialize_libudev(dylibloader_verbose) == 0;
+ if (use_udev) {
+ 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 and loaded successfully.");
+ print_verbose("JoypadLinux: udev enabled, but couldn't be loaded. Falling back to /dev/input to detect joypads.");
}
- } else {
- print_verbose("JoypadLinux: udev enabled, but couldn't be loaded. Falling back to /dev/input to detect joypads.");
}
#endif
#else
diff --git a/platform/linuxbsd/os_linuxbsd.cpp b/platform/linuxbsd/os_linuxbsd.cpp
index 82500f83cb..8d8c8ce27b 100644
--- a/platform/linuxbsd/os_linuxbsd.cpp
+++ b/platform/linuxbsd/os_linuxbsd.cpp
@@ -30,6 +30,7 @@
#include "os_linuxbsd.h"
+#include "core/io/certs_compressed.gen.h"
#include "core/io/dir_access.h"
#include "main/main.h"
#include "servers/display_server.h"
@@ -494,6 +495,11 @@ bool OS_LinuxBSD::_check_internal_feature_support(const String &p_feature) {
return true;
}
+ // Match against the specific OS (linux, freebsd, etc).
+ if (p_feature == get_name().to_lower()) {
+ return true;
+ }
+
return false;
}
@@ -1080,6 +1086,40 @@ Error OS_LinuxBSD::move_to_trash(const String &p_path) {
return OK;
}
+String OS_LinuxBSD::get_system_ca_certificates() {
+ String certfile;
+ Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
+
+ // Compile time preferred certificates path.
+ if (!String(_SYSTEM_CERTS_PATH).is_empty() && da->file_exists(_SYSTEM_CERTS_PATH)) {
+ certfile = _SYSTEM_CERTS_PATH;
+ } else if (da->file_exists("/etc/ssl/certs/ca-certificates.crt")) {
+ // Debian/Ubuntu
+ certfile = "/etc/ssl/certs/ca-certificates.crt";
+ } else if (da->file_exists("/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem")) {
+ // Fedora
+ certfile = "/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem";
+ } else if (da->file_exists("/etc/ca-certificates/extracted/tls-ca-bundle.pem")) {
+ // Arch Linux
+ certfile = "/etc/ca-certificates/extracted/tls-ca-bundle.pem";
+ } else if (da->file_exists("/var/lib/ca-certificates/ca-bundle.pem")) {
+ // openSUSE
+ certfile = "/var/lib/ca-certificates/ca-bundle.pem";
+ } else if (da->file_exists("/etc/ssl/cert.pem")) {
+ // FreeBSD/OpenBSD
+ certfile = "/etc/ssl/cert.pem";
+ }
+
+ if (certfile.is_empty()) {
+ return "";
+ }
+
+ Ref<FileAccess> f = FileAccess::open(certfile, FileAccess::READ);
+ ERR_FAIL_COND_V_MSG(f.is_null(), "", vformat("Failed to open system CA certificates file: '%s'", certfile));
+
+ return f->get_as_text();
+}
+
OS_LinuxBSD::OS_LinuxBSD() {
main_loop = nullptr;
diff --git a/platform/linuxbsd/os_linuxbsd.h b/platform/linuxbsd/os_linuxbsd.h
index 8dda06b6df..c1e735b0d4 100644
--- a/platform/linuxbsd/os_linuxbsd.h
+++ b/platform/linuxbsd/os_linuxbsd.h
@@ -133,6 +133,8 @@ public:
virtual Error move_to_trash(const String &p_path) override;
+ virtual String get_system_ca_certificates() override;
+
OS_LinuxBSD();
~OS_LinuxBSD();
};
diff --git a/platform/linuxbsd/x11/detect_prime_x11.cpp b/platform/linuxbsd/x11/detect_prime_x11.cpp
index 3d07be1c76..78778a8b56 100644
--- a/platform/linuxbsd/x11/detect_prime_x11.cpp
+++ b/platform/linuxbsd/x11/detect_prime_x11.cpp
@@ -60,6 +60,9 @@
typedef GLXContext (*GLXCREATECONTEXTATTRIBSARBPROC)(Display *, GLXFBConfig, GLXContext, Bool, const int *);
+// To prevent shadowing warnings
+#undef glGetString
+
struct vendor {
const char *glxvendor = nullptr;
int priority = 0;
diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp
index 043a18349f..13f261aa43 100644
--- a/platform/linuxbsd/x11/display_server_x11.cpp
+++ b/platform/linuxbsd/x11/display_server_x11.cpp
@@ -2725,8 +2725,8 @@ void DisplayServerX11::cursor_set_custom_image(const Ref<Resource> &p_cursor, Cu
XcursorImageDestroy(cursor_image);
} else {
// Reset to default system cursor
- if (img[p_shape]) {
- cursors[p_shape] = XcursorImageLoadCursor(x11_display, img[p_shape]);
+ if (cursor_img[p_shape]) {
+ cursors[p_shape] = XcursorImageLoadCursor(x11_display, cursor_img[p_shape]);
}
CursorShape c = current_cursor;
@@ -5360,7 +5360,7 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
for (int i = 0; i < CURSOR_MAX; i++) {
cursors[i] = None;
- img[i] = nullptr;
+ cursor_img[i] = nullptr;
}
XInitThreads(); //always use threads
@@ -5717,8 +5717,8 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
"question_arrow"
};
- img[i] = XcursorLibraryLoadImage(cursor_file[i], cursor_theme, cursor_size);
- if (!img[i]) {
+ cursor_img[i] = XcursorLibraryLoadImage(cursor_file[i], cursor_theme, cursor_size);
+ if (!cursor_img[i]) {
const char *fallback = nullptr;
switch (i) {
@@ -5756,7 +5756,7 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
fallback = "bd_double_arrow";
break;
case CURSOR_MOVE:
- img[i] = img[CURSOR_DRAG];
+ cursor_img[i] = cursor_img[CURSOR_DRAG];
break;
case CURSOR_VSPLIT:
fallback = "sb_v_double_arrow";
@@ -5769,11 +5769,11 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
break;
}
if (fallback != nullptr) {
- img[i] = XcursorLibraryLoadImage(fallback, cursor_theme, cursor_size);
+ cursor_img[i] = XcursorLibraryLoadImage(fallback, cursor_theme, cursor_size);
}
}
- if (img[i]) {
- cursors[i] = XcursorImageLoadCursor(x11_display, img[i]);
+ if (cursor_img[i]) {
+ cursors[i] = XcursorImageLoadCursor(x11_display, cursor_img[i]);
} else {
print_verbose("Failed loading custom cursor: " + String(cursor_file[i]));
}
@@ -5912,8 +5912,8 @@ DisplayServerX11::~DisplayServerX11() {
if (cursors[i] != None) {
XFreeCursor(x11_display, cursors[i]);
}
- if (img[i] != nullptr) {
- XcursorImageDestroy(img[i]);
+ if (cursor_img[i] != nullptr) {
+ XcursorImageDestroy(cursor_img[i]);
}
}
diff --git a/platform/linuxbsd/x11/display_server_x11.h b/platform/linuxbsd/x11/display_server_x11.h
index 67fa21c75f..6d343be3ab 100644
--- a/platform/linuxbsd/x11/display_server_x11.h
+++ b/platform/linuxbsd/x11/display_server_x11.h
@@ -306,7 +306,7 @@ class DisplayServerX11 : public DisplayServer {
const char *cursor_theme = nullptr;
int cursor_size = 0;
- XcursorImage *img[CURSOR_MAX];
+ XcursorImage *cursor_img[CURSOR_MAX];
Cursor cursors[CURSOR_MAX];
Cursor null_cursor;
CursorShape current_cursor = CURSOR_ARROW;
diff --git a/platform/linuxbsd/x11/gl_manager_x11.cpp b/platform/linuxbsd/x11/gl_manager_x11.cpp
index ee767dfa80..1e579c9f01 100644
--- a/platform/linuxbsd/x11/gl_manager_x11.cpp
+++ b/platform/linuxbsd/x11/gl_manager_x11.cpp
@@ -44,6 +44,9 @@
typedef GLXContext (*GLXCREATECONTEXTATTRIBSARBPROC)(Display *, GLXFBConfig, GLXContext, Bool, const int *);
+// To prevent shadowing warnings
+#undef glXCreateContextAttribsARB
+
struct GLManager_X11_Private {
::GLXContext glx_context;
};
diff --git a/platform/macos/detect.py b/platform/macos/detect.py
index 1fefdb3c68..7b8d3fd853 100644
--- a/platform/macos/detect.py
+++ b/platform/macos/detect.py
@@ -235,6 +235,8 @@ def configure(env: "Environment"):
"CoreMedia",
"-framework",
"QuartzCore",
+ "-framework",
+ "Security",
]
)
env.Append(LIBS=["pthread", "z"])
diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm
index 5a7c309448..32f9441484 100644
--- a/platform/macos/display_server_macos.mm
+++ b/platform/macos/display_server_macos.mm
@@ -1840,9 +1840,9 @@ Error DisplayServerMacOS::dialog_show(String p_title, String p_description, Vect
if (!p_callback.is_null()) {
Variant button = button_pressed;
Variant *buttonp = &button;
- Variant ret;
+ Variant fun_ret;
Callable::CallError ce;
- p_callback.callp((const Variant **)&buttonp, 1, ret, ce);
+ p_callback.callp((const Variant **)&buttonp, 1, fun_ret, ce);
}
return OK;
@@ -1872,9 +1872,9 @@ Error DisplayServerMacOS::dialog_input_text(String p_title, String p_description
if (!p_callback.is_null()) {
Variant text = ret;
Variant *textp = &text;
- Variant ret;
+ Variant fun_ret;
Callable::CallError ce;
- p_callback.callp((const Variant **)&textp, 1, ret, ce);
+ p_callback.callp((const Variant **)&textp, 1, fun_ret, ce);
}
return OK;
@@ -1897,7 +1897,7 @@ void DisplayServerMacOS::mouse_set_mode(MouseMode p_mode) {
bool previously_shown = (mouse_mode == MOUSE_MODE_VISIBLE || mouse_mode == MOUSE_MODE_CONFINED);
if (show_cursor && !previously_shown) {
- WindowID window_id = get_window_at_screen_position(mouse_get_position());
+ window_id = get_window_at_screen_position(mouse_get_position());
if (window_id != INVALID_WINDOW_ID) {
send_window_event(windows[window_id], WINDOW_EVENT_MOUSE_ENTER);
}
diff --git a/platform/macos/os_macos.h b/platform/macos/os_macos.h
index eb7a30203a..07bae479be 100644
--- a/platform/macos/os_macos.h
+++ b/platform/macos/os_macos.h
@@ -119,6 +119,8 @@ public:
virtual Error move_to_trash(const String &p_path) override;
+ virtual String get_system_ca_certificates() override;
+
void run();
OS_MacOS();
diff --git a/platform/macos/os_macos.mm b/platform/macos/os_macos.mm
index 74cdef6f25..838ae742fd 100644
--- a/platform/macos/os_macos.mm
+++ b/platform/macos/os_macos.mm
@@ -30,6 +30,7 @@
#include "os_macos.h"
+#include "core/crypto/crypto_core.h"
#include "core/version_generated.gen.h"
#include "main/main.h"
@@ -671,6 +672,34 @@ Error OS_MacOS::move_to_trash(const String &p_path) {
return OK;
}
+String OS_MacOS::get_system_ca_certificates() {
+ CFArrayRef result;
+ SecCertificateRef item;
+ CFDataRef der;
+
+ OSStatus ret = SecTrustCopyAnchorCertificates(&result);
+ ERR_FAIL_COND_V(ret != noErr, "");
+
+ CFIndex l = CFArrayGetCount(result);
+ String certs;
+ PackedByteArray pba;
+ for (CFIndex i = 0; i < l; i++) {
+ item = (SecCertificateRef)CFArrayGetValueAtIndex(result, i);
+ der = SecCertificateCopyData(item);
+ int derlen = CFDataGetLength(der);
+ if (pba.size() < derlen * 3) {
+ pba.resize(derlen * 3);
+ }
+ size_t b64len = 0;
+ Error err = CryptoCore::b64_encode(pba.ptrw(), pba.size(), &b64len, (unsigned char *)CFDataGetBytePtr(der), derlen);
+ CFRelease(der);
+ ERR_CONTINUE(err != OK);
+ certs += "-----BEGIN CERTIFICATE-----\n" + String((char *)pba.ptr(), b64len) + "\n-----END CERTIFICATE-----\n";
+ }
+ CFRelease(result);
+ return certs;
+}
+
void OS_MacOS::run() {
if (!main_loop) {
return;
diff --git a/platform/windows/detect.py b/platform/windows/detect.py
index cd6d461a93..963f533d67 100644
--- a/platform/windows/detect.py
+++ b/platform/windows/detect.py
@@ -413,6 +413,7 @@ def configure_msvc(env, vcvars_msvc_config):
"dxguid",
"imm32",
"bcrypt",
+ "Crypt32",
"Avrt",
"dwmapi",
"dwrite",
@@ -592,6 +593,7 @@ def configure_mingw(env):
"ksuser",
"imm32",
"bcrypt",
+ "crypt32",
"avrt",
"uuid",
"dwmapi",
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index a13d6ed986..ae1649c75d 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -55,6 +55,7 @@
#include <regstr.h>
#include <shlobj.h>
#include <wbemcli.h>
+#include <wincrypt.h>
#ifdef DEBUG_ENABLED
#pragma pack(push, before_imagehlp, 8)
@@ -435,8 +436,6 @@ String OS_Windows::get_distribution_name() const {
}
String OS_Windows::get_version() const {
- typedef LONG NTSTATUS;
- typedef NTSTATUS(WINAPI * RtlGetVersionPtr)(PRTL_OSVERSIONINFOW);
RtlGetVersionPtr version_ptr = (RtlGetVersionPtr)GetProcAddress(GetModuleHandle("ntdll.dll"), "RtlGetVersion");
if (version_ptr != nullptr) {
RTL_OSVERSIONINFOW fow;
@@ -554,9 +553,9 @@ OS::DateTime OS_Windows::get_datetime(bool p_utc) const {
//Get DST information from Windows, but only if p_utc is false.
TIME_ZONE_INFORMATION info;
- bool daylight = false;
+ bool is_daylight = false;
if (!p_utc && GetTimeZoneInformation(&info) == TIME_ZONE_ID_DAYLIGHT) {
- daylight = true;
+ is_daylight = true;
}
DateTime dt;
@@ -567,20 +566,20 @@ OS::DateTime OS_Windows::get_datetime(bool p_utc) const {
dt.hour = systemtime.wHour;
dt.minute = systemtime.wMinute;
dt.second = systemtime.wSecond;
- dt.dst = daylight;
+ dt.dst = is_daylight;
return dt;
}
OS::TimeZoneInfo OS_Windows::get_time_zone_info() const {
TIME_ZONE_INFORMATION info;
- bool daylight = false;
+ bool is_daylight = false;
if (GetTimeZoneInformation(&info) == TIME_ZONE_ID_DAYLIGHT) {
- daylight = true;
+ is_daylight = true;
}
// Daylight Bias needs to be added to the bias if DST is in effect, or else it will not properly update.
TimeZoneInfo ret;
- if (daylight) {
+ if (is_daylight) {
ret.name = info.DaylightName;
ret.bias = info.Bias + info.DaylightBias;
} else {
@@ -1677,6 +1676,36 @@ Error OS_Windows::move_to_trash(const String &p_path) {
return OK;
}
+String OS_Windows::get_system_ca_certificates() {
+ HCERTSTORE cert_store = CertOpenSystemStoreA(0, "ROOT");
+ ERR_FAIL_COND_V_MSG(!cert_store, "", "Failed to read the root certificate store.");
+
+ FILETIME curr_time;
+ GetSystemTimeAsFileTime(&curr_time);
+
+ String certs;
+ PCCERT_CONTEXT curr = CertEnumCertificatesInStore(cert_store, nullptr);
+ while (curr) {
+ FILETIME ft;
+ DWORD size = sizeof(ft);
+ // Check if the certificate is disallowed.
+ if (CertGetCertificateContextProperty(curr, CERT_DISALLOWED_FILETIME_PROP_ID, &ft, &size) && CompareFileTime(&curr_time, &ft) != -1) {
+ curr = CertEnumCertificatesInStore(cert_store, curr);
+ continue;
+ }
+ // Encode and add to certificate list.
+ bool success = CryptBinaryToStringA(curr->pbCertEncoded, curr->cbCertEncoded, CRYPT_STRING_BASE64HEADER | CRYPT_STRING_NOCR, nullptr, &size);
+ ERR_CONTINUE(!success);
+ PackedByteArray pba;
+ pba.resize(size);
+ CryptBinaryToStringA(curr->pbCertEncoded, curr->cbCertEncoded, CRYPT_STRING_BASE64HEADER | CRYPT_STRING_NOCR, (char *)pba.ptrw(), &size);
+ certs += String((char *)pba.ptr(), size);
+ curr = CertEnumCertificatesInStore(cert_store, curr);
+ }
+ CertCloseStore(cert_store, 0);
+ return certs;
+}
+
OS_Windows::OS_Windows(HINSTANCE _hInstance) {
hInstance = _hInstance;
diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h
index 960c3f30a9..c5f95870b3 100644
--- a/platform/windows/os_windows.h
+++ b/platform/windows/os_windows.h
@@ -226,6 +226,8 @@ public:
virtual Error move_to_trash(const String &p_path) override;
+ virtual String get_system_ca_certificates() override;
+
void set_main_window(HWND p_main_window) { main_window = p_main_window; }
HINSTANCE get_hinstance() { return hInstance; }