summaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
Diffstat (limited to 'platform')
-rw-r--r--platform/android/SCsub8
-rw-r--r--platform/android/android_keys_utils.cpp4
-rw-r--r--platform/android/android_keys_utils.h8
-rw-r--r--platform/android/api/api.cpp4
-rw-r--r--platform/android/api/api.h4
-rw-r--r--platform/android/api/java_class_wrapper.h8
-rw-r--r--platform/android/api/jni_singleton.h6
-rw-r--r--platform/android/audio_driver_jandroid.cpp16
-rw-r--r--platform/android/audio_driver_jandroid.h4
-rw-r--r--platform/android/audio_driver_opensl.cpp6
-rw-r--r--platform/android/audio_driver_opensl.h16
-rw-r--r--platform/android/detect.py62
-rw-r--r--platform/android/dir_access_jandroid.cpp22
-rw-r--r--platform/android/dir_access_jandroid.h4
-rw-r--r--platform/android/display_server_android.cpp81
-rw-r--r--platform/android/display_server_android.h25
-rw-r--r--platform/android/export/export.cpp501
-rw-r--r--platform/android/export/export.h4
-rw-r--r--platform/android/export/gradle_export_util.h19
-rw-r--r--platform/android/file_access_android.cpp9
-rw-r--r--platform/android/file_access_android.h13
-rw-r--r--platform/android/file_access_jandroid.cpp197
-rw-r--r--platform/android/java/app/build.gradle2
-rw-r--r--platform/android/java/app/config.gradle5
-rw-r--r--platform/android/java/app/res/drawable/splash_drawable.xml2
-rw-r--r--platform/android/java/app/src/com/godot/game/GodotApp.java4
-rw-r--r--platform/android/java/lib/build.gradle4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/Dictionary.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/Godot.java9
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderService.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java17
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotIO.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotInstrumentation.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotLib.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java9
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java264
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/Joystick.java17
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java103
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginInfoProvider.java67
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginRegistry.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/plugin/SignalInfo.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/utils/Crypt.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/utils/GLUtils.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/utils/GodotNetUtils.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/vulkan/VkRenderer.kt4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/vulkan/VkSurfaceView.kt4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/vulkan/VkThread.kt4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/xr/XRMode.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrConfigChooser.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrContextFactory.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrWindowSurfaceFactory.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularFallbackConfigChooser.java4
-rw-r--r--platform/android/java/nativeSrcsConfigs/build.gradle2
-rw-r--r--platform/android/java_class_wrapper.cpp10
-rw-r--r--platform/android/java_godot_io_wrapper.cpp38
-rw-r--r--platform/android/java_godot_io_wrapper.h4
-rw-r--r--platform/android/java_godot_lib_jni.cpp22
-rw-r--r--platform/android/java_godot_lib_jni.h4
-rw-r--r--platform/android/java_godot_view_wrapper.cpp (renamed from platform/android/file_access_jandroid.h)79
-rw-r--r--platform/android/java_godot_view_wrapper.h (renamed from platform/uwp/thread_uwp.cpp)45
-rw-r--r--platform/android/java_godot_wrapper.cpp56
-rw-r--r--platform/android/java_godot_wrapper.h8
-rw-r--r--platform/android/jni_utils.cpp4
-rw-r--r--platform/android/jni_utils.h4
-rw-r--r--platform/android/net_socket_android.cpp10
-rw-r--r--platform/android/net_socket_android.h4
-rw-r--r--platform/android/os_android.cpp19
-rw-r--r--platform/android/os_android.h46
-rw-r--r--platform/android/platform_config.h4
-rw-r--r--platform/android/plugin/godot_plugin_config.h123
-rw-r--r--platform/android/plugin/godot_plugin_jni.cpp14
-rw-r--r--platform/android/plugin/godot_plugin_jni.h14
-rw-r--r--platform/android/string_android.h8
-rw-r--r--platform/android/thread_jandroid.cpp119
-rw-r--r--platform/android/thread_jandroid.h46
-rw-r--r--platform/android/vulkan/vulkan_context_android.cpp4
-rw-r--r--platform/android/vulkan/vulkan_context_android.h4
-rw-r--r--platform/iphone/app_delegate.h4
-rw-r--r--platform/iphone/app_delegate.mm4
-rw-r--r--platform/iphone/detect.py60
-rw-r--r--platform/iphone/device_metrics.h4
-rw-r--r--platform/iphone/device_metrics.m4
-rw-r--r--platform/iphone/display_layer.h4
-rw-r--r--platform/iphone/display_layer.mm6
-rw-r--r--platform/iphone/display_server_iphone.h6
-rw-r--r--platform/iphone/display_server_iphone.mm8
-rw-r--r--platform/iphone/export/export.cpp152
-rw-r--r--platform/iphone/export/export.h4
-rw-r--r--platform/iphone/godot_app_delegate.h4
-rw-r--r--platform/iphone/godot_app_delegate.m36
-rw-r--r--platform/iphone/godot_iphone.mm4
-rw-r--r--platform/iphone/godot_view.h12
-rw-r--r--platform/iphone/godot_view.mm13
-rw-r--r--platform/iphone/godot_view_gesture_recognizer.h4
-rw-r--r--platform/iphone/godot_view_gesture_recognizer.mm4
-rw-r--r--platform/iphone/godot_view_renderer.h4
-rw-r--r--platform/iphone/godot_view_renderer.mm4
-rw-r--r--platform/iphone/ios.h4
-rw-r--r--platform/iphone/ios.mm4
-rw-r--r--platform/iphone/joypad_iphone.h4
-rw-r--r--platform/iphone/joypad_iphone.mm4
-rw-r--r--platform/iphone/keyboard_input_view.h4
-rw-r--r--platform/iphone/keyboard_input_view.mm4
-rw-r--r--platform/iphone/main.m4
-rw-r--r--platform/iphone/native_video_view.h4
-rw-r--r--platform/iphone/native_video_view.m4
-rw-r--r--platform/iphone/os_iphone.h6
-rw-r--r--platform/iphone/os_iphone.mm14
-rw-r--r--platform/iphone/platform_config.h4
-rw-r--r--platform/iphone/plugin/godot_plugin_config.h129
-rw-r--r--platform/iphone/view_controller.h4
-rw-r--r--platform/iphone/view_controller.mm40
-rw-r--r--platform/iphone/vulkan_context_iphone.h4
-rw-r--r--platform/iphone/vulkan_context_iphone.mm4
-rw-r--r--platform/javascript/.eslintrc.engine.js1
-rw-r--r--platform/javascript/.eslintrc.libs.js3
-rw-r--r--platform/javascript/SCsub81
-rw-r--r--platform/javascript/api/api.cpp4
-rw-r--r--platform/javascript/api/api.h4
-rw-r--r--platform/javascript/api/javascript_eval.h4
-rw-r--r--platform/javascript/api/javascript_tools_editor_plugin.cpp13
-rw-r--r--platform/javascript/api/javascript_tools_editor_plugin.h8
-rw-r--r--platform/javascript/audio_driver_javascript.cpp18
-rw-r--r--platform/javascript/audio_driver_javascript.h6
-rw-r--r--platform/javascript/detect.py112
-rw-r--r--platform/javascript/display_server_javascript.cpp169
-rw-r--r--platform/javascript/display_server_javascript.h10
-rw-r--r--platform/javascript/dom_keys.inc4
-rw-r--r--platform/javascript/emscripten_helpers.py19
-rw-r--r--platform/javascript/export/export.cpp168
-rw-r--r--platform/javascript/export/export.h4
-rw-r--r--platform/javascript/godot_audio.h8
-rw-r--r--platform/javascript/godot_js.h23
-rw-r--r--platform/javascript/http_client.h.inc4
-rw-r--r--platform/javascript/http_client_javascript.cpp31
-rw-r--r--platform/javascript/http_request.h10
-rw-r--r--platform/javascript/javascript_eval.cpp4
-rw-r--r--platform/javascript/javascript_main.cpp15
-rw-r--r--platform/javascript/javascript_runtime.cpp (renamed from platform/uwp/thread_uwp.h)38
-rw-r--r--platform/javascript/js/engine/config.js100
-rw-r--r--platform/javascript/js/engine/engine.js223
-rw-r--r--platform/javascript/js/engine/utils.js2
-rw-r--r--platform/javascript/js/libs/audio.worklet.js4
-rw-r--r--platform/javascript/js/libs/library_godot_audio.js40
-rw-r--r--platform/javascript/js/libs/library_godot_display.js409
-rw-r--r--platform/javascript/js/libs/library_godot_editor_tools.js5
-rw-r--r--platform/javascript/js/libs/library_godot_eval.js5
-rw-r--r--platform/javascript/js/libs/library_godot_http_request.js43
-rw-r--r--platform/javascript/js/libs/library_godot_os.js51
-rw-r--r--platform/javascript/js/libs/library_godot_runtime.js4
-rw-r--r--platform/javascript/os_javascript.cpp42
-rw-r--r--platform/javascript/os_javascript.h9
-rw-r--r--platform/javascript/platform_config.h4
-rw-r--r--platform/linuxbsd/SCsub5
-rw-r--r--platform/linuxbsd/context_gl_x11.cpp4
-rw-r--r--platform/linuxbsd/context_gl_x11.h4
-rw-r--r--platform/linuxbsd/crash_handler_linuxbsd.cpp6
-rw-r--r--platform/linuxbsd/crash_handler_linuxbsd.h4
-rw-r--r--platform/linuxbsd/detect.py47
-rw-r--r--platform/linuxbsd/detect_prime_x11.cpp9
-rw-r--r--platform/linuxbsd/detect_prime_x11.h4
-rw-r--r--platform/linuxbsd/display_server_x11.cpp167
-rw-r--r--platform/linuxbsd/display_server_x11.h40
-rw-r--r--platform/linuxbsd/export/export.cpp4
-rw-r--r--platform/linuxbsd/export/export.h4
-rw-r--r--platform/linuxbsd/godot_linuxbsd.cpp4
-rw-r--r--platform/linuxbsd/joypad_linux.cpp80
-rw-r--r--platform/linuxbsd/joypad_linux.h26
-rw-r--r--platform/linuxbsd/key_mapping_x11.cpp4
-rw-r--r--platform/linuxbsd/key_mapping_x11.h4
-rw-r--r--platform/linuxbsd/libudev-so_wrap.c1013
-rw-r--r--platform/linuxbsd/libudev-so_wrap.h378
-rw-r--r--platform/linuxbsd/os_linuxbsd.cpp170
-rw-r--r--platform/linuxbsd/os_linuxbsd.h40
-rw-r--r--platform/linuxbsd/platform_config.h4
-rw-r--r--platform/linuxbsd/vulkan_context_x11.cpp4
-rw-r--r--platform/linuxbsd/vulkan_context_x11.h4
-rw-r--r--platform/osx/SCsub2
-rw-r--r--platform/osx/context_gl_osx.h4
-rw-r--r--platform/osx/context_gl_osx.mm4
-rw-r--r--platform/osx/crash_handler_osx.h4
-rw-r--r--platform/osx/crash_handler_osx.mm6
-rw-r--r--platform/osx/detect.py10
-rw-r--r--platform/osx/dir_access_osx.h4
-rw-r--r--platform/osx/dir_access_osx.mm4
-rw-r--r--platform/osx/display_server_osx.h19
-rw-r--r--platform/osx/display_server_osx.mm99
-rw-r--r--platform/osx/export/export.cpp53
-rw-r--r--platform/osx/export/export.h4
-rw-r--r--platform/osx/godot_main_osx.mm4
-rw-r--r--platform/osx/joypad_osx.cpp12
-rw-r--r--platform/osx/joypad_osx.h22
-rw-r--r--platform/osx/os_osx.h50
-rw-r--r--platform/osx/os_osx.mm12
-rw-r--r--platform/osx/platform_config.h4
-rw-r--r--platform/osx/vulkan_context_osx.h4
-rw-r--r--platform/osx/vulkan_context_osx.mm4
-rw-r--r--platform/register_platform_apis.h4
-rw-r--r--platform/server/detect.py41
-rw-r--r--platform/server/godot_server.cpp4
-rw-r--r--platform/server/os_server.cpp20
-rw-r--r--platform/server/os_server.h22
-rw-r--r--platform/server/platform_config.h4
-rw-r--r--platform/uwp/app.cpp4
-rw-r--r--platform/uwp/app.h4
-rw-r--r--platform/uwp/context_egl_uwp.cpp7
-rw-r--r--platform/uwp/context_egl_uwp.h4
-rw-r--r--platform/uwp/detect.py2
-rw-r--r--platform/uwp/export/export.cpp26
-rw-r--r--platform/uwp/export/export.h4
-rw-r--r--platform/uwp/joypad_uwp.cpp4
-rw-r--r--platform/uwp/joypad_uwp.h25
-rw-r--r--platform/uwp/os_uwp.cpp24
-rw-r--r--platform/uwp/os_uwp.h24
-rw-r--r--platform/uwp/platform_config.h4
-rw-r--r--platform/windows/SCsub2
-rw-r--r--platform/windows/context_gl_windows.cpp5
-rw-r--r--platform/windows/context_gl_windows.h4
-rw-r--r--platform/windows/crash_handler_windows.cpp6
-rw-r--r--platform/windows/crash_handler_windows.h4
-rw-r--r--platform/windows/detect.py36
-rw-r--r--platform/windows/display_server_windows.cpp215
-rw-r--r--platform/windows/display_server_windows.h32
-rw-r--r--platform/windows/export/export.cpp12
-rw-r--r--platform/windows/export/export.h4
-rw-r--r--platform/windows/godot.natvis60
-rw-r--r--platform/windows/godot_windows.cpp4
-rw-r--r--platform/windows/joypad_windows.cpp6
-rw-r--r--platform/windows/joypad_windows.h24
-rw-r--r--platform/windows/key_mapping_windows.cpp4
-rw-r--r--platform/windows/key_mapping_windows.h4
-rw-r--r--platform/windows/lang_table.h4
-rw-r--r--platform/windows/os_windows.cpp178
-rw-r--r--platform/windows/os_windows.h97
-rw-r--r--platform/windows/platform_config.h4
-rw-r--r--platform/windows/vulkan_context_win.cpp4
-rw-r--r--platform/windows/vulkan_context_win.h4
-rw-r--r--platform/windows/windows_terminal_logger.cpp4
-rw-r--r--platform/windows/windows_terminal_logger.h4
249 files changed, 5158 insertions, 2755 deletions
diff --git a/platform/android/SCsub b/platform/android/SCsub
index ec42bc42b5..7e9dac926c 100644
--- a/platform/android/SCsub
+++ b/platform/android/SCsub
@@ -6,7 +6,6 @@ android_files = [
"os_android.cpp",
"file_access_android.cpp",
"audio_driver_opensl.cpp",
- "file_access_jandroid.cpp",
"dir_access_jandroid.cpp",
"thread_jandroid.cpp",
"net_socket_android.cpp",
@@ -14,6 +13,7 @@ android_files = [
"java_godot_lib_jni.cpp",
"java_class_wrapper.cpp",
"java_godot_wrapper.cpp",
+ "java_godot_view_wrapper.cpp",
"java_godot_io_wrapper.cpp",
"jni_utils.cpp",
"android_keys_utils.cpp",
@@ -29,10 +29,14 @@ for x in android_files:
env_thirdparty = env_android.Clone()
env_thirdparty.disable_warnings()
-android_objects.append(env_thirdparty.SharedObject("#thirdparty/misc/ifaddrs-android.cc"))
+thirdparty_obj = env_thirdparty.SharedObject("#thirdparty/misc/ifaddrs-android.cc")
+android_objects.append(thirdparty_obj)
lib = env_android.add_shared_library("#bin/libgodot", [android_objects], SHLIBSUFFIX=env["SHLIBSUFFIX"])
+# Needed to force rebuilding the platform files when the thirdparty code is updated.
+env.Depends(lib, thirdparty_obj)
+
lib_arch_dir = ""
if env["android_arch"] == "armv7":
lib_arch_dir = "armeabi-v7a"
diff --git a/platform/android/android_keys_utils.cpp b/platform/android/android_keys_utils.cpp
index b5b4fb9a4b..5aa546c17b 100644
--- a/platform/android/android_keys_utils.cpp
+++ b/platform/android/android_keys_utils.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/android_keys_utils.h b/platform/android/android_keys_utils.h
index a10afa1df8..e0ee2888c0 100644
--- a/platform/android/android_keys_utils.h
+++ b/platform/android/android_keys_utils.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -35,8 +35,8 @@
#include <core/os/keyboard.h>
struct _WinTranslatePair {
- unsigned int keysym;
- unsigned int keycode;
+ unsigned int keysym = 0;
+ unsigned int keycode = 0;
};
static _WinTranslatePair _ak_to_keycode[] = {
diff --git a/platform/android/api/api.cpp b/platform/android/api/api.cpp
index 8b82733d2d..d3c49c6eb7 100644
--- a/platform/android/api/api.cpp
+++ b/platform/android/api/api.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/api/api.h b/platform/android/api/api.h
index 5e951b9c88..fe3a6734ac 100644
--- a/platform/android/api/api.h
+++ b/platform/android/api/api.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/api/java_class_wrapper.h b/platform/android/api/java_class_wrapper.h
index 64da049407..d6c7a1abe5 100644
--- a/platform/android/api/java_class_wrapper.h
+++ b/platform/android/api/java_class_wrapper.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -66,10 +66,10 @@ class JavaClass : public Reference {
Map<StringName, Variant> constant_map;
struct MethodInfo {
- bool _static;
+ bool _static = false;
Vector<uint32_t> param_types;
Vector<StringName> param_sigs;
- uint32_t return_type;
+ uint32_t return_type = 0;
jmethodID method;
};
diff --git a/platform/android/api/jni_singleton.h b/platform/android/api/jni_singleton.h
index 7f20c354a0..965eaabf81 100644
--- a/platform/android/api/jni_singleton.h
+++ b/platform/android/api/jni_singleton.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -83,7 +83,7 @@ public:
v = (jvalue *)alloca(sizeof(jvalue) * p_argcount);
}
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
int res = env->PushLocalFrame(16);
diff --git a/platform/android/audio_driver_jandroid.cpp b/platform/android/audio_driver_jandroid.cpp
index 1363c5ac1e..3a2ccac481 100644
--- a/platform/android/audio_driver_jandroid.cpp
+++ b/platform/android/audio_driver_jandroid.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -72,10 +72,10 @@ Error AudioDriverAndroid::init() {
// __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device");
- JNIEnv *env = ThreadAndroid::get_env();
- int mix_rate = GLOBAL_GET("audio/mix_rate");
+ JNIEnv *env = get_jni_env();
+ int mix_rate = GLOBAL_GET("audio/driver/mix_rate");
- int latency = GLOBAL_GET("audio/output_latency");
+ int latency = GLOBAL_GET("audio/driver/output_latency");
unsigned int buffer_size = next_power_of_2(latency * mix_rate / 1000);
print_verbose("Audio buffer size: " + itos(buffer_size));
@@ -98,7 +98,7 @@ void AudioDriverAndroid::start() {
}
void AudioDriverAndroid::setup(jobject p_io) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
io = p_io;
jclass c = env->GetObjectClass(io);
@@ -162,7 +162,7 @@ void AudioDriverAndroid::unlock() {
}
void AudioDriverAndroid::finish() {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
env->CallVoidMethod(io, _quit);
if (audioBuffer) {
@@ -175,7 +175,7 @@ void AudioDriverAndroid::finish() {
}
void AudioDriverAndroid::set_pause(bool p_pause) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
env->CallVoidMethod(io, _pause, p_pause);
}
diff --git a/platform/android/audio_driver_jandroid.h b/platform/android/audio_driver_jandroid.h
index 953ade9311..9007fd2f81 100644
--- a/platform/android/audio_driver_jandroid.h
+++ b/platform/android/audio_driver_jandroid.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/audio_driver_opensl.cpp b/platform/android/audio_driver_opensl.cpp
index 740e9a3132..a1d8fb4810 100644
--- a/platform/android/audio_driver_opensl.cpp
+++ b/platform/android/audio_driver_opensl.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -339,6 +339,4 @@ void AudioDriverOpenSL::set_pause(bool p_pause) {
AudioDriverOpenSL::AudioDriverOpenSL() {
s_ad = this;
- pause = false;
- active = false;
}
diff --git a/platform/android/audio_driver_opensl.h b/platform/android/audio_driver_opensl.h
index b30711705b..e3efaddba2 100644
--- a/platform/android/audio_driver_opensl.h
+++ b/platform/android/audio_driver_opensl.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -38,19 +38,19 @@
#include <SLES/OpenSLES_Android.h>
class AudioDriverOpenSL : public AudioDriver {
- bool active;
+ bool active = false;
Mutex mutex;
enum {
BUFFER_COUNT = 2
};
- bool pause;
+ bool pause = false;
- uint32_t buffer_size;
- int16_t *buffers[BUFFER_COUNT];
- int32_t *mixdown_buffer;
- int last_free;
+ uint32_t buffer_size = 0;
+ int16_t *buffers[BUFFER_COUNT] = {};
+ int32_t *mixdown_buffer = nullptr;
+ int last_free = 0;
Vector<int16_t> rec_buffer;
diff --git a/platform/android/detect.py b/platform/android/detect.py
index 0accacb679..5f0fcc9b77 100644
--- a/platform/android/detect.py
+++ b/platform/android/detect.py
@@ -13,7 +13,7 @@ def get_name():
def can_build():
- return "ANDROID_NDK_ROOT" in os.environ
+ return ("ANDROID_SDK_ROOT" in os.environ) or ("ANDROID_HOME" in os.environ)
def get_platform(platform):
@@ -24,13 +24,33 @@ def get_opts():
from SCons.Variables import BoolVariable, EnumVariable
return [
- ("ANDROID_NDK_ROOT", "Path to the Android NDK", os.environ.get("ANDROID_NDK_ROOT", 0)),
+ ("ANDROID_NDK_ROOT", "Path to the Android NDK", get_android_ndk_root()),
+ ("ANDROID_SDK_ROOT", "Path to the Android SDK", get_android_sdk_root()),
("ndk_platform", 'Target platform (android-<api>, e.g. "android-24")', "android-24"),
EnumVariable("android_arch", "Target architecture", "armv7", ("armv7", "arm64v8", "x86", "x86_64")),
BoolVariable("android_neon", "Enable NEON support (armv7 only)", True),
]
+# Return the ANDROID_SDK_ROOT environment variable.
+# While ANDROID_HOME has been deprecated, it's used as a fallback for backward
+# compatibility purposes.
+def get_android_sdk_root():
+ if "ANDROID_SDK_ROOT" in os.environ:
+ return os.environ.get("ANDROID_SDK_ROOT", 0)
+ else:
+ return os.environ.get("ANDROID_HOME", 0)
+
+
+# Return the ANDROID_NDK_ROOT environment variable.
+# We generate one for this build using the ANDROID_SDK_ROOT env
+# variable and the project ndk version.
+# If the env variable is already defined, we override it with
+# our own to match what the project expects.
+def get_android_ndk_root():
+ return get_android_sdk_root() + "/ndk/" + get_project_ndk_version()
+
+
def get_flags():
return [
("tools", False),
@@ -47,7 +67,31 @@ def create(env):
return env.Clone(tools=tools)
+# Check if ANDROID_NDK_ROOT is valid.
+# If not, install the ndk using ANDROID_SDK_ROOT and sdkmanager.
+def install_ndk_if_needed(env):
+ print("Checking for Android NDK...")
+ env_ndk_version = get_env_ndk_version(env["ANDROID_NDK_ROOT"])
+ if env_ndk_version is None:
+ # Reinstall the ndk and update ANDROID_NDK_ROOT.
+ print("Installing Android NDK...")
+ if env["ANDROID_SDK_ROOT"] is None:
+ raise Exception("Invalid ANDROID_SDK_ROOT environment variable.")
+
+ import subprocess
+
+ extension = ".bat" if os.name == "nt" else ""
+ sdkmanager_path = env["ANDROID_SDK_ROOT"] + "/cmdline-tools/latest/bin/sdkmanager" + extension
+ ndk_download_args = "ndk;" + get_project_ndk_version()
+ subprocess.check_call([sdkmanager_path, ndk_download_args])
+
+ env["ANDROID_NDK_ROOT"] = env["ANDROID_SDK_ROOT"] + "/ndk/" + get_project_ndk_version()
+ print("ANDROID_NDK_ROOT: " + env["ANDROID_NDK_ROOT"])
+
+
def configure(env):
+ install_ndk_if_needed(env)
+
# Workaround for MinGW. See:
# http://www.scons.org/wiki/LongCmdLinesOnWin32
if os.name == "nt":
@@ -215,7 +259,7 @@ def configure(env):
env.Append(CPPFLAGS=["-isystem", env["ANDROID_NDK_ROOT"] + "/sources/cxx-stl/llvm-libc++abi/include"])
# Disable exceptions and rtti on non-tools (template) builds
- if env["tools"]:
+ if env["tools"] or env["builtin_icu"]:
env.Append(CXXFLAGS=["-frtti"])
else:
env.Append(CXXFLAGS=["-fno-rtti", "-fno-exceptions"])
@@ -270,7 +314,7 @@ def configure(env):
# Link flags
- ndk_version = get_ndk_version(env["ANDROID_NDK_ROOT"])
+ ndk_version = get_env_ndk_version(env["ANDROID_NDK_ROOT"])
if ndk_version != None and LooseVersion(ndk_version) >= LooseVersion("17.1.4828580"):
env.Append(LINKFLAGS=["-Wl,--exclude-libs,libgcc.a", "-Wl,--exclude-libs,libatomic.a", "-nostdlib++"])
else:
@@ -323,8 +367,14 @@ def configure(env):
env.Append(LIBS=["OpenSLES", "EGL", "GLESv2", "vulkan", "android", "log", "z", "dl"])
+# Return the project NDK version.
+# This is kept in sync with the value in 'platform/android/java/app/config.gradle'.
+def get_project_ndk_version():
+ return "21.4.7075529"
+
+
# Return NDK version string in source.properties (adapted from the Chromium project).
-def get_ndk_version(path):
+def get_env_ndk_version(path):
if path is None:
return None
prop_file_path = os.path.join(path, "source.properties")
@@ -334,6 +384,6 @@ def get_ndk_version(path):
key_value = list(map(lambda x: x.strip(), line.split("=")))
if key_value[0] == "Pkg.Revision":
return key_value[1]
- except:
+ except Exception:
print("Could not read source prop file '%s'" % prop_file_path)
return None
diff --git a/platform/android/dir_access_jandroid.cpp b/platform/android/dir_access_jandroid.cpp
index ba75a4b10c..f8ac29c738 100644
--- a/platform/android/dir_access_jandroid.cpp
+++ b/platform/android/dir_access_jandroid.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,7 +30,7 @@
#include "dir_access_jandroid.h"
#include "core/string/print_string.h"
-#include "file_access_jandroid.h"
+#include "file_access_android.h"
#include "string_android.h"
#include "thread_jandroid.h"
@@ -47,7 +47,7 @@ DirAccess *DirAccessJAndroid::create_fs() {
Error DirAccessJAndroid::list_dir_begin() {
list_dir_end();
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
jstring js = env->NewStringUTF(current_dir.utf8().get_data());
int res = env->CallIntMethod(io, _dir_open, js);
@@ -62,7 +62,7 @@ Error DirAccessJAndroid::list_dir_begin() {
String DirAccessJAndroid::get_next() {
ERR_FAIL_COND_V(id == 0, "");
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
jstring str = (jstring)env->CallObjectMethod(io, _dir_next, id);
if (!str)
return "";
@@ -73,7 +73,7 @@ String DirAccessJAndroid::get_next() {
}
bool DirAccessJAndroid::current_is_dir() const {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
return env->CallBooleanMethod(io, _dir_is_dir, id);
}
@@ -86,7 +86,7 @@ void DirAccessJAndroid::list_dir_end() {
if (id == 0)
return;
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
env->CallVoidMethod(io, _dir_close, id);
id = 0;
}
@@ -100,7 +100,7 @@ String DirAccessJAndroid::get_drive(int p_drive) {
}
Error DirAccessJAndroid::change_dir(String p_dir) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
if (p_dir == "" || p_dir == "." || (p_dir == ".." && current_dir == ""))
return OK;
@@ -146,7 +146,7 @@ bool DirAccessJAndroid::file_exists(String p_file) {
else
sd = current_dir.plus_file(p_file);
- FileAccessJAndroid *f = memnew(FileAccessJAndroid);
+ FileAccessAndroid *f = memnew(FileAccessAndroid);
bool exists = f->file_exists(sd);
memdelete(f);
@@ -154,7 +154,7 @@ bool DirAccessJAndroid::file_exists(String p_file) {
}
bool DirAccessJAndroid::dir_exists(String p_dir) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
String sd;
@@ -207,7 +207,7 @@ size_t DirAccessJAndroid::get_space_left() {
}
void DirAccessJAndroid::setup(jobject p_io) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
io = p_io;
jclass c = env->GetObjectClass(io);
diff --git a/platform/android/dir_access_jandroid.h b/platform/android/dir_access_jandroid.h
index 7d0def137a..fed468d051 100644
--- a/platform/android/dir_access_jandroid.h
+++ b/platform/android/dir_access_jandroid.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/display_server_android.cpp b/platform/android/display_server_android.cpp
index e82a12ece5..5f7e5eaa83 100644
--- a/platform/android/display_server_android.cpp
+++ b/platform/android/display_server_android.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -41,7 +41,7 @@
#if defined(VULKAN_ENABLED)
#include "drivers/vulkan/rendering_device_vulkan.h"
#include "platform/android/vulkan/vulkan_context_android.h"
-#include "servers/rendering/rasterizer_rd/rasterizer_rd.h"
+#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
#endif
DisplayServerAndroid *DisplayServerAndroid::get_singleton() {
@@ -447,7 +447,7 @@ DisplayServerAndroid::DisplayServerAndroid(const String &p_rendering_driver, Dis
rendering_device_vulkan = memnew(RenderingDeviceVulkan);
rendering_device_vulkan->initialize(context_vulkan);
- RasterizerRD::make_current();
+ RendererCompositorRD::make_current();
}
#endif
@@ -498,9 +498,28 @@ void DisplayServerAndroid::_set_key_modifier_state(Ref<InputEventWithModifiers>
}
void DisplayServerAndroid::process_key_event(int p_keycode, int p_scancode, int p_unicode_char, bool p_pressed) {
+ static char32_t prev_wc = 0;
+ char32_t unicode = p_unicode_char;
+ if ((p_unicode_char & 0xfffffc00) == 0xd800) {
+ if (prev_wc != 0) {
+ ERR_PRINT("invalid utf16 surrogate input");
+ }
+ prev_wc = unicode;
+ return; // Skip surrogate.
+ } else if ((unicode & 0xfffffc00) == 0xdc00) {
+ if (prev_wc == 0) {
+ ERR_PRINT("invalid utf16 surrogate input");
+ return; // Skip invalid surrogate.
+ }
+ unicode = (prev_wc << 10UL) + unicode - ((0xd800 << 10UL) + 0xdc00 - 0x10000);
+ prev_wc = 0;
+ } else {
+ prev_wc = 0;
+ }
+
Ref<InputEventKey> ev;
ev.instance();
- int val = p_unicode_char;
+ int val = unicode;
int keycode = android_get_keysym(p_keycode);
int phy_keycode = android_get_keysym(p_scancode);
@@ -667,7 +686,7 @@ void DisplayServerAndroid::process_hover(int p_type, Point2 p_pos) {
}
}
-void DisplayServerAndroid::process_mouse_event(int event_action, int event_android_buttons_mask, Point2 event_pos, float event_vertical_factor, float event_horizontal_factor) {
+void DisplayServerAndroid::process_mouse_event(int input_device, int event_action, int event_android_buttons_mask, Point2 event_pos, float event_vertical_factor, float event_horizontal_factor) {
int event_buttons_mask = _android_button_mask_to_godot_button_mask(event_android_buttons_mask);
switch (event_action) {
case AMOTION_EVENT_ACTION_BUTTON_PRESS:
@@ -675,8 +694,13 @@ void DisplayServerAndroid::process_mouse_event(int event_action, int event_andro
Ref<InputEventMouseButton> ev;
ev.instance();
_set_key_modifier_state(ev);
- ev->set_position(event_pos);
- ev->set_global_position(event_pos);
+ if ((input_device & AINPUT_SOURCE_MOUSE) == AINPUT_SOURCE_MOUSE) {
+ ev->set_position(event_pos);
+ ev->set_global_position(event_pos);
+ } else {
+ ev->set_position(hover_prev_pos);
+ ev->set_global_position(hover_prev_pos);
+ }
ev->set_pressed(event_action == AMOTION_EVENT_ACTION_BUTTON_PRESS);
int changed_button_mask = buttons_state ^ event_buttons_mask;
@@ -691,18 +715,29 @@ void DisplayServerAndroid::process_mouse_event(int event_action, int event_andro
Ref<InputEventMouseMotion> ev;
ev.instance();
_set_key_modifier_state(ev);
- ev->set_position(event_pos);
- ev->set_global_position(event_pos);
- ev->set_relative(event_pos - hover_prev_pos);
+ if ((input_device & AINPUT_SOURCE_MOUSE) == AINPUT_SOURCE_MOUSE) {
+ ev->set_position(event_pos);
+ ev->set_global_position(event_pos);
+ ev->set_relative(event_pos - hover_prev_pos);
+ hover_prev_pos = event_pos;
+ } else {
+ ev->set_position(hover_prev_pos);
+ ev->set_global_position(hover_prev_pos);
+ ev->set_relative(event_pos);
+ }
ev->set_button_mask(event_buttons_mask);
Input::get_singleton()->accumulate_input_event(ev);
- hover_prev_pos = event_pos;
} break;
case AMOTION_EVENT_ACTION_SCROLL: {
Ref<InputEventMouseButton> ev;
ev.instance();
- ev->set_position(event_pos);
- ev->set_global_position(event_pos);
+ if ((input_device & AINPUT_SOURCE_MOUSE) == AINPUT_SOURCE_MOUSE) {
+ ev->set_position(event_pos);
+ ev->set_global_position(event_pos);
+ } else {
+ ev->set_position(hover_prev_pos);
+ ev->set_global_position(hover_prev_pos);
+ }
ev->set_pressed(true);
buttons_state = event_buttons_mask;
if (event_vertical_factor > 0) {
@@ -790,6 +825,24 @@ void DisplayServerAndroid::process_gyroscope(const Vector3 &p_gyroscope) {
Input::get_singleton()->set_gyroscope(p_gyroscope);
}
+void DisplayServerAndroid::mouse_set_mode(MouseMode p_mode) {
+ if (mouse_mode == p_mode) {
+ return;
+ }
+
+ if (p_mode == MouseMode::MOUSE_MODE_CAPTURED) {
+ OS_Android::get_singleton()->get_godot_java()->get_godot_view()->request_pointer_capture();
+ } else {
+ OS_Android::get_singleton()->get_godot_java()->get_godot_view()->release_pointer_capture();
+ }
+
+ mouse_mode = p_mode;
+}
+
+DisplayServer::MouseMode DisplayServerAndroid::mouse_get_mode() const {
+ return mouse_mode;
+}
+
Point2i DisplayServerAndroid::mouse_get_position() const {
return hover_prev_pos;
}
diff --git a/platform/android/display_server_android.h b/platform/android/display_server_android.h
index aa5a2c1185..b9d1641656 100644
--- a/platform/android/display_server_android.h
+++ b/platform/android/display_server_android.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -41,7 +41,7 @@ class RenderingDeviceVulkan;
class DisplayServerAndroid : public DisplayServer {
public:
struct TouchPos {
- int id;
+ int id = 0;
Point2 pos;
};
@@ -52,12 +52,12 @@ public:
};
struct JoypadEvent {
- int device;
- int type;
- int index;
- bool pressed;
- float value;
- int hat;
+ int device = 0;
+ int type = 0;
+ int index = 0;
+ bool pressed = false;
+ float value = 0;
+ int hat = 0;
};
private:
@@ -70,6 +70,8 @@ private:
int buttons_state;
+ MouseMode mouse_mode;
+
bool keep_screen_on;
Vector<TouchPos> touch;
@@ -172,12 +174,15 @@ public:
void process_gyroscope(const Vector3 &p_gyroscope);
void process_touch(int p_event, int p_pointer, const Vector<TouchPos> &p_points);
void process_hover(int p_type, Point2 p_pos);
- void process_mouse_event(int event_action, int event_android_buttons_mask, Point2 event_pos, float event_vertical_factor = 0, float event_horizontal_factor = 0);
+ void process_mouse_event(int input_device, int event_action, int event_android_buttons_mask, Point2 event_pos, float event_vertical_factor = 0, float event_horizontal_factor = 0);
void process_double_tap(int event_android_button_mask, Point2 p_pos);
void process_scroll(Point2 p_pos);
void process_joy_event(JoypadEvent p_event);
void process_key_event(int p_keycode, int p_scancode, int p_unicode_char, bool p_pressed);
+ void mouse_set_mode(MouseMode p_mode);
+ MouseMode mouse_get_mode() const;
+
static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
static Vector<String> get_rendering_drivers_func();
static void register_android_driver();
diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp
index d24c96f87a..888b1546e4 100644
--- a/platform/android/export/export.cpp
+++ b/platform/android/export/export.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -37,6 +37,7 @@
#include "core/os/dir_access.h"
#include "core/os/file_access.h"
#include "core/os/os.h"
+#include "core/templates/safe_refcount.h"
#include "core/version.h"
#include "drivers/png/png_driver_common.h"
#include "editor/editor_export.h"
@@ -202,10 +203,23 @@ static const char *android_perms[] = {
static const char *SPLASH_IMAGE_EXPORT_PATH = "res/drawable/splash.png";
static const char *SPLASH_BG_COLOR_PATH = "res/drawable/splash_bg_color.png";
+static const char *SPLASH_CONFIG_PATH = "res://android/build/res/drawable/splash_drawable.xml";
+
+const String SPLASH_CONFIG_XML_CONTENT = R"SPLASH(<?xml version="1.0" encoding="utf-8"?>
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:drawable="@drawable/splash_bg_color" />
+ <item>
+ <bitmap
+ android:gravity="%s"
+ android:filter="%s"
+ android:src="@drawable/splash" />
+ </item>
+</layer-list>
+)SPLASH";
struct LauncherIcon {
const char *export_path;
- int dimensions;
+ int dimensions = 0;
};
static const int icon_densities_count = 6;
@@ -240,6 +254,9 @@ static const LauncherIcon launcher_adaptive_icon_backgrounds[icon_densities_coun
{ "res/mipmap/icon_background.png", 432 }
};
+static const int EXPORT_FORMAT_APK = 0;
+static const int EXPORT_FORMAT_AAB = 1;
+
class EditorExportPlatformAndroid : public EditorExportPlatform {
GDCLASS(EditorExportPlatformAndroid, EditorExportPlatform);
@@ -250,62 +267,62 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
String id;
String name;
String description;
- int api_level;
+ int api_level = 0;
};
struct APKExportData {
zipFile apk;
- EditorProgress *ep;
+ EditorProgress *ep = nullptr;
};
- Vector<PluginConfig> plugins;
+ Vector<PluginConfigAndroid> plugins;
String last_plugin_names;
uint64_t last_custom_build_time = 0;
- volatile bool plugins_changed;
+ SafeFlag plugins_changed;
Mutex plugins_lock;
Vector<Device> devices;
- volatile bool devices_changed;
+ SafeFlag devices_changed;
Mutex device_lock;
- Thread *check_for_changes_thread;
- volatile bool quit_request;
+ Thread check_for_changes_thread;
+ SafeFlag quit_request;
static void _check_for_changes_poll_thread(void *ud) {
EditorExportPlatformAndroid *ea = (EditorExportPlatformAndroid *)ud;
- while (!ea->quit_request) {
+ while (!ea->quit_request.is_set()) {
// Check for plugins updates
{
// Nothing to do if we already know the plugins have changed.
- if (!ea->plugins_changed) {
- Vector<PluginConfig> loaded_plugins = get_plugins();
+ if (!ea->plugins_changed.is_set()) {
+ Vector<PluginConfigAndroid> loaded_plugins = get_plugins();
MutexLock lock(ea->plugins_lock);
if (ea->plugins.size() != loaded_plugins.size()) {
- ea->plugins_changed = true;
+ ea->plugins_changed.set();
} else {
for (int i = 0; i < ea->plugins.size(); i++) {
if (ea->plugins[i].name != loaded_plugins[i].name) {
- ea->plugins_changed = true;
+ ea->plugins_changed.set();
break;
}
}
}
- if (ea->plugins_changed) {
+ if (ea->plugins_changed.is_set()) {
ea->plugins = loaded_plugins;
}
}
}
// Check for devices updates
- String adb = EditorSettings::get_singleton()->get("export/android/adb");
+ String adb = get_adb_path();
if (FileAccess::exists(adb)) {
String devices;
List<String> args;
args.push_back("devices");
int ec;
- OS::get_singleton()->execute(adb, args, true, nullptr, &devices, &ec);
+ OS::get_singleton()->execute(adb, args, &devices, &ec);
Vector<String> ds = devices.split("\n");
Vector<String> ldevices;
@@ -358,7 +375,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
int ec2;
String dp;
- OS::get_singleton()->execute(adb, args, true, nullptr, &dp, &ec2);
+ OS::get_singleton()->execute(adb, args, &dp, &ec2);
Vector<String> props = dp.split("\n");
String vendor;
@@ -406,7 +423,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
}
ea->devices = ndevices;
- ea->devices_changed = true;
+ ea->devices_changed.set();
}
}
@@ -415,21 +432,21 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
uint64_t time = OS::get_singleton()->get_ticks_usec();
while (OS::get_singleton()->get_ticks_usec() - time < wait) {
OS::get_singleton()->delay_usec(1000 * sleep);
- if (ea->quit_request) {
+ if (ea->quit_request.is_set()) {
break;
}
}
}
if (EditorSettings::get_singleton()->get("export/android/shutdown_adb_on_exit")) {
- String adb = EditorSettings::get_singleton()->get("export/android/adb");
+ String adb = get_adb_path();
if (!FileAccess::exists(adb)) {
return; //adb not configured
}
List<String> args;
args.push_back("kill-server");
- OS::get_singleton()->execute(adb, args, true);
+ OS::get_singleton()->execute(adb, args);
};
}
@@ -626,7 +643,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
continue;
}
- if (file.ends_with(PLUGIN_CONFIG_EXT)) {
+ if (file.ends_with(PluginConfigAndroid::PLUGIN_CONFIG_EXT)) {
dir_files.push_back(file);
}
}
@@ -636,8 +653,8 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
return dir_files;
}
- static Vector<PluginConfig> get_plugins() {
- Vector<PluginConfig> loaded_plugins;
+ static Vector<PluginConfigAndroid> get_plugins() {
+ Vector<PluginConfigAndroid> loaded_plugins;
String plugins_dir = ProjectSettings::get_singleton()->get_resource_path().plus_file("android/plugins");
@@ -647,10 +664,10 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
if (DirAccess::exists(plugins_dir)) {
Vector<String> plugins_filenames = list_gdap_files(plugins_dir);
- if (!plugins_filenames.empty()) {
+ if (!plugins_filenames.is_empty()) {
Ref<ConfigFile> config_file = memnew(ConfigFile);
for (int i = 0; i < plugins_filenames.size(); i++) {
- PluginConfig config = load_plugin_config(config_file, plugins_dir.plus_file(plugins_filenames[i]));
+ PluginConfigAndroid config = load_plugin_config(config_file, plugins_dir.plus_file(plugins_filenames[i]));
if (config.valid_config) {
loaded_plugins.push_back(config);
} else {
@@ -663,11 +680,11 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
return loaded_plugins;
}
- static Vector<PluginConfig> get_enabled_plugins(const Ref<EditorExportPreset> &p_presets) {
- Vector<PluginConfig> enabled_plugins;
- Vector<PluginConfig> all_plugins = get_plugins();
+ static Vector<PluginConfigAndroid> get_enabled_plugins(const Ref<EditorExportPreset> &p_presets) {
+ Vector<PluginConfigAndroid> enabled_plugins;
+ Vector<PluginConfigAndroid> all_plugins = get_plugins();
for (int i = 0; i < all_plugins.size(); i++) {
- PluginConfig plugin = all_plugins[i];
+ PluginConfigAndroid plugin = all_plugins[i];
bool enabled = p_presets->get("plugins/" + plugin.name);
if (enabled) {
enabled_plugins.push_back(plugin);
@@ -750,7 +767,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
PackedStringArray user_perms = p_preset->get("permissions/custom_permissions");
for (int i = 0; i < user_perms.size(); i++) {
String user_perm = user_perms[i].strip_edges();
- if (!user_perm.empty()) {
+ if (!user_perm.is_empty()) {
r_permissions.push_back(user_perm);
}
}
@@ -772,6 +789,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
}
void _write_tmp_manifest(const Ref<EditorExportPreset> &p_preset, bool p_give_internet, bool p_debug) {
+ print_verbose("Building temporary manifest..");
String manifest_text =
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
"<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"
@@ -792,6 +810,8 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
manifest_text += _get_application_tag(p_preset, plugins_names);
manifest_text += "</manifest>\n";
String manifest_path = vformat("res://android/build/src/%s/AndroidManifest.xml", (p_debug ? "debug" : "release"));
+
+ print_verbose("Storing manifest into " + manifest_path + ": " + "\n" + manifest_text);
store_string_at_path(manifest_path, manifest_text);
}
@@ -975,7 +995,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
encode_uint32(xr_mode_index == /* XRMode.OVR */ 1 && focus_awareness ? 0xFFFFFFFF : 0, &p_manifest.write[iofs + 16]);
}
- if (tname == "meta-data" && attrname == "value" && value == "plugins_value" && !plugins_names.empty()) {
+ if (tname == "meta-data" && attrname == "value" && value == "plugins_value" && !plugins_names.is_empty()) {
// Update the meta-data 'android:value' attribute with the list of enabled plugins.
string_table.write[attr_value] = plugins_names;
}
@@ -1467,20 +1487,26 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
}
}
- void load_splash_refs(Ref<Image> &splash_image, Ref<Image> &splash_bg_color_image) {
- // TODO: Figure out how to handle remaining boot splash parameters (e.g: fullsize, filter)
+ String load_splash_refs(Ref<Image> &splash_image, Ref<Image> &splash_bg_color_image) {
+ bool scale_splash = ProjectSettings::get_singleton()->get("application/boot_splash/fullsize");
+ bool apply_filter = ProjectSettings::get_singleton()->get("application/boot_splash/use_filter");
String project_splash_path = ProjectSettings::get_singleton()->get("application/boot_splash/image");
- if (!project_splash_path.empty()) {
+ if (!project_splash_path.is_empty()) {
splash_image.instance();
+ print_verbose("Loading splash image: " + project_splash_path);
const Error err = ImageLoader::load_image(project_splash_path, splash_image);
if (err) {
+ if (OS::get_singleton()->is_stdout_verbose()) {
+ print_error("- unable to load splash image from " + project_splash_path + " (" + itos(err) + ")");
+ }
splash_image.unref();
}
}
if (splash_image.is_null()) {
// Use the default
+ print_verbose("Using default splash image.");
splash_image = Ref<Image>(memnew(Image(boot_splash_png)));
}
@@ -1491,9 +1517,14 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
bg_color = boot_splash_bg_color;
}
+ print_verbose("Creating splash background color image.");
splash_bg_color_image.instance();
splash_bg_color_image->create(splash_image->get_width(), splash_image->get_height(), false, splash_image->get_format());
splash_bg_color_image->fill(bg_color);
+
+ String gravity = scale_splash ? "fill" : "center";
+ String processed_splash_config_xml = vformat(SPLASH_CONFIG_XML_CONTENT, gravity, bool_to_string(apply_filter));
+ return processed_splash_config_xml;
}
void load_icon_refs(const Ref<EditorExportPreset> &p_preset, Ref<Image> &icon, Ref<Image> &foreground, Ref<Image> &background) {
@@ -1505,19 +1536,24 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
// Regular icon: user selection -> project icon -> default.
String path = static_cast<String>(p_preset->get(launcher_icon_option)).strip_edges();
- if (path.empty() || ImageLoader::load_image(path, icon) != OK) {
+ print_verbose("Loading regular icon from " + path);
+ if (path.is_empty() || ImageLoader::load_image(path, icon) != OK) {
+ print_verbose("- falling back to project icon: " + project_icon_path);
ImageLoader::load_image(project_icon_path, icon);
}
// Adaptive foreground: user selection -> regular icon (user selection -> project icon -> default).
path = static_cast<String>(p_preset->get(launcher_adaptive_icon_foreground_option)).strip_edges();
- if (path.empty() || ImageLoader::load_image(path, foreground) != OK) {
+ print_verbose("Loading adaptive foreground icon from " + path);
+ if (path.is_empty() || ImageLoader::load_image(path, foreground) != OK) {
+ print_verbose("- falling back to using the regular icon");
foreground = icon;
}
// Adaptive background: user selection -> default.
path = static_cast<String>(p_preset->get(launcher_adaptive_icon_background_option)).strip_edges();
- if (!path.empty()) {
+ if (!path.is_empty()) {
+ print_verbose("Loading adaptive background icon from " + path);
ImageLoader::load_image(path, background);
}
}
@@ -1532,20 +1568,29 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
}
void _copy_icons_to_gradle_project(const Ref<EditorExportPreset> &p_preset,
+ const String &processed_splash_config_xml,
const Ref<Image> &splash_image,
const Ref<Image> &splash_bg_color_image,
const Ref<Image> &main_image,
const Ref<Image> &foreground,
const Ref<Image> &background) {
+ // Store the splash configuration
+ if (!processed_splash_config_xml.is_empty()) {
+ print_verbose("Storing processed splash configuration: " + String("\n") + processed_splash_config_xml);
+ store_string_at_path(SPLASH_CONFIG_PATH, processed_splash_config_xml);
+ }
+
// Store the splash image
- if (splash_image.is_valid() && !splash_image->empty()) {
+ if (splash_image.is_valid() && !splash_image->is_empty()) {
+ print_verbose("Storing splash image in " + String(SPLASH_IMAGE_EXPORT_PATH));
Vector<uint8_t> data;
_load_image_data(splash_image, data);
store_image(SPLASH_IMAGE_EXPORT_PATH, data);
}
// Store the splash bg color image
- if (splash_bg_color_image.is_valid() && !splash_bg_color_image->empty()) {
+ if (splash_bg_color_image.is_valid() && !splash_bg_color_image->is_empty()) {
+ print_verbose("Storing splash background image in " + String(SPLASH_BG_COLOR_PATH));
Vector<uint8_t> data;
_load_image_data(splash_bg_color_image, data);
store_image(SPLASH_BG_COLOR_PATH, data);
@@ -1555,20 +1600,23 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
// the default image from the export template will be used.
for (int i = 0; i < icon_densities_count; ++i) {
- if (main_image.is_valid() && !main_image->empty()) {
+ if (main_image.is_valid() && !main_image->is_empty()) {
+ print_verbose("Processing launcher icon for dimension " + itos(launcher_icons[i].dimensions) + " into " + launcher_icons[i].export_path);
Vector<uint8_t> data;
_process_launcher_icons(launcher_icons[i].export_path, main_image, launcher_icons[i].dimensions, data);
store_image(launcher_icons[i], data);
}
- if (foreground.is_valid() && !foreground->empty()) {
+ if (foreground.is_valid() && !foreground->is_empty()) {
+ print_verbose("Processing launcher adaptive icon foreground for dimension " + itos(launcher_adaptive_icon_foregrounds[i].dimensions) + " into " + launcher_adaptive_icon_foregrounds[i].export_path);
Vector<uint8_t> data;
_process_launcher_icons(launcher_adaptive_icon_foregrounds[i].export_path, foreground,
launcher_adaptive_icon_foregrounds[i].dimensions, data);
store_image(launcher_adaptive_icon_foregrounds[i], data);
}
- if (background.is_valid() && !background->empty()) {
+ if (background.is_valid() && !background->is_empty()) {
+ print_verbose("Processing launcher adaptive icon background for dimension " + itos(launcher_adaptive_icon_backgrounds[i].dimensions) + " into " + launcher_adaptive_icon_backgrounds[i].export_path);
Vector<uint8_t> data;
_process_launcher_icons(launcher_adaptive_icon_backgrounds[i].export_path, background,
launcher_adaptive_icon_backgrounds[i].dimensions, data);
@@ -1594,7 +1642,7 @@ public:
public:
virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) override {
- String driver = ProjectSettings::get_singleton()->get("rendering/quality/driver/driver_name");
+ String driver = ProjectSettings::get_singleton()->get("rendering/driver/driver_name");
if (driver == "GLES2") {
r_features->push_back("etc");
}
@@ -1613,14 +1661,14 @@ public:
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, "*.apk"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, "*.apk"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "custom_template/use_custom_build"), false));
- r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "custom_template/export_format", PROPERTY_HINT_ENUM, "Export APK,Export AAB"), 0));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "custom_template/export_format", PROPERTY_HINT_ENUM, "Export APK,Export AAB"), EXPORT_FORMAT_APK));
- Vector<PluginConfig> plugins_configs = get_plugins();
+ Vector<PluginConfigAndroid> plugins_configs = get_plugins();
for (int i = 0; i < plugins_configs.size(); i++) {
print_verbose("Found Android plugin " + plugins_configs[i].name);
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "plugins/" + plugins_configs[i].name), false));
}
- plugins_changed = false;
+ plugins_changed.clear();
Vector<String> abis = get_abis();
for (int i = 0; i < abis.size(); ++i) {
@@ -1690,19 +1738,19 @@ public:
}
virtual bool should_update_export_options() override {
- bool export_options_changed = plugins_changed;
+ bool export_options_changed = plugins_changed.is_set();
if (export_options_changed) {
// don't clear unless we're reporting true, to avoid race
- plugins_changed = false;
+ plugins_changed.clear();
}
return export_options_changed;
}
virtual bool poll_export() override {
- bool dc = devices_changed;
+ bool dc = devices_changed.is_set();
if (dc) {
// don't clear unless we're reporting true, to avoid race
- devices_changed = false;
+ devices_changed.clear();
}
return dc;
}
@@ -1749,7 +1797,7 @@ public:
EditorProgress ep("run", "Running on " + devices[p_device].name, 3);
- String adb = EditorSettings::get_singleton()->get("export/android/adb");
+ String adb = get_adb_path();
// Export_temp APK.
if (ep.step("Exporting APK...", 0)) {
@@ -1772,7 +1820,7 @@ public:
}
// Export to temporary APK before sending to device.
- Error err = export_project(p_preset, true, tmp_export_path, p_debug_flags);
+ Error err = export_project_helper(p_preset, true, tmp_export_path, EXPORT_FORMAT_APK, true, p_debug_flags);
if (err != OK) {
CLEANUP_AND_RETURN(err);
@@ -1797,7 +1845,7 @@ public:
args.push_back("uninstall");
args.push_back(get_package_name(package_name));
- err = OS::get_singleton()->execute(adb, args, true, nullptr, nullptr, &rv);
+ err = OS::get_singleton()->execute(adb, args, nullptr, &rv);
}
print_line("Installing to device (please wait...): " + devices[p_device].name);
@@ -1812,7 +1860,7 @@ public:
args.push_back("-r");
args.push_back(tmp_export_path);
- err = OS::get_singleton()->execute(adb, args, true, nullptr, nullptr, &rv);
+ err = OS::get_singleton()->execute(adb, args, nullptr, &rv);
if (err || rv != 0) {
EditorNode::add_io_error("Could not install to device.");
CLEANUP_AND_RETURN(ERR_CANT_CREATE);
@@ -1829,7 +1877,7 @@ public:
args.push_back(devices[p_device].id);
args.push_back("reverse");
args.push_back("--remove-all");
- OS::get_singleton()->execute(adb, args, true, nullptr, nullptr, &rv);
+ OS::get_singleton()->execute(adb, args, nullptr, &rv);
if (p_debug_flags & DEBUG_FLAG_REMOTE_DEBUG) {
int dbg_port = EditorSettings::get_singleton()->get("network/debug/remote_port");
@@ -1840,7 +1888,7 @@ public:
args.push_back("tcp:" + itos(dbg_port));
args.push_back("tcp:" + itos(dbg_port));
- OS::get_singleton()->execute(adb, args, true, nullptr, nullptr, &rv);
+ OS::get_singleton()->execute(adb, args, nullptr, &rv);
print_line("Reverse result: " + itos(rv));
}
@@ -1854,7 +1902,7 @@ public:
args.push_back("tcp:" + itos(fs_port));
args.push_back("tcp:" + itos(fs_port));
- err = OS::get_singleton()->execute(adb, args, true, nullptr, nullptr, &rv);
+ err = OS::get_singleton()->execute(adb, args, nullptr, &rv);
print_line("Reverse result2: " + itos(rv));
}
} else {
@@ -1882,7 +1930,7 @@ public:
args.push_back("-n");
args.push_back(get_package_name(package_name) + "/com.godot.game.GodotApp");
- err = OS::get_singleton()->execute(adb, args, true, nullptr, nullptr, &rv);
+ err = OS::get_singleton()->execute(adb, args, nullptr, &rv);
if (err || rv != 0) {
EditorNode::add_io_error("Could not execute on device.");
CLEANUP_AND_RETURN(ERR_CANT_CREATE);
@@ -1896,6 +1944,55 @@ public:
return run_icon;
}
+ static String get_adb_path() {
+ String exe_ext = "";
+ if (OS::get_singleton()->get_name() == "Windows") {
+ exe_ext = ".exe";
+ }
+ String sdk_path = EditorSettings::get_singleton()->get("export/android/android_sdk_path");
+ return sdk_path.plus_file("platform-tools/adb" + exe_ext);
+ }
+
+ static String get_apksigner_path() {
+ String exe_ext = "";
+ if (OS::get_singleton()->get_name() == "Windows") {
+ exe_ext = ".bat";
+ }
+ String apksigner_command_name = "apksigner" + exe_ext;
+ String sdk_path = EditorSettings::get_singleton()->get("export/android/android_sdk_path");
+ String apksigner_path = "";
+
+ Error errn;
+ String build_tools_dir = sdk_path.plus_file("build-tools");
+ DirAccessRef da = DirAccess::open(build_tools_dir, &errn);
+ if (errn != OK) {
+ print_error("Unable to open Android 'build-tools' directory.");
+ return apksigner_path;
+ }
+
+ // There are additional versions directories we need to go through.
+ da->list_dir_begin();
+ String sub_dir = da->get_next();
+ while (!sub_dir.is_empty()) {
+ if (!sub_dir.begins_with(".") && da->current_is_dir()) {
+ // Check if the tool is here.
+ String tool_path = build_tools_dir.plus_file(sub_dir).plus_file(apksigner_command_name);
+ if (FileAccess::exists(tool_path)) {
+ apksigner_path = tool_path;
+ break;
+ }
+ }
+ sub_dir = da->get_next();
+ }
+ da->list_dir_end();
+
+ if (apksigner_path.is_empty()) {
+ EditorNode::get_singleton()->show_warning(TTR("Unable to find the 'apksigner' tool."));
+ }
+
+ return apksigner_path;
+ }
+
virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const override {
String err;
bool valid = false;
@@ -1931,25 +2028,16 @@ public:
}
} else {
valid = exists_export_template("android_source.zip", &err);
+
+ if (!FileAccess::exists("res://android/build/build.gradle")) {
+ err += TTR("Android build template not installed in the project. Install it from the Project menu.") + "\n";
+ valid = false;
+ }
}
r_missing_templates = !valid;
// Validate the rest of the configuration.
- String adb = EditorSettings::get_singleton()->get("export/android/adb");
-
- if (!FileAccess::exists(adb)) {
- valid = false;
- err += TTR("ADB executable not configured in the Editor Settings.") + "\n";
- }
-
- String js = EditorSettings::get_singleton()->get("export/android/jarsigner");
-
- if (!FileAccess::exists(js)) {
- valid = false;
- err += TTR("OpenJDK jarsigner not configured in the Editor Settings.") + "\n";
- }
-
String dk = p_preset->get("keystore/debug");
if (!FileAccess::exists(dk)) {
@@ -1962,30 +2050,50 @@ public:
String rk = p_preset->get("keystore/release");
- if (!rk.empty() && !FileAccess::exists(rk)) {
+ if (!rk.is_empty() && !FileAccess::exists(rk)) {
valid = false;
err += TTR("Release keystore incorrectly configured in the export preset.") + "\n";
}
- if (bool(p_preset->get("custom_template/use_custom_build"))) {
- String sdk_path = EditorSettings::get_singleton()->get("export/android/custom_build_sdk_path");
- if (sdk_path == "") {
- err += TTR("Custom build requires a valid Android SDK path in Editor Settings.") + "\n";
+ String sdk_path = EditorSettings::get_singleton()->get("export/android/android_sdk_path");
+ if (sdk_path == "") {
+ err += TTR("A valid Android SDK path is required in Editor Settings.") + "\n";
+ valid = false;
+ } else {
+ Error errn;
+ // Check for the platform-tools directory.
+ DirAccessRef da = DirAccess::open(sdk_path.plus_file("platform-tools"), &errn);
+ if (errn != OK) {
+ err += TTR("Invalid Android SDK path in Editor Settings.");
+ err += TTR("Missing 'platform-tools' directory!");
+ err += "\n";
valid = false;
- } else {
- Error errn;
- // Check for the platform-tools directory.
- DirAccessRef da = DirAccess::open(sdk_path.plus_file("platform-tools"), &errn);
- if (errn != OK) {
- err += TTR("Invalid Android SDK path for custom build in Editor Settings.");
- err += TTR("Missing 'platform-tools' directory!");
- err += "\n";
- valid = false;
- }
}
- if (!FileAccess::exists("res://android/build/build.gradle")) {
- err += TTR("Android build template not installed in the project. Install it from the Project menu.") + "\n";
+ // Validate that adb is available
+ String adb_path = get_adb_path();
+ if (!FileAccess::exists(adb_path)) {
+ err += TTR("Unable to find Android SDK platform-tools' adb command.");
+ err += TTR("Please check in the Android SDK directory specified in Editor Settings.");
+ err += "\n";
+ valid = false;
+ }
+
+ // Check for the build-tools directory.
+ DirAccessRef build_tools_da = DirAccess::open(sdk_path.plus_file("build-tools"), &errn);
+ if (errn != OK) {
+ err += TTR("Invalid Android SDK path in Editor Settings.");
+ err += TTR("Missing 'build-tools' directory!");
+ err += "\n";
+ valid = false;
+ }
+
+ // Validate that apksigner is available
+ String apksigner_path = get_apksigner_path();
+ if (!FileAccess::exists(apksigner_path)) {
+ err += TTR("Unable to find Android SDK build-tools' apksigner command.");
+ err += TTR("Please check in the Android SDK directory specified in Editor Settings.");
+ err += "\n";
valid = false;
}
}
@@ -2019,7 +2127,7 @@ public:
// Ensure that `Use Custom Build` is enabled if a plugin is selected.
String enabled_plugins_names = get_plugins_names(get_enabled_plugins(p_preset));
bool custom_build_enabled = p_preset->get("custom_template/use_custom_build");
- if (!enabled_plugins_names.empty() && !custom_build_enabled) {
+ if (!enabled_plugins_names.is_empty() && !custom_build_enabled) {
valid = false;
err += TTR("\"Use Custom Build\" must be enabled to use the plugins.");
err += "\n";
@@ -2050,7 +2158,7 @@ public:
}
}
- if (int(p_preset->get("custom_template/export_format")) == 1 && /*AAB*/
+ if (int(p_preset->get("custom_template/export_format")) == EXPORT_FORMAT_AAB &&
!bool(p_preset->get("custom_template/use_custom_build"))) {
valid = false;
err += TTR("\"Export AAB\" is only valid when \"Use Custom Build\" is enabled.");
@@ -2068,7 +2176,7 @@ public:
return list;
}
- inline bool is_clean_build_required(Vector<PluginConfig> enabled_plugins) {
+ inline bool is_clean_build_required(Vector<PluginConfigAndroid> enabled_plugins) {
String plugin_names = get_plugins_names(enabled_plugins);
bool first_build = last_custom_build_time == 0;
bool have_plugins_changed = false;
@@ -2168,16 +2276,17 @@ public:
}
}
- Error sign_apk(const Ref<EditorExportPreset> &p_preset, bool p_debug, String export_path, EditorProgress ep) {
+ Error sign_apk(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &export_path, EditorProgress &ep) {
int export_format = int(p_preset->get("custom_template/export_format"));
- String export_label = export_format == 1 ? "AAB" : "APK";
+ String export_label = export_format == EXPORT_FORMAT_AAB ? "AAB" : "APK";
String release_keystore = p_preset->get("keystore/release");
String release_username = p_preset->get("keystore/release_user");
String release_password = p_preset->get("keystore/release_password");
- String jarsigner = EditorSettings::get_singleton()->get("export/android/jarsigner");
- if (!FileAccess::exists(jarsigner)) {
- EditorNode::add_io_error("'jarsigner' could not be found.\nPlease supply a path in the Editor Settings.\nThe resulting " + export_label + " is unsigned.");
+ String apksigner = get_apksigner_path();
+ print_verbose("Starting signing of the " + export_label + " binary using " + apksigner);
+ if (!FileAccess::exists(apksigner)) {
+ EditorNode::add_io_error("'apksigner' could not be found.\nPlease check the command is available in the Android SDK build-tools directory.\nThe resulting " + export_label + " is unsigned.");
return OK;
}
@@ -2189,13 +2298,13 @@ public:
password = p_preset->get("keystore/debug_password");
user = p_preset->get("keystore/debug_user");
- if (keystore.empty()) {
+ if (keystore.is_empty()) {
keystore = EditorSettings::get_singleton()->get("export/android/debug_keystore");
password = EditorSettings::get_singleton()->get("export/android/debug_keystore_pass");
user = EditorSettings::get_singleton()->get("export/android/debug_keystore_user");
}
- if (ep.step("Signing debug " + export_label + "...", 103)) {
+ if (ep.step("Signing debug " + export_label + "...", 104)) {
return ERR_SKIP;
}
@@ -2204,7 +2313,7 @@ public:
password = release_password;
user = release_username;
- if (ep.step("Signing release " + export_label + "...", 103)) {
+ if (ep.step("Signing release " + export_label + "...", 104)) {
return ERR_SKIP;
}
}
@@ -2215,58 +2324,76 @@ public:
}
List<String> args;
- args.push_back("-digestalg");
- args.push_back("SHA-256");
- args.push_back("-sigalg");
- args.push_back("SHA256withRSA");
- String tsa_url = EditorSettings::get_singleton()->get("export/android/timestamping_authority_url");
- if (tsa_url != "") {
- args.push_back("-tsa");
- args.push_back(tsa_url);
- }
- args.push_back("-verbose");
- args.push_back("-keystore");
+ args.push_back("sign");
+ args.push_back("--verbose");
+ args.push_back("--ks");
args.push_back(keystore);
- args.push_back("-storepass");
- args.push_back(password);
- args.push_back(export_path);
+ args.push_back("--ks-pass");
+ args.push_back("pass:" + password);
+ args.push_back("--ks-key-alias");
args.push_back(user);
+ args.push_back(export_path);
+ if (p_debug) {
+ // We only print verbose logs for debug builds to avoid leaking release keystore credentials.
+ print_verbose("Signing debug binary using: " + String("\n") + apksigner + " " + join_list(args, String(" ")));
+ }
int retval;
- OS::get_singleton()->execute(jarsigner, args, true, NULL, NULL, &retval);
+ OS::get_singleton()->execute(apksigner, args, nullptr, &retval);
if (retval) {
- EditorNode::add_io_error("'jarsigner' returned with error #" + itos(retval));
+ EditorNode::add_io_error("'apksigner' returned with error #" + itos(retval));
return ERR_CANT_CREATE;
}
- if (ep.step("Verifying " + export_label + "...", 104)) {
+ if (ep.step("Verifying " + export_label + "...", 105)) {
return ERR_SKIP;
}
args.clear();
- args.push_back("-verify");
- args.push_back("-keystore");
- args.push_back(keystore);
+ args.push_back("verify");
+ args.push_back("--verbose");
args.push_back(export_path);
- args.push_back("-verbose");
+ if (p_debug) {
+ print_verbose("Verifying signed build using: " + String("\n") + apksigner + " " + join_list(args, String(" ")));
+ }
- OS::get_singleton()->execute(jarsigner, args, true, NULL, NULL, &retval);
+ OS::get_singleton()->execute(apksigner, args, nullptr, &retval);
if (retval) {
- EditorNode::add_io_error("'jarsigner' verification of " + export_label + " failed. Make sure to use a jarsigner from OpenJDK 8.");
+ EditorNode::add_io_error("'apksigner' verification of " + export_label + " failed.");
return ERR_CANT_CREATE;
}
+
+ print_verbose("Successfully completed signing build.");
return OK;
}
void _clear_assets_directory() {
DirAccessRef da_res = DirAccess::create(DirAccess::ACCESS_RESOURCES);
if (da_res->dir_exists("res://android/build/assets")) {
+ print_verbose("Clearing assets directory..");
DirAccessRef da_assets = DirAccess::open("res://android/build/assets");
da_assets->erase_contents_recursive();
da_res->remove("res://android/build/assets");
}
}
+ String join_list(List<String> parts, const String &separator) const {
+ String ret;
+ for (int i = 0; i < parts.size(); ++i) {
+ if (i > 0) {
+ ret += separator;
+ }
+ ret += parts[i];
+ }
+ return ret;
+ }
+
virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0) override {
+ int export_format = int(p_preset->get("custom_template/export_format"));
+ bool should_sign = p_preset->get("package/signed");
+ return export_project_helper(p_preset, p_debug, p_path, export_format, should_sign, p_flags);
+ }
+
+ Error export_project_helper(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int export_format, bool should_sign, int p_flags) {
ExportNotifier notifier(*this, p_preset, p_debug, p_path, p_flags);
String src_apk;
@@ -2275,15 +2402,22 @@ public:
EditorProgress ep("export", "Exporting for Android", 105, true);
bool use_custom_build = bool(p_preset->get("custom_template/use_custom_build"));
- int export_format = int(p_preset->get("custom_template/export_format"));
bool p_give_internet = p_flags & (DEBUG_FLAG_DUMB_CLIENT | DEBUG_FLAG_REMOTE_DEBUG);
- bool _signed = p_preset->get("package/signed");
bool apk_expansion = p_preset->get("apk_expansion/enable");
Vector<String> enabled_abis = get_enabled_abis(p_preset);
+ print_verbose("Exporting for Android...");
+ print_verbose("- debug build: " + bool_to_string(p_debug));
+ print_verbose("- export path: " + p_path);
+ print_verbose("- export format: " + itos(export_format));
+ print_verbose("- sign build: " + bool_to_string(should_sign));
+ print_verbose("- custom build enabled: " + bool_to_string(use_custom_build));
+ print_verbose("- apk expansion enabled: " + bool_to_string(apk_expansion));
+ print_verbose("- enabled abis: " + String(",").join(enabled_abis));
+
Ref<Image> splash_image;
Ref<Image> splash_bg_color_image;
- load_splash_refs(splash_image, splash_bg_color_image);
+ String processed_splash_config_xml = load_splash_refs(splash_image, splash_bg_color_image);
Ref<Image> main_image;
Ref<Image> foreground;
@@ -2295,7 +2429,7 @@ public:
// Write command line flags into the command_line_flags variable.
get_command_line_flags(p_preset, p_path, p_flags, command_line_flags);
- if (export_format == 1) {
+ if (export_format == EXPORT_FORMAT_AAB) {
if (!p_path.ends_with(".aab")) {
EditorNode::get_singleton()->show_warning(TTR("Invalid filename! Android App Bundle requires the *.aab extension."));
return ERR_UNCONFIGURED;
@@ -2305,33 +2439,37 @@ public:
return ERR_UNCONFIGURED;
}
}
- if (export_format == 0 && !p_path.ends_with(".apk")) {
+ if (export_format == EXPORT_FORMAT_APK && !p_path.ends_with(".apk")) {
EditorNode::get_singleton()->show_warning(
TTR("Invalid filename! Android APK requires the *.apk extension."));
return ERR_UNCONFIGURED;
}
- if (export_format > 1 || export_format < 0) {
+ if (export_format > EXPORT_FORMAT_AAB || export_format < EXPORT_FORMAT_APK) {
EditorNode::add_io_error("Unsupported export format!\n");
return ERR_UNCONFIGURED; //TODO: is this the right error?
}
if (use_custom_build) {
+ print_verbose("Starting custom build..");
//test that installed build version is alright
{
+ print_verbose("Checking build version..");
FileAccessRef f = FileAccess::open("res://android/.build_version", FileAccess::READ);
if (!f) {
EditorNode::get_singleton()->show_warning(TTR("Trying to build from a custom built template, but no version info for it exists. Please reinstall from the 'Project' menu."));
return ERR_UNCONFIGURED;
}
String version = f->get_line().strip_edges();
+ print_verbose("- build version: " + version);
f->close();
if (version != VERSION_FULL_CONFIG) {
EditorNode::get_singleton()->show_warning(vformat(TTR("Android build version mismatch:\n Template installed: %s\n Godot Version: %s\nPlease reinstall Android build template from 'Project' menu."), version, VERSION_FULL_CONFIG));
return ERR_UNCONFIGURED;
}
}
- String sdk_path = EDITOR_GET("export/android/custom_build_sdk_path");
- ERR_FAIL_COND_V_MSG(sdk_path == "", ERR_UNCONFIGURED, "Android SDK path must be configured in Editor Settings at 'export/android/custom_build_sdk_path'.");
+ String sdk_path = EDITOR_GET("export/android/android_sdk_path");
+ ERR_FAIL_COND_V_MSG(sdk_path.is_empty(), ERR_UNCONFIGURED, "Android SDK path must be configured in Editor Settings at 'export/android/android_sdk_path'.");
+ print_verbose("Android sdk path: " + sdk_path);
// TODO: should we use "package/name" or "application/config/name"?
String project_name = get_project_name(p_preset->get("package/name"));
@@ -2340,27 +2478,31 @@ public:
EditorNode::add_io_error("Unable to overwrite res://android/build/res/*.xml files with project name");
}
// Copies the project icon files into the appropriate Gradle project directory.
- _copy_icons_to_gradle_project(p_preset, splash_image, splash_bg_color_image, main_image, foreground, background);
+ _copy_icons_to_gradle_project(p_preset, processed_splash_config_xml, splash_image, splash_bg_color_image, main_image, foreground, background);
// Write an AndroidManifest.xml file into the Gradle project directory.
_write_tmp_manifest(p_preset, p_give_internet, p_debug);
//stores all the project files inside the Gradle project directory. Also includes all ABIs
_clear_assets_directory();
if (!apk_expansion) {
+ print_verbose("Exporting project files..");
err = export_project_files(p_preset, rename_and_store_file_in_gradle_project, NULL, ignore_so_file);
if (err != OK) {
EditorNode::add_io_error("Could not export project files to gradle project\n");
return err;
}
} else {
+ print_verbose("Saving apk expansion file..");
err = save_apk_expansion_file(p_preset, p_path);
if (err != OK) {
EditorNode::add_io_error("Could not write expansion package file!");
return err;
}
}
+ print_verbose("Storing command line flags..");
store_file_at_path("res://android/build/assets/_cl_", command_line_flags);
+ print_verbose("Updating ANDROID_HOME environment to " + sdk_path);
OS::get_singleton()->set_environment("ANDROID_HOME", sdk_path); //set and overwrite if required
String build_command;
@@ -2377,12 +2519,12 @@ public:
String version_code = itos(p_preset->get("version/code"));
String version_name = p_preset->get("version/name");
String enabled_abi_string = String("|").join(enabled_abis);
- String sign_flag = _signed ? "true" : "false";
+ String sign_flag = should_sign ? "true" : "false";
String zipalign_flag = "true";
- Vector<PluginConfig> enabled_plugins = get_enabled_plugins(p_preset);
- String local_plugins_binaries = get_plugins_binaries(BINARY_TYPE_LOCAL, enabled_plugins);
- String remote_plugins_binaries = get_plugins_binaries(BINARY_TYPE_REMOTE, enabled_plugins);
+ Vector<PluginConfigAndroid> enabled_plugins = get_enabled_plugins(p_preset);
+ String local_plugins_binaries = get_plugins_binaries(PluginConfigAndroid::BINARY_TYPE_LOCAL, enabled_plugins);
+ String remote_plugins_binaries = get_plugins_binaries(PluginConfigAndroid::BINARY_TYPE_REMOTE, enabled_plugins);
String custom_maven_repos = get_plugins_custom_maven_repos(enabled_plugins);
bool clean_build_required = is_clean_build_required(enabled_plugins);
@@ -2392,14 +2534,16 @@ public:
}
String build_type = p_debug ? "Debug" : "Release";
- if (export_format == 1) {
+ if (export_format == EXPORT_FORMAT_AAB) {
String bundle_build_command = vformat("bundle%s", build_type);
cmdline.push_back(bundle_build_command);
- } else if (export_format == 0) {
+ } else if (export_format == EXPORT_FORMAT_APK) {
String apk_build_command = vformat("assemble%s", build_type);
cmdline.push_back(apk_build_command);
}
+ cmdline.push_back("-p"); // argument to specify the start directory.
+ cmdline.push_back(build_path); // start directory.
cmdline.push_back("-Pexport_package_name=" + package_name); // argument to specify the package name.
cmdline.push_back("-Pexport_version_code=" + version_code); // argument to specify the version code.
cmdline.push_back("-Pexport_version_name=" + version_name); // argument to specify the version name.
@@ -2409,7 +2553,14 @@ public:
cmdline.push_back("-Pplugins_maven_repos=" + custom_maven_repos); // argument to specify the list of custom maven repos for the plugins dependencies.
cmdline.push_back("-Pperform_zipalign=" + zipalign_flag); // argument to specify whether the build should be zipaligned.
cmdline.push_back("-Pperform_signing=" + sign_flag); // argument to specify whether the build should be signed.
- if (_signed && !p_debug) {
+
+ // NOTE: The release keystore is not included in the verbose logging
+ // to avoid accidentally leaking sensitive information when sharing verbose logs for troubleshooting.
+ // Any non-sensitive additions to the command line arguments must be done above this section.
+ // Sensitive additions must be done below the logging statement.
+ print_verbose("Build Android project using gradle command: " + String("\n") + build_command + " " + join_list(cmdline, String(" ")));
+
+ if (should_sign && !p_debug) {
// Pass the release keystore info as well
String release_keystore = p_preset->get("keystore/release");
String release_username = p_preset->get("keystore/release_user");
@@ -2423,8 +2574,6 @@ public:
cmdline.push_back("-Prelease_keystore_alias=" + release_username); // argument to specify the release keystore alias.
cmdline.push_back("-Prelease_keystore_password=" + release_password); // argument to specity the release keystore password.
}
- cmdline.push_back("-p"); // argument to specify the start directory.
- cmdline.push_back(build_path); // start directory.
int result = EditorNode::get_singleton()->execute_and_show_output(TTR("Building Android Project (gradle)"), build_command, cmdline);
if (result != 0) {
@@ -2434,9 +2583,9 @@ public:
List<String> copy_args;
String copy_command;
- if (export_format == 1) {
+ if (export_format == EXPORT_FORMAT_AAB) {
copy_command = vformat("copyAndRename%sAab", build_type);
- } else if (export_format == 0) {
+ } else if (export_format == EXPORT_FORMAT_APK) {
copy_command = vformat("copyAndRename%sApk", build_type);
}
@@ -2455,15 +2604,18 @@ public:
copy_args.push_back("-Pexport_path=file:" + export_path);
copy_args.push_back("-Pexport_filename=" + export_filename);
+ print_verbose("Copying Android binary using gradle command: " + String("\n") + build_command + " " + join_list(copy_args, String(" ")));
int copy_result = EditorNode::get_singleton()->execute_and_show_output(TTR("Moving output"), build_command, copy_args);
if (copy_result != 0) {
EditorNode::get_singleton()->show_warning(TTR("Unable to copy and rename export file, check gradle project directory for outputs."));
return ERR_CANT_CREATE;
}
+ print_verbose("Successfully completed Android custom build.");
return OK;
}
// This is the start of the Legacy build system
+ print_verbose("Starting legacy build system..");
if (p_debug)
src_apk = p_preset->get("custom_template/debug");
else
@@ -2549,27 +2701,27 @@ public:
}
// Process the splash image
- if (file == SPLASH_IMAGE_EXPORT_PATH && splash_image.is_valid() && !splash_image->empty()) {
+ if (file == SPLASH_IMAGE_EXPORT_PATH && splash_image.is_valid() && !splash_image->is_empty()) {
_load_image_data(splash_image, data);
}
// Process the splash bg color image
- if (file == SPLASH_BG_COLOR_PATH && splash_bg_color_image.is_valid() && !splash_bg_color_image->empty()) {
+ if (file == SPLASH_BG_COLOR_PATH && splash_bg_color_image.is_valid() && !splash_bg_color_image->is_empty()) {
_load_image_data(splash_bg_color_image, data);
}
for (int i = 0; i < icon_densities_count; ++i) {
- if (main_image.is_valid() && !main_image->empty()) {
+ if (main_image.is_valid() && !main_image->is_empty()) {
if (file == launcher_icons[i].export_path) {
_process_launcher_icons(file, main_image, launcher_icons[i].dimensions, data);
}
}
- if (foreground.is_valid() && !foreground->empty()) {
+ if (foreground.is_valid() && !foreground->is_empty()) {
if (file == launcher_adaptive_icon_foregrounds[i].export_path) {
_process_launcher_icons(file, foreground, launcher_adaptive_icon_foregrounds[i].dimensions, data);
}
}
- if (background.is_valid() && !background->empty()) {
+ if (background.is_valid() && !background->is_empty()) {
if (file == launcher_adaptive_icon_backgrounds[i].export_path) {
_process_launcher_icons(file, background, launcher_adaptive_icon_backgrounds[i].dimensions, data);
}
@@ -2590,7 +2742,7 @@ public:
}
}
- if (file.begins_with("META-INF") && _signed) {
+ if (file.begins_with("META-INF") && should_sign) {
skip = true;
}
@@ -2620,7 +2772,7 @@ public:
ret = unzGoToNextFile(pkg);
}
- if (!invalid_abis.empty()) {
+ if (!invalid_abis.is_empty()) {
String unsupported_arch = String(", ").join(invalid_abis);
EditorNode::add_io_error("Missing libraries in the export template for the selected architectures: " + unsupported_arch + ".\n" +
"Please build a template with all required libraries, or uncheck the missing architectures in the export preset.");
@@ -2678,18 +2830,13 @@ public:
CLEANUP_AND_RETURN(err);
}
- if (_signed) {
- err = sign_apk(p_preset, p_debug, tmp_unaligned_path, ep);
- if (err != OK) {
- CLEANUP_AND_RETURN(err);
- }
- }
-
- // Let's zip-align (must be done after signing)
+ // Let's zip-align (must be done before signing)
static const int ZIP_ALIGNMENT = 4;
- if (ep.step("Aligning APK...", 105)) {
+ // If we're not signing the apk, then the next step should be the last.
+ const int next_step = should_sign ? 103 : 105;
+ if (ep.step("Aligning APK...", next_step)) {
CLEANUP_AND_RETURN(ERR_SKIP);
}
@@ -2763,6 +2910,15 @@ public:
zipClose(final_apk, nullptr);
unzClose(tmp_unaligned);
+ if (should_sign) {
+ // Signing must be done last as any additional modifications to the
+ // file will invalidate the signature.
+ err = sign_apk(p_preset, p_debug, p_path, ep);
+ if (err != OK) {
+ CLEANUP_AND_RETURN(err);
+ }
+ }
+
CLEANUP_AND_RETURN(OK);
}
@@ -2783,16 +2939,14 @@ public:
run_icon.instance();
run_icon->create_from_image(img);
- devices_changed = true;
- plugins_changed = true;
- quit_request = false;
- check_for_changes_thread = Thread::create(_check_for_changes_poll_thread, this);
+ devices_changed.set();
+ plugins_changed.set();
+ check_for_changes_thread.start(_check_for_changes_poll_thread, this);
}
~EditorExportPlatformAndroid() {
- quit_request = true;
- Thread::wait_to_finish(check_for_changes_thread);
- memdelete(check_for_changes_thread);
+ quit_request.set();
+ check_for_changes_thread.wait_to_finish();
}
};
@@ -2802,19 +2956,14 @@ void register_android_exporter() {
exe_ext = "*.exe";
}
- EDITOR_DEF("export/android/adb", "");
- EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/android/adb", PROPERTY_HINT_GLOBAL_FILE, exe_ext));
- EDITOR_DEF("export/android/jarsigner", "");
- EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/android/jarsigner", PROPERTY_HINT_GLOBAL_FILE, exe_ext));
+ EDITOR_DEF("export/android/android_sdk_path", "");
+ EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/android/android_sdk_path", PROPERTY_HINT_GLOBAL_DIR));
EDITOR_DEF("export/android/debug_keystore", "");
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/android/debug_keystore", PROPERTY_HINT_GLOBAL_FILE, "*.keystore,*.jks"));
EDITOR_DEF("export/android/debug_keystore_user", "androiddebugkey");
EDITOR_DEF("export/android/debug_keystore_pass", "android");
EDITOR_DEF("export/android/force_system_user", false);
- EDITOR_DEF("export/android/custom_build_sdk_path", "");
- EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/android/custom_build_sdk_path", PROPERTY_HINT_GLOBAL_DIR));
- EDITOR_DEF("export/android/timestamping_authority_url", "");
EDITOR_DEF("export/android/shutdown_adb_on_exit", true);
Ref<EditorExportPlatformAndroid> exporter = Ref<EditorExportPlatformAndroid>(memnew(EditorExportPlatformAndroid));
diff --git a/platform/android/export/export.h b/platform/android/export/export.h
index d11ab9f49e..28e09f41db 100644
--- a/platform/android/export/export.h
+++ b/platform/android/export/export.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/export/gradle_export_util.h b/platform/android/export/gradle_export_util.h
index a9f38869e0..ce6a3c96db 100644
--- a/platform/android/export/gradle_export_util.h
+++ b/platform/android/export/gradle_export_util.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -146,6 +146,9 @@ Error store_string_at_path(const String &p_path, const String &p_data) {
String dir = p_path.get_base_dir();
Error err = create_directory(dir);
if (err != OK) {
+ if (OS::get_singleton()->is_stdout_verbose()) {
+ print_error("Unable to write data into " + p_path);
+ }
return err;
}
FileAccess *fa = FileAccess::open(p_path, FileAccess::WRITE);
@@ -162,12 +165,14 @@ Error store_string_at_path(const String &p_path, const String &p_data) {
// This method will be called ONLY when custom build is enabled.
Error rename_and_store_file_in_gradle_project(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key) {
String dst_path = p_path.replace_first("res://", "res://android/build/assets/");
+ print_verbose("Saving project files from " + p_path + " into " + dst_path);
Error err = store_file_at_path(dst_path, p_data);
return err;
}
// Creates strings.xml files inside the gradle project for different locales.
Error _create_project_name_strings_files(const Ref<EditorExportPreset> &p_preset, const String &project_name) {
+ print_verbose("Creating strings resources for supported locales for project " + project_name);
// Stores the string into the default values directory.
String processed_default_xml_string = vformat(godot_project_name_xml_string, project_name.xml_escape(true));
store_string_at_path("res://android/build/res/values/godot_project_name_string.xml", processed_default_xml_string);
@@ -175,6 +180,9 @@ Error _create_project_name_strings_files(const Ref<EditorExportPreset> &p_preset
// Searches the Gradle project res/ directory to find all supported locales
DirAccessRef da = DirAccess::open("res://android/build/res");
if (!da) {
+ if (OS::get_singleton()->is_stdout_verbose()) {
+ print_error("Unable to open Android resources directory.");
+ }
return ERR_CANT_OPEN;
}
da->list_dir_begin();
@@ -193,6 +201,7 @@ Error _create_project_name_strings_files(const Ref<EditorExportPreset> &p_preset
if (ProjectSettings::get_singleton()->has_setting(property_name)) {
String locale_project_name = ProjectSettings::get_singleton()->get(property_name);
String processed_xml_string = vformat(godot_project_name_xml_string, locale_project_name.xml_escape(true));
+ print_verbose("Storing project name for locale " + locale + " under " + locale_directory);
store_string_at_path(locale_directory, processed_xml_string);
} else {
// TODO: Once the legacy build system is deprecated we don't need to have xml files for this else branch
@@ -208,8 +217,8 @@ String bool_to_string(bool v) {
}
String _get_gles_tag() {
- bool min_gles3 = ProjectSettings::get_singleton()->get("rendering/quality/driver/driver_name") == "GLES3" &&
- !ProjectSettings::get_singleton()->get("rendering/quality/driver/fallback_to_gles2");
+ bool min_gles3 = ProjectSettings::get_singleton()->get("rendering/driver/driver_name") == "GLES3" &&
+ !ProjectSettings::get_singleton()->get("rendering/driver/fallback_to_gles2");
return min_gles3 ? " <uses-feature android:glEsVersion=\"0x00030000\" android:required=\"true\" />\n" : "";
}
@@ -261,7 +270,7 @@ String _get_instrumentation_tag(const Ref<EditorExportPreset> &p_preset) {
}
String _get_plugins_tag(const String &plugins_names) {
- if (!plugins_names.empty()) {
+ if (!plugins_names.is_empty()) {
return vformat(" <meta-data tools:node=\"replace\" android:name=\"plugins\" android:value=\"%s\" />\n", plugins_names);
} else {
return " <meta-data tools:node=\"remove\" android:name=\"plugins\" />\n";
diff --git a/platform/android/file_access_android.cpp b/platform/android/file_access_android.cpp
index 2446ca2829..165d5da3ae 100644
--- a/platform/android/file_access_android.cpp
+++ b/platform/android/file_access_android.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -157,11 +157,6 @@ bool FileAccessAndroid::file_exists(const String &p_path) {
return true;
}
-FileAccessAndroid::FileAccessAndroid() {
- a = nullptr;
- eof = false;
-}
-
FileAccessAndroid::~FileAccessAndroid() {
close();
}
diff --git a/platform/android/file_access_android.h b/platform/android/file_access_android.h
index a347c63ffb..56010c918a 100644
--- a/platform/android/file_access_android.h
+++ b/platform/android/file_access_android.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -39,10 +39,10 @@
class FileAccessAndroid : public FileAccess {
static FileAccess *create_android();
- mutable AAsset *a;
- mutable size_t len;
- mutable size_t pos;
- mutable bool eof;
+ mutable AAsset *a = nullptr;
+ mutable size_t len = 0;
+ mutable size_t pos = 0;
+ mutable bool eof = false;
public:
static AAssetManager *asset_manager;
@@ -74,7 +74,6 @@ public:
//static void make_default();
- FileAccessAndroid();
~FileAccessAndroid();
};
diff --git a/platform/android/file_access_jandroid.cpp b/platform/android/file_access_jandroid.cpp
deleted file mode 100644
index df8b57fd3a..0000000000
--- a/platform/android/file_access_jandroid.cpp
+++ /dev/null
@@ -1,197 +0,0 @@
-/*************************************************************************/
-/* file_access_jandroid.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "file_access_jandroid.h"
-#include "core/os/os.h"
-#include "thread_jandroid.h"
-#include <unistd.h>
-
-jobject FileAccessJAndroid::io = nullptr;
-jclass FileAccessJAndroid::cls;
-jmethodID FileAccessJAndroid::_file_open = 0;
-jmethodID FileAccessJAndroid::_file_get_size = 0;
-jmethodID FileAccessJAndroid::_file_seek = 0;
-jmethodID FileAccessJAndroid::_file_read = 0;
-jmethodID FileAccessJAndroid::_file_tell = 0;
-jmethodID FileAccessJAndroid::_file_eof = 0;
-jmethodID FileAccessJAndroid::_file_close = 0;
-
-FileAccess *FileAccessJAndroid::create_jandroid() {
- return memnew(FileAccessJAndroid);
-}
-
-Error FileAccessJAndroid::_open(const String &p_path, int p_mode_flags) {
- if (is_open())
- close();
-
- String path = fix_path(p_path).simplify_path();
- if (path.begins_with("/"))
- path = path.substr(1, path.length());
- else if (path.begins_with("res://"))
- path = path.substr(6, path.length());
-
- JNIEnv *env = ThreadAndroid::get_env();
-
- jstring js = env->NewStringUTF(path.utf8().get_data());
- int res = env->CallIntMethod(io, _file_open, js, (p_mode_flags & WRITE) ? true : false);
- env->DeleteLocalRef(js);
-
- OS::get_singleton()->print("fopen: '%s' ret %i\n", path.utf8().get_data(), res);
-
- if (res <= 0)
- return ERR_FILE_CANT_OPEN;
- id = res;
-
- return OK;
-}
-
-void FileAccessJAndroid::close() {
- if (!is_open())
- return;
-
- JNIEnv *env = ThreadAndroid::get_env();
-
- env->CallVoidMethod(io, _file_close, id);
- id = 0;
-}
-
-bool FileAccessJAndroid::is_open() const {
- return id != 0;
-}
-
-void FileAccessJAndroid::seek(size_t p_position) {
- JNIEnv *env = ThreadAndroid::get_env();
-
- ERR_FAIL_COND_MSG(!is_open(), "File must be opened before use.");
- env->CallVoidMethod(io, _file_seek, id, p_position);
-}
-
-void FileAccessJAndroid::seek_end(int64_t p_position) {
- ERR_FAIL_COND_MSG(!is_open(), "File must be opened before use.");
-
- seek(get_len());
-}
-
-size_t FileAccessJAndroid::get_position() const {
- JNIEnv *env = ThreadAndroid::get_env();
- ERR_FAIL_COND_V_MSG(!is_open(), 0, "File must be opened before use.");
- return env->CallIntMethod(io, _file_tell, id);
-}
-
-size_t FileAccessJAndroid::get_len() const {
- JNIEnv *env = ThreadAndroid::get_env();
- ERR_FAIL_COND_V_MSG(!is_open(), 0, "File must be opened before use.");
- return env->CallIntMethod(io, _file_get_size, id);
-}
-
-bool FileAccessJAndroid::eof_reached() const {
- JNIEnv *env = ThreadAndroid::get_env();
- ERR_FAIL_COND_V_MSG(!is_open(), 0, "File must be opened before use.");
- return env->CallIntMethod(io, _file_eof, id);
-}
-
-uint8_t FileAccessJAndroid::get_8() const {
- ERR_FAIL_COND_V_MSG(!is_open(), 0, "File must be opened before use.");
- uint8_t byte;
- get_buffer(&byte, 1);
- return byte;
-}
-
-int FileAccessJAndroid::get_buffer(uint8_t *p_dst, int p_length) const {
- ERR_FAIL_COND_V_MSG(!is_open(), 0, "File must be opened before use.");
- if (p_length == 0)
- return 0;
- JNIEnv *env = ThreadAndroid::get_env();
-
- jbyteArray jca = (jbyteArray)env->CallObjectMethod(io, _file_read, id, p_length);
-
- int len = env->GetArrayLength(jca);
- env->GetByteArrayRegion(jca, 0, len, (jbyte *)p_dst);
- env->DeleteLocalRef((jobject)jca);
-
- return len;
-}
-
-Error FileAccessJAndroid::get_error() const {
- if (eof_reached())
- return ERR_FILE_EOF;
- return OK;
-}
-
-void FileAccessJAndroid::flush() {
-}
-
-void FileAccessJAndroid::store_8(uint8_t p_dest) {
-}
-
-bool FileAccessJAndroid::file_exists(const String &p_path) {
- JNIEnv *env = ThreadAndroid::get_env();
-
- String path = fix_path(p_path).simplify_path();
- if (path.begins_with("/"))
- path = path.substr(1, path.length());
- else if (path.begins_with("res://"))
- path = path.substr(6, path.length());
-
- jstring js = env->NewStringUTF(path.utf8().get_data());
- int res = env->CallIntMethod(io, _file_open, js, false);
- if (res <= 0) {
- env->DeleteLocalRef(js);
- return false;
- }
- env->CallVoidMethod(io, _file_close, res);
- env->DeleteLocalRef(js);
- return true;
-}
-
-void FileAccessJAndroid::setup(jobject p_io) {
- io = p_io;
- JNIEnv *env = ThreadAndroid::get_env();
-
- jclass c = env->GetObjectClass(io);
- cls = (jclass)env->NewGlobalRef(c);
-
- _file_open = env->GetMethodID(cls, "file_open", "(Ljava/lang/String;Z)I");
- _file_get_size = env->GetMethodID(cls, "file_get_size", "(I)I");
- _file_tell = env->GetMethodID(cls, "file_tell", "(I)I");
- _file_eof = env->GetMethodID(cls, "file_eof", "(I)Z");
- _file_seek = env->GetMethodID(cls, "file_seek", "(II)V");
- _file_read = env->GetMethodID(cls, "file_read", "(II)[B");
- _file_close = env->GetMethodID(cls, "file_close", "(I)V");
-}
-
-FileAccessJAndroid::FileAccessJAndroid() {
- id = 0;
-}
-
-FileAccessJAndroid::~FileAccessJAndroid() {
- if (is_open())
- close();
-}
diff --git a/platform/android/java/app/build.gradle b/platform/android/java/app/build.gradle
index 53d11fda5b..814cc30613 100644
--- a/platform/android/java/app/build.gradle
+++ b/platform/android/java/app/build.gradle
@@ -98,6 +98,8 @@ android {
disable 'MissingTranslation', 'UnusedResources'
}
+ ndkVersion versions.ndkVersion
+
packagingOptions {
exclude 'META-INF/LICENSE'
exclude 'META-INF/NOTICE'
diff --git a/platform/android/java/app/config.gradle b/platform/android/java/app/config.gradle
index 80cf6f7ede..202b3c35c0 100644
--- a/platform/android/java/app/config.gradle
+++ b/platform/android/java/app/config.gradle
@@ -1,5 +1,5 @@
ext.versions = [
- androidGradlePlugin: '4.1.0',
+ androidGradlePlugin: '4.0.1',
compileSdk : 29,
minSdk : 18,
targetSdk : 29,
@@ -7,7 +7,8 @@ ext.versions = [
supportCoreUtils : '1.0.0',
kotlinVersion : '1.4.10',
v4Support : '1.0.0',
- javaVersion : 1.8
+ javaVersion : 1.8,
+ ndkVersion : '21.4.7075529' // Also update 'platform/android/detect.py#get_project_ndk_version()' when this is updated.
]
diff --git a/platform/android/java/app/res/drawable/splash_drawable.xml b/platform/android/java/app/res/drawable/splash_drawable.xml
index 2794a40817..30627b998c 100644
--- a/platform/android/java/app/res/drawable/splash_drawable.xml
+++ b/platform/android/java/app/res/drawable/splash_drawable.xml
@@ -6,7 +6,7 @@
<item>
<bitmap
android:gravity="center"
+ android:filter="false"
android:src="@drawable/splash" />
</item>
-
</layer-list>
diff --git a/platform/android/java/app/src/com/godot/game/GodotApp.java b/platform/android/java/app/src/com/godot/game/GodotApp.java
index 51df70969e..955446b0c2 100644
--- a/platform/android/java/app/src/com/godot/game/GodotApp.java
+++ b/platform/android/java/app/src/com/godot/game/GodotApp.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/build.gradle b/platform/android/java/lib/build.gradle
index 89ce3d15e6..ca5153f7f6 100644
--- a/platform/android/java/lib/build.gradle
+++ b/platform/android/java/lib/build.gradle
@@ -13,6 +13,8 @@ android {
compileSdkVersion versions.compileSdk
buildToolsVersion versions.buildTools
+ ndkVersion versions.ndkVersion
+
defaultConfig {
minSdkVersion versions.minSdk
targetSdkVersion versions.targetSdk
@@ -68,7 +70,7 @@ android {
File sconsExecutableFile = null
def sconsName = "scons"
def sconsExts = (org.gradle.internal.os.OperatingSystem.current().isWindows()
- ? [".bat", ".exe"]
+ ? [".bat", ".cmd", ".ps1", ".exe"]
: [""])
logger.lifecycle("Looking for $sconsName executable path")
for (ext in sconsExts) {
diff --git a/platform/android/java/lib/src/org/godotengine/godot/Dictionary.java b/platform/android/java/lib/src/org/godotengine/godot/Dictionary.java
index 8b7a9c6c74..0572cf3589 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/Dictionary.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/Dictionary.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java b/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java
index 5aa48d87da..4e67402c63 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
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 3bbe35091c..7d396b402e 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/Godot.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -988,4 +988,9 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
public void initInputDevices() {
mRenderView.initInputDevices();
}
+
+ @Keep
+ private GodotRenderView getRenderView() { // used by native side to get renderView
+ return mRenderView;
+ }
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java b/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java
index a3dae15980..9784d51182 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderService.java b/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderService.java
index 434da95bc0..d33faab641 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderService.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderService.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java b/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java
index d731e080c4..63c91561ff 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -144,6 +144,11 @@ public class GodotGLRenderView extends GLSurfaceView implements GodotRenderView
return inputHandler.onGenericMotionEvent(event) || super.onGenericMotionEvent(event);
}
+ @Override
+ public boolean onCapturedPointerEvent(MotionEvent event) {
+ return inputHandler.onGenericMotionEvent(event);
+ }
+
private void init(XRMode xrMode, boolean translucent, int depth, int stencil) {
setPreserveEGLContextOnPause(true);
setFocusableInTouchMode(true);
@@ -183,15 +188,15 @@ public class GodotGLRenderView extends GLSurfaceView implements GodotRenderView
if (GLUtils.use_32) {
setEGLConfigChooser(translucent ?
- new RegularFallbackConfigChooser(8, 8, 8, 8, 24, stencil,
+ new RegularFallbackConfigChooser(8, 8, 8, 8, 24, stencil,
new RegularConfigChooser(8, 8, 8, 8, 16, stencil)) :
- new RegularFallbackConfigChooser(8, 8, 8, 8, 24, stencil,
+ new RegularFallbackConfigChooser(8, 8, 8, 8, 24, stencil,
new RegularConfigChooser(5, 6, 5, 0, 16, stencil)));
} else {
setEGLConfigChooser(translucent ?
- new RegularConfigChooser(8, 8, 8, 8, 16, stencil) :
- new RegularConfigChooser(5, 6, 5, 0, 16, stencil));
+ new RegularConfigChooser(8, 8, 8, 8, 16, stencil) :
+ new RegularConfigChooser(5, 6, 5, 0, 16, stencil));
}
break;
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java
index 894009e30f..c7c7c1b40c 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotInstrumentation.java b/platform/android/java/lib/src/org/godotengine/godot/GodotInstrumentation.java
index 965e616ef3..7f5fd8627c 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotInstrumentation.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotInstrumentation.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java b/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java
index 6ccbe91e60..534a50e9ed 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java b/platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java
index 68b8a16641..2047c88070 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java b/platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java
index 64395f7d1e..59bdbf7f8d 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java b/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java
index 6cd5ca7b4e..2e59dbc0d0 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -120,6 +120,11 @@ public class GodotVulkanRenderView extends VkSurfaceView implements GodotRenderV
}
@Override
+ public boolean onCapturedPointerEvent(MotionEvent event) {
+ return mInputHandler.onGenericMotionEvent(event);
+ }
+
+ @Override
public void onResume() {
super.onResume();
diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java
index c95339c583..d1e8ae5ca9 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java
index fb151fa504..2c39d06832 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java
index f3e985f944..435b8b325f 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -38,6 +38,8 @@ import org.godotengine.godot.input.InputManagerCompat.InputDeviceListener;
import android.os.Build;
import android.util.Log;
+import android.util.SparseArray;
+import android.util.SparseIntArray;
import android.view.InputDevice;
import android.view.InputDevice.MotionRange;
import android.view.KeyEvent;
@@ -46,17 +48,24 @@ import android.view.MotionEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
+import java.util.Map;
+import java.util.Set;
/**
* Handles input related events for the {@link GodotRenderView} view.
*/
public class GodotInputHandler implements InputDeviceListener {
- private final ArrayList<Joystick> mJoysticksDevices = new ArrayList<Joystick>();
-
private final GodotRenderView mRenderView;
private final InputManagerCompat mInputManager;
+ private final String tag = this.getClass().getSimpleName();
+
+ private final SparseIntArray mJoystickIds = new SparseIntArray(4);
+ private final SparseArray<Joystick> mJoysticksDevices = new SparseArray<Joystick>(4);
+
public GodotInputHandler(GodotRenderView godotView) {
mRenderView = godotView;
mInputManager = InputManagerCompat.Factory.getInputManager(mRenderView.getView().getContext());
@@ -82,19 +91,20 @@ public class GodotInputHandler implements InputDeviceListener {
if (keyCode == KeyEvent.KEYCODE_VOLUME_UP || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
return false;
- };
+ }
int source = event.getSource();
if (isKeyEvent_GameDevice(source)) {
- final int button = getGodotButton(keyCode);
- final int device_id = findJoystickDevice(event.getDeviceId());
-
// Check if the device exists
- if (device_id > -1) {
+ final int deviceId = event.getDeviceId();
+ if (mJoystickIds.indexOfKey(deviceId) >= 0) {
+ final int button = getGodotButton(keyCode);
+ final int godotJoyId = mJoystickIds.get(deviceId);
+
queueEvent(new Runnable() {
@Override
public void run() {
- GodotLib.joybutton(device_id, button, false);
+ GodotLib.joybutton(godotJoyId, button, false);
}
});
}
@@ -107,7 +117,7 @@ public class GodotInputHandler implements InputDeviceListener {
GodotLib.key(keyCode, scanCode, chr, false);
}
});
- };
+ }
return true;
}
@@ -122,24 +132,25 @@ public class GodotInputHandler implements InputDeviceListener {
if (keyCode == KeyEvent.KEYCODE_VOLUME_UP || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
return false;
- };
+ }
int source = event.getSource();
//Log.e(TAG, String.format("Key down! source %d, device %d, joystick %d, %d, %d", event.getDeviceId(), source, (source & InputDevice.SOURCE_JOYSTICK), (source & InputDevice.SOURCE_DPAD), (source & InputDevice.SOURCE_GAMEPAD)));
+ final int deviceId = event.getDeviceId();
+ // Check if source is a game device and that the device is a registered gamepad
if (isKeyEvent_GameDevice(source)) {
if (event.getRepeatCount() > 0) // ignore key echo
return true;
- final int button = getGodotButton(keyCode);
- final int device_id = findJoystickDevice(event.getDeviceId());
+ if (mJoystickIds.indexOfKey(deviceId) >= 0) {
+ final int button = getGodotButton(keyCode);
+ final int godotJoyId = mJoystickIds.get(deviceId);
- // Check if the device exists
- if (device_id > -1) {
queueEvent(new Runnable() {
@Override
public void run() {
- GodotLib.joybutton(device_id, button, true);
+ GodotLib.joybutton(godotJoyId, button, true);
}
});
}
@@ -152,7 +163,7 @@ public class GodotInputHandler implements InputDeviceListener {
GodotLib.key(keyCode, scanCode, chr, true);
}
});
- };
+ }
return true;
}
@@ -181,6 +192,7 @@ public class GodotInputHandler implements InputDeviceListener {
arr[i * 3 + 2] = event.getY(i);
}
final int action = event.getActionMasked();
+ final int pointer_idx = event.getPointerId(event.getActionIndex());
mRenderView.queueOnRenderThread(new Runnable() {
@Override
@@ -189,12 +201,9 @@ public class GodotInputHandler implements InputDeviceListener {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_MOVE: {
- GodotLib.touch(event.getSource(), action, 0, evcount, arr);
- } break;
+ case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_POINTER_UP:
case MotionEvent.ACTION_POINTER_DOWN: {
- int pointer_idx = event.getPointerId(event.getActionIndex());
GodotLib.touch(event.getSource(), action, pointer_idx, evcount, arr);
} break;
}
@@ -205,38 +214,52 @@ public class GodotInputHandler implements InputDeviceListener {
}
public boolean onGenericMotionEvent(MotionEvent event) {
- if ((event.getSource() & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK && event.getAction() == MotionEvent.ACTION_MOVE) {
- final int device_id = findJoystickDevice(event.getDeviceId());
-
+ if (event.isFromSource(InputDevice.SOURCE_JOYSTICK) && event.getAction() == MotionEvent.ACTION_MOVE) {
// Check if the device exists
- if (device_id > -1) {
- Joystick joy = mJoysticksDevices.get(device_id);
-
- for (int i = 0; i < joy.axes.size(); i++) {
- InputDevice.MotionRange range = joy.axes.get(i);
- final float value = (event.getAxisValue(range.getAxis()) - range.getMin()) / range.getRange() * 2.0f - 1.0f;
- final int idx = i;
- queueEvent(new Runnable() {
- @Override
- public void run() {
- GodotLib.joyaxis(device_id, idx, value);
- }
- });
+ final int deviceId = event.getDeviceId();
+ if (mJoystickIds.indexOfKey(deviceId) >= 0) {
+ final int godotJoyId = mJoystickIds.get(deviceId);
+ Joystick joystick = mJoysticksDevices.get(deviceId);
+
+ for (int i = 0; i < joystick.axes.size(); i++) {
+ final int axis = joystick.axes.get(i);
+ final float value = event.getAxisValue(axis);
+ /**
+ * As all axes are polled for each event, only fire an axis event if the value has actually changed.
+ * Prevents flooding Godot with repeated events.
+ */
+ if (joystick.axesValues.indexOfKey(axis) < 0 || (float)joystick.axesValues.get(axis) != value) {
+ // save value to prevent repeats
+ joystick.axesValues.put(axis, value);
+ final int godotAxisIdx = i;
+ queueEvent(new Runnable() {
+ @Override
+ public void run() {
+ GodotLib.joyaxis(godotJoyId, godotAxisIdx, value);
+ //Log.i(tag, "GodotLib.joyaxis("+godotJoyId+", "+godotAxisIdx+", "+value+");");
+ }
+ });
+ }
}
- for (int i = 0; i < joy.hats.size(); i += 2) {
- final int hatX = Math.round(event.getAxisValue(joy.hats.get(i).getAxis()));
- final int hatY = Math.round(event.getAxisValue(joy.hats.get(i + 1).getAxis()));
- queueEvent(new Runnable() {
- @Override
- public void run() {
- GodotLib.joyhat(device_id, hatX, hatY);
- }
- });
+ if (joystick.hasAxisHat) {
+ final int hatX = Math.round(event.getAxisValue(MotionEvent.AXIS_HAT_X));
+ final int hatY = Math.round(event.getAxisValue(MotionEvent.AXIS_HAT_Y));
+ if (joystick.hatX != hatX || joystick.hatY != hatY) {
+ joystick.hatX = hatX;
+ joystick.hatY = hatY;
+ queueEvent(new Runnable() {
+ @Override
+ public void run() {
+ GodotLib.joyhat(godotJoyId, hatX, hatY);
+ //Log.i(tag, "GodotLib.joyhat("+godotJoyId+", "+hatX+", "+hatY+");");
+ }
+ });
+ }
}
return true;
}
- } else if ((event.getSource() & InputDevice.SOURCE_STYLUS) == InputDevice.SOURCE_STYLUS) {
+ } else if (event.isFromSource(InputDevice.SOURCE_STYLUS)) {
final float x = event.getX();
final float y = event.getY();
final int type = event.getAction();
@@ -247,7 +270,8 @@ public class GodotInputHandler implements InputDeviceListener {
}
});
return true;
- } else if ((event.getSource() & InputDevice.SOURCE_MOUSE) == InputDevice.SOURCE_MOUSE) {
+
+ } else if (event.isFromSource(InputDevice.SOURCE_MOUSE) || event.isFromSource(InputDevice.SOURCE_MOUSE_RELATIVE)) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return handleMouseEvent(event);
}
@@ -268,67 +292,98 @@ public class GodotInputHandler implements InputDeviceListener {
}
}
+ private int assignJoystickIdNumber(int deviceId) {
+ int godotJoyId = 0;
+ while (mJoystickIds.indexOfValue(godotJoyId) >= 0) {
+ godotJoyId++;
+ }
+ mJoystickIds.put(deviceId, godotJoyId);
+ return godotJoyId;
+ }
+
@Override
public void onInputDeviceAdded(int deviceId) {
- int id = findJoystickDevice(deviceId);
-
// Check if the device has not been already added
- if (id < 0) {
- InputDevice device = mInputManager.getInputDevice(deviceId);
- //device can be null if deviceId is not found
- if (device != null) {
- int sources = device.getSources();
- if (((sources & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD) ||
- ((sources & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK)) {
- id = mJoysticksDevices.size();
-
- Joystick joy = new Joystick();
- joy.device_id = deviceId;
- joy.name = device.getName();
- joy.axes = new ArrayList<InputDevice.MotionRange>();
- joy.hats = new ArrayList<InputDevice.MotionRange>();
-
- List<InputDevice.MotionRange> ranges = device.getMotionRanges();
- Collections.sort(ranges, new RangeComparator());
-
- for (InputDevice.MotionRange range : ranges) {
- if (range.getAxis() == MotionEvent.AXIS_HAT_X || range.getAxis() == MotionEvent.AXIS_HAT_Y) {
- joy.hats.add(range);
- } else {
- joy.axes.add(range);
- }
- }
- mJoysticksDevices.add(joy);
+ if (mJoystickIds.indexOfKey(deviceId) >= 0) {
+ return;
+ }
+
+ InputDevice device = mInputManager.getInputDevice(deviceId);
+ //device can be null if deviceId is not found
+ if (device == null) {
+ return;
+ }
+
+ int sources = device.getSources();
- final int device_id = id;
- final String name = joy.name;
- queueEvent(new Runnable() {
- @Override
- public void run() {
- GodotLib.joyconnectionchanged(device_id, true, name);
- }
- });
+ // Device may not be a joystick or gamepad
+ if ((sources & InputDevice.SOURCE_GAMEPAD) != InputDevice.SOURCE_GAMEPAD &&
+ (sources & InputDevice.SOURCE_JOYSTICK) != InputDevice.SOURCE_JOYSTICK) {
+ return;
+ }
+
+ // Assign first available number. Re-use numbers where possible.
+ final int id = assignJoystickIdNumber(deviceId);
+
+ final Joystick joystick = new Joystick();
+ joystick.device_id = deviceId;
+ joystick.name = device.getName();
+
+ //Helps with creating new joypad mappings.
+ Log.i(tag, "=== New Input Device: " + joystick.name);
+
+ Set<Integer> already = new HashSet<Integer>();
+ for (InputDevice.MotionRange range : device.getMotionRanges()) {
+ boolean isJoystick = range.isFromSource(InputDevice.SOURCE_JOYSTICK);
+ boolean isGamepad = range.isFromSource(InputDevice.SOURCE_GAMEPAD);
+ //Log.i(tag, "axis: "+range.getAxis()+ ", isJoystick: "+isJoystick+", isGamepad: "+isGamepad);
+ if (!isJoystick && !isGamepad) {
+ continue;
+ }
+ final int axis = range.getAxis();
+ if (axis == MotionEvent.AXIS_HAT_X || axis == MotionEvent.AXIS_HAT_Y) {
+ joystick.hasAxisHat = true;
+ } else {
+ if (!already.contains(axis)) {
+ already.add(axis);
+ joystick.axes.add(axis);
+ } else {
+ Log.w(tag, " - DUPLICATE AXIS VALUE IN LIST: " + axis);
}
}
}
+ Collections.sort(joystick.axes);
+ for (int idx = 0; idx < joystick.axes.size(); idx++) {
+ //Helps with creating new joypad mappings.
+ Log.i(tag, " - Mapping Android axis " + joystick.axes.get(idx) + " to Godot axis " + idx);
+ }
+ mJoysticksDevices.put(deviceId, joystick);
+
+ queueEvent(new Runnable() {
+ @Override
+ public void run() {
+ GodotLib.joyconnectionchanged(id, true, joystick.name);
+ }
+ });
}
@Override
public void onInputDeviceRemoved(int deviceId) {
- final int device_id = findJoystickDevice(deviceId);
-
- // Check if the evice has not been already removed
- if (device_id > -1) {
- mJoysticksDevices.remove(device_id);
-
- queueEvent(new Runnable() {
- @Override
- public void run() {
- GodotLib.joyconnectionchanged(device_id, false, "");
- }
- });
+ // Check if the device has not been already removed
+ if (mJoystickIds.indexOfKey(deviceId) < 0) {
+ return;
}
+ final int godotJoyId = mJoystickIds.get(deviceId);
+ mJoystickIds.delete(deviceId);
+ mJoysticksDevices.delete(deviceId);
+
+ queueEvent(new Runnable() {
+ @Override
+ public void run() {
+ GodotLib.joyconnectionchanged(godotJoyId, false, "");
+ }
+ });
}
@Override
@@ -409,16 +464,6 @@ public class GodotInputHandler implements InputDeviceListener {
return button;
}
- private int findJoystickDevice(int device_id) {
- for (int i = 0; i < mJoysticksDevices.size(); i++) {
- if (mJoysticksDevices.get(i).device_id == device_id) {
- return i;
- }
- }
-
- return -1;
- }
-
private boolean handleMouseEvent(final MotionEvent event) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_HOVER_ENTER:
@@ -464,6 +509,11 @@ public class GodotInputHandler implements InputDeviceListener {
}
});
}
+ case MotionEvent.ACTION_DOWN:
+ case MotionEvent.ACTION_UP: {
+ // we can safely ignore these cases because they are always come beside ACTION_BUTTON_PRESS and ACTION_BUTTON_RELEASE
+ return true;
+ }
}
return false;
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java
index 4dd1054738..3e0e6a65fd 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/Joystick.java b/platform/android/java/lib/src/org/godotengine/godot/input/Joystick.java
index 1f3fe1e527..4b7318c718 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/input/Joystick.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/Joystick.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,9 +30,10 @@
package org.godotengine.godot.input;
-import android.view.InputDevice.MotionRange;
+import android.util.SparseArray;
import java.util.ArrayList;
+import java.util.List;
/**
* POJO class to represent a Joystick input device.
@@ -40,6 +41,12 @@ import java.util.ArrayList;
class Joystick {
int device_id;
String name;
- ArrayList<MotionRange> axes;
- ArrayList<MotionRange> hats;
+ List<Integer> axes = new ArrayList<Integer>();
+ protected boolean hasAxisHat = false;
+ /*
+ * Keep track of values so we can prevent flooding the engine with useless events.
+ */
+ protected final SparseArray axesValues = new SparseArray<Float>(4);
+ protected int hatX;
+ protected int hatY;
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java b/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java
index 93c204935c..993f0e9127 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -46,7 +46,9 @@ import androidx.annotation.Nullable;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@@ -107,14 +109,47 @@ public abstract class GodotPlugin {
* This method is invoked on the render thread.
*/
public final void onRegisterPluginWithGodotNative() {
- nativeRegisterSingleton(getPluginName());
+ registeredSignals.putAll(registerPluginWithGodotNative(this, new GodotPluginInfoProvider() {
+ @NonNull
+ @Override
+ public String getPluginName() {
+ return GodotPlugin.this.getPluginName();
+ }
+
+ @NonNull
+ @Override
+ public List<String> getPluginMethods() {
+ return GodotPlugin.this.getPluginMethods();
+ }
+
+ @NonNull
+ @Override
+ public Set<SignalInfo> getPluginSignals() {
+ return GodotPlugin.this.getPluginSignals();
+ }
+
+ @NonNull
+ @Override
+ public Set<String> getPluginGDNativeLibrariesPaths() {
+ return GodotPlugin.this.getPluginGDNativeLibrariesPaths();
+ }
+ }));
+ }
- Class clazz = getClass();
+ /**
+ * Register the plugin with Godot native code.
+ *
+ * This method must be invoked on the render thread.
+ */
+ public static Map<String, SignalInfo> registerPluginWithGodotNative(Object pluginObject, GodotPluginInfoProvider pluginInfoProvider) {
+ nativeRegisterSingleton(pluginInfoProvider.getPluginName(), pluginObject);
+
+ Class clazz = pluginObject.getClass();
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
boolean found = false;
- for (String s : getPluginMethods()) {
+ for (String s : pluginInfoProvider.getPluginMethods()) {
if (s.equals(method.getName())) {
found = true;
break;
@@ -123,7 +158,7 @@ public abstract class GodotPlugin {
if (!found)
continue;
- List<String> ptr = new ArrayList<String>();
+ List<String> ptr = new ArrayList<>();
Class[] paramTypes = method.getParameterTypes();
for (Class c : paramTypes) {
@@ -133,26 +168,29 @@ public abstract class GodotPlugin {
String[] pt = new String[ptr.size()];
ptr.toArray(pt);
- nativeRegisterMethod(getPluginName(), method.getName(), method.getReturnType().getName(), pt);
+ nativeRegisterMethod(pluginInfoProvider.getPluginName(), method.getName(), method.getReturnType().getName(), pt);
}
// Register the signals for this plugin.
- for (SignalInfo signalInfo : getPluginSignals()) {
+ Map<String, SignalInfo> registeredSignals = new HashMap<>();
+ for (SignalInfo signalInfo : pluginInfoProvider.getPluginSignals()) {
String signalName = signalInfo.getName();
- nativeRegisterSignal(getPluginName(), signalName, signalInfo.getParamTypesNames());
+ nativeRegisterSignal(pluginInfoProvider.getPluginName(), signalName, signalInfo.getParamTypesNames());
registeredSignals.put(signalName, signalInfo);
}
// Get the list of gdnative libraries to register.
- Set<String> gdnativeLibrariesPaths = getPluginGDNativeLibrariesPaths();
+ Set<String> gdnativeLibrariesPaths = pluginInfoProvider.getPluginGDNativeLibrariesPaths();
if (!gdnativeLibrariesPaths.isEmpty()) {
nativeRegisterGDNativeLibraries(gdnativeLibrariesPaths.toArray(new String[0]));
}
+
+ return registeredSignals;
}
/**
* Invoked once during the Godot Android initialization process after creation of the
- * {@link org.godotengine.godot.GodotView} view.
+ * {@link org.godotengine.godot.GodotRenderView} view.
* <p>
* The plugin can return a non-null {@link View} layout in order to add it to the Godot view
* hierarchy.
@@ -290,8 +328,8 @@ public abstract class GodotPlugin {
/**
* Emit a registered Godot signal.
- * @param signalName
- * @param signalArgs
+ * @param signalName Name of the signal to emit. It will be validated against the set of registered signals.
+ * @param signalArgs Arguments used to populate the emitted signal. The arguments will be validated against the {@link SignalInfo} matching the registered signalName parameter.
*/
protected void emitSignal(final String signalName, final Object... signalArgs) {
try {
@@ -301,6 +339,27 @@ public abstract class GodotPlugin {
throw new IllegalArgumentException(
"Signal " + signalName + " is not registered for this plugin.");
}
+ emitSignal(getGodot(), getPluginName(), signalInfo, signalArgs);
+ } catch (IllegalArgumentException exception) {
+ Log.w(TAG, exception.getMessage());
+ if (BuildConfig.DEBUG) {
+ throw exception;
+ }
+ }
+ }
+
+ /**
+ * Emit a Godot signal.
+ * @param godot
+ * @param pluginName Name of the Godot plugin the signal will be emitted from. The plugin must already be registered with the Godot engine.
+ * @param signalInfo Information about the signal to emit.
+ * @param signalArgs Arguments used to populate the emitted signal. The arguments will be validated against the given {@link SignalInfo} parameter.
+ */
+ public static void emitSignal(Godot godot, String pluginName, SignalInfo signalInfo, final Object... signalArgs) {
+ try {
+ if (signalInfo == null) {
+ throw new IllegalArgumentException("Signal must be non null.");
+ }
// Validate the arguments count.
Class<?>[] signalParamTypes = signalInfo.getParamTypes();
@@ -317,12 +376,8 @@ public abstract class GodotPlugin {
}
}
- runOnRenderThread(new Runnable() {
- @Override
- public void run() {
- nativeEmitSignal(getPluginName(), signalName, signalArgs);
- }
- });
+ godot.runOnRenderThread(() -> nativeEmitSignal(pluginName, signalInfo.getName(), signalArgs));
+
} catch (IllegalArgumentException exception) {
Log.w(TAG, exception.getMessage());
if (BuildConfig.DEBUG) {
@@ -335,7 +390,7 @@ public abstract class GodotPlugin {
* Used to setup a {@link GodotPlugin} instance.
* @param p_name Name of the instance.
*/
- private native void nativeRegisterSingleton(String p_name);
+ private static native void nativeRegisterSingleton(String p_name, Object object);
/**
* Used to complete registration of the {@link GodotPlugin} instance's methods.
@@ -344,13 +399,13 @@ public abstract class GodotPlugin {
* @param p_ret Return type of the registered method
* @param p_params Method parameters types
*/
- private native void nativeRegisterMethod(String p_sname, String p_name, String p_ret, String[] p_params);
+ private static native void nativeRegisterMethod(String p_sname, String p_name, String p_ret, String[] p_params);
/**
* Used to register gdnative libraries bundled by the plugin.
* @param gdnlibPaths Paths to the libraries relative to the 'assets' directory.
*/
- private native void nativeRegisterGDNativeLibraries(String[] gdnlibPaths);
+ private static native void nativeRegisterGDNativeLibraries(String[] gdnlibPaths);
/**
* Used to complete registration of the {@link GodotPlugin} instance's methods.
@@ -358,7 +413,7 @@ public abstract class GodotPlugin {
* @param signalName Name of the signal to register
* @param signalParamTypes Signal parameters types
*/
- private native void nativeRegisterSignal(String pluginName, String signalName, String[] signalParamTypes);
+ private static native void nativeRegisterSignal(String pluginName, String signalName, String[] signalParamTypes);
/**
* Used to emit signal by {@link GodotPlugin} instance.
@@ -366,5 +421,5 @@ public abstract class GodotPlugin {
* @param signalName Name of the signal to emit
* @param signalParams Signal parameters
*/
- private native void nativeEmitSignal(String pluginName, String signalName, Object[] signalParams);
+ private static native void nativeEmitSignal(String pluginName, String signalName, Object[] signalParams);
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginInfoProvider.java b/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginInfoProvider.java
new file mode 100644
index 0000000000..c3084b036e
--- /dev/null
+++ b/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginInfoProvider.java
@@ -0,0 +1,67 @@
+/*************************************************************************/
+/* GodotPluginInfoProvider.java */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+package org.godotengine.godot.plugin;
+
+import androidx.annotation.NonNull;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Provides the set of information expected from a Godot plugin.
+ */
+public interface GodotPluginInfoProvider {
+ /**
+ * Returns the name of the plugin.
+ */
+ @NonNull
+ String getPluginName();
+
+ /**
+ * Returns the list of methods to be exposed to Godot.
+ */
+ @NonNull
+ List<String> getPluginMethods();
+
+ /**
+ * Returns the list of signals to be exposed to Godot.
+ */
+ @NonNull
+ Set<SignalInfo> getPluginSignals();
+
+ /**
+ * Returns the paths for the plugin's gdnative libraries (if any).
+ *
+ * The paths must be relative to the 'assets' directory and point to a '*.gdnlib' file.
+ */
+ @NonNull
+ Set<String> getPluginGDNativeLibrariesPaths();
+}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginRegistry.java b/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginRegistry.java
index 1c2d1a6563..99811f72ed 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginRegistry.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginRegistry.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/plugin/SignalInfo.java b/platform/android/java/lib/src/org/godotengine/godot/plugin/SignalInfo.java
index f82c4d3fa0..6428422641 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/plugin/SignalInfo.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/plugin/SignalInfo.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/utils/Crypt.java b/platform/android/java/lib/src/org/godotengine/godot/utils/Crypt.java
index acc9c4981b..d6e49bb635 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/utils/Crypt.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/utils/Crypt.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/utils/GLUtils.java b/platform/android/java/lib/src/org/godotengine/godot/utils/GLUtils.java
index 82420eda79..19588f8465 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/utils/GLUtils.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/utils/GLUtils.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
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 c89118ad55..721d7c65c6 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
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java b/platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java
index 7104baf86e..b0ca96271e 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkRenderer.kt b/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkRenderer.kt
index f93cf0fa38..a35f6ec5a7 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkRenderer.kt
+++ b/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkRenderer.kt
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkSurfaceView.kt b/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkSurfaceView.kt
index e5c7a39bfb..f0e37d80b8 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkSurfaceView.kt
+++ b/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkSurfaceView.kt
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkThread.kt b/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkThread.kt
index fb02e3a69f..b967fd5f24 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkThread.kt
+++ b/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkThread.kt
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/XRMode.java b/platform/android/java/lib/src/org/godotengine/godot/xr/XRMode.java
index 982e43f9d1..0995477baf 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/xr/XRMode.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/xr/XRMode.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrConfigChooser.java b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrConfigChooser.java
index 819bcccdf1..245d573bfc 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrConfigChooser.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrConfigChooser.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrContextFactory.java b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrContextFactory.java
index 2d9b921466..d3aca267ef 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrContextFactory.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrContextFactory.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrWindowSurfaceFactory.java b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrWindowSurfaceFactory.java
index 43c7f0f966..83aa458064 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrWindowSurfaceFactory.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrWindowSurfaceFactory.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java
index 54672db282..341427209b 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java
index 126f3ad5f5..71610d2d00 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularFallbackConfigChooser.java b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularFallbackConfigChooser.java
index c83c47bed7..e690c5b695 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularFallbackConfigChooser.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularFallbackConfigChooser.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/nativeSrcsConfigs/build.gradle b/platform/android/java/nativeSrcsConfigs/build.gradle
index 65b7bb9dc9..66077060ea 100644
--- a/platform/android/java/nativeSrcsConfigs/build.gradle
+++ b/platform/android/java/nativeSrcsConfigs/build.gradle
@@ -31,6 +31,8 @@ android {
}
}
+ ndkVersion versions.ndkVersion
+
externalNativeBuild {
cmake {
path "CMakeLists.txt"
diff --git a/platform/android/java_class_wrapper.cpp b/platform/android/java_class_wrapper.cpp
index 9b44ac4b41..ab03599dc3 100644
--- a/platform/android/java_class_wrapper.cpp
+++ b/platform/android/java_class_wrapper.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -37,7 +37,7 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
if (!M)
return false;
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
MethodInfo *method = nullptr;
for (List<MethodInfo>::Element *E = M->get().front(); E; E = E->next()) {
@@ -964,7 +964,7 @@ Ref<JavaClass> JavaClassWrapper::wrap(const String &p_class) {
if (class_cache.has(p_class))
return class_cache[p_class];
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
jclass bclass = env->FindClass(p_class.utf8().get_data());
ERR_FAIL_COND_V(!bclass, Ref<JavaClass>());
@@ -1148,7 +1148,7 @@ JavaClassWrapper *JavaClassWrapper::singleton = nullptr;
JavaClassWrapper::JavaClassWrapper(jobject p_activity) {
singleton = this;
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
jclass activityClass = env->FindClass("android/app/Activity");
jmethodID getClassLoader = env->GetMethodID(activityClass, "getClassLoader", "()Ljava/lang/ClassLoader;");
diff --git a/platform/android/java_godot_io_wrapper.cpp b/platform/android/java_godot_io_wrapper.cpp
index 8d1db395ab..41201db32b 100644
--- a/platform/android/java_godot_io_wrapper.cpp
+++ b/platform/android/java_godot_io_wrapper.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -34,7 +34,7 @@
// JNIEnv is only valid within the thread it belongs to, in a multi threading environment
// we can't cache it.
// For GodotIO we call all access methods from our thread and we thus get a valid JNIEnv
-// from ThreadAndroid.
+// from get_jni_env().
GodotIOJavaWrapper::GodotIOJavaWrapper(JNIEnv *p_env, jobject p_godot_io_instance) {
godot_io_instance = p_env->NewGlobalRef(p_godot_io_instance);
@@ -72,7 +72,7 @@ jobject GodotIOJavaWrapper::get_instance() {
Error GodotIOJavaWrapper::open_uri(const String &p_uri) {
if (_open_URI) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
jstring jStr = env->NewStringUTF(p_uri.utf8().get_data());
return env->CallIntMethod(godot_io_instance, _open_URI, jStr) ? ERR_CANT_OPEN : OK;
} else {
@@ -82,7 +82,7 @@ Error GodotIOJavaWrapper::open_uri(const String &p_uri) {
String GodotIOJavaWrapper::get_user_data_dir() {
if (_get_data_dir) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
jstring s = (jstring)env->CallObjectMethod(godot_io_instance, _get_data_dir);
return jstring_to_string(s, env);
} else {
@@ -92,7 +92,7 @@ String GodotIOJavaWrapper::get_user_data_dir() {
String GodotIOJavaWrapper::get_locale() {
if (_get_locale) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
jstring s = (jstring)env->CallObjectMethod(godot_io_instance, _get_locale);
return jstring_to_string(s, env);
} else {
@@ -102,7 +102,7 @@ String GodotIOJavaWrapper::get_locale() {
String GodotIOJavaWrapper::get_model() {
if (_get_model) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
jstring s = (jstring)env->CallObjectMethod(godot_io_instance, _get_model);
return jstring_to_string(s, env);
} else {
@@ -112,7 +112,7 @@ String GodotIOJavaWrapper::get_model() {
int GodotIOJavaWrapper::get_screen_dpi() {
if (_get_screen_DPI) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
return env->CallIntMethod(godot_io_instance, _get_screen_DPI);
} else {
return 160;
@@ -121,7 +121,7 @@ int GodotIOJavaWrapper::get_screen_dpi() {
void GodotIOJavaWrapper::screen_get_usable_rect(int (&p_rect_xywh)[4]) {
if (_screen_get_usable_rect) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
jintArray returnArray = (jintArray)env->CallObjectMethod(godot_io_instance, _screen_get_usable_rect);
ERR_FAIL_COND(env->GetArrayLength(returnArray) != 4);
jint *arrayBody = env->GetIntArrayElements(returnArray, JNI_FALSE);
@@ -134,7 +134,7 @@ void GodotIOJavaWrapper::screen_get_usable_rect(int (&p_rect_xywh)[4]) {
String GodotIOJavaWrapper::get_unique_id() {
if (_get_unique_id) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
jstring s = (jstring)env->CallObjectMethod(godot_io_instance, _get_unique_id);
return jstring_to_string(s, env);
} else {
@@ -148,7 +148,7 @@ bool GodotIOJavaWrapper::has_vk() {
void GodotIOJavaWrapper::show_vk(const String &p_existing, bool p_multiline, int p_max_input_length, int p_cursor_start, int p_cursor_end) {
if (_show_keyboard) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
jstring jStr = env->NewStringUTF(p_existing.utf8().get_data());
env->CallVoidMethod(godot_io_instance, _show_keyboard, jStr, p_multiline, p_max_input_length, p_cursor_start, p_cursor_end);
}
@@ -156,21 +156,21 @@ void GodotIOJavaWrapper::show_vk(const String &p_existing, bool p_multiline, int
void GodotIOJavaWrapper::hide_vk() {
if (_hide_keyboard) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
env->CallVoidMethod(godot_io_instance, _hide_keyboard);
}
}
void GodotIOJavaWrapper::set_screen_orientation(int p_orient) {
if (_set_screen_orientation) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
env->CallVoidMethod(godot_io_instance, _set_screen_orientation, p_orient);
}
}
int GodotIOJavaWrapper::get_screen_orientation() {
if (_get_screen_orientation) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
return env->CallIntMethod(godot_io_instance, _get_screen_orientation);
} else {
return 0;
@@ -179,7 +179,7 @@ int GodotIOJavaWrapper::get_screen_orientation() {
String GodotIOJavaWrapper::get_system_dir(int p_dir) {
if (_get_system_dir) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
jstring s = (jstring)env->CallObjectMethod(godot_io_instance, _get_system_dir, p_dir);
return jstring_to_string(s, env);
} else {
@@ -187,14 +187,14 @@ String GodotIOJavaWrapper::get_system_dir(int p_dir) {
}
}
-// volatile because it can be changed from non-main thread and we need to
+// SafeNumeric because it can be changed from non-main thread and we need to
// ensure the change is immediately visible to other threads.
-static volatile int virtual_keyboard_height;
+static SafeNumeric<int> virtual_keyboard_height;
int GodotIOJavaWrapper::get_vk_height() {
- return virtual_keyboard_height;
+ return virtual_keyboard_height.get();
}
void GodotIOJavaWrapper::set_vk_height(int p_height) {
- virtual_keyboard_height = p_height;
+ virtual_keyboard_height.set(p_height);
}
diff --git a/platform/android/java_godot_io_wrapper.h b/platform/android/java_godot_io_wrapper.h
index 13270c794b..394e97effa 100644
--- a/platform/android/java_godot_io_wrapper.h
+++ b/platform/android/java_godot_io_wrapper.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java_godot_lib_jni.cpp b/platform/android/java_godot_lib_jni.cpp
index 5dc773fae2..bb22162879 100644
--- a/platform/android/java_godot_lib_jni.cpp
+++ b/platform/android/java_godot_lib_jni.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -43,7 +43,6 @@
#include "dir_access_jandroid.h"
#include "display_server_android.h"
#include "file_access_android.h"
-#include "file_access_jandroid.h"
#include "jni_utils.h"
#include "main/main.h"
#include "net_socket_android.h"
@@ -88,15 +87,11 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *en
godot_java = new GodotJavaWrapper(env, activity, godot_instance);
godot_io_java = new GodotIOJavaWrapper(env, godot_java->get_member_object("io", "Lorg/godotengine/godot/GodotIO;", env));
- ThreadAndroid::make_default(jvm);
-#ifdef USE_JAVA_FILE_ACCESS
- FileAccessJAndroid::setup(godot_io_java->get_instance());
-#else
+ init_thread_jandroid(jvm, env);
jobject amgr = env->NewGlobalRef(p_asset_manager);
FileAccessAndroid::asset_manager = AAssetManager_fromJava(env, amgr);
-#endif
DirAccessJAndroid::setup(godot_io_java->get_instance());
AudioDriverAndroid::setup(godot_io_java->get_instance());
@@ -124,7 +119,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ondestroy(JNIEnv *env
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jclass clazz, jobjectArray p_cmdline) {
- ThreadAndroid::setup_thread();
+ setup_android_thread();
const char **cmdline = nullptr;
jstring *j_cmdline = nullptr;
@@ -211,7 +206,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, jcl
return;
if (step == 0) {
- // Since Godot is initialized on the UI thread, _main_thread_id was set to that thread's id,
+ // Since Godot is initialized on the UI thread, main_thread_id was set to that thread's id,
// but for Godot purposes, the main thread is the one running the game loop
Main::setup2(Thread::get_caller_id());
++step;
@@ -251,9 +246,8 @@ void touch_preprocessing(JNIEnv *env, jclass clazz, jint input_device, jint ev,
tp.id = (int)p[0];
points.push_back(tp);
}
-
- if ((input_device & AINPUT_SOURCE_MOUSE) == AINPUT_SOURCE_MOUSE) {
- DisplayServerAndroid::get_singleton()->process_mouse_event(ev, buttons_mask, points[0].pos, vertical_factor, horizontal_factor);
+ if ((input_device & AINPUT_SOURCE_MOUSE) == AINPUT_SOURCE_MOUSE || (input_device & AINPUT_SOURCE_MOUSE_RELATIVE) == AINPUT_SOURCE_MOUSE_RELATIVE) {
+ DisplayServerAndroid::get_singleton()->process_mouse_event(input_device, ev, buttons_mask, points[0].pos, vertical_factor, horizontal_factor);
} else {
DisplayServerAndroid::get_singleton()->process_touch(ev, pointer, points);
}
@@ -388,7 +382,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_focusout(JNIEnv *env,
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_audio(JNIEnv *env, jclass clazz) {
- ThreadAndroid::setup_thread();
+ setup_android_thread();
AudioDriverAndroid::thread_func(env);
}
diff --git a/platform/android/java_godot_lib_jni.h b/platform/android/java_godot_lib_jni.h
index b499f6dfa1..a3e2933185 100644
--- a/platform/android/java_godot_lib_jni.h
+++ b/platform/android/java_godot_lib_jni.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/file_access_jandroid.h b/platform/android/java_godot_view_wrapper.cpp
index e252a4d3ac..5b638300ef 100644
--- a/platform/android/file_access_jandroid.h
+++ b/platform/android/java_godot_view_wrapper.cpp
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* file_access_jandroid.h */
+/* java_godot_view_wrapper.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -28,56 +28,39 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef FILE_ACCESS_JANDROID_H
-#define FILE_ACCESS_JANDROID_H
+#include "java_godot_view_wrapper.h"
-#include "core/os/file_access.h"
-#include "java_godot_lib_jni.h"
-class FileAccessJAndroid : public FileAccess {
- static jobject io;
- static jclass cls;
+#include "thread_jandroid.h"
- static jmethodID _file_open;
- static jmethodID _file_get_size;
- static jmethodID _file_seek;
- static jmethodID _file_tell;
- static jmethodID _file_eof;
- static jmethodID _file_read;
- static jmethodID _file_close;
+GodotJavaViewWrapper::GodotJavaViewWrapper(jobject godot_view) {
+ JNIEnv *env = get_jni_env();
- int id;
- static FileAccess *create_jandroid();
+ _godot_view = env->NewGlobalRef(godot_view);
-public:
- virtual Error _open(const String &p_path, int p_mode_flags); ///< open a file
- virtual void close(); ///< close a file
- virtual bool is_open() const; ///< true when file is open
+ _cls = (jclass)env->NewGlobalRef(env->GetObjectClass(godot_view));
- virtual void seek(size_t p_position); ///< seek to a given position
- virtual void seek_end(int64_t p_position = 0); ///< seek from the end of file
- virtual size_t get_position() const; ///< get position in the file
- virtual size_t get_len() const; ///< get size of the file
+ if (android_get_device_api_level() >= __ANDROID_API_O__) {
+ _request_pointer_capture = env->GetMethodID(_cls, "requestPointerCapture", "()V");
+ _release_pointer_capture = env->GetMethodID(_cls, "releasePointerCapture", "()V");
+ }
+}
- virtual bool eof_reached() const; ///< reading passed EOF
+void GodotJavaViewWrapper::request_pointer_capture() {
+ if (_request_pointer_capture != 0) {
+ JNIEnv *env = get_jni_env();
+ env->CallVoidMethod(_godot_view, _request_pointer_capture);
+ }
+}
- virtual uint8_t get_8() const; ///< get a byte
- virtual int get_buffer(uint8_t *p_dst, int p_length) const;
+void GodotJavaViewWrapper::release_pointer_capture() {
+ if (_request_pointer_capture != 0) {
+ JNIEnv *env = get_jni_env();
+ env->CallVoidMethod(_godot_view, _release_pointer_capture);
+ }
+}
- virtual Error get_error() const; ///< get last error
-
- virtual void flush();
- virtual void store_8(uint8_t p_dest); ///< store a byte
-
- virtual bool file_exists(const String &p_path); ///< return true if a file exists
-
- static void setup(jobject p_io);
-
- virtual uint64_t _get_modified_time(const String &p_file) { return 0; }
- virtual uint32_t _get_unix_permissions(const String &p_file) { return 0; }
- virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) { return FAILED; }
-
- FileAccessJAndroid();
- ~FileAccessJAndroid();
-};
-
-#endif // FILE_ACCESS_JANDROID_H
+GodotJavaViewWrapper::~GodotJavaViewWrapper() {
+ JNIEnv *env = get_jni_env();
+ env->DeleteGlobalRef(_godot_view);
+ env->DeleteGlobalRef(_cls);
+}
diff --git a/platform/uwp/thread_uwp.cpp b/platform/android/java_godot_view_wrapper.h
index 8e7bb144be..548c278292 100644
--- a/platform/uwp/thread_uwp.cpp
+++ b/platform/android/java_godot_view_wrapper.h
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* thread_uwp.cpp */
+/* java_godot_view_wrapper.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -28,34 +28,29 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "thread_uwp.h"
+#ifndef GODOT_JAVA_GODOT_VIEW_WRAPPER_H
+#define GODOT_JAVA_GODOT_VIEW_WRAPPER_H
-#include "core/os/memory.h"
+#include <android/log.h>
+#include <jni.h>
-Thread *ThreadUWP::create_func_uwp(ThreadCreateCallback p_callback, void *p_user, const Settings &) {
- ThreadUWP *thread = memnew(ThreadUWP);
+// Class that makes functions in java/src/org/godotengine/godot/GodotView.java callable from C++
+class GodotJavaViewWrapper {
+private:
+ jclass _cls;
- std::thread new_thread(p_callback, p_user);
- std::swap(thread->thread, new_thread);
+ jobject _godot_view;
- return thread;
-};
+ jmethodID _request_pointer_capture = 0;
+ jmethodID _release_pointer_capture = 0;
-Thread::ID ThreadUWP::get_thread_id_func_uwp() {
- return std::hash<std::thread::id>()(std::this_thread::get_id());
-};
+public:
+ GodotJavaViewWrapper(jobject godot_view);
-void ThreadUWP::wait_to_finish_func_uwp(Thread *p_thread) {
- ThreadUWP *tp = static_cast<ThreadUWP *>(p_thread);
- tp->thread.join();
-};
+ void request_pointer_capture();
+ void release_pointer_capture();
-Thread::ID ThreadUWP::get_id() const {
- return std::hash<std::thread::id>()(thread.get_id());
+ ~GodotJavaViewWrapper();
};
-void ThreadUWP::make_default() {
- create_func = create_func_uwp;
- get_thread_id_func = get_thread_id_func_uwp;
- wait_to_finish_func = wait_to_finish_func_uwp;
-};
+#endif //GODOT_JAVA_GODOT_VIEW_WRAPPER_H
diff --git a/platform/android/java_godot_wrapper.cpp b/platform/android/java_godot_wrapper.cpp
index cff591d903..759980373a 100644
--- a/platform/android/java_godot_wrapper.cpp
+++ b/platform/android/java_godot_wrapper.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -33,7 +33,7 @@
// JNIEnv is only valid within the thread it belongs to, in a multi threading environment
// we can't cache it.
// For Godot we call most access methods from our thread and we thus get a valid JNIEnv
-// from ThreadAndroid. For one or two we expect to pass the environment
+// from get_jni_env(). For one or two we expect to pass the environment
// TODO we could probably create a base class for this...
@@ -91,7 +91,7 @@ jobject GodotJavaWrapper::get_activity() {
jobject GodotJavaWrapper::get_member_object(const char *p_name, const char *p_class, JNIEnv *p_env) {
if (godot_class) {
if (p_env == nullptr)
- p_env = ThreadAndroid::get_env();
+ p_env = get_jni_env();
jfieldID fid = p_env->GetStaticFieldID(godot_class, p_name, p_class);
return p_env->GetStaticObjectField(godot_class, fid);
@@ -102,17 +102,27 @@ jobject GodotJavaWrapper::get_member_object(const char *p_name, const char *p_cl
jobject GodotJavaWrapper::get_class_loader() {
if (_get_class_loader) {
- JNIEnv *env = ThreadAndroid::get_env();
- return env->CallObjectMethod(godot_instance, _get_class_loader);
+ JNIEnv *env = get_jni_env();
+ return env->CallObjectMethod(activity, _get_class_loader);
} else {
return nullptr;
}
}
+GodotJavaViewWrapper *GodotJavaWrapper::get_godot_view() {
+ if (_godot_view != nullptr) {
+ return _godot_view;
+ }
+ JNIEnv *env = get_jni_env();
+ jmethodID godot_view_getter = env->GetMethodID(godot_class, "getRenderView", "()Lorg/godotengine/godot/GodotRenderView;");
+ _godot_view = new GodotJavaViewWrapper(env->CallObjectMethod(godot_instance, godot_view_getter));
+ return _godot_view;
+}
+
void GodotJavaWrapper::on_video_init(JNIEnv *p_env) {
if (_on_video_init)
if (p_env == nullptr)
- p_env = ThreadAndroid::get_env();
+ p_env = get_jni_env();
p_env->CallVoidMethod(godot_instance, _on_video_init);
}
@@ -120,7 +130,7 @@ void GodotJavaWrapper::on_video_init(JNIEnv *p_env) {
void GodotJavaWrapper::on_godot_main_loop_started(JNIEnv *p_env) {
if (_on_godot_main_loop_started) {
if (p_env == nullptr) {
- p_env = ThreadAndroid::get_env();
+ p_env = get_jni_env();
}
}
p_env->CallVoidMethod(godot_instance, _on_godot_main_loop_started);
@@ -129,7 +139,7 @@ void GodotJavaWrapper::on_godot_main_loop_started(JNIEnv *p_env) {
void GodotJavaWrapper::restart(JNIEnv *p_env) {
if (_restart)
if (p_env == nullptr)
- p_env = ThreadAndroid::get_env();
+ p_env = get_jni_env();
p_env->CallVoidMethod(godot_instance, _restart);
}
@@ -137,21 +147,21 @@ void GodotJavaWrapper::restart(JNIEnv *p_env) {
void GodotJavaWrapper::force_quit(JNIEnv *p_env) {
if (_finish)
if (p_env == nullptr)
- p_env = ThreadAndroid::get_env();
+ p_env = get_jni_env();
p_env->CallVoidMethod(godot_instance, _finish);
}
void GodotJavaWrapper::set_keep_screen_on(bool p_enabled) {
if (_set_keep_screen_on) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
env->CallVoidMethod(godot_instance, _set_keep_screen_on, p_enabled);
}
}
void GodotJavaWrapper::alert(const String &p_message, const String &p_title) {
if (_alert) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
jstring jStrMessage = env->NewStringUTF(p_message.utf8().get_data());
jstring jStrTitle = env->NewStringUTF(p_title.utf8().get_data());
env->CallVoidMethod(godot_instance, _alert, jStrMessage, jStrTitle);
@@ -159,7 +169,7 @@ void GodotJavaWrapper::alert(const String &p_message, const String &p_title) {
}
int GodotJavaWrapper::get_gles_version_code() {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
if (_get_GLES_version_code) {
return env->CallIntMethod(godot_instance, _get_GLES_version_code);
}
@@ -173,7 +183,7 @@ bool GodotJavaWrapper::has_get_clipboard() {
String GodotJavaWrapper::get_clipboard() {
if (_get_clipboard) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
jstring s = (jstring)env->CallObjectMethod(godot_instance, _get_clipboard);
return jstring_to_string(s, env);
} else {
@@ -183,7 +193,7 @@ String GodotJavaWrapper::get_clipboard() {
String GodotJavaWrapper::get_input_fallback_mapping() {
if (_get_input_fallback_mapping) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
jstring fallback_mapping = (jstring)env->CallObjectMethod(godot_instance, _get_input_fallback_mapping);
return jstring_to_string(fallback_mapping, env);
} else {
@@ -197,7 +207,7 @@ bool GodotJavaWrapper::has_set_clipboard() {
void GodotJavaWrapper::set_clipboard(const String &p_text) {
if (_set_clipboard) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
jstring jStr = env->NewStringUTF(p_text.utf8().get_data());
env->CallVoidMethod(godot_instance, _set_clipboard, jStr);
}
@@ -205,7 +215,7 @@ void GodotJavaWrapper::set_clipboard(const String &p_text) {
bool GodotJavaWrapper::request_permission(const String &p_name) {
if (_request_permission) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
jstring jStrName = env->NewStringUTF(p_name.utf8().get_data());
return env->CallBooleanMethod(godot_instance, _request_permission, jStrName);
} else {
@@ -215,7 +225,7 @@ bool GodotJavaWrapper::request_permission(const String &p_name) {
bool GodotJavaWrapper::request_permissions() {
if (_request_permissions) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
return env->CallBooleanMethod(godot_instance, _request_permissions);
} else {
return false;
@@ -225,7 +235,7 @@ bool GodotJavaWrapper::request_permissions() {
Vector<String> GodotJavaWrapper::get_granted_permissions() const {
Vector<String> permissions_list;
if (_get_granted_permissions) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
jobject permissions_object = env->CallObjectMethod(godot_instance, _get_granted_permissions);
jobjectArray *arr = reinterpret_cast<jobjectArray *>(&permissions_object);
@@ -243,14 +253,14 @@ Vector<String> GodotJavaWrapper::get_granted_permissions() const {
void GodotJavaWrapper::init_input_devices() {
if (_init_input_devices) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
env->CallVoidMethod(godot_instance, _init_input_devices);
}
}
jobject GodotJavaWrapper::get_surface() {
if (_get_surface) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
return env->CallObjectMethod(godot_instance, _get_surface);
} else {
return nullptr;
@@ -259,7 +269,7 @@ jobject GodotJavaWrapper::get_surface() {
bool GodotJavaWrapper::is_activity_resumed() {
if (_is_activity_resumed) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
return env->CallBooleanMethod(godot_instance, _is_activity_resumed);
} else {
return false;
@@ -268,7 +278,7 @@ bool GodotJavaWrapper::is_activity_resumed() {
void GodotJavaWrapper::vibrate(int p_duration_ms) {
if (_vibrate) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
env->CallVoidMethod(godot_instance, _vibrate, p_duration_ms);
}
}
diff --git a/platform/android/java_godot_wrapper.h b/platform/android/java_godot_wrapper.h
index e0c3809a64..99a60dffa1 100644
--- a/platform/android/java_godot_wrapper.h
+++ b/platform/android/java_godot_wrapper.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -37,6 +37,7 @@
#include <android/log.h>
#include <jni.h>
+#include "java_godot_view_wrapper.h"
#include "string_android.h"
// Class that makes functions in java/src/org/godotengine/godot/Godot.java callable from C++
@@ -47,6 +48,8 @@ private:
jclass godot_class;
jclass activity_class;
+ GodotJavaViewWrapper *_godot_view = nullptr;
+
jmethodID _on_video_init = 0;
jmethodID _restart = 0;
jmethodID _finish = 0;
@@ -74,6 +77,7 @@ public:
jobject get_member_object(const char *p_name, const char *p_class, JNIEnv *p_env = nullptr);
jobject get_class_loader();
+ GodotJavaViewWrapper *get_godot_view();
void on_video_init(JNIEnv *p_env = nullptr);
void on_godot_main_loop_started(JNIEnv *p_env = nullptr);
diff --git a/platform/android/jni_utils.cpp b/platform/android/jni_utils.cpp
index 8e1ae53b78..94652ab7ac 100644
--- a/platform/android/jni_utils.cpp
+++ b/platform/android/jni_utils.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/jni_utils.h b/platform/android/jni_utils.h
index bda056604f..f2b89392b5 100644
--- a/platform/android/jni_utils.h
+++ b/platform/android/jni_utils.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/net_socket_android.cpp b/platform/android/net_socket_android.cpp
index 0341ef3ec6..ddc2368793 100644
--- a/platform/android/net_socket_android.cpp
+++ b/platform/android/net_socket_android.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -38,7 +38,7 @@ jmethodID NetSocketAndroid::_multicast_lock_acquire = 0;
jmethodID NetSocketAndroid::_multicast_lock_release = 0;
void NetSocketAndroid::setup(jobject p_net_utils) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
net_utils = env->NewGlobalRef(p_net_utils);
@@ -51,14 +51,14 @@ void NetSocketAndroid::setup(jobject p_net_utils) {
void NetSocketAndroid::multicast_lock_acquire() {
if (_multicast_lock_acquire) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
env->CallVoidMethod(net_utils, _multicast_lock_acquire);
}
}
void NetSocketAndroid::multicast_lock_release() {
if (_multicast_lock_release) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
env->CallVoidMethod(net_utils, _multicast_lock_release);
}
}
diff --git a/platform/android/net_socket_android.h b/platform/android/net_socket_android.h
index 955d906535..cc2a68ac49 100644
--- a/platform/android/net_socket_android.h
+++ b/platform/android/net_socket_android.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp
index 00733f6dbb..422814dd50 100644
--- a/platform/android/os_android.cpp
+++ b/platform/android/os_android.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,15 +31,13 @@
#include "os_android.h"
#include "core/config/project_settings.h"
-#include "core/io/file_access_buffered_fa.h"
#include "drivers/unix/dir_access_unix.h"
#include "drivers/unix/file_access_unix.h"
-#include "file_access_android.h"
#include "main/main.h"
#include "platform/android/display_server_android.h"
#include "dir_access_jandroid.h"
-#include "file_access_jandroid.h"
+#include "file_access_android.h"
#include "net_socket_android.h"
#include <dlfcn.h>
@@ -62,16 +60,10 @@ void OS_Android::initialize_core() {
if (use_apk_expansion)
FileAccess::make_default<FileAccessUnix>(FileAccess::ACCESS_RESOURCES);
else {
-#ifdef USE_JAVA_FILE_ACCESS
- FileAccess::make_default<FileAccessBufferedFA<FileAccessJAndroid>>(FileAccess::ACCESS_RESOURCES);
-#else
- //FileAccess::make_default<FileAccessBufferedFA<FileAccessAndroid> >(FileAccess::ACCESS_RESOURCES);
FileAccess::make_default<FileAccessAndroid>(FileAccess::ACCESS_RESOURCES);
-#endif
}
FileAccess::make_default<FileAccessUnix>(FileAccess::ACCESS_USERDATA);
FileAccess::make_default<FileAccessUnix>(FileAccess::ACCESS_FILESYSTEM);
- //FileAccessBufferedFA<FileAccessUnix>::make_default();
if (use_apk_expansion)
DirAccess::make_default<DirAccessUnix>(DirAccess::ACCESS_RESOURCES);
else
@@ -147,7 +139,7 @@ MainLoop *OS_Android::get_main_loop() const {
void OS_Android::main_loop_begin() {
if (main_loop)
- main_loop->init();
+ main_loop->initialize();
}
bool OS_Android::main_loop_iterate() {
@@ -159,7 +151,7 @@ bool OS_Android::main_loop_iterate() {
void OS_Android::main_loop_end() {
if (main_loop)
- main_loop->finish();
+ main_loop->finalize();
}
void OS_Android::main_loop_focusout() {
@@ -314,6 +306,7 @@ OS_Android::OS_Android(GodotJavaWrapper *p_godot_java, GodotIOJavaWrapper *p_god
#if defined(OPENGL_ENABLED)
gl_extensions = nullptr;
use_gl2 = false;
+ use_16bits_fbo = false;
#endif
#if defined(VULKAN_ENABLED)
diff --git a/platform/android/os_android.h b/platform/android/os_android.h
index cac7efaa88..dd14b69cf9 100644
--- a/platform/android/os_android.h
+++ b/platform/android/os_android.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -68,15 +68,15 @@ private:
GodotIOJavaWrapper *godot_io_java;
public:
- virtual void initialize_core();
- virtual void initialize();
+ virtual void initialize_core() override;
+ virtual void initialize() override;
- virtual void initialize_joypads();
+ virtual void initialize_joypads() override;
- virtual void set_main_loop(MainLoop *p_main_loop);
- virtual void delete_main_loop();
+ virtual void set_main_loop(MainLoop *p_main_loop) override;
+ virtual void delete_main_loop() override;
- virtual void finalize();
+ virtual void finalize() override;
typedef int64_t ProcessID;
@@ -84,14 +84,14 @@ public:
GodotJavaWrapper *get_godot_java();
GodotIOJavaWrapper *get_godot_io_java();
- virtual bool request_permission(const String &p_name);
- virtual bool request_permissions();
- virtual Vector<String> get_granted_permissions() const;
+ virtual bool request_permission(const String &p_name) override;
+ virtual bool request_permissions() override;
+ virtual Vector<String> get_granted_permissions() const override;
- virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false);
+ virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false) override;
- virtual String get_name() const;
- virtual MainLoop *get_main_loop() const;
+ virtual String get_name() const override;
+ virtual MainLoop *get_main_loop() const override;
void main_loop_begin();
bool main_loop_iterate();
@@ -109,19 +109,19 @@ public:
void set_native_window(ANativeWindow *p_native_window);
ANativeWindow *get_native_window() const;
- virtual Error shell_open(String p_uri);
- virtual String get_user_data_dir() const;
- virtual String get_resource_dir() const;
- virtual String get_locale() const;
- virtual String get_model_name() const;
+ virtual Error shell_open(String p_uri) override;
+ virtual String get_user_data_dir() const override;
+ virtual String get_resource_dir() const override;
+ virtual String get_locale() const override;
+ virtual String get_model_name() const override;
- virtual String get_unique_id() const;
+ virtual String get_unique_id() const override;
- virtual String get_system_dir(SystemDir p_dir) const;
+ virtual String get_system_dir(SystemDir p_dir) const override;
- void vibrate_handheld(int p_duration_ms);
+ void vibrate_handheld(int p_duration_ms) override;
- virtual bool _check_internal_feature_support(const String &p_feature);
+ virtual bool _check_internal_feature_support(const String &p_feature) override;
OS_Android(GodotJavaWrapper *p_godot_java, GodotIOJavaWrapper *p_godot_io_java, bool p_use_apk_expansion);
~OS_Android();
};
diff --git a/platform/android/platform_config.h b/platform/android/platform_config.h
index c5e896c4e1..601db9951f 100644
--- a/platform/android/platform_config.h
+++ b/platform/android/platform_config.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/plugin/godot_plugin_config.h b/platform/android/plugin/godot_plugin_config.h
index ecb9c0c7f5..173ac115a2 100644
--- a/platform/android/plugin/godot_plugin_config.h
+++ b/platform/android/plugin/godot_plugin_config.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -35,23 +35,6 @@
#include "core/io/config_file.h"
#include "core/string/ustring.h"
-static const char *PLUGIN_CONFIG_EXT = ".gdap";
-
-static const char *CONFIG_SECTION = "config";
-static const char *CONFIG_NAME_KEY = "name";
-static const char *CONFIG_BINARY_TYPE_KEY = "binary_type";
-static const char *CONFIG_BINARY_KEY = "binary";
-
-static const char *DEPENDENCIES_SECTION = "dependencies";
-static const char *DEPENDENCIES_LOCAL_KEY = "local";
-static const char *DEPENDENCIES_REMOTE_KEY = "remote";
-static const char *DEPENDENCIES_CUSTOM_MAVEN_REPOS_KEY = "custom_maven_repos";
-
-static const char *BINARY_TYPE_LOCAL = "local";
-static const char *BINARY_TYPE_REMOTE = "remote";
-
-static const char *PLUGIN_VALUE_SEPARATOR = "|";
-
/*
The `config` section and fields are required and defined as follow:
- **name**: name of the plugin
@@ -67,7 +50,24 @@ The `dependencies` section and fields are optional and defined as follow:
See https://github.com/godotengine/godot/issues/38157#issuecomment-618773871
*/
-struct PluginConfig {
+struct PluginConfigAndroid {
+ inline static const char *PLUGIN_CONFIG_EXT = ".gdap";
+
+ inline static const char *CONFIG_SECTION = "config";
+ inline static const char *CONFIG_NAME_KEY = "name";
+ inline static const char *CONFIG_BINARY_TYPE_KEY = "binary_type";
+ inline static const char *CONFIG_BINARY_KEY = "binary";
+
+ inline static const char *DEPENDENCIES_SECTION = "dependencies";
+ inline static const char *DEPENDENCIES_LOCAL_KEY = "local";
+ inline static const char *DEPENDENCIES_REMOTE_KEY = "remote";
+ inline static const char *DEPENDENCIES_CUSTOM_MAVEN_REPOS_KEY = "custom_maven_repos";
+
+ inline static const char *BINARY_TYPE_LOCAL = "local";
+ inline static const char *BINARY_TYPE_REMOTE = "remote";
+
+ inline static const char *PLUGIN_VALUE_SEPARATOR = "|";
+
// Set to true when the config file is properly loaded.
bool valid_config = false;
// Unix timestamp of last change to this plugin.
@@ -88,7 +88,7 @@ struct PluginConfig {
* Set of prebuilt plugins.
* Currently unused, this is just for future reference:
*/
-// static const PluginConfig MY_PREBUILT_PLUGIN = {
+// static const PluginConfigAndroid MY_PREBUILT_PLUGIN = {
// /*.valid_config =*/true,
// /*.last_updated =*/0,
// /*.name =*/"GodotPayment",
@@ -101,7 +101,7 @@ struct PluginConfig {
static inline String resolve_local_dependency_path(String plugin_config_dir, String dependency_path) {
String absolute_path;
- if (!dependency_path.empty()) {
+ if (!dependency_path.is_empty()) {
if (dependency_path.is_abs_path()) {
absolute_path = ProjectSettings::get_singleton()->globalize_path(dependency_path);
} else {
@@ -112,10 +112,10 @@ static inline String resolve_local_dependency_path(String plugin_config_dir, Str
return absolute_path;
}
-static inline PluginConfig resolve_prebuilt_plugin(PluginConfig prebuilt_plugin, String plugin_config_dir) {
- PluginConfig resolved = prebuilt_plugin;
- resolved.binary = resolved.binary_type == BINARY_TYPE_LOCAL ? resolve_local_dependency_path(plugin_config_dir, prebuilt_plugin.binary) : prebuilt_plugin.binary;
- if (!prebuilt_plugin.local_dependencies.empty()) {
+static inline PluginConfigAndroid resolve_prebuilt_plugin(PluginConfigAndroid prebuilt_plugin, String plugin_config_dir) {
+ PluginConfigAndroid resolved = prebuilt_plugin;
+ resolved.binary = resolved.binary_type == PluginConfigAndroid::BINARY_TYPE_LOCAL ? resolve_local_dependency_path(plugin_config_dir, prebuilt_plugin.binary) : prebuilt_plugin.binary;
+ if (!prebuilt_plugin.local_dependencies.is_empty()) {
resolved.local_dependencies.clear();
for (int i = 0; i < prebuilt_plugin.local_dependencies.size(); i++) {
resolved.local_dependencies.push_back(resolve_local_dependency_path(plugin_config_dir, prebuilt_plugin.local_dependencies[i]));
@@ -124,26 +124,27 @@ static inline PluginConfig resolve_prebuilt_plugin(PluginConfig prebuilt_plugin,
return resolved;
}
-static inline Vector<PluginConfig> get_prebuilt_plugins(String plugins_base_dir) {
- Vector<PluginConfig> prebuilt_plugins;
+static inline Vector<PluginConfigAndroid> get_prebuilt_plugins(String plugins_base_dir) {
+ Vector<PluginConfigAndroid> prebuilt_plugins;
// prebuilt_plugins.push_back(resolve_prebuilt_plugin(MY_PREBUILT_PLUGIN, plugins_base_dir));
return prebuilt_plugins;
}
-static inline bool is_plugin_config_valid(PluginConfig plugin_config) {
- bool valid_name = !plugin_config.name.empty();
- bool valid_binary_type = plugin_config.binary_type == BINARY_TYPE_LOCAL ||
- plugin_config.binary_type == BINARY_TYPE_REMOTE;
+static inline bool is_plugin_config_valid(PluginConfigAndroid plugin_config) {
+ bool valid_name = !plugin_config.name.is_empty();
+ bool valid_binary_type = plugin_config.binary_type == PluginConfigAndroid::BINARY_TYPE_LOCAL ||
+ plugin_config.binary_type == PluginConfigAndroid::BINARY_TYPE_REMOTE;
bool valid_binary = false;
if (valid_binary_type) {
- valid_binary = !plugin_config.binary.empty() &&
- (plugin_config.binary_type == BINARY_TYPE_REMOTE ||
+ valid_binary = !plugin_config.binary.is_empty() &&
+ (plugin_config.binary_type == PluginConfigAndroid::BINARY_TYPE_REMOTE ||
+
FileAccess::exists(plugin_config.binary));
}
bool valid_local_dependencies = true;
- if (!plugin_config.local_dependencies.empty()) {
+ if (!plugin_config.local_dependencies.is_empty()) {
for (int i = 0; i < plugin_config.local_dependencies.size(); i++) {
if (!FileAccess::exists(plugin_config.local_dependencies[i])) {
valid_local_dependencies = false;
@@ -154,7 +155,7 @@ static inline bool is_plugin_config_valid(PluginConfig plugin_config) {
return valid_name && valid_binary && valid_binary_type && valid_local_dependencies;
}
-static inline uint64_t get_plugin_modification_time(const PluginConfig &plugin_config, const String &config_path) {
+static inline uint64_t get_plugin_modification_time(const PluginConfigAndroid &plugin_config, const String &config_path) {
uint64_t last_updated = FileAccess::get_modified_time(config_path);
last_updated = MAX(last_updated, FileAccess::get_modified_time(plugin_config.binary));
@@ -166,30 +167,30 @@ static inline uint64_t get_plugin_modification_time(const PluginConfig &plugin_c
return last_updated;
}
-static inline PluginConfig load_plugin_config(Ref<ConfigFile> config_file, const String &path) {
- PluginConfig plugin_config = {};
+static inline PluginConfigAndroid load_plugin_config(Ref<ConfigFile> config_file, const String &path) {
+ PluginConfigAndroid plugin_config = {};
if (config_file.is_valid()) {
Error err = config_file->load(path);
if (err == OK) {
String config_base_dir = path.get_base_dir();
- plugin_config.name = config_file->get_value(CONFIG_SECTION, CONFIG_NAME_KEY, String());
- plugin_config.binary_type = config_file->get_value(CONFIG_SECTION, CONFIG_BINARY_TYPE_KEY, String());
+ plugin_config.name = config_file->get_value(PluginConfigAndroid::CONFIG_SECTION, PluginConfigAndroid::CONFIG_NAME_KEY, String());
+ plugin_config.binary_type = config_file->get_value(PluginConfigAndroid::CONFIG_SECTION, PluginConfigAndroid::CONFIG_BINARY_TYPE_KEY, String());
- String binary_path = config_file->get_value(CONFIG_SECTION, CONFIG_BINARY_KEY, String());
- plugin_config.binary = plugin_config.binary_type == BINARY_TYPE_LOCAL ? resolve_local_dependency_path(config_base_dir, binary_path) : binary_path;
+ String binary_path = config_file->get_value(PluginConfigAndroid::CONFIG_SECTION, PluginConfigAndroid::CONFIG_BINARY_KEY, String());
+ plugin_config.binary = plugin_config.binary_type == PluginConfigAndroid::BINARY_TYPE_LOCAL ? resolve_local_dependency_path(config_base_dir, binary_path) : binary_path;
- if (config_file->has_section(DEPENDENCIES_SECTION)) {
- Vector<String> local_dependencies_paths = config_file->get_value(DEPENDENCIES_SECTION, DEPENDENCIES_LOCAL_KEY, Vector<String>());
- if (!local_dependencies_paths.empty()) {
+ if (config_file->has_section(PluginConfigAndroid::DEPENDENCIES_SECTION)) {
+ Vector<String> local_dependencies_paths = config_file->get_value(PluginConfigAndroid::DEPENDENCIES_SECTION, PluginConfigAndroid::DEPENDENCIES_LOCAL_KEY, Vector<String>());
+ if (!local_dependencies_paths.is_empty()) {
for (int i = 0; i < local_dependencies_paths.size(); i++) {
plugin_config.local_dependencies.push_back(resolve_local_dependency_path(config_base_dir, local_dependencies_paths[i]));
}
}
- plugin_config.remote_dependencies = config_file->get_value(DEPENDENCIES_SECTION, DEPENDENCIES_REMOTE_KEY, Vector<String>());
- plugin_config.custom_maven_repos = config_file->get_value(DEPENDENCIES_SECTION, DEPENDENCIES_CUSTOM_MAVEN_REPOS_KEY, Vector<String>());
+ plugin_config.remote_dependencies = config_file->get_value(PluginConfigAndroid::DEPENDENCIES_SECTION, PluginConfigAndroid::DEPENDENCIES_REMOTE_KEY, Vector<String>());
+ plugin_config.custom_maven_repos = config_file->get_value(PluginConfigAndroid::DEPENDENCIES_SECTION, PluginConfigAndroid::DEPENDENCIES_CUSTOM_MAVEN_REPOS_KEY, Vector<String>());
}
plugin_config.valid_config = is_plugin_config_valid(plugin_config);
@@ -200,12 +201,12 @@ static inline PluginConfig load_plugin_config(Ref<ConfigFile> config_file, const
return plugin_config;
}
-static inline String get_plugins_binaries(String binary_type, Vector<PluginConfig> plugins_configs) {
+static inline String get_plugins_binaries(String binary_type, Vector<PluginConfigAndroid> plugins_configs) {
String plugins_binaries;
- if (!plugins_configs.empty()) {
+ if (!plugins_configs.is_empty()) {
Vector<String> binaries;
for (int i = 0; i < plugins_configs.size(); i++) {
- PluginConfig config = plugins_configs[i];
+ PluginConfigAndroid config = plugins_configs[i];
if (!config.valid_config) {
continue;
}
@@ -214,27 +215,27 @@ static inline String get_plugins_binaries(String binary_type, Vector<PluginConfi
binaries.push_back(config.binary);
}
- if (binary_type == BINARY_TYPE_LOCAL) {
+ if (binary_type == PluginConfigAndroid::BINARY_TYPE_LOCAL) {
binaries.append_array(config.local_dependencies);
}
- if (binary_type == BINARY_TYPE_REMOTE) {
+ if (binary_type == PluginConfigAndroid::BINARY_TYPE_REMOTE) {
binaries.append_array(config.remote_dependencies);
}
}
- plugins_binaries = String(PLUGIN_VALUE_SEPARATOR).join(binaries);
+ plugins_binaries = String(PluginConfigAndroid::PLUGIN_VALUE_SEPARATOR).join(binaries);
}
return plugins_binaries;
}
-static inline String get_plugins_custom_maven_repos(Vector<PluginConfig> plugins_configs) {
+static inline String get_plugins_custom_maven_repos(Vector<PluginConfigAndroid> plugins_configs) {
String custom_maven_repos;
- if (!plugins_configs.empty()) {
+ if (!plugins_configs.is_empty()) {
Vector<String> repos_urls;
for (int i = 0; i < plugins_configs.size(); i++) {
- PluginConfig config = plugins_configs[i];
+ PluginConfigAndroid config = plugins_configs[i];
if (!config.valid_config) {
continue;
}
@@ -242,24 +243,24 @@ static inline String get_plugins_custom_maven_repos(Vector<PluginConfig> plugins
repos_urls.append_array(config.custom_maven_repos);
}
- custom_maven_repos = String(PLUGIN_VALUE_SEPARATOR).join(repos_urls);
+ custom_maven_repos = String(PluginConfigAndroid::PLUGIN_VALUE_SEPARATOR).join(repos_urls);
}
return custom_maven_repos;
}
-static inline String get_plugins_names(Vector<PluginConfig> plugins_configs) {
+static inline String get_plugins_names(Vector<PluginConfigAndroid> plugins_configs) {
String plugins_names;
- if (!plugins_configs.empty()) {
+ if (!plugins_configs.is_empty()) {
Vector<String> names;
for (int i = 0; i < plugins_configs.size(); i++) {
- PluginConfig config = plugins_configs[i];
+ PluginConfigAndroid config = plugins_configs[i];
if (!config.valid_config) {
continue;
}
names.push_back(config.name);
}
- plugins_names = String(PLUGIN_VALUE_SEPARATOR).join(names);
+ plugins_names = String(PluginConfigAndroid::PLUGIN_VALUE_SEPARATOR).join(names);
}
return plugins_names;
diff --git a/platform/android/plugin/godot_plugin_jni.cpp b/platform/android/plugin/godot_plugin_jni.cpp
index b8e5345b85..ba3e9fa20f 100644
--- a/platform/android/plugin/godot_plugin_jni.cpp
+++ b/platform/android/plugin/godot_plugin_jni.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -41,7 +41,7 @@ static HashMap<String, JNISingleton *> jni_singletons;
extern "C" {
-JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterSingleton(JNIEnv *env, jobject obj, jstring name) {
+JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterSingleton(JNIEnv *env, jclass clazz, jstring name, jobject obj) {
String singname = jstring_to_string(name, env);
JNISingleton *s = (JNISingleton *)ClassDB::instance("JNISingleton");
s->set_instance(env->NewGlobalRef(obj));
@@ -51,7 +51,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegis
ProjectSettings::get_singleton()->set(singname, s);
}
-JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterMethod(JNIEnv *env, jobject obj, jstring sname, jstring name, jstring ret, jobjectArray args) {
+JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterMethod(JNIEnv *env, jclass clazz, jstring sname, jstring name, jstring ret, jobjectArray args) {
String singname = jstring_to_string(sname, env);
ERR_FAIL_COND(!jni_singletons.has(singname));
@@ -83,7 +83,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegis
s->add_method(mname, mid, types, get_jni_type(retval));
}
-JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterSignal(JNIEnv *env, jobject obj, jstring j_plugin_name, jstring j_signal_name, jobjectArray j_signal_param_types) {
+JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterSignal(JNIEnv *env, jclass clazz, jstring j_plugin_name, jstring j_signal_name, jobjectArray j_signal_param_types) {
String singleton_name = jstring_to_string(j_plugin_name, env);
ERR_FAIL_COND(!jni_singletons.has(singleton_name));
@@ -104,7 +104,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegis
singleton->add_signal(signal_name, types);
}
-JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeEmitSignal(JNIEnv *env, jobject obj, jstring j_plugin_name, jstring j_signal_name, jobjectArray j_signal_params) {
+JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeEmitSignal(JNIEnv *env, jclass clazz, jstring j_plugin_name, jstring j_signal_name, jobjectArray j_signal_params) {
String singleton_name = jstring_to_string(j_plugin_name, env);
ERR_FAIL_COND(!jni_singletons.has(singleton_name));
@@ -129,7 +129,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeEmitS
singleton->emit_signal(signal_name, args, count);
}
-JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterGDNativeLibraries(JNIEnv *env, jobject obj, jobjectArray gdnlib_paths) {
+JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterGDNativeLibraries(JNIEnv *env, jclass clazz, jobjectArray gdnlib_paths) {
int gdnlib_count = env->GetArrayLength(gdnlib_paths);
if (gdnlib_count == 0) {
return;
diff --git a/platform/android/plugin/godot_plugin_jni.h b/platform/android/plugin/godot_plugin_jni.h
index 80ce332e7c..b87f922e03 100644
--- a/platform/android/plugin/godot_plugin_jni.h
+++ b/platform/android/plugin/godot_plugin_jni.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -35,11 +35,11 @@
#include <jni.h>
extern "C" {
-JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterSingleton(JNIEnv *env, jobject obj, jstring name);
-JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterMethod(JNIEnv *env, jobject obj, jstring sname, jstring name, jstring ret, jobjectArray args);
-JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterSignal(JNIEnv *env, jobject obj, jstring j_plugin_name, jstring j_signal_name, jobjectArray j_signal_param_types);
-JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeEmitSignal(JNIEnv *env, jobject obj, jstring j_plugin_name, jstring j_signal_name, jobjectArray j_signal_params);
-JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterGDNativeLibraries(JNIEnv *env, jobject obj, jobjectArray gdnlib_paths);
+JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterSingleton(JNIEnv *env, jclass clazz, jstring name, jobject obj);
+JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterMethod(JNIEnv *env, jclass clazz, jstring sname, jstring name, jstring ret, jobjectArray args);
+JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterSignal(JNIEnv *env, jclass clazz, jstring j_plugin_name, jstring j_signal_name, jobjectArray j_signal_param_types);
+JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeEmitSignal(JNIEnv *env, jclass clazz, jstring j_plugin_name, jstring j_signal_name, jobjectArray j_signal_params);
+JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterGDNativeLibraries(JNIEnv *env, jclass clazz, jobjectArray gdnlib_paths);
}
#endif // GODOT_PLUGIN_JNI_H
diff --git a/platform/android/string_android.h b/platform/android/string_android.h
index 0a7dbf475d..3721315d3f 100644
--- a/platform/android/string_android.h
+++ b/platform/android/string_android.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -37,14 +37,14 @@
/**
* Converts JNI jstring to Godot String.
* @param source Source JNI string. If null an empty string is returned.
- * @param env JNI environment instance. If null obtained by ThreadAndroid::get_env().
+ * @param env JNI environment instance. If null obtained by get_jni_env().
* @return Godot string instance.
*/
static inline String jstring_to_string(jstring source, JNIEnv *env = nullptr) {
String result;
if (source) {
if (!env) {
- env = ThreadAndroid::get_env();
+ env = get_jni_env();
}
const char *const source_utf8 = env->GetStringUTFChars(source, nullptr);
if (source_utf8) {
diff --git a/platform/android/thread_jandroid.cpp b/platform/android/thread_jandroid.cpp
index 442e4d781b..afcc7294f2 100644
--- a/platform/android/thread_jandroid.cpp
+++ b/platform/android/thread_jandroid.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,116 +30,29 @@
#include "thread_jandroid.h"
-#include "core/object/script_language.h"
-#include "core/os/memory.h"
-#include "core/templates/safe_refcount.h"
+#include "core/os/thread.h"
-static void _thread_id_key_destr_callback(void *p_value) {
- memdelete(static_cast<Thread::ID *>(p_value));
-}
-
-static pthread_key_t _create_thread_id_key() {
- pthread_key_t key;
- pthread_key_create(&key, &_thread_id_key_destr_callback);
- return key;
-}
-
-pthread_key_t ThreadAndroid::thread_id_key = _create_thread_id_key();
-Thread::ID ThreadAndroid::next_thread_id = 0;
-
-Thread::ID ThreadAndroid::get_id() const {
- return id;
-}
-
-Thread *ThreadAndroid::create_thread_jandroid() {
- return memnew(ThreadAndroid);
-}
-
-void *ThreadAndroid::thread_callback(void *userdata) {
- ThreadAndroid *t = reinterpret_cast<ThreadAndroid *>(userdata);
- setup_thread();
- ScriptServer::thread_enter(); //scripts may need to attach a stack
- t->id = atomic_increment(&next_thread_id);
- pthread_setspecific(thread_id_key, (void *)memnew(ID(t->id)));
- t->callback(t->user);
- ScriptServer::thread_exit();
- return nullptr;
-}
-
-Thread *ThreadAndroid::create_func_jandroid(ThreadCreateCallback p_callback, void *p_user, const Settings &) {
- ThreadAndroid *tr = memnew(ThreadAndroid);
- tr->callback = p_callback;
- tr->user = p_user;
- pthread_attr_init(&tr->pthread_attr);
- pthread_attr_setdetachstate(&tr->pthread_attr, PTHREAD_CREATE_JOINABLE);
-
- pthread_create(&tr->pthread, &tr->pthread_attr, thread_callback, tr);
-
- return tr;
-}
+static JavaVM *java_vm = nullptr;
+static thread_local JNIEnv *env = nullptr;
-Thread::ID ThreadAndroid::get_thread_id_func_jandroid() {
- void *value = pthread_getspecific(thread_id_key);
-
- if (value)
- return *static_cast<ID *>(value);
-
- ID new_id = atomic_increment(&next_thread_id);
- pthread_setspecific(thread_id_key, (void *)memnew(ID(new_id)));
- return new_id;
-}
-
-void ThreadAndroid::wait_to_finish_func_jandroid(Thread *p_thread) {
- ThreadAndroid *tp = static_cast<ThreadAndroid *>(p_thread);
- ERR_FAIL_COND(!tp);
- ERR_FAIL_COND(tp->pthread == 0);
-
- pthread_join(tp->pthread, nullptr);
- tp->pthread = 0;
-}
-
-void ThreadAndroid::_thread_destroyed(void *value) {
- /* The thread is being destroyed, detach it from the Java VM and set the mThreadKey value to NULL as required */
- JNIEnv *env = (JNIEnv *)value;
- if (env != nullptr) {
- java_vm->DetachCurrentThread();
- pthread_setspecific(jvm_key, nullptr);
- }
-}
-
-pthread_key_t ThreadAndroid::jvm_key;
-JavaVM *ThreadAndroid::java_vm = nullptr;
-
-void ThreadAndroid::setup_thread() {
- if (pthread_getspecific(jvm_key))
- return; //already setup
- JNIEnv *env;
+static void init_thread() {
java_vm->AttachCurrentThread(&env, nullptr);
- pthread_setspecific(jvm_key, (void *)env);
}
-void ThreadAndroid::make_default(JavaVM *p_java_vm) {
- java_vm = p_java_vm;
- create_func = create_func_jandroid;
- get_thread_id_func = get_thread_id_func_jandroid;
- wait_to_finish_func = wait_to_finish_func_jandroid;
- pthread_key_create(&jvm_key, _thread_destroyed);
- setup_thread();
+static void term_thread() {
+ java_vm->DetachCurrentThread();
}
-JNIEnv *ThreadAndroid::get_env() {
- if (!pthread_getspecific(jvm_key)) {
- setup_thread();
- }
-
- JNIEnv *env = nullptr;
- java_vm->AttachCurrentThread(&env, nullptr);
- return env;
+void init_thread_jandroid(JavaVM *p_jvm, JNIEnv *p_env) {
+ java_vm = p_jvm;
+ env = p_env;
+ Thread::_set_platform_funcs(nullptr, nullptr, &init_thread, &term_thread);
}
-ThreadAndroid::ThreadAndroid() {
- pthread = 0;
+void setup_android_thread() {
+ init_thread();
}
-ThreadAndroid::~ThreadAndroid() {
+JNIEnv *get_jni_env() {
+ return env;
}
diff --git a/platform/android/thread_jandroid.h b/platform/android/thread_jandroid.h
index 9cfcc64813..ff13ae911f 100644
--- a/platform/android/thread_jandroid.h
+++ b/platform/android/thread_jandroid.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -28,46 +28,14 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef THREAD_POSIX_H
-#define THREAD_POSIX_H
+#ifndef THREAD_JANDROID_H
+#define THREAD_JANDROID_H
-#include "core/os/thread.h"
#include <jni.h>
-#include <pthread.h>
-#include <sys/types.h>
-class ThreadAndroid : public Thread {
- static pthread_key_t thread_id_key;
- static ID next_thread_id;
+void init_thread_jandroid(JavaVM *p_jvm, JNIEnv *p_env);
- pthread_t pthread;
- pthread_attr_t pthread_attr;
- ThreadCreateCallback callback;
- void *user;
- ID id;
-
- static Thread *create_thread_jandroid();
-
- static void *thread_callback(void *userdata);
-
- static Thread *create_func_jandroid(ThreadCreateCallback p_callback, void *, const Settings &);
- static ID get_thread_id_func_jandroid();
- static void wait_to_finish_func_jandroid(Thread *p_thread);
-
- static void _thread_destroyed(void *value);
- ThreadAndroid();
-
- static pthread_key_t jvm_key;
- static JavaVM *java_vm;
-
-public:
- virtual ID get_id() const;
-
- static void make_default(JavaVM *p_java_vm);
- static void setup_thread();
- static JNIEnv *get_env();
-
- ~ThreadAndroid();
-};
+void setup_android_thread();
+JNIEnv *get_jni_env();
#endif
diff --git a/platform/android/vulkan/vulkan_context_android.cpp b/platform/android/vulkan/vulkan_context_android.cpp
index 56ef99dfc7..1bf85f07f1 100644
--- a/platform/android/vulkan/vulkan_context_android.cpp
+++ b/platform/android/vulkan/vulkan_context_android.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/vulkan/vulkan_context_android.h b/platform/android/vulkan/vulkan_context_android.h
index 6bd3cbee36..c608f2d665 100644
--- a/platform/android/vulkan/vulkan_context_android.h
+++ b/platform/android/vulkan/vulkan_context_android.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/app_delegate.h b/platform/iphone/app_delegate.h
index 2f082f1e07..d6a2292dd2 100644
--- a/platform/iphone/app_delegate.h
+++ b/platform/iphone/app_delegate.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/app_delegate.mm b/platform/iphone/app_delegate.mm
index c1942e77dd..d10ea5c68c 100644
--- a/platform/iphone/app_delegate.mm
+++ b/platform/iphone/app_delegate.mm
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/detect.py b/platform/iphone/detect.py
index 0456458326..17796beb6f 100644
--- a/platform/iphone/detect.py
+++ b/platform/iphone/detect.py
@@ -12,7 +12,6 @@ def get_name():
def can_build():
-
if sys.platform == "darwin" or ("OSXCROSS_IOS" in os.environ):
return True
@@ -35,20 +34,19 @@ def get_opts():
" validation layers)",
False,
),
+ BoolVariable("ios_simulator", "Build for iOS Simulator", False),
BoolVariable("ios_exceptions", "Enable exceptions", False),
("ios_triple", "Triple for ios toolchain", ""),
]
def get_flags():
-
return [
("tools", False),
]
def configure(env):
-
## Build type
if env["target"].startswith("release"):
@@ -110,8 +108,17 @@ def configure(env):
## Compile flags
- if env["arch"] == "x86" or env["arch"] == "x86_64":
+ if env["ios_simulator"]:
detect_darwin_sdk_path("iphonesimulator", env)
+ env.Append(CCFLAGS=["-mios-simulator-version-min=13.0"])
+ env.Append(LINKFLAGS=["-mios-simulator-version-min=13.0"])
+ env.extra_suffix = ".simulator" + env.extra_suffix
+ else:
+ detect_darwin_sdk_path("iphone", env)
+ env.Append(CCFLAGS=["-miphoneos-version-min=11.0"])
+ env.Append(LINKFLAGS=["-miphoneos-version-min=11.0"])
+
+ if env["arch"] == "x86" or env["arch"] == "x86_64":
env["ENV"]["MACOSX_DEPLOYMENT_TARGET"] = "10.9"
arch_flag = "i386" if env["arch"] == "x86" else env["arch"]
env.Append(
@@ -119,11 +126,10 @@ def configure(env):
"-fobjc-arc -arch "
+ arch_flag
+ " -fobjc-abi-version=2 -fobjc-legacy-dispatch -fmessage-length=0 -fpascal-strings -fblocks"
- " -fasm-blocks -isysroot $IPHONESDK -mios-simulator-version-min=13.0"
+ " -fasm-blocks -isysroot $IPHONESDK"
).split()
)
elif env["arch"] == "arm":
- detect_darwin_sdk_path("iphone", env)
env.Append(
CCFLAGS=(
"-fobjc-arc -arch armv7 -fmessage-length=0 -fno-strict-aliasing"
@@ -131,16 +137,15 @@ def configure(env):
" -fpascal-strings -fblocks -isysroot $IPHONESDK -fvisibility=hidden -mthumb"
' "-DIBOutlet=__attribute__((iboutlet))"'
' "-DIBOutletCollection(ClassName)=__attribute__((iboutletcollection(ClassName)))"'
- ' "-DIBAction=void)__attribute__((ibaction)" -miphoneos-version-min=11.0 -MMD -MT dependencies'.split()
+ ' "-DIBAction=void)__attribute__((ibaction)" -MMD -MT dependencies'.split()
)
)
elif env["arch"] == "arm64":
- detect_darwin_sdk_path("iphone", env)
env.Append(
CCFLAGS=(
"-fobjc-arc -arch arm64 -fmessage-length=0 -fno-strict-aliasing"
" -fdiagnostics-print-source-range-info -fdiagnostics-show-category=id -fdiagnostics-parseable-fixits"
- " -fpascal-strings -fblocks -fvisibility=hidden -MMD -MT dependencies -miphoneos-version-min=11.0"
+ " -fpascal-strings -fblocks -fvisibility=hidden -MMD -MT dependencies"
" -isysroot $IPHONESDK".split()
)
)
@@ -165,7 +170,6 @@ def configure(env):
LINKFLAGS=[
"-arch",
arch_flag,
- "-mios-simulator-version-min=13.0",
"-isysroot",
"$IPHONESDK",
"-Xlinker",
@@ -176,46 +180,14 @@ def configure(env):
]
)
elif env["arch"] == "arm":
- env.Append(LINKFLAGS=["-arch", "armv7", "-Wl,-dead_strip", "-miphoneos-version-min=11.0"])
+ env.Append(LINKFLAGS=["-arch", "armv7", "-Wl,-dead_strip"])
if env["arch"] == "arm64":
- env.Append(LINKFLAGS=["-arch", "arm64", "-Wl,-dead_strip", "-miphoneos-version-min=11.0"])
+ env.Append(LINKFLAGS=["-arch", "arm64", "-Wl,-dead_strip"])
env.Append(
LINKFLAGS=[
"-isysroot",
"$IPHONESDK",
- "-framework",
- "AudioToolbox",
- "-framework",
- "AVFoundation",
- "-framework",
- "CoreAudio",
- "-framework",
- "CoreGraphics",
- "-framework",
- "CoreMedia",
- "-framework",
- "CoreVideo",
- "-framework",
- "CoreMotion",
- "-framework",
- "Foundation",
- "-framework",
- "GameController",
- "-framework",
- "MediaPlayer",
- "-framework",
- "Metal",
- "-framework",
- "QuartzCore",
- "-framework",
- "Security",
- "-framework",
- "SystemConfiguration",
- "-framework",
- "UIKit",
- "-framework",
- "ARKit",
]
)
diff --git a/platform/iphone/device_metrics.h b/platform/iphone/device_metrics.h
index 6d0ff49077..bc8f761dde 100644
--- a/platform/iphone/device_metrics.h
+++ b/platform/iphone/device_metrics.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/device_metrics.m b/platform/iphone/device_metrics.m
index 747872bc49..306ca95d03 100644
--- a/platform/iphone/device_metrics.m
+++ b/platform/iphone/device_metrics.m
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/display_layer.h b/platform/iphone/display_layer.h
index bfde8f96a3..1b8435d959 100644
--- a/platform/iphone/display_layer.h
+++ b/platform/iphone/display_layer.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/display_layer.mm b/platform/iphone/display_layer.mm
index 7420a5ebe6..b8df81b89a 100644
--- a/platform/iphone/display_layer.mm
+++ b/platform/iphone/display_layer.mm
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -89,7 +89,7 @@
// FIXME: Add Vulkan support via MoltenVK. Add fallback code back?
// Create GL ES 2 context
- if (GLOBAL_GET("rendering/quality/driver/driver_name") == "GLES2") {
+ if (GLOBAL_GET("rendering/driver/driver_name") == "GLES2") {
context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
NSLog(@"Setting up an OpenGL ES 2.0 context.");
if (!context) {
diff --git a/platform/iphone/display_server_iphone.h b/platform/iphone/display_server_iphone.h
index 229b1e80db..31a44723a5 100644
--- a/platform/iphone/display_server_iphone.h
+++ b/platform/iphone/display_server_iphone.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,7 +36,7 @@
#if defined(VULKAN_ENABLED)
#include "drivers/vulkan/rendering_device_vulkan.h"
-#include "servers/rendering/rasterizer_rd/rasterizer_rd.h"
+#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
#include "vulkan_context_iphone.h"
diff --git a/platform/iphone/display_server_iphone.mm b/platform/iphone/display_server_iphone.mm
index d47d131719..05dc78bb4d 100644
--- a/platform/iphone/display_server_iphone.mm
+++ b/platform/iphone/display_server_iphone.mm
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -73,7 +73,7 @@ DisplayServerIPhone::DisplayServerIPhone(const String &p_rendering_driver, Displ
// return ERR_UNAVAILABLE;
}
- // rendering_server = memnew(RenderingServerRaster);
+ // rendering_server = memnew(RenderingServerDefault);
// // FIXME: Reimplement threaded rendering
// if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {
// rendering_server = memnew(RenderingServerWrapMT(rendering_server,
@@ -118,7 +118,7 @@ DisplayServerIPhone::DisplayServerIPhone(const String &p_rendering_driver, Displ
rendering_device_vulkan = memnew(RenderingDeviceVulkan);
rendering_device_vulkan->initialize(context_vulkan);
- RasterizerRD::make_current();
+ RendererCompositorRD::make_current();
}
#endif
diff --git a/platform/iphone/export/export.cpp b/platform/iphone/export/export.cpp
index fff82c9467..c585c2afbe 100644
--- a/platform/iphone/export/export.cpp
+++ b/platform/iphone/export/export.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -37,6 +37,7 @@
#include "core/io/zip_io.h"
#include "core/os/file_access.h"
#include "core/os/os.h"
+#include "core/templates/safe_refcount.h"
#include "core/version.h"
#include "editor/editor_export.h"
#include "editor/editor_node.h"
@@ -56,11 +57,11 @@ class EditorExportPlatformIOS : public EditorExportPlatform {
Ref<ImageTexture> logo;
// Plugins
- volatile bool plugins_changed;
- Thread *check_for_changes_thread;
- volatile bool quit_request;
+ SafeFlag plugins_changed;
+ Thread check_for_changes_thread;
+ SafeFlag quit_request;
Mutex plugins_lock;
- Vector<PluginConfig> plugins;
+ Vector<PluginConfigIOS> plugins;
typedef Error (*FileHandler)(String p_file, void *p_userdata);
static Error _walk_dir_recursive(DirAccess *p_da, FileHandler p_handler, void *p_userdata);
@@ -94,8 +95,8 @@ class EditorExportPlatformIOS : public EditorExportPlatform {
struct IOSExportAsset {
String exported_path;
- bool is_framework; // framework is anything linked to the binary, otherwise it's a resource
- bool should_embed;
+ bool is_framework = false; // framework is anything linked to the binary, otherwise it's a resource
+ bool should_embed = false;
};
String _get_additional_plist_content();
@@ -141,19 +142,19 @@ class EditorExportPlatformIOS : public EditorExportPlatform {
static void _check_for_changes_poll_thread(void *ud) {
EditorExportPlatformIOS *ea = (EditorExportPlatformIOS *)ud;
- while (!ea->quit_request) {
+ while (!ea->quit_request.is_set()) {
// Nothing to do if we already know the plugins have changed.
- if (!ea->plugins_changed) {
+ if (!ea->plugins_changed.is_set()) {
MutexLock lock(ea->plugins_lock);
- Vector<PluginConfig> loaded_plugins = get_plugins();
+ Vector<PluginConfigIOS> loaded_plugins = get_plugins();
if (ea->plugins.size() != loaded_plugins.size()) {
- ea->plugins_changed = true;
+ ea->plugins_changed.set();
} else {
for (int i = 0; i < ea->plugins.size(); i++) {
if (ea->plugins[i].name != loaded_plugins[i].name || ea->plugins[i].last_updated != loaded_plugins[i].last_updated) {
- ea->plugins_changed = true;
+ ea->plugins_changed.set();
break;
}
}
@@ -165,7 +166,7 @@ class EditorExportPlatformIOS : public EditorExportPlatform {
while (OS::get_singleton()->get_ticks_usec() - time < wait) {
OS::get_singleton()->delay_usec(300000);
- if (ea->quit_request) {
+ if (ea->quit_request.is_set()) {
break;
}
}
@@ -182,10 +183,10 @@ public:
virtual Ref<Texture2D> get_logo() const override { return logo; }
virtual bool should_update_export_options() override {
- bool export_options_changed = plugins_changed;
+ bool export_options_changed = plugins_changed.is_set();
if (export_options_changed) {
// don't clear unless we're reporting true, to avoid race
- plugins_changed = false;
+ plugins_changed.clear();
}
return export_options_changed;
}
@@ -218,7 +219,7 @@ public:
da->list_dir_begin();
while (true) {
String file = da->get_next();
- if (file.empty()) {
+ if (file.is_empty()) {
break;
}
@@ -241,7 +242,7 @@ public:
continue;
}
- if (file.ends_with(PLUGIN_CONFIG_EXT)) {
+ if (file.ends_with(PluginConfigIOS::PLUGIN_CONFIG_EXT)) {
dir_files.push_back(file);
}
}
@@ -251,18 +252,18 @@ public:
return dir_files;
}
- static Vector<PluginConfig> get_plugins() {
- Vector<PluginConfig> loaded_plugins;
+ static Vector<PluginConfigIOS> get_plugins() {
+ Vector<PluginConfigIOS> loaded_plugins;
String plugins_dir = ProjectSettings::get_singleton()->get_resource_path().plus_file("ios/plugins");
if (DirAccess::exists(plugins_dir)) {
Vector<String> plugins_filenames = list_plugin_config_files(plugins_dir, true);
- if (!plugins_filenames.empty()) {
+ if (!plugins_filenames.is_empty()) {
Ref<ConfigFile> config_file = memnew(ConfigFile);
for (int i = 0; i < plugins_filenames.size(); i++) {
- PluginConfig config = load_plugin_config(config_file, plugins_dir.plus_file(plugins_filenames[i]));
+ PluginConfigIOS config = load_plugin_config(config_file, plugins_dir.plus_file(plugins_filenames[i]));
if (config.valid_config) {
loaded_plugins.push_back(config);
} else {
@@ -275,11 +276,11 @@ public:
return loaded_plugins;
}
- static Vector<PluginConfig> get_enabled_plugins(const Ref<EditorExportPreset> &p_presets) {
- Vector<PluginConfig> enabled_plugins;
- Vector<PluginConfig> all_plugins = get_plugins();
+ static Vector<PluginConfigIOS> get_enabled_plugins(const Ref<EditorExportPreset> &p_presets) {
+ Vector<PluginConfigIOS> enabled_plugins;
+ Vector<PluginConfigIOS> all_plugins = get_plugins();
for (int i = 0; i < all_plugins.size(); i++) {
- PluginConfig plugin = all_plugins[i];
+ PluginConfigIOS plugin = all_plugins[i];
bool enabled = p_presets->get("plugins/" + plugin.name);
if (enabled) {
enabled_plugins.push_back(plugin);
@@ -291,7 +292,7 @@ public:
};
void EditorExportPlatformIOS::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) {
- String driver = ProjectSettings::get_singleton()->get("rendering/quality/driver/driver_name");
+ String driver = ProjectSettings::get_singleton()->get("rendering/driver/driver_name");
r_features->push_back("pvrtc");
if (driver == "Vulkan") {
// FIXME: Review if this is correct.
@@ -314,9 +315,9 @@ Vector<EditorExportPlatformIOS::ExportArchitecture> EditorExportPlatformIOS::_ge
struct LoadingScreenInfo {
const char *preset_key;
const char *export_name;
- int width;
- int height;
- bool rotate;
+ int width = 0;
+ int height = 0;
+ bool rotate = false;
};
static const LoadingScreenInfo loading_screen_infos[] = {
@@ -360,11 +361,11 @@ void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options)
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/version"), "1.0"));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/copyright"), ""));
- Vector<PluginConfig> found_plugins = get_plugins();
+ Vector<PluginConfigIOS> found_plugins = get_plugins();
for (int i = 0; i < found_plugins.size(); i++) {
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "plugins/" + found_plugins[i].name), false));
}
- plugins_changed = false;
+ plugins_changed.clear();
plugins = found_plugins;
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "capabilities/access_wifi"), false));
@@ -667,7 +668,7 @@ struct IconInfo {
const char *actual_size_side;
const char *scale;
const char *unscaled_size;
- bool is_required;
+ bool is_required = false;
};
static const IconInfo icon_infos[] = {
@@ -815,7 +816,7 @@ Error EditorExportPlatformIOS::_export_loading_screen_file(const Ref<EditorExpor
const String splash_path = ProjectSettings::get_singleton()->get("application/boot_splash/image");
- if (!splash_path.empty()) {
+ if (!splash_path.is_empty()) {
splash.instance();
const Error err = splash->load(splash_path);
if (err) {
@@ -962,7 +963,7 @@ Error EditorExportPlatformIOS::_walk_dir_recursive(DirAccess *p_da, FileHandler
struct CodesignData {
const Ref<EditorExportPreset> &preset;
- bool debug;
+ bool debug = false;
CodesignData(const Ref<EditorExportPreset> &p_preset, bool p_debug) :
preset(p_preset),
@@ -979,7 +980,7 @@ Error EditorExportPlatformIOS::_codesign(String p_file, void *p_userdata) {
codesign_args.push_back("-s");
codesign_args.push_back(data->preset->get(data->debug ? "application/code_sign_identity_debug" : "application/code_sign_identity_release"));
codesign_args.push_back(p_file);
- return OS::get_singleton()->execute("codesign", codesign_args, true);
+ return OS::get_singleton()->execute("codesign", codesign_args);
}
return OK;
}
@@ -1229,7 +1230,7 @@ Error EditorExportPlatformIOS::_copy_asset(const String &p_out_dir, const String
install_name_args.push_back(String("@rpath").plus_file(framework_name).plus_file(file_name));
install_name_args.push_back(destination);
- OS::get_singleton()->execute("install_name_tool", install_name_args, true);
+ OS::get_singleton()->execute("install_name_tool", install_name_args);
}
// Creating Info.plist
@@ -1345,28 +1346,25 @@ Error EditorExportPlatformIOS::_export_ios_plugins(const Ref<EditorExportPreset>
Vector<String> plugin_embedded_dependencies;
Vector<String> plugin_files;
- Vector<PluginConfig> enabled_plugins = get_enabled_plugins(p_preset);
+ Vector<PluginConfigIOS> enabled_plugins = get_enabled_plugins(p_preset);
Vector<String> added_linked_dependenciy_names;
Vector<String> added_embedded_dependenciy_names;
HashMap<String, String> plist_values;
+ Set<String> plugin_linker_flags;
+
Error err;
for (int i = 0; i < enabled_plugins.size(); i++) {
- PluginConfig plugin = enabled_plugins[i];
+ PluginConfigIOS plugin = enabled_plugins[i];
// Export plugin binary.
- if (!plugin.supports_targets) {
- err = _copy_asset(dest_dir, plugin.binary, nullptr, true, true, r_exported_assets);
- } else {
- String plugin_binary_dir = plugin.binary.get_base_dir();
- String plugin_name_prefix = plugin.binary.get_basename().get_file();
- String plugin_file = plugin_name_prefix + "." + (p_debug ? "debug" : "release") + ".a";
- String result_file_name = plugin.binary.get_file();
-
- err = _copy_asset(dest_dir, plugin_binary_dir.plus_file(plugin_file), &result_file_name, true, true, r_exported_assets);
- }
+ String plugin_main_binary = get_plugin_main_binary(plugin, p_debug);
+ String plugin_binary_result_file = plugin.binary.get_file();
+ // We shouldn't embed .xcframework that contains static libraries.
+ // Static libraries are not embedded anyway.
+ err = _copy_asset(dest_dir, plugin_main_binary, &plugin_binary_result_file, true, false, r_exported_assets);
ERR_FAIL_COND_V(err, err);
@@ -1422,6 +1420,13 @@ Error EditorExportPlatformIOS::_export_ios_plugins(const Ref<EditorExportPreset>
p_config_data.capabilities.push_back(capability);
}
+ // Linker flags
+ // Checking duplicates
+ for (int j = 0; j < plugin.linker_flags.size(); j++) {
+ String linker_flag = plugin.linker_flags[j];
+ plugin_linker_flags.insert(linker_flag);
+ }
+
// Plist
// Using hash map container to remove duplicates
const String *K = nullptr;
@@ -1430,7 +1435,7 @@ Error EditorExportPlatformIOS::_export_ios_plugins(const Ref<EditorExportPreset>
String key = *K;
String value = plugin.plist[key];
- if (key.empty() || value.empty()) {
+ if (key.is_empty() || value.is_empty()) {
continue;
}
@@ -1457,7 +1462,7 @@ Error EditorExportPlatformIOS::_export_ios_plugins(const Ref<EditorExportPreset>
String key = *K;
String value = plist_values[key];
- if (key.empty() || value.empty()) {
+ if (key.is_empty() || value.is_empty()) {
continue;
}
@@ -1502,6 +1507,27 @@ Error EditorExportPlatformIOS::_export_ios_plugins(const Ref<EditorExportPreset>
p_config_data.cpp_code += plugin_cpp_code.format(plugin_format, "$_");
}
+
+ // Update Linker Flag Values
+ {
+ String result_linker_flags = " ";
+ for (Set<String>::Element *E = plugin_linker_flags.front(); E; E = E->next()) {
+ const String &flag = E->get();
+
+ if (flag.length() == 0) {
+ continue;
+ }
+
+ if (result_linker_flags.length() > 0) {
+ result_linker_flags += ' ';
+ }
+
+ result_linker_flags += flag;
+ }
+ result_linker_flags = result_linker_flags.replace("\"", "\\\"");
+ p_config_data.linker_flags += result_linker_flags;
+ }
+
return OK;
}
@@ -1575,9 +1601,9 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
return ERR_SKIP;
}
- String library_to_use = "libgodot.iphone." + String(p_debug ? "debug" : "release") + ".fat.a";
+ String library_to_use = "libgodot.iphone." + String(p_debug ? "debug" : "release") + ".xcframework";
- print_line("Static library: " + library_to_use);
+ print_line("Static framework: " + library_to_use);
String pkg_name;
if (p_preset->get("application/name") != "") {
pkg_name = p_preset->get("application/name"); // app_name
@@ -1663,7 +1689,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
if (files_to_parse.has(file)) {
_fix_config_file(p_preset, data, config_data, p_debug);
} else if (file.begins_with("libgodot.iphone")) {
- if (file != library_to_use) {
+ if (!file.begins_with(library_to_use) || file.ends_with(String("/empty"))) {
ret = unzGoToNextFile(src_pkg_zip);
continue; //ignore!
}
@@ -1671,7 +1697,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
#if defined(OSX_ENABLED) || defined(X11_ENABLED)
is_execute = true;
#endif
- file = "godot_ios.a";
+ file = file.replace(library_to_use, binary_name + ".xcframework");
}
if (file == project_file) {
@@ -1848,7 +1874,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
archive_args.push_back("archive");
archive_args.push_back("-archivePath");
archive_args.push_back(archive_path);
- err = OS::get_singleton()->execute("xcodebuild", archive_args, true);
+ err = OS::get_singleton()->execute("xcodebuild", archive_args);
ERR_FAIL_COND_V(err, err);
if (ep.step("Making .ipa", 4)) {
@@ -1863,7 +1889,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
export_args.push_back("-allowProvisioningUpdates");
export_args.push_back("-exportPath");
export_args.push_back(dest_dir);
- err = OS::get_singleton()->execute("xcodebuild", export_args, true);
+ err = OS::get_singleton()->execute("xcodebuild", export_args);
ERR_FAIL_COND_V(err, err);
#else
print_line(".ipa can only be built on macOS. Leaving Xcode project without building the package.");
@@ -1930,7 +1956,7 @@ bool EditorExportPlatformIOS::can_export(const Ref<EditorExportPreset> &p_preset
err += etc_error;
}
- if (!err.empty()) {
+ if (!err.is_empty()) {
r_error = err;
}
@@ -1942,16 +1968,14 @@ EditorExportPlatformIOS::EditorExportPlatformIOS() {
logo.instance();
logo->create_from_image(img);
- plugins_changed = true;
- quit_request = false;
+ plugins_changed.set();
- check_for_changes_thread = Thread::create(_check_for_changes_poll_thread, this);
+ check_for_changes_thread.start(_check_for_changes_poll_thread, this);
}
EditorExportPlatformIOS::~EditorExportPlatformIOS() {
- quit_request = true;
- Thread::wait_to_finish(check_for_changes_thread);
- memdelete(check_for_changes_thread);
+ quit_request.set();
+ check_for_changes_thread.wait_to_finish();
}
void register_iphone_exporter() {
diff --git a/platform/iphone/export/export.h b/platform/iphone/export/export.h
index 043d21f533..4a79ca279f 100644
--- a/platform/iphone/export/export.h
+++ b/platform/iphone/export/export.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/godot_app_delegate.h b/platform/iphone/godot_app_delegate.h
index ebb21c499b..6335ada50e 100644
--- a/platform/iphone/godot_app_delegate.h
+++ b/platform/iphone/godot_app_delegate.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/godot_app_delegate.m b/platform/iphone/godot_app_delegate.m
index a5aad26bd5..3ce9bffc79 100644
--- a/platform/iphone/godot_app_delegate.m
+++ b/platform/iphone/godot_app_delegate.m
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -302,37 +302,7 @@ static NSMutableArray<ApplicationDelegateService *> *services = nil;
// MARK: Remote Notification
-- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
- for (ApplicationDelegateService *service in services) {
- if (![service respondsToSelector:_cmd]) {
- continue;
- }
-
- [service application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
- }
-}
-
-- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
- for (ApplicationDelegateService *service in services) {
- if (![service respondsToSelector:_cmd]) {
- continue;
- }
-
- [service application:application didFailToRegisterForRemoteNotificationsWithError:error];
- }
-}
-
-- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler {
- for (ApplicationDelegateService *service in services) {
- if (![service respondsToSelector:_cmd]) {
- continue;
- }
-
- [service application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
- }
-
- completionHandler(UIBackgroundFetchResultNoData);
-}
+// Moved to the iOS Plugin
// MARK: User Activity and Handling Quick Actions
diff --git a/platform/iphone/godot_iphone.mm b/platform/iphone/godot_iphone.mm
index a4119bcafd..62bc2e6e52 100644
--- a/platform/iphone/godot_iphone.mm
+++ b/platform/iphone/godot_iphone.mm
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/godot_view.h b/platform/iphone/godot_view.h
index a8f4cb38d9..265f826173 100644
--- a/platform/iphone/godot_view.h
+++ b/platform/iphone/godot_view.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -32,12 +32,20 @@
class String;
+@class GodotView;
@protocol DisplayLayer;
@protocol GodotViewRendererProtocol;
+@protocol GodotViewDelegate
+
+- (BOOL)godotViewFinishedSetup:(GodotView *)view;
+
+@end
+
@interface GodotView : UIView
@property(assign, nonatomic) id<GodotViewRendererProtocol> renderer;
+@property(assign, nonatomic) id<GodotViewDelegate> delegate;
@property(assign, readonly, nonatomic) BOOL isActive;
diff --git a/platform/iphone/godot_view.mm b/platform/iphone/godot_view.mm
index 0c50842cfa..887297848e 100644
--- a/platform/iphone/godot_view.mm
+++ b/platform/iphone/godot_view.mm
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -120,6 +120,7 @@ static const int max_touches = 8;
[self stopRendering];
self.renderer = nil;
+ self.delegate = nil;
if (self.renderingLayer) {
[self.renderingLayer removeFromSuperlayer];
@@ -241,6 +242,14 @@ static const int max_touches = 8;
return;
}
+ if (self.delegate) {
+ BOOL delegateFinishedSetup = [self.delegate godotViewFinishedSetup:self];
+
+ if (!delegateFinishedSetup) {
+ return;
+ }
+ }
+
[self handleMotion];
[self.renderer renderOnView:self];
}
diff --git a/platform/iphone/godot_view_gesture_recognizer.h b/platform/iphone/godot_view_gesture_recognizer.h
index 1431a9fb89..48b2d5ffad 100644
--- a/platform/iphone/godot_view_gesture_recognizer.h
+++ b/platform/iphone/godot_view_gesture_recognizer.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/godot_view_gesture_recognizer.mm b/platform/iphone/godot_view_gesture_recognizer.mm
index 91cc07fcf6..cf6e5c5883 100644
--- a/platform/iphone/godot_view_gesture_recognizer.mm
+++ b/platform/iphone/godot_view_gesture_recognizer.mm
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/godot_view_renderer.h b/platform/iphone/godot_view_renderer.h
index ea8998c808..c6b0a05a4e 100644
--- a/platform/iphone/godot_view_renderer.h
+++ b/platform/iphone/godot_view_renderer.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/godot_view_renderer.mm b/platform/iphone/godot_view_renderer.mm
index f2ff417e6f..07d664715a 100644
--- a/platform/iphone/godot_view_renderer.mm
+++ b/platform/iphone/godot_view_renderer.mm
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/ios.h b/platform/iphone/ios.h
index 5415c36cd9..4bf64d4bc1 100644
--- a/platform/iphone/ios.h
+++ b/platform/iphone/ios.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/ios.mm b/platform/iphone/ios.mm
index d4e099063f..cef03534c4 100644
--- a/platform/iphone/ios.mm
+++ b/platform/iphone/ios.mm
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/joypad_iphone.h b/platform/iphone/joypad_iphone.h
index 85e26e1dc8..329cc8207f 100644
--- a/platform/iphone/joypad_iphone.h
+++ b/platform/iphone/joypad_iphone.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/joypad_iphone.mm b/platform/iphone/joypad_iphone.mm
index 22d7dd4bd2..a0f0eee5d3 100644
--- a/platform/iphone/joypad_iphone.mm
+++ b/platform/iphone/joypad_iphone.mm
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/keyboard_input_view.h b/platform/iphone/keyboard_input_view.h
index 5382a2e9a9..cfbfc7a120 100644
--- a/platform/iphone/keyboard_input_view.h
+++ b/platform/iphone/keyboard_input_view.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/keyboard_input_view.mm b/platform/iphone/keyboard_input_view.mm
index 1a37403de7..1408f78e90 100644
--- a/platform/iphone/keyboard_input_view.mm
+++ b/platform/iphone/keyboard_input_view.mm
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/main.m b/platform/iphone/main.m
index 351b40a881..fddd5bd99f 100644
--- a/platform/iphone/main.m
+++ b/platform/iphone/main.m
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/native_video_view.h b/platform/iphone/native_video_view.h
index d8687b3538..2df5e27fa4 100644
--- a/platform/iphone/native_video_view.h
+++ b/platform/iphone/native_video_view.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/native_video_view.m b/platform/iphone/native_video_view.m
index 1193946f2b..f126749600 100644
--- a/platform/iphone/native_video_view.m
+++ b/platform/iphone/native_video_view.m
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/os_iphone.h b/platform/iphone/os_iphone.h
index 04a0a478d5..f4ff909adf 100644
--- a/platform/iphone/os_iphone.h
+++ b/platform/iphone/os_iphone.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -38,7 +38,7 @@
#include "ios.h"
#include "joypad_iphone.h"
#include "servers/audio_server.h"
-#include "servers/rendering/rasterizer.h"
+#include "servers/rendering/renderer_compositor.h"
#if defined(VULKAN_ENABLED)
#include "drivers/vulkan/rendering_device_vulkan.h"
diff --git a/platform/iphone/os_iphone.mm b/platform/iphone/os_iphone.mm
index b87e6f37a0..51c4da2960 100644
--- a/platform/iphone/os_iphone.mm
+++ b/platform/iphone/os_iphone.mm
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -47,7 +47,7 @@
#import <dlfcn.h>
#if defined(VULKAN_ENABLED)
-#include "servers/rendering/rasterizer_rd/rasterizer_rd.h"
+#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
#import <QuartzCore/CAMetalLayer.h>
#include <vulkan/vulkan_metal.h>
#endif
@@ -144,12 +144,10 @@ void OSIPhone::deinitialize_modules() {
}
void OSIPhone::set_main_loop(MainLoop *p_main_loop) {
- godot_ios_plugins_initialize();
-
main_loop = p_main_loop;
if (main_loop) {
- main_loop->init();
+ main_loop->initialize();
}
}
@@ -159,7 +157,7 @@ MainLoop *OSIPhone::get_main_loop() const {
void OSIPhone::delete_main_loop() {
if (main_loop) {
- main_loop->finish();
+ main_loop->finalize();
memdelete(main_loop);
};
@@ -179,6 +177,8 @@ bool OSIPhone::iterate() {
}
void OSIPhone::start() {
+ godot_ios_plugins_initialize();
+
Main::start();
if (joypad_iphone) {
diff --git a/platform/iphone/platform_config.h b/platform/iphone/platform_config.h
index ec39ad0ba4..88ad4a3f67 100644
--- a/platform/iphone/platform_config.h
+++ b/platform/iphone/platform_config.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/plugin/godot_plugin_config.h b/platform/iphone/plugin/godot_plugin_config.h
index 5323f94989..f4e30c8349 100644
--- a/platform/iphone/plugin/godot_plugin_config.h
+++ b/platform/iphone/plugin/godot_plugin_config.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -35,23 +35,6 @@
#include "core/io/config_file.h"
#include "core/string/ustring.h"
-static const char *PLUGIN_CONFIG_EXT = ".gdip";
-
-static const char *CONFIG_SECTION = "config";
-static const char *CONFIG_NAME_KEY = "name";
-static const char *CONFIG_BINARY_KEY = "binary";
-static const char *CONFIG_INITIALIZE_KEY = "initialization";
-static const char *CONFIG_DEINITIALIZE_KEY = "deinitialization";
-
-static const char *DEPENDENCIES_SECTION = "dependencies";
-static const char *DEPENDENCIES_LINKED_KEY = "linked";
-static const char *DEPENDENCIES_EMBEDDED_KEY = "embedded";
-static const char *DEPENDENCIES_SYSTEM_KEY = "system";
-static const char *DEPENDENCIES_CAPABILITIES_KEY = "capabilities";
-static const char *DEPENDENCIES_FILES_KEY = "files";
-
-static const char *PLIST_SECTION = "plist";
-
/*
The `config` section and fields are required and defined as follow:
- **name**: name of the plugin
@@ -68,7 +51,25 @@ The `plist` section are optional.
- **key**: key and value that would be added in Info.plist file.
*/
-struct PluginConfig {
+struct PluginConfigIOS {
+ inline static const char *PLUGIN_CONFIG_EXT = ".gdip";
+
+ inline static const char *CONFIG_SECTION = "config";
+ inline static const char *CONFIG_NAME_KEY = "name";
+ inline static const char *CONFIG_BINARY_KEY = "binary";
+ inline static const char *CONFIG_INITIALIZE_KEY = "initialization";
+ inline static const char *CONFIG_DEINITIALIZE_KEY = "deinitialization";
+
+ inline static const char *DEPENDENCIES_SECTION = "dependencies";
+ inline static const char *DEPENDENCIES_LINKED_KEY = "linked";
+ inline static const char *DEPENDENCIES_EMBEDDED_KEY = "embedded";
+ inline static const char *DEPENDENCIES_SYSTEM_KEY = "system";
+ inline static const char *DEPENDENCIES_CAPABILITIES_KEY = "capabilities";
+ inline static const char *DEPENDENCIES_FILES_KEY = "files";
+ inline static const char *DEPENDENCIES_LINKER_FLAGS = "linker_flags";
+
+ inline static const char *PLIST_SECTION = "plist";
+
// Set to true when the config file is properly loaded.
bool valid_config = false;
bool supports_targets = false;
@@ -89,6 +90,8 @@ struct PluginConfig {
Vector<String> files_to_copy;
Vector<String> capabilities;
+ Vector<String> linker_flags;
+
// Optional plist section
// Supports only string types for now
HashMap<String, String> plist;
@@ -97,7 +100,7 @@ struct PluginConfig {
static inline String resolve_local_dependency_path(String plugin_config_dir, String dependency_path) {
String absolute_path;
- if (dependency_path.empty()) {
+ if (dependency_path.is_empty()) {
return absolute_path;
}
@@ -114,7 +117,7 @@ static inline String resolve_local_dependency_path(String plugin_config_dir, Str
static inline String resolve_system_dependency_path(String dependency_path) {
String absolute_path;
- if (dependency_path.empty()) {
+ if (dependency_path.is_empty()) {
return absolute_path;
}
@@ -133,7 +136,7 @@ static inline Vector<String> resolve_local_dependencies(String plugin_config_dir
for (int i = 0; i < p_paths.size(); i++) {
String path = resolve_local_dependency_path(plugin_config_dir, p_paths[i]);
- if (path.empty()) {
+ if (path.is_empty()) {
continue;
}
@@ -149,7 +152,7 @@ static inline Vector<String> resolve_system_dependencies(Vector<String> p_paths)
for (int i = 0; i < p_paths.size(); i++) {
String path = resolve_system_dependency_path(p_paths[i]);
- if (path.empty()) {
+ if (path.is_empty()) {
continue;
}
@@ -159,24 +162,33 @@ static inline Vector<String> resolve_system_dependencies(Vector<String> p_paths)
return paths;
}
-static inline bool validate_plugin(PluginConfig &plugin_config) {
- bool valid_name = !plugin_config.name.empty();
- bool valid_binary_name = !plugin_config.binary.empty();
- bool valid_initialize = !plugin_config.initialization_method.empty();
- bool valid_deinitialize = !plugin_config.deinitialization_method.empty();
+static inline bool validate_plugin(PluginConfigIOS &plugin_config) {
+ bool valid_name = !plugin_config.name.is_empty();
+ bool valid_binary_name = !plugin_config.binary.is_empty();
+ bool valid_initialize = !plugin_config.initialization_method.is_empty();
+ bool valid_deinitialize = !plugin_config.deinitialization_method.is_empty();
bool fields_value = valid_name && valid_binary_name && valid_initialize && valid_deinitialize;
- if (fields_value && FileAccess::exists(plugin_config.binary)) {
+ if (!fields_value) {
+ return false;
+ }
+
+ String plugin_extension = plugin_config.binary.get_extension().to_lower();
+
+ if ((plugin_extension == "a" && FileAccess::exists(plugin_config.binary)) ||
+ (plugin_extension == "xcframework" && DirAccess::exists(plugin_config.binary))) {
plugin_config.valid_config = true;
plugin_config.supports_targets = false;
- } else if (fields_value) {
+ } else {
String file_path = plugin_config.binary.get_base_dir();
String file_name = plugin_config.binary.get_basename().get_file();
- String release_file_name = file_path.plus_file(file_name + ".release.a");
- String debug_file_name = file_path.plus_file(file_name + ".debug.a");
+ String file_extension = plugin_config.binary.get_extension();
+ String release_file_name = file_path.plus_file(file_name + ".release." + file_extension);
+ String debug_file_name = file_path.plus_file(file_name + ".debug." + file_extension);
- if (FileAccess::exists(release_file_name) && FileAccess::exists(debug_file_name)) {
+ if ((plugin_extension == "a" && FileAccess::exists(release_file_name) && FileAccess::exists(debug_file_name)) ||
+ (plugin_extension == "xcframework" && DirAccess::exists(release_file_name) && DirAccess::exists(debug_file_name))) {
plugin_config.valid_config = true;
plugin_config.supports_targets = true;
}
@@ -185,7 +197,20 @@ static inline bool validate_plugin(PluginConfig &plugin_config) {
return plugin_config.valid_config;
}
-static inline uint64_t get_plugin_modification_time(const PluginConfig &plugin_config, const String &config_path) {
+static inline String get_plugin_main_binary(PluginConfigIOS &plugin_config, bool p_debug) {
+ if (!plugin_config.supports_targets) {
+ return plugin_config.binary;
+ }
+
+ String plugin_binary_dir = plugin_config.binary.get_base_dir();
+ String plugin_name_prefix = plugin_config.binary.get_basename().get_file();
+ String plugin_extension = plugin_config.binary.get_extension();
+ String plugin_file = plugin_name_prefix + "." + (p_debug ? "debug" : "release") + "." + plugin_extension;
+
+ return plugin_binary_dir.plus_file(plugin_file);
+}
+
+static inline uint64_t get_plugin_modification_time(const PluginConfigIOS &plugin_config, const String &config_path) {
uint64_t last_updated = FileAccess::get_modified_time(config_path);
if (!plugin_config.supports_targets) {
@@ -203,8 +228,8 @@ static inline uint64_t get_plugin_modification_time(const PluginConfig &plugin_c
return last_updated;
}
-static inline PluginConfig load_plugin_config(Ref<ConfigFile> config_file, const String &path) {
- PluginConfig plugin_config = {};
+static inline PluginConfigIOS load_plugin_config(Ref<ConfigFile> config_file, const String &path) {
+ PluginConfigIOS plugin_config = {};
if (!config_file.is_valid()) {
return plugin_config;
@@ -218,18 +243,18 @@ static inline PluginConfig load_plugin_config(Ref<ConfigFile> config_file, const
String config_base_dir = path.get_base_dir();
- plugin_config.name = config_file->get_value(CONFIG_SECTION, CONFIG_NAME_KEY, String());
- plugin_config.initialization_method = config_file->get_value(CONFIG_SECTION, CONFIG_INITIALIZE_KEY, String());
- plugin_config.deinitialization_method = config_file->get_value(CONFIG_SECTION, CONFIG_DEINITIALIZE_KEY, String());
+ plugin_config.name = config_file->get_value(PluginConfigIOS::CONFIG_SECTION, PluginConfigIOS::CONFIG_NAME_KEY, String());
+ plugin_config.initialization_method = config_file->get_value(PluginConfigIOS::CONFIG_SECTION, PluginConfigIOS::CONFIG_INITIALIZE_KEY, String());
+ plugin_config.deinitialization_method = config_file->get_value(PluginConfigIOS::CONFIG_SECTION, PluginConfigIOS::CONFIG_DEINITIALIZE_KEY, String());
- String binary_path = config_file->get_value(CONFIG_SECTION, CONFIG_BINARY_KEY, String());
+ String binary_path = config_file->get_value(PluginConfigIOS::CONFIG_SECTION, PluginConfigIOS::CONFIG_BINARY_KEY, String());
plugin_config.binary = resolve_local_dependency_path(config_base_dir, binary_path);
- if (config_file->has_section(DEPENDENCIES_SECTION)) {
- Vector<String> linked_dependencies = config_file->get_value(DEPENDENCIES_SECTION, DEPENDENCIES_LINKED_KEY, Vector<String>());
- Vector<String> embedded_dependencies = config_file->get_value(DEPENDENCIES_SECTION, DEPENDENCIES_EMBEDDED_KEY, Vector<String>());
- Vector<String> system_dependencies = config_file->get_value(DEPENDENCIES_SECTION, DEPENDENCIES_SYSTEM_KEY, Vector<String>());
- Vector<String> files = config_file->get_value(DEPENDENCIES_SECTION, DEPENDENCIES_FILES_KEY, Vector<String>());
+ if (config_file->has_section(PluginConfigIOS::DEPENDENCIES_SECTION)) {
+ Vector<String> linked_dependencies = config_file->get_value(PluginConfigIOS::DEPENDENCIES_SECTION, PluginConfigIOS::DEPENDENCIES_LINKED_KEY, Vector<String>());
+ Vector<String> embedded_dependencies = config_file->get_value(PluginConfigIOS::DEPENDENCIES_SECTION, PluginConfigIOS::DEPENDENCIES_EMBEDDED_KEY, Vector<String>());
+ Vector<String> system_dependencies = config_file->get_value(PluginConfigIOS::DEPENDENCIES_SECTION, PluginConfigIOS::DEPENDENCIES_SYSTEM_KEY, Vector<String>());
+ Vector<String> files = config_file->get_value(PluginConfigIOS::DEPENDENCIES_SECTION, PluginConfigIOS::DEPENDENCIES_FILES_KEY, Vector<String>());
plugin_config.linked_dependencies = resolve_local_dependencies(config_base_dir, linked_dependencies);
plugin_config.embedded_dependencies = resolve_local_dependencies(config_base_dir, embedded_dependencies);
@@ -237,17 +262,19 @@ static inline PluginConfig load_plugin_config(Ref<ConfigFile> config_file, const
plugin_config.files_to_copy = resolve_local_dependencies(config_base_dir, files);
- plugin_config.capabilities = config_file->get_value(DEPENDENCIES_SECTION, DEPENDENCIES_CAPABILITIES_KEY, Vector<String>());
+ plugin_config.capabilities = config_file->get_value(PluginConfigIOS::DEPENDENCIES_SECTION, PluginConfigIOS::DEPENDENCIES_CAPABILITIES_KEY, Vector<String>());
+
+ plugin_config.linker_flags = config_file->get_value(PluginConfigIOS::DEPENDENCIES_SECTION, PluginConfigIOS::DEPENDENCIES_LINKER_FLAGS, Vector<String>());
}
- if (config_file->has_section(PLIST_SECTION)) {
+ if (config_file->has_section(PluginConfigIOS::PLIST_SECTION)) {
List<String> keys;
- config_file->get_section_keys(PLIST_SECTION, &keys);
+ config_file->get_section_keys(PluginConfigIOS::PLIST_SECTION, &keys);
for (int i = 0; i < keys.size(); i++) {
- String value = config_file->get_value(PLIST_SECTION, keys[i], String());
+ String value = config_file->get_value(PluginConfigIOS::PLIST_SECTION, keys[i], String());
- if (value.empty()) {
+ if (value.is_empty()) {
continue;
}
diff --git a/platform/iphone/view_controller.h b/platform/iphone/view_controller.h
index ff76359842..52fb6fbbf2 100644
--- a/platform/iphone/view_controller.h
+++ b/platform/iphone/view_controller.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/view_controller.mm b/platform/iphone/view_controller.mm
index 7e44d30851..6cef244567 100644
--- a/platform/iphone/view_controller.mm
+++ b/platform/iphone/view_controller.mm
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -40,12 +40,14 @@
#import <AVFoundation/AVFoundation.h>
#import <GameController/GameController.h>
-@interface ViewController ()
+@interface ViewController () <GodotViewDelegate>
@property(strong, nonatomic) GodotViewRenderer *renderer;
@property(strong, nonatomic) GodotNativeVideoView *videoView;
@property(strong, nonatomic) GodotKeyboardInputView *keyboardView;
+@property(strong, nonatomic) UIView *godotLoadingOverlay;
+
@end
@implementation ViewController
@@ -62,6 +64,7 @@
self.view = view;
view.renderer = self.renderer;
+ view.delegate = self;
}
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
@@ -97,6 +100,7 @@
[super viewDidLoad];
[self observeKeyboard];
+ [self displayLoadingOverlay];
if (@available(iOS 11.0, *)) {
[self setNeedsUpdateOfScreenEdgesDeferringSystemGestures];
@@ -121,6 +125,31 @@
object:nil];
}
+- (void)displayLoadingOverlay {
+ NSBundle *bundle = [NSBundle mainBundle];
+ NSString *storyboardName = @"Launch Screen";
+
+ if ([bundle pathForResource:storyboardName ofType:@"storyboardc"] == nil) {
+ return;
+ }
+
+ UIStoryboard *launchStoryboard = [UIStoryboard storyboardWithName:storyboardName bundle:bundle];
+
+ UIViewController *controller = [launchStoryboard instantiateInitialViewController];
+ self.godotLoadingOverlay = controller.view;
+ self.godotLoadingOverlay.frame = self.view.bounds;
+ self.godotLoadingOverlay.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
+
+ [self.view addSubview:self.godotLoadingOverlay];
+}
+
+- (BOOL)godotViewFinishedSetup:(GodotView *)view {
+ [self.godotLoadingOverlay removeFromSuperview];
+ self.godotLoadingOverlay = nil;
+
+ return YES;
+}
+
- (void)dealloc {
[self.videoView stopVideo];
@@ -130,6 +159,11 @@
self.renderer = nil;
+ if (self.godotLoadingOverlay) {
+ [self.godotLoadingOverlay removeFromSuperview];
+ self.godotLoadingOverlay = nil;
+ }
+
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
diff --git a/platform/iphone/vulkan_context_iphone.h b/platform/iphone/vulkan_context_iphone.h
index 5c3d5fe33e..88764e270e 100644
--- a/platform/iphone/vulkan_context_iphone.h
+++ b/platform/iphone/vulkan_context_iphone.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/vulkan_context_iphone.mm b/platform/iphone/vulkan_context_iphone.mm
index d62e826957..b980ae99f0 100644
--- a/platform/iphone/vulkan_context_iphone.mm
+++ b/platform/iphone/vulkan_context_iphone.mm
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/javascript/.eslintrc.engine.js b/platform/javascript/.eslintrc.engine.js
index 00f0f147a9..3725cf164e 100644
--- a/platform/javascript/.eslintrc.engine.js
+++ b/platform/javascript/.eslintrc.engine.js
@@ -3,6 +3,7 @@ module.exports = {
"./.eslintrc.js",
],
"globals": {
+ "EngineConfig": true,
"Godot": true,
"Preloader": true,
"Utils": true,
diff --git a/platform/javascript/.eslintrc.libs.js b/platform/javascript/.eslintrc.libs.js
index e5f0c3d147..81b1b8c864 100644
--- a/platform/javascript/.eslintrc.libs.js
+++ b/platform/javascript/.eslintrc.libs.js
@@ -18,5 +18,8 @@ module.exports = {
"GodotRuntime": true,
"GodotFS": true,
"IDHandler": true,
+ "Browser": true,
+ "GL": true,
+ "XRWebGLLayer": true,
},
};
diff --git a/platform/javascript/SCsub b/platform/javascript/SCsub
index 627ae778b1..ab527ef419 100644
--- a/platform/javascript/SCsub
+++ b/platform/javascript/SCsub
@@ -12,13 +12,8 @@ javascript_files = [
"api/javascript_tools_editor_plugin.cpp",
]
-build_targets = ["#bin/godot${PROGSUFFIX}.js", "#bin/godot${PROGSUFFIX}.wasm"]
-if env["threads_enabled"]:
- build_targets.append("#bin/godot${PROGSUFFIX}.worker.js")
-
-build = env.add_program(build_targets, javascript_files)
-
-env.AddJSLibraries(
+sys_env = env.Clone()
+sys_env.AddJSLibraries(
[
"js/libs/library_godot_audio.js",
"js/libs/library_godot_display.js",
@@ -29,16 +24,57 @@ env.AddJSLibraries(
)
if env["tools"]:
- env.AddJSLibraries(["js/libs/library_godot_editor_tools.js"])
+ sys_env.AddJSLibraries(["js/libs/library_godot_editor_tools.js"])
if env["javascript_eval"]:
- env.AddJSLibraries(["js/libs/library_godot_eval.js"])
-for lib in env["JS_LIBS"]:
- env.Append(LINKFLAGS=["--js-library", lib])
-env.Depends(build, env["JS_LIBS"])
+ sys_env.AddJSLibraries(["js/libs/library_godot_eval.js"])
+
+for lib in sys_env["JS_LIBS"]:
+ sys_env.Append(LINKFLAGS=["--js-library", lib])
+for js in env["JS_PRE"]:
+ sys_env.Append(LINKFLAGS=["--pre-js", env.File(js).path])
+for ext in env["JS_EXTERNS"]:
+ sys_env["ENV"]["EMCC_CLOSURE_ARGS"] += " --externs " + ext.path
+
+build = []
+if env["gdnative_enabled"]:
+ build_targets = ["#bin/godot${PROGSUFFIX}.js", "#bin/godot${PROGSUFFIX}.wasm"]
+ # Reset libraries. The main runtime will only link emscripten libraries, not godot ones.
+ sys_env["LIBS"] = []
+ # We use IDBFS. Since Emscripten 1.39.1 it needs to be linked explicitly.
+ sys_env.Append(LIBS=["idbfs.js"])
+ # Configure it as a main module (dynamic linking support).
+ sys_env.Append(CCFLAGS=["-s", "MAIN_MODULE=1"])
+ sys_env.Append(LINKFLAGS=["-s", "MAIN_MODULE=1"])
+ sys_env.Append(CCFLAGS=["-s", "EXPORT_ALL=1"])
+ sys_env.Append(LINKFLAGS=["-s", "EXPORT_ALL=1"])
+ # Force exporting the standard library (printf, malloc, etc.)
+ sys_env["ENV"]["EMCC_FORCE_STDLIBS"] = "libc,libc++,libc++abi"
+ # The main emscripten runtime, with exported standard libraries.
+ sys = sys_env.Program(build_targets, ["javascript_runtime.cpp"])
+
+ # The side library, containing all Godot code.
+ wasm_env = env.Clone()
+ wasm_env.Append(CPPDEFINES=["WASM_GDNATIVE"]) # So that OS knows it can run GDNative libraries.
+ wasm_env.Append(CCFLAGS=["-s", "SIDE_MODULE=2"])
+ wasm_env.Append(LINKFLAGS=["-s", "SIDE_MODULE=2"])
+ wasm = wasm_env.add_program("#bin/godot.side${PROGSUFFIX}.wasm", javascript_files)
+ build = [sys[0], sys[1], wasm[0]]
+else:
+ build_targets = ["#bin/godot${PROGSUFFIX}.js", "#bin/godot${PROGSUFFIX}.wasm"]
+ if env["threads_enabled"]:
+ build_targets.append("#bin/godot${PROGSUFFIX}.worker.js")
+ # We use IDBFS. Since Emscripten 1.39.1 it needs to be linked explicitly.
+ sys_env.Append(LIBS=["idbfs.js"])
+ build = sys_env.Program(build_targets, javascript_files + ["javascript_runtime.cpp"])
+
+sys_env.Depends(build[0], sys_env["JS_LIBS"])
+sys_env.Depends(build[0], sys_env["JS_PRE"])
+sys_env.Depends(build[0], sys_env["JS_EXTERNS"])
engine = [
"js/engine/preloader.js",
"js/engine/utils.js",
+ "js/engine/config.js",
"js/engine/engine.js",
]
externs = [env.File("#platform/javascript/js/engine/engine.externs.js")]
@@ -59,12 +95,27 @@ out_files = [
zip_dir.File(binary_name + ".html"),
zip_dir.File(binary_name + ".audio.worklet.js"),
]
-html_file = "#misc/dist/html/editor.html" if env["tools"] else "#misc/dist/html/full-size.html"
+html_file = "#misc/dist/html/full-size.html"
+if env["tools"]:
+ subst_dict = {"\$GODOT_VERSION": env.GetBuildVersion()}
+ html_file = env.Substfile(
+ target="#bin/godot${PROGSUFFIX}.html", source="#misc/dist/html/editor.html", SUBST_DICT=subst_dict
+ )
+
in_files = [js_wrapped, build[1], html_file, "#platform/javascript/js/libs/audio.worklet.js"]
-if env["threads_enabled"]:
- in_files.append(build[2])
+if env["gdnative_enabled"]:
+ in_files.append(build[2]) # Runtime
+ out_files.append(zip_dir.File(binary_name + ".side.wasm"))
+elif env["threads_enabled"]:
+ in_files.append(build[2]) # Worker
out_files.append(zip_dir.File(binary_name + ".worker.js"))
+if env["tools"]:
+ in_files.append("#misc/dist/html/logo.svg")
+ out_files.append(zip_dir.File("logo.svg"))
+ in_files.append("#icon.png")
+ out_files.append(zip_dir.File("favicon.png"))
+
zip_files = env.InstallAs(out_files, in_files)
env.Zip(
"#bin/godot",
diff --git a/platform/javascript/api/api.cpp b/platform/javascript/api/api.cpp
index 6fd6c0ddf1..2f7bde065f 100644
--- a/platform/javascript/api/api.cpp
+++ b/platform/javascript/api/api.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/javascript/api/api.h b/platform/javascript/api/api.h
index 8afe0f33ce..2ac7333cdd 100644
--- a/platform/javascript/api/api.h
+++ b/platform/javascript/api/api.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/javascript/api/javascript_eval.h b/platform/javascript/api/javascript_eval.h
index 389983077e..24f7648ed9 100644
--- a/platform/javascript/api/javascript_eval.h
+++ b/platform/javascript/api/javascript_eval.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/javascript/api/javascript_tools_editor_plugin.cpp b/platform/javascript/api/javascript_tools_editor_plugin.cpp
index 8d781703ed..8355faccc2 100644
--- a/platform/javascript/api/javascript_tools_editor_plugin.cpp
+++ b/platform/javascript/api/javascript_tools_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -53,8 +53,7 @@ void JavaScriptToolsEditorPlugin::initialize() {
}
JavaScriptToolsEditorPlugin::JavaScriptToolsEditorPlugin(EditorNode *p_editor) {
- Variant v;
- add_tool_menu_item("Download Project Source", this, "_download_zip", v);
+ add_tool_menu_item("Download Project Source", callable_mp(this, &JavaScriptToolsEditorPlugin::_download_zip));
}
void JavaScriptToolsEditorPlugin::_download_zip(Variant p_v) {
@@ -73,10 +72,6 @@ void JavaScriptToolsEditorPlugin::_download_zip(Variant p_v) {
godot_js_editor_download_file("/tmp/project.zip", "project.zip", "application/zip");
}
-void JavaScriptToolsEditorPlugin::_bind_methods() {
- ClassDB::bind_method("_download_zip", &JavaScriptToolsEditorPlugin::_download_zip);
-}
-
void JavaScriptToolsEditorPlugin::_zip_file(String p_path, String p_base_path, zipFile p_zip) {
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
if (!f) {
@@ -113,7 +108,7 @@ void JavaScriptToolsEditorPlugin::_zip_recursive(String p_path, String p_base_pa
}
dir->list_dir_begin();
String cur = dir->get_next();
- while (!cur.empty()) {
+ while (!cur.is_empty()) {
String cs = p_path.plus_file(cur);
if (cur == "." || cur == ".." || cur == ".import") {
// Skip
diff --git a/platform/javascript/api/javascript_tools_editor_plugin.h b/platform/javascript/api/javascript_tools_editor_plugin.h
index cc09fa4cd3..557821d627 100644
--- a/platform/javascript/api/javascript_tools_editor_plugin.h
+++ b/platform/javascript/api/javascript_tools_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -41,10 +41,6 @@ class JavaScriptToolsEditorPlugin : public EditorPlugin {
private:
void _zip_file(String p_path, String p_base_path, zipFile p_zip);
void _zip_recursive(String p_path, String p_base_path, zipFile p_zip);
-
-protected:
- static void _bind_methods();
-
void _download_zip(Variant p_v);
public:
diff --git a/platform/javascript/audio_driver_javascript.cpp b/platform/javascript/audio_driver_javascript.cpp
index dd982bc3a8..478e848675 100644
--- a/platform/javascript/audio_driver_javascript.cpp
+++ b/platform/javascript/audio_driver_javascript.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -105,8 +105,8 @@ void AudioDriverJavaScript::_audio_driver_capture(int p_from, int p_samples) {
}
Error AudioDriverJavaScript::init() {
- mix_rate = GLOBAL_GET("audio/mix_rate");
- int latency = GLOBAL_GET("audio/output_latency");
+ mix_rate = GLOBAL_GET("audio/driver/mix_rate");
+ int latency = GLOBAL_GET("audio/driver/output_latency");
channel_count = godot_audio_init(mix_rate, latency, &_state_change_callback, &_latency_update_callback);
buffer_length = closest_power_of_2((latency * mix_rate / 1000));
@@ -189,7 +189,9 @@ Error AudioDriverJavaScript::capture_start() {
lock();
input_buffer_init(buffer_length);
unlock();
- godot_audio_capture_start();
+ if (godot_audio_capture_start()) {
+ return FAILED;
+ }
return OK;
}
@@ -265,7 +267,7 @@ int AudioDriverJavaScript::WorkletNode::create(int p_buffer_size, int p_channels
void AudioDriverJavaScript::WorkletNode::start(float *p_out_buf, int p_out_buf_size, float *p_in_buf, int p_in_buf_size) {
godot_audio_worklet_start(p_in_buf, p_in_buf_size, p_out_buf, p_out_buf_size, state);
- thread = Thread::create(_audio_thread_func, this);
+ thread.start(_audio_thread_func, this);
}
void AudioDriverJavaScript::WorkletNode::lock() {
@@ -278,8 +280,6 @@ void AudioDriverJavaScript::WorkletNode::unlock() {
void AudioDriverJavaScript::WorkletNode::finish() {
quit = true; // Ask thread to quit.
- Thread::wait_to_finish(thread);
- memdelete(thread);
- thread = nullptr;
+ thread.wait_to_finish();
}
#endif
diff --git a/platform/javascript/audio_driver_javascript.h b/platform/javascript/audio_driver_javascript.h
index f112a1ede4..393693640f 100644
--- a/platform/javascript/audio_driver_javascript.h
+++ b/platform/javascript/audio_driver_javascript.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -59,7 +59,7 @@ public:
STATE_MAX,
};
Mutex mutex;
- Thread *thread = nullptr;
+ Thread thread;
bool quit = false;
int32_t state[STATE_MAX] = { 0 };
diff --git a/platform/javascript/detect.py b/platform/javascript/detect.py
index 71189cf697..4297088c09 100644
--- a/platform/javascript/detect.py
+++ b/platform/javascript/detect.py
@@ -1,6 +1,15 @@
import os
-
-from emscripten_helpers import run_closure_compiler, create_engine_file, add_js_libraries
+import sys
+
+from emscripten_helpers import (
+ run_closure_compiler,
+ create_engine_file,
+ add_js_libraries,
+ add_js_pre,
+ add_js_externs,
+ get_build_version,
+)
+from methods import get_compiler_version
from SCons.Util import WhereIs
@@ -20,9 +29,17 @@ def get_opts():
from SCons.Variables import BoolVariable
return [
+ ("initial_memory", "Initial WASM memory (in MiB)", 16),
+ BoolVariable("use_assertions", "Use Emscripten runtime assertions", False),
+ BoolVariable("use_thinlto", "Use ThinLTO", False),
+ BoolVariable("use_ubsan", "Use Emscripten undefined behavior sanitizer (UBSAN)", False),
+ BoolVariable("use_asan", "Use Emscripten address sanitizer (ASAN)", False),
+ BoolVariable("use_lsan", "Use Emscripten leak sanitizer (LSAN)", False),
+ BoolVariable("use_safe_heap", "Use Emscripten SAFE_HEAP sanitizer", False),
# eval() can be a security concern, so it can be disabled.
BoolVariable("javascript_eval", "Enable JavaScript eval interface", True),
BoolVariable("threads_enabled", "Enable WebAssembly Threads support (limited browser support)", False),
+ BoolVariable("gdnative_enabled", "Enable WebAssembly GDNative support (produces bigger binaries)", False),
BoolVariable("use_closure_compiler", "Use closure compiler to minimize JavaScript code", False),
]
@@ -40,9 +57,13 @@ def get_flags():
def configure(env):
+ try:
+ env["initial_memory"] = int(env["initial_memory"])
+ except Exception:
+ print("Initial memory must be a valid integer")
+ sys.exit(255)
## Build type
-
if env["target"] == "release":
# Use -Os to prioritize optimizing for reduced file size. This is
# particularly valuable for the web platform because it directly
@@ -62,15 +83,20 @@ def configure(env):
env.Append(CPPDEFINES=["DEBUG_ENABLED"])
env.Append(CCFLAGS=["-O1", "-g"])
env.Append(LINKFLAGS=["-O1", "-g"])
+ env["use_assertions"] = True
+
+ if env["use_assertions"]:
env.Append(LINKFLAGS=["-s", "ASSERTIONS=1"])
if env["tools"]:
if not env["threads_enabled"]:
- raise RuntimeError(
- "Threads must be enabled to build the editor. Please add the 'threads_enabled=yes' option"
- )
- # Tools need more memory. Initial stack memory in bytes. See `src/settings.js` in emscripten repository (will be renamed to INITIAL_MEMORY).
- env.Append(LINKFLAGS=["-s", "TOTAL_MEMORY=33554432"])
+ print("Threads must be enabled to build the editor. Please add the 'threads_enabled=yes' option")
+ sys.exit(255)
+ if env["initial_memory"] < 64:
+ print("Editor build requires at least 64MiB of initial memory. Forcing it.")
+ env["initial_memory"] = 64
+ elif env["builtin_icu"]:
+ env.Append(CCFLAGS=["-frtti"])
else:
# Disable exceptions and rtti on non-tools (template) builds
# These flags help keep the file size down.
@@ -78,15 +104,32 @@ def configure(env):
# Don't use dynamic_cast, necessary with no-rtti.
env.Append(CPPDEFINES=["NO_SAFE_CAST"])
+ env.Append(LINKFLAGS=["-s", "INITIAL_MEMORY=%sMB" % env["initial_memory"]])
+
## Copy env variables.
env["ENV"] = os.environ
# LTO
- if env["use_lto"]:
- env.Append(CCFLAGS=["-s", "WASM_OBJECT_FILES=0"])
- env.Append(LINKFLAGS=["-s", "WASM_OBJECT_FILES=0"])
- env.Append(CCFLAGS=["-flto"])
- env.Append(LINKFLAGS=["-flto"])
+ if env["use_thinlto"]:
+ env.Append(CCFLAGS=["-flto=thin"])
+ env.Append(LINKFLAGS=["-flto=thin"])
+ elif env["use_lto"]:
+ env.Append(CCFLAGS=["-flto=full"])
+ env.Append(LINKFLAGS=["-flto=full"])
+
+ # Sanitizers
+ if env["use_ubsan"]:
+ env.Append(CCFLAGS=["-fsanitize=undefined"])
+ env.Append(LINKFLAGS=["-fsanitize=undefined"])
+ if env["use_asan"]:
+ env.Append(CCFLAGS=["-fsanitize=address"])
+ env.Append(LINKFLAGS=["-fsanitize=address"])
+ if env["use_lsan"]:
+ env.Append(CCFLAGS=["-fsanitize=leak"])
+ env.Append(LINKFLAGS=["-fsanitize=leak"])
+ if env["use_safe_heap"]:
+ env.Append(CCFLAGS=["-s", "SAFE_HEAP=1"])
+ env.Append(LINKFLAGS=["-s", "SAFE_HEAP=1"])
# Closure compiler
if env["use_closure_compiler"]:
@@ -96,8 +139,16 @@ def configure(env):
jscc = env.Builder(generator=run_closure_compiler, suffix=".cc.js", src_suffix=".js")
env.Append(BUILDERS={"BuildJS": jscc})
- # Add helper method for adding libraries.
+ # Add helper method for adding libraries, externs, pre-js.
+ env["JS_LIBS"] = []
+ env["JS_PRE"] = []
+ env["JS_EXTERNS"] = []
env.AddMethod(add_js_libraries, "AddJSLibraries")
+ env.AddMethod(add_js_pre, "AddJSPre")
+ env.AddMethod(add_js_externs, "AddJSExterns")
+
+ # Add method for getting build version string.
+ env.AddMethod(get_build_version, "GetBuildVersion")
# Add method that joins/compiles our Engine files.
env.AddMethod(create_engine_file, "CreateEngineFile")
@@ -133,6 +184,10 @@ def configure(env):
if env["javascript_eval"]:
env.Append(CPPDEFINES=["JAVASCRIPT_EVAL_ENABLED"])
+ if env["threads_enabled"] and env["gdnative_enabled"]:
+ print("Threads and GDNative support can't be both enabled due to WebAssembly limitations")
+ sys.exit(255)
+
# Thread support (via SharedArrayBuffer).
if env["threads_enabled"]:
env.Append(CPPDEFINES=["PTHREAD_NO_RENAME"])
@@ -144,14 +199,19 @@ def configure(env):
else:
env.Append(CPPDEFINES=["NO_THREADS"])
+ if env["gdnative_enabled"]:
+ major, minor, patch = get_compiler_version(env)
+ if major < 2 or (major == 2 and minor == 0 and patch < 10):
+ print("GDNative support requires emscripten >= 2.0.10, detected: %s.%s.%s" % (major, minor, patch))
+ sys.exit(255)
+ env.Append(CCFLAGS=["-s", "RELOCATABLE=1"])
+ env.Append(LINKFLAGS=["-s", "RELOCATABLE=1"])
+ env.extra_suffix = ".gdnative" + env.extra_suffix
+
# Reduce code size by generating less support code (e.g. skip NodeJS support).
env.Append(LINKFLAGS=["-s", "ENVIRONMENT=web,worker"])
- # We use IDBFS in javascript_main.cpp. Since Emscripten 1.39.1 it needs to
- # be linked explicitly.
- env.Append(LIBS=["idbfs.js"])
-
- env.Append(LINKFLAGS=["-s", "BINARYEN=1"])
+ # Wrap the JavaScript support code around a closure named Godot.
env.Append(LINKFLAGS=["-s", "MODULARIZE=1", "-s", "EXPORT_NAME='Godot'"])
# Allow increasing memory buffer size during runtime. This is efficient
@@ -162,12 +222,22 @@ def configure(env):
# This setting just makes WebGL 2 APIs available, it does NOT disable WebGL 1.
env.Append(LINKFLAGS=["-s", "USE_WEBGL2=1"])
+ # Do not call main immediately when the support code is ready.
env.Append(LINKFLAGS=["-s", "INVOKE_RUN=0"])
# Allow use to take control of swapping WebGL buffers.
env.Append(LINKFLAGS=["-s", "OFFSCREEN_FRAMEBUFFER=1"])
- # callMain for manual start, FS for preloading, PATH and ERRNO_CODES for BrowserFS.
- env.Append(LINKFLAGS=["-s", "EXTRA_EXPORTED_RUNTIME_METHODS=['callMain']"])
+ # callMain for manual start.
+ env.Append(LINKFLAGS=["-s", "EXTRA_EXPORTED_RUNTIME_METHODS=['callMain','cwrap']"])
+
# Add code that allow exiting runtime.
env.Append(LINKFLAGS=["-s", "EXIT_RUNTIME=1"])
+
+ # TODO remove once we have GLES support back (temporary fix undefined symbols due to dead code elimination).
+ env.Append(
+ LINKFLAGS=[
+ "-s",
+ "EXPORTED_FUNCTIONS=['_main', '_emscripten_webgl_get_current_context', '_emscripten_webgl_commit_frame', '_emscripten_webgl_create_context']",
+ ]
+ )
diff --git a/platform/javascript/display_server_javascript.cpp b/platform/javascript/display_server_javascript.cpp
index af8800d565..a605f22e16 100644
--- a/platform/javascript/display_server_javascript.cpp
+++ b/platform/javascript/display_server_javascript.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -59,41 +59,20 @@ bool DisplayServerJavaScript::is_canvas_focused() {
}
bool DisplayServerJavaScript::check_size_force_redraw() {
- int canvas_width;
- int canvas_height;
- emscripten_get_canvas_element_size(DisplayServerJavaScript::canvas_id, &canvas_width, &canvas_height);
- if (last_width != canvas_width || last_height != canvas_height) {
- last_width = canvas_width;
- last_height = canvas_height;
- // Update the framebuffer size for redraw.
- emscripten_set_canvas_element_size(DisplayServerJavaScript::canvas_id, canvas_width, canvas_height);
- return true;
- }
- return false;
+ return godot_js_display_size_update() != 0;
}
Point2 DisplayServerJavaScript::compute_position_in_canvas(int p_x, int p_y) {
- DisplayServerJavaScript *display = get_singleton();
- int canvas_x;
- int canvas_y;
- godot_js_display_canvas_bounding_rect_position_get(&canvas_x, &canvas_y);
- int canvas_width;
- int canvas_height;
- emscripten_get_canvas_element_size(display->canvas_id, &canvas_width, &canvas_height);
-
- double element_width;
- double element_height;
- emscripten_get_element_css_size(display->canvas_id, &element_width, &element_height);
-
- return Point2((int)(canvas_width / element_width * (p_x - canvas_x)),
- (int)(canvas_height / element_height * (p_y - canvas_y)));
+ int point[2];
+ godot_js_display_compute_position(p_x, p_y, point, point + 1);
+ return Point2(point[0], point[1]);
}
EM_BOOL DisplayServerJavaScript::fullscreen_change_callback(int p_event_type, const EmscriptenFullscreenChangeEvent *p_event, void *p_user_data) {
DisplayServerJavaScript *display = get_singleton();
// Empty ID is canvas.
String target_id = String::utf8(p_event->id);
- if (target_id.empty() || target_id == String::utf8(display->canvas_id)) {
+ if (target_id.is_empty() || target_id == String::utf8(&(display->canvas_id[1]))) {
// This event property is the only reliable data on
// browser fullscreen state.
if (p_event->isFullscreen) {
@@ -455,7 +434,7 @@ DisplayServer::MouseMode DisplayServerJavaScript::mouse_get_mode() const {
EmscriptenPointerlockChangeEvent ev;
emscripten_get_pointerlock_status(&ev);
- return (ev.isActive && String::utf8(ev.id) == String::utf8(canvas_id)) ? MOUSE_MODE_CAPTURED : MOUSE_MODE_VISIBLE;
+ return (ev.isActive && String::utf8(ev.id) == String::utf8(&canvas_id[1])) ? MOUSE_MODE_CAPTURED : MOUSE_MODE_VISIBLE;
}
// Wheel
@@ -558,57 +537,51 @@ bool DisplayServerJavaScript::screen_is_touchscreen(int p_screen) const {
}
// Gamepad
-
-EM_BOOL DisplayServerJavaScript::gamepad_change_callback(int p_event_type, const EmscriptenGamepadEvent *p_event, void *p_user_data) {
+void DisplayServerJavaScript::gamepad_callback(int p_index, int p_connected, const char *p_id, const char *p_guid) {
Input *input = Input::get_singleton();
- if (p_event_type == EMSCRIPTEN_EVENT_GAMEPADCONNECTED) {
- String guid = "";
- if (String::utf8(p_event->mapping) == "standard")
- guid = "Default HTML5 Gamepad";
- input->joy_connection_changed(p_event->index, true, String::utf8(p_event->id), guid);
+ if (p_connected) {
+ input->joy_connection_changed(p_index, true, String::utf8(p_id), String::utf8(p_guid));
} else {
- input->joy_connection_changed(p_event->index, false, "");
+ input->joy_connection_changed(p_index, false, "");
}
- return true;
}
void DisplayServerJavaScript::process_joypads() {
- int joypad_count = emscripten_get_num_gamepads();
Input *input = Input::get_singleton();
- for (int joypad = 0; joypad < joypad_count; joypad++) {
- EmscriptenGamepadEvent state;
- EMSCRIPTEN_RESULT query_result = emscripten_get_gamepad_status(joypad, &state);
- // Chromium reserves gamepads slots, so NO_DATA is an expected result.
- ERR_CONTINUE(query_result != EMSCRIPTEN_RESULT_SUCCESS &&
- query_result != EMSCRIPTEN_RESULT_NO_DATA);
- if (query_result == EMSCRIPTEN_RESULT_SUCCESS && state.connected) {
- int button_count = MIN(state.numButtons, 18);
- int axis_count = MIN(state.numAxes, 8);
- for (int button = 0; button < button_count; button++) {
- float value = state.analogButton[button];
- input->joy_button(joypad, button, value);
- }
- for (int axis = 0; axis < axis_count; axis++) {
+ int32_t pads = godot_js_display_gamepad_sample_count();
+ int32_t s_btns_num = 0;
+ int32_t s_axes_num = 0;
+ int32_t s_standard = 0;
+ float s_btns[16];
+ float s_axes[10];
+ for (int idx = 0; idx < pads; idx++) {
+ int err = godot_js_display_gamepad_sample_get(idx, s_btns, &s_btns_num, s_axes, &s_axes_num, &s_standard);
+ if (err) {
+ continue;
+ }
+ for (int b = 0; b < s_btns_num; b++) {
+ float value = s_btns[b];
+ // Buttons 6 and 7 in the standard mapping need to be
+ // axis to be handled as JOY_AXIS_TRIGGER by Godot.
+ if (s_standard && (b == 6 || b == 7)) {
Input::JoyAxis joy_axis;
- joy_axis.min = -1;
- joy_axis.value = state.axis[axis];
- input->joy_axis(joypad, axis, joy_axis);
+ joy_axis.min = 0;
+ joy_axis.value = value;
+ int a = b == 6 ? JOY_AXIS_TRIGGER_LEFT : JOY_AXIS_TRIGGER_RIGHT;
+ input->joy_axis(idx, a, joy_axis);
+ } else {
+ input->joy_button(idx, b, value);
}
}
+ for (int a = 0; a < s_axes_num; a++) {
+ Input::JoyAxis joy_axis;
+ joy_axis.min = -1;
+ joy_axis.value = s_axes[a];
+ input->joy_axis(idx, a, joy_axis);
+ }
}
}
-#if 0
-bool DisplayServerJavaScript::is_joy_known(int p_device) {
- return Input::get_singleton()->is_joy_mapped(p_device);
-}
-
-
-String DisplayServerJavaScript::get_joy_guid(int p_device) const {
- return Input::get_singleton()->get_joy_guid_remapped(p_device);
-}
-#endif
-
Vector<String> DisplayServerJavaScript::get_rendering_drivers_func() {
Vector<String> drivers;
drivers.push_back("dummy");
@@ -709,6 +682,9 @@ DisplayServerJavaScript::DisplayServerJavaScript(const String &p_rendering_drive
// Ensure the canvas ID.
godot_js_config_canvas_id_get(canvas_id, 256);
+ // Handle contextmenu, webglcontextlost
+ godot_js_display_setup_canvas(p_resolution.x, p_resolution.y, p_mode == WINDOW_MODE_FULLSCREEN);
+
// Check if it's windows.
swap_cancel_ok = godot_js_display_is_swap_ok_cancel() == 1;
@@ -751,11 +727,6 @@ DisplayServerJavaScript::DisplayServerJavaScript(const String &p_rendering_drive
video_driver_index = p_video_driver;
#endif
- window_set_mode(p_mode);
- if (godot_js_config_is_resize_on_start()) {
- window_set_size(p_resolution);
- }
-
EMSCRIPTEN_RESULT result;
#define EM_CHECK(ev) \
if (result != EMSCRIPTEN_RESULT_SUCCESS) \
@@ -766,9 +737,6 @@ DisplayServerJavaScript::DisplayServerJavaScript(const String &p_rendering_drive
#define SET_EM_WINDOW_CALLBACK(ev, cb) \
result = emscripten_set_##ev##_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, false, &cb); \
EM_CHECK(ev)
-#define SET_EM_CALLBACK_NOTARGET(ev, cb) \
- result = emscripten_set_##ev##_callback(nullptr, true, &cb); \
- EM_CHECK(ev)
// These callbacks from Emscripten's html5.h suffice to access most
// JavaScript APIs.
SET_EM_CALLBACK(canvas_id, mousedown, mouse_button_callback)
@@ -783,9 +751,6 @@ DisplayServerJavaScript::DisplayServerJavaScript(const String &p_rendering_drive
SET_EM_CALLBACK(canvas_id, keypress, keypress_callback)
SET_EM_CALLBACK(canvas_id, keyup, keyup_callback)
SET_EM_CALLBACK(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, fullscreenchange, fullscreen_change_callback)
- SET_EM_CALLBACK_NOTARGET(gamepadconnected, gamepad_change_callback)
- SET_EM_CALLBACK_NOTARGET(gamepaddisconnected, gamepad_change_callback)
-#undef SET_EM_CALLBACK_NOTARGET
#undef SET_EM_CALLBACK
#undef EM_CHECK
@@ -798,6 +763,7 @@ DisplayServerJavaScript::DisplayServerJavaScript(const String &p_rendering_drive
WINDOW_EVENT_FOCUS_OUT);
godot_js_display_paste_cb(update_clipboard_callback);
godot_js_display_drop_files_cb(drop_files_js_callback);
+ godot_js_display_gamepad_cb(&DisplayServerJavaScript::gamepad_callback);
Input::get_singleton()->set_event_dispatch_function(_dispatch_input_event);
}
@@ -850,20 +816,23 @@ Point2i DisplayServerJavaScript::screen_get_position(int p_screen) const {
}
Size2i DisplayServerJavaScript::screen_get_size(int p_screen) const {
- EmscriptenFullscreenChangeEvent ev;
- EMSCRIPTEN_RESULT result = emscripten_get_fullscreen_status(&ev);
- ERR_FAIL_COND_V(result != EMSCRIPTEN_RESULT_SUCCESS, Size2i());
- return Size2i(ev.screenWidth, ev.screenHeight);
+ int size[2];
+ godot_js_display_screen_size_get(size, size + 1);
+ return Size2(size[0], size[1]);
}
Rect2i DisplayServerJavaScript::screen_get_usable_rect(int p_screen) const {
- int canvas[2];
- emscripten_get_canvas_element_size(canvas_id, canvas, canvas + 1);
- return Rect2i(0, 0, canvas[0], canvas[1]);
+ int size[2];
+ godot_js_display_window_size_get(size, size + 1);
+ return Rect2i(0, 0, size[0], size[1]);
}
int DisplayServerJavaScript::screen_get_dpi(int p_screen) const {
- return 96; // TODO maybe check pixel ratio via window.devicePixelRatio * 96? Inexact.
+ return godot_js_display_screen_dpi_get();
+}
+
+float DisplayServerJavaScript::screen_get_scale(int p_screen) const {
+ return godot_js_display_pixel_ratio_get();
}
Vector<DisplayServer::WindowID> DisplayServerJavaScript::get_window_list() const {
@@ -945,17 +914,13 @@ Size2i DisplayServerJavaScript::window_get_min_size(WindowID p_window) const {
}
void DisplayServerJavaScript::window_set_size(const Size2i p_size, WindowID p_window) {
- last_width = p_size.x;
- last_height = p_size.y;
- double scale = godot_js_display_pixel_ratio_get();
- emscripten_set_canvas_element_size(canvas_id, p_size.x * scale, p_size.y * scale);
- emscripten_set_element_css_size(canvas_id, p_size.x, p_size.y);
+ godot_js_display_desired_size_set(p_size.x, p_size.y);
}
Size2i DisplayServerJavaScript::window_get_size(WindowID p_window) const {
- int canvas[2];
- emscripten_get_canvas_element_size(canvas_id, canvas, canvas + 1);
- return Size2(canvas[0], canvas[1]);
+ int size[2];
+ godot_js_display_window_size_get(size, size + 1);
+ return Size2i(size[0], size[1]);
}
Size2i DisplayServerJavaScript::window_get_real_size(WindowID p_window) const {
@@ -969,20 +934,13 @@ void DisplayServerJavaScript::window_set_mode(WindowMode p_mode, WindowID p_wind
switch (p_mode) {
case WINDOW_MODE_WINDOWED: {
if (window_mode == WINDOW_MODE_FULLSCREEN) {
- emscripten_exit_fullscreen();
+ godot_js_display_fullscreen_exit();
}
window_mode = WINDOW_MODE_WINDOWED;
- window_set_size(Size2i(last_width, last_height));
} break;
case WINDOW_MODE_FULLSCREEN: {
- EmscriptenFullscreenStrategy strategy;
- strategy.scaleMode = EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH;
- strategy.canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF;
- strategy.filteringMode = EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT;
- strategy.canvasResizedCallback = nullptr;
- EMSCRIPTEN_RESULT result = emscripten_request_fullscreen_strategy(canvas_id, false, &strategy);
- ERR_FAIL_COND_MSG(result == EMSCRIPTEN_RESULT_FAILED_NOT_DEFERRED, "Enabling fullscreen is only possible from an input callback for the HTML5 platform.");
- ERR_FAIL_COND_MSG(result != EMSCRIPTEN_RESULT_SUCCESS, "Enabling fullscreen is only possible from an input callback for the HTML5 platform.");
+ int result = godot_js_display_fullscreen_request();
+ ERR_FAIL_COND_MSG(result, "The request was denied. Remember that enabling fullscreen is only possible from an input callback for the HTML5 platform.");
} break;
case WINDOW_MODE_MAXIMIZED:
case WINDOW_MODE_MINIMIZED:
@@ -1026,8 +984,9 @@ bool DisplayServerJavaScript::can_any_window_draw() const {
}
void DisplayServerJavaScript::process_events() {
- if (emscripten_sample_gamepad_data() == EMSCRIPTEN_RESULT_SUCCESS)
+ if (godot_js_display_gamepad_sample() == OK) {
process_joypads();
+ }
}
int DisplayServerJavaScript::get_current_video_driver() const {
diff --git a/platform/javascript/display_server_javascript.h b/platform/javascript/display_server_javascript.h
index 1f00295d48..47e25ab2a0 100644
--- a/platform/javascript/display_server_javascript.h
+++ b/platform/javascript/display_server_javascript.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -57,9 +57,6 @@ private:
double last_click_ms = 0;
int last_click_button_index = -1;
- int last_width = 0;
- int last_height = 0;
-
bool swap_cancel_ok = false;
// utilities
@@ -86,7 +83,7 @@ private:
static EM_BOOL touch_press_callback(int p_event_type, const EmscriptenTouchEvent *p_event, void *p_user_data);
static EM_BOOL touchmove_callback(int p_event_type, const EmscriptenTouchEvent *p_event, void *p_user_data);
- static EM_BOOL gamepad_change_callback(int p_event_type, const EmscriptenGamepadEvent *p_event, void *p_user_data);
+ static void gamepad_callback(int p_index, int p_connected, const char *p_id, const char *p_guid);
void process_joypads();
static Vector<String> get_rendering_drivers_func();
@@ -136,6 +133,7 @@ public:
Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
Rect2i screen_get_usable_rect(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
int screen_get_dpi(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
+ float screen_get_scale(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
// windows
Vector<DisplayServer::WindowID> get_window_list() const override;
diff --git a/platform/javascript/dom_keys.inc b/platform/javascript/dom_keys.inc
index e3f2ce42b4..7902efafe0 100644
--- a/platform/javascript/dom_keys.inc
+++ b/platform/javascript/dom_keys.inc
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/javascript/emscripten_helpers.py b/platform/javascript/emscripten_helpers.py
index cc874c432e..d08555916b 100644
--- a/platform/javascript/emscripten_helpers.py
+++ b/platform/javascript/emscripten_helpers.py
@@ -15,6 +15,15 @@ def run_closure_compiler(target, source, env, for_signature):
return " ".join(cmd)
+def get_build_version(env):
+ import version
+
+ name = "custom_build"
+ if os.getenv("BUILD_NAME") != None:
+ name = os.getenv("BUILD_NAME")
+ return "%d.%d.%d.%s.%s" % (version.major, version.minor, version.patch, version.status, name)
+
+
def create_engine_file(env, target, source, externs):
if env["use_closure_compiler"]:
return env.BuildJS(target, source, JSEXTERNS=externs)
@@ -22,6 +31,12 @@ def create_engine_file(env, target, source, externs):
def add_js_libraries(env, libraries):
- if "JS_LIBS" not in env:
- env["JS_LIBS"] = []
env.Append(JS_LIBS=env.File(libraries))
+
+
+def add_js_pre(env, js_pre):
+ env.Append(JS_PRE=env.File(js_pre))
+
+
+def add_js_externs(env, externs):
+ env.Append(JS_EXTERNS=env.File(externs))
diff --git a/platform/javascript/export/export.cpp b/platform/javascript/export/export.cpp
index c3b7e0304e..353cc49ef8 100644
--- a/platform/javascript/export/export.cpp
+++ b/platform/javascript/export/export.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -37,16 +37,13 @@
#include "platform/javascript/logo.gen.h"
#include "platform/javascript/run_icon.gen.h"
-#define EXPORT_TEMPLATE_WEBASSEMBLY_RELEASE "webassembly_release.zip"
-#define EXPORT_TEMPLATE_WEBASSEMBLY_DEBUG "webassembly_debug.zip"
-
class EditorHTTPServer : public Reference {
private:
Ref<TCP_Server> server;
Ref<StreamPeerTCP> connection;
- uint64_t time;
+ uint64_t time = 0;
uint8_t req_buf[4096];
- int req_pos;
+ int req_pos = 0;
void _clear_client() {
connection = Ref<StreamPeerTCP>();
@@ -85,36 +82,44 @@ public:
// Wrong protocol
ERR_FAIL_COND_MSG(req[0] != "GET" || req[2] != "HTTP/1.1", "Invalid method or HTTP version.");
- String filepath = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmp_js_export");
+ const String cache_path = EditorSettings::get_singleton()->get_cache_dir();
const String basereq = "/tmp_js_export";
- String ctype = "";
+ String filepath;
+ String ctype;
if (req[1] == basereq + ".html") {
- filepath += ".html";
+ filepath = cache_path.plus_file(req[1].get_file());
ctype = "text/html";
} else if (req[1] == basereq + ".js") {
- filepath += ".js";
+ filepath = cache_path.plus_file(req[1].get_file());
ctype = "application/javascript";
} else if (req[1] == basereq + ".audio.worklet.js") {
- filepath += ".audio.worklet.js";
+ filepath = cache_path.plus_file(req[1].get_file());
ctype = "application/javascript";
} else if (req[1] == basereq + ".worker.js") {
- filepath += ".worker.js";
+ filepath = cache_path.plus_file(req[1].get_file());
ctype = "application/javascript";
} else if (req[1] == basereq + ".pck") {
- filepath += ".pck";
+ filepath = cache_path.plus_file(req[1].get_file());
ctype = "application/octet-stream";
} else if (req[1] == basereq + ".png" || req[1] == "/favicon.png") {
// Also allow serving the generated favicon for a smoother loading experience.
if (req[1] == "/favicon.png") {
filepath = EditorSettings::get_singleton()->get_cache_dir().plus_file("favicon.png");
} else {
- filepath += ".png";
+ filepath = basereq + ".png";
}
ctype = "image/png";
+ } else if (req[1] == basereq + ".side.wasm") {
+ filepath = cache_path.plus_file(req[1].get_file());
+ ctype = "application/wasm";
} else if (req[1] == basereq + ".wasm") {
- filepath += ".wasm";
+ filepath = cache_path.plus_file(req[1].get_file());
ctype = "application/wasm";
- } else {
+ } else if (req[1].ends_with(".wasm")) {
+ filepath = cache_path.plus_file(req[1].get_file()); // TODO dangerous?
+ ctype = "application/wasm";
+ }
+ if (filepath.is_empty() || !FileAccess::exists(filepath)) {
String s = "HTTP/1.1 404 Not Found\r\n";
s += "Connection: Close\r\n";
s += "\r\n";
@@ -130,6 +135,7 @@ public:
s += "Access-Control-Allow-Origin: *\r\n";
s += "Cross-Origin-Opener-Policy: same-origin\r\n";
s += "Cross-Origin-Embedder-Policy: require-corp\r\n";
+ s += "Cache-Control: no-store, max-age=0\r\n";
s += "\r\n";
CharString cs = s.utf8();
Error err = connection->put_data((const uint8_t *)cs.get_data(), cs.size() - 1);
@@ -203,15 +209,40 @@ class EditorExportPlatformJavaScript : public EditorExportPlatform {
Ref<ImageTexture> logo;
Ref<ImageTexture> run_icon;
Ref<ImageTexture> stop_icon;
- int menu_options;
-
- void _fix_html(Vector<uint8_t> &p_html, const Ref<EditorExportPreset> &p_preset, const String &p_name, bool p_debug, int p_flags);
+ int menu_options = 0;
-private:
Ref<EditorHTTPServer> server;
- bool server_quit;
+ bool server_quit = false;
Mutex server_lock;
- Thread *server_thread;
+ Thread server_thread;
+
+ enum ExportMode {
+ EXPORT_MODE_NORMAL = 0,
+ EXPORT_MODE_THREADS = 1,
+ EXPORT_MODE_GDNATIVE = 2,
+ };
+
+ String _get_template_name(ExportMode p_mode, bool p_debug) const {
+ String name = "webassembly";
+ switch (p_mode) {
+ case EXPORT_MODE_THREADS:
+ name += "_threads";
+ break;
+ case EXPORT_MODE_GDNATIVE:
+ name += "_gdnative";
+ break;
+ default:
+ break;
+ }
+ if (p_debug) {
+ name += "_debug.zip";
+ } else {
+ name += "_release.zip";
+ }
+ return name;
+ }
+
+ void _fix_html(Vector<uint8_t> &p_html, const Ref<EditorExportPreset> &p_preset, const String &p_name, bool p_debug, int p_flags, const Vector<SharedObject> p_shared_objects);
static void _server_thread_poll(void *data);
@@ -250,23 +281,33 @@ public:
~EditorExportPlatformJavaScript();
};
-void EditorExportPlatformJavaScript::_fix_html(Vector<uint8_t> &p_html, const Ref<EditorExportPreset> &p_preset, const String &p_name, bool p_debug, int p_flags) {
+void EditorExportPlatformJavaScript::_fix_html(Vector<uint8_t> &p_html, const Ref<EditorExportPreset> &p_preset, const String &p_name, bool p_debug, int p_flags, const Vector<SharedObject> p_shared_objects) {
String str_template = String::utf8(reinterpret_cast<const char *>(p_html.ptr()), p_html.size());
String str_export;
Vector<String> lines = str_template.split("\n");
+ Array libs;
+ for (int i = 0; i < p_shared_objects.size(); i++) {
+ libs.push_back(p_shared_objects[i].path.get_file());
+ }
Vector<String> flags;
- String flags_json;
- gen_export_flags(flags, p_flags);
- flags_json = JSON::print(flags);
+ gen_export_flags(flags, p_flags & (~DEBUG_FLAG_DUMB_CLIENT));
+ Array args;
+ for (int i = 0; i < flags.size(); i++) {
+ args.push_back(flags[i]);
+ }
+ Dictionary config;
+ config["canvasResizePolicy"] = p_preset->get("html/canvas_resize_policy");
+ config["gdnativeLibs"] = libs;
+ config["executable"] = p_name;
+ config["args"] = args;
+ const String str_config = JSON::print(config);
for (int i = 0; i < lines.size(); i++) {
String current_line = lines[i];
- current_line = current_line.replace("$GODOT_BASENAME", p_name);
+ current_line = current_line.replace("$GODOT_URL", p_name + ".js");
current_line = current_line.replace("$GODOT_PROJECT_NAME", ProjectSettings::get_singleton()->get_setting("application/config/name"));
current_line = current_line.replace("$GODOT_HEAD_INCLUDE", p_preset->get("html/head_include"));
- current_line = current_line.replace("$GODOT_FULL_WINDOW", p_preset->get("html/full_window_size") ? "true" : "false");
- current_line = current_line.replace("$GODOT_DEBUG_ENABLED", p_debug ? "true" : "false");
- current_line = current_line.replace("$GODOT_ARGS", flags_json);
+ current_line = current_line.replace("$GODOT_CONFIG", str_config);
str_export += current_line + "\n";
}
@@ -283,7 +324,7 @@ void EditorExportPlatformJavaScript::get_preset_features(const Ref<EditorExportP
}
if (p_preset->get("vram_texture_compression/for_mobile")) {
- String driver = ProjectSettings::get_singleton()->get("rendering/quality/driver/driver_name");
+ String driver = ProjectSettings::get_singleton()->get("rendering/driver/driver_name");
if (driver == "GLES2") {
r_features->push_back("etc");
} else if (driver == "Vulkan") {
@@ -291,18 +332,25 @@ void EditorExportPlatformJavaScript::get_preset_features(const Ref<EditorExportP
r_features->push_back("etc2");
}
}
+ ExportMode mode = (ExportMode)(int)p_preset->get("variant/export_type");
+ if (mode == EXPORT_MODE_THREADS) {
+ r_features->push_back("threads");
+ } else if (mode == EXPORT_MODE_GDNATIVE) {
+ r_features->push_back("wasm32");
+ }
}
void EditorExportPlatformJavaScript::get_export_options(List<ExportOption> *r_options) {
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "variant/export_type", PROPERTY_HINT_ENUM, "Regular,Threads,GDNative"), 0)); // Export type.
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "vram_texture_compression/for_desktop"), true)); // S3TC
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "vram_texture_compression/for_mobile"), false)); // ETC or ETC2, depending on renderer
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "html/custom_html_shell", PROPERTY_HINT_FILE, "*.html"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "html/head_include", PROPERTY_HINT_MULTILINE_TEXT), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "html/full_window_size"), true));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "html/canvas_resize_policy", PROPERTY_HINT_ENUM, "None,Project,Adaptive"), 2));
}
String EditorExportPlatformJavaScript::get_name() const {
@@ -320,11 +368,11 @@ Ref<Texture2D> EditorExportPlatformJavaScript::get_logo() const {
bool EditorExportPlatformJavaScript::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const {
String err;
bool valid = false;
+ ExportMode mode = (ExportMode)(int)p_preset->get("variant/export_type");
// Look for export templates (first official, and if defined custom templates).
-
- bool dvalid = exists_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_DEBUG, &err);
- bool rvalid = exists_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_RELEASE, &err);
+ bool dvalid = exists_export_template(_get_template_name(mode, true), &err);
+ bool rvalid = exists_export_template(_get_template_name(mode, false), &err);
if (p_preset->get("custom_template/debug") != "") {
dvalid = FileAccess::exists(p_preset->get("custom_template/debug"));
@@ -352,7 +400,7 @@ bool EditorExportPlatformJavaScript::can_export(const Ref<EditorExportPreset> &p
}
}
- if (!err.empty()) {
+ if (!err.is_empty()) {
r_error = err;
}
@@ -377,11 +425,8 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
template_path = template_path.strip_edges();
if (template_path == String()) {
- if (p_debug) {
- template_path = find_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_DEBUG);
- } else {
- template_path = find_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_RELEASE);
- }
+ ExportMode mode = (ExportMode)(int)p_preset->get("variant/export_type");
+ template_path = find_export_template(_get_template_name(mode, p_debug));
}
if (!DirAccess::exists(p_path.get_base_dir())) {
@@ -393,12 +438,24 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
return ERR_FILE_NOT_FOUND;
}
+ Vector<SharedObject> shared_objects;
String pck_path = p_path.get_basename() + ".pck";
- Error error = save_pack(p_preset, pck_path);
+ Error error = save_pack(p_preset, pck_path, &shared_objects);
if (error != OK) {
EditorNode::get_singleton()->show_warning(TTR("Could not write file:") + "\n" + pck_path);
return error;
}
+ DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
+ for (int i = 0; i < shared_objects.size(); i++) {
+ String dst = p_path.get_base_dir().plus_file(shared_objects[i].path.get_file());
+ error = da->copy(shared_objects[i].path, dst);
+ if (error != OK) {
+ EditorNode::get_singleton()->show_warning(TTR("Could not write file:") + "\n" + shared_objects[i].path.get_file());
+ memdelete(da);
+ return error;
+ }
+ }
+ memdelete(da);
FileAccess *src_f = nullptr;
zlib_filefunc_def io = zipio_create_io_from_file(&src_f);
@@ -434,17 +491,21 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
//write
if (file == "godot.html") {
- if (!custom_html.empty()) {
+ if (!custom_html.is_empty()) {
continue;
}
- _fix_html(data, p_preset, p_path.get_file().get_basename(), p_debug, p_flags);
+ _fix_html(data, p_preset, p_path.get_file().get_basename(), p_debug, p_flags, shared_objects);
file = p_path.get_file();
} else if (file == "godot.js") {
file = p_path.get_file().get_basename() + ".js";
+
} else if (file == "godot.worker.js") {
file = p_path.get_file().get_basename() + ".worker.js";
+ } else if (file == "godot.side.wasm") {
+ file = p_path.get_file().get_basename() + ".side.wasm";
+
} else if (file == "godot.audio.worklet.js") {
file = p_path.get_file().get_basename() + ".audio.worklet.js";
@@ -465,7 +526,7 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
} while (unzGoToNextFile(pkg) == UNZ_OK);
unzClose(pkg);
- if (!custom_html.empty()) {
+ if (!custom_html.is_empty()) {
FileAccess *f = FileAccess::open(custom_html, FileAccess::READ);
if (!f) {
EditorNode::get_singleton()->show_warning(TTR("Could not read custom HTML shell:") + "\n" + custom_html);
@@ -475,7 +536,7 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
buf.resize(f->get_len());
f->get_buffer(buf.ptrw(), buf.size());
memdelete(f);
- _fix_html(buf, p_preset, p_path.get_file().get_basename(), p_debug, p_flags);
+ _fix_html(buf, p_preset, p_path.get_file().get_basename(), p_debug, p_flags, shared_objects);
f = FileAccess::open(p_path, FileAccess::WRITE);
if (!f) {
@@ -488,7 +549,7 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
Ref<Image> splash;
const String splash_path = String(GLOBAL_GET("application/boot_splash/image")).strip_edges();
- if (!splash_path.empty()) {
+ if (!splash_path.is_empty()) {
splash.instance();
const Error err = splash->load(splash_path);
if (err) {
@@ -509,7 +570,7 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
// This way, the favicon can be displayed immediately when loading the page.
Ref<Image> favicon;
const String favicon_path = String(GLOBAL_GET("application/config/icon")).strip_edges();
- if (!favicon_path.empty()) {
+ if (!favicon_path.is_empty()) {
favicon.instance();
const Error err = favicon->load(favicon_path);
if (err) {
@@ -577,6 +638,7 @@ Error EditorExportPlatformJavaScript::run(const Ref<EditorExportPreset> &p_prese
DirAccess::remove_file_or_error(basepath + ".audio.worklet.js");
DirAccess::remove_file_or_error(basepath + ".pck");
DirAccess::remove_file_or_error(basepath + ".png");
+ DirAccess::remove_file_or_error(basepath + ".side.wasm");
DirAccess::remove_file_or_error(basepath + ".wasm");
DirAccess::remove_file_or_error(EditorSettings::get_singleton()->get_cache_dir().plus_file("favicon.png"));
return err;
@@ -625,8 +687,7 @@ void EditorExportPlatformJavaScript::_server_thread_poll(void *data) {
EditorExportPlatformJavaScript::EditorExportPlatformJavaScript() {
server.instance();
- server_quit = false;
- server_thread = Thread::create(_server_thread_poll, this);
+ server_thread.start(_server_thread_poll, this);
Ref<Image> img = memnew(Image(_javascript_logo));
logo.instance();
@@ -642,15 +703,12 @@ EditorExportPlatformJavaScript::EditorExportPlatformJavaScript() {
} else {
stop_icon.instance();
}
-
- menu_options = 0;
}
EditorExportPlatformJavaScript::~EditorExportPlatformJavaScript() {
server->stop();
server_quit = true;
- Thread::wait_to_finish(server_thread);
- memdelete(server_thread);
+ server_thread.wait_to_finish();
}
void register_javascript_exporter() {
diff --git a/platform/javascript/export/export.h b/platform/javascript/export/export.h
index 30c5c855d1..e641339f55 100644
--- a/platform/javascript/export/export.h
+++ b/platform/javascript/export/export.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/javascript/godot_audio.h b/platform/javascript/godot_audio.h
index 7ebda3ad39..54fc8fa3b5 100644
--- a/platform/javascript/godot_audio.h
+++ b/platform/javascript/godot_audio.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -41,14 +41,14 @@ extern int godot_audio_is_available();
extern int godot_audio_init(int p_mix_rate, int p_latency, void (*_state_cb)(int), void (*_latency_cb)(float));
extern void godot_audio_resume();
-extern void godot_audio_capture_start();
+extern int godot_audio_capture_start();
extern void godot_audio_capture_stop();
// Worklet
typedef int32_t GodotAudioState[4];
extern void godot_audio_worklet_create(int p_channels);
extern void godot_audio_worklet_start(float *p_in_buf, int p_in_size, float *p_out_buf, int p_out_size, GodotAudioState p_state);
-extern void godot_audio_worklet_state_add(GodotAudioState p_state, int p_idx, int p_value);
+extern int godot_audio_worklet_state_add(GodotAudioState p_state, int p_idx, int p_value);
extern int godot_audio_worklet_state_get(GodotAudioState p_state, int p_idx);
extern int godot_audio_worklet_state_wait(int32_t *p_state, int p_idx, int32_t p_expected, int p_timeout);
diff --git a/platform/javascript/godot_js.h b/platform/javascript/godot_js.h
index 23596a0897..5aa8677a54 100644
--- a/platform/javascript/godot_js.h
+++ b/platform/javascript/godot_js.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -40,7 +40,6 @@ extern "C" {
// Config
extern void godot_js_config_locale_get(char *p_ptr, int p_ptr_max);
extern void godot_js_config_canvas_id_get(char *p_ptr, int p_ptr_max);
-extern int godot_js_config_is_resize_on_start();
// OS
extern void godot_js_os_finish_async(void (*p_callback)());
@@ -49,8 +48,10 @@ extern int godot_js_os_fs_is_persistent();
extern void godot_js_os_fs_sync(void (*p_callback)());
extern int godot_js_os_execute(const char *p_json);
extern void godot_js_os_shell_open(const char *p_uri);
+extern int godot_js_os_hw_concurrency_get();
// Display
+extern int godot_js_display_screen_dpi_get();
extern double godot_js_display_pixel_ratio_get();
extern void godot_js_display_alert(const char *p_text);
extern int godot_js_display_touchscreen_is_available();
@@ -59,10 +60,15 @@ extern int godot_js_display_is_swap_ok_cancel();
// Display canvas
extern void godot_js_display_canvas_focus();
extern int godot_js_display_canvas_is_focused();
-extern void godot_js_display_canvas_bounding_rect_position_get(int32_t *p_x, int32_t *p_y);
// Display window
-extern void godot_js_display_window_request_fullscreen();
+extern void godot_js_display_desired_size_set(int p_width, int p_height);
+extern int godot_js_display_size_update();
+extern void godot_js_display_window_size_get(int32_t *p_x, int32_t *p_y);
+extern void godot_js_display_screen_size_get(int32_t *p_x, int32_t *p_y);
+extern int godot_js_display_fullscreen_request();
+extern int godot_js_display_fullscreen_exit();
+extern void godot_js_display_compute_position(int p_x, int p_y, int32_t *r_x, int32_t *r_y);
extern void godot_js_display_window_title_set(const char *p_text);
extern void godot_js_display_window_icon_set(const uint8_t *p_ptr, int p_len);
@@ -76,10 +82,17 @@ extern int godot_js_display_cursor_is_hidden();
extern void godot_js_display_cursor_set_custom_shape(const char *p_shape, const uint8_t *p_ptr, int p_len, int p_hotspot_x, int p_hotspot_y);
extern void godot_js_display_cursor_set_visible(int p_visible);
+// Display gamepad
+extern char *godot_js_display_gamepad_cb(void (*p_on_change)(int p_index, int p_connected, const char *p_id, const char *p_guid));
+extern int godot_js_display_gamepad_sample();
+extern int godot_js_display_gamepad_sample_count();
+extern int godot_js_display_gamepad_sample_get(int p_idx, float r_btns[16], int32_t *r_btns_num, float r_axes[10], int32_t *r_axes_num, int32_t *r_standard);
+
// Display listeners
extern void godot_js_display_notification_cb(void (*p_callback)(int p_notification), int p_enter, int p_exit, int p_in, int p_out);
extern void godot_js_display_paste_cb(void (*p_callback)(const char *p_text));
extern void godot_js_display_drop_files_cb(void (*p_callback)(char **p_filev, int p_filec));
+extern void godot_js_display_setup_canvas(int p_width, int p_height, int p_fullscreen);
#ifdef __cplusplus
}
#endif
diff --git a/platform/javascript/http_client.h.inc b/platform/javascript/http_client.h.inc
index 4d5ff88bdd..2ef1ad5b83 100644
--- a/platform/javascript/http_client.h.inc
+++ b/platform/javascript/http_client.h.inc
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/javascript/http_client_javascript.cpp b/platform/javascript/http_client_javascript.cpp
index cb0e48b8a9..1136ea299d 100644
--- a/platform/javascript/http_client_javascript.cpp
+++ b/platform/javascript/http_client_javascript.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -78,15 +78,15 @@ Error HTTPClient::prepare_request(Method p_method, const String &p_url, const Ve
ERR_FAIL_INDEX_V(p_method, METHOD_MAX, ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V_MSG(p_method == METHOD_TRACE || p_method == METHOD_CONNECT, ERR_UNAVAILABLE, "HTTP methods TRACE and CONNECT are not supported for the HTML5 platform.");
ERR_FAIL_COND_V(status != STATUS_CONNECTED, ERR_INVALID_PARAMETER);
- ERR_FAIL_COND_V(host.empty(), ERR_UNCONFIGURED);
+ ERR_FAIL_COND_V(host.is_empty(), ERR_UNCONFIGURED);
ERR_FAIL_COND_V(port < 0, ERR_UNCONFIGURED);
ERR_FAIL_COND_V(!p_url.begins_with("/"), ERR_INVALID_PARAMETER);
String url = (use_tls ? "https://" : "http://") + host + ":" + itos(port) + p_url;
godot_xhr_reset(xhr_id);
godot_xhr_open(xhr_id, _methods[p_method], url.utf8().get_data(),
- username.empty() ? nullptr : username.utf8().get_data(),
- password.empty() ? nullptr : password.utf8().get_data());
+ username.is_empty() ? nullptr : username.utf8().get_data(),
+ password.is_empty() ? nullptr : password.utf8().get_data());
for (int i = 0; i < p_headers.size(); i++) {
int header_separator = p_headers[i].find(": ");
@@ -104,7 +104,11 @@ Error HTTPClient::request_raw(Method p_method, const String &p_url, const Vector
Error err = prepare_request(p_method, p_url, p_headers);
if (err != OK)
return err;
- godot_xhr_send_data(xhr_id, p_body.ptr(), p_body.size());
+ if (p_body.is_empty()) {
+ godot_xhr_send(xhr_id, nullptr, 0);
+ } else {
+ godot_xhr_send(xhr_id, p_body.ptr(), p_body.size());
+ }
return OK;
}
@@ -112,7 +116,12 @@ Error HTTPClient::request(Method p_method, const String &p_url, const Vector<Str
Error err = prepare_request(p_method, p_url, p_headers);
if (err != OK)
return err;
- godot_xhr_send_string(xhr_id, p_body.utf8().get_data());
+ if (p_body.is_empty()) {
+ godot_xhr_send(xhr_id, nullptr, 0);
+ } else {
+ const CharString cs = p_body.utf8();
+ godot_xhr_send(xhr_id, cs.get_data(), cs.length());
+ }
return OK;
}
@@ -132,7 +141,7 @@ HTTPClient::Status HTTPClient::get_status() const {
}
bool HTTPClient::has_response() const {
- return !polled_response_header.empty();
+ return !polled_response_header.is_empty();
}
bool HTTPClient::is_response_chunked() const {
@@ -145,7 +154,7 @@ int HTTPClient::get_response_code() const {
}
Error HTTPClient::get_response_headers(List<String> *r_response) {
- if (polled_response_header.empty())
+ if (polled_response_header.is_empty())
return ERR_INVALID_PARAMETER;
Vector<String> header_lines = polled_response_header.split("\r\n", false);
@@ -220,13 +229,13 @@ Error HTTPClient::poll() {
has_polled = true;
} else {
// forcing synchronous requests is not possible on the web
- if (last_polling_frame == Engine::get_singleton()->get_idle_frames()) {
+ if (last_polling_frame == Engine::get_singleton()->get_process_frames()) {
WARN_PRINT("HTTPClient polled multiple times in one frame, "
"but request cannot progress more than once per "
"frame on the HTML5 platform.");
}
}
- last_polling_frame = Engine::get_singleton()->get_idle_frames();
+ last_polling_frame = Engine::get_singleton()->get_process_frames();
#endif
polled_response_code = godot_xhr_get_status(xhr_id);
diff --git a/platform/javascript/http_request.h b/platform/javascript/http_request.h
index 54e98c1927..a9d6faade2 100644
--- a/platform/javascript/http_request.h
+++ b/platform/javascript/http_request.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -47,15 +47,13 @@ typedef enum {
extern int godot_xhr_new();
extern void godot_xhr_reset(int p_xhr_id);
-extern bool godot_xhr_free(int p_xhr_id);
+extern void godot_xhr_free(int p_xhr_id);
extern int godot_xhr_open(int p_xhr_id, const char *p_method, const char *p_url, const char *p_user = nullptr, const char *p_password = nullptr);
extern void godot_xhr_set_request_header(int p_xhr_id, const char *p_header, const char *p_value);
-extern void godot_xhr_send_null(int p_xhr_id);
-extern void godot_xhr_send_string(int p_xhr_id, const char *p_data);
-extern void godot_xhr_send_data(int p_xhr_id, const void *p_data, int p_len);
+extern void godot_xhr_send(int p_xhr_id, const void *p_data, int p_len);
extern void godot_xhr_abort(int p_xhr_id);
/* this is an HTTPClient::ResponseCode, not ::Status */
diff --git a/platform/javascript/javascript_eval.cpp b/platform/javascript/javascript_eval.cpp
index b203253a39..cb19dd20d4 100644
--- a/platform/javascript/javascript_eval.cpp
+++ b/platform/javascript/javascript_eval.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/javascript/javascript_main.cpp b/platform/javascript/javascript_main.cpp
index 2d28a63566..0fe95b0a8f 100644
--- a/platform/javascript/javascript_main.cpp
+++ b/platform/javascript/javascript_main.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -75,7 +75,7 @@ void main_loop_callback() {
}
/// When calling main, it is assumed FS is setup and synced.
-int main(int argc, char *argv[]) {
+extern EMSCRIPTEN_KEEPALIVE int godot_js_main(int argc, char *argv[]) {
os = new OS_JavaScript();
// We must override main when testing is enabled
@@ -87,7 +87,14 @@ int main(int argc, char *argv[]) {
ResourceLoader::set_abort_on_missing_resources(false);
Main::start();
- os->get_main_loop()->init();
+ os->get_main_loop()->initialize();
+#ifdef TOOLS_ENABLED
+ if (Main::is_project_manager() && FileAccess::exists("/tmp/preload.zip")) {
+ PackedStringArray ps;
+ ps.push_back("/tmp/preload.zip");
+ os->get_main_loop()->emit_signal("files_dropped", ps, -1);
+ }
+#endif
emscripten_set_main_loop(main_loop_callback, -1, false);
// Immediately run the first iteration.
// We are inside an animation frame, we want to immediately draw on the newly setup canvas.
diff --git a/platform/uwp/thread_uwp.h b/platform/javascript/javascript_runtime.cpp
index 9b2a2590a8..2996e95a95 100644
--- a/platform/uwp/thread_uwp.h
+++ b/platform/javascript/javascript_runtime.cpp
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* thread_uwp.h */
+/* javascript_runtime.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -28,32 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef THREAD_UWP_H
-#define THREAD_UWP_H
+extern int godot_js_main(int argc, char *argv[]);
-#ifdef UWP_ENABLED
-
-#include "core/os/thread.h"
-
-#include <thread>
-
-class ThreadUWP : public Thread {
- std::thread thread;
-
- static Thread *create_func_uwp(ThreadCreateCallback p_callback, void *, const Settings &);
- static ID get_thread_id_func_uwp();
- static void wait_to_finish_func_uwp(Thread *p_thread);
-
- ThreadUWP() {}
-
-public:
- virtual ID get_id() const;
-
- static void make_default();
-
- ~ThreadUWP() {}
-};
-
-#endif // UWP_ENABLED
-
-#endif // THREAD_UWP_H
+int main(int argc, char *argv[]) {
+ return godot_js_main(argc, argv);
+}
diff --git a/platform/javascript/js/engine/config.js b/platform/javascript/js/engine/config.js
new file mode 100644
index 0000000000..97fd718815
--- /dev/null
+++ b/platform/javascript/js/engine/config.js
@@ -0,0 +1,100 @@
+/** @constructor */
+function EngineConfig(opts) {
+ // Module config
+ this.unloadAfterInit = true;
+ this.onPrintError = function () {
+ console.error.apply(console, Array.from(arguments)); // eslint-disable-line no-console
+ };
+ this.onPrint = function () {
+ console.log.apply(console, Array.from(arguments)); // eslint-disable-line no-console
+ };
+ this.onProgress = null;
+
+ // Godot Config
+ this.canvas = null;
+ this.executable = '';
+ this.mainPack = null;
+ this.locale = null;
+ this.canvasResizePolicy = false;
+ this.persistentPaths = ['/userfs'];
+ this.gdnativeLibs = [];
+ this.args = [];
+ this.onExecute = null;
+ this.onExit = null;
+ this.update(opts);
+}
+
+EngineConfig.prototype.update = function (opts) {
+ const config = opts || {};
+ function parse(key, def) {
+ if (typeof (config[key]) === 'undefined') {
+ return def;
+ }
+ return config[key];
+ }
+ // Module config
+ this.unloadAfterInit = parse('unloadAfterInit', this.unloadAfterInit);
+ this.onPrintError = parse('onPrintError', this.onPrintError);
+ this.onPrint = parse('onPrint', this.onPrint);
+ this.onProgress = parse('onProgress', this.onProgress);
+
+ // Godot config
+ this.canvas = parse('canvas', this.canvas);
+ this.executable = parse('executable', this.executable);
+ this.mainPack = parse('mainPack', this.mainPack);
+ this.locale = parse('locale', this.locale);
+ this.canvasResizePolicy = parse('canvasResizePolicy', this.canvasResizePolicy);
+ this.persistentPaths = parse('persistentPaths', this.persistentPaths);
+ this.gdnativeLibs = parse('gdnativeLibs', this.gdnativeLibs);
+ this.args = parse('args', this.args);
+ this.onExecute = parse('onExecute', this.onExecute);
+ this.onExit = parse('onExit', this.onExit);
+};
+
+EngineConfig.prototype.getModuleConfig = function (loadPath, loadPromise) {
+ const me = this;
+ return {
+ 'print': this.onPrint,
+ 'printErr': this.onPrintError,
+ 'locateFile': Utils.createLocateRewrite(loadPath),
+ 'instantiateWasm': Utils.createInstantiatePromise(loadPromise),
+ 'thisProgram': me.executable,
+ 'noExitRuntime': true,
+ 'dynamicLibraries': [`${me.executable}.side.wasm`],
+ };
+};
+
+EngineConfig.prototype.getGodotConfig = function (cleanup) {
+ if (!(this.canvas instanceof HTMLCanvasElement)) {
+ this.canvas = Utils.findCanvas();
+ if (!this.canvas) {
+ throw new Error('No canvas found in page');
+ }
+ }
+
+ // Canvas can grab focus on click, or key events won't work.
+ if (this.canvas.tabIndex < 0) {
+ this.canvas.tabIndex = 0;
+ }
+
+ // Browser locale, or custom one if defined.
+ let locale = this.locale;
+ if (!locale) {
+ locale = navigator.languages ? navigator.languages[0] : navigator.language;
+ locale = locale.split('.')[0];
+ }
+ const onExit = this.onExit;
+ // Godot configuration.
+ return {
+ 'canvas': this.canvas,
+ 'canvasResizePolicy': this.canvasResizePolicy,
+ 'locale': locale,
+ 'onExecute': this.onExecute,
+ 'onExit': function (p_code) {
+ cleanup(); // We always need to call the cleanup callback to free memory.
+ if (typeof (onExit) === 'function') {
+ onExit(p_code);
+ }
+ },
+ };
+};
diff --git a/platform/javascript/js/engine/engine.js b/platform/javascript/js/engine/engine.js
index 74153b672a..d14e0e5806 100644
--- a/platform/javascript/js/engine/engine.js
+++ b/platform/javascript/js/engine/engine.js
@@ -1,20 +1,14 @@
const Engine = (function () {
const preloader = new Preloader();
- let wasmExt = '.wasm';
- let unloadAfterInit = true;
- let loadPath = '';
let loadPromise = null;
+ let loadPath = '';
let initPromise = null;
- let stderr = null;
- let stdout = null;
- let progressFunc = null;
function load(basePath) {
if (loadPromise == null) {
loadPath = basePath;
- loadPromise = preloader.loadPromise(basePath + wasmExt);
- preloader.setProgressFunc(progressFunc);
+ loadPromise = preloader.loadPromise(`${loadPath}.wasm`);
requestAnimationFrame(preloader.animateProgress);
}
return loadPromise;
@@ -25,15 +19,9 @@ const Engine = (function () {
}
/** @constructor */
- function Engine() { // eslint-disable-line no-shadow
- this.canvas = null;
- this.executableName = '';
+ function Engine(opts) { // eslint-disable-line no-shadow
+ this.config = new EngineConfig(opts);
this.rtenv = null;
- this.customLocale = null;
- this.resizeCanvasOnStart = false;
- this.onExecute = null;
- this.onExit = null;
- this.persistentPaths = ['/userfs'];
}
Engine.prototype.init = /** @param {string=} basePath */ function (basePath) {
@@ -47,21 +35,14 @@ const Engine = (function () {
}
load(basePath);
}
- let config = {};
- if (typeof stdout === 'function') {
- config.print = stdout;
- }
- if (typeof stderr === 'function') {
- config.printErr = stderr;
- }
+ preloader.setProgressFunc(this.config.onProgress);
+ let config = this.config.getModuleConfig(loadPath, loadPromise);
const me = this;
initPromise = new Promise(function (resolve, reject) {
- config['locateFile'] = Utils.createLocateRewrite(loadPath);
- config['instantiateWasm'] = Utils.createInstantiatePromise(loadPromise);
Godot(config).then(function (module) {
- module['initFS'](me.persistentPaths).then(function (fs_err) {
+ module['initFS'](me.config.persistentPaths).then(function (fs_err) {
me.rtenv = module;
- if (unloadAfterInit) {
+ if (me.config.unloadAfterInit) {
unload();
}
resolve();
@@ -78,166 +59,60 @@ const Engine = (function () {
};
/** @type {function(...string):Object} */
- Engine.prototype.start = function () {
- // Start from arguments.
- const args = [];
- for (let i = 0; i < arguments.length; i++) {
- args.push(arguments[i]);
- }
+ Engine.prototype.start = function (override) {
+ this.config.update(override);
const me = this;
return me.init().then(function () {
if (!me.rtenv) {
return Promise.reject(new Error('The engine must be initialized before it can be started'));
}
- if (!(me.canvas instanceof HTMLCanvasElement)) {
- me.canvas = Utils.findCanvas();
- if (!me.canvas) {
- return Promise.reject(new Error('No canvas found in page'));
- }
- }
-
- // Canvas can grab focus on click, or key events won't work.
- if (me.canvas.tabIndex < 0) {
- me.canvas.tabIndex = 0;
- }
-
- // Disable right-click context menu.
- me.canvas.addEventListener('contextmenu', function (ev) {
- ev.preventDefault();
- }, false);
-
- // Until context restoration is implemented warn the user of context loss.
- me.canvas.addEventListener('webglcontextlost', function (ev) {
- alert('WebGL context lost, please reload the page'); // eslint-disable-line no-alert
- ev.preventDefault();
- }, false);
-
- // Browser locale, or custom one if defined.
- let locale = me.customLocale;
- if (!locale) {
- locale = navigator.languages ? navigator.languages[0] : navigator.language;
- locale = locale.split('.')[0];
+ let config = {};
+ try {
+ config = me.config.getGodotConfig(function () {
+ me.rtenv = null;
+ });
+ } catch (e) {
+ return Promise.reject(e);
}
- // Emscripten configuration.
- me.rtenv['thisProgram'] = me.executableName;
- me.rtenv['noExitRuntime'] = true;
// Godot configuration.
- me.rtenv['initConfig']({
- 'resizeCanvasOnStart': me.resizeCanvasOnStart,
- 'canvas': me.canvas,
- 'locale': locale,
- 'onExecute': function (p_args) {
- if (me.onExecute) {
- me.onExecute(p_args);
- return 0;
- }
- return 1;
- },
- 'onExit': function (p_code) {
- me.rtenv['deinitFS']();
- if (me.onExit) {
- me.onExit(p_code);
- }
- me.rtenv = null;
- },
- });
+ me.rtenv['initConfig'](config);
- return new Promise(function (resolve, reject) {
- preloader.preloadedFiles.forEach(function (file) {
- me.rtenv['copyToFS'](file.path, file.buffer);
+ // Preload GDNative libraries.
+ const libs = [];
+ me.config.gdnativeLibs.forEach(function (lib) {
+ libs.push(me.rtenv['loadDynamicLibrary'](lib, { 'loadAsync': true }));
+ });
+ return Promise.all(libs).then(function () {
+ return new Promise(function (resolve, reject) {
+ preloader.preloadedFiles.forEach(function (file) {
+ me.rtenv['copyToFS'](file.path, file.buffer);
+ });
+ preloader.preloadedFiles.length = 0; // Clear memory
+ me.rtenv['callMain'](me.config.args);
+ initPromise = null;
+ resolve();
});
- preloader.preloadedFiles.length = 0; // Clear memory
- me.rtenv['callMain'](args);
- initPromise = null;
- resolve();
});
});
};
- Engine.prototype.startGame = function (execName, mainPack, extraArgs) {
+ Engine.prototype.startGame = function (override) {
+ this.config.update(override);
+ // Add main-pack argument.
+ const exe = this.config.executable;
+ const pack = this.config.mainPack || `${exe}.pck`;
+ this.config.args = ['--main-pack', pack].concat(this.config.args);
// Start and init with execName as loadPath if not inited.
- this.executableName = execName;
const me = this;
return Promise.all([
- this.init(execName),
- this.preloadFile(mainPack, mainPack),
+ this.init(exe),
+ this.preloadFile(pack, pack),
]).then(function () {
- let args = ['--main-pack', mainPack];
- if (extraArgs) {
- args = args.concat(extraArgs);
- }
- return me.start.apply(me, args);
+ return me.start.apply(me);
});
};
- Engine.prototype.setWebAssemblyFilenameExtension = function (override) {
- if (String(override).length === 0) {
- throw new Error('Invalid WebAssembly filename extension override');
- }
- wasmExt = String(override);
- };
-
- Engine.prototype.setUnloadAfterInit = function (enabled) {
- unloadAfterInit = enabled;
- };
-
- Engine.prototype.setCanvas = function (canvasElem) {
- this.canvas = canvasElem;
- };
-
- Engine.prototype.setCanvasResizedOnStart = function (enabled) {
- this.resizeCanvasOnStart = enabled;
- };
-
- Engine.prototype.setLocale = function (locale) {
- this.customLocale = locale;
- };
-
- Engine.prototype.setExecutableName = function (newName) {
- this.executableName = newName;
- };
-
- Engine.prototype.setProgressFunc = function (func) {
- progressFunc = func;
- };
-
- Engine.prototype.setStdoutFunc = function (func) {
- const print = function (text) {
- let msg = text;
- if (arguments.length > 1) {
- msg = Array.prototype.slice.call(arguments).join(' ');
- }
- func(msg);
- };
- if (this.rtenv) {
- this.rtenv.print = print;
- }
- stdout = print;
- };
-
- Engine.prototype.setStderrFunc = function (func) {
- const printErr = function (text) {
- let msg = text;
- if (arguments.length > 1) {
- msg = Array.prototype.slice.call(arguments).join(' ');
- }
- func(msg);
- };
- if (this.rtenv) {
- this.rtenv.printErr = printErr;
- }
- stderr = printErr;
- };
-
- Engine.prototype.setOnExecute = function (onExecute) {
- this.onExecute = onExecute;
- };
-
- Engine.prototype.setOnExit = function (onExit) {
- this.onExit = onExit;
- };
-
Engine.prototype.copyToFS = function (path, buffer) {
if (this.rtenv == null) {
throw new Error('Engine must be inited before copying files');
@@ -245,10 +120,6 @@ const Engine = (function () {
this.rtenv['copyToFS'](path, buffer);
};
- Engine.prototype.setPersistentPaths = function (persistentPaths) {
- this.persistentPaths = persistentPaths;
- };
-
Engine.prototype.requestQuit = function () {
if (this.rtenv) {
this.rtenv['request_quit']();
@@ -264,19 +135,7 @@ const Engine = (function () {
Engine.prototype['preloadFile'] = Engine.prototype.preloadFile;
Engine.prototype['start'] = Engine.prototype.start;
Engine.prototype['startGame'] = Engine.prototype.startGame;
- Engine.prototype['setWebAssemblyFilenameExtension'] = Engine.prototype.setWebAssemblyFilenameExtension;
- Engine.prototype['setUnloadAfterInit'] = Engine.prototype.setUnloadAfterInit;
- Engine.prototype['setCanvas'] = Engine.prototype.setCanvas;
- Engine.prototype['setCanvasResizedOnStart'] = Engine.prototype.setCanvasResizedOnStart;
- Engine.prototype['setLocale'] = Engine.prototype.setLocale;
- Engine.prototype['setExecutableName'] = Engine.prototype.setExecutableName;
- Engine.prototype['setProgressFunc'] = Engine.prototype.setProgressFunc;
- Engine.prototype['setStdoutFunc'] = Engine.prototype.setStdoutFunc;
- Engine.prototype['setStderrFunc'] = Engine.prototype.setStderrFunc;
- Engine.prototype['setOnExecute'] = Engine.prototype.setOnExecute;
- Engine.prototype['setOnExit'] = Engine.prototype.setOnExit;
Engine.prototype['copyToFS'] = Engine.prototype.copyToFS;
- Engine.prototype['setPersistentPaths'] = Engine.prototype.setPersistentPaths;
Engine.prototype['requestQuit'] = Engine.prototype.requestQuit;
return Engine;
}());
diff --git a/platform/javascript/js/engine/utils.js b/platform/javascript/js/engine/utils.js
index d0fca4e1cb..9273bbad42 100644
--- a/platform/javascript/js/engine/utils.js
+++ b/platform/javascript/js/engine/utils.js
@@ -8,6 +8,8 @@ const Utils = { // eslint-disable-line no-unused-vars
return `${execName}.audio.worklet.js`;
} else if (path.endsWith('.js')) {
return `${execName}.js`;
+ } else if (path.endsWith('.side.wasm')) {
+ return `${execName}.side.wasm`;
} else if (path.endsWith('.wasm')) {
return `${execName}.wasm`;
}
diff --git a/platform/javascript/js/libs/audio.worklet.js b/platform/javascript/js/libs/audio.worklet.js
index 414dc37097..6b3f80c6a9 100644
--- a/platform/javascript/js/libs/audio.worklet.js
+++ b/platform/javascript/js/libs/audio.worklet.js
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/javascript/js/libs/library_godot_audio.js b/platform/javascript/js/libs/library_godot_audio.js
index 0c1f477f34..8e385e9176 100644
--- a/platform/javascript/js/libs/library_godot_audio.js
+++ b/platform/javascript/js/libs/library_godot_audio.js
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -77,28 +77,37 @@ const GodotAudio = {
create_input: function (callback) {
if (GodotAudio.input) {
- return; // Already started.
+ return 0; // Already started.
}
function gotMediaInput(stream) {
- GodotAudio.input = GodotAudio.ctx.createMediaStreamSource(stream);
- callback(GodotAudio.input);
+ try {
+ GodotAudio.input = GodotAudio.ctx.createMediaStreamSource(stream);
+ callback(GodotAudio.input);
+ } catch (e) {
+ GodotRuntime.error('Failed creaating input.', e);
+ }
}
- if (navigator.mediaDevices.getUserMedia) {
+ if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
navigator.mediaDevices.getUserMedia({
'audio': true,
}).then(gotMediaInput, function (e) {
- GodotRuntime.print(e);
+ GodotRuntime.error('Error getting user media.', e);
});
} else {
if (!navigator.getUserMedia) {
navigator.getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
}
+ if (!navigator.getUserMedia) {
+ GodotRuntime.error('getUserMedia not available.');
+ return 1;
+ }
navigator.getUserMedia({
'audio': true,
}, gotMediaInput, function (e) {
GodotRuntime.print(e);
});
}
+ return 0;
},
close_async: function (resolve, reject) {
@@ -137,6 +146,7 @@ const GodotAudio = {
},
},
+ godot_audio_is_available__sig: 'i',
godot_audio_is_available__proxy: 'sync',
godot_audio_is_available: function () {
if (!(window.AudioContext || window.webkitAudioContext)) {
@@ -145,12 +155,14 @@ const GodotAudio = {
return 1;
},
+ godot_audio_init__sig: 'iiiii',
godot_audio_init: function (p_mix_rate, p_latency, p_state_change, p_latency_update) {
const statechange = GodotRuntime.get_func(p_state_change);
const latencyupdate = GodotRuntime.get_func(p_latency_update);
return GodotAudio.init(p_mix_rate, p_latency, statechange, latencyupdate);
},
+ godot_audio_resume__sig: 'v',
godot_audio_resume: function () {
if (GodotAudio.ctx && GodotAudio.ctx.state !== 'running') {
GodotAudio.ctx.resume();
@@ -158,16 +170,15 @@ const GodotAudio = {
},
godot_audio_capture_start__proxy: 'sync',
+ godot_audio_capture_start__sig: 'i',
godot_audio_capture_start: function () {
- if (GodotAudio.input) {
- return; // Already started.
- }
- GodotAudio.create_input(function (input) {
+ return GodotAudio.create_input(function (input) {
input.connect(GodotAudio.driver.get_node());
});
},
godot_audio_capture_stop__proxy: 'sync',
+ godot_audio_capture_stop__sig: 'v',
godot_audio_capture_stop: function () {
if (GodotAudio.input) {
const tracks = GodotAudio.input['mediaStream']['getTracks']();
@@ -241,10 +252,12 @@ const GodotAudioWorklet = {
},
},
+ godot_audio_worklet_create__sig: 'vi',
godot_audio_worklet_create: function (channels) {
GodotAudioWorklet.create(channels);
},
+ godot_audio_worklet_start__sig: 'viiiii',
godot_audio_worklet_start: function (p_in_buf, p_in_size, p_out_buf, p_out_size, p_state) {
const out_buffer = GodotRuntime.heapSub(HEAPF32, p_out_buf, p_out_size);
const in_buffer = GodotRuntime.heapSub(HEAPF32, p_in_buf, p_in_size);
@@ -252,15 +265,18 @@ const GodotAudioWorklet = {
GodotAudioWorklet.start(in_buffer, out_buffer, state);
},
+ godot_audio_worklet_state_wait__sig: 'iiii',
godot_audio_worklet_state_wait: function (p_state, p_idx, p_expected, p_timeout) {
Atomics.wait(HEAP32, (p_state >> 2) + p_idx, p_expected, p_timeout);
return Atomics.load(HEAP32, (p_state >> 2) + p_idx);
},
+ godot_audio_worklet_state_add__sig: 'iiii',
godot_audio_worklet_state_add: function (p_state, p_idx, p_value) {
return Atomics.add(HEAP32, (p_state >> 2) + p_idx, p_value);
},
+ godot_audio_worklet_state_get__sig: 'iii',
godot_audio_worklet_state_get: function (p_state, p_idx) {
return Atomics.load(HEAP32, (p_state >> 2) + p_idx);
},
@@ -330,10 +346,12 @@ const GodotAudioScript = {
},
},
+ godot_audio_script_create__sig: 'iii',
godot_audio_script_create: function (buffer_length, channel_count) {
return GodotAudioScript.create(buffer_length, channel_count);
},
+ godot_audio_script_start__sig: 'viiiii',
godot_audio_script_start: function (p_in_buf, p_in_size, p_out_buf, p_out_size, p_cb) {
const onprocess = GodotRuntime.get_func(p_cb);
GodotAudioScript.start(p_in_buf, p_in_size, p_out_buf, p_out_size, onprocess);
diff --git a/platform/javascript/js/libs/library_godot_display.js b/platform/javascript/js/libs/library_godot_display.js
index 9651b48952..fdb5cc0ec2 100644
--- a/platform/javascript/js/libs/library_godot_display.js
+++ b/platform/javascript/js/libs/library_godot_display.js
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -269,17 +269,271 @@ const GodotDisplayCursor = {
};
mergeInto(LibraryManager.library, GodotDisplayCursor);
+/*
+ * Display Gamepad API helper.
+ */
+const GodotDisplayGamepads = {
+ $GodotDisplayGamepads__deps: ['$GodotRuntime', '$GodotDisplayListeners'],
+ $GodotDisplayGamepads: {
+ samples: [],
+
+ get_pads: function () {
+ try {
+ // Will throw in iframe when permission is denied.
+ // Will throw/warn in the future for insecure contexts.
+ // See https://github.com/w3c/gamepad/pull/120
+ const pads = navigator.getGamepads();
+ if (pads) {
+ return pads;
+ }
+ return [];
+ } catch (e) {
+ return [];
+ }
+ },
+
+ get_samples: function () {
+ return GodotDisplayGamepads.samples;
+ },
+
+ get_sample: function (index) {
+ const samples = GodotDisplayGamepads.samples;
+ return index < samples.length ? samples[index] : null;
+ },
+
+ sample: function () {
+ const pads = GodotDisplayGamepads.get_pads();
+ const samples = [];
+ for (let i = 0; i < pads.length; i++) {
+ const pad = pads[i];
+ if (!pad) {
+ samples.push(null);
+ continue;
+ }
+ const s = {
+ standard: pad.mapping === 'standard',
+ buttons: [],
+ axes: [],
+ connected: pad.connected,
+ };
+ for (let b = 0; b < pad.buttons.length; b++) {
+ s.buttons.push(pad.buttons[b].value);
+ }
+ for (let a = 0; a < pad.axes.length; a++) {
+ s.axes.push(pad.axes[a]);
+ }
+ samples.push(s);
+ }
+ GodotDisplayGamepads.samples = samples;
+ },
+
+ init: function (onchange) {
+ GodotDisplayListeners.samples = [];
+ function add(pad) {
+ const guid = GodotDisplayGamepads.get_guid(pad);
+ const c_id = GodotRuntime.allocString(pad.id);
+ const c_guid = GodotRuntime.allocString(guid);
+ onchange(pad.index, 1, c_id, c_guid);
+ GodotRuntime.free(c_id);
+ GodotRuntime.free(c_guid);
+ }
+ const pads = GodotDisplayGamepads.get_pads();
+ for (let i = 0; i < pads.length; i++) {
+ // Might be reserved space.
+ if (pads[i]) {
+ add(pads[i]);
+ }
+ }
+ GodotDisplayListeners.add(window, 'gamepadconnected', function (evt) {
+ add(evt.gamepad);
+ }, false);
+ GodotDisplayListeners.add(window, 'gamepaddisconnected', function (evt) {
+ onchange(evt.gamepad.index, 0);
+ }, false);
+ },
+
+ get_guid: function (pad) {
+ if (pad.mapping) {
+ return pad.mapping;
+ }
+ const ua = navigator.userAgent;
+ let os = 'Unknown';
+ if (ua.indexOf('Android') >= 0) {
+ os = 'Android';
+ } else if (ua.indexOf('Linux') >= 0) {
+ os = 'Linux';
+ } else if (ua.indexOf('iPhone') >= 0) {
+ os = 'iOS';
+ } else if (ua.indexOf('Macintosh') >= 0) {
+ // Updated iPads will fall into this category.
+ os = 'MacOSX';
+ } else if (ua.indexOf('Windows') >= 0) {
+ os = 'Windows';
+ }
+
+ const id = pad.id;
+ // Chrom* style: NAME (Vendor: xxxx Product: xxxx)
+ const exp1 = /vendor: ([0-9a-f]{4}) product: ([0-9a-f]{4})/i;
+ // Firefox/Safari style (safari may remove leading zeores)
+ const exp2 = /^([0-9a-f]+)-([0-9a-f]+)-/i;
+ let vendor = '';
+ let product = '';
+ if (exp1.test(id)) {
+ const match = exp1.exec(id);
+ vendor = match[1].padStart(4, '0');
+ product = match[2].padStart(4, '0');
+ } else if (exp2.test(id)) {
+ const match = exp2.exec(id);
+ vendor = match[1].padStart(4, '0');
+ product = match[2].padStart(4, '0');
+ }
+ if (!vendor || !product) {
+ return `${os}Unknown`;
+ }
+ return os + vendor + product;
+ },
+ },
+};
+mergeInto(LibraryManager.library, GodotDisplayGamepads);
+
+const GodotDisplayScreen = {
+ $GodotDisplayScreen__deps: ['$GodotConfig', '$GodotOS', '$GL', 'emscripten_webgl_get_current_context'],
+ $GodotDisplayScreen: {
+ desired_size: [0, 0],
+ isFullscreen: function () {
+ const elem = document.fullscreenElement || document.mozFullscreenElement
+ || document.webkitFullscreenElement || document.msFullscreenElement;
+ if (elem) {
+ return elem === GodotConfig.canvas;
+ }
+ // But maybe knowing the element is not supported.
+ return document.fullscreen || document.mozFullScreen
+ || document.webkitIsFullscreen;
+ },
+ hasFullscreen: function () {
+ return document.fullscreenEnabled || document.mozFullScreenEnabled
+ || document.webkitFullscreenEnabled;
+ },
+ requestFullscreen: function () {
+ if (!GodotDisplayScreen.hasFullscreen()) {
+ return 1;
+ }
+ const canvas = GodotConfig.canvas;
+ try {
+ const promise = (canvas.requestFullscreen || canvas.msRequestFullscreen
+ || canvas.mozRequestFullScreen || canvas.mozRequestFullscreen
+ || canvas.webkitRequestFullscreen
+ ).call(canvas);
+ // Some browsers (Safari) return undefined.
+ // For the standard ones, we need to catch it.
+ if (promise) {
+ promise.catch(function () {
+ // nothing to do.
+ });
+ }
+ } catch (e) {
+ return 1;
+ }
+ return 0;
+ },
+ exitFullscreen: function () {
+ if (!GodotDisplayScreen.isFullscreen()) {
+ return 0;
+ }
+ try {
+ const promise = document.exitFullscreen();
+ if (promise) {
+ promise.catch(function () {
+ // nothing to do.
+ });
+ }
+ } catch (e) {
+ return 1;
+ }
+ return 0;
+ },
+ _updateGL: function () {
+ const gl_context_handle = _emscripten_webgl_get_current_context(); // eslint-disable-line no-undef
+ const gl = GL.getContext(gl_context_handle);
+ if (gl) {
+ GL.resizeOffscreenFramebuffer(gl);
+ }
+ },
+ updateSize: function () {
+ const isFullscreen = GodotDisplayScreen.isFullscreen();
+ const wantsFullWindow = GodotConfig.canvas_resize_policy === 2;
+ const noResize = GodotConfig.canvas_resize_policy === 0;
+ const wwidth = GodotDisplayScreen.desired_size[0];
+ const wheight = GodotDisplayScreen.desired_size[1];
+ const canvas = GodotConfig.canvas;
+ let width = wwidth;
+ let height = wheight;
+ if (noResize) {
+ // Don't resize canvas, just update GL if needed.
+ if (canvas.width !== width || canvas.height !== height) {
+ GodotDisplayScreen.desired_size = [canvas.width, canvas.height];
+ GodotDisplayScreen._updateGL();
+ return 1;
+ }
+ return 0;
+ }
+ const scale = window.devicePixelRatio || 1;
+ if (isFullscreen || wantsFullWindow) {
+ // We need to match screen size.
+ width = window.innerWidth * scale;
+ height = window.innerHeight * scale;
+ }
+ const csw = `${width / scale}px`;
+ const csh = `${height / scale}px`;
+ if (canvas.style.width !== csw || canvas.style.height !== csh || canvas.width !== width || canvas.height !== height) {
+ // Size doesn't match.
+ // Resize canvas, set correct CSS pixel size, update GL.
+ canvas.width = width;
+ canvas.height = height;
+ canvas.style.width = csw;
+ canvas.style.height = csh;
+ GodotDisplayScreen._updateGL();
+ return 1;
+ }
+ return 0;
+ },
+ },
+};
+mergeInto(LibraryManager.library, GodotDisplayScreen);
+
/**
* Display server interface.
*
* Exposes all the functions needed by DisplayServer implementation.
*/
const GodotDisplay = {
- $GodotDisplay__deps: ['$GodotConfig', '$GodotRuntime', '$GodotDisplayCursor', '$GodotDisplayListeners', '$GodotDisplayDragDrop'],
+ $GodotDisplay__deps: ['$GodotConfig', '$GodotRuntime', '$GodotDisplayCursor', '$GodotDisplayListeners', '$GodotDisplayDragDrop', '$GodotDisplayGamepads', '$GodotDisplayScreen'],
$GodotDisplay: {
window_icon: '',
+ findDPI: function () {
+ function testDPI(dpi) {
+ return window.matchMedia(`(max-resolution: ${dpi}dpi)`).matches;
+ }
+ function bisect(low, high, func) {
+ const mid = parseInt(((high - low) / 2) + low, 10);
+ if (high - low <= 1) {
+ return func(high) ? high : low;
+ }
+ if (func(mid)) {
+ return bisect(low, mid, func);
+ }
+ return bisect(mid, high, func);
+ }
+ try {
+ const dpi = bisect(0, 800, testDPI);
+ return dpi >= 96 ? dpi : 96;
+ } catch (e) {
+ return 96;
+ }
+ },
},
+ godot_js_display_is_swap_ok_cancel__sig: 'i',
godot_js_display_is_swap_ok_cancel: function () {
const win = (['Windows', 'Win64', 'Win32', 'WinCE']);
const plat = navigator.platform || '';
@@ -289,34 +543,80 @@ const GodotDisplay = {
return 0;
},
+ godot_js_display_alert__sig: 'vi',
godot_js_display_alert: function (p_text) {
window.alert(GodotRuntime.parseString(p_text)); // eslint-disable-line no-alert
},
+ godot_js_display_screen_dpi_get__sig: 'i',
+ godot_js_display_screen_dpi_get: function () {
+ return GodotDisplay.findDPI();
+ },
+
+ godot_js_display_pixel_ratio_get__sig: 'f',
godot_js_display_pixel_ratio_get: function () {
return window.devicePixelRatio || 1;
},
+ godot_js_display_fullscreen_request__sig: 'i',
+ godot_js_display_fullscreen_request: function () {
+ return GodotDisplayScreen.requestFullscreen();
+ },
+
+ godot_js_display_fullscreen_exit__sig: 'i',
+ godot_js_display_fullscreen_exit: function () {
+ return GodotDisplayScreen.exitFullscreen();
+ },
+
+ godot_js_display_desired_size_set__sig: 'v',
+ godot_js_display_desired_size_set: function (width, height) {
+ GodotDisplayScreen.desired_size = [width, height];
+ GodotDisplayScreen.updateSize();
+ },
+
+ godot_js_display_size_update__sig: 'i',
+ godot_js_display_size_update: function () {
+ return GodotDisplayScreen.updateSize();
+ },
+
+ godot_js_display_screen_size_get__sig: 'vii',
+ godot_js_display_screen_size_get: function (width, height) {
+ const scale = window.devicePixelRatio || 1;
+ GodotRuntime.setHeapValue(width, window.screen.width * scale, 'i32');
+ GodotRuntime.setHeapValue(height, window.screen.height * scale, 'i32');
+ },
+
+ godot_js_display_window_size_get: function (p_width, p_height) {
+ GodotRuntime.setHeapValue(p_width, GodotConfig.canvas.width, 'i32');
+ GodotRuntime.setHeapValue(p_height, GodotConfig.canvas.height, 'i32');
+ },
+
+ godot_js_display_compute_position: function (x, y, r_x, r_y) {
+ const canvas = GodotConfig.canvas;
+ const rect = canvas.getBoundingClientRect();
+ const rw = canvas.width / rect.width;
+ const rh = canvas.height / rect.height;
+ GodotRuntime.setHeapValue(r_x, (x - rect.x) * rw, 'i32');
+ GodotRuntime.setHeapValue(r_y, (y - rect.y) * rh, 'i32');
+ },
+
/*
* Canvas
*/
+ godot_js_display_canvas_focus__sig: 'v',
godot_js_display_canvas_focus: function () {
GodotConfig.canvas.focus();
},
+ godot_js_display_canvas_is_focused__sig: 'i',
godot_js_display_canvas_is_focused: function () {
return document.activeElement === GodotConfig.canvas;
},
- godot_js_display_canvas_bounding_rect_position_get: function (r_x, r_y) {
- const brect = GodotConfig.canvas.getBoundingClientRect();
- GodotRuntime.setHeapValue(r_x, brect.x, 'i32');
- GodotRuntime.setHeapValue(r_y, brect.y, 'i32');
- },
-
/*
* Touchscreen
*/
+ godot_js_display_touchscreen_is_available__sig: 'i',
godot_js_display_touchscreen_is_available: function () {
return 'ontouchstart' in window;
},
@@ -324,6 +624,7 @@ const GodotDisplay = {
/*
* Clipboard
*/
+ godot_js_display_clipboard_set__sig: 'ii',
godot_js_display_clipboard_set: function (p_text) {
const text = GodotRuntime.parseString(p_text);
if (!navigator.clipboard || !navigator.clipboard.writeText) {
@@ -336,6 +637,7 @@ const GodotDisplay = {
return 0;
},
+ godot_js_display_clipboard_get__sig: 'ii',
godot_js_display_clipboard_get: function (callback) {
const func = GodotRuntime.get_func(callback);
try {
@@ -354,18 +656,12 @@ const GodotDisplay = {
/*
* Window
*/
- godot_js_display_window_request_fullscreen: function () {
- const canvas = GodotConfig.canvas;
- (canvas.requestFullscreen || canvas.msRequestFullscreen
- || canvas.mozRequestFullScreen || canvas.mozRequestFullscreen
- || canvas.webkitRequestFullscreen
- ).call(canvas);
- },
-
+ godot_js_display_window_title_set__sig: 'vi',
godot_js_display_window_title_set: function (p_data) {
document.title = GodotRuntime.parseString(p_data);
},
+ godot_js_display_window_icon_set__sig: 'vii',
godot_js_display_window_icon_set: function (p_ptr, p_len) {
let link = document.getElementById('-gd-engine-icon');
if (link === null) {
@@ -386,6 +682,7 @@ const GodotDisplay = {
/*
* Cursor
*/
+ godot_js_display_cursor_set_visible__sig: 'vi',
godot_js_display_cursor_set_visible: function (p_visible) {
const visible = p_visible !== 0;
if (visible === GodotDisplayCursor.visible) {
@@ -399,14 +696,17 @@ const GodotDisplay = {
}
},
+ godot_js_display_cursor_is_hidden__sig: 'i',
godot_js_display_cursor_is_hidden: function () {
return !GodotDisplayCursor.visible;
},
+ godot_js_display_cursor_set_shape__sig: 'vi',
godot_js_display_cursor_set_shape: function (p_string) {
GodotDisplayCursor.set_shape(GodotRuntime.parseString(p_string));
},
+ godot_js_display_cursor_set_custom_shape__sig: 'viiiii',
godot_js_display_cursor_set_custom_shape: function (p_shape, p_ptr, p_len, p_hotspot_x, p_hotspot_y) {
const shape = GodotRuntime.parseString(p_shape);
const old_shape = GodotDisplayCursor.cursors[shape];
@@ -432,6 +732,7 @@ const GodotDisplay = {
/*
* Listeners
*/
+ godot_js_display_notification_cb__sig: 'viiiii',
godot_js_display_notification_cb: function (callback, p_enter, p_exit, p_in, p_out) {
const canvas = GodotConfig.canvas;
const func = GodotRuntime.get_func(callback);
@@ -443,6 +744,7 @@ const GodotDisplay = {
});
},
+ godot_js_display_paste_cb__sig: 'vi',
godot_js_display_paste_cb: function (callback) {
const func = GodotRuntime.get_func(callback);
GodotDisplayListeners.add(window, 'paste', function (evt) {
@@ -453,6 +755,7 @@ const GodotDisplay = {
}, false);
},
+ godot_js_display_drop_files_cb__sig: 'vi',
godot_js_display_drop_files_cb: function (callback) {
const func = GodotRuntime.get_func(callback);
const dropFiles = function (files) {
@@ -472,6 +775,78 @@ const GodotDisplay = {
}, false);
GodotDisplayListeners.add(canvas, 'drop', GodotDisplayDragDrop.handler(dropFiles));
},
+
+ godot_js_display_setup_canvas__sig: 'viii',
+ godot_js_display_setup_canvas: function (p_width, p_height, p_fullscreen) {
+ const canvas = GodotConfig.canvas;
+ GodotDisplayListeners.add(canvas, 'contextmenu', function (ev) {
+ ev.preventDefault();
+ }, false);
+ GodotDisplayListeners.add(canvas, 'webglcontextlost', function (ev) {
+ alert('WebGL context lost, please reload the page'); // eslint-disable-line no-alert
+ ev.preventDefault();
+ }, false);
+ switch (GodotConfig.canvas_resize_policy) {
+ case 0: // None
+ GodotDisplayScreen.desired_size = [canvas.width, canvas.height];
+ break;
+ case 1: // Project
+ GodotDisplayScreen.desired_size = [p_width, p_height];
+ break;
+ default: // Full window
+ // Ensure we display in the right place, the size will be handled by updateSize
+ canvas.style.position = 'absolute';
+ canvas.style.top = 0;
+ canvas.style.left = 0;
+ break;
+ }
+ if (p_fullscreen) {
+ GodotDisplayScreen.requestFullscreen();
+ }
+ },
+
+ /*
+ * Gamepads
+ */
+ godot_js_display_gamepad_cb__sig: 'vi',
+ godot_js_display_gamepad_cb: function (change_cb) {
+ const onchange = GodotRuntime.get_func(change_cb);
+ GodotDisplayGamepads.init(onchange);
+ },
+
+ godot_js_display_gamepad_sample_count__sig: 'i',
+ godot_js_display_gamepad_sample_count: function () {
+ return GodotDisplayGamepads.get_samples().length;
+ },
+
+ godot_js_display_gamepad_sample__sig: 'i',
+ godot_js_display_gamepad_sample: function () {
+ GodotDisplayGamepads.sample();
+ return 0;
+ },
+
+ godot_js_display_gamepad_sample_get__sig: 'iiiiiii',
+ godot_js_display_gamepad_sample_get: function (p_index, r_btns, r_btns_num, r_axes, r_axes_num, r_standard) {
+ const sample = GodotDisplayGamepads.get_sample(p_index);
+ if (!sample || !sample.connected) {
+ return 1;
+ }
+ const btns = sample.buttons;
+ const btns_len = btns.length < 16 ? btns.length : 16;
+ for (let i = 0; i < btns_len; i++) {
+ GodotRuntime.setHeapValue(r_btns + (i << 2), btns[i], 'float');
+ }
+ GodotRuntime.setHeapValue(r_btns_num, btns_len, 'i32');
+ const axes = sample.axes;
+ const axes_len = axes.length < 10 ? axes.length : 10;
+ for (let i = 0; i < axes_len; i++) {
+ GodotRuntime.setHeapValue(r_axes + (i << 2), axes[i], 'float');
+ }
+ GodotRuntime.setHeapValue(r_axes_num, axes_len, 'i32');
+ const is_standard = sample.standard ? 1 : 0;
+ GodotRuntime.setHeapValue(r_standard, is_standard, 'i32');
+ return 0;
+ },
};
autoAddDeps(GodotDisplay, '$GodotDisplay');
diff --git a/platform/javascript/js/libs/library_godot_editor_tools.js b/platform/javascript/js/libs/library_godot_editor_tools.js
index f39fed04a8..d7f1ad5ea1 100644
--- a/platform/javascript/js/libs/library_godot_editor_tools.js
+++ b/platform/javascript/js/libs/library_godot_editor_tools.js
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,6 +30,7 @@
const GodotEditorTools = {
godot_js_editor_download_file__deps: ['$FS'],
+ godot_js_editor_download_file__sig: 'viii',
godot_js_editor_download_file: function (p_path, p_name, p_mime) {
const path = GodotRuntime.parseString(p_path);
const name = GodotRuntime.parseString(p_name);
diff --git a/platform/javascript/js/libs/library_godot_eval.js b/platform/javascript/js/libs/library_godot_eval.js
index 33ff231726..9ab392b813 100644
--- a/platform/javascript/js/libs/library_godot_eval.js
+++ b/platform/javascript/js/libs/library_godot_eval.js
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,6 +30,7 @@
const GodotEval = {
godot_js_eval__deps: ['$GodotRuntime'],
+ godot_js_eval__sig: 'iiiiiii',
godot_js_eval: function (p_js, p_use_global_ctx, p_union_ptr, p_byte_arr, p_byte_arr_write, p_callback) {
const js_code = GodotRuntime.parseString(p_js);
let eval_ret = null;
diff --git a/platform/javascript/js/libs/library_godot_http_request.js b/platform/javascript/js/libs/library_godot_http_request.js
index 2b9aa88208..7dc2a2df29 100644
--- a/platform/javascript/js/libs/library_godot_http_request.js
+++ b/platform/javascript/js/libs/library_godot_http_request.js
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -50,6 +50,7 @@ const GodotHTTPRequest = {
},
},
+ godot_xhr_new__sig: 'i',
godot_xhr_new: function () {
const newId = GodotHTTPRequest.getUnusedRequestId();
GodotHTTPRequest.requests[newId] = new XMLHttpRequest();
@@ -57,67 +58,61 @@ const GodotHTTPRequest = {
return newId;
},
+ godot_xhr_reset__sig: 'vi',
godot_xhr_reset: function (xhrId) {
GodotHTTPRequest.requests[xhrId] = new XMLHttpRequest();
GodotHTTPRequest.setupRequest(GodotHTTPRequest.requests[xhrId]);
},
+ godot_xhr_free__sig: 'vi',
godot_xhr_free: function (xhrId) {
GodotHTTPRequest.requests[xhrId].abort();
GodotHTTPRequest.requests[xhrId] = null;
},
+ godot_xhr_open__sig: 'viiiii',
godot_xhr_open: function (xhrId, method, url, p_user, p_password) {
const user = p_user > 0 ? GodotRuntime.parseString(p_user) : null;
const password = p_password > 0 ? GodotRuntime.parseString(p_password) : null;
GodotHTTPRequest.requests[xhrId].open(GodotRuntime.parseString(method), GodotRuntime.parseString(url), true, user, password);
},
+ godot_xhr_set_request_header__sig: 'viii',
godot_xhr_set_request_header: function (xhrId, header, value) {
GodotHTTPRequest.requests[xhrId].setRequestHeader(GodotRuntime.parseString(header), GodotRuntime.parseString(value));
},
- godot_xhr_send_null: function (xhrId) {
- GodotHTTPRequest.requests[xhrId].send();
- },
-
- godot_xhr_send_string: function (xhrId, strPtr) {
- if (!strPtr) {
- GodotRuntime.error('Failed to send string per XHR: null pointer');
- return;
- }
- GodotHTTPRequest.requests[xhrId].send(GodotRuntime.parseString(strPtr));
- },
-
- godot_xhr_send_data: function (xhrId, ptr, len) {
- if (!ptr) {
- GodotRuntime.error('Failed to send data per XHR: null pointer');
- return;
- }
- if (len < 0) {
- GodotRuntime.error('Failed to send data per XHR: buffer length less than 0');
- return;
+ godot_xhr_send__sig: 'viii',
+ godot_xhr_send: function (xhrId, p_ptr, p_len) {
+ let data = null;
+ if (p_ptr && p_len) {
+ data = GodotRuntime.heapCopy(HEAP8, p_ptr, p_len);
}
- GodotHTTPRequest.requests[xhrId].send(HEAPU8.subarray(ptr, ptr + len));
+ GodotHTTPRequest.requests[xhrId].send(data);
},
+ godot_xhr_abort__sig: 'vi',
godot_xhr_abort: function (xhrId) {
GodotHTTPRequest.requests[xhrId].abort();
},
+ godot_xhr_get_status__sig: 'ii',
godot_xhr_get_status: function (xhrId) {
return GodotHTTPRequest.requests[xhrId].status;
},
+ godot_xhr_get_ready_state__sig: 'ii',
godot_xhr_get_ready_state: function (xhrId) {
return GodotHTTPRequest.requests[xhrId].readyState;
},
+ godot_xhr_get_response_headers_length__sig: 'ii',
godot_xhr_get_response_headers_length: function (xhrId) {
const headers = GodotHTTPRequest.requests[xhrId].getAllResponseHeaders();
return headers === null ? 0 : GodotRuntime.strlen(headers);
},
+ godot_xhr_get_response_headers__sig: 'viii',
godot_xhr_get_response_headers: function (xhrId, dst, len) {
const str = GodotHTTPRequest.requests[xhrId].getAllResponseHeaders();
if (str === null) {
@@ -126,11 +121,13 @@ const GodotHTTPRequest = {
GodotRuntime.stringToHeap(str, dst, len);
},
+ godot_xhr_get_response_length__sig: 'ii',
godot_xhr_get_response_length: function (xhrId) {
const body = GodotHTTPRequest.requests[xhrId].response;
return body === null ? 0 : body.byteLength;
},
+ godot_xhr_get_response__sig: 'viii',
godot_xhr_get_response: function (xhrId, dst, len) {
let buf = GodotHTTPRequest.requests[xhrId].response;
if (buf === null) {
diff --git a/platform/javascript/js/libs/library_godot_os.js b/platform/javascript/js/libs/library_godot_os.js
index 488753d704..0f189b013c 100644
--- a/platform/javascript/js/libs/library_godot_os.js
+++ b/platform/javascript/js/libs/library_godot_os.js
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -58,34 +58,39 @@ const GodotConfig = {
$GodotConfig: {
canvas: null,
locale: 'en',
- resize_on_start: false,
+ canvas_resize_policy: 2, // Adaptive
on_execute: null,
+ on_exit: null,
init_config: function (p_opts) {
- GodotConfig.resize_on_start = !!p_opts['resizeCanvasOnStart'];
+ GodotConfig.canvas_resize_policy = p_opts['canvasResizePolicy'];
GodotConfig.canvas = p_opts['canvas'];
GodotConfig.locale = p_opts['locale'] || GodotConfig.locale;
GodotConfig.on_execute = p_opts['onExecute'];
- // This is called by emscripten, even if undocumented.
- Module['onExit'] = p_opts['onExit']; // eslint-disable-line no-undef
+ GodotConfig.on_exit = p_opts['onExit'];
},
locate_file: function (file) {
return Module['locateFile'](file); // eslint-disable-line no-undef
},
+ clear: function () {
+ GodotConfig.canvas = null;
+ GodotConfig.locale = 'en';
+ GodotConfig.canvas_resize_policy = 2;
+ GodotConfig.on_execute = null;
+ GodotConfig.on_exit = null;
+ },
},
+ godot_js_config_canvas_id_get__sig: 'vii',
godot_js_config_canvas_id_get: function (p_ptr, p_ptr_max) {
GodotRuntime.stringToHeap(`#${GodotConfig.canvas.id}`, p_ptr, p_ptr_max);
},
+ godot_js_config_locale_get__sig: 'vii',
godot_js_config_locale_get: function (p_ptr, p_ptr_max) {
GodotRuntime.stringToHeap(GodotConfig.locale, p_ptr, p_ptr_max);
},
-
- godot_js_config_is_resize_on_start: function () {
- return GodotConfig.resize_on_start ? 1 : 0;
- },
};
autoAddDeps(GodotConfig, '$GodotConfig');
@@ -95,7 +100,6 @@ const GodotFS = {
$GodotFS__deps: ['$FS', '$IDBFS', '$GodotRuntime'],
$GodotFS__postset: [
'Module["initFS"] = GodotFS.init;',
- 'Module["deinitFS"] = GodotFS.deinit;',
'Module["copyToFS"] = GodotFS.copy_to_fs;',
].join(''),
$GodotFS: {
@@ -200,16 +204,17 @@ const GodotFS = {
}
FS.mkdirTree(dir);
}
- FS.writeFile(path, new Uint8Array(buffer), { 'flags': 'wx+' });
+ FS.writeFile(path, new Uint8Array(buffer));
},
},
};
mergeInto(LibraryManager.library, GodotFS);
const GodotOS = {
- $GodotOS__deps: ['$GodotFS', '$GodotRuntime'],
+ $GodotOS__deps: ['$GodotRuntime', '$GodotConfig', '$GodotFS'],
$GodotOS__postset: [
'Module["request_quit"] = function() { GodotOS.request_quit() };',
+ 'Module["onExit"] = GodotOS.cleanup;',
'GodotOS._fs_sync_promise = Promise.resolve();',
].join(''),
$GodotOS: {
@@ -221,6 +226,15 @@ const GodotOS = {
GodotOS._async_cbs.push(p_promise_cb);
},
+ cleanup: function (exit_code) {
+ const cb = GodotConfig.on_exit;
+ GodotFS.deinit();
+ GodotConfig.clear();
+ if (cb) {
+ cb(exit_code);
+ }
+ },
+
finish_async: function (callback) {
GodotOS._fs_sync_promise.then(function (err) {
const promises = [];
@@ -239,19 +253,23 @@ const GodotOS = {
},
},
+ godot_js_os_finish_async__sig: 'vi',
godot_js_os_finish_async: function (p_callback) {
const func = GodotRuntime.get_func(p_callback);
GodotOS.finish_async(func);
},
+ godot_js_os_request_quit_cb__sig: 'vi',
godot_js_os_request_quit_cb: function (p_callback) {
GodotOS.request_quit = GodotRuntime.get_func(p_callback);
},
+ godot_js_os_fs_is_persistent__sig: 'i',
godot_js_os_fs_is_persistent: function () {
return GodotFS.is_persistent();
},
+ godot_js_os_fs_sync__sig: 'vi',
godot_js_os_fs_sync: function (callback) {
const func = GodotRuntime.get_func(callback);
GodotOS._fs_sync_promise = GodotFS.sync();
@@ -260,6 +278,7 @@ const GodotOS = {
});
},
+ godot_js_os_execute__sig: 'ii',
godot_js_os_execute: function (p_json) {
const json_args = GodotRuntime.parseString(p_json);
const args = JSON.parse(json_args);
@@ -270,9 +289,15 @@ const GodotOS = {
return 1;
},
+ godot_js_os_shell_open__sig: 'vi',
godot_js_os_shell_open: function (p_uri) {
window.open(GodotRuntime.parseString(p_uri), '_blank');
},
+
+ godot_js_os_hw_concurrency_get__sig: 'i',
+ godot_js_os_hw_concurrency_get: function () {
+ return navigator.hardwareConcurrency || 1;
+ },
};
autoAddDeps(GodotOS, '$GodotOS');
diff --git a/platform/javascript/js/libs/library_godot_runtime.js b/platform/javascript/js/libs/library_godot_runtime.js
index 04f29ad681..7e36ff8ab5 100644
--- a/platform/javascript/js/libs/library_godot_runtime.js
+++ b/platform/javascript/js/libs/library_godot_runtime.js
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp
index 80723d54fc..0b1650076c 100644
--- a/platform/javascript/os_javascript.cpp
+++ b/platform/javascript/os_javascript.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,7 +31,6 @@
#include "os_javascript.h"
#include "core/debugger/engine_debugger.h"
-#include "core/io/file_access_buffered_fa.h"
#include "core/io/json.h"
#include "drivers/unix/dir_access_unix.h"
#include "drivers/unix/file_access_unix.h"
@@ -43,6 +42,7 @@
#include "modules/websocket/remote_debugger_peer_websocket.h"
#endif
+#include <dlfcn.h>
#include <emscripten.h>
#include <stdlib.h>
@@ -51,7 +51,6 @@
// Lifecycle
void OS_JavaScript::initialize() {
OS_Unix::initialize_core();
- FileAccess::make_default<FileAccessBufferedFA<FileAccessUnix>>(FileAccess::ACCESS_RESOURCES);
DisplayServerJavaScript::register_javascript_driver();
#ifdef MODULE_WEBSOCKET_ENABLED
@@ -107,14 +106,18 @@ void OS_JavaScript::finalize() {
// Miscellaneous
-Error OS_JavaScript::execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex) {
+Error OS_JavaScript::execute(const String &p_path, const List<String> &p_arguments, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex) {
+ return create_process(p_path, p_arguments);
+}
+
+Error OS_JavaScript::create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id) {
Array args;
for (const List<String>::Element *E = p_arguments.front(); E; E = E->next()) {
args.push_back(E->get());
}
String json_args = JSON::print(args);
int failed = godot_js_os_execute(json_args.utf8().get_data());
- ERR_FAIL_COND_V_MSG(failed, ERR_UNAVAILABLE, "OS::execute() must be implemented in JavaScript via 'engine.setOnExecute' if required.");
+ ERR_FAIL_COND_V_MSG(failed, ERR_UNAVAILABLE, "OS::execute() or create_process() must be implemented in JavaScript via 'engine.setOnExecute' if required.");
return OK;
}
@@ -126,13 +129,29 @@ int OS_JavaScript::get_process_id() const {
ERR_FAIL_V_MSG(0, "OS::get_process_id() is not available on the HTML5 platform.");
}
+int OS_JavaScript::get_processor_count() const {
+ return godot_js_os_hw_concurrency_get();
+}
+
bool OS_JavaScript::_check_internal_feature_support(const String &p_feature) {
- if (p_feature == "HTML5" || p_feature == "web")
+ if (p_feature == "HTML5" || p_feature == "web") {
return true;
+ }
#ifdef JAVASCRIPT_EVAL_ENABLED
- if (p_feature == "JavaScript")
+ if (p_feature == "JavaScript") {
return true;
+ }
+#endif
+#ifndef NO_THREADS
+ if (p_feature == "threads") {
+ return true;
+ }
+#endif
+#if WASM_GDNATIVE
+ if (p_feature == "wasm32") {
+ return true;
+ }
#endif
return false;
@@ -187,6 +206,13 @@ bool OS_JavaScript::is_userfs_persistent() const {
return idb_available;
}
+Error OS_JavaScript::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path) {
+ String path = p_path.get_file();
+ p_library_handle = dlopen(path.utf8().get_data(), RTLD_NOW);
+ ERR_FAIL_COND_V_MSG(!p_library_handle, ERR_CANT_OPEN, "Can't open dynamic library: " + p_path + ". Error: " + dlerror());
+ return OK;
+}
+
OS_JavaScript *OS_JavaScript::get_singleton() {
return static_cast<OS_JavaScript *>(OS::get_singleton());
}
diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h
index 03a3053367..81bb9c5f3d 100644
--- a/platform/javascript/os_javascript.h
+++ b/platform/javascript/os_javascript.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -70,9 +70,11 @@ public:
MainLoop *get_main_loop() const override;
bool main_loop_iterate();
- Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking = true, ProcessID *r_child_id = nullptr, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr) override;
+ Error execute(const String &p_path, const List<String> &p_arguments, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr) override;
+ Error create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id = nullptr) override;
Error kill(const ProcessID &p_pid) override;
int get_process_id() const override;
+ int get_processor_count() const override;
String get_executable_path() const override;
Error shell_open(String p_uri) override;
@@ -87,6 +89,7 @@ public:
String get_user_data_dir() const override;
bool is_userfs_persistent() const override;
+ Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path) override;
void resume_audio();
diff --git a/platform/javascript/platform_config.h b/platform/javascript/platform_config.h
index e2200376d3..65df34902e 100644
--- a/platform/javascript/platform_config.h
+++ b/platform/javascript/platform_config.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/linuxbsd/SCsub b/platform/linuxbsd/SCsub
index 6e43ffcedb..46714e9502 100644
--- a/platform/linuxbsd/SCsub
+++ b/platform/linuxbsd/SCsub
@@ -16,7 +16,10 @@ common_x11 = [
"key_mapping_x11.cpp",
]
+if "udev" in env and env["udev"]:
+ common_x11.append("libudev-so_wrap.c")
+
prog = env.add_program("#bin/godot", ["godot_linuxbsd.cpp"] + common_x11)
-if env["debug_symbols"] == "yes" and env["separate_debug_symbols"]:
+if env["debug_symbols"] and env["separate_debug_symbols"]:
env.AddPostAction(prog, run_in_subprocess(platform_linuxbsd_builders.make_debug_linuxbsd))
diff --git a/platform/linuxbsd/context_gl_x11.cpp b/platform/linuxbsd/context_gl_x11.cpp
index 71dc9602b3..1f92370ab7 100644
--- a/platform/linuxbsd/context_gl_x11.cpp
+++ b/platform/linuxbsd/context_gl_x11.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/linuxbsd/context_gl_x11.h b/platform/linuxbsd/context_gl_x11.h
index 7aed280c98..d089886f4d 100644
--- a/platform/linuxbsd/context_gl_x11.h
+++ b/platform/linuxbsd/context_gl_x11.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/linuxbsd/crash_handler_linuxbsd.cpp b/platform/linuxbsd/crash_handler_linuxbsd.cpp
index 36c304b7f9..ea0222cb19 100644
--- a/platform/linuxbsd/crash_handler_linuxbsd.cpp
+++ b/platform/linuxbsd/crash_handler_linuxbsd.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -104,7 +104,7 @@ static void handle_crash(int sig) {
// Try to get the file/line number using addr2line
int ret;
- Error err = OS::get_singleton()->execute(String("addr2line"), args, true, nullptr, &output, &ret);
+ Error err = OS::get_singleton()->execute(String("addr2line"), args, &output, &ret);
if (err == OK) {
output.erase(output.length() - 1, 1);
}
diff --git a/platform/linuxbsd/crash_handler_linuxbsd.h b/platform/linuxbsd/crash_handler_linuxbsd.h
index 9bb03579bc..a3dae0cc22 100644
--- a/platform/linuxbsd/crash_handler_linuxbsd.h
+++ b/platform/linuxbsd/crash_handler_linuxbsd.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/linuxbsd/detect.py b/platform/linuxbsd/detect.py
index a8bc3a09f6..ff521e4e7f 100644
--- a/platform/linuxbsd/detect.py
+++ b/platform/linuxbsd/detect.py
@@ -12,7 +12,6 @@ def get_name():
def can_build():
-
if os.name != "posix" or sys.platform == "darwin":
return False
@@ -65,15 +64,15 @@ def get_opts():
BoolVariable("use_llvm", "Use the LLVM compiler", False),
BoolVariable("use_lld", "Use the LLD linker", False),
BoolVariable("use_thinlto", "Use ThinLTO", False),
- BoolVariable("use_static_cpp", "Link libgcc and libstdc++ statically for better portability", False),
+ BoolVariable("use_static_cpp", "Link libgcc and libstdc++ statically for better portability", True),
BoolVariable("use_coverage", "Test Godot coverage", False),
BoolVariable("use_ubsan", "Use LLVM/GCC compiler undefined behavior sanitizer (UBSAN)", False),
BoolVariable("use_asan", "Use LLVM/GCC compiler address sanitizer (ASAN))", False),
BoolVariable("use_lsan", "Use LLVM/GCC compiler leak sanitizer (LSAN))", False),
BoolVariable("use_tsan", "Use LLVM/GCC compiler thread sanitizer (TSAN))", False),
BoolVariable("pulseaudio", "Detect and use PulseAudio", True),
- BoolVariable("udev", "Use udev for gamepad connection callbacks", False),
- EnumVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", "yes", ("yes", "no")),
+ BoolVariable("udev", "Use udev for gamepad connection callbacks", True),
+ BoolVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", True),
BoolVariable("separate_debug_symbols", "Create a separate file containing debugging symbols", False),
BoolVariable("touch", "Enable touch events", True),
BoolVariable("execinfo", "Use libexecinfo on systems where glibc is not available", False),
@@ -81,12 +80,10 @@ def get_opts():
def get_flags():
-
return []
def configure(env):
-
## Build type
if env["target"] == "release":
@@ -95,7 +92,7 @@ def configure(env):
else: # optimize for size
env.Prepend(CCFLAGS=["-Os"])
- if env["debug_symbols"] == "yes":
+ if env["debug_symbols"]:
env.Prepend(CCFLAGS=["-g2"])
elif env["target"] == "release_debug":
@@ -105,7 +102,7 @@ def configure(env):
env.Prepend(CCFLAGS=["-Os"])
env.Prepend(CPPDEFINES=["DEBUG_ENABLED"])
- if env["debug_symbols"] == "yes":
+ if env["debug_symbols"]:
env.Prepend(CCFLAGS=["-g2"])
elif env["target"] == "debug":
@@ -130,6 +127,7 @@ def configure(env):
env["CC"] = "clang"
env["CXX"] = "clang++"
env.extra_suffix = ".llvm" + env.extra_suffix
+ env.Append(LIBS=["atomic"])
if env["use_lld"]:
if env["use_llvm"]:
@@ -205,14 +203,31 @@ def configure(env):
# freetype depends on libpng and zlib, so bundling one of them while keeping others
# as shared libraries leads to weird issues
- if env["builtin_freetype"] or env["builtin_libpng"] or env["builtin_zlib"]:
+ if (
+ env["builtin_freetype"]
+ or env["builtin_libpng"]
+ or env["builtin_zlib"]
+ or env["builtin_graphite"]
+ or env["builtin_harfbuzz"]
+ ):
env["builtin_freetype"] = True
env["builtin_libpng"] = True
env["builtin_zlib"] = True
+ env["builtin_graphite"] = True
+ env["builtin_harfbuzz"] = True
if not env["builtin_freetype"]:
env.ParseConfig("pkg-config freetype2 --cflags --libs")
+ if not env["builtin_graphite"]:
+ env.ParseConfig("pkg-config graphite2 --cflags --libs")
+
+ if not env["builtin_icu"]:
+ env.ParseConfig("pkg-config icu-uc --cflags --libs")
+
+ if not env["builtin_harfbuzz"]:
+ env.ParseConfig("pkg-config harfbuzz harfbuzz-icu --cflags --libs")
+
if not env["builtin_libpng"]:
env.ParseConfig("pkg-config libpng16 --cflags --libs")
@@ -296,9 +311,8 @@ def configure(env):
if os.system("pkg-config --exists alsa") == 0: # 0 means found
print("Enabling ALSA")
+ env["alsa"] = True
env.Append(CPPDEFINES=["ALSA_ENABLED", "ALSAMIDI_ENABLED"])
- # Don't parse --cflags, we don't need to add /usr/include/alsa to include path
- env.ParseConfig("pkg-config alsa --libs")
else:
print("ALSA libraries not found, disabling driver")
@@ -306,20 +320,20 @@ def configure(env):
if os.system("pkg-config --exists libpulse") == 0: # 0 means found
print("Enabling PulseAudio")
env.Append(CPPDEFINES=["PULSEAUDIO_ENABLED"])
- env.ParseConfig("pkg-config --cflags --libs libpulse")
+ env.ParseConfig("pkg-config --cflags libpulse")
else:
print("PulseAudio development libraries not found, disabling driver")
if platform.system() == "Linux":
env.Append(CPPDEFINES=["JOYDEV_ENABLED"])
-
if env["udev"]:
if os.system("pkg-config --exists libudev") == 0: # 0 means found
print("Enabling udev support")
env.Append(CPPDEFINES=["UDEV_ENABLED"])
- env.ParseConfig("pkg-config libudev --cflags --libs")
else:
print("libudev development libraries not found, disabling udev support")
+ else:
+ env["udev"] = False # Linux specific
# Linkflags below this line should typically stay the last ones
if not env["builtin_zlib"]:
@@ -376,4 +390,7 @@ def configure(env):
# Link those statically for portability
if env["use_static_cpp"]:
- env.Append(LINKFLAGS=["-static-libgcc", "-static-libstdc++"])
+ # Workaround for GH-31743, Ubuntu 18.04 i386 crashes when it's used.
+ # That doesn't make any sense but it's likely a Ubuntu bug?
+ if is64 or env["bits"] == "64":
+ env.Append(LINKFLAGS=["-static-libgcc", "-static-libstdc++"])
diff --git a/platform/linuxbsd/detect_prime_x11.cpp b/platform/linuxbsd/detect_prime_x11.cpp
index e5a9bb4737..da1c95a593 100644
--- a/platform/linuxbsd/detect_prime_x11.cpp
+++ b/platform/linuxbsd/detect_prime_x11.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -56,11 +56,12 @@ typedef GLXContext (*GLXCREATECONTEXTATTRIBSARBPROC)(Display *, GLXFBConfig, GLX
struct vendor {
const char *glxvendor;
- int priority;
+ int priority = 0;
};
vendor vendormap[] = {
{ "Advanced Micro Devices, Inc.", 30 },
+ { "AMD", 30 },
{ "NVIDIA Corporation", 30 },
{ "X.Org", 30 },
{ "Intel Open Source Technology Center", 20 },
@@ -128,7 +129,7 @@ void create_context() {
int detect_prime() {
pid_t p;
- int priorities[2];
+ int priorities[2] = {};
String vendors[2];
String renderers[2];
diff --git a/platform/linuxbsd/detect_prime_x11.h b/platform/linuxbsd/detect_prime_x11.h
index 039bdee76b..0b548b849e 100644
--- a/platform/linuxbsd/detect_prime_x11.h
+++ b/platform/linuxbsd/detect_prime_x11.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp
index 74c69c0823..fceeb82325 100644
--- a/platform/linuxbsd/display_server_x11.cpp
+++ b/platform/linuxbsd/display_server_x11.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -40,9 +40,10 @@
#include "scene/resources/texture.h"
#if defined(VULKAN_ENABLED)
-#include "servers/rendering/rasterizer_rd/rasterizer_rd.h"
+#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
#endif
+#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -94,6 +95,15 @@
static const double abs_resolution_mult = 10000.0;
static const double abs_resolution_range_mult = 10.0;
+// Hints for X11 fullscreen
+struct Hints {
+ unsigned long flags = 0;
+ unsigned long functions = 0;
+ unsigned long decorations = 0;
+ long inputMode = 0;
+ unsigned long status = 0;
+};
+
bool DisplayServerX11::has_feature(Feature p_feature) const {
switch (p_feature) {
case FEATURE_SUBWINDOWS:
@@ -181,7 +191,7 @@ void DisplayServerX11::alert(const String &p_alert, const String &p_title) {
}
if (program.length()) {
- OS::get_singleton()->execute(program, args, true);
+ OS::get_singleton()->execute(program, args);
} else {
print_line(p_alert);
}
@@ -465,59 +475,138 @@ Bool DisplayServerX11::_predicate_clipboard_selection(Display *display, XEvent *
}
}
+Bool DisplayServerX11::_predicate_clipboard_incr(Display *display, XEvent *event, XPointer arg) {
+ if (event->type == PropertyNotify && event->xproperty.state == PropertyNewValue) {
+ return True;
+ } else {
+ return False;
+ }
+}
+
String DisplayServerX11::_clipboard_get_impl(Atom p_source, Window x11_window, Atom target) const {
String ret;
- Atom type;
- Atom selection = XA_PRIMARY;
- int format, result;
- unsigned long len, bytes_left, dummy;
- unsigned char *data;
Window selection_owner = XGetSelectionOwner(x11_display, p_source);
-
if (selection_owner == x11_window) {
return internal_clipboard;
}
if (selection_owner != None) {
- {
- // Block events polling while processing selection events.
- MutexLock mutex_lock(events_mutex);
+ // Block events polling while processing selection events.
+ MutexLock mutex_lock(events_mutex);
- XConvertSelection(x11_display, p_source, target, selection,
- x11_window, CurrentTime);
+ Atom selection = XA_PRIMARY;
+ XConvertSelection(x11_display, p_source, target, selection,
+ x11_window, CurrentTime);
- XFlush(x11_display);
+ XFlush(x11_display);
- // Blocking wait for predicate to be True
- // and remove the event from the queue.
- XEvent event;
- XIfEvent(x11_display, &event, _predicate_clipboard_selection, (XPointer)&x11_window);
- }
+ // Blocking wait for predicate to be True and remove the event from the queue.
+ XEvent event;
+ XIfEvent(x11_display, &event, _predicate_clipboard_selection, (XPointer)&x11_window);
- //
- // Do not get any data, see how much data is there
- //
+ // Do not get any data, see how much data is there.
+ Atom type;
+ int format, result;
+ unsigned long len, bytes_left, dummy;
+ unsigned char *data;
XGetWindowProperty(x11_display, x11_window,
selection, // Tricky..
0, 0, // offset - len
0, // Delete 0==FALSE
- AnyPropertyType, //flag
+ AnyPropertyType, // flag
&type, // return type
&format, // return format
- &len, &bytes_left, //that
+ &len, &bytes_left, // data length
&data);
- // DATA is There
- if (bytes_left > 0) {
+
+ if (data) {
+ XFree(data);
+ }
+
+ if (type == XInternAtom(x11_display, "INCR", 0)) {
+ // Data is going to be received incrementally.
+ DEBUG_LOG_X11("INCR selection started.\n");
+
+ LocalVector<uint8_t> incr_data;
+ uint32_t data_size = 0;
+ bool success = false;
+
+ // Delete INCR property to notify the owner.
+ XDeleteProperty(x11_display, x11_window, type);
+
+ // Process events from the queue.
+ bool done = false;
+ while (!done) {
+ if (!_wait_for_events()) {
+ // Error or timeout, abort.
+ break;
+ }
+
+ // Non-blocking wait for next event and remove it from the queue.
+ XEvent ev;
+ while (XCheckIfEvent(x11_display, &ev, _predicate_clipboard_incr, nullptr)) {
+ result = XGetWindowProperty(x11_display, x11_window,
+ selection, // selection type
+ 0, LONG_MAX, // offset - len
+ True, // delete property to notify the owner
+ AnyPropertyType, // flag
+ &type, // return type
+ &format, // return format
+ &len, &bytes_left, // data length
+ &data);
+
+ DEBUG_LOG_X11("PropertyNotify: len=%lu, format=%i\n", len, format);
+
+ if (result == Success) {
+ if (data && (len > 0)) {
+ uint32_t prev_size = incr_data.size();
+ if (prev_size == 0) {
+ // First property contains initial data size.
+ unsigned long initial_size = *(unsigned long *)data;
+ incr_data.resize(initial_size);
+ } else {
+ // New chunk, resize to be safe and append data.
+ incr_data.resize(MAX(data_size + len, prev_size));
+ memcpy(incr_data.ptr() + data_size, data, len);
+ data_size += len;
+ }
+ } else {
+ // Last chunk, process finished.
+ done = true;
+ success = true;
+ }
+ } else {
+ printf("Failed to get selection data chunk.\n");
+ done = true;
+ }
+
+ if (data) {
+ XFree(data);
+ }
+
+ if (done) {
+ break;
+ }
+ }
+ }
+
+ if (success && (data_size > 0)) {
+ ret.parse_utf8((const char *)incr_data.ptr(), data_size);
+ }
+ } else if (bytes_left > 0) {
+ // Data is ready and can be processed all at once.
result = XGetWindowProperty(x11_display, x11_window,
selection, 0, bytes_left, 0,
AnyPropertyType, &type, &format,
&len, &dummy, &data);
+
if (result == Success) {
ret.parse_utf8((const char *)data);
} else {
- printf("FAIL\n");
+ printf("Failed to get selection data.\n");
}
+
if (data) {
XFree(data);
}
@@ -533,7 +622,7 @@ String DisplayServerX11::_clipboard_get(Atom p_source, Window x11_window) const
if (utf8_atom != None) {
ret = _clipboard_get_impl(p_source, x11_window, utf8_atom);
}
- if (ret.empty()) {
+ if (ret.is_empty()) {
ret = _clipboard_get_impl(p_source, x11_window, XA_STRING);
}
return ret;
@@ -545,7 +634,7 @@ String DisplayServerX11::clipboard_get() const {
String ret;
ret = _clipboard_get(XInternAtom(x11_display, "CLIPBOARD", 0), windows[MAIN_WINDOW_ID].x11_window);
- if (ret.empty()) {
+ if (ret.is_empty()) {
ret = _clipboard_get(XA_PRIMARY, windows[MAIN_WINDOW_ID].x11_window);
}
@@ -2608,7 +2697,7 @@ bool DisplayServerX11::_wait_for_events() const {
}
void DisplayServerX11::_poll_events() {
- while (!events_thread_done) {
+ while (!events_thread_done.is_set()) {
_wait_for_events();
// Process events from the queue.
@@ -3271,7 +3360,7 @@ void DisplayServerX11::process_events() {
Vector<String> files = String((char *)p.data).split("\n", false);
for (int i = 0; i < files.size(); i++) {
- files.write[i] = files[i].replace("file://", "").http_unescape().strip_edges();
+ files.write[i] = files[i].replace("file://", "").uri_decode().strip_edges();
}
if (!windows[window_id].drop_files_callback.is_null()) {
@@ -4008,12 +4097,12 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
rendering_device_vulkan = memnew(RenderingDeviceVulkan);
rendering_device_vulkan->initialize(context_vulkan);
- RasterizerRD::make_current();
+ RendererCompositorRD::make_current();
}
#endif
/*
- rendering_server = memnew(RenderingServerRaster);
+ rendering_server = memnew(RenderingServerDefault);
if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {
rendering_server = memnew(RenderingServerWrapMT(rendering_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD));
}
@@ -4177,7 +4266,7 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
}
}
- events_thread = Thread::create(_poll_events_thread, this);
+ events_thread.start(_poll_events_thread, this);
_update_real_mouse_position(windows[MAIN_WINDOW_ID]);
@@ -4190,10 +4279,8 @@ DisplayServerX11::~DisplayServerX11() {
_clipboard_transfer_ownership(XA_PRIMARY, x11_main_window);
_clipboard_transfer_ownership(XInternAtom(x11_display, "CLIPBOARD", 0), x11_main_window);
- events_thread_done = true;
- Thread::wait_to_finish(events_thread);
- memdelete(events_thread);
- events_thread = nullptr;
+ events_thread_done.set();
+ events_thread.wait_to_finish();
//destroy all windows
for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) {
diff --git a/platform/linuxbsd/display_server_x11.h b/platform/linuxbsd/display_server_x11.h
index 682f1c8ef3..10686d8424 100644
--- a/platform/linuxbsd/display_server_x11.h
+++ b/platform/linuxbsd/display_server_x11.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -43,7 +43,7 @@
#include "drivers/unix/os_unix.h"
#include "joypad_linux.h"
#include "servers/audio_server.h"
-#include "servers/rendering/rasterizer.h"
+#include "servers/rendering/renderer_compositor.h"
#include "servers/rendering_server.h"
#if defined(OPENGL_ENABLED)
@@ -61,27 +61,18 @@
#include <X11/extensions/Xrandr.h>
#include <X11/keysym.h>
-// Hints for X11 fullscreen
-typedef struct {
- unsigned long flags;
- unsigned long functions;
- unsigned long decorations;
- long inputMode;
- unsigned long status;
-} Hints;
-
typedef struct _xrr_monitor_info {
Atom name;
- Bool primary;
- Bool automatic;
- int noutput;
- int x;
- int y;
- int width;
- int height;
- int mwidth;
- int mheight;
- RROutput *outputs;
+ Bool primary = false;
+ Bool automatic = false;
+ int noutput = 0;
+ int x = 0;
+ int y = 0;
+ int width = 0;
+ int height = 0;
+ int mwidth = 0;
+ int mheight = 0;
+ RROutput *outputs = nullptr;
} xrr_monitor_info;
#undef CursorShape
@@ -261,8 +252,8 @@ class DisplayServerX11 : public DisplayServer {
void _dispatch_input_event(const Ref<InputEvent> &p_event);
mutable Mutex events_mutex;
- Thread *events_thread = nullptr;
- bool events_thread_done = false;
+ Thread events_thread;
+ SafeFlag events_thread_done;
LocalVector<XEvent> polled_events;
static void _poll_events_thread(void *ud);
bool _wait_for_events() const;
@@ -270,6 +261,7 @@ class DisplayServerX11 : public DisplayServer {
static Bool _predicate_all_events(Display *display, XEvent *event, XPointer arg);
static Bool _predicate_clipboard_selection(Display *display, XEvent *event, XPointer arg);
+ static Bool _predicate_clipboard_incr(Display *display, XEvent *event, XPointer arg);
static Bool _predicate_clipboard_save_targets(Display *display, XEvent *event, XPointer arg);
protected:
diff --git a/platform/linuxbsd/export/export.cpp b/platform/linuxbsd/export/export.cpp
index 86ea95c563..cb95068314 100644
--- a/platform/linuxbsd/export/export.cpp
+++ b/platform/linuxbsd/export/export.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/linuxbsd/export/export.h b/platform/linuxbsd/export/export.h
index 5ee81f485e..61e96aa2f6 100644
--- a/platform/linuxbsd/export/export.h
+++ b/platform/linuxbsd/export/export.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/linuxbsd/godot_linuxbsd.cpp b/platform/linuxbsd/godot_linuxbsd.cpp
index e1796ccefe..6f5c46b59c 100644
--- a/platform/linuxbsd/godot_linuxbsd.cpp
+++ b/platform/linuxbsd/godot_linuxbsd.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/linuxbsd/joypad_linux.cpp b/platform/linuxbsd/joypad_linux.cpp
index 4a9d0a8181..471259e50f 100644
--- a/platform/linuxbsd/joypad_linux.cpp
+++ b/platform/linuxbsd/joypad_linux.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -32,13 +32,14 @@
#include "joypad_linux.h"
+#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <linux/input.h>
#include <unistd.h>
#ifdef UDEV_ENABLED
-#include <libudev.h>
+#include "libudev-so_wrap.h"
#endif
#define LONG_BITS (sizeof(long) * 8)
@@ -49,15 +50,6 @@
static const char *ignore_str = "/dev/input/js";
#endif
-JoypadLinux::Joypad::Joypad() {
- fd = -1;
- dpad = 0;
- devpath = "";
- for (int i = 0; i < MAX_ABS; i++) {
- abs_info[i] = nullptr;
- }
-}
-
JoypadLinux::Joypad::~Joypad() {
for (int i = 0; i < MAX_ABS; i++) {
if (abs_info[i]) {
@@ -80,15 +72,28 @@ void JoypadLinux::Joypad::reset() {
}
JoypadLinux::JoypadLinux(Input *in) {
- exit_udev = false;
+#ifdef UDEV_ENABLED
+#ifdef DEBUG_ENABLED
+ int dylibloader_verbose = 1;
+#else
+ int dylibloader_verbose = 0;
+#endif
+ use_udev = initialize_libudev(dylibloader_verbose) == 0;
+ if (use_udev) {
+ 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.");
+ }
+#else
+ print_verbose("JoypadLinux: udev disabled, parsing /dev/input to detect joypads.");
+#endif
input = in;
- joy_thread = Thread::create(joy_thread_func, this);
+ joy_thread.start(joy_thread_func, this);
}
JoypadLinux::~JoypadLinux() {
- exit_udev = true;
- Thread::wait_to_finish(joy_thread);
- memdelete(joy_thread);
+ exit_monitor.set();
+ joy_thread.wait_to_finish();
close_joypad();
}
@@ -101,11 +106,20 @@ void JoypadLinux::joy_thread_func(void *p_user) {
void JoypadLinux::run_joypad_thread() {
#ifdef UDEV_ENABLED
- udev *_udev = udev_new();
- ERR_FAIL_COND(!_udev);
- enumerate_joypads(_udev);
- monitor_joypads(_udev);
- udev_unref(_udev);
+ if (use_udev) {
+ udev *_udev = udev_new();
+ if (!_udev) {
+ use_udev = false;
+ ERR_PRINT("Failed getting an udev context, falling back to parsing /dev/input.");
+ monitor_joypads();
+ } else {
+ enumerate_joypads(_udev);
+ monitor_joypads(_udev);
+ udev_unref(_udev);
+ }
+ } else {
+ monitor_joypads();
+ }
#else
monitor_joypads();
#endif
@@ -146,7 +160,7 @@ void JoypadLinux::monitor_joypads(udev *p_udev) {
udev_monitor_enable_receiving(mon);
int fd = udev_monitor_get_fd(mon);
- while (!exit_udev) {
+ while (!exit_monitor.is_set()) {
fd_set fds;
struct timeval tv;
int ret;
@@ -188,17 +202,27 @@ void JoypadLinux::monitor_joypads(udev *p_udev) {
#endif
void JoypadLinux::monitor_joypads() {
- while (!exit_udev) {
+ while (!exit_monitor.is_set()) {
{
MutexLock lock(joy_mutex);
- for (int i = 0; i < 32; i++) {
+ DIR *input_directory;
+ input_directory = opendir("/dev/input");
+ if (input_directory) {
+ struct dirent *current;
char fname[64];
- sprintf(fname, "/dev/input/event%d", i);
- if (attached_devices.find(fname) == -1) {
- open_joypad(fname);
+
+ while ((current = readdir(input_directory)) != NULL) {
+ if (strncmp(current->d_name, "event", 5) != 0) {
+ continue;
+ }
+ sprintf(fname, "/dev/input/%.*s", 16, current->d_name);
+ if (attached_devices.find(fname) == -1) {
+ open_joypad(fname);
+ }
}
}
+ closedir(input_directory);
}
usleep(1000000); // 1s
}
diff --git a/platform/linuxbsd/joypad_linux.h b/platform/linuxbsd/joypad_linux.h
index 0d175193a5..b0d0db047b 100644
--- a/platform/linuxbsd/joypad_linux.h
+++ b/platform/linuxbsd/joypad_linux.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -56,25 +56,27 @@ private:
Input::JoyAxis curr_axis[MAX_ABS];
int key_map[MAX_KEY];
int abs_map[MAX_ABS];
- int dpad;
- int fd;
+ int dpad = 0;
+ int fd = -1;
String devpath;
- input_absinfo *abs_info[MAX_ABS];
+ input_absinfo *abs_info[MAX_ABS] = {};
- bool force_feedback;
- int ff_effect_id;
- uint64_t ff_effect_timestamp;
+ bool force_feedback = false;
+ int ff_effect_id = 0;
+ uint64_t ff_effect_timestamp = 0;
- Joypad();
~Joypad();
void reset();
};
- bool exit_udev;
+#ifdef UDEV_ENABLED
+ bool use_udev = false;
+#endif
+ SafeFlag exit_monitor;
Mutex joy_mutex;
- Thread *joy_thread;
- Input *input;
+ Thread joy_thread;
+ Input *input = nullptr;
Joypad joypads[JOYPADS_MAX];
Vector<String> attached_devices;
diff --git a/platform/linuxbsd/key_mapping_x11.cpp b/platform/linuxbsd/key_mapping_x11.cpp
index 78049f2dfc..f9f612fa74 100644
--- a/platform/linuxbsd/key_mapping_x11.cpp
+++ b/platform/linuxbsd/key_mapping_x11.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/linuxbsd/key_mapping_x11.h b/platform/linuxbsd/key_mapping_x11.h
index 8f5e01a3c2..163a8e21db 100644
--- a/platform/linuxbsd/key_mapping_x11.h
+++ b/platform/linuxbsd/key_mapping_x11.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/linuxbsd/libudev-so_wrap.c b/platform/linuxbsd/libudev-so_wrap.c
new file mode 100644
index 0000000000..a9fa4a494a
--- /dev/null
+++ b/platform/linuxbsd/libudev-so_wrap.c
@@ -0,0 +1,1013 @@
+// This file is generated. Do not edit!
+// see https://github.com/hpvb/dynload-wrapper for details
+// generated by /home/hp/Projects/godot/pulse/generate-wrapper.py 0.3 on 2021-02-20 00:08:59
+// flags: /home/hp/Projects/godot/pulse/generate-wrapper.py --include /usr/include/libudev.h --sys-include <libudev.h> --soname libudev.so.1 --init-name libudev --omit-prefix gnu_ --output-header libudev-so_wrap.h --output-implementation libudev-so_wrap.c
+//
+#include <stdint.h>
+
+#define udev_ref udev_ref_dylibloader_orig_libudev
+#define udev_unref udev_unref_dylibloader_orig_libudev
+#define udev_new udev_new_dylibloader_orig_libudev
+#define udev_set_log_fn udev_set_log_fn_dylibloader_orig_libudev
+#define udev_get_log_priority udev_get_log_priority_dylibloader_orig_libudev
+#define udev_set_log_priority udev_set_log_priority_dylibloader_orig_libudev
+#define udev_get_userdata udev_get_userdata_dylibloader_orig_libudev
+#define udev_set_userdata udev_set_userdata_dylibloader_orig_libudev
+#define udev_list_entry_get_next udev_list_entry_get_next_dylibloader_orig_libudev
+#define udev_list_entry_get_by_name udev_list_entry_get_by_name_dylibloader_orig_libudev
+#define udev_list_entry_get_name udev_list_entry_get_name_dylibloader_orig_libudev
+#define udev_list_entry_get_value udev_list_entry_get_value_dylibloader_orig_libudev
+#define udev_device_ref udev_device_ref_dylibloader_orig_libudev
+#define udev_device_unref udev_device_unref_dylibloader_orig_libudev
+#define udev_device_get_udev udev_device_get_udev_dylibloader_orig_libudev
+#define udev_device_new_from_syspath udev_device_new_from_syspath_dylibloader_orig_libudev
+#define udev_device_new_from_devnum udev_device_new_from_devnum_dylibloader_orig_libudev
+#define udev_device_new_from_subsystem_sysname udev_device_new_from_subsystem_sysname_dylibloader_orig_libudev
+#define udev_device_new_from_device_id udev_device_new_from_device_id_dylibloader_orig_libudev
+#define udev_device_new_from_environment udev_device_new_from_environment_dylibloader_orig_libudev
+#define udev_device_get_parent udev_device_get_parent_dylibloader_orig_libudev
+#define udev_device_get_parent_with_subsystem_devtype udev_device_get_parent_with_subsystem_devtype_dylibloader_orig_libudev
+#define udev_device_get_devpath udev_device_get_devpath_dylibloader_orig_libudev
+#define udev_device_get_subsystem udev_device_get_subsystem_dylibloader_orig_libudev
+#define udev_device_get_devtype udev_device_get_devtype_dylibloader_orig_libudev
+#define udev_device_get_syspath udev_device_get_syspath_dylibloader_orig_libudev
+#define udev_device_get_sysname udev_device_get_sysname_dylibloader_orig_libudev
+#define udev_device_get_sysnum udev_device_get_sysnum_dylibloader_orig_libudev
+#define udev_device_get_devnode udev_device_get_devnode_dylibloader_orig_libudev
+#define udev_device_get_is_initialized udev_device_get_is_initialized_dylibloader_orig_libudev
+#define udev_device_get_devlinks_list_entry udev_device_get_devlinks_list_entry_dylibloader_orig_libudev
+#define udev_device_get_properties_list_entry udev_device_get_properties_list_entry_dylibloader_orig_libudev
+#define udev_device_get_tags_list_entry udev_device_get_tags_list_entry_dylibloader_orig_libudev
+#define udev_device_get_sysattr_list_entry udev_device_get_sysattr_list_entry_dylibloader_orig_libudev
+#define udev_device_get_property_value udev_device_get_property_value_dylibloader_orig_libudev
+#define udev_device_get_driver udev_device_get_driver_dylibloader_orig_libudev
+#define udev_device_get_devnum udev_device_get_devnum_dylibloader_orig_libudev
+#define udev_device_get_action udev_device_get_action_dylibloader_orig_libudev
+#define udev_device_get_seqnum udev_device_get_seqnum_dylibloader_orig_libudev
+#define udev_device_get_usec_since_initialized udev_device_get_usec_since_initialized_dylibloader_orig_libudev
+#define udev_device_get_sysattr_value udev_device_get_sysattr_value_dylibloader_orig_libudev
+#define udev_device_set_sysattr_value udev_device_set_sysattr_value_dylibloader_orig_libudev
+#define udev_device_has_tag udev_device_has_tag_dylibloader_orig_libudev
+#define udev_monitor_ref udev_monitor_ref_dylibloader_orig_libudev
+#define udev_monitor_unref udev_monitor_unref_dylibloader_orig_libudev
+#define udev_monitor_get_udev udev_monitor_get_udev_dylibloader_orig_libudev
+#define udev_monitor_new_from_netlink udev_monitor_new_from_netlink_dylibloader_orig_libudev
+#define udev_monitor_enable_receiving udev_monitor_enable_receiving_dylibloader_orig_libudev
+#define udev_monitor_set_receive_buffer_size udev_monitor_set_receive_buffer_size_dylibloader_orig_libudev
+#define udev_monitor_get_fd udev_monitor_get_fd_dylibloader_orig_libudev
+#define udev_monitor_receive_device udev_monitor_receive_device_dylibloader_orig_libudev
+#define udev_monitor_filter_add_match_subsystem_devtype udev_monitor_filter_add_match_subsystem_devtype_dylibloader_orig_libudev
+#define udev_monitor_filter_add_match_tag udev_monitor_filter_add_match_tag_dylibloader_orig_libudev
+#define udev_monitor_filter_update udev_monitor_filter_update_dylibloader_orig_libudev
+#define udev_monitor_filter_remove udev_monitor_filter_remove_dylibloader_orig_libudev
+#define udev_enumerate_ref udev_enumerate_ref_dylibloader_orig_libudev
+#define udev_enumerate_unref udev_enumerate_unref_dylibloader_orig_libudev
+#define udev_enumerate_get_udev udev_enumerate_get_udev_dylibloader_orig_libudev
+#define udev_enumerate_new udev_enumerate_new_dylibloader_orig_libudev
+#define udev_enumerate_add_match_subsystem udev_enumerate_add_match_subsystem_dylibloader_orig_libudev
+#define udev_enumerate_add_nomatch_subsystem udev_enumerate_add_nomatch_subsystem_dylibloader_orig_libudev
+#define udev_enumerate_add_match_sysattr udev_enumerate_add_match_sysattr_dylibloader_orig_libudev
+#define udev_enumerate_add_nomatch_sysattr udev_enumerate_add_nomatch_sysattr_dylibloader_orig_libudev
+#define udev_enumerate_add_match_property udev_enumerate_add_match_property_dylibloader_orig_libudev
+#define udev_enumerate_add_match_sysname udev_enumerate_add_match_sysname_dylibloader_orig_libudev
+#define udev_enumerate_add_match_tag udev_enumerate_add_match_tag_dylibloader_orig_libudev
+#define udev_enumerate_add_match_parent udev_enumerate_add_match_parent_dylibloader_orig_libudev
+#define udev_enumerate_add_match_is_initialized udev_enumerate_add_match_is_initialized_dylibloader_orig_libudev
+#define udev_enumerate_add_syspath udev_enumerate_add_syspath_dylibloader_orig_libudev
+#define udev_enumerate_scan_devices udev_enumerate_scan_devices_dylibloader_orig_libudev
+#define udev_enumerate_scan_subsystems udev_enumerate_scan_subsystems_dylibloader_orig_libudev
+#define udev_enumerate_get_list_entry udev_enumerate_get_list_entry_dylibloader_orig_libudev
+#define udev_queue_ref udev_queue_ref_dylibloader_orig_libudev
+#define udev_queue_unref udev_queue_unref_dylibloader_orig_libudev
+#define udev_queue_get_udev udev_queue_get_udev_dylibloader_orig_libudev
+#define udev_queue_new udev_queue_new_dylibloader_orig_libudev
+#define udev_queue_get_kernel_seqnum udev_queue_get_kernel_seqnum_dylibloader_orig_libudev
+#define udev_queue_get_udev_seqnum udev_queue_get_udev_seqnum_dylibloader_orig_libudev
+#define udev_queue_get_udev_is_active udev_queue_get_udev_is_active_dylibloader_orig_libudev
+#define udev_queue_get_queue_is_empty udev_queue_get_queue_is_empty_dylibloader_orig_libudev
+#define udev_queue_get_seqnum_is_finished udev_queue_get_seqnum_is_finished_dylibloader_orig_libudev
+#define udev_queue_get_seqnum_sequence_is_finished udev_queue_get_seqnum_sequence_is_finished_dylibloader_orig_libudev
+#define udev_queue_get_fd udev_queue_get_fd_dylibloader_orig_libudev
+#define udev_queue_flush udev_queue_flush_dylibloader_orig_libudev
+#define udev_queue_get_queued_list_entry udev_queue_get_queued_list_entry_dylibloader_orig_libudev
+#define udev_hwdb_new udev_hwdb_new_dylibloader_orig_libudev
+#define udev_hwdb_ref udev_hwdb_ref_dylibloader_orig_libudev
+#define udev_hwdb_unref udev_hwdb_unref_dylibloader_orig_libudev
+#define udev_hwdb_get_properties_list_entry udev_hwdb_get_properties_list_entry_dylibloader_orig_libudev
+#define udev_util_encode_string udev_util_encode_string_dylibloader_orig_libudev
+#include <libudev.h>
+#undef udev_ref
+#undef udev_unref
+#undef udev_new
+#undef udev_set_log_fn
+#undef udev_get_log_priority
+#undef udev_set_log_priority
+#undef udev_get_userdata
+#undef udev_set_userdata
+#undef udev_list_entry_get_next
+#undef udev_list_entry_get_by_name
+#undef udev_list_entry_get_name
+#undef udev_list_entry_get_value
+#undef udev_device_ref
+#undef udev_device_unref
+#undef udev_device_get_udev
+#undef udev_device_new_from_syspath
+#undef udev_device_new_from_devnum
+#undef udev_device_new_from_subsystem_sysname
+#undef udev_device_new_from_device_id
+#undef udev_device_new_from_environment
+#undef udev_device_get_parent
+#undef udev_device_get_parent_with_subsystem_devtype
+#undef udev_device_get_devpath
+#undef udev_device_get_subsystem
+#undef udev_device_get_devtype
+#undef udev_device_get_syspath
+#undef udev_device_get_sysname
+#undef udev_device_get_sysnum
+#undef udev_device_get_devnode
+#undef udev_device_get_is_initialized
+#undef udev_device_get_devlinks_list_entry
+#undef udev_device_get_properties_list_entry
+#undef udev_device_get_tags_list_entry
+#undef udev_device_get_sysattr_list_entry
+#undef udev_device_get_property_value
+#undef udev_device_get_driver
+#undef udev_device_get_devnum
+#undef udev_device_get_action
+#undef udev_device_get_seqnum
+#undef udev_device_get_usec_since_initialized
+#undef udev_device_get_sysattr_value
+#undef udev_device_set_sysattr_value
+#undef udev_device_has_tag
+#undef udev_monitor_ref
+#undef udev_monitor_unref
+#undef udev_monitor_get_udev
+#undef udev_monitor_new_from_netlink
+#undef udev_monitor_enable_receiving
+#undef udev_monitor_set_receive_buffer_size
+#undef udev_monitor_get_fd
+#undef udev_monitor_receive_device
+#undef udev_monitor_filter_add_match_subsystem_devtype
+#undef udev_monitor_filter_add_match_tag
+#undef udev_monitor_filter_update
+#undef udev_monitor_filter_remove
+#undef udev_enumerate_ref
+#undef udev_enumerate_unref
+#undef udev_enumerate_get_udev
+#undef udev_enumerate_new
+#undef udev_enumerate_add_match_subsystem
+#undef udev_enumerate_add_nomatch_subsystem
+#undef udev_enumerate_add_match_sysattr
+#undef udev_enumerate_add_nomatch_sysattr
+#undef udev_enumerate_add_match_property
+#undef udev_enumerate_add_match_sysname
+#undef udev_enumerate_add_match_tag
+#undef udev_enumerate_add_match_parent
+#undef udev_enumerate_add_match_is_initialized
+#undef udev_enumerate_add_syspath
+#undef udev_enumerate_scan_devices
+#undef udev_enumerate_scan_subsystems
+#undef udev_enumerate_get_list_entry
+#undef udev_queue_ref
+#undef udev_queue_unref
+#undef udev_queue_get_udev
+#undef udev_queue_new
+#undef udev_queue_get_kernel_seqnum
+#undef udev_queue_get_udev_seqnum
+#undef udev_queue_get_udev_is_active
+#undef udev_queue_get_queue_is_empty
+#undef udev_queue_get_seqnum_is_finished
+#undef udev_queue_get_seqnum_sequence_is_finished
+#undef udev_queue_get_fd
+#undef udev_queue_flush
+#undef udev_queue_get_queued_list_entry
+#undef udev_hwdb_new
+#undef udev_hwdb_ref
+#undef udev_hwdb_unref
+#undef udev_hwdb_get_properties_list_entry
+#undef udev_util_encode_string
+#include <dlfcn.h>
+#include <stdio.h>
+struct udev* (*udev_ref_dylibloader_wrapper_libudev)(struct udev*);
+struct udev* (*udev_unref_dylibloader_wrapper_libudev)(struct udev*);
+struct udev* (*udev_new_dylibloader_wrapper_libudev)( void);
+void (*udev_set_log_fn_dylibloader_wrapper_libudev)(struct udev*, void*);
+int (*udev_get_log_priority_dylibloader_wrapper_libudev)(struct udev*);
+void (*udev_set_log_priority_dylibloader_wrapper_libudev)(struct udev*, int);
+void* (*udev_get_userdata_dylibloader_wrapper_libudev)(struct udev*);
+void (*udev_set_userdata_dylibloader_wrapper_libudev)(struct udev*, void*);
+struct udev_list_entry* (*udev_list_entry_get_next_dylibloader_wrapper_libudev)(struct udev_list_entry*);
+struct udev_list_entry* (*udev_list_entry_get_by_name_dylibloader_wrapper_libudev)(struct udev_list_entry*,const char*);
+const char* (*udev_list_entry_get_name_dylibloader_wrapper_libudev)(struct udev_list_entry*);
+const char* (*udev_list_entry_get_value_dylibloader_wrapper_libudev)(struct udev_list_entry*);
+struct udev_device* (*udev_device_ref_dylibloader_wrapper_libudev)(struct udev_device*);
+struct udev_device* (*udev_device_unref_dylibloader_wrapper_libudev)(struct udev_device*);
+struct udev* (*udev_device_get_udev_dylibloader_wrapper_libudev)(struct udev_device*);
+struct udev_device* (*udev_device_new_from_syspath_dylibloader_wrapper_libudev)(struct udev*,const char*);
+struct udev_device* (*udev_device_new_from_devnum_dylibloader_wrapper_libudev)(struct udev*, char, dev_t);
+struct udev_device* (*udev_device_new_from_subsystem_sysname_dylibloader_wrapper_libudev)(struct udev*,const char*,const char*);
+struct udev_device* (*udev_device_new_from_device_id_dylibloader_wrapper_libudev)(struct udev*,const char*);
+struct udev_device* (*udev_device_new_from_environment_dylibloader_wrapper_libudev)(struct udev*);
+struct udev_device* (*udev_device_get_parent_dylibloader_wrapper_libudev)(struct udev_device*);
+struct udev_device* (*udev_device_get_parent_with_subsystem_devtype_dylibloader_wrapper_libudev)(struct udev_device*,const char*,const char*);
+const char* (*udev_device_get_devpath_dylibloader_wrapper_libudev)(struct udev_device*);
+const char* (*udev_device_get_subsystem_dylibloader_wrapper_libudev)(struct udev_device*);
+const char* (*udev_device_get_devtype_dylibloader_wrapper_libudev)(struct udev_device*);
+const char* (*udev_device_get_syspath_dylibloader_wrapper_libudev)(struct udev_device*);
+const char* (*udev_device_get_sysname_dylibloader_wrapper_libudev)(struct udev_device*);
+const char* (*udev_device_get_sysnum_dylibloader_wrapper_libudev)(struct udev_device*);
+const char* (*udev_device_get_devnode_dylibloader_wrapper_libudev)(struct udev_device*);
+int (*udev_device_get_is_initialized_dylibloader_wrapper_libudev)(struct udev_device*);
+struct udev_list_entry* (*udev_device_get_devlinks_list_entry_dylibloader_wrapper_libudev)(struct udev_device*);
+struct udev_list_entry* (*udev_device_get_properties_list_entry_dylibloader_wrapper_libudev)(struct udev_device*);
+struct udev_list_entry* (*udev_device_get_tags_list_entry_dylibloader_wrapper_libudev)(struct udev_device*);
+struct udev_list_entry* (*udev_device_get_sysattr_list_entry_dylibloader_wrapper_libudev)(struct udev_device*);
+const char* (*udev_device_get_property_value_dylibloader_wrapper_libudev)(struct udev_device*,const char*);
+const char* (*udev_device_get_driver_dylibloader_wrapper_libudev)(struct udev_device*);
+dev_t (*udev_device_get_devnum_dylibloader_wrapper_libudev)(struct udev_device*);
+const char* (*udev_device_get_action_dylibloader_wrapper_libudev)(struct udev_device*);
+unsigned long long int (*udev_device_get_seqnum_dylibloader_wrapper_libudev)(struct udev_device*);
+unsigned long long int (*udev_device_get_usec_since_initialized_dylibloader_wrapper_libudev)(struct udev_device*);
+const char* (*udev_device_get_sysattr_value_dylibloader_wrapper_libudev)(struct udev_device*,const char*);
+int (*udev_device_set_sysattr_value_dylibloader_wrapper_libudev)(struct udev_device*,const char*,const char*);
+int (*udev_device_has_tag_dylibloader_wrapper_libudev)(struct udev_device*,const char*);
+struct udev_monitor* (*udev_monitor_ref_dylibloader_wrapper_libudev)(struct udev_monitor*);
+struct udev_monitor* (*udev_monitor_unref_dylibloader_wrapper_libudev)(struct udev_monitor*);
+struct udev* (*udev_monitor_get_udev_dylibloader_wrapper_libudev)(struct udev_monitor*);
+struct udev_monitor* (*udev_monitor_new_from_netlink_dylibloader_wrapper_libudev)(struct udev*,const char*);
+int (*udev_monitor_enable_receiving_dylibloader_wrapper_libudev)(struct udev_monitor*);
+int (*udev_monitor_set_receive_buffer_size_dylibloader_wrapper_libudev)(struct udev_monitor*, int);
+int (*udev_monitor_get_fd_dylibloader_wrapper_libudev)(struct udev_monitor*);
+struct udev_device* (*udev_monitor_receive_device_dylibloader_wrapper_libudev)(struct udev_monitor*);
+int (*udev_monitor_filter_add_match_subsystem_devtype_dylibloader_wrapper_libudev)(struct udev_monitor*,const char*,const char*);
+int (*udev_monitor_filter_add_match_tag_dylibloader_wrapper_libudev)(struct udev_monitor*,const char*);
+int (*udev_monitor_filter_update_dylibloader_wrapper_libudev)(struct udev_monitor*);
+int (*udev_monitor_filter_remove_dylibloader_wrapper_libudev)(struct udev_monitor*);
+struct udev_enumerate* (*udev_enumerate_ref_dylibloader_wrapper_libudev)(struct udev_enumerate*);
+struct udev_enumerate* (*udev_enumerate_unref_dylibloader_wrapper_libudev)(struct udev_enumerate*);
+struct udev* (*udev_enumerate_get_udev_dylibloader_wrapper_libudev)(struct udev_enumerate*);
+struct udev_enumerate* (*udev_enumerate_new_dylibloader_wrapper_libudev)(struct udev*);
+int (*udev_enumerate_add_match_subsystem_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*);
+int (*udev_enumerate_add_nomatch_subsystem_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*);
+int (*udev_enumerate_add_match_sysattr_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*,const char*);
+int (*udev_enumerate_add_nomatch_sysattr_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*,const char*);
+int (*udev_enumerate_add_match_property_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*,const char*);
+int (*udev_enumerate_add_match_sysname_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*);
+int (*udev_enumerate_add_match_tag_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*);
+int (*udev_enumerate_add_match_parent_dylibloader_wrapper_libudev)(struct udev_enumerate*,struct udev_device*);
+int (*udev_enumerate_add_match_is_initialized_dylibloader_wrapper_libudev)(struct udev_enumerate*);
+int (*udev_enumerate_add_syspath_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*);
+int (*udev_enumerate_scan_devices_dylibloader_wrapper_libudev)(struct udev_enumerate*);
+int (*udev_enumerate_scan_subsystems_dylibloader_wrapper_libudev)(struct udev_enumerate*);
+struct udev_list_entry* (*udev_enumerate_get_list_entry_dylibloader_wrapper_libudev)(struct udev_enumerate*);
+struct udev_queue* (*udev_queue_ref_dylibloader_wrapper_libudev)(struct udev_queue*);
+struct udev_queue* (*udev_queue_unref_dylibloader_wrapper_libudev)(struct udev_queue*);
+struct udev* (*udev_queue_get_udev_dylibloader_wrapper_libudev)(struct udev_queue*);
+struct udev_queue* (*udev_queue_new_dylibloader_wrapper_libudev)(struct udev*);
+unsigned long long int (*udev_queue_get_kernel_seqnum_dylibloader_wrapper_libudev)(struct udev_queue*);
+unsigned long long int (*udev_queue_get_udev_seqnum_dylibloader_wrapper_libudev)(struct udev_queue*);
+int (*udev_queue_get_udev_is_active_dylibloader_wrapper_libudev)(struct udev_queue*);
+int (*udev_queue_get_queue_is_empty_dylibloader_wrapper_libudev)(struct udev_queue*);
+int (*udev_queue_get_seqnum_is_finished_dylibloader_wrapper_libudev)(struct udev_queue*, unsigned long long int);
+int (*udev_queue_get_seqnum_sequence_is_finished_dylibloader_wrapper_libudev)(struct udev_queue*, unsigned long long int, unsigned long long int);
+int (*udev_queue_get_fd_dylibloader_wrapper_libudev)(struct udev_queue*);
+int (*udev_queue_flush_dylibloader_wrapper_libudev)(struct udev_queue*);
+struct udev_list_entry* (*udev_queue_get_queued_list_entry_dylibloader_wrapper_libudev)(struct udev_queue*);
+struct udev_hwdb* (*udev_hwdb_new_dylibloader_wrapper_libudev)(struct udev*);
+struct udev_hwdb* (*udev_hwdb_ref_dylibloader_wrapper_libudev)(struct udev_hwdb*);
+struct udev_hwdb* (*udev_hwdb_unref_dylibloader_wrapper_libudev)(struct udev_hwdb*);
+struct udev_list_entry* (*udev_hwdb_get_properties_list_entry_dylibloader_wrapper_libudev)(struct udev_hwdb*,const char*, unsigned);
+int (*udev_util_encode_string_dylibloader_wrapper_libudev)(const char*, char*, size_t);
+int initialize_libudev(int verbose) {
+ void *handle;
+ char *error;
+ handle = dlopen("libudev.so.1", RTLD_LAZY);
+ if (!handle) {
+ if (verbose) {
+ fprintf(stderr, "%s\n", dlerror());
+ }
+ return(1);
+ }
+ dlerror();
+// udev_ref
+ *(void **) (&udev_ref_dylibloader_wrapper_libudev) = dlsym(handle, "udev_ref");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_unref
+ *(void **) (&udev_unref_dylibloader_wrapper_libudev) = dlsym(handle, "udev_unref");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_new
+ *(void **) (&udev_new_dylibloader_wrapper_libudev) = dlsym(handle, "udev_new");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_set_log_fn
+ *(void **) (&udev_set_log_fn_dylibloader_wrapper_libudev) = dlsym(handle, "udev_set_log_fn");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_get_log_priority
+ *(void **) (&udev_get_log_priority_dylibloader_wrapper_libudev) = dlsym(handle, "udev_get_log_priority");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_set_log_priority
+ *(void **) (&udev_set_log_priority_dylibloader_wrapper_libudev) = dlsym(handle, "udev_set_log_priority");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_get_userdata
+ *(void **) (&udev_get_userdata_dylibloader_wrapper_libudev) = dlsym(handle, "udev_get_userdata");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_set_userdata
+ *(void **) (&udev_set_userdata_dylibloader_wrapper_libudev) = dlsym(handle, "udev_set_userdata");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_list_entry_get_next
+ *(void **) (&udev_list_entry_get_next_dylibloader_wrapper_libudev) = dlsym(handle, "udev_list_entry_get_next");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_list_entry_get_by_name
+ *(void **) (&udev_list_entry_get_by_name_dylibloader_wrapper_libudev) = dlsym(handle, "udev_list_entry_get_by_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_list_entry_get_name
+ *(void **) (&udev_list_entry_get_name_dylibloader_wrapper_libudev) = dlsym(handle, "udev_list_entry_get_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_list_entry_get_value
+ *(void **) (&udev_list_entry_get_value_dylibloader_wrapper_libudev) = dlsym(handle, "udev_list_entry_get_value");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_ref
+ *(void **) (&udev_device_ref_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_ref");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_unref
+ *(void **) (&udev_device_unref_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_unref");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_get_udev
+ *(void **) (&udev_device_get_udev_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_udev");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_new_from_syspath
+ *(void **) (&udev_device_new_from_syspath_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_new_from_syspath");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_new_from_devnum
+ *(void **) (&udev_device_new_from_devnum_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_new_from_devnum");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_new_from_subsystem_sysname
+ *(void **) (&udev_device_new_from_subsystem_sysname_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_new_from_subsystem_sysname");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_new_from_device_id
+ *(void **) (&udev_device_new_from_device_id_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_new_from_device_id");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_new_from_environment
+ *(void **) (&udev_device_new_from_environment_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_new_from_environment");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_get_parent
+ *(void **) (&udev_device_get_parent_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_parent");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_get_parent_with_subsystem_devtype
+ *(void **) (&udev_device_get_parent_with_subsystem_devtype_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_parent_with_subsystem_devtype");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_get_devpath
+ *(void **) (&udev_device_get_devpath_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_devpath");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_get_subsystem
+ *(void **) (&udev_device_get_subsystem_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_subsystem");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_get_devtype
+ *(void **) (&udev_device_get_devtype_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_devtype");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_get_syspath
+ *(void **) (&udev_device_get_syspath_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_syspath");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_get_sysname
+ *(void **) (&udev_device_get_sysname_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_sysname");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_get_sysnum
+ *(void **) (&udev_device_get_sysnum_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_sysnum");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_get_devnode
+ *(void **) (&udev_device_get_devnode_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_devnode");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_get_is_initialized
+ *(void **) (&udev_device_get_is_initialized_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_is_initialized");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_get_devlinks_list_entry
+ *(void **) (&udev_device_get_devlinks_list_entry_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_devlinks_list_entry");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_get_properties_list_entry
+ *(void **) (&udev_device_get_properties_list_entry_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_properties_list_entry");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_get_tags_list_entry
+ *(void **) (&udev_device_get_tags_list_entry_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_tags_list_entry");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_get_sysattr_list_entry
+ *(void **) (&udev_device_get_sysattr_list_entry_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_sysattr_list_entry");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_get_property_value
+ *(void **) (&udev_device_get_property_value_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_property_value");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_get_driver
+ *(void **) (&udev_device_get_driver_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_driver");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_get_devnum
+ *(void **) (&udev_device_get_devnum_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_devnum");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_get_action
+ *(void **) (&udev_device_get_action_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_action");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_get_seqnum
+ *(void **) (&udev_device_get_seqnum_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_seqnum");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_get_usec_since_initialized
+ *(void **) (&udev_device_get_usec_since_initialized_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_usec_since_initialized");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_get_sysattr_value
+ *(void **) (&udev_device_get_sysattr_value_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_sysattr_value");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_set_sysattr_value
+ *(void **) (&udev_device_set_sysattr_value_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_set_sysattr_value");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_has_tag
+ *(void **) (&udev_device_has_tag_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_has_tag");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_monitor_ref
+ *(void **) (&udev_monitor_ref_dylibloader_wrapper_libudev) = dlsym(handle, "udev_monitor_ref");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_monitor_unref
+ *(void **) (&udev_monitor_unref_dylibloader_wrapper_libudev) = dlsym(handle, "udev_monitor_unref");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_monitor_get_udev
+ *(void **) (&udev_monitor_get_udev_dylibloader_wrapper_libudev) = dlsym(handle, "udev_monitor_get_udev");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_monitor_new_from_netlink
+ *(void **) (&udev_monitor_new_from_netlink_dylibloader_wrapper_libudev) = dlsym(handle, "udev_monitor_new_from_netlink");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_monitor_enable_receiving
+ *(void **) (&udev_monitor_enable_receiving_dylibloader_wrapper_libudev) = dlsym(handle, "udev_monitor_enable_receiving");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_monitor_set_receive_buffer_size
+ *(void **) (&udev_monitor_set_receive_buffer_size_dylibloader_wrapper_libudev) = dlsym(handle, "udev_monitor_set_receive_buffer_size");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_monitor_get_fd
+ *(void **) (&udev_monitor_get_fd_dylibloader_wrapper_libudev) = dlsym(handle, "udev_monitor_get_fd");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_monitor_receive_device
+ *(void **) (&udev_monitor_receive_device_dylibloader_wrapper_libudev) = dlsym(handle, "udev_monitor_receive_device");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_monitor_filter_add_match_subsystem_devtype
+ *(void **) (&udev_monitor_filter_add_match_subsystem_devtype_dylibloader_wrapper_libudev) = dlsym(handle, "udev_monitor_filter_add_match_subsystem_devtype");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_monitor_filter_add_match_tag
+ *(void **) (&udev_monitor_filter_add_match_tag_dylibloader_wrapper_libudev) = dlsym(handle, "udev_monitor_filter_add_match_tag");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_monitor_filter_update
+ *(void **) (&udev_monitor_filter_update_dylibloader_wrapper_libudev) = dlsym(handle, "udev_monitor_filter_update");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_monitor_filter_remove
+ *(void **) (&udev_monitor_filter_remove_dylibloader_wrapper_libudev) = dlsym(handle, "udev_monitor_filter_remove");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_enumerate_ref
+ *(void **) (&udev_enumerate_ref_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_ref");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_enumerate_unref
+ *(void **) (&udev_enumerate_unref_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_unref");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_enumerate_get_udev
+ *(void **) (&udev_enumerate_get_udev_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_get_udev");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_enumerate_new
+ *(void **) (&udev_enumerate_new_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_new");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_enumerate_add_match_subsystem
+ *(void **) (&udev_enumerate_add_match_subsystem_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_add_match_subsystem");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_enumerate_add_nomatch_subsystem
+ *(void **) (&udev_enumerate_add_nomatch_subsystem_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_add_nomatch_subsystem");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_enumerate_add_match_sysattr
+ *(void **) (&udev_enumerate_add_match_sysattr_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_add_match_sysattr");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_enumerate_add_nomatch_sysattr
+ *(void **) (&udev_enumerate_add_nomatch_sysattr_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_add_nomatch_sysattr");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_enumerate_add_match_property
+ *(void **) (&udev_enumerate_add_match_property_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_add_match_property");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_enumerate_add_match_sysname
+ *(void **) (&udev_enumerate_add_match_sysname_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_add_match_sysname");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_enumerate_add_match_tag
+ *(void **) (&udev_enumerate_add_match_tag_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_add_match_tag");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_enumerate_add_match_parent
+ *(void **) (&udev_enumerate_add_match_parent_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_add_match_parent");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_enumerate_add_match_is_initialized
+ *(void **) (&udev_enumerate_add_match_is_initialized_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_add_match_is_initialized");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_enumerate_add_syspath
+ *(void **) (&udev_enumerate_add_syspath_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_add_syspath");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_enumerate_scan_devices
+ *(void **) (&udev_enumerate_scan_devices_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_scan_devices");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_enumerate_scan_subsystems
+ *(void **) (&udev_enumerate_scan_subsystems_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_scan_subsystems");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_enumerate_get_list_entry
+ *(void **) (&udev_enumerate_get_list_entry_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_get_list_entry");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_queue_ref
+ *(void **) (&udev_queue_ref_dylibloader_wrapper_libudev) = dlsym(handle, "udev_queue_ref");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_queue_unref
+ *(void **) (&udev_queue_unref_dylibloader_wrapper_libudev) = dlsym(handle, "udev_queue_unref");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_queue_get_udev
+ *(void **) (&udev_queue_get_udev_dylibloader_wrapper_libudev) = dlsym(handle, "udev_queue_get_udev");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_queue_new
+ *(void **) (&udev_queue_new_dylibloader_wrapper_libudev) = dlsym(handle, "udev_queue_new");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_queue_get_kernel_seqnum
+ *(void **) (&udev_queue_get_kernel_seqnum_dylibloader_wrapper_libudev) = dlsym(handle, "udev_queue_get_kernel_seqnum");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_queue_get_udev_seqnum
+ *(void **) (&udev_queue_get_udev_seqnum_dylibloader_wrapper_libudev) = dlsym(handle, "udev_queue_get_udev_seqnum");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_queue_get_udev_is_active
+ *(void **) (&udev_queue_get_udev_is_active_dylibloader_wrapper_libudev) = dlsym(handle, "udev_queue_get_udev_is_active");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_queue_get_queue_is_empty
+ *(void **) (&udev_queue_get_queue_is_empty_dylibloader_wrapper_libudev) = dlsym(handle, "udev_queue_get_queue_is_empty");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_queue_get_seqnum_is_finished
+ *(void **) (&udev_queue_get_seqnum_is_finished_dylibloader_wrapper_libudev) = dlsym(handle, "udev_queue_get_seqnum_is_finished");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_queue_get_seqnum_sequence_is_finished
+ *(void **) (&udev_queue_get_seqnum_sequence_is_finished_dylibloader_wrapper_libudev) = dlsym(handle, "udev_queue_get_seqnum_sequence_is_finished");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_queue_get_fd
+ *(void **) (&udev_queue_get_fd_dylibloader_wrapper_libudev) = dlsym(handle, "udev_queue_get_fd");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_queue_flush
+ *(void **) (&udev_queue_flush_dylibloader_wrapper_libudev) = dlsym(handle, "udev_queue_flush");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_queue_get_queued_list_entry
+ *(void **) (&udev_queue_get_queued_list_entry_dylibloader_wrapper_libudev) = dlsym(handle, "udev_queue_get_queued_list_entry");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_hwdb_new
+ *(void **) (&udev_hwdb_new_dylibloader_wrapper_libudev) = dlsym(handle, "udev_hwdb_new");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_hwdb_ref
+ *(void **) (&udev_hwdb_ref_dylibloader_wrapper_libudev) = dlsym(handle, "udev_hwdb_ref");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_hwdb_unref
+ *(void **) (&udev_hwdb_unref_dylibloader_wrapper_libudev) = dlsym(handle, "udev_hwdb_unref");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_hwdb_get_properties_list_entry
+ *(void **) (&udev_hwdb_get_properties_list_entry_dylibloader_wrapper_libudev) = dlsym(handle, "udev_hwdb_get_properties_list_entry");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_util_encode_string
+ *(void **) (&udev_util_encode_string_dylibloader_wrapper_libudev) = dlsym(handle, "udev_util_encode_string");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+return 0;
+}
diff --git a/platform/linuxbsd/libudev-so_wrap.h b/platform/linuxbsd/libudev-so_wrap.h
new file mode 100644
index 0000000000..dd43fd1191
--- /dev/null
+++ b/platform/linuxbsd/libudev-so_wrap.h
@@ -0,0 +1,378 @@
+#ifndef DYLIBLOAD_WRAPPER_LIBUDEV
+#define DYLIBLOAD_WRAPPER_LIBUDEV
+// This file is generated. Do not edit!
+// see https://github.com/hpvb/dynload-wrapper for details
+// generated by /home/hp/Projects/godot/pulse/generate-wrapper.py 0.3 on 2021-02-20 00:08:59
+// flags: /home/hp/Projects/godot/pulse/generate-wrapper.py --include /usr/include/libudev.h --sys-include <libudev.h> --soname libudev.so.1 --init-name libudev --omit-prefix gnu_ --output-header libudev-so_wrap.h --output-implementation libudev-so_wrap.c
+//
+#include <stdint.h>
+
+#define udev_ref udev_ref_dylibloader_orig_libudev
+#define udev_unref udev_unref_dylibloader_orig_libudev
+#define udev_new udev_new_dylibloader_orig_libudev
+#define udev_set_log_fn udev_set_log_fn_dylibloader_orig_libudev
+#define udev_get_log_priority udev_get_log_priority_dylibloader_orig_libudev
+#define udev_set_log_priority udev_set_log_priority_dylibloader_orig_libudev
+#define udev_get_userdata udev_get_userdata_dylibloader_orig_libudev
+#define udev_set_userdata udev_set_userdata_dylibloader_orig_libudev
+#define udev_list_entry_get_next udev_list_entry_get_next_dylibloader_orig_libudev
+#define udev_list_entry_get_by_name udev_list_entry_get_by_name_dylibloader_orig_libudev
+#define udev_list_entry_get_name udev_list_entry_get_name_dylibloader_orig_libudev
+#define udev_list_entry_get_value udev_list_entry_get_value_dylibloader_orig_libudev
+#define udev_device_ref udev_device_ref_dylibloader_orig_libudev
+#define udev_device_unref udev_device_unref_dylibloader_orig_libudev
+#define udev_device_get_udev udev_device_get_udev_dylibloader_orig_libudev
+#define udev_device_new_from_syspath udev_device_new_from_syspath_dylibloader_orig_libudev
+#define udev_device_new_from_devnum udev_device_new_from_devnum_dylibloader_orig_libudev
+#define udev_device_new_from_subsystem_sysname udev_device_new_from_subsystem_sysname_dylibloader_orig_libudev
+#define udev_device_new_from_device_id udev_device_new_from_device_id_dylibloader_orig_libudev
+#define udev_device_new_from_environment udev_device_new_from_environment_dylibloader_orig_libudev
+#define udev_device_get_parent udev_device_get_parent_dylibloader_orig_libudev
+#define udev_device_get_parent_with_subsystem_devtype udev_device_get_parent_with_subsystem_devtype_dylibloader_orig_libudev
+#define udev_device_get_devpath udev_device_get_devpath_dylibloader_orig_libudev
+#define udev_device_get_subsystem udev_device_get_subsystem_dylibloader_orig_libudev
+#define udev_device_get_devtype udev_device_get_devtype_dylibloader_orig_libudev
+#define udev_device_get_syspath udev_device_get_syspath_dylibloader_orig_libudev
+#define udev_device_get_sysname udev_device_get_sysname_dylibloader_orig_libudev
+#define udev_device_get_sysnum udev_device_get_sysnum_dylibloader_orig_libudev
+#define udev_device_get_devnode udev_device_get_devnode_dylibloader_orig_libudev
+#define udev_device_get_is_initialized udev_device_get_is_initialized_dylibloader_orig_libudev
+#define udev_device_get_devlinks_list_entry udev_device_get_devlinks_list_entry_dylibloader_orig_libudev
+#define udev_device_get_properties_list_entry udev_device_get_properties_list_entry_dylibloader_orig_libudev
+#define udev_device_get_tags_list_entry udev_device_get_tags_list_entry_dylibloader_orig_libudev
+#define udev_device_get_sysattr_list_entry udev_device_get_sysattr_list_entry_dylibloader_orig_libudev
+#define udev_device_get_property_value udev_device_get_property_value_dylibloader_orig_libudev
+#define udev_device_get_driver udev_device_get_driver_dylibloader_orig_libudev
+#define udev_device_get_devnum udev_device_get_devnum_dylibloader_orig_libudev
+#define udev_device_get_action udev_device_get_action_dylibloader_orig_libudev
+#define udev_device_get_seqnum udev_device_get_seqnum_dylibloader_orig_libudev
+#define udev_device_get_usec_since_initialized udev_device_get_usec_since_initialized_dylibloader_orig_libudev
+#define udev_device_get_sysattr_value udev_device_get_sysattr_value_dylibloader_orig_libudev
+#define udev_device_set_sysattr_value udev_device_set_sysattr_value_dylibloader_orig_libudev
+#define udev_device_has_tag udev_device_has_tag_dylibloader_orig_libudev
+#define udev_monitor_ref udev_monitor_ref_dylibloader_orig_libudev
+#define udev_monitor_unref udev_monitor_unref_dylibloader_orig_libudev
+#define udev_monitor_get_udev udev_monitor_get_udev_dylibloader_orig_libudev
+#define udev_monitor_new_from_netlink udev_monitor_new_from_netlink_dylibloader_orig_libudev
+#define udev_monitor_enable_receiving udev_monitor_enable_receiving_dylibloader_orig_libudev
+#define udev_monitor_set_receive_buffer_size udev_monitor_set_receive_buffer_size_dylibloader_orig_libudev
+#define udev_monitor_get_fd udev_monitor_get_fd_dylibloader_orig_libudev
+#define udev_monitor_receive_device udev_monitor_receive_device_dylibloader_orig_libudev
+#define udev_monitor_filter_add_match_subsystem_devtype udev_monitor_filter_add_match_subsystem_devtype_dylibloader_orig_libudev
+#define udev_monitor_filter_add_match_tag udev_monitor_filter_add_match_tag_dylibloader_orig_libudev
+#define udev_monitor_filter_update udev_monitor_filter_update_dylibloader_orig_libudev
+#define udev_monitor_filter_remove udev_monitor_filter_remove_dylibloader_orig_libudev
+#define udev_enumerate_ref udev_enumerate_ref_dylibloader_orig_libudev
+#define udev_enumerate_unref udev_enumerate_unref_dylibloader_orig_libudev
+#define udev_enumerate_get_udev udev_enumerate_get_udev_dylibloader_orig_libudev
+#define udev_enumerate_new udev_enumerate_new_dylibloader_orig_libudev
+#define udev_enumerate_add_match_subsystem udev_enumerate_add_match_subsystem_dylibloader_orig_libudev
+#define udev_enumerate_add_nomatch_subsystem udev_enumerate_add_nomatch_subsystem_dylibloader_orig_libudev
+#define udev_enumerate_add_match_sysattr udev_enumerate_add_match_sysattr_dylibloader_orig_libudev
+#define udev_enumerate_add_nomatch_sysattr udev_enumerate_add_nomatch_sysattr_dylibloader_orig_libudev
+#define udev_enumerate_add_match_property udev_enumerate_add_match_property_dylibloader_orig_libudev
+#define udev_enumerate_add_match_sysname udev_enumerate_add_match_sysname_dylibloader_orig_libudev
+#define udev_enumerate_add_match_tag udev_enumerate_add_match_tag_dylibloader_orig_libudev
+#define udev_enumerate_add_match_parent udev_enumerate_add_match_parent_dylibloader_orig_libudev
+#define udev_enumerate_add_match_is_initialized udev_enumerate_add_match_is_initialized_dylibloader_orig_libudev
+#define udev_enumerate_add_syspath udev_enumerate_add_syspath_dylibloader_orig_libudev
+#define udev_enumerate_scan_devices udev_enumerate_scan_devices_dylibloader_orig_libudev
+#define udev_enumerate_scan_subsystems udev_enumerate_scan_subsystems_dylibloader_orig_libudev
+#define udev_enumerate_get_list_entry udev_enumerate_get_list_entry_dylibloader_orig_libudev
+#define udev_queue_ref udev_queue_ref_dylibloader_orig_libudev
+#define udev_queue_unref udev_queue_unref_dylibloader_orig_libudev
+#define udev_queue_get_udev udev_queue_get_udev_dylibloader_orig_libudev
+#define udev_queue_new udev_queue_new_dylibloader_orig_libudev
+#define udev_queue_get_kernel_seqnum udev_queue_get_kernel_seqnum_dylibloader_orig_libudev
+#define udev_queue_get_udev_seqnum udev_queue_get_udev_seqnum_dylibloader_orig_libudev
+#define udev_queue_get_udev_is_active udev_queue_get_udev_is_active_dylibloader_orig_libudev
+#define udev_queue_get_queue_is_empty udev_queue_get_queue_is_empty_dylibloader_orig_libudev
+#define udev_queue_get_seqnum_is_finished udev_queue_get_seqnum_is_finished_dylibloader_orig_libudev
+#define udev_queue_get_seqnum_sequence_is_finished udev_queue_get_seqnum_sequence_is_finished_dylibloader_orig_libudev
+#define udev_queue_get_fd udev_queue_get_fd_dylibloader_orig_libudev
+#define udev_queue_flush udev_queue_flush_dylibloader_orig_libudev
+#define udev_queue_get_queued_list_entry udev_queue_get_queued_list_entry_dylibloader_orig_libudev
+#define udev_hwdb_new udev_hwdb_new_dylibloader_orig_libudev
+#define udev_hwdb_ref udev_hwdb_ref_dylibloader_orig_libudev
+#define udev_hwdb_unref udev_hwdb_unref_dylibloader_orig_libudev
+#define udev_hwdb_get_properties_list_entry udev_hwdb_get_properties_list_entry_dylibloader_orig_libudev
+#define udev_util_encode_string udev_util_encode_string_dylibloader_orig_libudev
+#include <libudev.h>
+#undef udev_ref
+#undef udev_unref
+#undef udev_new
+#undef udev_set_log_fn
+#undef udev_get_log_priority
+#undef udev_set_log_priority
+#undef udev_get_userdata
+#undef udev_set_userdata
+#undef udev_list_entry_get_next
+#undef udev_list_entry_get_by_name
+#undef udev_list_entry_get_name
+#undef udev_list_entry_get_value
+#undef udev_device_ref
+#undef udev_device_unref
+#undef udev_device_get_udev
+#undef udev_device_new_from_syspath
+#undef udev_device_new_from_devnum
+#undef udev_device_new_from_subsystem_sysname
+#undef udev_device_new_from_device_id
+#undef udev_device_new_from_environment
+#undef udev_device_get_parent
+#undef udev_device_get_parent_with_subsystem_devtype
+#undef udev_device_get_devpath
+#undef udev_device_get_subsystem
+#undef udev_device_get_devtype
+#undef udev_device_get_syspath
+#undef udev_device_get_sysname
+#undef udev_device_get_sysnum
+#undef udev_device_get_devnode
+#undef udev_device_get_is_initialized
+#undef udev_device_get_devlinks_list_entry
+#undef udev_device_get_properties_list_entry
+#undef udev_device_get_tags_list_entry
+#undef udev_device_get_sysattr_list_entry
+#undef udev_device_get_property_value
+#undef udev_device_get_driver
+#undef udev_device_get_devnum
+#undef udev_device_get_action
+#undef udev_device_get_seqnum
+#undef udev_device_get_usec_since_initialized
+#undef udev_device_get_sysattr_value
+#undef udev_device_set_sysattr_value
+#undef udev_device_has_tag
+#undef udev_monitor_ref
+#undef udev_monitor_unref
+#undef udev_monitor_get_udev
+#undef udev_monitor_new_from_netlink
+#undef udev_monitor_enable_receiving
+#undef udev_monitor_set_receive_buffer_size
+#undef udev_monitor_get_fd
+#undef udev_monitor_receive_device
+#undef udev_monitor_filter_add_match_subsystem_devtype
+#undef udev_monitor_filter_add_match_tag
+#undef udev_monitor_filter_update
+#undef udev_monitor_filter_remove
+#undef udev_enumerate_ref
+#undef udev_enumerate_unref
+#undef udev_enumerate_get_udev
+#undef udev_enumerate_new
+#undef udev_enumerate_add_match_subsystem
+#undef udev_enumerate_add_nomatch_subsystem
+#undef udev_enumerate_add_match_sysattr
+#undef udev_enumerate_add_nomatch_sysattr
+#undef udev_enumerate_add_match_property
+#undef udev_enumerate_add_match_sysname
+#undef udev_enumerate_add_match_tag
+#undef udev_enumerate_add_match_parent
+#undef udev_enumerate_add_match_is_initialized
+#undef udev_enumerate_add_syspath
+#undef udev_enumerate_scan_devices
+#undef udev_enumerate_scan_subsystems
+#undef udev_enumerate_get_list_entry
+#undef udev_queue_ref
+#undef udev_queue_unref
+#undef udev_queue_get_udev
+#undef udev_queue_new
+#undef udev_queue_get_kernel_seqnum
+#undef udev_queue_get_udev_seqnum
+#undef udev_queue_get_udev_is_active
+#undef udev_queue_get_queue_is_empty
+#undef udev_queue_get_seqnum_is_finished
+#undef udev_queue_get_seqnum_sequence_is_finished
+#undef udev_queue_get_fd
+#undef udev_queue_flush
+#undef udev_queue_get_queued_list_entry
+#undef udev_hwdb_new
+#undef udev_hwdb_ref
+#undef udev_hwdb_unref
+#undef udev_hwdb_get_properties_list_entry
+#undef udev_util_encode_string
+#ifdef __cplusplus
+extern "C" {
+#endif
+#define udev_ref udev_ref_dylibloader_wrapper_libudev
+#define udev_unref udev_unref_dylibloader_wrapper_libudev
+#define udev_new udev_new_dylibloader_wrapper_libudev
+#define udev_set_log_fn udev_set_log_fn_dylibloader_wrapper_libudev
+#define udev_get_log_priority udev_get_log_priority_dylibloader_wrapper_libudev
+#define udev_set_log_priority udev_set_log_priority_dylibloader_wrapper_libudev
+#define udev_get_userdata udev_get_userdata_dylibloader_wrapper_libudev
+#define udev_set_userdata udev_set_userdata_dylibloader_wrapper_libudev
+#define udev_list_entry_get_next udev_list_entry_get_next_dylibloader_wrapper_libudev
+#define udev_list_entry_get_by_name udev_list_entry_get_by_name_dylibloader_wrapper_libudev
+#define udev_list_entry_get_name udev_list_entry_get_name_dylibloader_wrapper_libudev
+#define udev_list_entry_get_value udev_list_entry_get_value_dylibloader_wrapper_libudev
+#define udev_device_ref udev_device_ref_dylibloader_wrapper_libudev
+#define udev_device_unref udev_device_unref_dylibloader_wrapper_libudev
+#define udev_device_get_udev udev_device_get_udev_dylibloader_wrapper_libudev
+#define udev_device_new_from_syspath udev_device_new_from_syspath_dylibloader_wrapper_libudev
+#define udev_device_new_from_devnum udev_device_new_from_devnum_dylibloader_wrapper_libudev
+#define udev_device_new_from_subsystem_sysname udev_device_new_from_subsystem_sysname_dylibloader_wrapper_libudev
+#define udev_device_new_from_device_id udev_device_new_from_device_id_dylibloader_wrapper_libudev
+#define udev_device_new_from_environment udev_device_new_from_environment_dylibloader_wrapper_libudev
+#define udev_device_get_parent udev_device_get_parent_dylibloader_wrapper_libudev
+#define udev_device_get_parent_with_subsystem_devtype udev_device_get_parent_with_subsystem_devtype_dylibloader_wrapper_libudev
+#define udev_device_get_devpath udev_device_get_devpath_dylibloader_wrapper_libudev
+#define udev_device_get_subsystem udev_device_get_subsystem_dylibloader_wrapper_libudev
+#define udev_device_get_devtype udev_device_get_devtype_dylibloader_wrapper_libudev
+#define udev_device_get_syspath udev_device_get_syspath_dylibloader_wrapper_libudev
+#define udev_device_get_sysname udev_device_get_sysname_dylibloader_wrapper_libudev
+#define udev_device_get_sysnum udev_device_get_sysnum_dylibloader_wrapper_libudev
+#define udev_device_get_devnode udev_device_get_devnode_dylibloader_wrapper_libudev
+#define udev_device_get_is_initialized udev_device_get_is_initialized_dylibloader_wrapper_libudev
+#define udev_device_get_devlinks_list_entry udev_device_get_devlinks_list_entry_dylibloader_wrapper_libudev
+#define udev_device_get_properties_list_entry udev_device_get_properties_list_entry_dylibloader_wrapper_libudev
+#define udev_device_get_tags_list_entry udev_device_get_tags_list_entry_dylibloader_wrapper_libudev
+#define udev_device_get_sysattr_list_entry udev_device_get_sysattr_list_entry_dylibloader_wrapper_libudev
+#define udev_device_get_property_value udev_device_get_property_value_dylibloader_wrapper_libudev
+#define udev_device_get_driver udev_device_get_driver_dylibloader_wrapper_libudev
+#define udev_device_get_devnum udev_device_get_devnum_dylibloader_wrapper_libudev
+#define udev_device_get_action udev_device_get_action_dylibloader_wrapper_libudev
+#define udev_device_get_seqnum udev_device_get_seqnum_dylibloader_wrapper_libudev
+#define udev_device_get_usec_since_initialized udev_device_get_usec_since_initialized_dylibloader_wrapper_libudev
+#define udev_device_get_sysattr_value udev_device_get_sysattr_value_dylibloader_wrapper_libudev
+#define udev_device_set_sysattr_value udev_device_set_sysattr_value_dylibloader_wrapper_libudev
+#define udev_device_has_tag udev_device_has_tag_dylibloader_wrapper_libudev
+#define udev_monitor_ref udev_monitor_ref_dylibloader_wrapper_libudev
+#define udev_monitor_unref udev_monitor_unref_dylibloader_wrapper_libudev
+#define udev_monitor_get_udev udev_monitor_get_udev_dylibloader_wrapper_libudev
+#define udev_monitor_new_from_netlink udev_monitor_new_from_netlink_dylibloader_wrapper_libudev
+#define udev_monitor_enable_receiving udev_monitor_enable_receiving_dylibloader_wrapper_libudev
+#define udev_monitor_set_receive_buffer_size udev_monitor_set_receive_buffer_size_dylibloader_wrapper_libudev
+#define udev_monitor_get_fd udev_monitor_get_fd_dylibloader_wrapper_libudev
+#define udev_monitor_receive_device udev_monitor_receive_device_dylibloader_wrapper_libudev
+#define udev_monitor_filter_add_match_subsystem_devtype udev_monitor_filter_add_match_subsystem_devtype_dylibloader_wrapper_libudev
+#define udev_monitor_filter_add_match_tag udev_monitor_filter_add_match_tag_dylibloader_wrapper_libudev
+#define udev_monitor_filter_update udev_monitor_filter_update_dylibloader_wrapper_libudev
+#define udev_monitor_filter_remove udev_monitor_filter_remove_dylibloader_wrapper_libudev
+#define udev_enumerate_ref udev_enumerate_ref_dylibloader_wrapper_libudev
+#define udev_enumerate_unref udev_enumerate_unref_dylibloader_wrapper_libudev
+#define udev_enumerate_get_udev udev_enumerate_get_udev_dylibloader_wrapper_libudev
+#define udev_enumerate_new udev_enumerate_new_dylibloader_wrapper_libudev
+#define udev_enumerate_add_match_subsystem udev_enumerate_add_match_subsystem_dylibloader_wrapper_libudev
+#define udev_enumerate_add_nomatch_subsystem udev_enumerate_add_nomatch_subsystem_dylibloader_wrapper_libudev
+#define udev_enumerate_add_match_sysattr udev_enumerate_add_match_sysattr_dylibloader_wrapper_libudev
+#define udev_enumerate_add_nomatch_sysattr udev_enumerate_add_nomatch_sysattr_dylibloader_wrapper_libudev
+#define udev_enumerate_add_match_property udev_enumerate_add_match_property_dylibloader_wrapper_libudev
+#define udev_enumerate_add_match_sysname udev_enumerate_add_match_sysname_dylibloader_wrapper_libudev
+#define udev_enumerate_add_match_tag udev_enumerate_add_match_tag_dylibloader_wrapper_libudev
+#define udev_enumerate_add_match_parent udev_enumerate_add_match_parent_dylibloader_wrapper_libudev
+#define udev_enumerate_add_match_is_initialized udev_enumerate_add_match_is_initialized_dylibloader_wrapper_libudev
+#define udev_enumerate_add_syspath udev_enumerate_add_syspath_dylibloader_wrapper_libudev
+#define udev_enumerate_scan_devices udev_enumerate_scan_devices_dylibloader_wrapper_libudev
+#define udev_enumerate_scan_subsystems udev_enumerate_scan_subsystems_dylibloader_wrapper_libudev
+#define udev_enumerate_get_list_entry udev_enumerate_get_list_entry_dylibloader_wrapper_libudev
+#define udev_queue_ref udev_queue_ref_dylibloader_wrapper_libudev
+#define udev_queue_unref udev_queue_unref_dylibloader_wrapper_libudev
+#define udev_queue_get_udev udev_queue_get_udev_dylibloader_wrapper_libudev
+#define udev_queue_new udev_queue_new_dylibloader_wrapper_libudev
+#define udev_queue_get_kernel_seqnum udev_queue_get_kernel_seqnum_dylibloader_wrapper_libudev
+#define udev_queue_get_udev_seqnum udev_queue_get_udev_seqnum_dylibloader_wrapper_libudev
+#define udev_queue_get_udev_is_active udev_queue_get_udev_is_active_dylibloader_wrapper_libudev
+#define udev_queue_get_queue_is_empty udev_queue_get_queue_is_empty_dylibloader_wrapper_libudev
+#define udev_queue_get_seqnum_is_finished udev_queue_get_seqnum_is_finished_dylibloader_wrapper_libudev
+#define udev_queue_get_seqnum_sequence_is_finished udev_queue_get_seqnum_sequence_is_finished_dylibloader_wrapper_libudev
+#define udev_queue_get_fd udev_queue_get_fd_dylibloader_wrapper_libudev
+#define udev_queue_flush udev_queue_flush_dylibloader_wrapper_libudev
+#define udev_queue_get_queued_list_entry udev_queue_get_queued_list_entry_dylibloader_wrapper_libudev
+#define udev_hwdb_new udev_hwdb_new_dylibloader_wrapper_libudev
+#define udev_hwdb_ref udev_hwdb_ref_dylibloader_wrapper_libudev
+#define udev_hwdb_unref udev_hwdb_unref_dylibloader_wrapper_libudev
+#define udev_hwdb_get_properties_list_entry udev_hwdb_get_properties_list_entry_dylibloader_wrapper_libudev
+#define udev_util_encode_string udev_util_encode_string_dylibloader_wrapper_libudev
+extern struct udev* (*udev_ref_dylibloader_wrapper_libudev)(struct udev*);
+extern struct udev* (*udev_unref_dylibloader_wrapper_libudev)(struct udev*);
+extern struct udev* (*udev_new_dylibloader_wrapper_libudev)( void);
+extern void (*udev_set_log_fn_dylibloader_wrapper_libudev)(struct udev*, void*);
+extern int (*udev_get_log_priority_dylibloader_wrapper_libudev)(struct udev*);
+extern void (*udev_set_log_priority_dylibloader_wrapper_libudev)(struct udev*, int);
+extern void* (*udev_get_userdata_dylibloader_wrapper_libudev)(struct udev*);
+extern void (*udev_set_userdata_dylibloader_wrapper_libudev)(struct udev*, void*);
+extern struct udev_list_entry* (*udev_list_entry_get_next_dylibloader_wrapper_libudev)(struct udev_list_entry*);
+extern struct udev_list_entry* (*udev_list_entry_get_by_name_dylibloader_wrapper_libudev)(struct udev_list_entry*,const char*);
+extern const char* (*udev_list_entry_get_name_dylibloader_wrapper_libudev)(struct udev_list_entry*);
+extern const char* (*udev_list_entry_get_value_dylibloader_wrapper_libudev)(struct udev_list_entry*);
+extern struct udev_device* (*udev_device_ref_dylibloader_wrapper_libudev)(struct udev_device*);
+extern struct udev_device* (*udev_device_unref_dylibloader_wrapper_libudev)(struct udev_device*);
+extern struct udev* (*udev_device_get_udev_dylibloader_wrapper_libudev)(struct udev_device*);
+extern struct udev_device* (*udev_device_new_from_syspath_dylibloader_wrapper_libudev)(struct udev*,const char*);
+extern struct udev_device* (*udev_device_new_from_devnum_dylibloader_wrapper_libudev)(struct udev*, char, dev_t);
+extern struct udev_device* (*udev_device_new_from_subsystem_sysname_dylibloader_wrapper_libudev)(struct udev*,const char*,const char*);
+extern struct udev_device* (*udev_device_new_from_device_id_dylibloader_wrapper_libudev)(struct udev*,const char*);
+extern struct udev_device* (*udev_device_new_from_environment_dylibloader_wrapper_libudev)(struct udev*);
+extern struct udev_device* (*udev_device_get_parent_dylibloader_wrapper_libudev)(struct udev_device*);
+extern struct udev_device* (*udev_device_get_parent_with_subsystem_devtype_dylibloader_wrapper_libudev)(struct udev_device*,const char*,const char*);
+extern const char* (*udev_device_get_devpath_dylibloader_wrapper_libudev)(struct udev_device*);
+extern const char* (*udev_device_get_subsystem_dylibloader_wrapper_libudev)(struct udev_device*);
+extern const char* (*udev_device_get_devtype_dylibloader_wrapper_libudev)(struct udev_device*);
+extern const char* (*udev_device_get_syspath_dylibloader_wrapper_libudev)(struct udev_device*);
+extern const char* (*udev_device_get_sysname_dylibloader_wrapper_libudev)(struct udev_device*);
+extern const char* (*udev_device_get_sysnum_dylibloader_wrapper_libudev)(struct udev_device*);
+extern const char* (*udev_device_get_devnode_dylibloader_wrapper_libudev)(struct udev_device*);
+extern int (*udev_device_get_is_initialized_dylibloader_wrapper_libudev)(struct udev_device*);
+extern struct udev_list_entry* (*udev_device_get_devlinks_list_entry_dylibloader_wrapper_libudev)(struct udev_device*);
+extern struct udev_list_entry* (*udev_device_get_properties_list_entry_dylibloader_wrapper_libudev)(struct udev_device*);
+extern struct udev_list_entry* (*udev_device_get_tags_list_entry_dylibloader_wrapper_libudev)(struct udev_device*);
+extern struct udev_list_entry* (*udev_device_get_sysattr_list_entry_dylibloader_wrapper_libudev)(struct udev_device*);
+extern const char* (*udev_device_get_property_value_dylibloader_wrapper_libudev)(struct udev_device*,const char*);
+extern const char* (*udev_device_get_driver_dylibloader_wrapper_libudev)(struct udev_device*);
+extern dev_t (*udev_device_get_devnum_dylibloader_wrapper_libudev)(struct udev_device*);
+extern const char* (*udev_device_get_action_dylibloader_wrapper_libudev)(struct udev_device*);
+extern unsigned long long int (*udev_device_get_seqnum_dylibloader_wrapper_libudev)(struct udev_device*);
+extern unsigned long long int (*udev_device_get_usec_since_initialized_dylibloader_wrapper_libudev)(struct udev_device*);
+extern const char* (*udev_device_get_sysattr_value_dylibloader_wrapper_libudev)(struct udev_device*,const char*);
+extern int (*udev_device_set_sysattr_value_dylibloader_wrapper_libudev)(struct udev_device*,const char*,const char*);
+extern int (*udev_device_has_tag_dylibloader_wrapper_libudev)(struct udev_device*,const char*);
+extern struct udev_monitor* (*udev_monitor_ref_dylibloader_wrapper_libudev)(struct udev_monitor*);
+extern struct udev_monitor* (*udev_monitor_unref_dylibloader_wrapper_libudev)(struct udev_monitor*);
+extern struct udev* (*udev_monitor_get_udev_dylibloader_wrapper_libudev)(struct udev_monitor*);
+extern struct udev_monitor* (*udev_monitor_new_from_netlink_dylibloader_wrapper_libudev)(struct udev*,const char*);
+extern int (*udev_monitor_enable_receiving_dylibloader_wrapper_libudev)(struct udev_monitor*);
+extern int (*udev_monitor_set_receive_buffer_size_dylibloader_wrapper_libudev)(struct udev_monitor*, int);
+extern int (*udev_monitor_get_fd_dylibloader_wrapper_libudev)(struct udev_monitor*);
+extern struct udev_device* (*udev_monitor_receive_device_dylibloader_wrapper_libudev)(struct udev_monitor*);
+extern int (*udev_monitor_filter_add_match_subsystem_devtype_dylibloader_wrapper_libudev)(struct udev_monitor*,const char*,const char*);
+extern int (*udev_monitor_filter_add_match_tag_dylibloader_wrapper_libudev)(struct udev_monitor*,const char*);
+extern int (*udev_monitor_filter_update_dylibloader_wrapper_libudev)(struct udev_monitor*);
+extern int (*udev_monitor_filter_remove_dylibloader_wrapper_libudev)(struct udev_monitor*);
+extern struct udev_enumerate* (*udev_enumerate_ref_dylibloader_wrapper_libudev)(struct udev_enumerate*);
+extern struct udev_enumerate* (*udev_enumerate_unref_dylibloader_wrapper_libudev)(struct udev_enumerate*);
+extern struct udev* (*udev_enumerate_get_udev_dylibloader_wrapper_libudev)(struct udev_enumerate*);
+extern struct udev_enumerate* (*udev_enumerate_new_dylibloader_wrapper_libudev)(struct udev*);
+extern int (*udev_enumerate_add_match_subsystem_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*);
+extern int (*udev_enumerate_add_nomatch_subsystem_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*);
+extern int (*udev_enumerate_add_match_sysattr_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*,const char*);
+extern int (*udev_enumerate_add_nomatch_sysattr_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*,const char*);
+extern int (*udev_enumerate_add_match_property_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*,const char*);
+extern int (*udev_enumerate_add_match_sysname_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*);
+extern int (*udev_enumerate_add_match_tag_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*);
+extern int (*udev_enumerate_add_match_parent_dylibloader_wrapper_libudev)(struct udev_enumerate*,struct udev_device*);
+extern int (*udev_enumerate_add_match_is_initialized_dylibloader_wrapper_libudev)(struct udev_enumerate*);
+extern int (*udev_enumerate_add_syspath_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*);
+extern int (*udev_enumerate_scan_devices_dylibloader_wrapper_libudev)(struct udev_enumerate*);
+extern int (*udev_enumerate_scan_subsystems_dylibloader_wrapper_libudev)(struct udev_enumerate*);
+extern struct udev_list_entry* (*udev_enumerate_get_list_entry_dylibloader_wrapper_libudev)(struct udev_enumerate*);
+extern struct udev_queue* (*udev_queue_ref_dylibloader_wrapper_libudev)(struct udev_queue*);
+extern struct udev_queue* (*udev_queue_unref_dylibloader_wrapper_libudev)(struct udev_queue*);
+extern struct udev* (*udev_queue_get_udev_dylibloader_wrapper_libudev)(struct udev_queue*);
+extern struct udev_queue* (*udev_queue_new_dylibloader_wrapper_libudev)(struct udev*);
+extern unsigned long long int (*udev_queue_get_kernel_seqnum_dylibloader_wrapper_libudev)(struct udev_queue*);
+extern unsigned long long int (*udev_queue_get_udev_seqnum_dylibloader_wrapper_libudev)(struct udev_queue*);
+extern int (*udev_queue_get_udev_is_active_dylibloader_wrapper_libudev)(struct udev_queue*);
+extern int (*udev_queue_get_queue_is_empty_dylibloader_wrapper_libudev)(struct udev_queue*);
+extern int (*udev_queue_get_seqnum_is_finished_dylibloader_wrapper_libudev)(struct udev_queue*, unsigned long long int);
+extern int (*udev_queue_get_seqnum_sequence_is_finished_dylibloader_wrapper_libudev)(struct udev_queue*, unsigned long long int, unsigned long long int);
+extern int (*udev_queue_get_fd_dylibloader_wrapper_libudev)(struct udev_queue*);
+extern int (*udev_queue_flush_dylibloader_wrapper_libudev)(struct udev_queue*);
+extern struct udev_list_entry* (*udev_queue_get_queued_list_entry_dylibloader_wrapper_libudev)(struct udev_queue*);
+extern struct udev_hwdb* (*udev_hwdb_new_dylibloader_wrapper_libudev)(struct udev*);
+extern struct udev_hwdb* (*udev_hwdb_ref_dylibloader_wrapper_libudev)(struct udev_hwdb*);
+extern struct udev_hwdb* (*udev_hwdb_unref_dylibloader_wrapper_libudev)(struct udev_hwdb*);
+extern struct udev_list_entry* (*udev_hwdb_get_properties_list_entry_dylibloader_wrapper_libudev)(struct udev_hwdb*,const char*, unsigned);
+extern int (*udev_util_encode_string_dylibloader_wrapper_libudev)(const char*, char*, size_t);
+int initialize_libudev(int verbose);
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/platform/linuxbsd/os_linuxbsd.cpp b/platform/linuxbsd/os_linuxbsd.cpp
index e569aa03d7..09e1f9461c 100644
--- a/platform/linuxbsd/os_linuxbsd.cpp
+++ b/platform/linuxbsd/os_linuxbsd.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -65,9 +65,9 @@ void OS_LinuxBSD::initialize_joypads() {
String OS_LinuxBSD::get_unique_id() const {
static String machine_id;
- if (machine_id.empty()) {
+ if (machine_id.is_empty()) {
if (FileAccess *f = FileAccess::open("/etc/machine-id", FileAccess::READ)) {
- while (machine_id.empty() && !f->eof_reached()) {
+ while (machine_id.is_empty() && !f->eof_reached()) {
machine_id = f->get_line().strip_edges();
}
f->close();
@@ -128,7 +128,7 @@ Error OS_LinuxBSD::shell_open(String p_uri) {
args.push_back(p_uri);
// Agnostic
- ok = execute("xdg-open", args, true, nullptr, nullptr, &err_code);
+ ok = execute("xdg-open", args, nullptr, &err_code);
if (ok == OK && !err_code) {
return OK;
} else if (err_code == 2) {
@@ -136,25 +136,25 @@ Error OS_LinuxBSD::shell_open(String p_uri) {
}
// GNOME
args.push_front("open"); // The command is `gio open`, so we need to add it to args
- ok = execute("gio", args, true, nullptr, nullptr, &err_code);
+ ok = execute("gio", args, nullptr, &err_code);
if (ok == OK && !err_code) {
return OK;
} else if (err_code == 2) {
return ERR_FILE_NOT_FOUND;
}
args.pop_front();
- ok = execute("gvfs-open", args, true, nullptr, nullptr, &err_code);
+ ok = execute("gvfs-open", args, nullptr, &err_code);
if (ok == OK && !err_code) {
return OK;
} else if (err_code == 2) {
return ERR_FILE_NOT_FOUND;
}
// KDE
- ok = execute("kde-open5", args, true, nullptr, nullptr, &err_code);
+ ok = execute("kde-open5", args, nullptr, &err_code);
if (ok == OK && !err_code) {
return OK;
}
- ok = execute("kde-open", args, true, nullptr, nullptr, &err_code);
+ ok = execute("kde-open", args, nullptr, &err_code);
return !err_code ? ok : FAILED;
}
@@ -232,7 +232,7 @@ String OS_LinuxBSD::get_system_dir(SystemDir p_dir) const {
String pipe;
List<String> arg;
arg.push_back(xdgparam);
- Error err = const_cast<OS_LinuxBSD *>(this)->execute("xdg-user-dir", arg, true, nullptr, &pipe);
+ Error err = const_cast<OS_LinuxBSD *>(this)->execute("xdg-user-dir", arg, &pipe);
if (err != OK) {
return ".";
}
@@ -246,7 +246,7 @@ void OS_LinuxBSD::run() {
return;
}
- main_loop->init();
+ main_loop->initialize();
//uint64_t last_ticks=get_ticks_usec();
@@ -263,7 +263,7 @@ void OS_LinuxBSD::run() {
}
};
- main_loop->finish();
+ main_loop->finalize();
}
void OS_LinuxBSD::disable_crash_handler() {
@@ -303,65 +303,147 @@ static String get_mountpoint(const String &p_path) {
}
Error OS_LinuxBSD::move_to_trash(const String &p_path) {
- String trash_can = "";
+ int err_code;
+ List<String> args;
+ args.push_back(p_path);
+ args.push_front("trash"); // The command is `gio trash <file_name>` so we need to add it to args.
+ Error result = execute("gio", args, nullptr, &err_code); // For GNOME based machines.
+ if (result == OK && !err_code) {
+ return OK;
+ } else if (err_code == 2) {
+ return ERR_FILE_NOT_FOUND;
+ }
+
+ args.pop_front();
+ args.push_front("move");
+ args.push_back("trash:/"); // The command is `kioclient5 move <file_name> trash:/`.
+ result = execute("kioclient5", args, nullptr, &err_code); // For KDE based machines.
+ if (result == OK && !err_code) {
+ return OK;
+ } else if (err_code == 2) {
+ return ERR_FILE_NOT_FOUND;
+ }
+
+ args.pop_front();
+ args.pop_back();
+ result = execute("gvfs-trash", args, nullptr, &err_code); // For older Linux machines.
+ if (result == OK && !err_code) {
+ return OK;
+ } else if (err_code == 2) {
+ return ERR_FILE_NOT_FOUND;
+ }
+
+ // If the commands `kioclient5`, `gio` or `gvfs-trash` don't exist on the system we do it manually.
+ String trash_path = "";
String mnt = get_mountpoint(p_path);
- // If there is a directory "[Mountpoint]/.Trash-[UID]/files", use it as the trash can.
+ // If there is a directory "[Mountpoint]/.Trash-[UID], use it as the trash can.
if (mnt != "") {
- String path(mnt + "/.Trash-" + itos(getuid()) + "/files");
+ String path(mnt + "/.Trash-" + itos(getuid()));
struct stat s;
if (!stat(path.utf8().get_data(), &s)) {
- trash_can = path;
+ trash_path = path;
}
}
- // Otherwise, if ${XDG_DATA_HOME} is defined, use "${XDG_DATA_HOME}/Trash/files" as the trash can.
- if (trash_can == "") {
+ // Otherwise, if ${XDG_DATA_HOME} is defined, use "${XDG_DATA_HOME}/Trash" as the trash can.
+ if (trash_path == "") {
char *dhome = getenv("XDG_DATA_HOME");
if (dhome) {
- trash_can = String(dhome) + "/Trash/files";
+ trash_path = String(dhome) + "/Trash";
}
}
- // Otherwise, if ${HOME} is defined, use "${HOME}/.local/share/Trash/files" as the trash can.
- if (trash_can == "") {
+ // Otherwise, if ${HOME} is defined, use "${HOME}/.local/share/Trash" as the trash can.
+ if (trash_path == "") {
char *home = getenv("HOME");
if (home) {
- trash_can = String(home) + "/.local/share/Trash/files";
+ trash_path = String(home) + "/.local/share/Trash";
}
}
// Issue an error if none of the previous locations is appropriate for the trash can.
- if (trash_can == "") {
- ERR_PRINT("move_to_trash: Could not determine the trash can location");
- return FAILED;
- }
+ ERR_FAIL_COND_V_MSG(trash_path == "", FAILED, "Could not determine the trash can location");
// Create needed directories for decided trash can location.
- DirAccess *dir_access = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
- Error err = dir_access->make_dir_recursive(trash_can);
- memdelete(dir_access);
+ {
+ DirAccess *dir_access = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
+ Error err = dir_access->make_dir_recursive(trash_path);
+
+ // Issue an error if trash can is not created proprely.
+ ERR_FAIL_COND_V_MSG(err != OK, err, "Could not create the trash path \"" + trash_path + "\"");
+ err = dir_access->make_dir_recursive(trash_path + "/files");
+ ERR_FAIL_COND_V_MSG(err != OK, err, "Could not create the trash path \"" + trash_path + "\"/files");
+ err = dir_access->make_dir_recursive(trash_path + "/info");
+ ERR_FAIL_COND_V_MSG(err != OK, err, "Could not create the trash path \"" + trash_path + "\"/info");
+ memdelete(dir_access);
+ }
- // Issue an error if trash can is not created proprely.
- if (err != OK) {
- ERR_PRINT("move_to_trash: Could not create the trash can \"" + trash_can + "\"");
- return err;
+ // The trash can is successfully created, now we check that we don't exceed our file name length limit.
+ // If the file name is too long trim it so we can add the identifying number and ".trashinfo".
+ // Assumes that the file name length limit is 255 characters.
+ String file_name = basename(p_path.utf8().get_data());
+ if (file_name.length() > 240) {
+ file_name = file_name.substr(0, file_name.length() - 15);
+ }
+
+ String dest_path = trash_path + "/files/" + file_name;
+ struct stat buff;
+ int id_number = 0;
+ String fn = file_name;
+
+ // Checks if a resource with the same name already exist in the trash can,
+ // if there is, add an identifying number to our resource's name.
+ while (stat(dest_path.utf8().get_data(), &buff) == 0) {
+ id_number++;
+
+ // Added a limit to check for identically named files already on the trash can
+ // if there are too many it could make the editor unresponsive.
+ ERR_FAIL_COND_V_MSG(id_number > 99, FAILED, "Too many identically named resources already in the trash can.");
+ fn = file_name + "." + itos(id_number);
+ dest_path = trash_path + "/files/" + fn;
+ }
+ file_name = fn;
+
+ // Generates the .trashinfo file
+ OS::Date date = OS::get_singleton()->get_date(false);
+ OS::Time time = OS::get_singleton()->get_time(false);
+ String timestamp = vformat("%04d-%02d-%02dT%02d:%02d:", date.year, date.month, date.day, time.hour, time.min);
+ timestamp = vformat("%s%02d", timestamp, time.sec); // vformat only supports up to 6 arguments.
+ String trash_info = "[Trash Info]\nPath=" + p_path.uri_encode() + "\nDeletionDate=" + timestamp + "\n";
+ {
+ Error err;
+ FileAccess *file = FileAccess::open(trash_path + "/info/" + file_name + ".trashinfo", FileAccess::WRITE, &err);
+ ERR_FAIL_COND_V_MSG(err != OK, err, "Can't create trashinfo file:" + trash_path + "/info/" + file_name + ".trashinfo");
+ file->store_string(trash_info);
+ file->close();
+
+ // Rename our resource before moving it to the trash can.
+ DirAccess *dir_access = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
+ err = dir_access->rename(p_path, p_path.get_base_dir() + "/" + file_name);
+ ERR_FAIL_COND_V_MSG(err != OK, err, "Can't rename file \"" + p_path + "\"");
+ memdelete(dir_access);
}
- // The trash can is successfully created, now move the given resource to it.
+ // Move the given resource to the trash can.
// Do not use DirAccess:rename() because it can't move files across multiple mountpoints.
List<String> mv_args;
- mv_args.push_back(p_path);
- mv_args.push_back(trash_can);
- int retval;
- err = execute("mv", mv_args, true, nullptr, nullptr, &retval);
-
- // Issue an error if "mv" failed to move the given resource to the trash can.
- if (err != OK || retval != 0) {
- ERR_PRINT("move_to_trash: Could not move the resource \"" + p_path + "\" to the trash can \"" + trash_can + "\"");
- return FAILED;
+ mv_args.push_back(p_path.get_base_dir() + "/" + file_name);
+ mv_args.push_back(trash_path + "/files");
+ {
+ int retval;
+ Error err = execute("mv", mv_args, nullptr, &retval);
+
+ // Issue an error if "mv" failed to move the given resource to the trash can.
+ if (err != OK || retval != 0) {
+ ERR_PRINT("move_to_trash: Could not move the resource \"" + p_path + "\" to the trash can \"" + trash_path + "/files\"");
+ DirAccess *dir_access = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
+ err = dir_access->rename(p_path.get_base_dir() + "/" + file_name, p_path);
+ memdelete(dir_access);
+ ERR_FAIL_COND_V_MSG(err != OK, err, "Could not rename " + p_path.get_base_dir() + "/" + file_name + " back to its original name:" + p_path);
+ return FAILED;
+ }
}
-
return OK;
}
diff --git a/platform/linuxbsd/os_linuxbsd.h b/platform/linuxbsd/os_linuxbsd.h
index cd4fbd9db5..b6cf93c551 100644
--- a/platform/linuxbsd/os_linuxbsd.h
+++ b/platform/linuxbsd/os_linuxbsd.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -39,11 +39,11 @@
#include "drivers/unix/os_unix.h"
#include "joypad_linux.h"
#include "servers/audio_server.h"
-#include "servers/rendering/rasterizer.h"
+#include "servers/rendering/renderer_compositor.h"
#include "servers/rendering_server.h"
class OS_LinuxBSD : public OS_Unix {
- virtual void delete_main_loop();
+ virtual void delete_main_loop() override;
bool force_quit;
@@ -68,36 +68,36 @@ class OS_LinuxBSD : public OS_Unix {
MainLoop *main_loop;
protected:
- virtual void initialize();
- virtual void finalize();
+ virtual void initialize() override;
+ virtual void finalize() override;
- virtual void initialize_joypads();
+ virtual void initialize_joypads() override;
- virtual void set_main_loop(MainLoop *p_main_loop);
+ virtual void set_main_loop(MainLoop *p_main_loop) override;
public:
- virtual String get_name() const;
+ virtual String get_name() const override;
- virtual MainLoop *get_main_loop() const;
+ virtual MainLoop *get_main_loop() const override;
- virtual String get_config_path() const;
- virtual String get_data_path() const;
- virtual String get_cache_path() const;
+ virtual String get_config_path() const override;
+ virtual String get_data_path() const override;
+ virtual String get_cache_path() const override;
- virtual String get_system_dir(SystemDir p_dir) const;
+ virtual String get_system_dir(SystemDir p_dir) const override;
- virtual Error shell_open(String p_uri);
+ virtual Error shell_open(String p_uri) override;
- virtual String get_unique_id() const;
+ virtual String get_unique_id() const override;
- virtual bool _check_internal_feature_support(const String &p_feature);
+ virtual bool _check_internal_feature_support(const String &p_feature) override;
void run();
- void disable_crash_handler();
- bool is_disable_crash_handler() const;
+ virtual void disable_crash_handler() override;
+ virtual bool is_disable_crash_handler() const override;
- virtual Error move_to_trash(const String &p_path);
+ virtual Error move_to_trash(const String &p_path) override;
OS_LinuxBSD();
};
diff --git a/platform/linuxbsd/platform_config.h b/platform/linuxbsd/platform_config.h
index 571ad03db0..3195d08935 100644
--- a/platform/linuxbsd/platform_config.h
+++ b/platform/linuxbsd/platform_config.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/linuxbsd/vulkan_context_x11.cpp b/platform/linuxbsd/vulkan_context_x11.cpp
index 2eaa9f9446..021db630e0 100644
--- a/platform/linuxbsd/vulkan_context_x11.cpp
+++ b/platform/linuxbsd/vulkan_context_x11.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/linuxbsd/vulkan_context_x11.h b/platform/linuxbsd/vulkan_context_x11.h
index af3d923cfe..26472444ad 100644
--- a/platform/linuxbsd/vulkan_context_x11.h
+++ b/platform/linuxbsd/vulkan_context_x11.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/osx/SCsub b/platform/osx/SCsub
index aa95a89444..46c13d8550 100644
--- a/platform/osx/SCsub
+++ b/platform/osx/SCsub
@@ -18,5 +18,5 @@ files = [
prog = env.add_program("#bin/godot", files)
-if env["debug_symbols"] == "yes" and env["separate_debug_symbols"]:
+if env["debug_symbols"] and env["separate_debug_symbols"]:
env.AddPostAction(prog, run_in_subprocess(platform_osx_builders.make_debug_osx))
diff --git a/platform/osx/context_gl_osx.h b/platform/osx/context_gl_osx.h
index 1d467513e2..ac45559217 100644
--- a/platform/osx/context_gl_osx.h
+++ b/platform/osx/context_gl_osx.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/osx/context_gl_osx.mm b/platform/osx/context_gl_osx.mm
index 2319e9eb1f..88db1a296e 100644
--- a/platform/osx/context_gl_osx.mm
+++ b/platform/osx/context_gl_osx.mm
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/osx/crash_handler_osx.h b/platform/osx/crash_handler_osx.h
index 9970f6045a..1601bbaab6 100644
--- a/platform/osx/crash_handler_osx.h
+++ b/platform/osx/crash_handler_osx.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/osx/crash_handler_osx.mm b/platform/osx/crash_handler_osx.mm
index 1429024598..147ce26779 100644
--- a/platform/osx/crash_handler_osx.mm
+++ b/platform/osx/crash_handler_osx.mm
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -135,7 +135,7 @@ static void handle_crash(int sig) {
int ret;
String out = "";
- Error err = OS::get_singleton()->execute(String("atos"), args, true, NULL, &out, &ret);
+ Error err = OS::get_singleton()->execute(String("atos"), args, &out, &ret);
if (err == OK && out.substr(0, 2) != "0x") {
out.erase(out.length() - 1, 1);
output = out;
diff --git a/platform/osx/detect.py b/platform/osx/detect.py
index ea41479bb0..acea00c5ac 100644
--- a/platform/osx/detect.py
+++ b/platform/osx/detect.py
@@ -12,7 +12,6 @@ def get_name():
def can_build():
-
if sys.platform == "darwin" or ("OSXCROSS_ROOT" in os.environ):
return True
@@ -31,7 +30,8 @@ def get_opts():
" validation layers)",
False,
),
- EnumVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", "yes", ("yes", "no")),
+ EnumVariable("macports_clang", "Build using Clang from MacPorts", "no", ("no", "5.0", "devel")),
+ BoolVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", True),
BoolVariable("separate_debug_symbols", "Create a separate file containing debugging symbols", False),
BoolVariable("use_ubsan", "Use LLVM/GCC compiler undefined behavior sanitizer (UBSAN)", False),
BoolVariable("use_asan", "Use LLVM/GCC compiler address sanitizer (ASAN))", False),
@@ -40,12 +40,10 @@ def get_opts():
def get_flags():
-
return []
def configure(env):
-
## Build type
if env["target"] == "release":
@@ -56,7 +54,7 @@ def configure(env):
if env["arch"] != "arm64":
env.Prepend(CCFLAGS=["-msse2"])
- if env["debug_symbols"] == "yes":
+ if env["debug_symbols"]:
env.Prepend(CCFLAGS=["-g2"])
elif env["target"] == "release_debug":
@@ -65,7 +63,7 @@ def configure(env):
else: # optimize for size
env.Prepend(CCFLAGS=["-Os"])
env.Prepend(CPPDEFINES=["DEBUG_ENABLED"])
- if env["debug_symbols"] == "yes":
+ if env["debug_symbols"]:
env.Prepend(CCFLAGS=["-g2"])
elif env["target"] == "debug":
diff --git a/platform/osx/dir_access_osx.h b/platform/osx/dir_access_osx.h
index 91b8f9b2c5..f61581979f 100644
--- a/platform/osx/dir_access_osx.h
+++ b/platform/osx/dir_access_osx.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/osx/dir_access_osx.mm b/platform/osx/dir_access_osx.mm
index 439c6a075f..552c33d018 100644
--- a/platform/osx/dir_access_osx.mm
+++ b/platform/osx/dir_access_osx.mm
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/osx/display_server_osx.h b/platform/osx/display_server_osx.h
index 073d35008b..9fac99810b 100644
--- a/platform/osx/display_server_osx.h
+++ b/platform/osx/display_server_osx.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -77,13 +77,13 @@ public:
struct KeyEvent {
WindowID window_id;
- unsigned int osx_state;
- bool pressed;
- bool echo;
- bool raw;
- uint32_t keycode;
- uint32_t physical_keycode;
- uint32_t unicode;
+ unsigned int osx_state = false;
+ bool pressed = false;
+ bool echo = false;
+ bool raw = false;
+ uint32_t keycode = 0;
+ uint32_t physical_keycode = 0;
+ uint32_t unicode = 0;
};
struct WarpEvent {
@@ -93,6 +93,7 @@ public:
List<WarpEvent> warp_events;
NSTimeInterval last_warp = 0;
+ bool ignore_warp = false;
Vector<KeyEvent> key_event_buffer;
int key_event_pos;
diff --git a/platform/osx/display_server_osx.mm b/platform/osx/display_server_osx.mm
index 1ad7117b39..ed7d89009f 100644
--- a/platform/osx/display_server_osx.mm
+++ b/platform/osx/display_server_osx.mm
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -52,7 +52,7 @@
#endif
#if defined(VULKAN_ENABLED)
-#include "servers/rendering/rasterizer_rd/rasterizer_rd.h"
+#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
#include <QuartzCore/CAMetalLayer.h>
#endif
@@ -256,9 +256,7 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
List<String> args;
args.push_back(((OS_OSX *)(OS_OSX::get_singleton()))->open_with_filename);
String exec = OS::get_singleton()->get_executable_path();
-
- OS::ProcessID pid = 0;
- OS::get_singleton()->execute(exec, args, false, &pid);
+ OS::get_singleton()->create_process(exec, args);
}
#endif
return YES;
@@ -701,8 +699,6 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
characters = (NSString *)aString;
}
- NSUInteger i, length = [characters length];
-
NSCharacterSet *ctrlChars = [NSCharacterSet controlCharacterSet];
NSCharacterSet *wsnlChars = [NSCharacterSet whitespaceAndNewlineCharacterSet];
if ([characters rangeOfCharacterFromSet:ctrlChars].length && [characters rangeOfCharacterFromSet:wsnlChars].length == 0) {
@@ -712,8 +708,15 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
return;
}
- for (i = 0; i < length; i++) {
- const unichar codepoint = [characters characterAtIndex:i];
+ Char16String text;
+ text.resize([characters length] + 1);
+ [characters getCharacters:(unichar *)text.ptrw() range:NSMakeRange(0, [characters length])];
+
+ String u32text;
+ u32text.parse_utf16(text.ptr(), text.length());
+
+ for (int i = 0; i < u32text.length(); i++) {
+ const char32_t codepoint = u32text[i];
if ((codepoint & 0xFF00) == 0xF700) {
continue;
}
@@ -746,28 +749,32 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
ERR_FAIL_COND_V(!DS_OSX->windows.has(window_id), NO);
DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id];
- NSPasteboard *pboard = [sender draggingPasteboard];
-#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101400
- NSArray<NSURL *> *filenames = [pboard propertyListForType:NSPasteboardTypeFileURL];
-#else
- NSArray *filenames = [pboard propertyListForType:NSFilenamesPboardType];
-#endif
+ if (!wd.drop_files_callback.is_null()) {
+ Vector<String> files;
+ NSPasteboard *pboard = [sender draggingPasteboard];
- Vector<String> files;
- for (NSUInteger i = 0; i < filenames.count; i++) {
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101400
- NSString *ns = [[filenames objectAtIndex:i] path];
+ NSArray *items = pboard.pasteboardItems;
+ for (NSPasteboardItem *item in items) {
+ NSString *path = [item stringForType:NSPasteboardTypeFileURL];
+ NSString *ns = [NSURL URLWithString:path].path;
+ char *utfs = strdup([ns UTF8String]);
+ String ret;
+ ret.parse_utf8(utfs);
+ free(utfs);
+ files.push_back(ret);
+ }
#else
- NSString *ns = [filenames objectAtIndex:i];
+ NSArray *filenames = [pboard propertyListForType:NSFilenamesPboardType];
+ for (NSString *ns in filenames) {
+ char *utfs = strdup([ns UTF8String]);
+ String ret;
+ ret.parse_utf8(utfs);
+ free(utfs);
+ files.push_back(ret);
+ }
#endif
- char *utfs = strdup([ns UTF8String]);
- String ret;
- ret.parse_utf8(utfs);
- free(utfs);
- files.push_back(ret);
- }
- if (!wd.drop_files_callback.is_null()) {
Variant v = files;
Variant *vp = &v;
Variant ret;
@@ -864,6 +871,15 @@ static void _mouseDownEvent(DisplayServer::WindowID window_id, NSEvent *event, i
NSPoint delta = NSMakePoint([event deltaX], [event deltaY]);
NSPoint mpos = [event locationInWindow];
+ if (DS_OSX->ignore_warp) {
+ // Discard late events, before warp
+ if (([event timestamp]) < DS_OSX->last_warp) {
+ return;
+ }
+ DS_OSX->ignore_warp = false;
+ return;
+ }
+
if (DS_OSX->mouse_mode == DisplayServer::MOUSE_MODE_CONFINED) {
// Discard late events
if (([event timestamp]) < DS_OSX->last_warp) {
@@ -1315,7 +1331,16 @@ static int remapKey(unsigned int key, unsigned int state) {
if (!wd.im_active && length > 0 && keycode_has_unicode(remapKey([event keyCode], [event modifierFlags]))) {
// Fallback unicode character handler used if IME is not active
- for (NSUInteger i = 0; i < length; i++) {
+ Char16String text;
+ text.resize([characters length] + 1);
+ [characters getCharacters:(unichar *)text.ptrw() range:NSMakeRange(0, [characters length])];
+
+ String u32text;
+ u32text.parse_utf16(text.ptr(), text.length());
+
+ for (int i = 0; i < u32text.length(); i++) {
+ const char32_t codepoint = u32text[i];
+
DisplayServerOSX::KeyEvent ke;
ke.window_id = window_id;
@@ -1325,7 +1350,7 @@ static int remapKey(unsigned int key, unsigned int state) {
ke.keycode = remapKey([event keyCode], [event modifierFlags]);
ke.physical_keycode = translateKey([event keyCode]);
ke.raw = true;
- ke.unicode = [characters characterAtIndex:i];
+ ke.unicode = codepoint;
_push_to_key_event_buffer(ke);
}
@@ -1417,7 +1442,15 @@ static int remapKey(unsigned int key, unsigned int state) {
// Fallback unicode character handler used if IME is not active
if (!wd.im_active && length > 0 && keycode_has_unicode(remapKey([event keyCode], [event modifierFlags]))) {
- for (NSUInteger i = 0; i < length; i++) {
+ Char16String text;
+ text.resize([characters length] + 1);
+ [characters getCharacters:(unichar *)text.ptrw() range:NSMakeRange(0, [characters length])];
+
+ String u32text;
+ u32text.parse_utf16(text.ptr(), text.length());
+
+ for (int i = 0; i < u32text.length(); i++) {
+ const char32_t codepoint = u32text[i];
DisplayServerOSX::KeyEvent ke;
ke.window_id = window_id;
@@ -1427,7 +1460,7 @@ static int remapKey(unsigned int key, unsigned int state) {
ke.keycode = remapKey([event keyCode], [event modifierFlags]);
ke.physical_keycode = translateKey([event keyCode]);
ke.raw = true;
- ke.unicode = [characters characterAtIndex:i];
+ ke.unicode = codepoint;
_push_to_key_event_buffer(ke);
}
@@ -2074,6 +2107,8 @@ void DisplayServerOSX::mouse_set_mode(MouseMode p_mode) {
CGAssociateMouseAndMouseCursorPosition(true);
}
+ last_warp = [[NSProcessInfo processInfo] systemUptime];
+ ignore_warp = true;
warp_events.clear();
mouse_mode = p_mode;
}
@@ -3848,7 +3883,7 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode
rendering_device_vulkan = memnew(RenderingDeviceVulkan);
rendering_device_vulkan->initialize(context_vulkan);
- RasterizerRD::make_current();
+ RendererCompositorRD::make_current();
}
#endif
diff --git a/platform/osx/export/export.cpp b/platform/osx/export/export.cpp
index e988e51e72..337cfd6808 100644
--- a/platform/osx/export/export.cpp
+++ b/platform/osx/export/export.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -42,13 +42,13 @@
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
#include "platform/osx/logo.gen.h"
-#include "string.h"
+
#include <sys/stat.h>
class EditorExportPlatformOSX : public EditorExportPlatform {
GDCLASS(EditorExportPlatformOSX, EditorExportPlatform);
- int version_code;
+ int version_code = 0;
Ref<ImageTexture> logo;
@@ -419,7 +419,7 @@ Error EditorExportPlatformOSX::_notarize(const Ref<EditorExportPreset> &p_preset
args.push_back(p_path);
String str;
- Error err = OS::get_singleton()->execute("xcrun", args, true, nullptr, &str, nullptr, true);
+ Error err = OS::get_singleton()->execute("xcrun", args, &str, nullptr, true);
ERR_FAIL_COND_V(err != OK, err);
print_line("altool (" + p_path + "):\n" + str);
@@ -457,7 +457,7 @@ Error EditorExportPlatformOSX::_code_sign(const Ref<EditorExportPreset> &p_prese
PackedStringArray user_args = p_preset->get("codesign/custom_options");
for (int i = 0; i < user_args.size(); i++) {
String user_arg = user_args[i].strip_edges();
- if (!user_arg.empty()) {
+ if (!user_arg.is_empty()) {
args.push_back(user_arg);
}
}
@@ -470,7 +470,7 @@ Error EditorExportPlatformOSX::_code_sign(const Ref<EditorExportPreset> &p_prese
args.push_back(p_path);
String str;
- Error err = OS::get_singleton()->execute("codesign", args, true, nullptr, &str, nullptr, true);
+ Error err = OS::get_singleton()->execute("codesign", args, &str, nullptr, true);
ERR_FAIL_COND_V(err != OK, err);
print_line("codesign (" + p_path + "):\n" + str);
@@ -504,7 +504,7 @@ Error EditorExportPlatformOSX::_create_dmg(const String &p_dmg_path, const Strin
args.push_back(p_app_path_name);
String str;
- Error err = OS::get_singleton()->execute("hdiutil", args, true, nullptr, &str, nullptr, true);
+ Error err = OS::get_singleton()->execute("hdiutil", args, &str, nullptr, true);
ERR_FAIL_COND_V(err != OK, err);
print_line("hdiutil returned: " + str);
@@ -572,36 +572,36 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
pkg_name = "Unnamed";
}
- String pkg_name_safe = OS::get_singleton()->get_safe_dir_name(pkg_name);
-
- Error err = OK;
- String tmp_app_path_name = "";
+ pkg_name = OS::get_singleton()->get_safe_dir_name(pkg_name);
- DirAccess *tmp_app_path = nullptr;
String export_format = use_dmg() && p_path.ends_with("dmg") ? "dmg" : "zip";
// Create our application bundle.
- tmp_app_path_name = EditorSettings::get_singleton()->get_cache_dir().plus_file(pkg_name + ".app");
+ String tmp_app_dir_name = pkg_name + ".app";
+ String tmp_app_path_name = EditorSettings::get_singleton()->get_cache_dir().plus_file(tmp_app_dir_name);
print_line("Exporting to " + tmp_app_path_name);
- tmp_app_path = DirAccess::create_for_path(tmp_app_path_name);
- if (!tmp_app_path) {
+
+ Error err = OK;
+
+ DirAccessRef tmp_app_dir = DirAccess::create_for_path(tmp_app_path_name);
+ if (!tmp_app_dir) {
err = ERR_CANT_CREATE;
}
// Create our folder structure.
if (err == OK) {
print_line("Creating " + tmp_app_path_name + "/Contents/MacOS");
- err = tmp_app_path->make_dir_recursive(tmp_app_path_name + "/Contents/MacOS");
+ err = tmp_app_dir->make_dir_recursive(tmp_app_path_name + "/Contents/MacOS");
}
if (err == OK) {
print_line("Creating " + tmp_app_path_name + "/Contents/Frameworks");
- err = tmp_app_path->make_dir_recursive(tmp_app_path_name + "/Contents/Frameworks");
+ err = tmp_app_dir->make_dir_recursive(tmp_app_path_name + "/Contents/Frameworks");
}
if (err == OK) {
print_line("Creating " + tmp_app_path_name + "/Contents/Resources");
- err = tmp_app_path->make_dir_recursive(tmp_app_path_name + "/Contents/Resources");
+ err = tmp_app_dir->make_dir_recursive(tmp_app_path_name + "/Contents/Resources");
}
// Now process our template.
@@ -665,7 +665,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
Ref<Image> icon;
icon.instance();
icon->load(iconpath);
- if (!icon->empty()) {
+ if (!icon->is_empty()) {
_make_icon(icon, data);
}
}
@@ -678,14 +678,14 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
ret = unzGoToNextFile(src_pkg_zip);
continue; // skip
}
- file = file.replace("/data.mono.osx.64.release_debug/", "/data_" + pkg_name_safe + "/");
+ file = file.replace("/data.mono.osx.64.release_debug/", "/data_" + pkg_name + "/");
}
if (file.find("/data.mono.osx.64.release/") != -1) {
if (p_debug) {
ret = unzGoToNextFile(src_pkg_zip);
continue; // skip
}
- file = file.replace("/data.mono.osx.64.release/", "/data_" + pkg_name_safe + "/");
+ file = file.replace("/data.mono.osx.64.release/", "/data_" + pkg_name + "/");
}
print_line("ADDING: " + file + " size: " + itos(data.size()));
@@ -694,7 +694,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
// Write it into our application bundle.
file = tmp_app_path_name.plus_file(file);
if (err == OK) {
- err = tmp_app_path->make_dir_recursive(file.get_base_dir());
+ err = tmp_app_dir->make_dir_recursive(file.get_base_dir());
}
if (err == OK) {
FileAccess *f = FileAccess::open(file, FileAccess::WRITE);
@@ -797,7 +797,10 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
}
// Clean up temporary .app dir.
- OS::get_singleton()->move_to_trash(tmp_app_path_name);
+ tmp_app_dir->change_dir(tmp_app_path_name);
+ tmp_app_dir->erase_contents_recursive();
+ tmp_app_dir->change_dir("..");
+ tmp_app_dir->remove(tmp_app_dir_name);
}
return err;
@@ -924,7 +927,7 @@ bool EditorExportPlatformOSX::can_export(const Ref<EditorExportPreset> &p_preset
}
}
- if (!err.empty()) {
+ if (!err.is_empty()) {
r_error = err;
}
return valid;
diff --git a/platform/osx/export/export.h b/platform/osx/export/export.h
index 4ddcec09fb..f8cf41c0e7 100644
--- a/platform/osx/export/export.h
+++ b/platform/osx/export/export.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/osx/godot_main_osx.mm b/platform/osx/godot_main_osx.mm
index 4e73d5441c..7e7dbf6afb 100644
--- a/platform/osx/godot_main_osx.mm
+++ b/platform/osx/godot_main_osx.mm
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/osx/joypad_osx.cpp b/platform/osx/joypad_osx.cpp
index cfc371710b..0b6a0e20a6 100644
--- a/platform/osx/joypad_osx.cpp
+++ b/platform/osx/joypad_osx.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -37,14 +37,6 @@
static JoypadOSX *self = nullptr;
joypad::joypad() {
- device_ref = nullptr;
- ff_device = nullptr;
- ff_axes = nullptr;
- ff_directions = nullptr;
- ffservice = 0;
- ff_timestamp = 0;
- id = 0;
-
ff_constant_force.lMagnitude = 10000;
ff_effect.dwDuration = 0;
ff_effect.dwSamplePeriod = 0;
diff --git a/platform/osx/joypad_osx.h b/platform/osx/joypad_osx.h
index dc238e68e4..bf7e8949df 100644
--- a/platform/osx/joypad_osx.h
+++ b/platform/osx/joypad_osx.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -46,10 +46,10 @@ struct rec_element {
IOHIDElementRef ref;
IOHIDElementCookie cookie;
- uint32_t usage;
+ uint32_t usage = 0;
- int min;
- int max;
+ int min = 0;
+ int max = 0;
struct Comparator {
bool operator()(const rec_element p_a, const rec_element p_b) const { return p_a.usage < p_b.usage; }
@@ -57,22 +57,22 @@ struct rec_element {
};
struct joypad {
- IOHIDDeviceRef device_ref;
+ IOHIDDeviceRef device_ref = nullptr;
Vector<rec_element> axis_elements;
Vector<rec_element> button_elements;
Vector<rec_element> hat_elements;
- int id;
+ int id = 0;
- io_service_t ffservice; /* Interface for force feedback, 0 = no ff */
+ io_service_t ffservice = 0; /* Interface for force feedback, 0 = no ff */
FFCONSTANTFORCE ff_constant_force;
FFDeviceObjectReference ff_device;
FFEffectObjectReference ff_object;
- uint64_t ff_timestamp;
- LONG *ff_directions;
+ uint64_t ff_timestamp = 0;
+ LONG *ff_directions = nullptr;
FFEFFECT ff_effect;
- DWORD *ff_axes;
+ DWORD *ff_axes = nullptr;
void add_hid_elements(CFArrayRef p_array);
void add_hid_element(IOHIDElementRef p_element);
diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h
index 5a9e43450f..d57940775d 100644
--- a/platform/osx/os_osx.h
+++ b/platform/osx/os_osx.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -40,7 +40,7 @@
#include "servers/audio_server.h"
class OS_OSX : public OS_Unix {
- virtual void delete_main_loop();
+ virtual void delete_main_loop() override;
bool force_quit;
@@ -61,45 +61,45 @@ public:
String open_with_filename;
protected:
- virtual void initialize_core();
- virtual void initialize();
- virtual void finalize();
+ virtual void initialize_core() override;
+ virtual void initialize() override;
+ virtual void finalize() override;
- virtual void initialize_joypads();
+ virtual void initialize_joypads() override;
- virtual void set_main_loop(MainLoop *p_main_loop);
+ virtual void set_main_loop(MainLoop *p_main_loop) override;
public:
- virtual String get_name() const;
+ virtual String get_name() const override;
- virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false);
+ virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false) override;
- virtual MainLoop *get_main_loop() const;
+ virtual MainLoop *get_main_loop() const override;
- virtual String get_config_path() const;
- virtual String get_data_path() const;
- virtual String get_cache_path() const;
- virtual String get_bundle_resource_dir() const;
- virtual String get_godot_dir_name() const;
+ virtual String get_config_path() const override;
+ virtual String get_data_path() const override;
+ virtual String get_cache_path() const override;
+ virtual String get_bundle_resource_dir() const override;
+ virtual String get_godot_dir_name() const override;
- virtual String get_system_dir(SystemDir p_dir) const;
+ virtual String get_system_dir(SystemDir p_dir) const override;
- Error shell_open(String p_uri);
+ Error shell_open(String p_uri) override;
- String get_locale() const;
+ String get_locale() const override;
- virtual String get_executable_path() const;
+ virtual String get_executable_path() const override;
- virtual String get_unique_id() const; //++
+ virtual String get_unique_id() const override; //++
- virtual bool _check_internal_feature_support(const String &p_feature);
+ virtual bool _check_internal_feature_support(const String &p_feature) override;
void run();
- void disable_crash_handler();
- bool is_disable_crash_handler() const;
+ virtual void disable_crash_handler() override;
+ virtual bool is_disable_crash_handler() const override;
- virtual Error move_to_trash(const String &p_path);
+ virtual Error move_to_trash(const String &p_path) override;
OS_OSX();
};
diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm
index 399a29cbe0..7b5daf5bfb 100644
--- a/platform/osx/os_osx.mm
+++ b/platform/osx/os_osx.mm
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -99,7 +99,7 @@ public:
String OS_OSX::get_unique_id() const {
static String serial_number;
- if (serial_number.empty()) {
+ if (serial_number.is_empty()) {
io_service_t platformExpert = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice"));
CFStringRef serialNumberAsCFString = NULL;
if (platformExpert) {
@@ -286,7 +286,7 @@ Error OS_OSX::shell_open(String p_uri) {
String OS_OSX::get_locale() const {
NSString *locale_code = [[NSLocale preferredLanguages] objectAtIndex:0];
- return [locale_code UTF8String];
+ return String([locale_code UTF8String]).replace("-", "_");
}
String OS_OSX::get_executable_path() const {
@@ -312,7 +312,7 @@ void OS_OSX::run() {
if (!main_loop)
return;
- main_loop->init();
+ main_loop->initialize();
bool quit = false;
while (!force_quit && !quit) {
@@ -329,7 +329,7 @@ void OS_OSX::run() {
ERR_PRINT("NSException: " + String([exception reason].UTF8String));
}
};
- main_loop->finish();
+ main_loop->finalize();
}
Error OS_OSX::move_to_trash(const String &p_path) {
diff --git a/platform/osx/platform_config.h b/platform/osx/platform_config.h
index e657aca955..2d0fd872dc 100644
--- a/platform/osx/platform_config.h
+++ b/platform/osx/platform_config.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/osx/vulkan_context_osx.h b/platform/osx/vulkan_context_osx.h
index e996f176a9..8b6a75adfb 100644
--- a/platform/osx/vulkan_context_osx.h
+++ b/platform/osx/vulkan_context_osx.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/osx/vulkan_context_osx.mm b/platform/osx/vulkan_context_osx.mm
index ec8745ff01..75a4fc990f 100644
--- a/platform/osx/vulkan_context_osx.mm
+++ b/platform/osx/vulkan_context_osx.mm
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/register_platform_apis.h b/platform/register_platform_apis.h
index 6b962f5d91..4cf84b321f 100644
--- a/platform/register_platform_apis.h
+++ b/platform/register_platform_apis.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/server/detect.py b/platform/server/detect.py
index d9ac357679..1c3fa990fe 100644
--- a/platform/server/detect.py
+++ b/platform/server/detect.py
@@ -21,7 +21,6 @@ def get_program_suffix():
def can_build():
-
if os.name != "posix":
return False
@@ -33,20 +32,19 @@ def get_opts():
return [
BoolVariable("use_llvm", "Use the LLVM compiler", False),
- BoolVariable("use_static_cpp", "Link libgcc and libstdc++ statically for better portability", False),
+ BoolVariable("use_static_cpp", "Link libgcc and libstdc++ statically for better portability", True),
BoolVariable("use_coverage", "Test Godot coverage", False),
BoolVariable("use_ubsan", "Use LLVM/GCC compiler undefined behavior sanitizer (UBSAN)", False),
BoolVariable("use_asan", "Use LLVM/GCC compiler address sanitizer (ASAN))", False),
BoolVariable("use_lsan", "Use LLVM/GCC compiler leak sanitizer (LSAN))", False),
BoolVariable("use_tsan", "Use LLVM/GCC compiler thread sanitizer (TSAN))", False),
- EnumVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", "yes", ("yes", "no")),
+ BoolVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", True),
BoolVariable("separate_debug_symbols", "Create a separate file containing debugging symbols", False),
BoolVariable("execinfo", "Use libexecinfo on systems where glibc is not available", False),
]
def get_flags():
-
return []
@@ -60,7 +58,7 @@ def configure(env):
else: # optimize for size
env.Prepend(CCFLAGS=["-Os"])
- if env["debug_symbols"] == "yes":
+ if env["debug_symbols"]:
env.Prepend(CCFLAGS=["-g2"])
elif env["target"] == "release_debug":
@@ -70,7 +68,7 @@ def configure(env):
env.Prepend(CCFLAGS=["-Os"])
env.Prepend(CPPDEFINES=["DEBUG_ENABLED"])
- if env["debug_symbols"] == "yes":
+ if env["debug_symbols"]:
env.Prepend(CCFLAGS=["-g2"])
elif env["target"] == "debug":
@@ -138,14 +136,31 @@ def configure(env):
# freetype depends on libpng and zlib, so bundling one of them while keeping others
# as shared libraries leads to weird issues
- if env["builtin_freetype"] or env["builtin_libpng"] or env["builtin_zlib"]:
+ if (
+ env["builtin_freetype"]
+ or env["builtin_libpng"]
+ or env["builtin_zlib"]
+ or env["builtin_graphite"]
+ or env["builtin_harfbuzz"]
+ ):
env["builtin_freetype"] = True
env["builtin_libpng"] = True
env["builtin_zlib"] = True
+ env["builtin_graphite"] = True
+ env["builtin_harfbuzz"] = True
if not env["builtin_freetype"]:
env.ParseConfig("pkg-config freetype2 --cflags --libs")
+ if not env["builtin_graphite"]:
+ env.ParseConfig("pkg-config graphite2 --cflags --libs")
+
+ if not env["builtin_icu"]:
+ env.ParseConfig("pkg-config icu-uc --cflags --libs")
+
+ if not env["builtin_harfbuzz"]:
+ env.ParseConfig("pkg-config harfbuzz harfbuzz-icu --cflags --libs")
+
if not env["builtin_libpng"]:
env.ParseConfig("pkg-config libpng16 --cflags --libs")
@@ -233,7 +248,17 @@ def configure(env):
env.Append(CPPDEFINES=["SERVER_ENABLED", "UNIX_ENABLED"])
if platform.system() == "Darwin":
- env.Append(LINKFLAGS=["-framework", "Cocoa", "-framework", "Carbon", "-lz", "-framework", "IOKit"])
+ env.Append(
+ LINKFLAGS=[
+ "-framework",
+ "Cocoa",
+ "-framework",
+ "Carbon",
+ "-lz",
+ "-framework",
+ "IOKit",
+ ]
+ )
env.Append(LIBS=["pthread"])
diff --git a/platform/server/godot_server.cpp b/platform/server/godot_server.cpp
index 9f22240a80..1ced95fcbc 100644
--- a/platform/server/godot_server.cpp
+++ b/platform/server/godot_server.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/server/os_server.cpp b/platform/server/os_server.cpp
index 9937ae5b62..852ec7c4ef 100644
--- a/platform/server/os_server.cpp
+++ b/platform/server/os_server.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -33,7 +33,7 @@
#include "core/string/print_string.h"
#include "drivers/dummy/rasterizer_dummy.h"
#include "drivers/dummy/texture_loader_dummy.h"
-#include "servers/rendering/rendering_server_raster.h"
+#include "servers/rendering/rendering_server_default.h"
#include "main/main.h"
@@ -49,14 +49,6 @@ const char *OS_Server::get_video_driver_name(int p_driver) const {
return "Dummy";
}
-int OS_Server::get_audio_driver_count() const {
- return 1;
-}
-
-const char *OS_Server::get_audio_driver_name(int p_driver) const {
- return "Dummy";
-}
-
int OS_Server::get_current_video_driver() const {
return video_driver_index;
}
@@ -76,7 +68,7 @@ Error OS_Server::initialize(const VideoMode &p_desired, int p_video_driver, int
video_driver_index = p_video_driver; // unused in server platform, but should still be initialized
- rendering_server = memnew(RenderingServerRaster);
+ rendering_server = memnew(RenderingServerDefault);
rendering_server->init();
AudioDriverManager::initialize(p_audio_driver);
@@ -158,10 +150,6 @@ void OS_Server::set_main_loop(MainLoop *p_main_loop) {
input->set_main_loop(p_main_loop);
}
-bool OS_Server::can_draw() const {
- return false; //can never draw
-};
-
String OS_Server::get_name() const {
return "Server";
}
diff --git a/platform/server/os_server.h b/platform/server/os_server.h
index 06ea483fd4..61025fa14b 100644
--- a/platform/server/os_server.h
+++ b/platform/server/os_server.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -41,28 +41,28 @@
#include "platform/x11/crash_handler_linuxbsd.h"
#endif
#include "servers/audio_server.h"
-#include "servers/rendering/rasterizer.h"
+#include "servers/rendering/renderer_compositor.h"
#include "servers/rendering_server.h"
#undef CursorShape
class OS_Server : public OS_Unix {
- RenderingServer *rendering_server;
+ RenderingServer *rendering_server = nullptr;
VideoMode current_videomode;
List<String> args;
- MainLoop *main_loop;
+ MainLoop *main_loop = nullptr;
- bool grab;
+ bool grab = false;
virtual void delete_main_loop();
- bool force_quit;
+ bool force_quit = false;
- InputDefault *input;
+ InputDefault *input = nullptr;
CrashHandler crash_handler;
- int video_driver_index;
+ int video_driver_index = 0;
Ref<ResourceFormatDummyTexture> resource_loader_dummy;
@@ -70,8 +70,6 @@ protected:
virtual int get_video_driver_count() const;
virtual const char *get_video_driver_name(int p_driver) const;
virtual int get_current_video_driver() const;
- virtual int get_audio_driver_count() const;
- virtual const char *get_audio_driver_name(int p_driver) const;
virtual void initialize_core();
virtual Error initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
@@ -91,8 +89,6 @@ public:
virtual MainLoop *get_main_loop() const;
- virtual bool can_draw() const;
-
virtual void set_video_mode(const VideoMode &p_video_mode, int p_screen = 0);
virtual VideoMode get_video_mode(int p_screen = 0) const;
virtual void get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen = 0) const;
diff --git a/platform/server/platform_config.h b/platform/server/platform_config.h
index 73136ec81b..32a19d811b 100644
--- a/platform/server/platform_config.h
+++ b/platform/server/platform_config.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/uwp/app.cpp b/platform/uwp/app.cpp
index 6090d13854..dc4238bdd4 100644
--- a/platform/uwp/app.cpp
+++ b/platform/uwp/app.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/uwp/app.h b/platform/uwp/app.h
index 5cffe378b1..0b02527dae 100644
--- a/platform/uwp/app.h
+++ b/platform/uwp/app.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/uwp/context_egl_uwp.cpp b/platform/uwp/context_egl_uwp.cpp
index 2da6c5897a..bb2a14e9fc 100644
--- a/platform/uwp/context_egl_uwp.cpp
+++ b/platform/uwp/context_egl_uwp.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -204,7 +204,8 @@ ContextEGL_UWP::ContextEGL_UWP(CoreWindow ^ p_window, Driver p_driver) :
mEglContext(EGL_NO_CONTEXT),
mEglSurface(EGL_NO_SURFACE),
driver(p_driver),
- window(p_window) {}
+ window(p_window),
+ vsync(false) {}
ContextEGL_UWP::~ContextEGL_UWP() {
cleanup();
diff --git a/platform/uwp/context_egl_uwp.h b/platform/uwp/context_egl_uwp.h
index 5e7dc1802d..974faa3ac7 100644
--- a/platform/uwp/context_egl_uwp.h
+++ b/platform/uwp/context_egl_uwp.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/uwp/detect.py b/platform/uwp/detect.py
index 2af7803749..fda8fdec66 100644
--- a/platform/uwp/detect.py
+++ b/platform/uwp/detect.py
@@ -30,7 +30,6 @@ def get_opts():
def get_flags():
-
return [
("tools", False),
("xaudio2", True),
@@ -39,7 +38,6 @@ def get_flags():
def configure(env):
-
env.msvc = True
if env["bits"] != "default":
diff --git a/platform/uwp/export/export.cpp b/platform/uwp/export/export.cpp
index 30568241a9..1aad2bfa1a 100644
--- a/platform/uwp/export/export.cpp
+++ b/platform/uwp/export/export.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -108,7 +108,7 @@ class AppxPackager {
struct BlockHash {
String base64_hash;
- size_t compressed_size;
+ size_t compressed_size = 0;
};
struct FileMeta {
@@ -120,12 +120,10 @@ class AppxPackager {
Vector<BlockHash> hashes;
uLong file_crc32 = 0;
ZPOS64_T zip_offset = 0;
-
- FileMeta() {}
};
String progress_task;
- FileAccess *package;
+ FileAccess *package = nullptr;
Set<String> mime_types;
@@ -643,7 +641,7 @@ class EditorExportPlatformUWP : public EditorExportPlatform {
};
bool _valid_resource_name(const String &p_name) const {
- if (p_name.empty()) {
+ if (p_name.is_empty()) {
return false;
}
if (p_name.ends_with(".")) {
@@ -689,7 +687,7 @@ class EditorExportPlatformUWP : public EditorExportPlatform {
}
bool _valid_bgcolor(const String &p_color) const {
- if (p_color.empty()) {
+ if (p_color.is_empty()) {
return true;
}
if (p_color.begins_with("#") && p_color.is_valid_html_color()) {
@@ -762,10 +760,10 @@ class EditorExportPlatformUWP : public EditorExportPlatform {
result = result.replace("$version_string$", version);
Platform arch = (Platform)(int)p_preset->get("architecture/target");
- String architecture = arch == ARM ? "arm" : arch == X86 ? "x86" : "x64";
+ String architecture = arch == ARM ? "arm" : (arch == X86 ? "x86" : "x64");
result = result.replace("$architecture$", architecture);
- result = result.replace("$display_name$", String(p_preset->get("package/display_name")).empty() ? (String)ProjectSettings::get_singleton()->get("application/config/name") : String(p_preset->get("package/display_name")));
+ result = result.replace("$display_name$", String(p_preset->get("package/display_name")).is_empty() ? (String)ProjectSettings::get_singleton()->get("application/config/name") : String(p_preset->get("package/display_name")));
result = result.replace("$publisher_display_name$", p_preset->get("package/publisher_display_name"));
result = result.replace("$app_description$", p_preset->get("package/description"));
@@ -784,7 +782,7 @@ class EditorExportPlatformUWP : public EditorExportPlatform {
}
String show_name_on_tiles = "";
- if (!name_on_tiles.empty()) {
+ if (!name_on_tiles.is_empty()) {
show_name_on_tiles = "<uap:ShowNameOnTiles>\n" + name_on_tiles + " </uap:ShowNameOnTiles>";
}
@@ -805,7 +803,7 @@ class EditorExportPlatformUWP : public EditorExportPlatform {
}
String rotation_preference = "";
- if (!rotations.empty()) {
+ if (!rotations.is_empty()) {
rotation_preference = "<uap:InitialRotationPreference>\n" + rotations + " </uap:InitialRotationPreference>";
}
@@ -839,7 +837,7 @@ class EditorExportPlatformUWP : public EditorExportPlatform {
}
String capabilities_string = "<Capabilities />";
- if (!capabilities_elements.empty()) {
+ if (!capabilities_elements.is_empty()) {
capabilities_string = "<Capabilities>\n" + capabilities_elements + " </Capabilities>";
}
@@ -1413,7 +1411,7 @@ public:
args.push_back(cert_pass);
args.push_back(p_path);
- OS::get_singleton()->execute(signtool_path, args, true);
+ OS::get_singleton()->execute(signtool_path, args);
#endif // WINDOWS_ENABLED
return OK;
diff --git a/platform/uwp/export/export.h b/platform/uwp/export/export.h
index 1a1555d8ee..bc23cad38c 100644
--- a/platform/uwp/export/export.h
+++ b/platform/uwp/export/export.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/uwp/joypad_uwp.cpp b/platform/uwp/joypad_uwp.cpp
index 4fdfde9673..5da90db49d 100644
--- a/platform/uwp/joypad_uwp.cpp
+++ b/platform/uwp/joypad_uwp.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/uwp/joypad_uwp.h b/platform/uwp/joypad_uwp.h
index 13f246a438..5df4a211ac 100644
--- a/platform/uwp/joypad_uwp.h
+++ b/platform/uwp/joypad_uwp.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -58,21 +58,12 @@ private:
struct ControllerDevice {
Windows::Gaming::Input::IGameController ^ controller_reference;
- int id;
- bool connected;
- ControllerType type;
- float ff_timestamp;
- float ff_end_timestamp;
- bool vibrating;
-
- ControllerDevice() {
- id = -1;
- connected = false;
- type = ControllerType::GAMEPAD_CONTROLLER;
- ff_timestamp = 0.0f;
- ff_end_timestamp = 0.0f;
- vibrating = false;
- }
+ int id = -1;
+ bool connected = false;
+ ControllerType type = ControllerType::GAMEPAD_CONTROLLER;
+ float ff_timestamp = 0;
+ float ff_end_timestamp = 0;
+ bool vibrating = false;
};
ControllerDevice controllers[MAX_CONTROLLERS];
diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp
index 79508055e5..fa97948395 100644
--- a/platform/uwp/os_uwp.cpp
+++ b/platform/uwp/os_uwp.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -39,14 +39,11 @@
#include "drivers/windows/dir_access_windows.h"
#include "drivers/windows/file_access_windows.h"
#include "drivers/windows/mutex_windows.h"
-#include "drivers/windows/rw_lock_windows.h"
#include "drivers/windows/semaphore_windows.h"
#include "main/main.h"
#include "platform/windows/windows_terminal_logger.h"
#include "servers/audio_server.h"
-#include "servers/rendering/rendering_server_raster.h"
-#include "servers/rendering/rendering_server_wrap_mt.h"
-#include "thread_uwp.h"
+#include "servers/rendering/rendering_server_default.h"
#include <ppltasks.h>
#include <wrl.h>
@@ -131,9 +128,6 @@ void OS_UWP::initialize_core() {
//RedirectIOToConsole();
- ThreadUWP::make_default();
- RWLockWindows::make_default();
-
FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_RESOURCES);
FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_USERDATA);
FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_FILESYSTEM);
@@ -156,10 +150,6 @@ void OS_UWP::initialize_core() {
cursor_shape = CURSOR_ARROW;
}
-bool OS_UWP::can_draw() const {
- return !minimized;
-};
-
void OS_UWP::set_window(Windows::UI::Core::CoreWindow ^ p_window) {
window = p_window;
}
@@ -240,7 +230,7 @@ Error OS_UWP::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
set_video_mode(vm);
- rendering_server = memnew(RenderingServerRaster);
+ rendering_server = memnew(RenderingServerDefault);
// FIXME: Reimplement threaded rendering
if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {
rendering_server = memnew(RenderingServerWrapMT(rendering_server, false));
@@ -642,7 +632,11 @@ void OS_UWP::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c
// TODO
}
-Error OS_UWP::execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex) {
+Error OS_UWP::execute(const String &p_path, const List<String> &p_arguments, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex) {
+ return FAILED;
+};
+
+Error OS_UWP::create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id) {
return FAILED;
};
diff --git a/platform/uwp/os_uwp.h b/platform/uwp/os_uwp.h
index 88961bf143..a4d3d6d52a 100644
--- a/platform/uwp/os_uwp.h
+++ b/platform/uwp/os_uwp.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -39,7 +39,7 @@
#include "drivers/xaudio2/audio_driver_xaudio2.h"
#include "joypad_uwp.h"
#include "servers/audio_server.h"
-#include "servers/rendering/rasterizer.h"
+#include "servers/rendering/renderer_compositor.h"
#include "servers/rendering_server.h"
#include <fcntl.h>
@@ -55,13 +55,13 @@ public:
CHAR_EVENT_MESSAGE
};
- bool alt, shift, control;
- MessageType type;
- bool pressed;
- unsigned int keycode;
- unsigned int physical_keycode;
- unsigned int unicode;
- bool echo;
+ bool alt = false, shift = false, control = false;
+ MessageType type = KEY_EVENT_MESSAGE;
+ bool pressed = false;
+ unsigned int keycode = 0;
+ unsigned int physical_keycode = 0;
+ unsigned int unicode = 0;
+ bool echo = false;
CorePhysicalKeyStatus status;
};
@@ -194,13 +194,13 @@ public:
virtual TimeZoneInfo get_time_zone_info() const;
virtual uint64_t get_unix_time() const;
- virtual bool can_draw() const;
virtual Error set_cwd(const String &p_cwd);
virtual void delay_usec(uint32_t p_usec) const;
virtual uint64_t get_ticks_usec() const;
- virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking = true, ProcessID *r_child_id = nullptr, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr);
+ virtual Error execute(const String &p_path, const List<String> &p_arguments, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr);
+ virtual Error create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id = nullptr);
virtual Error kill(const ProcessID &p_pid);
virtual bool has_environment(const String &p_var) const;
diff --git a/platform/uwp/platform_config.h b/platform/uwp/platform_config.h
index 09a16614e0..481f583f6f 100644
--- a/platform/uwp/platform_config.h
+++ b/platform/uwp/platform_config.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/windows/SCsub b/platform/windows/SCsub
index 0c9aa77803..47d8e14680 100644
--- a/platform/windows/SCsub
+++ b/platform/windows/SCsub
@@ -32,5 +32,5 @@ if env["vsproj"]:
env.vs_srcs += ["platform/windows/" + str(x)]
if not os.getenv("VCINSTALLDIR"):
- if env["debug_symbols"] == "yes" and env["separate_debug_symbols"]:
+ if env["debug_symbols"] and env["separate_debug_symbols"]:
env.AddPostAction(prog, run_in_subprocess(platform_windows_builders.make_debug_mingw))
diff --git a/platform/windows/context_gl_windows.cpp b/platform/windows/context_gl_windows.cpp
index 1c32639a38..207b0a1168 100644
--- a/platform/windows/context_gl_windows.cpp
+++ b/platform/windows/context_gl_windows.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -211,6 +211,7 @@ ContextGL_Windows::ContextGL_Windows(HWND hwnd, bool p_opengl_3_context) {
hWnd = hwnd;
use_vsync = false;
vsync_via_compositor = false;
+ pixel_format = 0;
}
ContextGL_Windows::~ContextGL_Windows() {
diff --git a/platform/windows/context_gl_windows.h b/platform/windows/context_gl_windows.h
index 0013177609..e44e2945ca 100644
--- a/platform/windows/context_gl_windows.h
+++ b/platform/windows/context_gl_windows.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/windows/crash_handler_windows.cpp b/platform/windows/crash_handler_windows.cpp
index 7abf451062..e24e466f88 100644
--- a/platform/windows/crash_handler_windows.cpp
+++ b/platform/windows/crash_handler_windows.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -57,7 +57,7 @@
struct module_data {
std::string image_name;
std::string module_name;
- void *base_address;
+ void *base_address = nullptr;
DWORD load_size;
};
diff --git a/platform/windows/crash_handler_windows.h b/platform/windows/crash_handler_windows.h
index 66a4cac296..e1ec8e6787 100644
--- a/platform/windows/crash_handler_windows.h
+++ b/platform/windows/crash_handler_windows.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/windows/detect.py b/platform/windows/detect.py
index e0b2a52014..f26dea8d35 100644
--- a/platform/windows/detect.py
+++ b/platform/windows/detect.py
@@ -64,23 +64,22 @@ def get_opts():
# XP support dropped after EOL due to missing API for IPv6 and other issues
# Vista support dropped after EOL due to GH-10243
("target_win_version", "Targeted Windows version, >= 0x0601 (Windows 7)", "0x0601"),
- EnumVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", "yes", ("yes", "no")),
+ BoolVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", True),
EnumVariable("windows_subsystem", "Windows subsystem", "default", ("default", "console", "gui")),
BoolVariable("separate_debug_symbols", "Create a separate file containing debugging symbols", False),
("msvc_version", "MSVC version to use. Ignored if VCINSTALLDIR is set in shell env.", None),
- BoolVariable("use_mingw", "Use the Mingw compiler, even if MSVC is installed. Only used on Windows.", False),
+ BoolVariable("use_mingw", "Use the Mingw compiler, even if MSVC is installed.", False),
BoolVariable("use_llvm", "Use the LLVM compiler", False),
BoolVariable("use_thinlto", "Use ThinLTO", False),
+ BoolVariable("use_static_cpp", "Link MinGW/MSVC C++ runtime libraries statically", True),
]
def get_flags():
-
return []
def build_res_file(target, source, env):
-
if env["bits"] == "32":
cmdbase = env["mingw_prefix_32"]
else:
@@ -94,7 +93,7 @@ def build_res_file(target, source, env):
out = subprocess.Popen(cmd, shell=True, stderr=subprocess.PIPE).communicate()
if len(out[1]):
return 1
- except:
+ except Exception:
return 1
return 0
@@ -205,12 +204,12 @@ def configure_msvc(env, manual_msvc_config):
env.Append(LINKFLAGS=["/OPT:REF"])
elif env["target"] == "debug":
- env.AppendUnique(CCFLAGS=["/Z7", "/Od", "/EHsc"])
+ env.AppendUnique(CCFLAGS=["/Zi", "/FS", "/Od", "/EHsc"])
env.AppendUnique(CPPDEFINES=["DEBUG_ENABLED"])
env.Append(LINKFLAGS=["/DEBUG"])
- if env["debug_symbols"] == "yes":
- env.AppendUnique(CCFLAGS=["/Z7"])
+ if env["debug_symbols"]:
+ env.AppendUnique(CCFLAGS=["/Zi", "/FS"])
env.AppendUnique(LINKFLAGS=["/DEBUG"])
if env["windows_subsystem"] == "gui":
@@ -221,7 +220,12 @@ def configure_msvc(env, manual_msvc_config):
## Compile/link flags
- env.AppendUnique(CCFLAGS=["/MT", "/Gd", "/GR", "/nologo"])
+ if env["use_static_cpp"]:
+ env.AppendUnique(CCFLAGS=["/MT"])
+ else:
+ env.AppendUnique(CCFLAGS=["/MD"])
+
+ env.AppendUnique(CCFLAGS=["/Gd", "/GR", "/nologo"])
# Force to use Unicode encoding
env.AppendUnique(CCFLAGS=["/utf-8"])
env.AppendUnique(CXXFLAGS=["/TP"]) # assume all sources are C++
@@ -336,13 +340,13 @@ def configure_mingw(env):
else: # optimize for size
env.Prepend(CCFLAGS=["-Os"])
- if env["debug_symbols"] == "yes":
+ if env["debug_symbols"]:
env.Prepend(CCFLAGS=["-g2"])
elif env["target"] == "release_debug":
env.Append(CCFLAGS=["-O2"])
env.Append(CPPDEFINES=["DEBUG_ENABLED"])
- if env["debug_symbols"] == "yes":
+ if env["debug_symbols"]:
env.Prepend(CCFLAGS=["-g2"])
if env["optimize"] == "speed": # optimize for speed (default)
env.Append(CCFLAGS=["-O2"])
@@ -373,12 +377,14 @@ def configure_mingw(env):
mingw_prefix = ""
if env["bits"] == "32":
- env.Append(LINKFLAGS=["-static"])
- env.Append(LINKFLAGS=["-static-libgcc"])
- env.Append(LINKFLAGS=["-static-libstdc++"])
+ if env["use_static_cpp"]:
+ env.Append(LINKFLAGS=["-static"])
+ env.Append(LINKFLAGS=["-static-libgcc"])
+ env.Append(LINKFLAGS=["-static-libstdc++"])
mingw_prefix = env["mingw_prefix_32"]
else:
- env.Append(LINKFLAGS=["-static"])
+ if env["use_static_cpp"]:
+ env.Append(LINKFLAGS=["-static"])
mingw_prefix = env["mingw_prefix_64"]
if env["use_llvm"]:
diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp
index dfbb734ee4..b9b78f7bd4 100644
--- a/platform/windows/display_server_windows.cpp
+++ b/platform/windows/display_server_windows.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -535,7 +535,7 @@ void DisplayServerWindows::delete_sub_window(WindowID p_window) {
}
#endif
- if ((OS::get_singleton()->get_current_tablet_driver() == "wintab") && wintab_available && windows[p_window].wtctx) {
+ if ((tablet_get_current_driver() == "wintab") && wintab_available && windows[p_window].wtctx) {
wintab_WTClose(windows[p_window].wtctx);
windows[p_window].wtctx = 0;
}
@@ -903,6 +903,9 @@ void DisplayServerWindows::_get_window_style(bool p_main_window, bool p_fullscre
r_style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU;
}
}
+ if (!p_borderless) {
+ r_style |= WS_VISIBLE;
+ }
if (p_no_activate_focus) {
r_style_ex |= WS_EX_TOPMOST | WS_EX_NOACTIVATE;
@@ -910,7 +913,7 @@ void DisplayServerWindows::_get_window_style(bool p_main_window, bool p_fullscre
r_style |= WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
}
-void DisplayServerWindows::_update_window_style(WindowID p_window, bool p_repaint, bool p_maximized) {
+void DisplayServerWindows::_update_window_style(WindowID p_window, bool p_repaint) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -943,6 +946,7 @@ void DisplayServerWindows::window_set_mode(WindowMode p_mode, WindowID p_window)
RECT rect;
wd.fullscreen = false;
+ wd.maximized = wd.was_maximized;
if (wd.pre_fs_valid) {
rect = wd.pre_fs_rect;
@@ -951,13 +955,16 @@ void DisplayServerWindows::window_set_mode(WindowMode p_mode, WindowID p_window)
rect.right = wd.width;
rect.top = 0;
rect.bottom = wd.height;
+ wd.pre_fs_valid = true;
}
- _update_window_style(p_window, false, wd.was_maximized);
+ _update_window_style(p_window, false);
MoveWindow(wd.hWnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, TRUE);
-
- wd.pre_fs_valid = true;
+ } else if (p_mode == WINDOW_MODE_WINDOWED) {
+ ShowWindow(wd.hWnd, SW_RESTORE);
+ wd.maximized = false;
+ wd.minimized = false;
}
if (p_mode == WINDOW_MODE_MAXIMIZED) {
@@ -966,12 +973,6 @@ void DisplayServerWindows::window_set_mode(WindowMode p_mode, WindowID p_window)
wd.minimized = false;
}
- if (p_mode == WINDOW_MODE_WINDOWED) {
- ShowWindow(wd.hWnd, SW_RESTORE);
- wd.maximized = false;
- wd.minimized = false;
- }
-
if (p_mode == WINDOW_MODE_MINIMIZED) {
ShowWindow(wd.hWnd, SW_MINIMIZE);
wd.maximized = false;
@@ -1783,7 +1784,10 @@ void DisplayServerWindows::_dispatch_input_event(const Ref<InputEvent> &p_event)
Ref<InputEventFromWindow> event_from_window = p_event;
if (event_from_window.is_valid() && event_from_window->get_window_id() != INVALID_WINDOW_ID) {
//send to a window
- ERR_FAIL_COND(!windows.has(event_from_window->get_window_id()));
+ if (!windows.has(event_from_window->get_window_id())) {
+ in_dispatch_input_event = false;
+ ERR_FAIL_MSG("DisplayServerWindows: Invalid window id in input event.");
+ }
Callable callable = windows[event_from_window->get_window_id()].input_event_callback;
if (callable.is_null()) {
in_dispatch_input_event = false;
@@ -1875,27 +1879,16 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
break;
}
- case WM_ACTIVATE: // Watch For Window Activate Message
- {
- windows[window_id].minimized = HIWORD(wParam) != 0;
-
- if (LOWORD(wParam) == WA_ACTIVE || LOWORD(wParam) == WA_CLICKACTIVE) {
- _send_window_event(windows[window_id], WINDOW_EVENT_FOCUS_IN);
- windows[window_id].window_focused = true;
- alt_mem = false;
- control_mem = false;
- shift_mem = false;
- } else { // WM_INACTIVE
- Input::get_singleton()->release_pressed_events();
- _send_window_event(windows[window_id], WINDOW_EVENT_FOCUS_OUT);
- windows[window_id].window_focused = false;
- alt_mem = false;
- };
+ case WM_ACTIVATE: { // Watch For Window Activate Message
+ if (!windows[window_id].window_focused) {
+ _process_activate_event(window_id, wParam, lParam);
+ } else {
+ windows[window_id].saved_wparam = wParam;
+ windows[window_id].saved_lparam = lParam;
- if ((OS::get_singleton()->get_current_tablet_driver() == "wintab") && wintab_available && windows[window_id].wtctx) {
- wintab_WTEnable(windows[window_id].wtctx, GET_WM_ACTIVATE_STATE(wParam, lParam));
+ // Run a timer to prevent event catching warning if the focused window is closing.
+ windows[window_id].focus_timer_id = SetTimer(windows[window_id].hWnd, 2, USER_TIMER_MINIMUM, (TIMERPROC) nullptr);
}
-
return 0; // Return To The Message Loop
}
case WM_GETMINMAXINFO: {
@@ -1936,6 +1929,9 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
case WM_CLOSE: // Did We Receive A Close Message?
{
+ if (windows[window_id].focus_timer_id != 0U) {
+ KillTimer(windows[window_id].hWnd, windows[window_id].focus_timer_id);
+ }
_send_window_event(windows[window_id], WINDOW_EVENT_CLOSE_REQUEST);
return 0; // Jump Back
@@ -2025,7 +2021,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
} break;
case WT_CSRCHANGE:
case WT_PROXIMITY: {
- if ((OS::get_singleton()->get_current_tablet_driver() == "wintab") && wintab_available && windows[window_id].wtctx) {
+ if ((tablet_get_current_driver() == "wintab") && wintab_available && windows[window_id].wtctx) {
AXIS pressure;
if (wintab_WTInfo(WTI_DEVICES + windows[window_id].wtlc.lcDevice, DVC_NPRESSURE, &pressure)) {
windows[window_id].min_pressure = int(pressure.axMin);
@@ -2039,7 +2035,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
}
} break;
case WT_PACKET: {
- if ((OS::get_singleton()->get_current_tablet_driver() == "wintab") && wintab_available && windows[window_id].wtctx) {
+ if ((tablet_get_current_driver() == "wintab") && wintab_available && windows[window_id].wtctx) {
PACKET packet;
if (wintab_WTPacket(windows[window_id].wtctx, wParam, &packet)) {
float pressure = float(packet.pkNormalPressure - windows[window_id].min_pressure) / float(windows[window_id].max_pressure - windows[window_id].min_pressure);
@@ -2118,7 +2114,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
break;
}
- if ((OS::get_singleton()->get_current_tablet_driver() != "winink") || !winink_available) {
+ if ((tablet_get_current_driver() != "winink") || !winink_available) {
break;
}
@@ -2144,7 +2140,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
break;
}
- if ((OS::get_singleton()->get_current_tablet_driver() != "winink") || !winink_available) {
+ if ((tablet_get_current_driver() != "winink") || !winink_available) {
break;
}
@@ -2308,7 +2304,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
mm->set_shift((wParam & MK_SHIFT) != 0);
mm->set_alt(alt_mem);
- if ((OS::get_singleton()->get_current_tablet_driver() == "wintab") && wintab_available && windows[window_id].wtctx) {
+ if ((tablet_get_current_driver() == "wintab") && wintab_available && windows[window_id].wtctx) {
// Note: WinTab sends both WT_PACKET and WM_xBUTTONDOWN/UP/MOUSEMOVE events, use mouse 1/0 pressure only when last_pressure was not update recently.
if (windows[window_id].last_pressure_update < 10) {
windows[window_id].last_pressure_update++;
@@ -2618,17 +2614,21 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
case WM_ENTERSIZEMOVE: {
Input::get_singleton()->release_pressed_events();
- move_timer_id = SetTimer(windows[window_id].hWnd, 1, USER_TIMER_MINIMUM, (TIMERPROC) nullptr);
+ windows[window_id].move_timer_id = SetTimer(windows[window_id].hWnd, 1, USER_TIMER_MINIMUM, (TIMERPROC) nullptr);
} break;
case WM_EXITSIZEMOVE: {
- KillTimer(windows[window_id].hWnd, move_timer_id);
+ KillTimer(windows[window_id].hWnd, windows[window_id].move_timer_id);
} break;
case WM_TIMER: {
- if (wParam == move_timer_id) {
+ if (wParam == windows[window_id].move_timer_id) {
_process_key_events();
if (!Main::is_iterating()) {
Main::iteration();
}
+ } else if (wParam == windows[window_id].focus_timer_id) {
+ _process_activate_event(window_id, windows[window_id].saved_wparam, windows[window_id].saved_lparam);
+ KillTimer(windows[window_id].hWnd, wParam);
+ windows[window_id].focus_timer_id = 0U;
}
} break;
@@ -2785,6 +2785,25 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
}
+void DisplayServerWindows::_process_activate_event(WindowID p_window_id, WPARAM wParam, LPARAM lParam) {
+ if (LOWORD(wParam) == WA_ACTIVE || LOWORD(wParam) == WA_CLICKACTIVE) {
+ _send_window_event(windows[p_window_id], WINDOW_EVENT_FOCUS_IN);
+ windows[p_window_id].window_focused = true;
+ alt_mem = false;
+ control_mem = false;
+ shift_mem = false;
+ } else { // WM_INACTIVE
+ Input::get_singleton()->release_pressed_events();
+ _send_window_event(windows[p_window_id], WINDOW_EVENT_FOCUS_OUT);
+ windows[p_window_id].window_focused = false;
+ alt_mem = false;
+ }
+
+ if ((tablet_get_current_driver() == "wintab") && wintab_available && windows[p_window_id].wtctx) {
+ wintab_WTEnable(windows[p_window_id].wtctx, GET_WM_ACTIVATE_STATE(wParam, lParam));
+ }
+}
+
void DisplayServerWindows::_process_key_events() {
for (int i = 0; i < key_event_pos; i++) {
KeyEvent &ke = key_event_buffer[i];
@@ -2792,6 +2811,24 @@ void DisplayServerWindows::_process_key_events() {
case WM_CHAR: {
// extended keys should only be processed as WM_KEYDOWN message.
if (!KeyMappingWindows::is_extended_key(ke.wParam) && ((i == 0 && ke.uMsg == WM_CHAR) || (i > 0 && key_event_buffer[i - 1].uMsg == WM_CHAR))) {
+ static char32_t prev_wc = 0;
+ char32_t unicode = ke.wParam;
+ if ((unicode & 0xfffffc00) == 0xd800) {
+ if (prev_wc != 0) {
+ ERR_PRINT("invalid utf16 surrogate input");
+ }
+ prev_wc = unicode;
+ break; // Skip surrogate.
+ } else if ((unicode & 0xfffffc00) == 0xdc00) {
+ if (prev_wc == 0) {
+ ERR_PRINT("invalid utf16 surrogate input");
+ break; // Skip invalid surrogate.
+ }
+ unicode = (prev_wc << 10UL) + unicode - ((0xd800 << 10UL) + 0xdc00 - 0x10000);
+ prev_wc = 0;
+ } else {
+ prev_wc = 0;
+ }
Ref<InputEventKey> k;
k.instance();
@@ -2803,7 +2840,7 @@ void DisplayServerWindows::_process_key_events() {
k->set_pressed(true);
k->set_keycode(KeyMappingWindows::get_keysym(ke.wParam));
k->set_physical_keycode(KeyMappingWindows::get_scansym((ke.lParam >> 16) & 0xFF, ke.lParam & (1 << 24)));
- k->set_unicode(ke.wParam);
+ k->set_unicode(unicode);
if (k->get_unicode() && gr_mem) {
k->set_alt(false);
k->set_control(false);
@@ -2840,7 +2877,25 @@ void DisplayServerWindows::_process_key_events() {
k->set_physical_keycode(KeyMappingWindows::get_scansym((ke.lParam >> 16) & 0xFF, ke.lParam & (1 << 24)));
if (i + 1 < key_event_pos && key_event_buffer[i + 1].uMsg == WM_CHAR) {
- k->set_unicode(key_event_buffer[i + 1].wParam);
+ char32_t unicode = key_event_buffer[i + 1].wParam;
+ static char32_t prev_wck = 0;
+ if ((unicode & 0xfffffc00) == 0xd800) {
+ if (prev_wck != 0) {
+ ERR_PRINT("invalid utf16 surrogate input");
+ }
+ prev_wck = unicode;
+ break; // Skip surrogate.
+ } else if ((unicode & 0xfffffc00) == 0xdc00) {
+ if (prev_wck == 0) {
+ ERR_PRINT("invalid utf16 surrogate input");
+ break; // Skip invalid surrogate.
+ }
+ unicode = (prev_wck << 10UL) + unicode - ((0xd800 << 10UL) + 0xdc00 - 0x10000);
+ prev_wck = 0;
+ } else {
+ prev_wck = 0;
+ }
+ k->set_unicode(unicode);
}
if (k->get_unicode() && gr_mem) {
k->set_alt(false);
@@ -2920,7 +2975,7 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode,
Rect2i r;
r.position = screen_get_position(i);
r.size = screen_get_size(i);
- Rect2 inters = r.clip(p_rect);
+ Rect2 inters = r.intersection(p_rect);
int area = inters.size.width * inters.size.height;
if (area >= nearest_area) {
screen_rect = r;
@@ -2956,6 +3011,9 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode,
windows.erase(id);
return INVALID_WINDOW_ID;
}
+ if (p_mode != WINDOW_MODE_FULLSCREEN) {
+ wd.pre_fs_valid = true;
+ }
#ifdef VULKAN_ENABLED
if (rendering_driver == "vulkan") {
@@ -2979,7 +3037,7 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode,
DragAcceptFiles(wd.hWnd, true);
- if ((OS::get_singleton()->get_current_tablet_driver() == "wintab") && wintab_available) {
+ if ((tablet_get_current_driver() == "wintab") && wintab_available) {
wintab_WTInfo(WTI_DEFSYSCTX, 0, &wd.wtlc);
wd.wtlc.lcOptions |= CXO_MESSAGES;
wd.wtlc.lcPktData = PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE | PK_ORIENTATION;
@@ -3046,6 +3104,40 @@ typedef enum _SHC_PROCESS_DPI_AWARENESS {
SHC_PROCESS_PER_MONITOR_DPI_AWARE = 2
} SHC_PROCESS_DPI_AWARENESS;
+int DisplayServerWindows::tablet_get_driver_count() const {
+ return tablet_drivers.size();
+}
+
+String DisplayServerWindows::tablet_get_driver_name(int p_driver) const {
+ if (p_driver < 0 || p_driver >= tablet_drivers.size()) {
+ return "";
+ } else {
+ return tablet_drivers[p_driver];
+ }
+}
+
+String DisplayServerWindows::tablet_get_current_driver() const {
+ return tablet_driver;
+}
+
+void DisplayServerWindows::tablet_set_current_driver(const String &p_driver) {
+ if (tablet_get_driver_count() == 0) {
+ return;
+ }
+ bool found = false;
+ for (int i = 0; i < tablet_get_driver_count(); i++) {
+ if (p_driver == tablet_get_driver_name(i)) {
+ found = true;
+ }
+ }
+ if (found) {
+ _update_tablet_ctx(tablet_driver, p_driver);
+ tablet_driver = p_driver;
+ } else {
+ ERR_PRINT("Unknown tablet driver " + p_driver + ".");
+ }
+}
+
DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
drop_events = false;
key_event_pos = 0;
@@ -3064,6 +3156,35 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
outside = true;
+ //Note: Wacom WinTab driver API for pen input, for devices incompatible with Windows Ink.
+ HMODULE wintab_lib = LoadLibraryW(L"wintab32.dll");
+ if (wintab_lib) {
+ wintab_WTOpen = (WTOpenPtr)GetProcAddress(wintab_lib, "WTOpenW");
+ wintab_WTClose = (WTClosePtr)GetProcAddress(wintab_lib, "WTClose");
+ wintab_WTInfo = (WTInfoPtr)GetProcAddress(wintab_lib, "WTInfoW");
+ wintab_WTPacket = (WTPacketPtr)GetProcAddress(wintab_lib, "WTPacket");
+ wintab_WTEnable = (WTEnablePtr)GetProcAddress(wintab_lib, "WTEnable");
+
+ wintab_available = wintab_WTOpen && wintab_WTClose && wintab_WTInfo && wintab_WTPacket && wintab_WTEnable;
+ }
+
+ if (wintab_available) {
+ tablet_drivers.push_back("wintab");
+ }
+
+ //Note: Windows Ink API for pen input, available on Windows 8+ only.
+ HMODULE user32_lib = LoadLibraryW(L"user32.dll");
+ if (user32_lib) {
+ win8p_GetPointerType = (GetPointerTypePtr)GetProcAddress(user32_lib, "GetPointerType");
+ win8p_GetPointerPenInfo = (GetPointerPenInfoPtr)GetProcAddress(user32_lib, "GetPointerPenInfo");
+
+ winink_available = win8p_GetPointerType && win8p_GetPointerPenInfo;
+ }
+
+ if (winink_available) {
+ tablet_drivers.push_back("winink");
+ }
+
if (OS::get_singleton()->is_hidpi_allowed()) {
HMODULE Shcore = LoadLibraryW(L"Shcore.dll");
@@ -3169,12 +3290,10 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
rendering_device_vulkan = memnew(RenderingDeviceVulkan);
rendering_device_vulkan->initialize(context_vulkan);
- RasterizerRD::make_current();
+ RendererCompositorRD::make_current();
}
#endif
- move_timer_id = 1;
-
//set_ime_active(false);
if (!OS::get_singleton()->is_in_low_processor_usage_mode()) {
diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h
index c64a1b3b09..a734077e59 100644
--- a/platform/windows/display_server_windows.h
+++ b/platform/windows/display_server_windows.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -43,8 +43,8 @@
#include "joypad_windows.h"
#include "key_mapping_windows.h"
#include "servers/audio_server.h"
-#include "servers/rendering/rasterizer.h"
-#include "servers/rendering/rasterizer_rd/rasterizer_rd.h"
+#include "servers/rendering/renderer_compositor.h"
+#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
#include "servers/rendering_server.h"
#ifdef XAUDIO2_ENABLED
@@ -264,7 +264,6 @@ class DisplayServerWindows : public DisplayServer {
_THREAD_SAFE_CLASS_
-public:
// WinTab API
static bool wintab_available;
static WTOpenPtr wintab_WTOpen;
@@ -279,8 +278,9 @@ public:
static GetPointerPenInfoPtr win8p_GetPointerPenInfo;
void _update_tablet_ctx(const String &p_old_driver, const String &p_new_driver);
+ String tablet_driver;
+ Vector<String> tablet_drivers;
-private:
void GetMaskBitmaps(HBITMAP hSourceBitmap, COLORREF clrTransparent, OUT HBITMAP &hAndMaskBitmap, OUT HBITMAP &hXorMaskBitmap);
enum {
@@ -339,6 +339,14 @@ private:
bool no_focus = false;
bool window_has_focus = false;
+ // Used to transfer data between events using timer.
+ WPARAM saved_wparam;
+ LPARAM saved_lparam;
+
+ // Timers.
+ uint32_t move_timer_id = 0U;
+ uint32_t focus_timer_id = 0U;
+
HANDLE wtctx;
LOGCONTEXTW wtlc;
int min_pressure;
@@ -387,8 +395,6 @@ private:
WindowID last_focused_window = INVALID_WINDOW_ID;
- uint32_t move_timer_id;
-
HCURSOR hCursor;
WNDPROC user_proc = nullptr;
@@ -411,19 +417,20 @@ private:
WNDCLASSEXW wc;
HCURSOR cursors[CURSOR_MAX] = { nullptr };
- CursorShape cursor_shape;
+ CursorShape cursor_shape = CursorShape::CURSOR_ARROW;
Map<CursorShape, Vector<Variant>> cursors_cache;
void _drag_event(WindowID p_window, float p_x, float p_y, int idx);
void _touch_event(WindowID p_window, bool p_pressed, float p_x, float p_y, int idx);
- void _update_window_style(WindowID p_window, bool p_repaint = true, bool p_maximized = false);
+ void _update_window_style(WindowID p_window, bool p_repaint = true);
void _update_window_mouse_passthrough(WindowID p_window);
void _update_real_mouse_position(WindowID p_window);
void _set_mouse_mode_impl(MouseMode p_mode);
+ void _process_activate_event(WindowID p_window_id, WPARAM wParam, LPARAM lParam);
void _process_key_events();
static void _dispatch_input_events(const Ref<InputEvent> &p_event);
@@ -535,6 +542,11 @@ public:
virtual String keyboard_get_layout_language(int p_index) const;
virtual String keyboard_get_layout_name(int p_index) const;
+ virtual int tablet_get_driver_count() const;
+ virtual String tablet_get_driver_name(int p_driver) const;
+ virtual String tablet_get_current_driver() const;
+ virtual void tablet_set_current_driver(const String &p_driver);
+
virtual void process_events();
virtual void force_process_and_drop_events();
diff --git a/platform/windows/export/export.cpp b/platform/windows/export/export.cpp
index c2436e8b64..222597b3ff 100644
--- a/platform/windows/export/export.cpp
+++ b/platform/windows/export/export.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -173,11 +173,11 @@ void EditorExportPlatformWindows::_rcedit_add_data(const Ref<EditorExportPreset>
}
#ifdef WINDOWS_ENABLED
- OS::get_singleton()->execute(rcedit_path, args, true);
+ OS::get_singleton()->execute(rcedit_path, args);
#else
// On non-Windows we need WINE to run rcedit
args.push_front(rcedit_path);
- OS::get_singleton()->execute(wine_path, args, true);
+ OS::get_singleton()->execute(wine_path, args);
#endif
}
@@ -299,7 +299,7 @@ Error EditorExportPlatformWindows::_code_sign(const Ref<EditorExportPreset> &p_p
PackedStringArray user_args = p_preset->get("codesign/custom_options");
for (int i = 0; i < user_args.size(); i++) {
String user_arg = user_args[i].strip_edges();
- if (!user_arg.empty()) {
+ if (!user_arg.is_empty()) {
args.push_back(user_arg);
}
}
@@ -314,7 +314,7 @@ Error EditorExportPlatformWindows::_code_sign(const Ref<EditorExportPreset> &p_p
#endif
String str;
- Error err = OS::get_singleton()->execute(signtool_path, args, true, nullptr, &str, nullptr, true);
+ Error err = OS::get_singleton()->execute(signtool_path, args, &str, nullptr, true);
ERR_FAIL_COND_V(err != OK, err);
print_line("codesign (" + p_path + "): " + str);
diff --git a/platform/windows/export/export.h b/platform/windows/export/export.h
index d669192831..6a7131c73f 100644
--- a/platform/windows/export/export.h
+++ b/platform/windows/export/export.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/windows/godot.natvis b/platform/windows/godot.natvis
index 1f625cfb77..d85dfbc3d3 100644
--- a/platform/windows/godot.natvis
+++ b/platform/windows/godot.natvis
@@ -10,16 +10,6 @@
</Expand>
</Type>
- <Type Name="PoolVector&lt;*&gt;">
- <Expand>
- <Item Name="[size]">alloc ? (alloc-&gt;size / sizeof($T1)) : 0</Item>
- <ArrayItems>
- <Size>alloc ? (alloc-&gt;size / sizeof($T1)) : 0</Size>
- <ValuePointer>alloc ? (($T1 *)alloc-&gt;mem) : 0</ValuePointer>
- </ArrayItems>
- </Expand>
- </Type>
-
<Type Name="List&lt;*&gt;">
<Expand>
<Item Name="[size]">_data ? (_data->size_cache) : 0</Item>
@@ -36,7 +26,7 @@
<DisplayString Condition="type == Variant::NIL">nil</DisplayString>
<DisplayString Condition="type == Variant::BOOL">{_data._bool}</DisplayString>
<DisplayString Condition="type == Variant::INT">{_data._int}</DisplayString>
- <DisplayString Condition="type == Variant::REAL">{_data._real}</DisplayString>
+ <DisplayString Condition="type == Variant::FLOAT">{_data._float}</DisplayString>
<DisplayString Condition="type == Variant::TRANSFORM2D">{_data._transform2d}</DisplayString>
<DisplayString Condition="type == Variant::AABB">{_data._aabb}</DisplayString>
<DisplayString Condition="type == Variant::BASIS">{_data._basis}</DisplayString>
@@ -49,24 +39,26 @@
<DisplayString Condition="type == Variant::QUAT">{*(Quat *)_data._mem}</DisplayString>
<DisplayString Condition="type == Variant::COLOR">{*(Color *)_data._mem}</DisplayString>
<DisplayString Condition="type == Variant::NODE_PATH">{*(NodePath *)_data._mem}</DisplayString>
- <DisplayString Condition="type == Variant::RID">{*(RID *)_data._mem}</DisplayString>
+ <DisplayString Condition="type == Variant::RID">{*(::RID *)_data._mem}</DisplayString>
<DisplayString Condition="type == Variant::OBJECT">{*(Object *)_data._mem}</DisplayString>
<DisplayString Condition="type == Variant::DICTIONARY">{*(Dictionary *)_data._mem}</DisplayString>
<DisplayString Condition="type == Variant::ARRAY">{*(Array *)_data._mem}</DisplayString>
- <DisplayString Condition="type == Variant::POOL_BYTE_ARRAY">{*(PoolByteArray *)_data._mem}</DisplayString>
- <DisplayString Condition="type == Variant::POOL_INT_ARRAY">{*(PoolIntArray *)_data._mem}</DisplayString>
- <DisplayString Condition="type == Variant::POOL_REAL_ARRAY">{*(PoolRealArray *)_data._mem}</DisplayString>
- <DisplayString Condition="type == Variant::POOL_STRING_ARRAY">{*(PoolStringArray *)_data._mem}</DisplayString>
- <DisplayString Condition="type == Variant::POOL_VECTOR2_ARRAY">{*(PoolVector2Array *)_data._mem}</DisplayString>
- <DisplayString Condition="type == Variant::POOL_VECTOR3_ARRAY">{*(PoolVector3Array *)_data._mem}</DisplayString>
- <DisplayString Condition="type == Variant::POOL_COLOR_ARRAY">{*(PoolColorArray *)_data._mem}</DisplayString>
+ <DisplayString Condition="type == Variant::PACKED_BYTE_ARRAY">{*(PackedByteArray *)_data._mem}</DisplayString>
+ <DisplayString Condition="type == Variant::PACKED_INT32_ARRAY">{*(PackedInt32Array *)_data._mem}</DisplayString>
+ <DisplayString Condition="type == Variant::PACKED_INT64_ARRAY">{*(PackedInt64Array *)_data._mem}</DisplayString>
+ <DisplayString Condition="type == Variant::PACKED_FLOAT32_ARRAY">{*(PackedFloat32Array *)_data._mem}</DisplayString>
+ <DisplayString Condition="type == Variant::PACKED_FLOAT64_ARRAY">{*(PackedFloat64Array *)_data._mem}</DisplayString>
+ <DisplayString Condition="type == Variant::PACKED_STRING_ARRAY">{*(PackedStringArray *)_data._mem}</DisplayString>
+ <DisplayString Condition="type == Variant::PACKED_VECTOR2_ARRAY">{*(PackedVector2Array *)_data._mem}</DisplayString>
+ <DisplayString Condition="type == Variant::PACKED_VECTOR3_ARRAY">{*(PackedVector3Array *)_data._mem}</DisplayString>
+ <DisplayString Condition="type == Variant::PACKED_COLOR_ARRAY">{*(PackedColorArray *)_data._mem}</DisplayString>
- <StringView Condition="type == Variant::STRING &amp;&amp; ((String *)(_data._mem))->_cowdata._ptr">((String *)(_data._mem))->_cowdata._ptr,su</StringView>
+ <StringView Condition="type == Variant::STRING &amp;&amp; ((String *)(_data._mem))->_cowdata._ptr">((String *)(_data._mem))->_cowdata._ptr,s32</StringView>
<Expand>
<Item Name="[value]" Condition="type == Variant::BOOL">_data._bool</Item>
<Item Name="[value]" Condition="type == Variant::INT">_data._int</Item>
- <Item Name="[value]" Condition="type == Variant::REAL">_data._real</Item>
+ <Item Name="[value]" Condition="type == Variant::FLOAT">_data._float</Item>
<Item Name="[value]" Condition="type == Variant::TRANSFORM2D">_data._transform2d</Item>
<Item Name="[value]" Condition="type == Variant::AABB">_data._aabb</Item>
<Item Name="[value]" Condition="type == Variant::BASIS">_data._basis</Item>
@@ -79,32 +71,34 @@
<Item Name="[value]" Condition="type == Variant::QUAT">*(Quat *)_data._mem</Item>
<Item Name="[value]" Condition="type == Variant::COLOR">*(Color *)_data._mem</Item>
<Item Name="[value]" Condition="type == Variant::NODE_PATH">*(NodePath *)_data._mem</Item>
- <Item Name="[value]" Condition="type == Variant::RID">*(RID *)_data._mem</Item>
+ <Item Name="[value]" Condition="type == Variant::RID">*(::RID *)_data._mem</Item>
<Item Name="[value]" Condition="type == Variant::OBJECT">*(Object *)_data._mem</Item>
<Item Name="[value]" Condition="type == Variant::DICTIONARY">*(Dictionary *)_data._mem</Item>
<Item Name="[value]" Condition="type == Variant::ARRAY">*(Array *)_data._mem</Item>
- <Item Name="[value]" Condition="type == Variant::POOL_BYTE_ARRAY">*(PoolByteArray *)_data._mem</Item>
- <Item Name="[value]" Condition="type == Variant::POOL_INT_ARRAY">*(PoolIntArray *)_data._mem</Item>
- <Item Name="[value]" Condition="type == Variant::POOL_REAL_ARRAY">*(PoolRealArray *)_data._mem</Item>
- <Item Name="[value]" Condition="type == Variant::POOL_STRING_ARRAY">*(PoolStringArray *)_data._mem</Item>
- <Item Name="[value]" Condition="type == Variant::POOL_VECTOR2_ARRAY">*(PoolVector2Array *)_data._mem</Item>
- <Item Name="[value]" Condition="type == Variant::POOL_VECTOR3_ARRAY">*(PoolVector3Array *)_data._mem</Item>
- <Item Name="[value]" Condition="type == Variant::POOL_COLOR_ARRAY">*(PoolColorArray *)_data._mem</Item>
+ <Item Name="[value]" Condition="type == Variant::PACKED_BYTE_ARRAY">*(PackedByteArray *)_data._mem</Item>
+ <Item Name="[value]" Condition="type == Variant::PACKED_INT32_ARRAY">*(PackedInt32Array *)_data._mem</Item>
+ <Item Name="[value]" Condition="type == Variant::PACKED_INT64_ARRAY">*(PackedInt64Array *)_data._mem</Item>
+ <Item Name="[value]" Condition="type == Variant::PACKED_FLOAT32_ARRAY">*(PackedFloat32Array *)_data._mem</Item>
+ <Item Name="[value]" Condition="type == Variant::PACKED_FLOAT64_ARRAY">*(PackedFloat64Array *)_data._mem</Item>
+ <Item Name="[value]" Condition="type == Variant::PACKED_STRING_ARRAY">*(PackedStringArray *)_data._mem</Item>
+ <Item Name="[value]" Condition="type == Variant::PACKED_VECTOR2_ARRAY">*(PackedVector2Array *)_data._mem</Item>
+ <Item Name="[value]" Condition="type == Variant::PACKED_VECTOR3_ARRAY">*(PackedVector3Array *)_data._mem</Item>
+ <Item Name="[value]" Condition="type == Variant::PACKED_COLOR_ARRAY">*(PackedColorArray *)_data._mem</Item>
</Expand>
</Type>
<Type Name="String">
<DisplayString Condition="_cowdata._ptr == 0">[empty]</DisplayString>
- <DisplayString Condition="_cowdata._ptr != 0">{_cowdata._ptr,su}</DisplayString>
- <StringView Condition="_cowdata._ptr != 0">_cowdata._ptr,su</StringView>
+ <DisplayString Condition="_cowdata._ptr != 0">{_cowdata._ptr,s32}</DisplayString>
+ <StringView Condition="_cowdata._ptr != 0">_cowdata._ptr,s32</StringView>
</Type>
<Type Name="StringName">
<DisplayString Condition="_data &amp;&amp; _data->cname">{_data->cname}</DisplayString>
- <DisplayString Condition="_data &amp;&amp; !_data->cname">{_data->name,su}</DisplayString>
+ <DisplayString Condition="_data &amp;&amp; !_data->cname">{_data->name,s32}</DisplayString>
<DisplayString Condition="!_data">[empty]</DisplayString>
<StringView Condition="_data &amp;&amp; _data->cname">_data->cname</StringView>
- <StringView Condition="_data &amp;&amp; !_data->cname">_data->name,su</StringView>
+ <StringView Condition="_data &amp;&amp; !_data->cname">_data->name,s32</StringView>
</Type>
<Type Name="Vector2">
diff --git a/platform/windows/godot_windows.cpp b/platform/windows/godot_windows.cpp
index add559a717..22e2e5f7e5 100644
--- a/platform/windows/godot_windows.cpp
+++ b/platform/windows/godot_windows.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/windows/joypad_windows.cpp b/platform/windows/joypad_windows.cpp
index 2a5c8a7763..f46a0dbe2e 100644
--- a/platform/windows/joypad_windows.cpp
+++ b/platform/windows/joypad_windows.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -151,7 +151,7 @@ bool JoypadWindows::setup_dinput_joypad(const DIDEVICEINSTANCE *instance) {
const DWORD devtype = (instance->dwDevType & 0xFF);
- if ((devtype != DI8DEVTYPE_JOYSTICK) && (devtype != DI8DEVTYPE_GAMEPAD) && (devtype != DI8DEVTYPE_1STPERSON)) {
+ if ((devtype != DI8DEVTYPE_JOYSTICK) && (devtype != DI8DEVTYPE_GAMEPAD) && (devtype != DI8DEVTYPE_1STPERSON) && (devtype != DI8DEVTYPE_DRIVING)) {
return false;
}
diff --git a/platform/windows/joypad_windows.h b/platform/windows/joypad_windows.h
index 223b44fcd6..4727b4a14c 100644
--- a/platform/windows/joypad_windows.h
+++ b/platform/windows/joypad_windows.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -92,21 +92,13 @@ private:
};
struct xinput_gamepad {
- int id;
- bool attached;
- bool vibrating;
- DWORD last_packet;
+ int id = 0;
+ bool attached = false;
+ bool vibrating = false;
+ DWORD last_packet = 0;
XINPUT_STATE state;
- uint64_t ff_timestamp;
- uint64_t ff_end_timestamp;
-
- xinput_gamepad() {
- attached = false;
- vibrating = false;
- ff_timestamp = 0;
- ff_end_timestamp = 0;
- last_packet = 0;
- }
+ uint64_t ff_timestamp = 0;
+ uint64_t ff_end_timestamp = 0;
};
typedef DWORD(WINAPI *XInputGetState_t)(DWORD dwUserIndex, XINPUT_STATE *pState);
diff --git a/platform/windows/key_mapping_windows.cpp b/platform/windows/key_mapping_windows.cpp
index 25eff7df57..3312c91932 100644
--- a/platform/windows/key_mapping_windows.cpp
+++ b/platform/windows/key_mapping_windows.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/windows/key_mapping_windows.h b/platform/windows/key_mapping_windows.h
index f64f1feb9f..fb07227014 100644
--- a/platform/windows/key_mapping_windows.h
+++ b/platform/windows/key_mapping_windows.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/windows/lang_table.h b/platform/windows/lang_table.h
index f81bab13a4..51583cc11e 100644
--- a/platform/windows/lang_table.h
+++ b/platform/windows/lang_table.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index 646bc3aa4c..3280a36e9b 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -39,15 +39,12 @@
#include "core/version_generated.gen.h"
#include "drivers/windows/dir_access_windows.h"
#include "drivers/windows/file_access_windows.h"
-#include "drivers/windows/rw_lock_windows.h"
-#include "drivers/windows/thread_windows.h"
#include "joypad_windows.h"
#include "lang_table.h"
#include "main/main.h"
#include "platform/windows/display_server_windows.h"
#include "servers/audio_server.h"
-#include "servers/rendering/rendering_server_raster.h"
-#include "servers/rendering/rendering_server_wrap_mt.h"
+#include "servers/rendering/rendering_server_default.h"
#include "windows_terminal_logger.h"
#include <avrt.h>
@@ -177,13 +174,9 @@ void OS_Windows::initialize() {
//RedirectIOToConsole();
- ThreadWindows::make_default();
- RWLockWindows::make_default();
-
FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_RESOURCES);
FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_USERDATA);
FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_FILESYSTEM);
- //FileAccessBufferedFA<FileAccessWindows>::make_default();
DirAccess::make_default<DirAccessWindows>(DirAccess::ACCESS_RESOURCES);
DirAccess::make_default<DirAccessWindows>(DirAccess::ACCESS_USERDATA);
DirAccess::make_default<DirAccessWindows>(DirAccess::ACCESS_FILESYSTEM);
@@ -411,24 +404,23 @@ String OS_Windows::_quote_command_line_argument(const String &p_text) const {
return p_text;
}
-Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex) {
+Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex) {
String path = p_path.replace("/", "\\");
+ String command = _quote_command_line_argument(path);
+ for (const List<String>::Element *E = p_arguments.front(); E; E = E->next()) {
+ command += " " + _quote_command_line_argument(E->get());
+ }
- if (p_blocking && r_pipe) {
- String argss = _quote_command_line_argument(path);
- for (const List<String>::Element *E = p_arguments.front(); E; E = E->next()) {
- argss += " " + _quote_command_line_argument(E->get());
- }
-
+ if (r_pipe) {
if (read_stderr) {
- argss += " 2>&1"; // Read stderr too
+ command += " 2>&1"; // Include stderr
}
- // Note: _wpopen is calling command as "cmd.exe /c argss", instead of executing it directly, add extra quotes around full command, to prevent it from stripping quotes in the command.
- argss = _quote_command_line_argument(argss);
-
- FILE *f = _wpopen((LPCWSTR)(argss.utf16().get_data()), L"r");
- ERR_FAIL_COND_V(!f, ERR_CANT_OPEN);
+ // Add extra quotes around the full command, to prevent it from stripping quotes in the command,
+ // because _wpopen calls command as "cmd.exe /c command", instead of executing it directly
+ command = _quote_command_line_argument(command);
+ FILE *f = _wpopen((LPCWSTR)(command.utf16().get_data()), L"r");
+ ERR_FAIL_COND_V_MSG(!f, ERR_CANT_OPEN, "Cannot create pipe from command: " + command);
char buf[65535];
while (fgets(buf, 65535, f)) {
if (p_pipe_mutex) {
@@ -439,20 +431,40 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments,
p_pipe_mutex->unlock();
}
}
-
int rv = _pclose(f);
+
if (r_exitcode) {
*r_exitcode = rv;
}
-
return OK;
}
- String cmdline = _quote_command_line_argument(path);
- const List<String>::Element *I = p_arguments.front();
- while (I) {
- cmdline += " " + _quote_command_line_argument(I->get());
- I = I->next();
+ ProcessInfo pi;
+ ZeroMemory(&pi.si, sizeof(pi.si));
+ pi.si.cb = sizeof(pi.si);
+ ZeroMemory(&pi.pi, sizeof(pi.pi));
+ LPSTARTUPINFOW si_w = (LPSTARTUPINFOW)&pi.si;
+
+ int ret = CreateProcessW(nullptr, (LPWSTR)(command.utf16().ptrw()), nullptr, nullptr, false, NORMAL_PRIORITY_CLASS & CREATE_NO_WINDOW, nullptr, nullptr, si_w, &pi.pi);
+ ERR_FAIL_COND_V_MSG(ret == 0, ERR_CANT_FORK, "Could not create child process: " + command);
+
+ WaitForSingleObject(pi.pi.hProcess, INFINITE);
+ if (r_exitcode) {
+ DWORD ret2;
+ GetExitCodeProcess(pi.pi.hProcess, &ret2);
+ *r_exitcode = ret2;
+ }
+ CloseHandle(pi.pi.hProcess);
+ CloseHandle(pi.pi.hThread);
+
+ return OK;
+};
+
+Error OS_Windows::create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id) {
+ String path = p_path.replace("/", "\\");
+ String command = _quote_command_line_argument(path);
+ for (const List<String>::Element *E = p_arguments.front(); E; E = E->next()) {
+ command += " " + _quote_command_line_argument(E->get());
}
ProcessInfo pi;
@@ -461,27 +473,15 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments,
ZeroMemory(&pi.pi, sizeof(pi.pi));
LPSTARTUPINFOW si_w = (LPSTARTUPINFOW)&pi.si;
- Char16String modstr = cmdline.utf16(); // Windows wants to change this no idea why.
- int ret = CreateProcessW(nullptr, (LPWSTR)(modstr.ptrw()), nullptr, nullptr, 0, NORMAL_PRIORITY_CLASS & CREATE_NO_WINDOW, nullptr, nullptr, si_w, &pi.pi);
- ERR_FAIL_COND_V(ret == 0, ERR_CANT_FORK);
+ int ret = CreateProcessW(nullptr, (LPWSTR)(command.utf16().ptrw()), nullptr, nullptr, false, NORMAL_PRIORITY_CLASS & CREATE_NO_WINDOW, nullptr, nullptr, si_w, &pi.pi);
+ ERR_FAIL_COND_V_MSG(ret == 0, ERR_CANT_FORK, "Could not create child process: " + command);
- if (p_blocking) {
- WaitForSingleObject(pi.pi.hProcess, INFINITE);
- if (r_exitcode) {
- DWORD ret2;
- GetExitCodeProcess(pi.pi.hProcess, &ret2);
- *r_exitcode = ret2;
- }
-
- CloseHandle(pi.pi.hProcess);
- CloseHandle(pi.pi.hThread);
- } else {
- ProcessID pid = pi.pi.dwProcessId;
- if (r_child_id) {
- *r_child_id = pid;
- }
- process_map->insert(pid, pi);
+ ProcessID pid = pi.pi.dwProcessId;
+ if (r_child_id) {
+ *r_child_id = pid;
}
+ process_map->insert(pid, pi);
+
return OK;
};
@@ -562,21 +562,21 @@ String OS_Windows::get_locale() const {
LANGID langid = GetUserDefaultUILanguage();
String neutral;
- int lang = langid & ((1 << 9) - 1);
- int sublang = langid & ~((1 << 9) - 1);
+ int lang = PRIMARYLANGID(langid);
+ int sublang = SUBLANGID(langid);
while (wl->locale) {
if (wl->main_lang == lang && wl->sublang == SUBLANG_NEUTRAL)
neutral = wl->locale;
if (lang == wl->main_lang && sublang == wl->sublang)
- return wl->locale;
+ return String(wl->locale).replace("-", "_");
wl++;
}
if (neutral != "")
- return neutral;
+ return String(neutral).replace("-", "_");
return "en";
}
@@ -615,7 +615,7 @@ void OS_Windows::run() {
if (!main_loop)
return;
- main_loop->init();
+ main_loop->initialize();
while (!force_quit) {
DisplayServer::get_singleton()->process_events(); // get rid of pending events
@@ -623,7 +623,7 @@ void OS_Windows::run() {
break;
};
- main_loop->finish();
+ main_loop->finalize();
}
MainLoop *OS_Windows::get_main_loop() const {
@@ -765,71 +765,11 @@ Error OS_Windows::move_to_trash(const String &p_path) {
return OK;
}
-int OS_Windows::get_tablet_driver_count() const {
- return tablet_drivers.size();
-}
-
-String OS_Windows::get_tablet_driver_name(int p_driver) const {
- if (p_driver < 0 || p_driver >= tablet_drivers.size()) {
- return "";
- } else {
- return tablet_drivers[p_driver];
- }
-}
-
-String OS_Windows::get_current_tablet_driver() const {
- return tablet_driver;
-}
-
-void OS_Windows::set_current_tablet_driver(const String &p_driver) {
- if (get_tablet_driver_count() == 0) {
- return;
- }
- bool found = false;
- for (int i = 0; i < get_tablet_driver_count(); i++) {
- if (p_driver == get_tablet_driver_name(i)) {
- found = true;
- }
- }
- if (found) {
- if (DisplayServerWindows::get_singleton()) {
- ((DisplayServerWindows *)DisplayServerWindows::get_singleton())->_update_tablet_ctx(tablet_driver, p_driver);
- }
- tablet_driver = p_driver;
- } else {
- ERR_PRINT("Unknown tablet driver " + p_driver + ".");
- }
-}
-
OS_Windows::OS_Windows(HINSTANCE _hInstance) {
- //Note: Wacom WinTab driver API for pen input, for devices incompatible with Windows Ink.
- HMODULE wintab_lib = LoadLibraryW(L"wintab32.dll");
- if (wintab_lib) {
- DisplayServerWindows::wintab_WTOpen = (WTOpenPtr)GetProcAddress(wintab_lib, "WTOpenW");
- DisplayServerWindows::wintab_WTClose = (WTClosePtr)GetProcAddress(wintab_lib, "WTClose");
- DisplayServerWindows::wintab_WTInfo = (WTInfoPtr)GetProcAddress(wintab_lib, "WTInfoW");
- DisplayServerWindows::wintab_WTPacket = (WTPacketPtr)GetProcAddress(wintab_lib, "WTPacket");
- DisplayServerWindows::wintab_WTEnable = (WTEnablePtr)GetProcAddress(wintab_lib, "WTEnable");
-
- DisplayServerWindows::wintab_available = DisplayServerWindows::wintab_WTOpen && DisplayServerWindows::wintab_WTClose && DisplayServerWindows::wintab_WTInfo && DisplayServerWindows::wintab_WTPacket && DisplayServerWindows::wintab_WTEnable;
- }
-
- if (DisplayServerWindows::wintab_available) {
- tablet_drivers.push_back("wintab");
- }
-
- //Note: Windows Ink API for pen input, available on Windows 8+ only.
- HMODULE user32_lib = LoadLibraryW(L"user32.dll");
- if (user32_lib) {
- DisplayServerWindows::win8p_GetPointerType = (GetPointerTypePtr)GetProcAddress(user32_lib, "GetPointerType");
- DisplayServerWindows::win8p_GetPointerPenInfo = (GetPointerPenInfoPtr)GetProcAddress(user32_lib, "GetPointerPenInfo");
-
- DisplayServerWindows::winink_available = DisplayServerWindows::win8p_GetPointerType && DisplayServerWindows::win8p_GetPointerPenInfo;
- }
-
- if (DisplayServerWindows::winink_available) {
- tablet_drivers.push_back("winink");
- }
+ ticks_per_second = 0;
+ ticks_start = 0;
+ main_loop = nullptr;
+ process_map = nullptr;
force_quit = false;
diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h
index a3dbb23182..8f9ef254f1 100644
--- a/platform/windows/os_windows.h
+++ b/platform/windows/os_windows.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -40,7 +40,7 @@
#include "drivers/winmidi/midi_driver_winmidi.h"
#include "key_mapping_windows.h"
#include "servers/audio_server.h"
-#include "servers/rendering/rasterizer.h"
+#include "servers/rendering/renderer_compositor.h"
#include "servers/rendering_server.h"
#ifdef XAUDIO2_ENABLED
#include "drivers/xaudio2/audio_driver_xaudio2.h"
@@ -73,9 +73,6 @@ class OS_Windows : public OS {
HINSTANCE hInstance;
MainLoop *main_loop;
- String tablet_driver;
- Vector<String> tablet_drivers;
-
#ifdef WASAPI_ENABLED
AudioDriverWASAPI driver_wasapi;
#endif
@@ -93,14 +90,14 @@ class OS_Windows : public OS {
// functions used by main to initialize/deinitialize the OS
protected:
- virtual void initialize();
+ virtual void initialize() override;
- virtual void set_main_loop(MainLoop *p_main_loop);
- virtual void delete_main_loop();
+ virtual void set_main_loop(MainLoop *p_main_loop) override;
+ virtual void delete_main_loop() override;
- virtual void finalize();
- virtual void finalize_core();
- virtual String get_stdin_string(bool p_block);
+ virtual void finalize() override;
+ virtual void finalize_core() override;
+ virtual String get_stdin_string(bool p_block) override;
String _quote_command_line_argument(const String &p_text) const;
@@ -111,66 +108,62 @@ protected:
Map<ProcessID, ProcessInfo> *process_map;
public:
- virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false);
- virtual Error close_dynamic_library(void *p_library_handle);
- virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional = false);
-
- virtual MainLoop *get_main_loop() const;
+ virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false) override;
+ virtual Error close_dynamic_library(void *p_library_handle) override;
+ virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional = false) override;
- virtual String get_name() const;
+ virtual MainLoop *get_main_loop() const override;
- virtual int get_tablet_driver_count() const;
- virtual String get_tablet_driver_name(int p_driver) const;
- virtual String get_current_tablet_driver() const;
- virtual void set_current_tablet_driver(const String &p_driver);
+ virtual String get_name() const override;
- virtual void initialize_joypads() {}
+ virtual void initialize_joypads() override {}
- virtual Date get_date(bool utc) const;
- virtual Time get_time(bool utc) const;
- virtual TimeZoneInfo get_time_zone_info() const;
- virtual double get_unix_time() const;
+ virtual Date get_date(bool utc) const override;
+ virtual Time get_time(bool utc) const override;
+ virtual TimeZoneInfo get_time_zone_info() const override;
+ virtual double get_unix_time() const override;
- virtual Error set_cwd(const String &p_cwd);
+ virtual Error set_cwd(const String &p_cwd) override;
- virtual void delay_usec(uint32_t p_usec) const;
- virtual uint64_t get_ticks_usec() const;
+ virtual void delay_usec(uint32_t p_usec) const override;
+ virtual uint64_t get_ticks_usec() const override;
- virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking = true, ProcessID *r_child_id = nullptr, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr);
- virtual Error kill(const ProcessID &p_pid);
- virtual int get_process_id() const;
+ virtual Error execute(const String &p_path, const List<String> &p_arguments, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr) override;
+ virtual Error create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id = nullptr) override;
+ virtual Error kill(const ProcessID &p_pid) override;
+ virtual int get_process_id() const override;
- virtual bool has_environment(const String &p_var) const;
- virtual String get_environment(const String &p_var) const;
- virtual bool set_environment(const String &p_var, const String &p_value) const;
+ virtual bool has_environment(const String &p_var) const override;
+ virtual String get_environment(const String &p_var) const override;
+ virtual bool set_environment(const String &p_var, const String &p_value) const override;
- virtual String get_executable_path() const;
+ virtual String get_executable_path() const override;
- virtual String get_locale() const;
+ virtual String get_locale() const override;
- virtual int get_processor_count() const;
+ virtual int get_processor_count() const override;
- virtual String get_config_path() const;
- virtual String get_data_path() const;
- virtual String get_cache_path() const;
- virtual String get_godot_dir_name() const;
+ virtual String get_config_path() const override;
+ virtual String get_data_path() const override;
+ virtual String get_cache_path() const override;
+ virtual String get_godot_dir_name() const override;
- virtual String get_system_dir(SystemDir p_dir) const;
- virtual String get_user_data_dir() const;
+ virtual String get_system_dir(SystemDir p_dir) const override;
+ virtual String get_user_data_dir() const override;
- virtual String get_unique_id() const;
+ virtual String get_unique_id() const override;
- virtual Error shell_open(String p_uri);
+ virtual Error shell_open(String p_uri) override;
void run();
- virtual bool _check_internal_feature_support(const String &p_feature);
+ virtual bool _check_internal_feature_support(const String &p_feature) override;
- void disable_crash_handler();
- bool is_disable_crash_handler() const;
- virtual void initialize_debugging();
+ virtual void disable_crash_handler() override;
+ virtual bool is_disable_crash_handler() const override;
+ virtual void initialize_debugging() override;
- virtual Error move_to_trash(const String &p_path);
+ virtual Error move_to_trash(const String &p_path) override;
void set_main_window(HWND p_main_window) { main_window = p_main_window; }
diff --git a/platform/windows/platform_config.h b/platform/windows/platform_config.h
index 09a16614e0..481f583f6f 100644
--- a/platform/windows/platform_config.h
+++ b/platform/windows/platform_config.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/windows/vulkan_context_win.cpp b/platform/windows/vulkan_context_win.cpp
index 2c63281c49..e5e176ab93 100644
--- a/platform/windows/vulkan_context_win.cpp
+++ b/platform/windows/vulkan_context_win.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/windows/vulkan_context_win.h b/platform/windows/vulkan_context_win.h
index 6e80db0286..4fe987218d 100644
--- a/platform/windows/vulkan_context_win.h
+++ b/platform/windows/vulkan_context_win.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/windows/windows_terminal_logger.cpp b/platform/windows/windows_terminal_logger.cpp
index 0938b65b04..56b620a6d9 100644
--- a/platform/windows/windows_terminal_logger.cpp
+++ b/platform/windows/windows_terminal_logger.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/windows/windows_terminal_logger.h b/platform/windows/windows_terminal_logger.h
index d4443a707d..aacfe5869e 100644
--- a/platform/windows/windows_terminal_logger.h
+++ b/platform/windows/windows_terminal_logger.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */