summaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
Diffstat (limited to 'platform')
-rw-r--r--platform/android/SCsub1
-rw-r--r--platform/android/android_input_handler.cpp10
-rw-r--r--platform/android/android_input_handler.h2
-rw-r--r--platform/android/detect.py328
-rw-r--r--platform/android/dir_access_jandroid.cpp304
-rw-r--r--platform/android/dir_access_jandroid.h72
-rw-r--r--platform/android/export/export.cpp4
-rw-r--r--platform/android/export/export_plugin.cpp124
-rw-r--r--platform/android/export/export_plugin.h6
-rw-r--r--platform/android/export/gradle_export_util.cpp4
-rw-r--r--platform/android/export/gradle_export_util.h10
-rw-r--r--platform/android/file_access_android.cpp12
-rw-r--r--platform/android/file_access_android.h8
-rw-r--r--platform/android/file_access_filesystem_jandroid.cpp329
-rw-r--r--platform/android/file_access_filesystem_jandroid.h98
-rw-r--r--platform/android/java/app/AndroidManifest.xml1
-rw-r--r--platform/android/java/app/config.gradle8
-rw-r--r--platform/android/java/editor/build.gradle3
-rw-r--r--platform/android/java/editor/src/main/AndroidManifest.xml10
-rw-r--r--platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.kt52
-rw-r--r--platform/android/java/editor/src/main/res/values/strings.xml2
-rw-r--r--platform/android/java/lib/AndroidManifest.xml2
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/Godot.java22
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotIO.java96
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotLib.java22
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java9
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/io/StorageScope.kt113
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/io/directory/AssetsDirectoryAccess.kt177
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/io/directory/DirectoryAccessHandler.kt224
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/io/directory/FilesystemDirectoryAccess.kt231
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/io/file/DataAccess.kt187
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/io/file/FileAccessFlags.kt87
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/io/file/FileAccessHandler.kt203
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/io/file/FileData.kt93
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/io/file/MediaStoreData.kt284
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java55
-rw-r--r--platform/android/java_godot_lib_jni.cpp24
-rw-r--r--platform/android/java_godot_lib_jni.h3
-rw-r--r--platform/android/java_godot_view_wrapper.h6
-rw-r--r--platform/android/os_android.cpp32
-rw-r--r--platform/android/os_android.h2
-rw-r--r--platform/ios/SCsub (renamed from platform/iphone/SCsub)18
-rw-r--r--platform/ios/api/api.cpp (renamed from platform/iphone/api/api.cpp)10
-rw-r--r--platform/ios/api/api.h (renamed from platform/iphone/api/api.h)12
-rw-r--r--platform/ios/app_delegate.h (renamed from platform/iphone/app_delegate.h)0
-rw-r--r--platform/ios/app_delegate.mm (renamed from platform/iphone/app_delegate.mm)18
-rw-r--r--platform/ios/detect.py (renamed from platform/iphone/detect.py)34
-rw-r--r--platform/ios/device_metrics.h (renamed from platform/iphone/device_metrics.h)0
-rw-r--r--platform/ios/device_metrics.m (renamed from platform/iphone/device_metrics.m)0
-rw-r--r--platform/ios/display_layer.h (renamed from platform/iphone/display_layer.h)0
-rw-r--r--platform/ios/display_layer.mm (renamed from platform/iphone/display_layer.mm)4
-rw-r--r--platform/ios/display_server_ios.h (renamed from platform/iphone/display_server_iphone.h)24
-rw-r--r--platform/ios/display_server_ios.mm (renamed from platform/iphone/display_server_iphone.mm)197
-rw-r--r--platform/ios/export/export.cpp (renamed from platform/iphone/export/export.cpp)3
-rw-r--r--platform/ios/export/export.h (renamed from platform/osx/export/export.h)8
-rw-r--r--platform/ios/export/export_plugin.cpp (renamed from platform/iphone/export/export_plugin.cpp)26
-rw-r--r--platform/ios/export/export_plugin.h (renamed from platform/iphone/export/export_plugin.h)10
-rw-r--r--platform/ios/export/godot_plugin_config.cpp (renamed from platform/iphone/export/godot_plugin_config.cpp)0
-rw-r--r--platform/ios/export/godot_plugin_config.h (renamed from platform/iphone/export/godot_plugin_config.h)6
-rw-r--r--platform/ios/godot_app_delegate.h (renamed from platform/iphone/godot_app_delegate.h)0
-rw-r--r--platform/ios/godot_app_delegate.m (renamed from platform/iphone/godot_app_delegate.m)0
-rw-r--r--platform/ios/godot_ios.mm (renamed from platform/iphone/godot_iphone.mm)23
-rw-r--r--platform/ios/godot_view.h (renamed from platform/iphone/godot_view.h)0
-rw-r--r--platform/ios/godot_view.mm (renamed from platform/iphone/godot_view.mm)46
-rw-r--r--platform/ios/godot_view_gesture_recognizer.h (renamed from platform/iphone/godot_view_gesture_recognizer.h)0
-rw-r--r--platform/ios/godot_view_gesture_recognizer.mm (renamed from platform/iphone/godot_view_gesture_recognizer.mm)0
-rw-r--r--platform/ios/godot_view_renderer.h (renamed from platform/iphone/godot_view_renderer.h)0
-rw-r--r--platform/ios/godot_view_renderer.mm (renamed from platform/iphone/godot_view_renderer.mm)10
-rw-r--r--platform/ios/ios.h (renamed from platform/iphone/ios.h)2
-rw-r--r--platform/ios/ios.mm (renamed from platform/iphone/ios.mm)0
-rw-r--r--platform/ios/joypad_ios.h (renamed from platform/iphone/joypad_iphone.h)12
-rw-r--r--platform/ios/joypad_ios.mm (renamed from platform/iphone/joypad_iphone.mm)18
-rw-r--r--platform/ios/keyboard_input_view.h (renamed from platform/iphone/keyboard_input_view.h)0
-rw-r--r--platform/ios/keyboard_input_view.mm (renamed from platform/iphone/keyboard_input_view.mm)12
-rw-r--r--platform/ios/logo.png (renamed from platform/iphone/logo.png)bin1297 -> 1297 bytes
-rw-r--r--platform/ios/main.m (renamed from platform/iphone/main.m)0
-rw-r--r--platform/ios/os_ios.h (renamed from platform/iphone/os_iphone.h)26
-rw-r--r--platform/ios/os_ios.mm (renamed from platform/iphone/os_iphone.mm)98
-rw-r--r--platform/ios/platform_config.h (renamed from platform/iphone/platform_config.h)0
-rw-r--r--platform/ios/tts_ios.h (renamed from platform/iphone/tts_ios.h)0
-rw-r--r--platform/ios/tts_ios.mm (renamed from platform/iphone/tts_ios.mm)0
-rw-r--r--platform/ios/view_controller.h (renamed from platform/iphone/view_controller.h)0
-rw-r--r--platform/ios/view_controller.mm (renamed from platform/iphone/view_controller.mm)20
-rw-r--r--platform/ios/vulkan_context_ios.h (renamed from platform/iphone/vulkan_context_iphone.h)14
-rw-r--r--platform/ios/vulkan_context_ios.mm (renamed from platform/iphone/vulkan_context_iphone.mm)12
-rw-r--r--platform/javascript/audio_driver_javascript.h2
-rw-r--r--platform/javascript/display_server_javascript.cpp4
-rw-r--r--platform/javascript/export/export.h2
-rw-r--r--platform/javascript/export/export_plugin.cpp9
-rw-r--r--platform/javascript/export/export_plugin.h4
-rw-r--r--platform/javascript/export/export_server.h3
-rw-r--r--platform/javascript/godot_audio.h2
-rw-r--r--platform/javascript/godot_js.h2
-rw-r--r--platform/javascript/godot_webgl2.h2
-rw-r--r--platform/javascript/http_client_javascript.h1
-rw-r--r--platform/javascript/js/engine/config.js1
-rw-r--r--platform/javascript/os_javascript.h2
-rw-r--r--platform/linuxbsd/SCsub12
-rw-r--r--platform/linuxbsd/crash_handler_linuxbsd.h6
-rw-r--r--platform/linuxbsd/detect.py110
-rw-r--r--platform/linuxbsd/detect_prime_x11.h3
-rw-r--r--platform/linuxbsd/display_server_x11.cpp72
-rw-r--r--platform/linuxbsd/display_server_x11.h3
-rw-r--r--platform/linuxbsd/export/export.cpp8
-rw-r--r--platform/linuxbsd/export/export_plugin.cpp2
-rw-r--r--platform/linuxbsd/export/export_plugin.h4
-rw-r--r--platform/linuxbsd/freedesktop_screensaver.h5
-rw-r--r--platform/linuxbsd/godot_linuxbsd.cpp4
-rw-r--r--platform/linuxbsd/os_linuxbsd.h2
-rw-r--r--platform/linuxbsd/vulkan_context_x11.h6
-rw-r--r--platform/macos/SCsub30
-rw-r--r--platform/macos/crash_handler_macos.h (renamed from platform/osx/crash_handler_osx.h)8
-rw-r--r--platform/macos/crash_handler_macos.mm (renamed from platform/osx/crash_handler_osx.mm)4
-rw-r--r--platform/macos/detect.py (renamed from platform/osx/detect.py)69
-rw-r--r--platform/macos/dir_access_macos.h (renamed from platform/osx/dir_access_osx.h)13
-rw-r--r--platform/macos/dir_access_macos.mm (renamed from platform/osx/dir_access_osx.mm)14
-rw-r--r--platform/macos/display_server_macos.h (renamed from platform/osx/display_server_osx.h)30
-rw-r--r--platform/macos/display_server_macos.mm (renamed from platform/osx/display_server_osx.mm)469
-rw-r--r--platform/macos/export/codesign.cpp (renamed from platform/osx/export/codesign.cpp)0
-rw-r--r--platform/macos/export/codesign.h (renamed from platform/osx/export/codesign.h)6
-rw-r--r--platform/macos/export/export.cpp (renamed from platform/osx/export/export.cpp)4
-rw-r--r--platform/macos/export/export.h (renamed from platform/iphone/export/export.h)8
-rw-r--r--platform/macos/export/export_plugin.cpp (renamed from platform/osx/export/export_plugin.cpp)98
-rw-r--r--platform/macos/export/export_plugin.h (renamed from platform/osx/export/export_plugin.h)22
-rw-r--r--platform/macos/export/lipo.cpp (renamed from platform/osx/export/lipo.cpp)0
-rw-r--r--platform/macos/export/lipo.h (renamed from platform/osx/export/lipo.h)6
-rw-r--r--platform/macos/export/macho.cpp (renamed from platform/osx/export/macho.cpp)0
-rw-r--r--platform/macos/export/macho.h (renamed from platform/osx/export/macho.h)6
-rw-r--r--platform/macos/export/plist.cpp (renamed from platform/osx/export/plist.cpp)0
-rw-r--r--platform/macos/export/plist.h (renamed from platform/osx/export/plist.h)6
-rw-r--r--platform/macos/gl_manager_macos_legacy.h (renamed from platform/osx/gl_manager_osx_legacy.h)19
-rw-r--r--platform/macos/gl_manager_macos_legacy.mm (renamed from platform/osx/gl_manager_osx_legacy.mm)42
-rw-r--r--platform/macos/godot_application.h (renamed from platform/osx/godot_application.h)0
-rw-r--r--platform/macos/godot_application.mm (renamed from platform/osx/godot_application.mm)4
-rw-r--r--platform/macos/godot_application_delegate.h (renamed from platform/osx/godot_application_delegate.h)1
-rw-r--r--platform/macos/godot_application_delegate.mm (renamed from platform/osx/godot_application_delegate.mm)81
-rw-r--r--platform/macos/godot_content_view.h (renamed from platform/osx/godot_content_view.h)1
-rw-r--r--platform/macos/godot_content_view.mm (renamed from platform/osx/godot_content_view.mm)135
-rw-r--r--platform/macos/godot_main_macos.mm (renamed from platform/osx/godot_main_osx.mm)19
-rw-r--r--platform/macos/godot_menu_item.h (renamed from platform/osx/godot_menu_item.h)0
-rw-r--r--platform/macos/godot_window.h (renamed from platform/osx/godot_window.h)2
-rw-r--r--platform/macos/godot_window.mm (renamed from platform/osx/godot_window.mm)12
-rw-r--r--platform/macos/godot_window_delegate.h (renamed from platform/osx/godot_window_delegate.h)2
-rw-r--r--platform/macos/godot_window_delegate.mm (renamed from platform/osx/godot_window_delegate.mm)66
-rw-r--r--platform/macos/joypad_macos.cpp (renamed from platform/osx/joypad_osx.cpp)32
-rw-r--r--platform/macos/joypad_macos.h (renamed from platform/osx/joypad_osx.h)14
-rw-r--r--platform/macos/key_mapping_macos.h (renamed from platform/osx/key_mapping_osx.h)12
-rw-r--r--platform/macos/key_mapping_macos.mm (renamed from platform/osx/key_mapping_osx.mm)24
-rw-r--r--platform/macos/logo.png (renamed from platform/osx/logo.png)bin7195 -> 7195 bytes
-rw-r--r--platform/macos/macos_terminal_logger.h (renamed from platform/osx/osx_terminal_logger.h)15
-rw-r--r--platform/macos/macos_terminal_logger.mm (renamed from platform/osx/osx_terminal_logger.mm)10
-rw-r--r--platform/macos/os_macos.h (renamed from platform/osx/os_osx.h)26
-rw-r--r--platform/macos/os_macos.mm (renamed from platform/osx/os_osx.mm)104
-rw-r--r--platform/macos/platform_config.h (renamed from platform/osx/platform_config.h)0
-rw-r--r--platform/macos/platform_macos_builders.py (renamed from platform/osx/platform_osx_builders.py)2
-rw-r--r--platform/macos/tts_macos.h (renamed from platform/osx/tts_osx.h)10
-rw-r--r--platform/macos/tts_macos.mm (renamed from platform/osx/tts_osx.mm)6
-rw-r--r--platform/macos/vulkan_context_macos.h (renamed from platform/osx/vulkan_context_osx.h)14
-rw-r--r--platform/macos/vulkan_context_macos.mm (renamed from platform/osx/vulkan_context_osx.mm)12
-rw-r--r--platform/osx/SCsub30
-rw-r--r--platform/register_platform_apis.h6
-rw-r--r--platform/uwp/app_uwp.h1
-rw-r--r--platform/uwp/export/app_packager.h4
-rw-r--r--platform/uwp/export/export_plugin.cpp4
-rw-r--r--platform/uwp/export/export_plugin.h4
-rw-r--r--platform/uwp/joypad_uwp.h2
-rw-r--r--platform/uwp/os_uwp.cpp1
-rw-r--r--platform/uwp/os_uwp.h2
-rw-r--r--platform/windows/detect.py5
-rw-r--r--platform/windows/display_server_windows.cpp37
-rw-r--r--platform/windows/display_server_windows.h16
-rw-r--r--platform/windows/export/export.cpp8
-rw-r--r--platform/windows/export/export.h2
-rw-r--r--platform/windows/export/export_plugin.cpp2
-rw-r--r--platform/windows/export/export_plugin.h4
-rw-r--r--platform/windows/godot.natvis2
-rw-r--r--platform/windows/godot_windows.cpp4
-rw-r--r--platform/windows/os_windows.cpp6
-rw-r--r--platform/windows/os_windows.h2
-rw-r--r--platform/windows/vulkan_context_win.h6
-rw-r--r--platform/windows/windows_terminal_logger.h2
181 files changed, 3996 insertions, 1806 deletions
diff --git a/platform/android/SCsub b/platform/android/SCsub
index ad226255bc..d370a4d18d 100644
--- a/platform/android/SCsub
+++ b/platform/android/SCsub
@@ -6,6 +6,7 @@ android_files = [
"os_android.cpp",
"android_input_handler.cpp",
"file_access_android.cpp",
+ "file_access_filesystem_jandroid.cpp",
"audio_driver_opensl.cpp",
"dir_access_jandroid.cpp",
"tts_android.cpp",
diff --git a/platform/android/android_input_handler.cpp b/platform/android/android_input_handler.cpp
index 10f23b320b..81802298d9 100644
--- a/platform/android/android_input_handler.cpp
+++ b/platform/android/android_input_handler.cpp
@@ -381,13 +381,3 @@ MouseButton AndroidInputHandler::_android_button_mask_to_godot_button_mask(int a
return godot_button_mask;
}
-
-void AndroidInputHandler::process_scroll(Point2 p_pos) {
- Ref<InputEventPanGesture> ev;
- ev.instantiate();
- _set_key_modifier_state(ev);
- ev->set_position(p_pos);
- ev->set_delta(p_pos - scroll_prev_pos);
- Input::get_singleton()->parse_input_event(ev);
- scroll_prev_pos = p_pos;
-}
diff --git a/platform/android/android_input_handler.h b/platform/android/android_input_handler.h
index e9c0ec1475..1397ca59e4 100644
--- a/platform/android/android_input_handler.h
+++ b/platform/android/android_input_handler.h
@@ -69,7 +69,6 @@ private:
Vector<TouchPos> touch;
Point2 hover_prev_pos; // needed to calculate the relative position on hover events
- Point2 scroll_prev_pos; // needed to calculate the relative position on scroll events
void _set_key_modifier_state(Ref<InputEventWithModifiers> ev);
@@ -83,7 +82,6 @@ public:
void process_hover(int p_type, Point2 p_pos);
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);
};
diff --git a/platform/android/detect.py b/platform/android/detect.py
index 0099ac7e0d..2ff5bf59ea 100644
--- a/platform/android/detect.py
+++ b/platform/android/detect.py
@@ -1,7 +1,7 @@
import os
import sys
import platform
-from distutils.version import LooseVersion
+import subprocess
def is_active():
@@ -13,41 +13,35 @@ def get_name():
def can_build():
- return ("ANDROID_SDK_ROOT" in os.environ) or ("ANDROID_HOME" in os.environ)
-
-
-def get_platform(platform):
- return int(platform.split("-")[1])
+ return os.path.exists(get_env_android_sdk_root())
def get_opts():
from SCons.Variables import BoolVariable, EnumVariable
return [
- ("ANDROID_NDK_ROOT", "Path to the Android NDK", get_android_ndk_root()),
- ("ANDROID_SDK_ROOT", "Path to the Android SDK", get_android_sdk_root()),
+ ("ANDROID_SDK_ROOT", "Path to the Android SDK", get_env_android_sdk_root()),
("ndk_platform", 'Target platform (android-<api>, e.g. "android-24")', "android-24"),
EnumVariable("android_arch", "Target architecture", "arm64v8", ("armv7", "arm64v8", "x86", "x86_64")),
]
# 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)
+def get_env_android_sdk_root():
+ return os.environ.get("ANDROID_SDK_ROOT", -1)
-# 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_min_sdk_version(platform):
+ return int(platform.split("-")[1])
+
+
+def get_android_ndk_root(env):
+ return env["ANDROID_SDK_ROOT"] + "/ndk/" + get_ndk_version()
+
+
+# This is kept in sync with the value in 'platform/android/java/app/config.gradle'.
+def get_ndk_version():
+ return "23.2.8568313"
def get_flags():
@@ -56,133 +50,67 @@ def get_flags():
]
-def create(env):
- tools = env["TOOLS"]
- if "mingw" in tools:
- tools.remove("mingw")
- if "applelink" in tools:
- tools.remove("applelink")
- env.Tool("gcc")
- return env.Clone(tools=tools)
-
-
-# Check if ANDROID_NDK_ROOT is valid.
-# If not, install the ndk using ANDROID_SDK_ROOT and sdkmanager.
+# Check if Android NDK version is installed
+# If not, install it.
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
-
+ sdk_root = env["ANDROID_SDK_ROOT"]
+ if not os.path.exists(get_android_ndk_root(env)):
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"])
+ sdkmanager = sdk_root + "/cmdline-tools/latest/bin/sdkmanager" + extension
+ if os.path.exists(sdkmanager):
+ # Install the Android NDK
+ print("Installing Android NDK...")
+ ndk_download_args = "ndk;" + get_ndk_version()
+ subprocess.check_call([sdkmanager, ndk_download_args])
+ else:
+ print("Cannot find " + sdkmanager)
+ print(
+ "Please ensure ANDROID_SDK_ROOT is correct and cmdline-tools are installed, or install NDK version "
+ + get_ndk_version()
+ + " manually."
+ )
+ sys.exit()
+ env["ANDROID_NDK_ROOT"] = get_android_ndk_root(env)
def configure(env):
install_ndk_if_needed(env)
-
- # Workaround for MinGW. See:
- # https://www.scons.org/wiki/LongCmdLinesOnWin32
- if os.name == "nt":
-
- import subprocess
-
- def mySubProcess(cmdline, env):
- # print("SPAWNED : " + cmdline)
- startupinfo = subprocess.STARTUPINFO()
- startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
- proc = subprocess.Popen(
- cmdline,
- stdin=subprocess.PIPE,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- startupinfo=startupinfo,
- shell=False,
- env=env,
- )
- data, err = proc.communicate()
- rv = proc.wait()
- if rv:
- print("=====")
- print(err)
- print("=====")
- return rv
-
- def mySpawn(sh, escape, cmd, args, env):
-
- newargs = " ".join(args[1:])
- cmdline = cmd + " " + newargs
-
- rv = 0
- if len(cmdline) > 32000 and cmd.endswith("ar"):
- cmdline = cmd + " " + args[1] + " " + args[2] + " "
- for i in range(3, len(args)):
- rv = mySubProcess(cmdline + args[i], env)
- if rv:
- break
- else:
- rv = mySubProcess(cmdline, env)
-
- return rv
-
- env["SPAWN"] = mySpawn
+ ndk_root = env["ANDROID_NDK_ROOT"]
# Architecture
if env["android_arch"] not in ["armv7", "arm64v8", "x86", "x86_64"]:
- env["android_arch"] = "armv7"
+ env["android_arch"] = "arm64v8"
print("Building for Android, platform " + env["ndk_platform"] + " (" + env["android_arch"] + ")")
- can_vectorize = True
- if env["android_arch"] == "x86":
- env["ARCH"] = "arch-x86"
- env.extra_suffix = ".x86" + env.extra_suffix
- target_subpath = "x86-4.9"
- abi_subpath = "i686-linux-android"
- arch_subpath = "x86"
- env["x86_libtheora_opt_gcc"] = True
- elif env["android_arch"] == "x86_64":
- if get_platform(env["ndk_platform"]) < 21:
+ if get_min_sdk_version(env["ndk_platform"]) < 21:
+ if env["android_arch"] == "x86_64" or env["android_arch"] == "arm64v8":
print(
- "WARNING: android_arch=x86_64 is not supported by ndk_platform lower than android-21; setting"
- " ndk_platform=android-21"
+ "WARNING: android_arch="
+ + env["android_arch"]
+ + " is not supported by ndk_platform lower than android-21; setting ndk_platform=android-21"
)
env["ndk_platform"] = "android-21"
- env["ARCH"] = "arch-x86_64"
- env.extra_suffix = ".x86_64" + env.extra_suffix
- target_subpath = "x86_64-4.9"
- abi_subpath = "x86_64-linux-android"
- arch_subpath = "x86_64"
- env["x86_libtheora_opt_gcc"] = True
- elif env["android_arch"] == "armv7":
- env["ARCH"] = "arch-arm"
- target_subpath = "arm-linux-androideabi-4.9"
- abi_subpath = "arm-linux-androideabi"
- arch_subpath = "armeabi-v7a"
+
+ if env["android_arch"] == "armv7":
+ target_triple = "armv7a-linux-androideabi"
env.extra_suffix = ".armv7" + env.extra_suffix
elif env["android_arch"] == "arm64v8":
- if get_platform(env["ndk_platform"]) < 21:
- print(
- "WARNING: android_arch=arm64v8 is not supported by ndk_platform lower than android-21; setting"
- " ndk_platform=android-21"
- )
- env["ndk_platform"] = "android-21"
- env["ARCH"] = "arch-arm64"
- target_subpath = "aarch64-linux-android-4.9"
- abi_subpath = "aarch64-linux-android"
- arch_subpath = "arm64-v8a"
+ target_triple = "aarch64-linux-android"
env.extra_suffix = ".armv8" + env.extra_suffix
+ elif env["android_arch"] == "x86":
+ target_triple = "i686-linux-android"
+ env.extra_suffix = ".x86" + env.extra_suffix
+ elif env["android_arch"] == "x86_64":
+ target_triple = "x86_64-linux-android"
+ env.extra_suffix = ".x86_64" + env.extra_suffix
+
+ target_option = ["-target", target_triple + str(get_min_sdk_version(env["ndk_platform"]))]
+ env.Append(ASFLAGS=[target_option, "-c"])
+ env.Append(CCFLAGS=target_option)
+ env.Append(LINKFLAGS=target_option)
# Build type
@@ -191,15 +119,11 @@ def configure(env):
# `-O2` is more friendly to debuggers than `-O3`, leading to better crash backtraces
# when using `target=release_debug`.
opt = "-O3" if env["target"] == "release" else "-O2"
- env.Append(LINKFLAGS=[opt])
env.Append(CCFLAGS=[opt, "-fomit-frame-pointer"])
elif env["optimize"] == "size": # optimize for size
- env.Append(CCFLAGS=["-Os"])
- env.Append(LINKFLAGS=["-Os"])
-
+ env.Append(CCFLAGS=["-Oz"])
env.Append(CPPDEFINES=["NDEBUG"])
- if can_vectorize:
- env.Append(CCFLAGS=["-ftree-vectorize"])
+ env.Append(CCFLAGS=["-ftree-vectorize"])
elif env["target"] == "debug":
env.Append(LINKFLAGS=["-O0"])
env.Append(CCFLAGS=["-O0", "-g", "-fno-limit-debug-info"])
@@ -211,7 +135,6 @@ def configure(env):
env["SHLIBSUFFIX"] = ".so"
if env["PLATFORM"] == "win32":
- env.Tool("gcc")
env.use_windows_spawn_fix()
if sys.platform.startswith("linux"):
@@ -224,32 +147,14 @@ def configure(env):
else:
host_subpath = "windows"
- compiler_path = env["ANDROID_NDK_ROOT"] + "/toolchains/llvm/prebuilt/" + host_subpath + "/bin"
- gcc_toolchain_path = env["ANDROID_NDK_ROOT"] + "/toolchains/" + target_subpath + "/prebuilt/" + host_subpath
- tools_path = gcc_toolchain_path + "/" + abi_subpath + "/bin"
-
- # For Clang to find NDK tools in preference of those system-wide
- env.PrependENVPath("PATH", tools_path)
-
- ccache_path = os.environ.get("CCACHE")
- if ccache_path is None:
- env["CC"] = compiler_path + "/clang"
- env["CXX"] = compiler_path + "/clang++"
- else:
- # there aren't any ccache wrappers available for Android,
- # to enable caching we need to prepend the path to the ccache binary
- env["CC"] = ccache_path + " " + compiler_path + "/clang"
- env["CXX"] = ccache_path + " " + compiler_path + "/clang++"
- env["AR"] = tools_path + "/ar"
- env["RANLIB"] = tools_path + "/ranlib"
- env["AS"] = tools_path + "/as"
+ toolchain_path = ndk_root + "/toolchains/llvm/prebuilt/" + host_subpath
+ compiler_path = toolchain_path + "/bin"
- common_opts = ["-gcc-toolchain", gcc_toolchain_path]
-
- # Compile flags
-
- env.Append(CPPFLAGS=["-isystem", env["ANDROID_NDK_ROOT"] + "/sources/cxx-stl/llvm-libc++/include"])
- env.Append(CPPFLAGS=["-isystem", env["ANDROID_NDK_ROOT"] + "/sources/cxx-stl/llvm-libc++abi/include"])
+ env["CC"] = compiler_path + "/clang"
+ env["CXX"] = compiler_path + "/clang++"
+ env["AR"] = compiler_path + "/llvm-ar"
+ env["RANLIB"] = compiler_path + "/llvm-ranlib"
+ env["AS"] = compiler_path + "/clang"
# Disable exceptions and rtti on non-tools (template) builds
if env["tools"]:
@@ -261,100 +166,31 @@ def configure(env):
# Don't use dynamic_cast, necessary with no-rtti.
env.Append(CPPDEFINES=["NO_SAFE_CAST"])
- lib_sysroot = env["ANDROID_NDK_ROOT"] + "/platforms/" + env["ndk_platform"] + "/" + env["ARCH"]
-
- # Using NDK unified headers (NDK r15+)
- sysroot = env["ANDROID_NDK_ROOT"] + "/sysroot"
- env.Append(CPPFLAGS=["--sysroot=" + sysroot])
- env.Append(CPPFLAGS=["-isystem", sysroot + "/usr/include/" + abi_subpath])
- env.Append(CPPFLAGS=["-isystem", env["ANDROID_NDK_ROOT"] + "/sources/android/support/include"])
- # For unified headers this define has to be set manually
- env.Append(CPPDEFINES=[("__ANDROID_API__", str(get_platform(env["ndk_platform"])))])
-
env.Append(
CCFLAGS=(
- "-fpic -ffunction-sections -funwind-tables -fstack-protector-strong -fvisibility=hidden"
- " -fno-strict-aliasing".split()
+ "-fpic -ffunction-sections -funwind-tables -fstack-protector-strong -fvisibility=hidden -fno-strict-aliasing".split()
)
)
env.Append(CPPDEFINES=["NO_STATVFS", "GLES_ENABLED"])
- if get_platform(env["ndk_platform"]) >= 24:
+ if get_min_sdk_version(env["ndk_platform"]) >= 24:
env.Append(CPPDEFINES=[("_FILE_OFFSET_BITS", 64)])
if env["android_arch"] == "x86":
- target_opts = ["-target", "i686-none-linux-android"]
- # The NDK adds this if targeting API < 21, so we can drop it when Godot targets it at least
+ # The NDK adds this if targeting API < 24, so we can drop it when Godot targets it at least
env.Append(CCFLAGS=["-mstackrealign"])
-
- elif env["android_arch"] == "x86_64":
- target_opts = ["-target", "x86_64-none-linux-android"]
-
elif env["android_arch"] == "armv7":
- target_opts = ["-target", "armv7-none-linux-androideabi"]
env.Append(CCFLAGS="-march=armv7-a -mfloat-abi=softfp".split())
env.Append(CPPDEFINES=["__ARM_ARCH_7__", "__ARM_ARCH_7A__"])
- # Enable ARM NEON instructions to compile more optimized code.
- env.Append(CCFLAGS=["-mfpu=neon"])
env.Append(CPPDEFINES=["__ARM_NEON__"])
-
elif env["android_arch"] == "arm64v8":
- target_opts = ["-target", "aarch64-none-linux-android"]
env.Append(CCFLAGS=["-mfix-cortex-a53-835769"])
env.Append(CPPDEFINES=["__ARM_ARCH_8A__"])
- env.Append(CCFLAGS=target_opts)
- env.Append(CCFLAGS=common_opts)
-
# Link flags
- 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:
- env.Append(
- LINKFLAGS=[
- env["ANDROID_NDK_ROOT"] + "/sources/cxx-stl/llvm-libc++/libs/" + arch_subpath + "/libandroid_support.a"
- ]
- )
- env.Append(LINKFLAGS=["-shared", "--sysroot=" + lib_sysroot, "-Wl,--warn-shared-textrel"])
- env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"] + "/sources/cxx-stl/llvm-libc++/libs/" + arch_subpath + "/"])
- env.Append(
- LINKFLAGS=[env["ANDROID_NDK_ROOT"] + "/sources/cxx-stl/llvm-libc++/libs/" + arch_subpath + "/libc++_shared.so"]
- )
-
- if env["android_arch"] == "armv7":
- env.Append(LINKFLAGS="-Wl,--fix-cortex-a8".split())
- env.Append(LINKFLAGS="-Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now".split())
- env.Append(LINKFLAGS="-Wl,-soname,libgodot_android.so -Wl,--gc-sections".split())
-
- env.Append(LINKFLAGS=target_opts)
- env.Append(LINKFLAGS=common_opts)
-
- env.Append(
- LIBPATH=[
- env["ANDROID_NDK_ROOT"]
- + "/toolchains/"
- + target_subpath
- + "/prebuilt/"
- + host_subpath
- + "/lib/gcc/"
- + abi_subpath
- + "/4.9.x"
- ]
- )
- env.Append(
- LIBPATH=[
- env["ANDROID_NDK_ROOT"]
- + "/toolchains/"
- + target_subpath
- + "/prebuilt/"
- + host_subpath
- + "/"
- + abi_subpath
- + "/lib"
- ]
- )
+ env.Append(LINKFLAGS="-Wl,--gc-sections -Wl,--no-undefined -Wl,-z,now".split())
+ env.Append(LINKFLAGS="-Wl,-soname,libgodot_android.so")
env.Prepend(CPPPATH=["#platform/android"])
env.Append(CPPDEFINES=["ANDROID_ENABLED", "UNIX_ENABLED", "NO_FCNTL"])
@@ -364,25 +200,3 @@ def configure(env):
env.Append(CPPDEFINES=["VULKAN_ENABLED"])
if not env["use_volk"]:
env.Append(LIBS=["vulkan"])
-
-
-# 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_env_ndk_version(path):
- if path is None:
- return None
- prop_file_path = os.path.join(path, "source.properties")
- try:
- with open(prop_file_path) as prop_file:
- for line in prop_file:
- key_value = list(map(lambda x: x.strip(), line.split("=")))
- if key_value[0] == "Pkg.Revision":
- return key_value[1]
- 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 5b9eee8117..eb344d3b43 100644
--- a/platform/android/dir_access_jandroid.cpp
+++ b/platform/android/dir_access_jandroid.cpp
@@ -31,30 +31,32 @@
#include "dir_access_jandroid.h"
#include "core/string/print_string.h"
-#include "file_access_android.h"
#include "string_android.h"
#include "thread_jandroid.h"
-jobject DirAccessJAndroid::io = nullptr;
+jobject DirAccessJAndroid::dir_access_handler = nullptr;
jclass DirAccessJAndroid::cls = nullptr;
jmethodID DirAccessJAndroid::_dir_open = nullptr;
jmethodID DirAccessJAndroid::_dir_next = nullptr;
jmethodID DirAccessJAndroid::_dir_close = nullptr;
jmethodID DirAccessJAndroid::_dir_is_dir = nullptr;
-
-Ref<DirAccess> DirAccessJAndroid::create_fs() {
- return memnew(DirAccessJAndroid);
-}
+jmethodID DirAccessJAndroid::_dir_exists = nullptr;
+jmethodID DirAccessJAndroid::_file_exists = nullptr;
+jmethodID DirAccessJAndroid::_get_drive_count = nullptr;
+jmethodID DirAccessJAndroid::_get_drive = nullptr;
+jmethodID DirAccessJAndroid::_make_dir = nullptr;
+jmethodID DirAccessJAndroid::_get_space_left = nullptr;
+jmethodID DirAccessJAndroid::_rename = nullptr;
+jmethodID DirAccessJAndroid::_remove = nullptr;
+jmethodID DirAccessJAndroid::_current_is_hidden = nullptr;
Error DirAccessJAndroid::list_dir_begin() {
list_dir_end();
- JNIEnv *env = get_jni_env();
-
- jstring js = env->NewStringUTF(current_dir.utf8().get_data());
- int res = env->CallIntMethod(io, _dir_open, js);
+ int res = dir_open(current_dir);
if (res <= 0) {
return ERR_CANT_OPEN;
}
+
id = res;
return OK;
@@ -62,169 +64,236 @@ Error DirAccessJAndroid::list_dir_begin() {
String DirAccessJAndroid::get_next() {
ERR_FAIL_COND_V(id == 0, "");
+ if (_dir_next) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND_V(env == nullptr, "");
+ jstring str = (jstring)env->CallObjectMethod(dir_access_handler, _dir_next, get_access_type(), id);
+ if (!str) {
+ return "";
+ }
- JNIEnv *env = get_jni_env();
- jstring str = (jstring)env->CallObjectMethod(io, _dir_next, id);
- if (!str) {
+ String ret = jstring_to_string((jstring)str, env);
+ env->DeleteLocalRef((jobject)str);
+ return ret;
+ } else {
return "";
}
- String ret = jstring_to_string((jstring)str, env);
- env->DeleteLocalRef((jobject)str);
- return ret;
}
bool DirAccessJAndroid::current_is_dir() const {
- JNIEnv *env = get_jni_env();
-
- return env->CallBooleanMethod(io, _dir_is_dir, id);
+ if (_dir_is_dir) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND_V(env == nullptr, false);
+ return env->CallBooleanMethod(dir_access_handler, _dir_is_dir, get_access_type(), id);
+ } else {
+ return false;
+ }
}
bool DirAccessJAndroid::current_is_hidden() const {
- return current != "." && current != ".." && current.begins_with(".");
+ if (_current_is_hidden) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND_V(env == nullptr, false);
+ return env->CallBooleanMethod(dir_access_handler, _current_is_hidden, get_access_type(), id);
+ }
+ return false;
}
void DirAccessJAndroid::list_dir_end() {
if (id == 0) {
return;
}
- JNIEnv *env = get_jni_env();
- env->CallVoidMethod(io, _dir_close, id);
+
+ dir_close(id);
id = 0;
}
int DirAccessJAndroid::get_drive_count() {
- return 0;
+ if (_get_drive_count) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND_V(env == nullptr, 0);
+ return env->CallIntMethod(dir_access_handler, _get_drive_count, get_access_type());
+ } else {
+ return 0;
+ }
}
String DirAccessJAndroid::get_drive(int p_drive) {
- return "";
+ if (_get_drive) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND_V(env == nullptr, "");
+ jstring j_drive = (jstring)env->CallObjectMethod(dir_access_handler, _get_drive, get_access_type(), p_drive);
+ if (!j_drive) {
+ return "";
+ }
+
+ String drive = jstring_to_string(j_drive, env);
+ env->DeleteLocalRef(j_drive);
+ return drive;
+ } else {
+ return "";
+ }
}
Error DirAccessJAndroid::change_dir(String p_dir) {
- JNIEnv *env = get_jni_env();
-
- if (p_dir.is_empty() || p_dir == "." || (p_dir == ".." && current_dir.is_empty())) {
+ String new_dir = get_absolute_path(p_dir);
+ if (new_dir == current_dir) {
return OK;
}
- String new_dir;
-
- if (p_dir != "res://" && p_dir.length() > 1 && p_dir.ends_with("/")) {
- p_dir = p_dir.substr(0, p_dir.length() - 1);
- }
-
- if (p_dir.begins_with("/")) {
- new_dir = p_dir.substr(1, p_dir.length());
- } else if (p_dir.begins_with("res://")) {
- new_dir = p_dir.substr(6, p_dir.length());
- } else if (current_dir.is_empty()) {
- new_dir = p_dir;
- } else {
- new_dir = current_dir.plus_file(p_dir);
- }
-
- //test if newdir exists
- new_dir = new_dir.simplify_path();
-
- jstring js = env->NewStringUTF(new_dir.utf8().get_data());
- int res = env->CallIntMethod(io, _dir_open, js);
- env->DeleteLocalRef(js);
- if (res <= 0) {
+ if (!dir_exists(new_dir)) {
return ERR_INVALID_PARAMETER;
}
- env->CallVoidMethod(io, _dir_close, res);
-
current_dir = new_dir;
-
return OK;
}
-String DirAccessJAndroid::get_current_dir(bool p_include_drive) const {
- return "res://" + current_dir;
+String DirAccessJAndroid::get_absolute_path(String p_path) {
+ if (current_dir != "" && p_path == current_dir) {
+ return current_dir;
+ }
+
+ if (p_path.is_relative_path()) {
+ p_path = get_current_dir().plus_file(p_path);
+ }
+
+ p_path = fix_path(p_path);
+ p_path = p_path.simplify_path();
+ return p_path;
}
bool DirAccessJAndroid::file_exists(String p_file) {
- String sd;
- if (current_dir.is_empty()) {
- sd = p_file;
+ if (_file_exists) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND_V(env == nullptr, false);
+
+ String path = get_absolute_path(p_file);
+ jstring j_path = env->NewStringUTF(path.utf8().get_data());
+ bool result = env->CallBooleanMethod(dir_access_handler, _file_exists, get_access_type(), j_path);
+ env->DeleteLocalRef(j_path);
+ return result;
} else {
- sd = current_dir.plus_file(p_file);
+ return false;
}
-
- Ref<FileAccessAndroid> f;
- f.instantiate();
- bool exists = f->file_exists(sd);
-
- return exists;
}
bool DirAccessJAndroid::dir_exists(String p_dir) {
- JNIEnv *env = get_jni_env();
-
- String sd;
-
- if (current_dir.is_empty()) {
- sd = p_dir;
+ if (_dir_exists) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND_V(env == nullptr, false);
+
+ String path = get_absolute_path(p_dir);
+ jstring j_path = env->NewStringUTF(path.utf8().get_data());
+ bool result = env->CallBooleanMethod(dir_access_handler, _dir_exists, get_access_type(), j_path);
+ env->DeleteLocalRef(j_path);
+ return result;
} else {
- if (p_dir.is_relative_path()) {
- sd = current_dir.plus_file(p_dir);
- } else {
- sd = fix_path(p_dir);
- }
- }
-
- String path = sd.simplify_path();
-
- if (path.begins_with("/")) {
- path = path.substr(1, path.length());
- } else if (path.begins_with("res://")) {
- path = path.substr(6, path.length());
+ return false;
}
+}
- jstring js = env->NewStringUTF(path.utf8().get_data());
- int res = env->CallIntMethod(io, _dir_open, js);
- env->DeleteLocalRef(js);
- if (res <= 0) {
- return false;
+Error DirAccessJAndroid::make_dir_recursive(String p_dir) {
+ // Check if the directory exists already
+ if (dir_exists(p_dir)) {
+ return ERR_ALREADY_EXISTS;
}
- env->CallVoidMethod(io, _dir_close, res);
+ if (_make_dir) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND_V(env == nullptr, ERR_UNCONFIGURED);
- return true;
+ String path = get_absolute_path(p_dir);
+ jstring j_dir = env->NewStringUTF(path.utf8().get_data());
+ bool result = env->CallBooleanMethod(dir_access_handler, _make_dir, get_access_type(), j_dir);
+ env->DeleteLocalRef(j_dir);
+ if (result) {
+ return OK;
+ } else {
+ return FAILED;
+ }
+ } else {
+ return ERR_UNCONFIGURED;
+ }
}
Error DirAccessJAndroid::make_dir(String p_dir) {
- ERR_FAIL_V(ERR_UNAVAILABLE);
+ return make_dir_recursive(p_dir);
}
Error DirAccessJAndroid::rename(String p_from, String p_to) {
- ERR_FAIL_V(ERR_UNAVAILABLE);
-}
+ if (_rename) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND_V(env == nullptr, ERR_UNCONFIGURED);
-Error DirAccessJAndroid::remove(String p_name) {
- ERR_FAIL_V(ERR_UNAVAILABLE);
+ String from_path = get_absolute_path(p_from);
+ jstring j_from = env->NewStringUTF(from_path.utf8().get_data());
+
+ String to_path = get_absolute_path(p_to);
+ jstring j_to = env->NewStringUTF(to_path.utf8().get_data());
+
+ bool result = env->CallBooleanMethod(dir_access_handler, _rename, get_access_type(), j_from, j_to);
+ env->DeleteLocalRef(j_from);
+ env->DeleteLocalRef(j_to);
+ if (result) {
+ return OK;
+ } else {
+ return FAILED;
+ }
+ } else {
+ return ERR_UNCONFIGURED;
+ }
}
-String DirAccessJAndroid::get_filesystem_type() const {
- return "APK";
+Error DirAccessJAndroid::remove(String p_name) {
+ if (_remove) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND_V(env == nullptr, ERR_UNCONFIGURED);
+
+ String path = get_absolute_path(p_name);
+ jstring j_name = env->NewStringUTF(path.utf8().get_data());
+ bool result = env->CallBooleanMethod(dir_access_handler, _remove, get_access_type(), j_name);
+ env->DeleteLocalRef(j_name);
+ if (result) {
+ return OK;
+ } else {
+ return FAILED;
+ }
+ } else {
+ return ERR_UNCONFIGURED;
+ }
}
uint64_t DirAccessJAndroid::get_space_left() {
- return 0;
+ if (_get_space_left) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND_V(env == nullptr, 0);
+ return env->CallLongMethod(dir_access_handler, _get_space_left, get_access_type());
+ } else {
+ return 0;
+ }
}
-void DirAccessJAndroid::setup(jobject p_io) {
+void DirAccessJAndroid::setup(jobject p_dir_access_handler) {
JNIEnv *env = get_jni_env();
- io = p_io;
+ dir_access_handler = env->NewGlobalRef(p_dir_access_handler);
- jclass c = env->GetObjectClass(io);
+ jclass c = env->GetObjectClass(dir_access_handler);
cls = (jclass)env->NewGlobalRef(c);
- _dir_open = env->GetMethodID(cls, "dir_open", "(Ljava/lang/String;)I");
- _dir_next = env->GetMethodID(cls, "dir_next", "(I)Ljava/lang/String;");
- _dir_close = env->GetMethodID(cls, "dir_close", "(I)V");
- _dir_is_dir = env->GetMethodID(cls, "dir_is_dir", "(I)Z");
+ _dir_open = env->GetMethodID(cls, "dirOpen", "(ILjava/lang/String;)I");
+ _dir_next = env->GetMethodID(cls, "dirNext", "(II)Ljava/lang/String;");
+ _dir_close = env->GetMethodID(cls, "dirClose", "(II)V");
+ _dir_is_dir = env->GetMethodID(cls, "dirIsDir", "(II)Z");
+ _dir_exists = env->GetMethodID(cls, "dirExists", "(ILjava/lang/String;)Z");
+ _file_exists = env->GetMethodID(cls, "fileExists", "(ILjava/lang/String;)Z");
+ _get_drive_count = env->GetMethodID(cls, "getDriveCount", "(I)I");
+ _get_drive = env->GetMethodID(cls, "getDrive", "(II)Ljava/lang/String;");
+ _make_dir = env->GetMethodID(cls, "makeDir", "(ILjava/lang/String;)Z");
+ _get_space_left = env->GetMethodID(cls, "getSpaceLeft", "(I)J");
+ _rename = env->GetMethodID(cls, "rename", "(ILjava/lang/String;Ljava/lang/String;)Z");
+ _remove = env->GetMethodID(cls, "remove", "(ILjava/lang/String;)Z");
+ _current_is_hidden = env->GetMethodID(cls, "isCurrentHidden", "(II)Z");
}
DirAccessJAndroid::DirAccessJAndroid() {
@@ -233,3 +302,26 @@ DirAccessJAndroid::DirAccessJAndroid() {
DirAccessJAndroid::~DirAccessJAndroid() {
list_dir_end();
}
+
+int DirAccessJAndroid::dir_open(String p_path) {
+ if (_dir_open) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND_V(env == nullptr, 0);
+
+ String path = get_absolute_path(p_path);
+ jstring js = env->NewStringUTF(path.utf8().get_data());
+ int dirId = env->CallIntMethod(dir_access_handler, _dir_open, get_access_type(), js);
+ env->DeleteLocalRef(js);
+ return dirId;
+ } else {
+ return 0;
+ }
+}
+
+void DirAccessJAndroid::dir_close(int p_id) {
+ if (_dir_close) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND(env == nullptr);
+ env->CallVoidMethod(dir_access_handler, _dir_close, get_access_type(), p_id);
+ }
+}
diff --git a/platform/android/dir_access_jandroid.h b/platform/android/dir_access_jandroid.h
index 0e1b12cb58..d469c9d317 100644
--- a/platform/android/dir_access_jandroid.h
+++ b/platform/android/dir_access_jandroid.h
@@ -32,58 +32,70 @@
#define DIR_ACCESS_JANDROID_H
#include "core/io/dir_access.h"
+#include "drivers/unix/dir_access_unix.h"
#include "java_godot_lib_jni.h"
#include <stdio.h>
-class DirAccessJAndroid : public DirAccess {
- static jobject io;
+/// Android implementation of the DirAccess interface used to provide access to
+/// ACCESS_FILESYSTEM and ACCESS_RESOURCES directory resources.
+/// The implementation use jni in order to comply with Android filesystem
+/// access restriction.
+class DirAccessJAndroid : public DirAccessUnix {
+ static jobject dir_access_handler;
static jclass cls;
static jmethodID _dir_open;
static jmethodID _dir_next;
static jmethodID _dir_close;
static jmethodID _dir_is_dir;
-
- int id = 0;
-
- String current_dir;
- String current;
-
- static Ref<DirAccess> create_fs();
+ static jmethodID _dir_exists;
+ static jmethodID _file_exists;
+ static jmethodID _get_drive_count;
+ static jmethodID _get_drive;
+ static jmethodID _make_dir;
+ static jmethodID _get_space_left;
+ static jmethodID _rename;
+ static jmethodID _remove;
+ static jmethodID _current_is_hidden;
public:
- virtual Error list_dir_begin(); ///< This starts dir listing
- virtual String get_next();
- virtual bool current_is_dir() const;
- virtual bool current_is_hidden() const;
- virtual void list_dir_end(); ///<
+ virtual Error list_dir_begin() override; ///< This starts dir listing
+ virtual String get_next() override;
+ virtual bool current_is_dir() const override;
+ virtual bool current_is_hidden() const override;
+ virtual void list_dir_end() override; ///<
- virtual int get_drive_count();
- virtual String get_drive(int p_drive);
+ virtual int get_drive_count() override;
+ virtual String get_drive(int p_drive) override;
- virtual Error change_dir(String p_dir); ///< can be relative or absolute, return false on success
- virtual String get_current_dir(bool p_include_drive = true) const; ///< return current dir location
+ virtual Error change_dir(String p_dir) override; ///< can be relative or absolute, return false on success
- virtual bool file_exists(String p_file);
- virtual bool dir_exists(String p_dir);
+ virtual bool file_exists(String p_file) override;
+ virtual bool dir_exists(String p_dir) override;
- virtual Error make_dir(String p_dir);
+ virtual Error make_dir(String p_dir) override;
+ virtual Error make_dir_recursive(String p_dir) override;
- virtual Error rename(String p_from, String p_to);
- virtual Error remove(String p_name);
+ virtual Error rename(String p_from, String p_to) override;
+ virtual Error remove(String p_name) override;
- virtual bool is_link(String p_file) { return false; }
- virtual String read_link(String p_file) { return p_file; }
- virtual Error create_link(String p_source, String p_target) { return FAILED; }
+ virtual bool is_link(String p_file) override { return false; }
+ virtual String read_link(String p_file) override { return p_file; }
+ virtual Error create_link(String p_source, String p_target) override { return FAILED; }
- virtual String get_filesystem_type() const;
+ virtual uint64_t get_space_left() override;
- uint64_t get_space_left();
-
- static void setup(jobject p_io);
+ static void setup(jobject p_dir_access_handler);
DirAccessJAndroid();
~DirAccessJAndroid();
+
+private:
+ int id = 0;
+
+ int dir_open(String p_path);
+ void dir_close(int p_id);
+ String get_absolute_path(String p_path);
};
#endif // DIR_ACCESS_JANDROID_H
diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp
index 560f188b82..5bbe0ffab6 100644
--- a/platform/android/export/export.cpp
+++ b/platform/android/export/export.cpp
@@ -30,10 +30,10 @@
#include "export.h"
-#include "export_plugin.h"
-
#include "core/os/os.h"
#include "editor/editor_settings.h"
+#include "editor/export/editor_export.h"
+#include "export_plugin.h"
void register_android_exporter() {
EDITOR_DEF("export/android/android_sdk_path", "");
diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp
index 73c6fcc7e8..2cfb152804 100644
--- a/platform/android/export/export_plugin.cpp
+++ b/platform/android/export/export_plugin.cpp
@@ -123,6 +123,7 @@ static const char *android_perms[] = {
"MANAGE_ACCOUNTS",
"MANAGE_APP_TOKENS",
"MANAGE_DOCUMENTS",
+ "MANAGE_EXTERNAL_STORAGE",
"MASTER_CLEAR",
"MEDIA_CONTENT_CONTROL",
"MODIFY_AUDIO_SETTINGS",
@@ -245,8 +246,7 @@ static const char *APK_ASSETS_DIRECTORY = "res://android/build/assets";
static const char *AAB_ASSETS_DIRECTORY = "res://android/build/assetPacks/installTime/src/main/assets";
static const int DEFAULT_MIN_SDK_VERSION = 19; // Should match the value in 'platform/android/java/app/config.gradle#minSdk'
-static const int DEFAULT_TARGET_SDK_VERSION = 30; // Should match the value in 'platform/android/java/app/config.gradle#targetSdk'
-const String SDK_VERSION_RANGE = vformat("%s,%s,1", DEFAULT_MIN_SDK_VERSION, DEFAULT_TARGET_SDK_VERSION);
+static const int DEFAULT_TARGET_SDK_VERSION = 32; // Should match the value in 'platform/android/java/app/config.gradle#targetSdk'
void EditorExportPlatformAndroid::_check_for_changes_poll_thread(void *ud) {
EditorExportPlatformAndroid *ea = static_cast<EditorExportPlatformAndroid *>(ud);
@@ -277,6 +277,7 @@ void EditorExportPlatformAndroid::_check_for_changes_poll_thread(void *ud) {
}
}
+#ifndef ANDROID_ENABLED
// Check for devices updates
String adb = get_adb_path();
if (FileAccess::exists(adb)) {
@@ -388,6 +389,7 @@ void EditorExportPlatformAndroid::_check_for_changes_poll_thread(void *ud) {
ea->devices_changed.set();
}
}
+#endif
uint64_t sleep = 200;
uint64_t wait = 3000000;
@@ -400,6 +402,7 @@ void EditorExportPlatformAndroid::_check_for_changes_poll_thread(void *ud) {
}
}
+#ifndef ANDROID_ENABLED
if (EditorSettings::get_singleton()->get("export/android/shutdown_adb_on_exit")) {
String adb = get_adb_path();
if (!FileAccess::exists(adb)) {
@@ -410,6 +413,7 @@ void EditorExportPlatformAndroid::_check_for_changes_poll_thread(void *ud) {
args.push_back("kill-server");
OS::get_singleton()->execute(adb, args);
}
+#endif
}
String EditorExportPlatformAndroid::get_project_name(const String &p_name) const {
@@ -748,10 +752,14 @@ Error EditorExportPlatformAndroid::copy_gradle_so(void *p_userdata, const Shared
return OK;
}
-bool EditorExportPlatformAndroid::_has_storage_permission(const Vector<String> &p_permissions) {
+bool EditorExportPlatformAndroid::_has_read_write_storage_permission(const Vector<String> &p_permissions) {
return p_permissions.find("android.permission.READ_EXTERNAL_STORAGE") != -1 || p_permissions.find("android.permission.WRITE_EXTERNAL_STORAGE") != -1;
}
+bool EditorExportPlatformAndroid::_has_manage_external_storage_permission(const Vector<String> &p_permissions) {
+ return p_permissions.find("android.permission.MANAGE_EXTERNAL_STORAGE") != -1;
+}
+
void EditorExportPlatformAndroid::_get_permissions(const Ref<EditorExportPreset> &p_preset, bool p_give_internet, Vector<String> &r_permissions) {
const char **aperms = android_perms;
while (*aperms) {
@@ -799,7 +807,7 @@ void EditorExportPlatformAndroid::_write_tmp_manifest(const Ref<EditorExportPres
_get_permissions(p_preset, p_give_internet, perms);
for (int i = 0; i < perms.size(); i++) {
String permission = perms.get(i);
- if (permission == "android.permission.WRITE_EXTERNAL_STORAGE" || permission == "android.permission.READ_EXTERNAL_STORAGE") {
+ if (permission == "android.permission.WRITE_EXTERNAL_STORAGE" || (permission == "android.permission.READ_EXTERNAL_STORAGE" && _has_manage_external_storage_permission(perms))) {
manifest_text += vformat(" <uses-permission android:name=\"%s\" android:maxSdkVersion=\"29\" />\n", permission);
} else {
manifest_text += vformat(" <uses-permission android:name=\"%s\" />\n", permission);
@@ -807,7 +815,7 @@ void EditorExportPlatformAndroid::_write_tmp_manifest(const Ref<EditorExportPres
}
manifest_text += _get_xr_features_tag(p_preset);
- manifest_text += _get_application_tag(p_preset, _has_storage_permission(perms));
+ manifest_text += _get_application_tag(p_preset, _has_read_write_storage_permission(perms));
manifest_text += "</manifest>\n";
String manifest_path = vformat("res://android/build/src/%s/AndroidManifest.xml", (p_debug ? "debug" : "release"));
@@ -865,7 +873,7 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref<EditorExportPreset> &p
Vector<String> perms;
// Write permissions into the perms variable.
_get_permissions(p_preset, p_give_internet, perms);
- bool has_storage_permission = _has_storage_permission(perms);
+ bool has_read_write_storage_permission = _has_read_write_storage_permission(perms);
while (ofs < (uint32_t)p_manifest.size()) {
uint32_t chunk = decode_uint32(&p_manifest[ofs]);
@@ -949,7 +957,7 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref<EditorExportPreset> &p
}
if (tname == "application" && attrname == "requestLegacyExternalStorage") {
- encode_uint32(has_storage_permission ? 0xFFFFFFFF : 0, &p_manifest.write[iofs + 16]);
+ encode_uint32(has_read_write_storage_permission ? 0xFFFFFFFF : 0, &p_manifest.write[iofs + 16]);
}
if (tname == "application" && attrname == "allowBackup") {
@@ -1682,8 +1690,13 @@ void EditorExportPlatformAndroid::get_preset_features(const Ref<EditorExportPres
void EditorExportPlatformAndroid::get_export_options(List<ExportOption> *r_options) {
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"), EXPORT_FORMAT_APK));
+
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "custom_build/use_custom_build"), false));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "custom_build/export_format", PROPERTY_HINT_ENUM, "Export APK,Export AAB"), EXPORT_FORMAT_APK));
+ // Using String instead of int to default to an empty string (no override) with placeholder for instructions (see GH-62465).
+ // This implies doing validation that the string is a proper int.
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_build/min_sdk", PROPERTY_HINT_PLACEHOLDER_TEXT, vformat("%d (default)", DEFAULT_MIN_SDK_VERSION)), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_build/target_sdk", PROPERTY_HINT_PLACEHOLDER_TEXT, vformat("%d (default)", DEFAULT_TARGET_SDK_VERSION)), ""));
Vector<PluginConfigAndroid> plugins_configs = get_plugins();
for (int i = 0; i < plugins_configs.size(); i++) {
@@ -1710,8 +1723,6 @@ void EditorExportPlatformAndroid::get_export_options(List<ExportOption> *r_optio
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "version/code", PROPERTY_HINT_RANGE, "1,4096,1,or_greater"), 1));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "version/name"), "1.0"));
- r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "version/min_sdk", PROPERTY_HINT_RANGE, SDK_VERSION_RANGE), DEFAULT_MIN_SDK_VERSION));
- r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "version/target_sdk", PROPERTY_HINT_RANGE, SDK_VERSION_RANGE), DEFAULT_TARGET_SDK_VERSION));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/unique_name", PROPERTY_HINT_PLACEHOLDER_TEXT, "ext.domain.name"), "org.godotengine.$genname"));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Game Name [default if blank]"), ""));
@@ -2039,7 +2050,7 @@ String EditorExportPlatformAndroid::get_apksigner_path() {
bool EditorExportPlatformAndroid::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const {
String err;
bool valid = false;
- const bool custom_build_enabled = p_preset->get("custom_template/use_custom_build");
+ const bool custom_build_enabled = p_preset->get("custom_build/use_custom_build");
// Look for export templates (first official, and if defined custom templates).
@@ -2201,43 +2212,73 @@ bool EditorExportPlatformAndroid::can_export(const Ref<EditorExportPreset> &p_pr
if (xr_mode_index != XR_MODE_OPENXR) {
if (hand_tracking > XR_HAND_TRACKING_NONE) {
valid = false;
- err += TTR("\"Hand Tracking\" is only valid when \"Xr Mode\" is \"OpenXR\".");
+ err += TTR("\"Hand Tracking\" is only valid when \"XR Mode\" is \"OpenXR\".");
err += "\n";
}
if (passthrough_mode > XR_PASSTHROUGH_NONE) {
valid = false;
- err += TTR("\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\".");
+ err += TTR("\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\".");
err += "\n";
}
}
- if (int(p_preset->get("custom_template/export_format")) == EXPORT_FORMAT_AAB &&
+ if (int(p_preset->get("custom_build/export_format")) == EXPORT_FORMAT_AAB &&
!custom_build_enabled) {
valid = false;
err += TTR("\"Export AAB\" is only valid when \"Use Custom Build\" is enabled.");
err += "\n";
}
- // Check the min sdk version
- int min_sdk_version = p_preset->get("version/min_sdk");
- if (min_sdk_version != DEFAULT_MIN_SDK_VERSION && !custom_build_enabled) {
- valid = false;
- err += TTR("Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled.");
- err += "\n";
+ // Check the min sdk version.
+ String min_sdk_str = p_preset->get("custom_build/min_sdk");
+ int min_sdk_int = DEFAULT_MIN_SDK_VERSION;
+ if (!min_sdk_str.is_empty()) { // Empty means no override, nothing to do.
+ if (!custom_build_enabled) {
+ valid = false;
+ err += TTR("\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled.");
+ err += "\n";
+ }
+ if (!min_sdk_str.is_valid_int()) {
+ valid = false;
+ err += vformat(TTR("\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."), min_sdk_str);
+ err += "\n";
+ } else {
+ min_sdk_int = min_sdk_str.to_int();
+ if (min_sdk_int < DEFAULT_MIN_SDK_VERSION) {
+ valid = false;
+ err += vformat(TTR("\"Min SDK\" cannot be lower than %d, which is the version needed by the Godot library."), DEFAULT_MIN_SDK_VERSION);
+ err += "\n";
+ }
+ }
}
- // Check the target sdk version
- int target_sdk_version = p_preset->get("version/target_sdk");
- if (target_sdk_version != DEFAULT_TARGET_SDK_VERSION && !custom_build_enabled) {
- valid = false;
- err += TTR("Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is enabled.");
- err += "\n";
+ // Check the target sdk version.
+ String target_sdk_str = p_preset->get("custom_build/target_sdk");
+ int target_sdk_int = DEFAULT_TARGET_SDK_VERSION;
+ if (!target_sdk_str.is_empty()) { // Empty means no override, nothing to do.
+ if (!custom_build_enabled) {
+ valid = false;
+ err += TTR("\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled.");
+ err += "\n";
+ }
+ if (!target_sdk_str.is_valid_int()) {
+ valid = false;
+ err += vformat(TTR("\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."), target_sdk_str);
+ err += "\n";
+ } else {
+ target_sdk_int = target_sdk_str.to_int();
+ if (target_sdk_int > DEFAULT_TARGET_SDK_VERSION) {
+ // Warning only, so don't override `valid`.
+ err += vformat(TTR("\"Target SDK\" %d is higher than the default version %d. This may work, but wasn't tested and may be unstable."), target_sdk_int, DEFAULT_TARGET_SDK_VERSION);
+ err += "\n";
+ }
+ }
}
- if (target_sdk_version < min_sdk_version) {
+ if (target_sdk_int < min_sdk_int) {
valid = false;
- err += TTR("\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version.");
+ err += TTR("\"Target SDK\" version must be greater or equal to \"Min SDK\" version.");
err += "\n";
}
@@ -2326,7 +2367,7 @@ void EditorExportPlatformAndroid::get_command_line_flags(const Ref<EditorExportP
}
Error EditorExportPlatformAndroid::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"));
+ int export_format = int(p_preset->get("custom_build/export_format"));
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");
@@ -2482,7 +2523,7 @@ String EditorExportPlatformAndroid::join_list(List<String> parts, const String &
}
Error EditorExportPlatformAndroid::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) {
- int export_format = int(p_preset->get("custom_template/export_format"));
+ int export_format = int(p_preset->get("custom_build/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);
}
@@ -2495,7 +2536,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
EditorProgress ep("export", TTR("Exporting for Android"), 105, true);
- bool use_custom_build = bool(p_preset->get("custom_template/use_custom_build"));
+ bool use_custom_build = bool(p_preset->get("custom_build/use_custom_build"));
bool p_give_internet = p_flags & (DEBUG_FLAG_DUMB_CLIENT | DEBUG_FLAG_REMOTE_DEBUG);
bool apk_expansion = p_preset->get("apk_expansion/enable");
Vector<String> enabled_abis = get_enabled_abis(p_preset);
@@ -2623,8 +2664,14 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
String package_name = get_package_name(p_preset->get("package/unique_name"));
String version_code = itos(p_preset->get("version/code"));
String version_name = p_preset->get("version/name");
- String min_sdk_version = itos(p_preset->get("version/min_sdk"));
- String target_sdk_version = itos(p_preset->get("version/target_sdk"));
+ String min_sdk_version = p_preset->get("custom_build/min_sdk");
+ if (!min_sdk_version.is_valid_int()) {
+ min_sdk_version = itos(DEFAULT_MIN_SDK_VERSION);
+ }
+ String target_sdk_version = p_preset->get("custom_build/target_sdk");
+ if (!target_sdk_version.is_valid_int()) {
+ target_sdk_version = itos(DEFAULT_TARGET_SDK_VERSION);
+ }
String enabled_abi_string = String("|").join(enabled_abis);
String sign_flag = should_sign ? "true" : "false";
String zipalign_flag = "true";
@@ -3071,13 +3118,8 @@ void EditorExportPlatformAndroid::resolve_platform_feature_priorities(const Ref<
}
EditorExportPlatformAndroid::EditorExportPlatformAndroid() {
- Ref<Image> img = memnew(Image(_android_logo));
- logo.instantiate();
- logo->create_from_image(img);
-
- img = Ref<Image>(memnew(Image(_android_run_icon)));
- run_icon.instantiate();
- run_icon->create_from_image(img);
+ logo = ImageTexture::create_from_image(memnew(Image(_android_logo)));
+ run_icon = ImageTexture::create_from_image(memnew(Image(_android_run_icon)));
devices_changed.set();
plugins_changed.set();
diff --git a/platform/android/export/export_plugin.h b/platform/android/export/export_plugin.h
index eeb5aae0f1..8fd2f0680d 100644
--- a/platform/android/export/export_plugin.h
+++ b/platform/android/export/export_plugin.h
@@ -35,7 +35,7 @@
#include "core/io/zip_io.h"
#include "core/os/os.h"
-#include "editor/editor_export.h"
+#include "editor/export/editor_export_platform.h"
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">
@@ -116,7 +116,9 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
static Error copy_gradle_so(void *p_userdata, const SharedObject &p_so);
- bool _has_storage_permission(const Vector<String> &p_permissions);
+ bool _has_read_write_storage_permission(const Vector<String> &p_permissions);
+
+ bool _has_manage_external_storage_permission(const Vector<String> &p_permissions);
void _get_permissions(const Ref<EditorExportPreset> &p_preset, bool p_give_internet, Vector<String> &r_permissions);
diff --git a/platform/android/export/gradle_export_util.cpp b/platform/android/export/gradle_export_util.cpp
index 9a470edfdd..8d370a31a4 100644
--- a/platform/android/export/gradle_export_util.cpp
+++ b/platform/android/export/gradle_export_util.cpp
@@ -254,7 +254,7 @@ String _get_activity_tag(const Ref<EditorExportPreset> &p_preset) {
return manifest_activity_text;
}
-String _get_application_tag(const Ref<EditorExportPreset> &p_preset, bool p_has_storage_permission) {
+String _get_application_tag(const Ref<EditorExportPreset> &p_preset, bool p_has_read_write_storage_permission) {
int xr_mode_index = (int)(p_preset->get("xr_features/xr_mode"));
bool uses_xr = xr_mode_index == XR_MODE_OPENXR;
String manifest_application_text = vformat(
@@ -271,7 +271,7 @@ String _get_application_tag(const Ref<EditorExportPreset> &p_preset, bool p_has_
bool_to_string(p_preset->get("user_data_backup/allow")),
bool_to_string(p_preset->get("package/classify_as_game")),
bool_to_string(p_preset->get("package/retain_data_on_uninstall")),
- bool_to_string(p_has_storage_permission));
+ bool_to_string(p_has_read_write_storage_permission));
if (uses_xr) {
bool hand_tracking_enabled = (int)(p_preset->get("xr_features/hand_tracking")) > XR_HAND_TRACKING_NONE;
diff --git a/platform/android/export/gradle_export_util.h b/platform/android/export/gradle_export_util.h
index 109852bdfc..232b4458c6 100644
--- a/platform/android/export/gradle_export_util.h
+++ b/platform/android/export/gradle_export_util.h
@@ -28,14 +28,14 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef GODOT_GRADLE_EXPORT_UTIL_H
-#define GODOT_GRADLE_EXPORT_UTIL_H
+#ifndef ANDROID_GRADLE_EXPORT_UTIL_H
+#define ANDROID_GRADLE_EXPORT_UTIL_H
#include "core/io/dir_access.h"
#include "core/io/file_access.h"
#include "core/io/zip_io.h"
#include "core/os/os.h"
-#include "editor/editor_export.h"
+#include "editor/export/editor_export.h"
const String godot_project_name_xml_string = R"(<?xml version="1.0" encoding="utf-8"?>
<!--WARNING: THIS FILE WILL BE OVERWRITTEN AT BUILD TIME-->
@@ -104,6 +104,6 @@ String _get_xr_features_tag(const Ref<EditorExportPreset> &p_preset);
String _get_activity_tag(const Ref<EditorExportPreset> &p_preset);
-String _get_application_tag(const Ref<EditorExportPreset> &p_preset, bool p_has_storage_permission);
+String _get_application_tag(const Ref<EditorExportPreset> &p_preset, bool p_has_read_write_storage_permission);
-#endif // GODOT_GRADLE_EXPORT_UTIL_H
+#endif // ANDROID_GRADLE_EXPORT_UTIL_H
diff --git a/platform/android/file_access_android.cpp b/platform/android/file_access_android.cpp
index 4bb8a13bb6..ace7636e6c 100644
--- a/platform/android/file_access_android.cpp
+++ b/platform/android/file_access_android.cpp
@@ -34,14 +34,20 @@
AAssetManager *FileAccessAndroid::asset_manager = nullptr;
-Ref<FileAccess> FileAccessAndroid::create_android() {
- return memnew(FileAccessAndroid);
+String FileAccessAndroid::get_path() const {
+ return path_src;
+}
+
+String FileAccessAndroid::get_path_absolute() const {
+ return absolute_path;
}
Error FileAccessAndroid::_open(const String &p_path, int p_mode_flags) {
_close();
+ path_src = p_path;
String path = fix_path(p_path).simplify_path();
+ absolute_path = path;
if (path.begins_with("/")) {
path = path.substr(1, path.length());
} else if (path.begins_with("res://")) {
@@ -134,7 +140,7 @@ uint64_t FileAccessAndroid::get_buffer(uint8_t *p_dst, uint64_t p_length) const
}
Error FileAccessAndroid::get_error() const {
- return eof ? ERR_FILE_EOF : OK; //not sure what else it may happen
+ return eof ? ERR_FILE_EOF : OK; // not sure what else it may happen
}
void FileAccessAndroid::flush() {
diff --git a/platform/android/file_access_android.h b/platform/android/file_access_android.h
index c16f74ac43..e6fd8c857b 100644
--- a/platform/android/file_access_android.h
+++ b/platform/android/file_access_android.h
@@ -37,11 +37,12 @@
#include <stdio.h>
class FileAccessAndroid : public FileAccess {
- static Ref<FileAccess> create_android();
mutable AAsset *asset = nullptr;
mutable uint64_t len = 0;
mutable uint64_t pos = 0;
mutable bool eof = false;
+ String absolute_path;
+ String path_src;
void _close();
@@ -51,6 +52,11 @@ public:
virtual Error _open(const String &p_path, int p_mode_flags); // open a file
virtual bool is_open() const; // true when file is open
+ /// returns the path for the current open file
+ virtual String get_path() const;
+ /// returns the absolute path for the current open file
+ virtual String get_path_absolute() const;
+
virtual void seek(uint64_t p_position); // seek to a given position
virtual void seek_end(int64_t p_position = 0); // seek from the end of file
virtual uint64_t get_position() const; // get position in the file
diff --git a/platform/android/file_access_filesystem_jandroid.cpp b/platform/android/file_access_filesystem_jandroid.cpp
new file mode 100644
index 0000000000..733d92f741
--- /dev/null
+++ b/platform/android/file_access_filesystem_jandroid.cpp
@@ -0,0 +1,329 @@
+/*************************************************************************/
+/* file_access_filesystem_jandroid.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 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_filesystem_jandroid.h"
+#include "core/os/os.h"
+#include "core/templates/local_vector.h"
+#include "thread_jandroid.h"
+#include <unistd.h>
+
+jobject FileAccessFilesystemJAndroid::file_access_handler = nullptr;
+jclass FileAccessFilesystemJAndroid::cls;
+
+jmethodID FileAccessFilesystemJAndroid::_file_open = nullptr;
+jmethodID FileAccessFilesystemJAndroid::_file_get_size = nullptr;
+jmethodID FileAccessFilesystemJAndroid::_file_seek = nullptr;
+jmethodID FileAccessFilesystemJAndroid::_file_seek_end = nullptr;
+jmethodID FileAccessFilesystemJAndroid::_file_read = nullptr;
+jmethodID FileAccessFilesystemJAndroid::_file_tell = nullptr;
+jmethodID FileAccessFilesystemJAndroid::_file_eof = nullptr;
+jmethodID FileAccessFilesystemJAndroid::_file_close = nullptr;
+jmethodID FileAccessFilesystemJAndroid::_file_write = nullptr;
+jmethodID FileAccessFilesystemJAndroid::_file_flush = nullptr;
+jmethodID FileAccessFilesystemJAndroid::_file_exists = nullptr;
+jmethodID FileAccessFilesystemJAndroid::_file_last_modified = nullptr;
+
+String FileAccessFilesystemJAndroid::get_path() const {
+ return path_src;
+}
+
+String FileAccessFilesystemJAndroid::get_path_absolute() const {
+ return absolute_path;
+}
+
+Error FileAccessFilesystemJAndroid::_open(const String &p_path, int p_mode_flags) {
+ if (is_open()) {
+ _close();
+ }
+
+ if (_file_open) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND_V(env == nullptr, ERR_UNCONFIGURED);
+
+ String path = fix_path(p_path).simplify_path();
+ jstring js = env->NewStringUTF(path.utf8().get_data());
+ int res = env->CallIntMethod(file_access_handler, _file_open, js, p_mode_flags);
+ env->DeleteLocalRef(js);
+
+ if (res <= 0) {
+ switch (res) {
+ case 0:
+ default:
+ return ERR_FILE_CANT_OPEN;
+
+ case -1:
+ return ERR_FILE_NOT_FOUND;
+ }
+ }
+
+ id = res;
+ path_src = p_path;
+ absolute_path = path;
+ return OK;
+ } else {
+ return ERR_UNCONFIGURED;
+ }
+}
+
+void FileAccessFilesystemJAndroid::_close() {
+ if (!is_open()) {
+ return;
+ }
+
+ if (_file_close) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND(env == nullptr);
+ env->CallVoidMethod(file_access_handler, _file_close, id);
+ }
+ id = 0;
+}
+
+bool FileAccessFilesystemJAndroid::is_open() const {
+ return id != 0;
+}
+
+void FileAccessFilesystemJAndroid::seek(uint64_t p_position) {
+ if (_file_seek) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND(env == nullptr);
+ ERR_FAIL_COND_MSG(!is_open(), "File must be opened before use.");
+ env->CallVoidMethod(file_access_handler, _file_seek, id, p_position);
+ }
+}
+
+void FileAccessFilesystemJAndroid::seek_end(int64_t p_position) {
+ if (_file_seek_end) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND(env == nullptr);
+ ERR_FAIL_COND_MSG(!is_open(), "File must be opened before use.");
+ env->CallVoidMethod(file_access_handler, _file_seek_end, id, p_position);
+ }
+}
+
+uint64_t FileAccessFilesystemJAndroid::get_position() const {
+ if (_file_tell) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND_V(env == nullptr, 0);
+ ERR_FAIL_COND_V_MSG(!is_open(), 0, "File must be opened before use.");
+ return env->CallLongMethod(file_access_handler, _file_tell, id);
+ } else {
+ return 0;
+ }
+}
+
+uint64_t FileAccessFilesystemJAndroid::get_length() const {
+ if (_file_get_size) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND_V(env == nullptr, 0);
+ ERR_FAIL_COND_V_MSG(!is_open(), 0, "File must be opened before use.");
+ return env->CallLongMethod(file_access_handler, _file_get_size, id);
+ } else {
+ return 0;
+ }
+}
+
+bool FileAccessFilesystemJAndroid::eof_reached() const {
+ if (_file_eof) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND_V(env == nullptr, false);
+ ERR_FAIL_COND_V_MSG(!is_open(), false, "File must be opened before use.");
+ return env->CallBooleanMethod(file_access_handler, _file_eof, id);
+ } else {
+ return false;
+ }
+}
+
+uint8_t FileAccessFilesystemJAndroid::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;
+}
+
+String FileAccessFilesystemJAndroid::get_line() const {
+ ERR_FAIL_COND_V_MSG(!is_open(), String(), "File must be opened before use.");
+
+ const size_t buffer_size_limit = 2048;
+ const uint64_t file_size = get_length();
+ const uint64_t start_position = get_position();
+
+ String result;
+ LocalVector<uint8_t> line_buffer;
+ size_t current_buffer_size = 0;
+ uint64_t line_buffer_position = 0;
+
+ while (true) {
+ size_t line_buffer_size = MIN(buffer_size_limit, file_size - get_position());
+ if (line_buffer_size <= 0) {
+ break;
+ }
+
+ current_buffer_size += line_buffer_size;
+ line_buffer.resize(current_buffer_size);
+
+ uint64_t bytes_read = get_buffer(&line_buffer[line_buffer_position], current_buffer_size - line_buffer_position);
+ if (bytes_read <= 0) {
+ break;
+ }
+
+ for (; bytes_read > 0; line_buffer_position++, bytes_read--) {
+ uint8_t elem = line_buffer[line_buffer_position];
+ if (elem == '\n' || elem == '\0') {
+ // Found the end of the line
+ const_cast<FileAccessFilesystemJAndroid *>(this)->seek(start_position + line_buffer_position + 1);
+ if (result.parse_utf8((const char *)line_buffer.ptr(), line_buffer_position)) {
+ return String();
+ }
+ return result;
+ }
+ }
+ }
+
+ if (result.parse_utf8((const char *)line_buffer.ptr(), line_buffer_position)) {
+ return String();
+ }
+ return result;
+}
+
+uint64_t FileAccessFilesystemJAndroid::get_buffer(uint8_t *p_dst, uint64_t p_length) const {
+ if (_file_read) {
+ ERR_FAIL_COND_V_MSG(!is_open(), 0, "File must be opened before use.");
+ if (p_length == 0) {
+ return 0;
+ }
+
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND_V(env == nullptr, 0);
+
+ jobject j_buffer = env->NewDirectByteBuffer(p_dst, p_length);
+ int length = env->CallIntMethod(file_access_handler, _file_read, id, j_buffer);
+ env->DeleteLocalRef(j_buffer);
+ return length;
+ } else {
+ return 0;
+ }
+}
+
+void FileAccessFilesystemJAndroid::store_8(uint8_t p_dest) {
+ store_buffer(&p_dest, 1);
+}
+
+void FileAccessFilesystemJAndroid::store_buffer(const uint8_t *p_src, uint64_t p_length) {
+ if (_file_write) {
+ ERR_FAIL_COND_MSG(!is_open(), "File must be opened before use.");
+ if (p_length == 0) {
+ return;
+ }
+
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND(env == nullptr);
+
+ jobject j_buffer = env->NewDirectByteBuffer((void *)p_src, p_length);
+ env->CallVoidMethod(file_access_handler, _file_write, id, j_buffer);
+ env->DeleteLocalRef(j_buffer);
+ }
+}
+
+Error FileAccessFilesystemJAndroid::get_error() const {
+ if (eof_reached()) {
+ return ERR_FILE_EOF;
+ }
+ return OK;
+}
+
+void FileAccessFilesystemJAndroid::flush() {
+ if (_file_flush) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND(env == nullptr);
+ ERR_FAIL_COND_MSG(!is_open(), "File must be opened before use.");
+ env->CallVoidMethod(file_access_handler, _file_flush, id);
+ }
+}
+
+bool FileAccessFilesystemJAndroid::file_exists(const String &p_path) {
+ if (_file_exists) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND_V(env == nullptr, false);
+
+ String path = fix_path(p_path).simplify_path();
+ jstring js = env->NewStringUTF(path.utf8().get_data());
+ bool result = env->CallBooleanMethod(file_access_handler, _file_exists, js);
+ env->DeleteLocalRef(js);
+ return result;
+ } else {
+ return false;
+ }
+}
+
+uint64_t FileAccessFilesystemJAndroid::_get_modified_time(const String &p_file) {
+ if (_file_last_modified) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND_V(env == nullptr, false);
+
+ String path = fix_path(p_file).simplify_path();
+ jstring js = env->NewStringUTF(path.utf8().get_data());
+ uint64_t result = env->CallLongMethod(file_access_handler, _file_last_modified, js);
+ env->DeleteLocalRef(js);
+ return result;
+ } else {
+ return 0;
+ }
+}
+
+void FileAccessFilesystemJAndroid::setup(jobject p_file_access_handler) {
+ JNIEnv *env = get_jni_env();
+ file_access_handler = env->NewGlobalRef(p_file_access_handler);
+
+ jclass c = env->GetObjectClass(file_access_handler);
+ cls = (jclass)env->NewGlobalRef(c);
+
+ _file_open = env->GetMethodID(cls, "fileOpen", "(Ljava/lang/String;I)I");
+ _file_get_size = env->GetMethodID(cls, "fileGetSize", "(I)J");
+ _file_tell = env->GetMethodID(cls, "fileGetPosition", "(I)J");
+ _file_eof = env->GetMethodID(cls, "isFileEof", "(I)Z");
+ _file_seek = env->GetMethodID(cls, "fileSeek", "(IJ)V");
+ _file_seek_end = env->GetMethodID(cls, "fileSeekFromEnd", "(IJ)V");
+ _file_read = env->GetMethodID(cls, "fileRead", "(ILjava/nio/ByteBuffer;)I");
+ _file_close = env->GetMethodID(cls, "fileClose", "(I)V");
+ _file_write = env->GetMethodID(cls, "fileWrite", "(ILjava/nio/ByteBuffer;)V");
+ _file_flush = env->GetMethodID(cls, "fileFlush", "(I)V");
+ _file_exists = env->GetMethodID(cls, "fileExists", "(Ljava/lang/String;)Z");
+ _file_last_modified = env->GetMethodID(cls, "fileLastModified", "(Ljava/lang/String;)J");
+}
+
+FileAccessFilesystemJAndroid::FileAccessFilesystemJAndroid() {
+ id = 0;
+}
+
+FileAccessFilesystemJAndroid::~FileAccessFilesystemJAndroid() {
+ if (is_open()) {
+ _close();
+ }
+}
diff --git a/platform/android/file_access_filesystem_jandroid.h b/platform/android/file_access_filesystem_jandroid.h
new file mode 100644
index 0000000000..7deb8de37b
--- /dev/null
+++ b/platform/android/file_access_filesystem_jandroid.h
@@ -0,0 +1,98 @@
+/*************************************************************************/
+/* file_access_filesystem_jandroid.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 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. */
+/*************************************************************************/
+
+#ifndef FILE_ACCESS_FILESYSTEM_JANDROID_H
+#define FILE_ACCESS_FILESYSTEM_JANDROID_H
+
+#include "core/io/file_access.h"
+#include "java_godot_lib_jni.h"
+
+class FileAccessFilesystemJAndroid : public FileAccess {
+ static jobject file_access_handler;
+ static jclass cls;
+
+ static jmethodID _file_open;
+ static jmethodID _file_get_size;
+ static jmethodID _file_seek;
+ static jmethodID _file_seek_end;
+ static jmethodID _file_tell;
+ static jmethodID _file_eof;
+ static jmethodID _file_read;
+ static jmethodID _file_write;
+ static jmethodID _file_flush;
+ static jmethodID _file_close;
+ static jmethodID _file_exists;
+ static jmethodID _file_last_modified;
+
+ int id;
+ String absolute_path;
+ String path_src;
+
+ void _close(); ///< close a file
+
+public:
+ virtual Error _open(const String &p_path, int p_mode_flags) override; ///< open a file
+ virtual bool is_open() const override; ///< true when file is open
+
+ /// returns the path for the current open file
+ virtual String get_path() const override;
+ /// returns the absolute path for the current open file
+ virtual String get_path_absolute() const override;
+
+ virtual void seek(uint64_t p_position) override; ///< seek to a given position
+ virtual void seek_end(int64_t p_position = 0) override; ///< seek from the end of file
+ virtual uint64_t get_position() const override; ///< get position in the file
+ virtual uint64_t get_length() const override; ///< get size of the file
+
+ virtual bool eof_reached() const override; ///< reading passed EOF
+
+ virtual uint8_t get_8() const override; ///< get a byte
+ virtual String get_line() const override; ///< get a line
+ virtual uint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const override;
+
+ virtual Error get_error() const override; ///< get last error
+
+ virtual void flush() override;
+ virtual void store_8(uint8_t p_dest) override; ///< store a byte
+ virtual void store_buffer(const uint8_t *p_src, uint64_t p_length) override;
+
+ virtual bool file_exists(const String &p_path) override; ///< return true if a file exists
+
+ static void setup(jobject p_file_access_handler);
+
+ virtual uint64_t _get_modified_time(const String &p_file) override;
+ virtual uint32_t _get_unix_permissions(const String &p_file) override { return 0; }
+ virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override { return FAILED; }
+
+ FileAccessFilesystemJAndroid();
+ ~FileAccessFilesystemJAndroid();
+};
+
+#endif // FILE_ACCESS_FILESYSTEM_JANDROID_H
diff --git a/platform/android/java/app/AndroidManifest.xml b/platform/android/java/app/AndroidManifest.xml
index c98e8f1d55..2d4c4763a2 100644
--- a/platform/android/java/app/AndroidManifest.xml
+++ b/platform/android/java/app/AndroidManifest.xml
@@ -59,6 +59,7 @@
android:theme="@style/GodotAppSplashTheme"
android:launchMode="singleTask"
android:excludeFromRecents="false"
+ android:exported="true"
android:screenOrientation="landscape"
android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize|density|keyboard|navigation|screenLayout|uiMode"
android:resizeableActivity="false"
diff --git a/platform/android/java/app/config.gradle b/platform/android/java/app/config.gradle
index 73a412a2b0..fbd97fae0b 100644
--- a/platform/android/java/app/config.gradle
+++ b/platform/android/java/app/config.gradle
@@ -1,14 +1,14 @@
ext.versions = [
androidGradlePlugin: '7.0.3',
- compileSdk : 31,
+ compileSdk : 32,
minSdk : 19, // Also update 'platform/android/java/lib/AndroidManifest.xml#minSdkVersion' & 'platform/android/export/export_plugin.cpp#DEFAULT_MIN_SDK_VERSION'
- targetSdk : 30, // Also update 'platform/android/java/lib/AndroidManifest.xml#targetSdkVersion' & 'platform/android/export/export_plugin.cpp#DEFAULT_TARGET_SDK_VERSION'
- buildTools : '30.0.3',
+ targetSdk : 32, // Also update 'platform/android/java/lib/AndroidManifest.xml#targetSdkVersion' & 'platform/android/export/export_plugin.cpp#DEFAULT_TARGET_SDK_VERSION'
+ buildTools : '32.0.0',
kotlinVersion : '1.6.21',
fragmentVersion : '1.3.6',
nexusPublishVersion: '1.1.0',
javaVersion : 11,
- ndkVersion : '21.4.7075529' // Also update 'platform/android/detect.py#get_project_ndk_version()' when this is updated.
+ ndkVersion : '23.2.8568313' // Also update 'platform/android/detect.py#get_ndk_version()' when this is updated.
]
diff --git a/platform/android/java/editor/build.gradle b/platform/android/java/editor/build.gradle
index dd167c3880..729966ee69 100644
--- a/platform/android/java/editor/build.gradle
+++ b/platform/android/java/editor/build.gradle
@@ -23,8 +23,7 @@ android {
versionCode getGodotLibraryVersionCode()
versionName getGodotLibraryVersionName()
minSdkVersion versions.minSdk
- //noinspection ExpiredTargetSdkVersion - Restrict to version 29 until https://github.com/godotengine/godot/pull/51815 is submitted
- targetSdkVersion 29 // versions.targetSdk
+ targetSdkVersion versions.targetSdk
missingDimensionStrategy 'products', 'editor'
}
diff --git a/platform/android/java/editor/src/main/AndroidManifest.xml b/platform/android/java/editor/src/main/AndroidManifest.xml
index 659caf7ab4..abf506a83c 100644
--- a/platform/android/java/editor/src/main/AndroidManifest.xml
+++ b/platform/android/java/editor/src/main/AndroidManifest.xml
@@ -14,8 +14,12 @@
android:glEsVersion="0x00020000"
android:required="true" />
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+ <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
+ tools:ignore="ScopedStorage" />
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
+ android:maxSdkVersion="29"/>
+ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
+ android:maxSdkVersion="29"/>
<uses-permission android:name="android.permission.INTERNET" />
<application
@@ -49,6 +53,7 @@
android:process=":GodotEditor"
android:launchMode="singleTask"
android:screenOrientation="userLandscape"
+ android:exported="false"
android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen">
<layout android:defaultHeight="@dimen/editor_default_window_height"
android:defaultWidth="@dimen/editor_default_window_width" />
@@ -60,6 +65,7 @@
android:label="@string/godot_project_name_string"
android:process=":GodotGame"
android:launchMode="singleTask"
+ android:exported="false"
android:screenOrientation="userLandscape"
android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen">
<layout android:defaultHeight="@dimen/editor_default_window_height"
diff --git a/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.kt b/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.kt
index a1ade722e8..740f3f48d3 100644
--- a/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.kt
+++ b/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.kt
@@ -30,10 +30,14 @@
package org.godotengine.editor
+import android.Manifest
import android.content.Intent
+import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import android.os.Debug
+import android.os.Environment
+import android.widget.Toast
import androidx.window.layout.WindowMetricsCalculator
import org.godotengine.godot.FullScreenGodotApp
import org.godotengine.godot.utils.PermissionsUtil
@@ -68,7 +72,7 @@ open class GodotEditor : FullScreenGodotApp() {
val params = intent.getStringArrayExtra(COMMAND_LINE_PARAMS)
updateCommandLineParams(params)
- if (BuildConfig.BUILD_TYPE == "debug" && WAIT_FOR_DEBUGGER) {
+ if (BuildConfig.BUILD_TYPE == "dev" && WAIT_FOR_DEBUGGER) {
Debug.waitForDebugger()
}
@@ -143,4 +147,50 @@ open class GodotEditor : FullScreenGodotApp() {
* The Godot Android Editor sets its own orientation via its AndroidManifest
*/
protected open fun overrideOrientationRequest() = true
+
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+ super.onActivityResult(requestCode, resultCode, data)
+ // Check if we got the MANAGE_EXTERNAL_STORAGE permission
+ if (requestCode == PermissionsUtil.REQUEST_MANAGE_EXTERNAL_STORAGE_REQ_CODE) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
+ if (!Environment.isExternalStorageManager()) {
+ Toast.makeText(
+ this,
+ R.string.denied_storage_permission_error_msg,
+ Toast.LENGTH_LONG
+ ).show()
+ }
+ }
+ }
+ }
+
+ override fun onRequestPermissionsResult(
+ requestCode: Int,
+ permissions: Array<String?>,
+ grantResults: IntArray
+ ) {
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults)
+ // Check if we got access to the necessary storage permissions
+ if (requestCode == PermissionsUtil.REQUEST_ALL_PERMISSION_REQ_CODE) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
+ var hasReadAccess = false
+ var hasWriteAccess = false
+ for (i in permissions.indices) {
+ if (Manifest.permission.READ_EXTERNAL_STORAGE == permissions[i] && grantResults[i] == PackageManager.PERMISSION_GRANTED) {
+ hasReadAccess = true
+ }
+ if (Manifest.permission.WRITE_EXTERNAL_STORAGE == permissions[i] && grantResults[i] == PackageManager.PERMISSION_GRANTED) {
+ hasWriteAccess = true
+ }
+ }
+ if (!hasReadAccess || !hasWriteAccess) {
+ Toast.makeText(
+ this,
+ R.string.denied_storage_permission_error_msg,
+ Toast.LENGTH_LONG
+ ).show()
+ }
+ }
+ }
+ }
}
diff --git a/platform/android/java/editor/src/main/res/values/strings.xml b/platform/android/java/editor/src/main/res/values/strings.xml
index e8ce34f34d..837a5d62e1 100644
--- a/platform/android/java/editor/src/main/res/values/strings.xml
+++ b/platform/android/java/editor/src/main/res/values/strings.xml
@@ -1,4 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="godot_editor_name_string">Godot Editor 4.x</string>
+
+ <string name="denied_storage_permission_error_msg">Missing storage access permission!</string>
</resources>
diff --git a/platform/android/java/lib/AndroidManifest.xml b/platform/android/java/lib/AndroidManifest.xml
index 90dc61a6ac..79b5aadf2a 100644
--- a/platform/android/java/lib/AndroidManifest.xml
+++ b/platform/android/java/lib/AndroidManifest.xml
@@ -5,7 +5,7 @@
android:versionName="1.0">
<!-- Should match the mindSdk and targetSdk values in platform/android/java/app/config.gradle -->
- <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="30" />
+ <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="32" />
<application>
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 cafae94d62..28e689e63a 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/Godot.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.java
@@ -34,6 +34,8 @@ import static android.content.Context.MODE_PRIVATE;
import static android.content.Context.WINDOW_SERVICE;
import org.godotengine.godot.input.GodotEditText;
+import org.godotengine.godot.io.directory.DirectoryAccessHandler;
+import org.godotengine.godot.io.file.FileAccessHandler;
import org.godotengine.godot.plugin.GodotPlugin;
import org.godotengine.godot.plugin.GodotPluginRegistry;
import org.godotengine.godot.tts.GodotTTS;
@@ -164,9 +166,9 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
private Sensor mMagnetometer;
private Sensor mGyroscope;
- public static GodotIO io;
- public static GodotNetUtils netUtils;
- public static GodotTTS tts;
+ public GodotIO io;
+ public GodotNetUtils netUtils;
+ public GodotTTS tts;
public interface ResultCallback {
void callback(int requestCode, int resultCode, Intent data);
@@ -458,16 +460,26 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
final Activity activity = getActivity();
io = new GodotIO(activity);
- GodotLib.io = io;
netUtils = new GodotNetUtils(activity);
tts = new GodotTTS(activity);
+ Context context = getContext();
+ DirectoryAccessHandler directoryAccessHandler = new DirectoryAccessHandler(context);
+ FileAccessHandler fileAccessHandler = new FileAccessHandler(context);
mSensorManager = (SensorManager)activity.getSystemService(Context.SENSOR_SERVICE);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mGravity = mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY);
mMagnetometer = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
mGyroscope = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
- GodotLib.initialize(activity, this, activity.getAssets(), use_apk_expansion);
+ GodotLib.initialize(activity,
+ this,
+ activity.getAssets(),
+ io,
+ netUtils,
+ directoryAccessHandler,
+ fileAccessHandler,
+ use_apk_expansion,
+ tts);
result_callback = null;
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 a8e3669ac6..0434efdf4c 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java
@@ -36,7 +36,6 @@ import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.content.pm.ActivityInfo;
-import android.content.res.AssetManager;
import android.graphics.Point;
import android.graphics.Rect;
import android.net.Uri;
@@ -46,12 +45,10 @@ import android.provider.Settings;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
-import android.util.SparseArray;
import android.view.Display;
import android.view.DisplayCutout;
import android.view.WindowInsets;
-import java.io.IOException;
import java.util.List;
import java.util.Locale;
@@ -60,7 +57,6 @@ import java.util.Locale;
public class GodotIO {
private static final String TAG = GodotIO.class.getSimpleName();
- private final AssetManager am;
private final Activity activity;
private final String uniqueId;
GodotEditText edit;
@@ -73,100 +69,8 @@ public class GodotIO {
final int SCREEN_SENSOR_PORTRAIT = 5;
final int SCREEN_SENSOR = 6;
- /////////////////////////
- /// DIRECTORIES
- /////////////////////////
-
- static class AssetDir {
- public String[] files;
- public int current;
- public String path;
- }
-
- private int last_dir_id = 1;
-
- private final SparseArray<AssetDir> dirs;
-
- public int dir_open(String path) {
- AssetDir ad = new AssetDir();
- ad.current = 0;
- ad.path = path;
-
- try {
- ad.files = am.list(path);
- // no way to find path is directory or file exactly.
- // but if ad.files.length==0, then it's an empty directory or file.
- if (ad.files.length == 0) {
- return -1;
- }
- } catch (IOException e) {
- System.out.printf("Exception on dir_open: %s\n", e);
- return -1;
- }
-
- ++last_dir_id;
- dirs.put(last_dir_id, ad);
-
- return last_dir_id;
- }
-
- public boolean dir_is_dir(int id) {
- if (dirs.get(id) == null) {
- System.out.printf("dir_next: invalid dir id: %d\n", id);
- return false;
- }
- AssetDir ad = dirs.get(id);
- //System.out.printf("go next: %d,%d\n",ad.current,ad.files.length);
- int idx = ad.current;
- if (idx > 0)
- idx--;
-
- if (idx >= ad.files.length)
- return false;
- String fname = ad.files[idx];
-
- try {
- if (ad.path.equals(""))
- am.open(fname);
- else
- am.open(ad.path + "/" + fname);
- return false;
- } catch (Exception e) {
- return true;
- }
- }
-
- public String dir_next(int id) {
- if (dirs.get(id) == null) {
- System.out.printf("dir_next: invalid dir id: %d\n", id);
- return "";
- }
-
- AssetDir ad = dirs.get(id);
- //System.out.printf("go next: %d,%d\n",ad.current,ad.files.length);
-
- if (ad.current >= ad.files.length) {
- ad.current++;
- return "";
- }
- String r = ad.files[ad.current];
- ad.current++;
- return r;
- }
-
- public void dir_close(int id) {
- if (dirs.get(id) == null) {
- System.out.printf("dir_close: invalid dir id: %d\n", id);
- return;
- }
-
- dirs.remove(id);
- }
-
GodotIO(Activity p_activity) {
- am = p_activity.getAssets();
activity = p_activity;
- dirs = new SparseArray<>();
String androidId = Settings.Secure.getString(activity.getContentResolver(),
Settings.Secure.ANDROID_ID);
if (androidId == null) {
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 1f8f8c82a6..e2ae62d9cf 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java
@@ -31,8 +31,13 @@
package org.godotengine.godot;
import org.godotengine.godot.gl.GodotRenderer;
+import org.godotengine.godot.io.directory.DirectoryAccessHandler;
+import org.godotengine.godot.io.file.FileAccessHandler;
+import org.godotengine.godot.tts.GodotTTS;
+import org.godotengine.godot.utils.GodotNetUtils;
import android.app.Activity;
+import android.content.res.AssetManager;
import android.hardware.SensorEvent;
import android.view.Surface;
@@ -42,8 +47,6 @@ import javax.microedition.khronos.opengles.GL10;
* Wrapper for native library
*/
public class GodotLib {
- public static GodotIO io;
-
static {
System.loadLibrary("godot_android");
}
@@ -51,7 +54,15 @@ public class GodotLib {
/**
* Invoked on the main thread to initialize Godot native layer.
*/
- public static native void initialize(Activity activity, Godot p_instance, Object p_asset_manager, boolean use_apk_expansion);
+ public static native void initialize(Activity activity,
+ Godot p_instance,
+ AssetManager p_asset_manager,
+ GodotIO godotIO,
+ GodotNetUtils netUtils,
+ DirectoryAccessHandler directoryAccessHandler,
+ FileAccessHandler fileAccessHandler,
+ boolean use_apk_expansion,
+ GodotTTS tts);
/**
* Invoked on the main thread to clean up Godot native layer.
@@ -114,11 +125,6 @@ public class GodotLib {
public static native void doubleTap(int buttonMask, int x, int y);
/**
- * Forward scroll events from the main thread to the GL thread.
- */
- public static native void scroll(int x, int y);
-
- /**
* Forward accelerometer sensor events from the main thread to the GL thread.
* @see android.hardware.SensorEventListener#onSensorChanged(SensorEvent)
*/
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 ac13cad23e..778efa914a 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
@@ -80,15 +80,6 @@ public class GodotGestureHandler extends GestureDetector.SimpleOnGestureListener
}
@Override
- public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
- //Log.i("GodotGesture", "onScroll");
- final int x = Math.round(distanceX);
- final int y = Math.round(distanceY);
- GodotLib.scroll(x, y);
- return true;
- }
-
- @Override
public boolean onFling(MotionEvent event1, MotionEvent event2, float velocityX, float velocityY) {
//Log.i("GodotGesture", "onFling");
return true;
diff --git a/platform/android/java/lib/src/org/godotengine/godot/io/StorageScope.kt b/platform/android/java/lib/src/org/godotengine/godot/io/StorageScope.kt
new file mode 100644
index 0000000000..c9282dd247
--- /dev/null
+++ b/platform/android/java/lib/src/org/godotengine/godot/io/StorageScope.kt
@@ -0,0 +1,113 @@
+/*************************************************************************/
+/* StorageScope.kt */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 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.io
+
+import android.content.Context
+import android.os.Build
+import android.os.Environment
+import java.io.File
+
+/**
+ * Represents the different storage scopes.
+ */
+internal enum class StorageScope {
+ /**
+ * Covers internal and external directories accessible to the app without restrictions.
+ */
+ APP,
+
+ /**
+ * Covers shared directories (from Android 10 and higher).
+ */
+ SHARED,
+
+ /**
+ * Everything else..
+ */
+ UNKNOWN;
+
+ class Identifier(context: Context) {
+
+ private val internalAppDir: String? = context.filesDir.canonicalPath
+ private val internalCacheDir: String? = context.cacheDir.canonicalPath
+ private val externalAppDir: String? = context.getExternalFilesDir(null)?.canonicalPath
+ private val sharedDir : String? = Environment.getExternalStorageDirectory().canonicalPath
+ private val downloadsSharedDir: String? = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).canonicalPath
+ private val documentsSharedDir: String? = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS).canonicalPath
+
+ /**
+ * Determines which [StorageScope] the given path falls under.
+ */
+ fun identifyStorageScope(path: String?): StorageScope {
+ if (path == null) {
+ return UNKNOWN
+ }
+
+ val pathFile = File(path)
+ if (!pathFile.isAbsolute) {
+ return UNKNOWN
+ }
+
+ val canonicalPathFile = pathFile.canonicalPath
+
+ if (internalAppDir != null && canonicalPathFile.startsWith(internalAppDir)) {
+ return APP
+ }
+
+ if (internalCacheDir != null && canonicalPathFile.startsWith(internalCacheDir)) {
+ return APP
+ }
+
+ if (externalAppDir != null && canonicalPathFile.startsWith(externalAppDir)) {
+ return APP
+ }
+
+ if (sharedDir != null && canonicalPathFile.startsWith(sharedDir)) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
+ // Before R, apps had access to shared storage so long as they have the right
+ // permissions (and flag on Q).
+ return APP
+ }
+
+ // Post R, access is limited based on the target destination
+ // 'Downloads' and 'Documents' are still accessible
+ if ((downloadsSharedDir != null && canonicalPathFile.startsWith(downloadsSharedDir))
+ || (documentsSharedDir != null && canonicalPathFile.startsWith(documentsSharedDir))) {
+ return APP
+ }
+
+ return SHARED
+ }
+
+ return UNKNOWN
+ }
+ }
+}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/io/directory/AssetsDirectoryAccess.kt b/platform/android/java/lib/src/org/godotengine/godot/io/directory/AssetsDirectoryAccess.kt
new file mode 100644
index 0000000000..098b10ae36
--- /dev/null
+++ b/platform/android/java/lib/src/org/godotengine/godot/io/directory/AssetsDirectoryAccess.kt
@@ -0,0 +1,177 @@
+/*************************************************************************/
+/* AssetsDirectoryAccess.kt */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 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.io.directory
+
+import android.content.Context
+import android.util.Log
+import android.util.SparseArray
+import org.godotengine.godot.io.directory.DirectoryAccessHandler.Companion.INVALID_DIR_ID
+import org.godotengine.godot.io.directory.DirectoryAccessHandler.Companion.STARTING_DIR_ID
+import java.io.File
+import java.io.IOException
+
+/**
+ * Handles directories access within the Android assets directory.
+ */
+internal class AssetsDirectoryAccess(context: Context) : DirectoryAccessHandler.DirectoryAccess {
+
+ companion object {
+ private val TAG = AssetsDirectoryAccess::class.java.simpleName
+ }
+
+ private data class AssetDir(val path: String, val files: Array<String>, var current: Int = 0)
+
+ private val assetManager = context.assets
+
+ private var lastDirId = STARTING_DIR_ID
+ private val dirs = SparseArray<AssetDir>()
+
+ private fun getAssetsPath(originalPath: String): String {
+ if (originalPath.startsWith(File.separatorChar)) {
+ return originalPath.substring(1)
+ }
+ return originalPath
+ }
+
+ override fun hasDirId(dirId: Int) = dirs.indexOfKey(dirId) >= 0
+
+ override fun dirOpen(path: String): Int {
+ val assetsPath = getAssetsPath(path) ?: return INVALID_DIR_ID
+ try {
+ val files = assetManager.list(assetsPath) ?: return INVALID_DIR_ID
+ // Empty directories don't get added to the 'assets' directory, so
+ // if ad.files.length > 0 ==> path is directory
+ // if ad.files.length == 0 ==> path is file
+ if (files.isEmpty()) {
+ return INVALID_DIR_ID
+ }
+
+ val ad = AssetDir(assetsPath, files)
+
+ dirs.put(++lastDirId, ad)
+ return lastDirId
+ } catch (e: IOException) {
+ Log.e(TAG, "Exception on dirOpen", e)
+ return INVALID_DIR_ID
+ }
+ }
+
+ override fun dirExists(path: String): Boolean {
+ val assetsPath = getAssetsPath(path)
+ try {
+ val files = assetManager.list(assetsPath) ?: return false
+ // Empty directories don't get added to the 'assets' directory, so
+ // if ad.files.length > 0 ==> path is directory
+ // if ad.files.length == 0 ==> path is file
+ return files.isNotEmpty()
+ } catch (e: IOException) {
+ Log.e(TAG, "Exception on dirExists", e)
+ return false
+ }
+ }
+
+ override fun fileExists(path: String): Boolean {
+ val assetsPath = getAssetsPath(path) ?: return false
+ try {
+ val files = assetManager.list(assetsPath) ?: return false
+ // Empty directories don't get added to the 'assets' directory, so
+ // if ad.files.length > 0 ==> path is directory
+ // if ad.files.length == 0 ==> path is file
+ return files.isEmpty()
+ } catch (e: IOException) {
+ Log.e(TAG, "Exception on fileExists", e)
+ return false
+ }
+ }
+
+ override fun dirIsDir(dirId: Int): Boolean {
+ val ad: AssetDir = dirs[dirId]
+
+ var idx = ad.current
+ if (idx > 0) {
+ idx--
+ }
+
+ if (idx >= ad.files.size) {
+ return false
+ }
+
+ val fileName = ad.files[idx]
+ // List the contents of $fileName. If it's a file, it will be empty, otherwise it'll be a
+ // directory
+ val filePath = if (ad.path == "") fileName else "${ad.path}/${fileName}"
+ val fileContents = assetManager.list(filePath)
+ return (fileContents?.size?: 0) > 0
+ }
+
+ override fun isCurrentHidden(dirId: Int): Boolean {
+ val ad = dirs[dirId]
+
+ var idx = ad.current
+ if (idx > 0) {
+ idx--
+ }
+
+ if (idx >= ad.files.size) {
+ return false
+ }
+
+ val fileName = ad.files[idx]
+ return fileName.startsWith('.')
+ }
+
+ override fun dirNext(dirId: Int): String {
+ val ad: AssetDir = dirs[dirId]
+
+ if (ad.current >= ad.files.size) {
+ ad.current++
+ return ""
+ }
+
+ return ad.files[ad.current++]
+ }
+
+ override fun dirClose(dirId: Int) {
+ dirs.remove(dirId)
+ }
+
+ override fun getDriveCount() = 0
+
+ override fun getDrive(drive: Int) = ""
+
+ override fun makeDir(dir: String) = false
+
+ override fun getSpaceLeft() = 0L
+
+ override fun rename(from: String, to: String) = false
+
+ override fun remove(filename: String) = false
+}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/io/directory/DirectoryAccessHandler.kt b/platform/android/java/lib/src/org/godotengine/godot/io/directory/DirectoryAccessHandler.kt
new file mode 100644
index 0000000000..fedcf4843f
--- /dev/null
+++ b/platform/android/java/lib/src/org/godotengine/godot/io/directory/DirectoryAccessHandler.kt
@@ -0,0 +1,224 @@
+/*************************************************************************/
+/* DirectoryAccessHandler.kt */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 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.io.directory
+
+import android.content.Context
+import android.util.Log
+import org.godotengine.godot.io.directory.DirectoryAccessHandler.AccessType.ACCESS_FILESYSTEM
+import org.godotengine.godot.io.directory.DirectoryAccessHandler.AccessType.ACCESS_RESOURCES
+
+/**
+ * Handles files and directories access and manipulation for the Android platform
+ */
+class DirectoryAccessHandler(context: Context) {
+
+ companion object {
+ private val TAG = DirectoryAccessHandler::class.java.simpleName
+
+ internal const val INVALID_DIR_ID = -1
+ internal const val STARTING_DIR_ID = 1
+
+ private fun getAccessTypeFromNative(accessType: Int): AccessType? {
+ return when (accessType) {
+ ACCESS_RESOURCES.nativeValue -> ACCESS_RESOURCES
+ ACCESS_FILESYSTEM.nativeValue -> ACCESS_FILESYSTEM
+ else -> null
+ }
+ }
+ }
+
+ private enum class AccessType(val nativeValue: Int) {
+ ACCESS_RESOURCES(0), ACCESS_FILESYSTEM(2)
+ }
+
+ internal interface DirectoryAccess {
+ fun dirOpen(path: String): Int
+ fun dirNext(dirId: Int): String
+ fun dirClose(dirId: Int)
+ fun dirIsDir(dirId: Int): Boolean
+ fun dirExists(path: String): Boolean
+ fun fileExists(path: String): Boolean
+ fun hasDirId(dirId: Int): Boolean
+ fun isCurrentHidden(dirId: Int): Boolean
+ fun getDriveCount() : Int
+ fun getDrive(drive: Int): String
+ fun makeDir(dir: String): Boolean
+ fun getSpaceLeft(): Long
+ fun rename(from: String, to: String): Boolean
+ fun remove(filename: String): Boolean
+ }
+
+ private val assetsDirAccess = AssetsDirectoryAccess(context)
+ private val fileSystemDirAccess = FilesystemDirectoryAccess(context)
+
+ private fun hasDirId(accessType: AccessType, dirId: Int): Boolean {
+ return when (accessType) {
+ ACCESS_RESOURCES -> assetsDirAccess.hasDirId(dirId)
+ ACCESS_FILESYSTEM -> fileSystemDirAccess.hasDirId(dirId)
+ }
+ }
+
+ fun dirOpen(nativeAccessType: Int, path: String?): Int {
+ val accessType = getAccessTypeFromNative(nativeAccessType)
+ if (path == null || accessType == null) {
+ return INVALID_DIR_ID
+ }
+
+ return when (accessType) {
+ ACCESS_RESOURCES -> assetsDirAccess.dirOpen(path)
+ ACCESS_FILESYSTEM -> fileSystemDirAccess.dirOpen(path)
+ }
+ }
+
+ fun dirNext(nativeAccessType: Int, dirId: Int): String {
+ val accessType = getAccessTypeFromNative(nativeAccessType)
+ if (accessType == null || !hasDirId(accessType, dirId)) {
+ Log.w(TAG, "dirNext: Invalid dir id: $dirId")
+ return ""
+ }
+
+ return when (accessType) {
+ ACCESS_RESOURCES -> assetsDirAccess.dirNext(dirId)
+ ACCESS_FILESYSTEM -> fileSystemDirAccess.dirNext(dirId)
+ }
+ }
+
+ fun dirClose(nativeAccessType: Int, dirId: Int) {
+ val accessType = getAccessTypeFromNative(nativeAccessType)
+ if (accessType == null || !hasDirId(accessType, dirId)) {
+ Log.w(TAG, "dirClose: Invalid dir id: $dirId")
+ return
+ }
+
+ when (accessType) {
+ ACCESS_RESOURCES -> assetsDirAccess.dirClose(dirId)
+ ACCESS_FILESYSTEM -> fileSystemDirAccess.dirClose(dirId)
+ }
+ }
+
+ fun dirIsDir(nativeAccessType: Int, dirId: Int): Boolean {
+ val accessType = getAccessTypeFromNative(nativeAccessType)
+ if (accessType == null || !hasDirId(accessType, dirId)) {
+ Log.w(TAG, "dirIsDir: Invalid dir id: $dirId")
+ return false
+ }
+
+ return when (accessType) {
+ ACCESS_RESOURCES -> assetsDirAccess.dirIsDir(dirId)
+ ACCESS_FILESYSTEM -> fileSystemDirAccess.dirIsDir(dirId)
+ }
+ }
+
+ fun isCurrentHidden(nativeAccessType: Int, dirId: Int): Boolean {
+ val accessType = getAccessTypeFromNative(nativeAccessType)
+ if (accessType == null || !hasDirId(accessType, dirId)) {
+ return false
+ }
+
+ return when (accessType) {
+ ACCESS_RESOURCES -> assetsDirAccess.isCurrentHidden(dirId)
+ ACCESS_FILESYSTEM -> fileSystemDirAccess.isCurrentHidden(dirId)
+ }
+ }
+
+ fun dirExists(nativeAccessType: Int, path: String?): Boolean {
+ val accessType = getAccessTypeFromNative(nativeAccessType)
+ if (path == null || accessType == null) {
+ return false
+ }
+
+ return when (accessType) {
+ ACCESS_RESOURCES -> assetsDirAccess.dirExists(path)
+ ACCESS_FILESYSTEM -> fileSystemDirAccess.dirExists(path)
+ }
+ }
+
+ fun fileExists(nativeAccessType: Int, path: String?): Boolean {
+ val accessType = getAccessTypeFromNative(nativeAccessType)
+ if (path == null || accessType == null) {
+ return false
+ }
+
+ return when (accessType) {
+ ACCESS_RESOURCES -> assetsDirAccess.fileExists(path)
+ ACCESS_FILESYSTEM -> fileSystemDirAccess.fileExists(path)
+ }
+ }
+
+ fun getDriveCount(nativeAccessType: Int): Int {
+ val accessType = getAccessTypeFromNative(nativeAccessType) ?: return 0
+ return when(accessType) {
+ ACCESS_RESOURCES -> assetsDirAccess.getDriveCount()
+ ACCESS_FILESYSTEM -> fileSystemDirAccess.getDriveCount()
+ }
+ }
+
+ fun getDrive(nativeAccessType: Int, drive: Int): String {
+ val accessType = getAccessTypeFromNative(nativeAccessType) ?: return ""
+ return when (accessType) {
+ ACCESS_RESOURCES -> assetsDirAccess.getDrive(drive)
+ ACCESS_FILESYSTEM -> fileSystemDirAccess.getDrive(drive)
+ }
+ }
+
+ fun makeDir(nativeAccessType: Int, dir: String): Boolean {
+ val accessType = getAccessTypeFromNative(nativeAccessType) ?: return false
+ return when (accessType) {
+ ACCESS_RESOURCES -> assetsDirAccess.makeDir(dir)
+ ACCESS_FILESYSTEM -> fileSystemDirAccess.makeDir(dir)
+ }
+ }
+
+ fun getSpaceLeft(nativeAccessType: Int): Long {
+ val accessType = getAccessTypeFromNative(nativeAccessType) ?: return 0L
+ return when (accessType) {
+ ACCESS_RESOURCES -> assetsDirAccess.getSpaceLeft()
+ ACCESS_FILESYSTEM -> fileSystemDirAccess.getSpaceLeft()
+ }
+ }
+
+ fun rename(nativeAccessType: Int, from: String, to: String): Boolean {
+ val accessType = getAccessTypeFromNative(nativeAccessType) ?: return false
+ return when (accessType) {
+ ACCESS_RESOURCES -> assetsDirAccess.rename(from, to)
+ ACCESS_FILESYSTEM -> fileSystemDirAccess.rename(from, to)
+ }
+ }
+
+ fun remove(nativeAccessType: Int, filename: String): Boolean {
+ val accessType = getAccessTypeFromNative(nativeAccessType) ?: return false
+ return when (accessType) {
+ ACCESS_RESOURCES -> assetsDirAccess.remove(filename)
+ ACCESS_FILESYSTEM -> fileSystemDirAccess.remove(filename)
+ }
+ }
+
+}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/io/directory/FilesystemDirectoryAccess.kt b/platform/android/java/lib/src/org/godotengine/godot/io/directory/FilesystemDirectoryAccess.kt
new file mode 100644
index 0000000000..54fc56fa3e
--- /dev/null
+++ b/platform/android/java/lib/src/org/godotengine/godot/io/directory/FilesystemDirectoryAccess.kt
@@ -0,0 +1,231 @@
+/*************************************************************************/
+/* FileSystemDirectoryAccess.kt */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 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.io.directory
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.os.Build
+import android.os.storage.StorageManager
+import android.util.Log
+import android.util.SparseArray
+import org.godotengine.godot.io.StorageScope
+import org.godotengine.godot.io.directory.DirectoryAccessHandler.Companion.INVALID_DIR_ID
+import org.godotengine.godot.io.directory.DirectoryAccessHandler.Companion.STARTING_DIR_ID
+import org.godotengine.godot.io.file.FileAccessHandler
+import java.io.File
+
+/**
+ * Handles directories access with the internal and external filesystem.
+ */
+internal class FilesystemDirectoryAccess(private val context: Context):
+ DirectoryAccessHandler.DirectoryAccess {
+
+ companion object {
+ private val TAG = FilesystemDirectoryAccess::class.java.simpleName
+ }
+
+ private data class DirData(val dirFile: File, val files: Array<File>, var current: Int = 0)
+
+ private val storageScopeIdentifier = StorageScope.Identifier(context)
+ private val storageManager = context.getSystemService(Context.STORAGE_SERVICE) as StorageManager
+ private var lastDirId = STARTING_DIR_ID
+ private val dirs = SparseArray<DirData>()
+
+ private fun inScope(path: String): Boolean {
+ // Directory access is available for shared storage on Android 11+
+ // On Android 10, access is also available as long as the `requestLegacyExternalStorage`
+ // tag is available.
+ return storageScopeIdentifier.identifyStorageScope(path) != StorageScope.UNKNOWN
+ }
+
+ override fun hasDirId(dirId: Int) = dirs.indexOfKey(dirId) >= 0
+
+ override fun dirOpen(path: String): Int {
+ if (!inScope(path)) {
+ Log.w(TAG, "Path $path is not accessible.")
+ return INVALID_DIR_ID
+ }
+
+ // Check this is a directory.
+ val dirFile = File(path)
+ if (!dirFile.isDirectory) {
+ return INVALID_DIR_ID
+ }
+
+ // Get the files in the directory
+ val files = dirFile.listFiles()?: return INVALID_DIR_ID
+
+ // Create the data representing this directory
+ val dirData = DirData(dirFile, files)
+
+ dirs.put(++lastDirId, dirData)
+ return lastDirId
+ }
+
+ override fun dirExists(path: String): Boolean {
+ if (!inScope(path)) {
+ Log.w(TAG, "Path $path is not accessible.")
+ return false
+ }
+
+ try {
+ return File(path).isDirectory
+ } catch (e: SecurityException) {
+ return false
+ }
+ }
+
+ override fun fileExists(path: String) = FileAccessHandler.fileExists(context, storageScopeIdentifier, path)
+
+ override fun dirNext(dirId: Int): String {
+ val dirData = dirs[dirId]
+ if (dirData.current >= dirData.files.size) {
+ dirData.current++
+ return ""
+ }
+
+ return dirData.files[dirData.current++].name
+ }
+
+ override fun dirClose(dirId: Int) {
+ dirs.remove(dirId)
+ }
+
+ override fun dirIsDir(dirId: Int): Boolean {
+ val dirData = dirs[dirId]
+
+ var index = dirData.current
+ if (index > 0) {
+ index--
+ }
+
+ if (index >= dirData.files.size) {
+ return false
+ }
+
+ return dirData.files[index].isDirectory
+ }
+
+ override fun isCurrentHidden(dirId: Int): Boolean {
+ val dirData = dirs[dirId]
+
+ var index = dirData.current
+ if (index > 0) {
+ index--
+ }
+
+ if (index >= dirData.files.size) {
+ return false
+ }
+
+ return dirData.files[index].isHidden
+ }
+
+ override fun getDriveCount(): Int {
+ return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ storageManager.storageVolumes.size
+ } else {
+ 0
+ }
+ }
+
+ override fun getDrive(drive: Int): String {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
+ return ""
+ }
+
+ if (drive < 0 || drive >= storageManager.storageVolumes.size) {
+ return ""
+ }
+
+ val storageVolume = storageManager.storageVolumes[drive]
+ return storageVolume.getDescription(context)
+ }
+
+ override fun makeDir(dir: String): Boolean {
+ if (!inScope(dir)) {
+ Log.w(TAG, "Directory $dir is not accessible.")
+ return false
+ }
+
+ try {
+ val dirFile = File(dir)
+ return dirFile.isDirectory || dirFile.mkdirs()
+ } catch (e: SecurityException) {
+ return false
+ }
+ }
+
+ @SuppressLint("UsableSpace")
+ override fun getSpaceLeft() = context.getExternalFilesDir(null)?.usableSpace ?: 0L
+
+ override fun rename(from: String, to: String): Boolean {
+ if (!inScope(from) || !inScope(to)) {
+ Log.w(TAG, "Argument filenames are not accessible:\n" +
+ "from: $from\n" +
+ "to: $to")
+ return false
+ }
+
+ return try {
+ val fromFile = File(from)
+ if (fromFile.isDirectory) {
+ fromFile.renameTo(File(to))
+ } else {
+ FileAccessHandler.renameFile(context, storageScopeIdentifier, from, to)
+ }
+ } catch (e: SecurityException) {
+ false
+ }
+ }
+
+ override fun remove(filename: String): Boolean {
+ if (!inScope(filename)) {
+ Log.w(TAG, "Filename $filename is not accessible.")
+ return false
+ }
+
+ return try {
+ val deleteFile = File(filename)
+ if (deleteFile.exists()) {
+ if (deleteFile.isDirectory) {
+ deleteFile.delete()
+ } else {
+ FileAccessHandler.removeFile(context, storageScopeIdentifier, filename)
+ }
+ } else {
+ true
+ }
+ } catch (e: SecurityException) {
+ false
+ }
+ }
+}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/io/file/DataAccess.kt b/platform/android/java/lib/src/org/godotengine/godot/io/file/DataAccess.kt
new file mode 100644
index 0000000000..463dabfb23
--- /dev/null
+++ b/platform/android/java/lib/src/org/godotengine/godot/io/file/DataAccess.kt
@@ -0,0 +1,187 @@
+/*************************************************************************/
+/* DataAccess.kt */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 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.io.file
+
+import android.content.Context
+import android.os.Build
+import android.util.Log
+import org.godotengine.godot.io.StorageScope
+import java.io.IOException
+import java.nio.ByteBuffer
+import java.nio.channels.FileChannel
+import kotlin.math.max
+
+/**
+ * Base class for file IO operations.
+ *
+ * Its derived instances provide concrete implementations to handle regular file access, as well
+ * as file access through the media store API on versions of Android were scoped storage is enabled.
+ */
+internal abstract class DataAccess(private val filePath: String) {
+
+ companion object {
+ private val TAG = DataAccess::class.java.simpleName
+
+ fun generateDataAccess(
+ storageScope: StorageScope,
+ context: Context,
+ filePath: String,
+ accessFlag: FileAccessFlags
+ ): DataAccess? {
+ return when (storageScope) {
+ StorageScope.APP -> FileData(filePath, accessFlag)
+
+ StorageScope.SHARED -> if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+ MediaStoreData(context, filePath, accessFlag)
+ } else {
+ null
+ }
+
+ StorageScope.UNKNOWN -> null
+ }
+ }
+
+ fun fileExists(storageScope: StorageScope, context: Context, path: String): Boolean {
+ return when(storageScope) {
+ StorageScope.APP -> FileData.fileExists(path)
+ StorageScope.SHARED -> MediaStoreData.fileExists(context, path)
+ StorageScope.UNKNOWN -> false
+ }
+ }
+
+ fun fileLastModified(storageScope: StorageScope, context: Context, path: String): Long {
+ return when(storageScope) {
+ StorageScope.APP -> FileData.fileLastModified(path)
+ StorageScope.SHARED -> MediaStoreData.fileLastModified(context, path)
+ StorageScope.UNKNOWN -> 0L
+ }
+ }
+
+ fun removeFile(storageScope: StorageScope, context: Context, path: String): Boolean {
+ return when(storageScope) {
+ StorageScope.APP -> FileData.delete(path)
+ StorageScope.SHARED -> MediaStoreData.delete(context, path)
+ StorageScope.UNKNOWN -> false
+ }
+ }
+
+ fun renameFile(storageScope: StorageScope, context: Context, from: String, to: String): Boolean {
+ return when(storageScope) {
+ StorageScope.APP -> FileData.rename(from, to)
+ StorageScope.SHARED -> MediaStoreData.rename(context, from, to)
+ StorageScope.UNKNOWN -> false
+ }
+ }
+ }
+
+ protected abstract val fileChannel: FileChannel
+ internal var endOfFile = false
+ private set
+
+ fun close() {
+ try {
+ fileChannel.close()
+ } catch (e: IOException) {
+ Log.w(TAG, "Exception when closing file $filePath.", e)
+ }
+ }
+
+ fun flush() {
+ try {
+ fileChannel.force(false)
+ } catch (e: IOException) {
+ Log.w(TAG, "Exception when flushing file $filePath.", e)
+ }
+ }
+
+ fun seek(position: Long) {
+ try {
+ fileChannel.position(position)
+ if (position <= size()) {
+ endOfFile = false
+ }
+ } catch (e: Exception) {
+ Log.w(TAG, "Exception when seeking file $filePath.", e)
+ }
+ }
+
+ fun seekFromEnd(positionFromEnd: Long) {
+ val positionFromBeginning = max(0, size() - positionFromEnd)
+ seek(positionFromBeginning)
+ }
+
+ fun position(): Long {
+ return try {
+ fileChannel.position()
+ } catch (e: IOException) {
+ Log.w(
+ TAG,
+ "Exception when retrieving position for file $filePath.",
+ e
+ )
+ 0L
+ }
+ }
+
+ fun size() = try {
+ fileChannel.size()
+ } catch (e: IOException) {
+ Log.w(TAG, "Exception when retrieving size for file $filePath.", e)
+ 0L
+ }
+
+ fun read(buffer: ByteBuffer): Int {
+ return try {
+ val readBytes = fileChannel.read(buffer)
+ endOfFile = readBytes == -1
+ || (fileChannel.position() >= fileChannel.size() && fileChannel.size() > 0)
+ if (readBytes == -1) {
+ 0
+ } else {
+ readBytes
+ }
+ } catch (e: IOException) {
+ Log.w(TAG, "Exception while reading from file $filePath.", e)
+ 0
+ }
+ }
+
+ fun write(buffer: ByteBuffer) {
+ try {
+ val writtenBytes = fileChannel.write(buffer)
+ if (writtenBytes > 0) {
+ endOfFile = false
+ }
+ } catch (e: IOException) {
+ Log.w(TAG, "Exception while writing to file $filePath.", e)
+ }
+ }
+}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/io/file/FileAccessFlags.kt b/platform/android/java/lib/src/org/godotengine/godot/io/file/FileAccessFlags.kt
new file mode 100644
index 0000000000..c6b242a4b6
--- /dev/null
+++ b/platform/android/java/lib/src/org/godotengine/godot/io/file/FileAccessFlags.kt
@@ -0,0 +1,87 @@
+/*************************************************************************/
+/* FileAccessFlags.kt */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 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.io.file
+
+/**
+ * Android representation of Godot native access flags.
+ */
+internal enum class FileAccessFlags(val nativeValue: Int) {
+ /**
+ * Opens the file for read operations.
+ * The cursor is positioned at the beginning of the file.
+ */
+ READ(1),
+
+ /**
+ * Opens the file for write operations.
+ * The file is created if it does not exist, and truncated if it does.
+ */
+ WRITE(2),
+
+ /**
+ * Opens the file for read and write operations.
+ * Does not truncate the file. The cursor is positioned at the beginning of the file.
+ */
+ READ_WRITE(3),
+
+ /**
+ * Opens the file for read and write operations.
+ * The file is created if it does not exist, and truncated if it does.
+ * The cursor is positioned at the beginning of the file.
+ */
+ WRITE_READ(7);
+
+ fun getMode(): String {
+ return when (this) {
+ READ -> "r"
+ WRITE -> "w"
+ READ_WRITE, WRITE_READ -> "rw"
+ }
+ }
+
+ fun shouldTruncate(): Boolean {
+ return when (this) {
+ READ, READ_WRITE -> false
+ WRITE, WRITE_READ -> true
+ }
+ }
+
+ companion object {
+ fun fromNativeModeFlags(modeFlag: Int): FileAccessFlags? {
+ for (flag in values()) {
+ if (flag.nativeValue == modeFlag) {
+ return flag
+ }
+ }
+ return null
+ }
+ }
+}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/io/file/FileAccessHandler.kt b/platform/android/java/lib/src/org/godotengine/godot/io/file/FileAccessHandler.kt
new file mode 100644
index 0000000000..04b6772c45
--- /dev/null
+++ b/platform/android/java/lib/src/org/godotengine/godot/io/file/FileAccessHandler.kt
@@ -0,0 +1,203 @@
+/*************************************************************************/
+/* FileAccessHandler.kt */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 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.io.file
+
+import android.content.Context
+import android.util.Log
+import android.util.SparseArray
+import org.godotengine.godot.io.StorageScope
+import java.io.FileNotFoundException
+import java.nio.ByteBuffer
+
+/**
+ * Handles regular and media store file access and interactions.
+ */
+class FileAccessHandler(val context: Context) {
+
+ companion object {
+ private val TAG = FileAccessHandler::class.java.simpleName
+
+ private const val FILE_NOT_FOUND_ERROR_ID = -1
+ private const val INVALID_FILE_ID = 0
+ private const val STARTING_FILE_ID = 1
+
+ internal fun fileExists(context: Context, storageScopeIdentifier: StorageScope.Identifier, path: String?): Boolean {
+ val storageScope = storageScopeIdentifier.identifyStorageScope(path)
+ if (storageScope == StorageScope.UNKNOWN) {
+ return false
+ }
+
+ return try {
+ DataAccess.fileExists(storageScope, context, path!!)
+ } catch (e: SecurityException) {
+ false
+ }
+ }
+
+ internal fun removeFile(context: Context, storageScopeIdentifier: StorageScope.Identifier, path: String?): Boolean {
+ val storageScope = storageScopeIdentifier.identifyStorageScope(path)
+ if (storageScope == StorageScope.UNKNOWN) {
+ return false
+ }
+
+ return try {
+ DataAccess.removeFile(storageScope, context, path!!)
+ } catch (e: Exception) {
+ false
+ }
+ }
+
+ internal fun renameFile(context: Context, storageScopeIdentifier: StorageScope.Identifier, from: String?, to: String?): Boolean {
+ val storageScope = storageScopeIdentifier.identifyStorageScope(from)
+ if (storageScope == StorageScope.UNKNOWN) {
+ return false
+ }
+
+ return try {
+ DataAccess.renameFile(storageScope, context, from!!, to!!)
+ } catch (e: Exception) {
+ false
+ }
+ }
+ }
+
+ private val storageScopeIdentifier = StorageScope.Identifier(context)
+ private val files = SparseArray<DataAccess>()
+ private var lastFileId = STARTING_FILE_ID
+
+ private fun hasFileId(fileId: Int) = files.indexOfKey(fileId) >= 0
+
+ fun fileOpen(path: String?, modeFlags: Int): Int {
+ val storageScope = storageScopeIdentifier.identifyStorageScope(path)
+ if (storageScope == StorageScope.UNKNOWN) {
+ return INVALID_FILE_ID
+ }
+
+ try {
+ val accessFlag = FileAccessFlags.fromNativeModeFlags(modeFlags) ?: return INVALID_FILE_ID
+ val dataAccess = DataAccess.generateDataAccess(storageScope, context, path!!, accessFlag) ?: return INVALID_FILE_ID
+
+ files.put(++lastFileId, dataAccess)
+ return lastFileId
+ } catch (e: FileNotFoundException) {
+ return FILE_NOT_FOUND_ERROR_ID
+ } catch (e: Exception) {
+ Log.w(TAG, "Error while opening $path", e)
+ return INVALID_FILE_ID
+ }
+ }
+
+ fun fileGetSize(fileId: Int): Long {
+ if (!hasFileId(fileId)) {
+ return 0L
+ }
+
+ return files[fileId].size()
+ }
+
+ fun fileSeek(fileId: Int, position: Long) {
+ if (!hasFileId(fileId)) {
+ return
+ }
+
+ files[fileId].seek(position)
+ }
+
+ fun fileSeekFromEnd(fileId: Int, position: Long) {
+ if (!hasFileId(fileId)) {
+ return
+ }
+
+ files[fileId].seekFromEnd(position)
+ }
+
+ fun fileRead(fileId: Int, byteBuffer: ByteBuffer?): Int {
+ if (!hasFileId(fileId) || byteBuffer == null) {
+ return 0
+ }
+
+ return files[fileId].read(byteBuffer)
+ }
+
+ fun fileWrite(fileId: Int, byteBuffer: ByteBuffer?) {
+ if (!hasFileId(fileId) || byteBuffer == null) {
+ return
+ }
+
+ files[fileId].write(byteBuffer)
+ }
+
+ fun fileFlush(fileId: Int) {
+ if (!hasFileId(fileId)) {
+ return
+ }
+
+ files[fileId].flush()
+ }
+
+ fun fileExists(path: String?) = Companion.fileExists(context, storageScopeIdentifier, path)
+
+ fun fileLastModified(filepath: String?): Long {
+ val storageScope = storageScopeIdentifier.identifyStorageScope(filepath)
+ if (storageScope == StorageScope.UNKNOWN) {
+ return 0L
+ }
+
+ return try {
+ DataAccess.fileLastModified(storageScope, context, filepath!!)
+ } catch (e: SecurityException) {
+ 0L
+ }
+ }
+
+ fun fileGetPosition(fileId: Int): Long {
+ if (!hasFileId(fileId)) {
+ return 0L
+ }
+
+ return files[fileId].position()
+ }
+
+ fun isFileEof(fileId: Int): Boolean {
+ if (!hasFileId(fileId)) {
+ return false
+ }
+
+ return files[fileId].endOfFile
+ }
+
+ fun fileClose(fileId: Int) {
+ if (hasFileId(fileId)) {
+ files[fileId].close()
+ files.remove(fileId)
+ }
+ }
+}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/io/file/FileData.kt b/platform/android/java/lib/src/org/godotengine/godot/io/file/FileData.kt
new file mode 100644
index 0000000000..5af694ad99
--- /dev/null
+++ b/platform/android/java/lib/src/org/godotengine/godot/io/file/FileData.kt
@@ -0,0 +1,93 @@
+/*************************************************************************/
+/* FileData.kt */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 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.io.file
+
+import java.io.File
+import java.io.FileOutputStream
+import java.io.RandomAccessFile
+import java.nio.channels.FileChannel
+
+/**
+ * Implementation of [DataAccess] which handles regular (not scoped) file access and interactions.
+ */
+internal class FileData(filePath: String, accessFlag: FileAccessFlags) : DataAccess(filePath) {
+
+ companion object {
+ private val TAG = FileData::class.java.simpleName
+
+ fun fileExists(path: String): Boolean {
+ return try {
+ File(path).isFile
+ } catch (e: SecurityException) {
+ false
+ }
+ }
+
+ fun fileLastModified(filepath: String): Long {
+ return try {
+ File(filepath).lastModified()
+ } catch (e: SecurityException) {
+ 0L
+ }
+ }
+
+ fun delete(filepath: String): Boolean {
+ return try {
+ File(filepath).delete()
+ } catch (e: Exception) {
+ false
+ }
+ }
+
+ fun rename(from: String, to: String): Boolean {
+ return try {
+ val fromFile = File(from)
+ fromFile.renameTo(File(to))
+ } catch (e: Exception) {
+ false
+ }
+ }
+ }
+
+ override val fileChannel: FileChannel
+
+ init {
+ if (accessFlag == FileAccessFlags.WRITE) {
+ fileChannel = FileOutputStream(filePath, !accessFlag.shouldTruncate()).channel
+ } else {
+ fileChannel = RandomAccessFile(filePath, accessFlag.getMode()).channel
+ }
+
+ if (accessFlag.shouldTruncate()) {
+ fileChannel.truncate(0)
+ }
+ }
+}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/io/file/MediaStoreData.kt b/platform/android/java/lib/src/org/godotengine/godot/io/file/MediaStoreData.kt
new file mode 100644
index 0000000000..81a7dd1705
--- /dev/null
+++ b/platform/android/java/lib/src/org/godotengine/godot/io/file/MediaStoreData.kt
@@ -0,0 +1,284 @@
+/*************************************************************************/
+/* MediaStoreData.kt */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 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.io.file
+
+import android.content.ContentUris
+import android.content.ContentValues
+import android.content.Context
+import android.database.Cursor
+import android.net.Uri
+import android.os.Build
+import android.os.Environment
+import android.provider.MediaStore
+import androidx.annotation.RequiresApi
+
+import java.io.File
+import java.io.FileInputStream
+import java.io.FileNotFoundException
+import java.io.FileOutputStream
+import java.nio.channels.FileChannel
+
+/**
+ * Implementation of [DataAccess] which handles access and interactions with file and data
+ * under scoped storage via the MediaStore API.
+ */
+@RequiresApi(Build.VERSION_CODES.Q)
+internal class MediaStoreData(context: Context, filePath: String, accessFlag: FileAccessFlags) :
+ DataAccess(filePath) {
+
+ private data class DataItem(
+ val id: Long,
+ val uri: Uri,
+ val displayName: String,
+ val relativePath: String,
+ val size: Int,
+ val dateModified: Int,
+ val mediaType: Int
+ )
+
+ companion object {
+ private val TAG = MediaStoreData::class.java.simpleName
+
+ private val COLLECTION = MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
+
+ private val PROJECTION = arrayOf(
+ MediaStore.Files.FileColumns._ID,
+ MediaStore.Files.FileColumns.DISPLAY_NAME,
+ MediaStore.Files.FileColumns.RELATIVE_PATH,
+ MediaStore.Files.FileColumns.SIZE,
+ MediaStore.Files.FileColumns.DATE_MODIFIED,
+ MediaStore.Files.FileColumns.MEDIA_TYPE,
+ )
+
+ private const val SELECTION_BY_PATH = "${MediaStore.Files.FileColumns.DISPLAY_NAME} = ? " +
+ " AND ${MediaStore.Files.FileColumns.RELATIVE_PATH} = ?"
+
+ private fun getSelectionByPathArguments(path: String): Array<String> {
+ return arrayOf(getMediaStoreDisplayName(path), getMediaStoreRelativePath(path))
+ }
+
+ private const val SELECTION_BY_ID = "${MediaStore.Files.FileColumns._ID} = ? "
+
+ private fun getSelectionByIdArgument(id: Long) = arrayOf(id.toString())
+
+ private fun getMediaStoreDisplayName(path: String) = File(path).name
+
+ private fun getMediaStoreRelativePath(path: String): String {
+ val pathFile = File(path)
+ val environmentDir = Environment.getExternalStorageDirectory()
+ var relativePath = (pathFile.parent?.replace(environmentDir.absolutePath, "") ?: "").trim('/')
+ if (relativePath.isNotBlank()) {
+ relativePath += "/"
+ }
+ return relativePath
+ }
+
+ private fun queryById(context: Context, id: Long): List<DataItem> {
+ val query = context.contentResolver.query(
+ COLLECTION,
+ PROJECTION,
+ SELECTION_BY_ID,
+ getSelectionByIdArgument(id),
+ null
+ )
+ return dataItemFromCursor(query)
+ }
+
+ private fun queryByPath(context: Context, path: String): List<DataItem> {
+ val query = context.contentResolver.query(
+ COLLECTION,
+ PROJECTION,
+ SELECTION_BY_PATH,
+ getSelectionByPathArguments(path),
+ null
+ )
+ return dataItemFromCursor(query)
+ }
+
+ private fun dataItemFromCursor(query: Cursor?): List<DataItem> {
+ query?.use { cursor ->
+ cursor.count
+ if (cursor.count == 0) {
+ return emptyList()
+ }
+ val idColumn = cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns._ID)
+ val displayNameColumn =
+ cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DISPLAY_NAME)
+ val relativePathColumn =
+ cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.RELATIVE_PATH)
+ val sizeColumn = cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.SIZE)
+ val dateModifiedColumn =
+ cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DATE_MODIFIED)
+ val mediaTypeColumn = cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.MEDIA_TYPE)
+
+ val result = ArrayList<DataItem>()
+ while (cursor.moveToNext()) {
+ val id = cursor.getLong(idColumn)
+ result.add(
+ DataItem(
+ id,
+ ContentUris.withAppendedId(COLLECTION, id),
+ cursor.getString(displayNameColumn),
+ cursor.getString(relativePathColumn),
+ cursor.getInt(sizeColumn),
+ cursor.getInt(dateModifiedColumn),
+ cursor.getInt(mediaTypeColumn)
+ )
+ )
+ }
+ return result
+ }
+ return emptyList()
+ }
+
+ private fun addFile(context: Context, path: String): DataItem? {
+ val fileDetails = ContentValues().apply {
+ put(MediaStore.Files.FileColumns._ID, 0)
+ put(MediaStore.Files.FileColumns.DISPLAY_NAME, getMediaStoreDisplayName(path))
+ put(MediaStore.Files.FileColumns.RELATIVE_PATH, getMediaStoreRelativePath(path))
+ }
+
+ context.contentResolver.insert(COLLECTION, fileDetails) ?: return null
+
+ // File was successfully added, let's retrieve its info
+ val infos = queryByPath(context, path)
+ if (infos.isEmpty()) {
+ return null
+ }
+
+ return infos[0]
+ }
+
+ fun delete(context: Context, path: String): Boolean {
+ val itemsToDelete = queryByPath(context, path)
+ if (itemsToDelete.isEmpty()) {
+ return false
+ }
+
+ val resolver = context.contentResolver
+ var itemsDeleted = 0
+ for (item in itemsToDelete) {
+ itemsDeleted += resolver.delete(item.uri, null, null)
+ }
+
+ return itemsDeleted > 0
+ }
+
+ fun fileExists(context: Context, path: String): Boolean {
+ return queryByPath(context, path).isNotEmpty()
+ }
+
+ fun fileLastModified(context: Context, path: String): Long {
+ val result = queryByPath(context, path)
+ if (result.isEmpty()) {
+ return 0L
+ }
+
+ val dataItem = result[0]
+ return dataItem.dateModified.toLong()
+ }
+
+ fun rename(context: Context, from: String, to: String): Boolean {
+ // Ensure the source exists.
+ val sources = queryByPath(context, from)
+ if (sources.isEmpty()) {
+ return false
+ }
+
+ // Take the first source
+ val source = sources[0]
+
+ // Set up the updated values
+ val updatedDetails = ContentValues().apply {
+ put(MediaStore.Files.FileColumns.DISPLAY_NAME, getMediaStoreDisplayName(to))
+ put(MediaStore.Files.FileColumns.RELATIVE_PATH, getMediaStoreRelativePath(to))
+ }
+
+ val updated = context.contentResolver.update(
+ source.uri,
+ updatedDetails,
+ SELECTION_BY_ID,
+ getSelectionByIdArgument(source.id)
+ )
+ return updated > 0
+ }
+ }
+
+ private val id: Long
+ private val uri: Uri
+ override val fileChannel: FileChannel
+
+ init {
+ val contentResolver = context.contentResolver
+ val dataItems = queryByPath(context, filePath)
+
+ val dataItem = when (accessFlag) {
+ FileAccessFlags.READ -> {
+ // The file should already exist
+ if (dataItems.isEmpty()) {
+ throw FileNotFoundException("Unable to access file $filePath")
+ }
+
+ val dataItem = dataItems[0]
+ dataItem
+ }
+
+ FileAccessFlags.WRITE, FileAccessFlags.READ_WRITE, FileAccessFlags.WRITE_READ -> {
+ // Create the file if it doesn't exist
+ val dataItem = if (dataItems.isEmpty()) {
+ addFile(context, filePath)
+ } else {
+ dataItems[0]
+ }
+
+ if (dataItem == null) {
+ throw FileNotFoundException("Unable to access file $filePath")
+ }
+ dataItem
+ }
+ }
+
+ id = dataItem.id
+ uri = dataItem.uri
+
+ val parcelFileDescriptor = contentResolver.openFileDescriptor(uri, accessFlag.getMode())
+ ?: throw IllegalStateException("Unable to access file descriptor")
+ fileChannel = if (accessFlag == FileAccessFlags.READ) {
+ FileInputStream(parcelFileDescriptor.fileDescriptor).channel
+ } else {
+ FileOutputStream(parcelFileDescriptor.fileDescriptor).channel
+ }
+
+ if (accessFlag.shouldTruncate()) {
+ fileChannel.truncate(0)
+ }
+ }
+}
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 e5b4f41153..57db0709f0 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
@@ -32,10 +32,14 @@ package org.godotengine.godot.utils;
import android.Manifest;
import android.app.Activity;
+import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PermissionInfo;
+import android.net.Uri;
import android.os.Build;
+import android.os.Environment;
+import android.provider.Settings;
import android.util.Log;
import androidx.core.content.ContextCompat;
@@ -53,7 +57,8 @@ public final class PermissionsUtil {
static final int REQUEST_RECORD_AUDIO_PERMISSION = 1;
static final int REQUEST_CAMERA_PERMISSION = 2;
static final int REQUEST_VIBRATE_PERMISSION = 3;
- static final int REQUEST_ALL_PERMISSION_REQ_CODE = 1001;
+ public static final int REQUEST_ALL_PERMISSION_REQ_CODE = 1001;
+ public static final int REQUEST_MANAGE_EXTERNAL_STORAGE_REQ_CODE = 2002;
private PermissionsUtil() {
}
@@ -108,13 +113,26 @@ public final class PermissionsUtil {
if (manifestPermissions.length == 0)
return true;
- List<String> dangerousPermissions = new ArrayList<>();
+ List<String> requestedPermissions = new ArrayList<>();
for (String manifestPermission : manifestPermissions) {
try {
- PermissionInfo permissionInfo = getPermissionInfo(activity, manifestPermission);
- int protectionLevel = Build.VERSION.SDK_INT >= Build.VERSION_CODES.P ? permissionInfo.getProtection() : permissionInfo.protectionLevel;
- if (protectionLevel == PermissionInfo.PROTECTION_DANGEROUS && ContextCompat.checkSelfPermission(activity, manifestPermission) != PackageManager.PERMISSION_GRANTED) {
- dangerousPermissions.add(manifestPermission);
+ if (manifestPermission.equals(Manifest.permission.MANAGE_EXTERNAL_STORAGE)) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && !Environment.isExternalStorageManager()) {
+ try {
+ Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
+ intent.setData(Uri.parse(String.format("package:%s", activity.getPackageName())));
+ activity.startActivityForResult(intent, REQUEST_MANAGE_EXTERNAL_STORAGE_REQ_CODE);
+ } catch (Exception ignored) {
+ Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
+ activity.startActivityForResult(intent, REQUEST_MANAGE_EXTERNAL_STORAGE_REQ_CODE);
+ }
+ }
+ } else {
+ PermissionInfo permissionInfo = getPermissionInfo(activity, manifestPermission);
+ int protectionLevel = Build.VERSION.SDK_INT >= Build.VERSION_CODES.P ? permissionInfo.getProtection() : permissionInfo.protectionLevel;
+ if (protectionLevel == PermissionInfo.PROTECTION_DANGEROUS && ContextCompat.checkSelfPermission(activity, manifestPermission) != PackageManager.PERMISSION_GRANTED) {
+ requestedPermissions.add(manifestPermission);
+ }
}
} catch (PackageManager.NameNotFoundException e) {
// Skip this permission and continue.
@@ -122,13 +140,12 @@ public final class PermissionsUtil {
}
}
- if (dangerousPermissions.isEmpty()) {
+ if (requestedPermissions.isEmpty()) {
// If list is empty, all of dangerous permissions were granted.
return true;
}
- String[] requestedPermissions = dangerousPermissions.toArray(new String[0]);
- activity.requestPermissions(requestedPermissions, REQUEST_ALL_PERMISSION_REQ_CODE);
+ activity.requestPermissions(requestedPermissions.toArray(new String[0]), REQUEST_ALL_PERMISSION_REQ_CODE);
return false;
}
@@ -148,13 +165,19 @@ public final class PermissionsUtil {
if (manifestPermissions.length == 0)
return manifestPermissions;
- List<String> dangerousPermissions = new ArrayList<>();
+ List<String> grantedPermissions = new ArrayList<>();
for (String manifestPermission : manifestPermissions) {
try {
- PermissionInfo permissionInfo = getPermissionInfo(activity, manifestPermission);
- int protectionLevel = Build.VERSION.SDK_INT >= Build.VERSION_CODES.P ? permissionInfo.getProtection() : permissionInfo.protectionLevel;
- if (protectionLevel == PermissionInfo.PROTECTION_DANGEROUS && ContextCompat.checkSelfPermission(activity, manifestPermission) == PackageManager.PERMISSION_GRANTED) {
- dangerousPermissions.add(manifestPermission);
+ if (manifestPermission.equals(Manifest.permission.MANAGE_EXTERNAL_STORAGE)) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && Environment.isExternalStorageManager()) {
+ grantedPermissions.add(manifestPermission);
+ }
+ } else {
+ PermissionInfo permissionInfo = getPermissionInfo(activity, manifestPermission);
+ int protectionLevel = Build.VERSION.SDK_INT >= Build.VERSION_CODES.P ? permissionInfo.getProtection() : permissionInfo.protectionLevel;
+ if (protectionLevel == PermissionInfo.PROTECTION_DANGEROUS && ContextCompat.checkSelfPermission(activity, manifestPermission) == PackageManager.PERMISSION_GRANTED) {
+ grantedPermissions.add(manifestPermission);
+ }
}
} catch (PackageManager.NameNotFoundException e) {
// Skip this permission and continue.
@@ -162,7 +185,7 @@ public final class PermissionsUtil {
}
}
- return dangerousPermissions.toArray(new String[0]);
+ return grantedPermissions.toArray(new String[0]);
}
/**
@@ -177,7 +200,7 @@ public final class PermissionsUtil {
if (permission.equals(p))
return true;
}
- } catch (PackageManager.NameNotFoundException e) {
+ } catch (PackageManager.NameNotFoundException ignored) {
}
return false;
diff --git a/platform/android/java_godot_lib_jni.cpp b/platform/android/java_godot_lib_jni.cpp
index de666f1b11..f4de4acfad 100644
--- a/platform/android/java_godot_lib_jni.cpp
+++ b/platform/android/java_godot_lib_jni.cpp
@@ -43,6 +43,7 @@
#include "dir_access_jandroid.h"
#include "display_server_android.h"
#include "file_access_android.h"
+#include "file_access_filesystem_jandroid.h"
#include "jni_utils.h"
#include "main/main.h"
#include "net_socket_android.h"
@@ -78,13 +79,13 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setVirtualKeyboardHei
}
}
-JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jclass clazz, jobject activity, jobject godot_instance, jobject p_asset_manager, jboolean p_use_apk_expansion) {
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jclass clazz, jobject p_activity, jobject p_godot_instance, jobject p_asset_manager, jobject p_godot_io, jobject p_net_utils, jobject p_directory_access_handler, jobject p_file_access_handler, jboolean p_use_apk_expansion, jobject p_godot_tts) {
JavaVM *jvm;
env->GetJavaVM(&jvm);
// create our wrapper classes
- 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));
+ godot_java = new GodotJavaWrapper(env, p_activity, p_godot_instance);
+ godot_io_java = new GodotIOJavaWrapper(env, p_godot_io);
init_thread_jandroid(jvm, env);
@@ -92,9 +93,10 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *en
FileAccessAndroid::asset_manager = AAssetManager_fromJava(env, amgr);
- DirAccessJAndroid::setup(godot_io_java->get_instance());
- NetSocketAndroid::setup(godot_java->get_member_object("netUtils", "Lorg/godotengine/godot/utils/GodotNetUtils;", env));
- TTS_Android::setup(godot_java->get_member_object("tts", "Lorg/godotengine/godot/tts/GodotTTS;", env));
+ DirAccessJAndroid::setup(p_directory_access_handler);
+ FileAccessFilesystemJAndroid::setup(p_file_access_handler);
+ NetSocketAndroid::setup(p_net_utils);
+ TTS_Android::setup(p_godot_tts);
os_android = new OS_Android(godot_java, godot_io_java, p_use_apk_expansion);
@@ -157,6 +159,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jc
memfree(cmdline);
}
+ // Note: --help and --version return ERR_HELP, but this should be translated to 0 if exit codes are propagated.
if (err != OK) {
return; // should exit instead and print the error
}
@@ -306,15 +309,6 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_doubleTap(JNIEnv *env
}
// Called on the UI thread
-JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_scroll(JNIEnv *env, jclass clazz, jint p_x, jint p_y) {
- if (step.get() <= 0) {
- return;
- }
-
- input_handler->process_scroll(Point2(p_x, p_y));
-}
-
-// Called on the UI thread
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joybutton(JNIEnv *env, jclass clazz, jint p_device, jint p_button, jboolean p_pressed) {
if (step.get() <= 0) {
return;
diff --git a/platform/android/java_godot_lib_jni.h b/platform/android/java_godot_lib_jni.h
index e1d30eea77..de16f197b8 100644
--- a/platform/android/java_godot_lib_jni.h
+++ b/platform/android/java_godot_lib_jni.h
@@ -37,7 +37,7 @@
// These functions can be called from within JAVA and are the means by which our JAVA implementation calls back into our C++ code.
// See java/src/org/godotengine/godot/GodotLib.java for the JAVA side of this (yes that's why we have the long names)
extern "C" {
-JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jclass clazz, jobject activity, jobject godot_instance, jobject p_asset_manager, jboolean p_use_apk_expansion);
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jclass clazz, jobject p_activity, jobject p_godot_instance, jobject p_asset_manager, jobject p_godot_io, jobject p_net_utils, jobject p_directory_access_handler, jobject p_file_access_handler, jboolean p_use_apk_expansion, jobject p_godot_tts);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ondestroy(JNIEnv *env, jclass clazz);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jclass clazz, jobjectArray p_cmdline);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, jclass clazz, jobject p_surface, jint p_width, jint p_height);
@@ -51,7 +51,6 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch__IIII_3FI(JNIEn
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch__IIII_3FIFF(JNIEnv *env, jclass clazz, jint input_device, jint ev, jint pointer, jint pointer_count, jfloatArray positions, jint buttons_mask, jfloat vertical_factor, jfloat horizontal_factor);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_hover(JNIEnv *env, jclass clazz, jint p_type, jfloat p_x, jfloat p_y);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_doubleTap(JNIEnv *env, jclass clazz, jint p_button_mask, jint p_x, jint p_y);
-JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_scroll(JNIEnv *env, jclass clazz, jint p_x, jint p_y);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jclass clazz, jint p_keycode, jint p_scancode, jint p_unicode_char, jboolean p_pressed);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joybutton(JNIEnv *env, jclass clazz, jint p_device, jint p_button, jboolean p_pressed);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyaxis(JNIEnv *env, jclass clazz, jint p_device, jint p_axis, jfloat p_value);
diff --git a/platform/android/java_godot_view_wrapper.h b/platform/android/java_godot_view_wrapper.h
index b1f258bbb5..c52f459d64 100644
--- a/platform/android/java_godot_view_wrapper.h
+++ b/platform/android/java_godot_view_wrapper.h
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef GODOT_JAVA_GODOT_VIEW_WRAPPER_H
-#define GODOT_JAVA_GODOT_VIEW_WRAPPER_H
+#ifndef JAVA_GODOT_VIEW_WRAPPER_H
+#define JAVA_GODOT_VIEW_WRAPPER_H
#include <android/log.h>
#include <jni.h>
@@ -57,4 +57,4 @@ public:
~GodotJavaViewWrapper();
};
-#endif // GODOT_JAVA_GODOT_VIEW_WRAPPER_H
+#endif // JAVA_GODOT_VIEW_WRAPPER_H
diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp
index 6674428de8..0f551e7f4f 100644
--- a/platform/android/os_android.cpp
+++ b/platform/android/os_android.cpp
@@ -40,6 +40,7 @@
#include "dir_access_jandroid.h"
#include "file_access_android.h"
+#include "file_access_filesystem_jandroid.h"
#include "net_socket_android.h"
#include <dlfcn.h>
@@ -93,7 +94,7 @@ void OS_Android::initialize_core() {
}
#endif
FileAccess::make_default<FileAccessUnix>(FileAccess::ACCESS_USERDATA);
- FileAccess::make_default<FileAccessUnix>(FileAccess::ACCESS_FILESYSTEM);
+ FileAccess::make_default<FileAccessFilesystemJAndroid>(FileAccess::ACCESS_FILESYSTEM);
#ifdef TOOLS_ENABLED
DirAccess::make_default<DirAccessUnix>(DirAccess::ACCESS_RESOURCES);
@@ -105,7 +106,7 @@ void OS_Android::initialize_core() {
}
#endif
DirAccess::make_default<DirAccessUnix>(DirAccess::ACCESS_USERDATA);
- DirAccess::make_default<DirAccessUnix>(DirAccess::ACCESS_FILESYSTEM);
+ DirAccess::make_default<DirAccessJAndroid>(DirAccess::ACCESS_FILESYSTEM);
NetSocketAndroid::make_default();
}
@@ -300,6 +301,33 @@ String OS_Android::get_system_dir(SystemDir p_dir, bool p_shared_storage) const
return godot_io_java->get_system_dir(p_dir, p_shared_storage);
}
+Error OS_Android::move_to_trash(const String &p_path) {
+ Ref<DirAccess> da_ref = DirAccess::create_for_path(p_path);
+ if (da_ref.is_null()) {
+ return FAILED;
+ }
+
+ // Check if it's a directory
+ if (da_ref->dir_exists(p_path)) {
+ Error err = da_ref->change_dir(p_path);
+ if (err) {
+ return err;
+ }
+ // This is directory, let's erase its contents
+ err = da_ref->erase_contents_recursive();
+ if (err) {
+ return err;
+ }
+ // Remove the top directory
+ return da_ref->remove(p_path);
+ } else if (da_ref->file_exists(p_path)) {
+ // This is a file, let's remove it.
+ return da_ref->remove(p_path);
+ } else {
+ return FAILED;
+ }
+}
+
void OS_Android::set_display_size(const Size2i &p_size) {
display_size = p_size;
}
diff --git a/platform/android/os_android.h b/platform/android/os_android.h
index 3f607eac48..96c06d715c 100644
--- a/platform/android/os_android.h
+++ b/platform/android/os_android.h
@@ -122,6 +122,8 @@ public:
virtual String get_system_dir(SystemDir p_dir, bool p_shared_storage = true) const override;
+ virtual Error move_to_trash(const String &p_path) override;
+
void vibrate_handheld(int p_duration_ms) override;
virtual String get_config_path() const override;
diff --git a/platform/iphone/SCsub b/platform/ios/SCsub
index 5e10bf5646..bf12ab6dd7 100644
--- a/platform/iphone/SCsub
+++ b/platform/ios/SCsub
@@ -2,16 +2,16 @@
Import("env")
-iphone_lib = [
- "godot_iphone.mm",
- "os_iphone.mm",
+ios_lib = [
+ "godot_ios.mm",
+ "os_ios.mm",
"main.m",
"app_delegate.mm",
"view_controller.mm",
"ios.mm",
- "vulkan_context_iphone.mm",
- "display_server_iphone.mm",
- "joypad_iphone.mm",
+ "vulkan_context_ios.mm",
+ "display_server_ios.mm",
+ "joypad_ios.mm",
"godot_view.mm",
"tts_ios.mm",
"display_layer.mm",
@@ -23,7 +23,7 @@ iphone_lib = [
]
env_ios = env.Clone()
-ios_lib = env_ios.add_library("iphone", iphone_lib)
+ios_lib = env_ios.add_library("ios", ios_lib)
# (iOS) Enable module support
env_ios.Append(CCFLAGS=["-fmodules", "-fcxx-modules"])
@@ -32,9 +32,9 @@ env_ios.Append(CCFLAGS=["-fmodules", "-fcxx-modules"])
def combine_libs(target=None, source=None, env=None):
lib_path = target[0].srcnode().abspath
if "osxcross" in env:
- libtool = "$IPHONEPATH/usr/bin/${ios_triple}libtool"
+ libtool = "$IOS_TOOLCHAIN_PATH/usr/bin/${ios_triple}libtool"
else:
- libtool = "$IPHONEPATH/usr/bin/libtool"
+ libtool = "$IOS_TOOLCHAIN_PATH/usr/bin/libtool"
env.Execute(
libtool + ' -static -o "' + lib_path + '" ' + " ".join([('"' + lib.srcnode().abspath + '"') for lib in source])
)
diff --git a/platform/iphone/api/api.cpp b/platform/ios/api/api.cpp
index f2e6fd7a7a..00c76a9256 100644
--- a/platform/iphone/api/api.cpp
+++ b/platform/ios/api/api.cpp
@@ -30,19 +30,19 @@
#include "api.h"
-#if defined(IPHONE_ENABLED)
+#if defined(IOS_ENABLED)
-void register_iphone_api() {
+void register_ios_api() {
godot_ios_plugins_initialize();
}
-void unregister_iphone_api() {
+void unregister_ios_api() {
godot_ios_plugins_deinitialize();
}
#else
-void register_iphone_api() {}
-void unregister_iphone_api() {}
+void register_ios_api() {}
+void unregister_ios_api() {}
#endif
diff --git a/platform/iphone/api/api.h b/platform/ios/api/api.h
index ece91a9f1a..c7fd4ce77b 100644
--- a/platform/iphone/api/api.h
+++ b/platform/ios/api/api.h
@@ -28,15 +28,15 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef IPHONE_API_H
-#define IPHONE_API_H
+#ifndef IOS_API_H
+#define IOS_API_H
-#if defined(IPHONE_ENABLED)
+#if defined(IOS_ENABLED)
extern void godot_ios_plugins_initialize();
extern void godot_ios_plugins_deinitialize();
#endif
-void register_iphone_api();
-void unregister_iphone_api();
+void register_ios_api();
+void unregister_ios_api();
-#endif // IPHONE_API_H
+#endif // IOS_API_H
diff --git a/platform/iphone/app_delegate.h b/platform/ios/app_delegate.h
index 0ec1dc071b..0ec1dc071b 100644
--- a/platform/iphone/app_delegate.h
+++ b/platform/ios/app_delegate.h
diff --git a/platform/iphone/app_delegate.mm b/platform/ios/app_delegate.mm
index c5c9b5a5f9..fb183d52d4 100644
--- a/platform/iphone/app_delegate.mm
+++ b/platform/ios/app_delegate.mm
@@ -34,7 +34,7 @@
#include "drivers/coreaudio/audio_driver_coreaudio.h"
#import "godot_view.h"
#include "main/main.h"
-#include "os_iphone.h"
+#include "os_ios.h"
#import "view_controller.h"
#import <AVFoundation/AVFoundation.h>
@@ -45,8 +45,8 @@
extern int gargc;
extern char **gargv;
-extern int iphone_main(int, char **, String, String);
-extern void iphone_finish();
+extern int ios_main(int, char **, String, String);
+extern void ios_finish();
@implementation AppDelegate
@@ -71,7 +71,7 @@ static ViewController *mainViewController = nil;
paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cacheDirectory = [paths objectAtIndex:0];
- int err = iphone_main(gargc, gargv, String::utf8([documentsDirectory UTF8String]), String::utf8([cacheDirectory UTF8String]));
+ int err = ios_main(gargc, gargv, String::utf8([documentsDirectory UTF8String]), String::utf8([cacheDirectory UTF8String]));
if (err != 0) {
// bail, things did not go very well for us, should probably output a message on screen with our error code...
@@ -106,10 +106,10 @@ static ViewController *mainViewController = nil;
if ([notification.name isEqualToString:AVAudioSessionInterruptionNotification]) {
if ([[notification.userInfo valueForKey:AVAudioSessionInterruptionTypeKey] isEqualToNumber:[NSNumber numberWithInt:AVAudioSessionInterruptionTypeBegan]]) {
NSLog(@"Audio interruption began");
- OSIPhone::get_singleton()->on_focus_out();
+ OS_IOS::get_singleton()->on_focus_out();
} else if ([[notification.userInfo valueForKey:AVAudioSessionInterruptionTypeKey] isEqualToNumber:[NSNumber numberWithInt:AVAudioSessionInterruptionTypeEnded]]) {
NSLog(@"Audio interruption ended");
- OSIPhone::get_singleton()->on_focus_in();
+ OS_IOS::get_singleton()->on_focus_in();
}
}
}
@@ -121,7 +121,7 @@ static ViewController *mainViewController = nil;
}
- (void)applicationWillTerminate:(UIApplication *)application {
- iphone_finish();
+ ios_finish();
}
// When application goes to background (e.g. user switches to another app or presses Home),
@@ -135,11 +135,11 @@ static ViewController *mainViewController = nil;
// notification panel by swiping from the upper part of the screen.
- (void)applicationWillResignActive:(UIApplication *)application {
- OSIPhone::get_singleton()->on_focus_out();
+ OS_IOS::get_singleton()->on_focus_out();
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
- OSIPhone::get_singleton()->on_focus_in();
+ OS_IOS::get_singleton()->on_focus_in();
}
- (void)dealloc {
diff --git a/platform/iphone/detect.py b/platform/ios/detect.py
index 392a0151be..67c90b10a0 100644
--- a/platform/iphone/detect.py
+++ b/platform/ios/detect.py
@@ -23,11 +23,11 @@ def get_opts():
return [
(
- "IPHONEPATH",
- "Path to iPhone toolchain",
+ "IOS_TOOLCHAIN_PATH",
+ "Path to iOS toolchain",
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain",
),
- ("IPHONESDK", "Path to the iPhone SDK", ""),
+ ("IOS_SDK_PATH", "Path to the iOS SDK", ""),
BoolVariable("ios_simulator", "Build for iOS Simulator", False),
BoolVariable("ios_exceptions", "Enable exceptions", False),
("ios_triple", "Triple for ios toolchain", ""),
@@ -75,10 +75,10 @@ def configure(env):
if "OSXCROSS_IOS" in os.environ:
env["osxcross"] = True
- env["ENV"]["PATH"] = env["IPHONEPATH"] + "/Developer/usr/bin/:" + env["ENV"]["PATH"]
+ env["ENV"]["PATH"] = env["IOS_TOOLCHAIN_PATH"] + "/Developer/usr/bin/:" + env["ENV"]["PATH"]
- compiler_path = "$IPHONEPATH/usr/bin/${ios_triple}"
- s_compiler_path = "$IPHONEPATH/Developer/usr/bin/"
+ compiler_path = "$IOS_TOOLCHAIN_PATH/usr/bin/${ios_triple}"
+ s_compiler_path = "$IOS_TOOLCHAIN_PATH/Developer/usr/bin/"
ccache_path = os.environ.get("CCACHE")
if ccache_path is None:
@@ -97,11 +97,13 @@ def configure(env):
## Compile flags
if env["ios_simulator"]:
- detect_darwin_sdk_path("iphonesimulator", env)
+ detect_darwin_sdk_path("iossimulator", env)
+ env.Append(ASFLAGS=["-mios-simulator-version-min=13.0"])
env.Append(CCFLAGS=["-mios-simulator-version-min=13.0"])
env.extra_suffix = ".simulator" + env.extra_suffix
else:
- detect_darwin_sdk_path("iphone", env)
+ detect_darwin_sdk_path("ios", env)
+ env.Append(ASFLAGS=["-miphoneos-version-min=11.0"])
env.Append(CCFLAGS=["-miphoneos-version-min=11.0"])
if env["arch"] == "x86_64":
@@ -110,18 +112,20 @@ def configure(env):
CCFLAGS=(
"-fobjc-arc -arch x86_64"
" -fobjc-abi-version=2 -fobjc-legacy-dispatch -fmessage-length=0 -fpascal-strings -fblocks"
- " -fasm-blocks -isysroot $IPHONESDK"
+ " -fasm-blocks -isysroot $IOS_SDK_PATH"
).split()
)
+ env.Append(ASFLAGS=["-arch", "x86_64"])
elif env["arch"] == "arm64":
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"
- " -isysroot $IPHONESDK".split()
+ " -isysroot $IOS_SDK_PATH".split()
)
)
+ env.Append(ASFLAGS=["-arch", "arm64"])
env.Append(CPPDEFINES=["NEED_LONG_INT"])
# Disable exceptions on non-tools (template) builds
@@ -131,18 +135,18 @@ def configure(env):
else:
env.Append(CCFLAGS=["-fno-exceptions"])
- # Temp fix for ABS/MAX/MIN macros in iPhone SDK blocking compilation
+ # Temp fix for ABS/MAX/MIN macros in iOS SDK blocking compilation
env.Append(CCFLAGS=["-Wno-ambiguous-macro"])
env.Prepend(
CPPPATH=[
- "$IPHONESDK/usr/include",
- "$IPHONESDK/System/Library/Frameworks/AudioUnit.framework/Headers",
+ "$IOS_SDK_PATH/usr/include",
+ "$IOS_SDK_PATH/System/Library/Frameworks/AudioUnit.framework/Headers",
]
)
- env.Prepend(CPPPATH=["#platform/iphone"])
- env.Append(CPPDEFINES=["IPHONE_ENABLED", "UNIX_ENABLED", "COREAUDIO_ENABLED"])
+ env.Prepend(CPPPATH=["#platform/ios"])
+ env.Append(CPPDEFINES=["IOS_ENABLED", "UNIX_ENABLED", "COREAUDIO_ENABLED"])
if env["vulkan"]:
env.Append(CPPDEFINES=["VULKAN_ENABLED"])
diff --git a/platform/iphone/device_metrics.h b/platform/ios/device_metrics.h
index b9fb9b2fd9..b9fb9b2fd9 100644
--- a/platform/iphone/device_metrics.h
+++ b/platform/ios/device_metrics.h
diff --git a/platform/iphone/device_metrics.m b/platform/ios/device_metrics.m
index ec4dd8130d..ec4dd8130d 100644
--- a/platform/iphone/device_metrics.m
+++ b/platform/ios/device_metrics.m
diff --git a/platform/iphone/display_layer.h b/platform/ios/display_layer.h
index a17c75dba1..a17c75dba1 100644
--- a/platform/iphone/display_layer.h
+++ b/platform/ios/display_layer.h
diff --git a/platform/iphone/display_layer.mm b/platform/ios/display_layer.mm
index 92e81448ac..7c83494768 100644
--- a/platform/iphone/display_layer.mm
+++ b/platform/ios/display_layer.mm
@@ -32,9 +32,9 @@
#include "core/config/project_settings.h"
#include "core/os/keyboard.h"
-#include "display_server_iphone.h"
+#include "display_server_ios.h"
#include "main/main.h"
-#include "os_iphone.h"
+#include "os_ios.h"
#include "servers/audio_server.h"
#import <AudioToolbox/AudioServices.h>
diff --git a/platform/iphone/display_server_iphone.h b/platform/ios/display_server_ios.h
index 7af222e3f8..5dd4d177ea 100644
--- a/platform/iphone/display_server_iphone.h
+++ b/platform/ios/display_server_ios.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* display_server_iphone.h */
+/* display_server_ios.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef display_server_iphone_h
-#define display_server_iphone_h
+#ifndef DISPLAY_SERVER_IOS_H
+#define DISPLAY_SERVER_IOS_H
#include "core/input/input.h"
#include "servers/display_server.h"
@@ -38,7 +38,7 @@
#include "drivers/vulkan/rendering_device_vulkan.h"
#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
-#include "vulkan_context_iphone.h"
+#include "vulkan_context_ios.h"
#import <QuartzCore/CAMetalLayer.h>
#ifdef USE_VOLK
@@ -48,13 +48,13 @@
#endif
#endif
-class DisplayServerIPhone : public DisplayServer {
- GDCLASS(DisplayServerIPhone, DisplayServer)
+class DisplayServerIOS : public DisplayServer {
+ GDCLASS(DisplayServerIOS, DisplayServer)
_THREAD_SAFE_CLASS_
#if defined(VULKAN_ENABLED)
- VulkanContextIPhone *context_vulkan = nullptr;
+ VulkanContextIOS *context_vulkan = nullptr;
RenderingDeviceVulkan *rendering_device_vulkan = nullptr;
#endif
@@ -73,15 +73,15 @@ class DisplayServerIPhone : public DisplayServer {
void perform_event(const Ref<InputEvent> &p_event);
- DisplayServerIPhone(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
- ~DisplayServerIPhone();
+ DisplayServerIOS(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
+ ~DisplayServerIOS();
public:
String rendering_driver;
- static DisplayServerIPhone *get_singleton();
+ static DisplayServerIOS *get_singleton();
- static void register_iphone_driver();
+ static void register_ios_driver();
static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
static Vector<String> get_rendering_drivers_func();
@@ -214,4 +214,4 @@ public:
void resize_window(CGSize size);
};
-#endif /* display_server_iphone_h */
+#endif // DISPLAY_SERVER_IOS_H
diff --git a/platform/iphone/display_server_iphone.mm b/platform/ios/display_server_ios.mm
index 573ee9b7a8..73d4a2a427 100644
--- a/platform/iphone/display_server_iphone.mm
+++ b/platform/ios/display_server_ios.mm
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* display_server_iphone.mm */
+/* display_server_ios.mm */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,7 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "display_server_iphone.h"
+#include "display_server_ios.h"
#import "app_delegate.h"
#include "core/config/project_settings.h"
@@ -37,20 +37,20 @@
#import "godot_view.h"
#include "ios.h"
#import "keyboard_input_view.h"
-#include "os_iphone.h"
+#include "os_ios.h"
#include "tts_ios.h"
#import "view_controller.h"
#import <Foundation/Foundation.h>
#import <sys/utsname.h>
-static const float kDisplayServerIPhoneAcceleration = 1;
+static const float kDisplayServerIOSAcceleration = 1.f;
-DisplayServerIPhone *DisplayServerIPhone::get_singleton() {
- return (DisplayServerIPhone *)DisplayServer::get_singleton();
+DisplayServerIOS *DisplayServerIOS::get_singleton() {
+ return (DisplayServerIOS *)DisplayServer::get_singleton();
}
-DisplayServerIPhone::DisplayServerIPhone(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
+DisplayServerIOS::DisplayServerIOS(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
rendering_driver = p_rendering_driver;
// Init TTS
@@ -101,7 +101,7 @@ DisplayServerIPhone::DisplayServerIPhone(const String &p_rendering_driver, Windo
rendering_device_vulkan = nullptr;
if (rendering_driver == "vulkan") {
- context_vulkan = memnew(VulkanContextIPhone);
+ context_vulkan = memnew(VulkanContextIOS);
if (context_vulkan->initialize() != OK) {
memdelete(context_vulkan);
context_vulkan = nullptr;
@@ -136,7 +136,7 @@ DisplayServerIPhone::DisplayServerIPhone(const String &p_rendering_driver, Windo
r_error = OK;
}
-DisplayServerIPhone::~DisplayServerIPhone() {
+DisplayServerIOS::~DisplayServerIOS() {
#if defined(VULKAN_ENABLED)
if (rendering_device_vulkan) {
rendering_device_vulkan->finalize();
@@ -152,11 +152,11 @@ DisplayServerIPhone::~DisplayServerIPhone() {
#endif
}
-DisplayServer *DisplayServerIPhone::create_func(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
- return memnew(DisplayServerIPhone(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error));
+DisplayServer *DisplayServerIOS::create_func(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
+ return memnew(DisplayServerIOS(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error));
}
-Vector<String> DisplayServerIPhone::get_rendering_drivers_func() {
+Vector<String> DisplayServerIOS::get_rendering_drivers_func() {
Vector<String> drivers;
#if defined(VULKAN_ENABLED)
@@ -169,51 +169,52 @@ Vector<String> DisplayServerIPhone::get_rendering_drivers_func() {
return drivers;
}
-void DisplayServerIPhone::register_iphone_driver() {
- register_create_function("iphone", create_func, get_rendering_drivers_func);
+void DisplayServerIOS::register_ios_driver() {
+ register_create_function("iOS", create_func, get_rendering_drivers_func);
}
// MARK: Events
-void DisplayServerIPhone::window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window) {
+void DisplayServerIOS::window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window) {
window_resize_callback = p_callable;
}
-void DisplayServerIPhone::window_set_window_event_callback(const Callable &p_callable, WindowID p_window) {
+void DisplayServerIOS::window_set_window_event_callback(const Callable &p_callable, WindowID p_window) {
window_event_callback = p_callable;
}
-void DisplayServerIPhone::window_set_input_event_callback(const Callable &p_callable, WindowID p_window) {
+void DisplayServerIOS::window_set_input_event_callback(const Callable &p_callable, WindowID p_window) {
input_event_callback = p_callable;
}
-void DisplayServerIPhone::window_set_input_text_callback(const Callable &p_callable, WindowID p_window) {
+void DisplayServerIOS::window_set_input_text_callback(const Callable &p_callable, WindowID p_window) {
input_text_callback = p_callable;
}
-void DisplayServerIPhone::window_set_drop_files_callback(const Callable &p_callable, WindowID p_window) {
+void DisplayServerIOS::window_set_drop_files_callback(const Callable &p_callable, WindowID p_window) {
// Probably not supported for iOS
}
-void DisplayServerIPhone::process_events() {
+void DisplayServerIOS::process_events() {
+ Input::get_singleton()->flush_buffered_events();
}
-void DisplayServerIPhone::_dispatch_input_events(const Ref<InputEvent> &p_event) {
- DisplayServerIPhone::get_singleton()->send_input_event(p_event);
+void DisplayServerIOS::_dispatch_input_events(const Ref<InputEvent> &p_event) {
+ DisplayServerIOS::get_singleton()->send_input_event(p_event);
}
-void DisplayServerIPhone::send_input_event(const Ref<InputEvent> &p_event) const {
+void DisplayServerIOS::send_input_event(const Ref<InputEvent> &p_event) const {
_window_callback(input_event_callback, p_event);
}
-void DisplayServerIPhone::send_input_text(const String &p_text) const {
+void DisplayServerIOS::send_input_text(const String &p_text) const {
_window_callback(input_text_callback, p_text);
}
-void DisplayServerIPhone::send_window_event(DisplayServer::WindowEvent p_event) const {
+void DisplayServerIOS::send_window_event(DisplayServer::WindowEvent p_event) const {
_window_callback(window_event_callback, int(p_event));
}
-void DisplayServerIPhone::_window_callback(const Callable &p_callable, const Variant &p_arg) const {
+void DisplayServerIOS::_window_callback(const Callable &p_callable, const Variant &p_arg) const {
if (!p_callable.is_null()) {
const Variant *argp = &p_arg;
Variant ret;
@@ -226,7 +227,7 @@ void DisplayServerIPhone::_window_callback(const Callable &p_callable, const Var
// MARK: Touches
-void DisplayServerIPhone::touch_press(int p_idx, int p_x, int p_y, bool p_pressed, bool p_double_click) {
+void DisplayServerIOS::touch_press(int p_idx, int p_x, int p_y, bool p_pressed, bool p_double_click) {
if (!GLOBAL_DEF("debug/disable_touch", false)) {
Ref<InputEventScreenTouch> ev;
ev.instantiate();
@@ -238,7 +239,7 @@ void DisplayServerIPhone::touch_press(int p_idx, int p_x, int p_y, bool p_presse
}
}
-void DisplayServerIPhone::touch_drag(int p_idx, int p_prev_x, int p_prev_y, int p_x, int p_y) {
+void DisplayServerIOS::touch_drag(int p_idx, int p_prev_x, int p_prev_y, int p_x, int p_y) {
if (!GLOBAL_DEF("debug/disable_touch", false)) {
Ref<InputEventScreenDrag> ev;
ev.instantiate();
@@ -249,17 +250,17 @@ void DisplayServerIPhone::touch_drag(int p_idx, int p_prev_x, int p_prev_y, int
}
}
-void DisplayServerIPhone::perform_event(const Ref<InputEvent> &p_event) {
+void DisplayServerIOS::perform_event(const Ref<InputEvent> &p_event) {
Input::get_singleton()->parse_input_event(p_event);
}
-void DisplayServerIPhone::touches_cancelled(int p_idx) {
+void DisplayServerIOS::touches_cancelled(int p_idx) {
touch_press(p_idx, -1, -1, false, false);
}
// MARK: Keyboard
-void DisplayServerIPhone::key(Key p_key, bool p_pressed) {
+void DisplayServerIOS::key(Key p_key, bool p_pressed) {
Ref<InputEventKey> ev;
ev.instantiate();
ev->set_echo(false);
@@ -272,31 +273,31 @@ void DisplayServerIPhone::key(Key p_key, bool p_pressed) {
// MARK: Motion
-void DisplayServerIPhone::update_gravity(float p_x, float p_y, float p_z) {
+void DisplayServerIOS::update_gravity(float p_x, float p_y, float p_z) {
Input::get_singleton()->set_gravity(Vector3(p_x, p_y, p_z));
}
-void DisplayServerIPhone::update_accelerometer(float p_x, float p_y, float p_z) {
+void DisplayServerIOS::update_accelerometer(float p_x, float p_y, float p_z) {
// Found out the Z should not be negated! Pass as is!
Vector3 v_accelerometer = Vector3(
- p_x / kDisplayServerIPhoneAcceleration,
- p_y / kDisplayServerIPhoneAcceleration,
- p_z / kDisplayServerIPhoneAcceleration);
+ p_x / kDisplayServerIOSAcceleration,
+ p_y / kDisplayServerIOSAcceleration,
+ p_z / kDisplayServerIOSAcceleration);
Input::get_singleton()->set_accelerometer(v_accelerometer);
}
-void DisplayServerIPhone::update_magnetometer(float p_x, float p_y, float p_z) {
+void DisplayServerIOS::update_magnetometer(float p_x, float p_y, float p_z) {
Input::get_singleton()->set_magnetometer(Vector3(p_x, p_y, p_z));
}
-void DisplayServerIPhone::update_gyroscope(float p_x, float p_y, float p_z) {
+void DisplayServerIOS::update_gyroscope(float p_x, float p_y, float p_z) {
Input::get_singleton()->set_gyroscope(Vector3(p_x, p_y, p_z));
}
// MARK: -
-bool DisplayServerIPhone::has_feature(Feature p_feature) const {
+bool DisplayServerIOS::has_feature(Feature p_feature) const {
switch (p_feature) {
// case FEATURE_CURSOR_SHAPE:
// case FEATURE_CUSTOM_CURSOR_SHAPE:
@@ -321,46 +322,46 @@ bool DisplayServerIPhone::has_feature(Feature p_feature) const {
}
}
-String DisplayServerIPhone::get_name() const {
- return "iPhone";
+String DisplayServerIOS::get_name() const {
+ return "iOS";
}
-bool DisplayServerIPhone::tts_is_speaking() const {
+bool DisplayServerIOS::tts_is_speaking() const {
ERR_FAIL_COND_V(!tts, false);
return [tts isSpeaking];
}
-bool DisplayServerIPhone::tts_is_paused() const {
+bool DisplayServerIOS::tts_is_paused() const {
ERR_FAIL_COND_V(!tts, false);
return [tts isPaused];
}
-Array DisplayServerIPhone::tts_get_voices() const {
+Array DisplayServerIOS::tts_get_voices() const {
ERR_FAIL_COND_V(!tts, Array());
return [tts getVoices];
}
-void DisplayServerIPhone::tts_speak(const String &p_text, const String &p_voice, int p_volume, float p_pitch, float p_rate, int p_utterance_id, bool p_interrupt) {
+void DisplayServerIOS::tts_speak(const String &p_text, const String &p_voice, int p_volume, float p_pitch, float p_rate, int p_utterance_id, bool p_interrupt) {
ERR_FAIL_COND(!tts);
[tts speak:p_text voice:p_voice volume:p_volume pitch:p_pitch rate:p_rate utterance_id:p_utterance_id interrupt:p_interrupt];
}
-void DisplayServerIPhone::tts_pause() {
+void DisplayServerIOS::tts_pause() {
ERR_FAIL_COND(!tts);
[tts pauseSpeaking];
}
-void DisplayServerIPhone::tts_resume() {
+void DisplayServerIOS::tts_resume() {
ERR_FAIL_COND(!tts);
[tts resumeSpeaking];
}
-void DisplayServerIPhone::tts_stop() {
+void DisplayServerIOS::tts_stop() {
ERR_FAIL_COND(!tts);
[tts stopSpeaking];
}
-Rect2i DisplayServerIPhone::get_display_safe_area() const {
+Rect2i DisplayServerIOS::get_display_safe_area() const {
if (@available(iOS 11, *)) {
UIEdgeInsets insets = UIEdgeInsetsZero;
UIView *view = AppDelegate.viewController.godotView;
@@ -376,15 +377,15 @@ Rect2i DisplayServerIPhone::get_display_safe_area() const {
}
}
-int DisplayServerIPhone::get_screen_count() const {
+int DisplayServerIOS::get_screen_count() const {
return 1;
}
-Point2i DisplayServerIPhone::screen_get_position(int p_screen) const {
+Point2i DisplayServerIOS::screen_get_position(int p_screen) const {
return Size2i();
}
-Size2i DisplayServerIPhone::screen_get_size(int p_screen) const {
+Size2i DisplayServerIOS::screen_get_size(int p_screen) const {
CALayer *layer = AppDelegate.viewController.godotView.renderingLayer;
if (!layer) {
@@ -394,11 +395,11 @@ Size2i DisplayServerIPhone::screen_get_size(int p_screen) const {
return Size2i(layer.bounds.size.width, layer.bounds.size.height) * screen_get_scale(p_screen);
}
-Rect2i DisplayServerIPhone::screen_get_usable_rect(int p_screen) const {
+Rect2i DisplayServerIOS::screen_get_usable_rect(int p_screen) const {
return Rect2i(screen_get_position(p_screen), screen_get_size(p_screen));
}
-int DisplayServerIPhone::screen_get_dpi(int p_screen) const {
+int DisplayServerIOS::screen_get_dpi(int p_screen) const {
struct utsname systemInfo;
uname(&systemInfo);
@@ -435,25 +436,25 @@ int DisplayServerIPhone::screen_get_dpi(int p_screen) const {
}
}
-float DisplayServerIPhone::screen_get_refresh_rate(int p_screen) const {
+float DisplayServerIOS::screen_get_refresh_rate(int p_screen) const {
return [UIScreen mainScreen].maximumFramesPerSecond;
}
-float DisplayServerIPhone::screen_get_scale(int p_screen) const {
+float DisplayServerIOS::screen_get_scale(int p_screen) const {
return [UIScreen mainScreen].nativeScale;
}
-Vector<DisplayServer::WindowID> DisplayServerIPhone::get_window_list() const {
+Vector<DisplayServer::WindowID> DisplayServerIOS::get_window_list() const {
Vector<DisplayServer::WindowID> list;
list.push_back(MAIN_WINDOW_ID);
return list;
}
-DisplayServer::WindowID DisplayServerIPhone::get_window_at_screen_position(const Point2i &p_position) const {
+DisplayServer::WindowID DisplayServerIOS::get_window_at_screen_position(const Point2i &p_position) const {
return MAIN_WINDOW_ID;
}
-int64_t DisplayServerIPhone::window_get_native_handle(HandleType p_handle_type, WindowID p_window) const {
+int64_t DisplayServerIOS::window_get_native_handle(HandleType p_handle_type, WindowID p_window) const {
ERR_FAIL_COND_V(p_window != MAIN_WINDOW_ID, 0);
switch (p_handle_type) {
case DISPLAY_HANDLE: {
@@ -471,120 +472,120 @@ int64_t DisplayServerIPhone::window_get_native_handle(HandleType p_handle_type,
}
}
-void DisplayServerIPhone::window_attach_instance_id(ObjectID p_instance, WindowID p_window) {
+void DisplayServerIOS::window_attach_instance_id(ObjectID p_instance, WindowID p_window) {
window_attached_instance_id = p_instance;
}
-ObjectID DisplayServerIPhone::window_get_attached_instance_id(WindowID p_window) const {
+ObjectID DisplayServerIOS::window_get_attached_instance_id(WindowID p_window) const {
return window_attached_instance_id;
}
-void DisplayServerIPhone::window_set_title(const String &p_title, WindowID p_window) {
+void DisplayServerIOS::window_set_title(const String &p_title, WindowID p_window) {
// Probably not supported for iOS
}
-int DisplayServerIPhone::window_get_current_screen(WindowID p_window) const {
+int DisplayServerIOS::window_get_current_screen(WindowID p_window) const {
return SCREEN_OF_MAIN_WINDOW;
}
-void DisplayServerIPhone::window_set_current_screen(int p_screen, WindowID p_window) {
+void DisplayServerIOS::window_set_current_screen(int p_screen, WindowID p_window) {
// Probably not supported for iOS
}
-Point2i DisplayServerIPhone::window_get_position(WindowID p_window) const {
+Point2i DisplayServerIOS::window_get_position(WindowID p_window) const {
return Point2i();
}
-void DisplayServerIPhone::window_set_position(const Point2i &p_position, WindowID p_window) {
+void DisplayServerIOS::window_set_position(const Point2i &p_position, WindowID p_window) {
// Probably not supported for single window iOS app
}
-void DisplayServerIPhone::window_set_transient(WindowID p_window, WindowID p_parent) {
+void DisplayServerIOS::window_set_transient(WindowID p_window, WindowID p_parent) {
// Probably not supported for iOS
}
-void DisplayServerIPhone::window_set_max_size(const Size2i p_size, WindowID p_window) {
+void DisplayServerIOS::window_set_max_size(const Size2i p_size, WindowID p_window) {
// Probably not supported for iOS
}
-Size2i DisplayServerIPhone::window_get_max_size(WindowID p_window) const {
+Size2i DisplayServerIOS::window_get_max_size(WindowID p_window) const {
return Size2i();
}
-void DisplayServerIPhone::window_set_min_size(const Size2i p_size, WindowID p_window) {
+void DisplayServerIOS::window_set_min_size(const Size2i p_size, WindowID p_window) {
// Probably not supported for iOS
}
-Size2i DisplayServerIPhone::window_get_min_size(WindowID p_window) const {
+Size2i DisplayServerIOS::window_get_min_size(WindowID p_window) const {
return Size2i();
}
-void DisplayServerIPhone::window_set_size(const Size2i p_size, WindowID p_window) {
+void DisplayServerIOS::window_set_size(const Size2i p_size, WindowID p_window) {
// Probably not supported for iOS
}
-Size2i DisplayServerIPhone::window_get_size(WindowID p_window) const {
+Size2i DisplayServerIOS::window_get_size(WindowID p_window) const {
CGRect screenBounds = [UIScreen mainScreen].bounds;
return Size2i(screenBounds.size.width, screenBounds.size.height) * screen_get_max_scale();
}
-Size2i DisplayServerIPhone::window_get_real_size(WindowID p_window) const {
+Size2i DisplayServerIOS::window_get_real_size(WindowID p_window) const {
return window_get_size(p_window);
}
-void DisplayServerIPhone::window_set_mode(WindowMode p_mode, WindowID p_window) {
+void DisplayServerIOS::window_set_mode(WindowMode p_mode, WindowID p_window) {
// Probably not supported for iOS
}
-DisplayServer::WindowMode DisplayServerIPhone::window_get_mode(WindowID p_window) const {
+DisplayServer::WindowMode DisplayServerIOS::window_get_mode(WindowID p_window) const {
return WindowMode::WINDOW_MODE_FULLSCREEN;
}
-bool DisplayServerIPhone::window_is_maximize_allowed(WindowID p_window) const {
+bool DisplayServerIOS::window_is_maximize_allowed(WindowID p_window) const {
return false;
}
-void DisplayServerIPhone::window_set_flag(WindowFlags p_flag, bool p_enabled, WindowID p_window) {
+void DisplayServerIOS::window_set_flag(WindowFlags p_flag, bool p_enabled, WindowID p_window) {
// Probably not supported for iOS
}
-bool DisplayServerIPhone::window_get_flag(WindowFlags p_flag, WindowID p_window) const {
+bool DisplayServerIOS::window_get_flag(WindowFlags p_flag, WindowID p_window) const {
return false;
}
-void DisplayServerIPhone::window_request_attention(WindowID p_window) {
+void DisplayServerIOS::window_request_attention(WindowID p_window) {
// Probably not supported for iOS
}
-void DisplayServerIPhone::window_move_to_foreground(WindowID p_window) {
+void DisplayServerIOS::window_move_to_foreground(WindowID p_window) {
// Probably not supported for iOS
}
-float DisplayServerIPhone::screen_get_max_scale() const {
+float DisplayServerIOS::screen_get_max_scale() const {
return screen_get_scale(SCREEN_OF_MAIN_WINDOW);
}
-void DisplayServerIPhone::screen_set_orientation(DisplayServer::ScreenOrientation p_orientation, int p_screen) {
+void DisplayServerIOS::screen_set_orientation(DisplayServer::ScreenOrientation p_orientation, int p_screen) {
screen_orientation = p_orientation;
}
-DisplayServer::ScreenOrientation DisplayServerIPhone::screen_get_orientation(int p_screen) const {
+DisplayServer::ScreenOrientation DisplayServerIOS::screen_get_orientation(int p_screen) const {
return screen_orientation;
}
-bool DisplayServerIPhone::window_can_draw(WindowID p_window) const {
+bool DisplayServerIOS::window_can_draw(WindowID p_window) const {
return true;
}
-bool DisplayServerIPhone::can_any_window_draw() const {
+bool DisplayServerIOS::can_any_window_draw() const {
return true;
}
-bool DisplayServerIPhone::screen_is_touchscreen(int p_screen) const {
+bool DisplayServerIOS::screen_is_touchscreen(int p_screen) const {
return true;
}
-void DisplayServerIPhone::virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect, bool p_multiline, int p_max_length, int p_cursor_start, int p_cursor_end) {
+void DisplayServerIOS::virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect, bool p_multiline, int p_max_length, int p_cursor_start, int p_cursor_end) {
NSString *existingString = [[NSString alloc] initWithUTF8String:p_existing_text.utf8().get_data()];
[AppDelegate.viewController.keyboardView
@@ -594,37 +595,37 @@ void DisplayServerIPhone::virtual_keyboard_show(const String &p_existing_text, c
cursorEnd:p_cursor_end];
}
-void DisplayServerIPhone::virtual_keyboard_hide() {
+void DisplayServerIOS::virtual_keyboard_hide() {
[AppDelegate.viewController.keyboardView resignFirstResponder];
}
-void DisplayServerIPhone::virtual_keyboard_set_height(int height) {
+void DisplayServerIOS::virtual_keyboard_set_height(int height) {
virtual_keyboard_height = height * screen_get_max_scale();
}
-int DisplayServerIPhone::virtual_keyboard_get_height() const {
+int DisplayServerIOS::virtual_keyboard_get_height() const {
return virtual_keyboard_height;
}
-void DisplayServerIPhone::clipboard_set(const String &p_text) {
+void DisplayServerIOS::clipboard_set(const String &p_text) {
[UIPasteboard generalPasteboard].string = [NSString stringWithUTF8String:p_text.utf8()];
}
-String DisplayServerIPhone::clipboard_get() const {
+String DisplayServerIOS::clipboard_get() const {
NSString *text = [UIPasteboard generalPasteboard].string;
return String::utf8([text UTF8String]);
}
-void DisplayServerIPhone::screen_set_keep_on(bool p_enable) {
+void DisplayServerIOS::screen_set_keep_on(bool p_enable) {
[UIApplication sharedApplication].idleTimerDisabled = p_enable;
}
-bool DisplayServerIPhone::screen_is_kept_on() const {
+bool DisplayServerIOS::screen_is_kept_on() const {
return [UIApplication sharedApplication].idleTimerDisabled;
}
-void DisplayServerIPhone::resize_window(CGSize viewSize) {
+void DisplayServerIOS::resize_window(CGSize viewSize) {
Size2i size = Size2i(viewSize.width, viewSize.height) * screen_get_max_scale();
#if defined(VULKAN_ENABLED)
@@ -637,14 +638,14 @@ void DisplayServerIPhone::resize_window(CGSize viewSize) {
_window_callback(window_resize_callback, resize_rect);
}
-void DisplayServerIPhone::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {
+void DisplayServerIOS::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {
_THREAD_SAFE_METHOD_
#if defined(VULKAN_ENABLED)
context_vulkan->set_vsync_mode(p_window, p_vsync_mode);
#endif
}
-DisplayServer::VSyncMode DisplayServerIPhone::window_get_vsync_mode(WindowID p_window) const {
+DisplayServer::VSyncMode DisplayServerIOS::window_get_vsync_mode(WindowID p_window) const {
_THREAD_SAFE_METHOD_
#if defined(VULKAN_ENABLED)
return context_vulkan->get_vsync_mode(p_window);
diff --git a/platform/iphone/export/export.cpp b/platform/ios/export/export.cpp
index 3b02e661c1..6024db2f2c 100644
--- a/platform/iphone/export/export.cpp
+++ b/platform/ios/export/export.cpp
@@ -30,9 +30,10 @@
#include "export.h"
+#include "editor/export/editor_export.h"
#include "export_plugin.h"
-void register_iphone_exporter() {
+void register_ios_exporter() {
Ref<EditorExportPlatformIOS> platform;
platform.instantiate();
diff --git a/platform/osx/export/export.h b/platform/ios/export/export.h
index b386337a09..756a1356ea 100644
--- a/platform/osx/export/export.h
+++ b/platform/ios/export/export.h
@@ -28,9 +28,9 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef OSX_EXPORT_H
-#define OSX_EXPORT_H
+#ifndef IOS_EXPORT_H
+#define IOS_EXPORT_H
-void register_osx_exporter();
+void register_ios_exporter();
-#endif // OSX_EXPORT_H
+#endif // IOS_EXPORT_H
diff --git a/platform/iphone/export/export_plugin.cpp b/platform/ios/export/export_plugin.cpp
index 4cf1c279eb..a2e80d33fd 100644
--- a/platform/iphone/export/export_plugin.cpp
+++ b/platform/ios/export/export_plugin.cpp
@@ -418,7 +418,7 @@ void EditorExportPlatformIOS::_fix_config_file(const Ref<EditorExportPreset> &p_
}
// !BAS! I'm assuming the 9 in the original code was a typo. I've added -1 or else it seems to also be adding our terminating zero...
- // should apply the same fix in our OSX export.
+ // should apply the same fix in our macOS export.
CharString cs = strnew.utf8();
pfile.resize(cs.size() - 1);
for (int i = 0; i < cs.size() - 1; i++) {
@@ -1394,7 +1394,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
if (src_pkg_name.is_empty()) {
String err;
- src_pkg_name = find_export_template("iphone.zip", &err);
+ src_pkg_name = find_export_template("ios.zip", &err);
if (src_pkg_name.is_empty()) {
add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Templates"), TTR("Export template not found."));
return ERR_FILE_NOT_FOUND;
@@ -1444,7 +1444,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
return ERR_SKIP;
}
- String library_to_use = "libgodot.iphone." + String(p_debug ? "debug" : "release") + ".xcframework";
+ String library_to_use = "libgodot.ios." + String(p_debug ? "debug" : "release") + ".xcframework";
print_line("Static framework: " + library_to_use);
String pkg_name;
@@ -1502,7 +1502,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
int ret = unzGoToFirstFile(src_pkg_zip);
Vector<uint8_t> project_file_data;
while (ret == UNZ_OK) {
-#if defined(OSX_ENABLED) || defined(X11_ENABLED)
+#if defined(MACOS_ENABLED) || defined(X11_ENABLED)
bool is_execute = false;
#endif
@@ -1527,17 +1527,17 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
//write
- file = file.replace_first("iphone/", "");
+ file = file.replace_first("ios/", "");
if (files_to_parse.has(file)) {
_fix_config_file(p_preset, data, config_data, p_debug);
- } else if (file.begins_with("libgodot.iphone")) {
+ } else if (file.begins_with("libgodot.ios")) {
if (!file.begins_with(library_to_use) || file.ends_with(String("/empty"))) {
ret = unzGoToNextFile(src_pkg_zip);
continue; //ignore!
}
found_library = true;
-#if defined(OSX_ENABLED) || defined(X11_ENABLED)
+#if defined(MACOS_ENABLED) || defined(X11_ENABLED)
is_execute = true;
#endif
file = file.replace(library_to_use, binary_name + ".xcframework");
@@ -1580,7 +1580,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
f->store_buffer(data.ptr(), data.size());
}
-#if defined(OSX_ENABLED) || defined(X11_ENABLED)
+#if defined(MACOS_ENABLED) || defined(X11_ENABLED)
if (is_execute) {
// we need execute rights on this file
chmod(file.utf8().get_data(), 0755);
@@ -1725,7 +1725,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
f->store_buffer(project_file_data.ptr(), project_file_data.size());
}
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
{
if (ep.step("Code-signing dylibs", 2)) {
return ERR_SKIP;
@@ -1790,7 +1790,7 @@ bool EditorExportPlatformIOS::can_export(const Ref<EditorExportPreset> &p_preset
// Look for export templates (first official, and if defined custom templates).
- bool dvalid = exists_export_template("iphone.zip", &err);
+ bool dvalid = exists_export_template("ios.zip", &err);
bool rvalid = dvalid; // Both in the same ZIP.
if (p_preset->get("custom_template/debug") != "") {
@@ -1838,12 +1838,8 @@ bool EditorExportPlatformIOS::can_export(const Ref<EditorExportPreset> &p_preset
}
EditorExportPlatformIOS::EditorExportPlatformIOS() {
- Ref<Image> img = memnew(Image(_iphone_logo));
- logo.instantiate();
- logo->create_from_image(img);
-
+ logo = ImageTexture::create_from_image(memnew(Image(_ios_logo)));
plugins_changed.set();
-
check_for_changes_thread.start(_check_for_changes_poll_thread, this);
}
diff --git a/platform/iphone/export/export_plugin.h b/platform/ios/export/export_plugin.h
index 1db7418e3f..ce470bba78 100644
--- a/platform/iphone/export/export_plugin.h
+++ b/platform/ios/export/export_plugin.h
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef IPHONE_EXPORT_PLUGIN_H
-#define IPHONE_EXPORT_PLUGIN_H
+#ifndef IOS_EXPORT_PLUGIN_H
+#define IOS_EXPORT_PLUGIN_H
#include "core/config/project_settings.h"
#include "core/io/file_access.h"
@@ -40,10 +40,10 @@
#include "core/os/os.h"
#include "core/templates/safe_refcount.h"
#include "core/version.h"
-#include "editor/editor_export.h"
#include "editor/editor_settings.h"
+#include "editor/export/editor_export_platform.h"
#include "main/splash.gen.h"
-#include "platform/iphone/logo.gen.h"
+#include "platform/ios/logo.gen.h"
#include "string.h"
#include "godot_plugin_config.h"
@@ -290,4 +290,4 @@ public:
}
};
-#endif
+#endif // IOS_EXPORT_PLUGIN_H
diff --git a/platform/iphone/export/godot_plugin_config.cpp b/platform/ios/export/godot_plugin_config.cpp
index 9118b95337..9118b95337 100644
--- a/platform/iphone/export/godot_plugin_config.cpp
+++ b/platform/ios/export/godot_plugin_config.cpp
diff --git a/platform/iphone/export/godot_plugin_config.h b/platform/ios/export/godot_plugin_config.h
index 9ef8aa8c6d..5ca8b05b42 100644
--- a/platform/iphone/export/godot_plugin_config.h
+++ b/platform/ios/export/godot_plugin_config.h
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef IPHONE_GODOT_PLUGIN_CONFIG_H
-#define IPHONE_GODOT_PLUGIN_CONFIG_H
+#ifndef IOS_GODOT_PLUGIN_CONFIG_H
+#define IOS_GODOT_PLUGIN_CONFIG_H
#include "core/error/error_list.h"
#include "core/io/config_file.h"
@@ -129,4 +129,4 @@ struct PluginConfigIOS {
static PluginConfigIOS load_plugin_config(Ref<ConfigFile> config_file, const String &path);
};
-#endif // GODOT_PLUGIN_CONFIG_H
+#endif // IOS_GODOT_PLUGIN_CONFIG_H
diff --git a/platform/iphone/godot_app_delegate.h b/platform/ios/godot_app_delegate.h
index 703a906bda..703a906bda 100644
--- a/platform/iphone/godot_app_delegate.h
+++ b/platform/ios/godot_app_delegate.h
diff --git a/platform/iphone/godot_app_delegate.m b/platform/ios/godot_app_delegate.m
index 84347f9a30..84347f9a30 100644
--- a/platform/iphone/godot_app_delegate.m
+++ b/platform/ios/godot_app_delegate.m
diff --git a/platform/iphone/godot_iphone.mm b/platform/ios/godot_ios.mm
index 49474ef554..5f3e786b8a 100644
--- a/platform/iphone/godot_iphone.mm
+++ b/platform/ios/godot_ios.mm
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* godot_iphone.mm */
+/* godot_ios.mm */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -30,17 +30,17 @@
#include "core/string/ustring.h"
#include "main/main.h"
-#include "os_iphone.h"
+#include "os_ios.h"
#include <stdio.h>
#include <string.h>
#include <unistd.h>
-static OSIPhone *os = nullptr;
+static OS_IOS *os = nullptr;
int add_path(int, char **);
int add_cmdline(int, char **);
-int iphone_main(int, char **, String);
+int ios_main(int, char **, String);
int add_path(int p_argc, char **p_args) {
NSString *str = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"godot_path"];
@@ -74,7 +74,7 @@ int add_cmdline(int p_argc, char **p_args) {
return p_argc;
}
-int iphone_main(int argc, char **argv, String data_dir, String cache_dir) {
+int ios_main(int argc, char **argv, String data_dir, String cache_dir) {
size_t len = strlen(argv[0]);
while (len--) {
@@ -91,11 +91,11 @@ int iphone_main(int argc, char **argv, String data_dir, String cache_dir) {
chdir(path);
}
- printf("godot_iphone %s\n", argv[0]);
+ printf("godot_ios %s\n", argv[0]);
char cwd[512];
getcwd(cwd, sizeof(cwd));
printf("cwd %s\n", cwd);
- os = new OSIPhone(data_dir, cache_dir);
+ os = new OS_IOS(data_dir, cache_dir);
// We must override main when testing is enabled
TEST_MAIN_OVERRIDE
@@ -112,7 +112,10 @@ int iphone_main(int argc, char **argv, String data_dir, String cache_dir) {
Error err = Main::setup(fargv[0], argc - 1, &fargv[1], false);
printf("setup %i\n", err);
- if (err != OK) {
+
+ if (err == ERR_HELP) { // Returned by --help and --version, so success.
+ return 0;
+ } else if (err != OK) {
return 255;
}
@@ -121,8 +124,8 @@ int iphone_main(int argc, char **argv, String data_dir, String cache_dir) {
return 0;
}
-void iphone_finish() {
- printf("iphone_finish\n");
+void ios_finish() {
+ printf("ios_finish\n");
Main::cleanup();
delete os;
}
diff --git a/platform/iphone/godot_view.h b/platform/ios/godot_view.h
index fcb97fa63a..fcb97fa63a 100644
--- a/platform/iphone/godot_view.h
+++ b/platform/ios/godot_view.h
diff --git a/platform/iphone/godot_view.mm b/platform/ios/godot_view.mm
index e48dd2e507..9ed219508c 100644
--- a/platform/iphone/godot_view.mm
+++ b/platform/ios/godot_view.mm
@@ -33,7 +33,7 @@
#include "core/os/keyboard.h"
#include "core/string/ustring.h"
#import "display_layer.h"
-#include "display_server_iphone.h"
+#include "display_server_ios.h"
#import "godot_view_gesture_recognizer.h"
#import "godot_view_renderer.h"
@@ -281,8 +281,8 @@ static const float earth_gravity = 9.80665;
self.renderingLayer.frame = self.bounds;
[self.renderingLayer layoutDisplayLayer];
- if (DisplayServerIPhone::get_singleton()) {
- DisplayServerIPhone::get_singleton()->resize_window(self.bounds.size);
+ if (DisplayServerIOS::get_singleton()) {
+ DisplayServerIOS::get_singleton()->resize_window(self.bounds.size);
}
}
@@ -348,7 +348,7 @@ static const float earth_gravity = 9.80665;
int tid = [self getTouchIDForTouch:touch];
ERR_FAIL_COND(tid == -1);
CGPoint touchPoint = [touch locationInView:self];
- DisplayServerIPhone::get_singleton()->touch_press(tid, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, true, touch.tapCount > 1);
+ DisplayServerIOS::get_singleton()->touch_press(tid, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, true, touch.tapCount > 1);
}
}
}
@@ -362,7 +362,7 @@ static const float earth_gravity = 9.80665;
ERR_FAIL_COND(tid == -1);
CGPoint touchPoint = [touch locationInView:self];
CGPoint prev_point = [touch previousLocationInView:self];
- DisplayServerIPhone::get_singleton()->touch_drag(tid, prev_point.x * self.contentScaleFactor, prev_point.y * self.contentScaleFactor, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor);
+ DisplayServerIOS::get_singleton()->touch_drag(tid, prev_point.x * self.contentScaleFactor, prev_point.y * self.contentScaleFactor, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor);
}
}
}
@@ -376,7 +376,7 @@ static const float earth_gravity = 9.80665;
ERR_FAIL_COND(tid == -1);
[self removeTouch:touch];
CGPoint touchPoint = [touch locationInView:self];
- DisplayServerIPhone::get_singleton()->touch_press(tid, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, false, false);
+ DisplayServerIOS::get_singleton()->touch_press(tid, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, false, false);
}
}
}
@@ -388,7 +388,7 @@ static const float earth_gravity = 9.80665;
UITouch *touch = [tlist objectAtIndex:i];
int tid = [self getTouchIDForTouch:touch];
ERR_FAIL_COND(tid == -1);
- DisplayServerIPhone::get_singleton()->touches_cancelled(tid);
+ DisplayServerIOS::get_singleton()->touches_cancelled(tid);
}
}
[self clearTouches];
@@ -452,28 +452,28 @@ static const float earth_gravity = 9.80665;
switch (interfaceOrientation) {
case UIInterfaceOrientationLandscapeLeft: {
- DisplayServerIPhone::get_singleton()->update_gravity(-gravity.y, gravity.x, gravity.z);
- DisplayServerIPhone::get_singleton()->update_accelerometer(-(acceleration.y + gravity.y), (acceleration.x + gravity.x), acceleration.z + gravity.z);
- DisplayServerIPhone::get_singleton()->update_magnetometer(-magnetic.y, magnetic.x, magnetic.z);
- DisplayServerIPhone::get_singleton()->update_gyroscope(-rotation.y, rotation.x, rotation.z);
+ DisplayServerIOS::get_singleton()->update_gravity(-gravity.y, gravity.x, gravity.z);
+ DisplayServerIOS::get_singleton()->update_accelerometer(-(acceleration.y + gravity.y), (acceleration.x + gravity.x), acceleration.z + gravity.z);
+ DisplayServerIOS::get_singleton()->update_magnetometer(-magnetic.y, magnetic.x, magnetic.z);
+ DisplayServerIOS::get_singleton()->update_gyroscope(-rotation.y, rotation.x, rotation.z);
} break;
case UIInterfaceOrientationLandscapeRight: {
- DisplayServerIPhone::get_singleton()->update_gravity(gravity.y, -gravity.x, gravity.z);
- DisplayServerIPhone::get_singleton()->update_accelerometer((acceleration.y + gravity.y), -(acceleration.x + gravity.x), acceleration.z + gravity.z);
- DisplayServerIPhone::get_singleton()->update_magnetometer(magnetic.y, -magnetic.x, magnetic.z);
- DisplayServerIPhone::get_singleton()->update_gyroscope(rotation.y, -rotation.x, rotation.z);
+ DisplayServerIOS::get_singleton()->update_gravity(gravity.y, -gravity.x, gravity.z);
+ DisplayServerIOS::get_singleton()->update_accelerometer((acceleration.y + gravity.y), -(acceleration.x + gravity.x), acceleration.z + gravity.z);
+ DisplayServerIOS::get_singleton()->update_magnetometer(magnetic.y, -magnetic.x, magnetic.z);
+ DisplayServerIOS::get_singleton()->update_gyroscope(rotation.y, -rotation.x, rotation.z);
} break;
case UIInterfaceOrientationPortraitUpsideDown: {
- DisplayServerIPhone::get_singleton()->update_gravity(-gravity.x, gravity.y, gravity.z);
- DisplayServerIPhone::get_singleton()->update_accelerometer(-(acceleration.x + gravity.x), (acceleration.y + gravity.y), acceleration.z + gravity.z);
- DisplayServerIPhone::get_singleton()->update_magnetometer(-magnetic.x, magnetic.y, magnetic.z);
- DisplayServerIPhone::get_singleton()->update_gyroscope(-rotation.x, rotation.y, rotation.z);
+ DisplayServerIOS::get_singleton()->update_gravity(-gravity.x, gravity.y, gravity.z);
+ DisplayServerIOS::get_singleton()->update_accelerometer(-(acceleration.x + gravity.x), (acceleration.y + gravity.y), acceleration.z + gravity.z);
+ DisplayServerIOS::get_singleton()->update_magnetometer(-magnetic.x, magnetic.y, magnetic.z);
+ DisplayServerIOS::get_singleton()->update_gyroscope(-rotation.x, rotation.y, rotation.z);
} break;
default: { // assume portrait
- DisplayServerIPhone::get_singleton()->update_gravity(gravity.x, gravity.y, gravity.z);
- DisplayServerIPhone::get_singleton()->update_accelerometer(acceleration.x + gravity.x, acceleration.y + gravity.y, acceleration.z + gravity.z);
- DisplayServerIPhone::get_singleton()->update_magnetometer(magnetic.x, magnetic.y, magnetic.z);
- DisplayServerIPhone::get_singleton()->update_gyroscope(rotation.x, rotation.y, rotation.z);
+ DisplayServerIOS::get_singleton()->update_gravity(gravity.x, gravity.y, gravity.z);
+ DisplayServerIOS::get_singleton()->update_accelerometer(acceleration.x + gravity.x, acceleration.y + gravity.y, acceleration.z + gravity.z);
+ DisplayServerIOS::get_singleton()->update_magnetometer(magnetic.x, magnetic.y, magnetic.z);
+ DisplayServerIOS::get_singleton()->update_gyroscope(rotation.x, rotation.y, rotation.z);
} break;
}
}
diff --git a/platform/iphone/godot_view_gesture_recognizer.h b/platform/ios/godot_view_gesture_recognizer.h
index 9fd8a6b222..9fd8a6b222 100644
--- a/platform/iphone/godot_view_gesture_recognizer.h
+++ b/platform/ios/godot_view_gesture_recognizer.h
diff --git a/platform/iphone/godot_view_gesture_recognizer.mm b/platform/ios/godot_view_gesture_recognizer.mm
index 49a92add5e..49a92add5e 100644
--- a/platform/iphone/godot_view_gesture_recognizer.mm
+++ b/platform/ios/godot_view_gesture_recognizer.mm
diff --git a/platform/iphone/godot_view_renderer.h b/platform/ios/godot_view_renderer.h
index b3ee23ae4f..b3ee23ae4f 100644
--- a/platform/iphone/godot_view_renderer.h
+++ b/platform/ios/godot_view_renderer.h
diff --git a/platform/iphone/godot_view_renderer.mm b/platform/ios/godot_view_renderer.mm
index 32477ae41c..140410fbef 100644
--- a/platform/iphone/godot_view_renderer.mm
+++ b/platform/ios/godot_view_renderer.mm
@@ -32,9 +32,9 @@
#include "core/config/project_settings.h"
#include "core/os/keyboard.h"
-#import "display_server_iphone.h"
+#import "display_server_ios.h"
#include "main/main.h"
-#include "os_iphone.h"
+#include "os_ios.h"
#include "servers/audio_server.h"
#import <AudioToolbox/AudioServices.h>
@@ -69,7 +69,7 @@
if (!self.hasStartedMain) {
self.hasStartedMain = YES;
- OSIPhone::get_singleton()->start();
+ OS_IOS::get_singleton()->start();
return YES;
}
@@ -108,11 +108,11 @@
}
- (void)renderOnView:(UIView *)view {
- if (!OSIPhone::get_singleton()) {
+ if (!OS_IOS::get_singleton()) {
return;
}
- OSIPhone::get_singleton()->iterate();
+ OS_IOS::get_singleton()->iterate();
}
@end
diff --git a/platform/iphone/ios.h b/platform/ios/ios.h
index 0607d7b395..0b3842b233 100644
--- a/platform/iphone/ios.h
+++ b/platform/ios/ios.h
@@ -58,4 +58,4 @@ public:
iOS();
};
-#endif
+#endif // IOS_H
diff --git a/platform/iphone/ios.mm b/platform/ios/ios.mm
index 79baae028a..79baae028a 100644
--- a/platform/iphone/ios.mm
+++ b/platform/ios/ios.mm
diff --git a/platform/iphone/joypad_iphone.h b/platform/ios/joypad_ios.h
index 37e272a2c9..66c4b090bc 100644
--- a/platform/iphone/joypad_iphone.h
+++ b/platform/ios/joypad_ios.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* joypad_iphone.h */
+/* joypad_ios.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -30,7 +30,7 @@
#import <GameController/GameController.h>
-@interface JoypadIPhoneObserver : NSObject
+@interface JoypadIOSObserver : NSObject
- (void)startObserving;
- (void)startProcessing;
@@ -38,13 +38,13 @@
@end
-class JoypadIPhone {
+class JoypadIOS {
private:
- JoypadIPhoneObserver *observer;
+ JoypadIOSObserver *observer;
public:
- JoypadIPhone();
- ~JoypadIPhone();
+ JoypadIOS();
+ ~JoypadIOS();
void start_processing();
};
diff --git a/platform/iphone/joypad_iphone.mm b/platform/ios/joypad_ios.mm
index 9c2feeaaca..e147cb2527 100644
--- a/platform/iphone/joypad_iphone.mm
+++ b/platform/ios/joypad_ios.mm
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* joypad_iphone.mm */
+/* joypad_ios.mm */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,7 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#import "joypad_iphone.h"
+#import "joypad_ios.h"
#include "core/config/project_settings.h"
#include "drivers/coreaudio/audio_driver_coreaudio.h"
@@ -36,27 +36,27 @@
#import "godot_view.h"
-#include "os_iphone.h"
+#include "os_ios.h"
-JoypadIPhone::JoypadIPhone() {
- observer = [[JoypadIPhoneObserver alloc] init];
+JoypadIOS::JoypadIOS() {
+ observer = [[JoypadIOSObserver alloc] init];
[observer startObserving];
}
-JoypadIPhone::~JoypadIPhone() {
+JoypadIOS::~JoypadIOS() {
if (observer) {
[observer finishObserving];
observer = nil;
}
}
-void JoypadIPhone::start_processing() {
+void JoypadIOS::start_processing() {
if (observer) {
[observer startProcessing];
}
}
-@interface JoypadIPhoneObserver ()
+@interface JoypadIOSObserver ()
@property(assign, nonatomic) BOOL isObserving;
@property(assign, nonatomic) BOOL isProcessing;
@@ -65,7 +65,7 @@ void JoypadIPhone::start_processing() {
@end
-@implementation JoypadIPhoneObserver
+@implementation JoypadIOSObserver
- (instancetype)init {
self = [super init];
diff --git a/platform/iphone/keyboard_input_view.h b/platform/ios/keyboard_input_view.h
index 33fa5d571a..33fa5d571a 100644
--- a/platform/iphone/keyboard_input_view.h
+++ b/platform/ios/keyboard_input_view.h
diff --git a/platform/iphone/keyboard_input_view.mm b/platform/ios/keyboard_input_view.mm
index f2a7b22483..76e3f23c9d 100644
--- a/platform/iphone/keyboard_input_view.mm
+++ b/platform/ios/keyboard_input_view.mm
@@ -31,8 +31,8 @@
#import "keyboard_input_view.h"
#include "core/os/keyboard.h"
-#include "display_server_iphone.h"
-#include "os_iphone.h"
+#include "display_server_ios.h"
+#include "os_ios.h"
@interface GodotKeyboardInputView () <UITextViewDelegate>
@@ -115,8 +115,8 @@
- (void)deleteText:(NSInteger)charactersToDelete {
for (int i = 0; i < charactersToDelete; i++) {
- DisplayServerIPhone::get_singleton()->key(Key::BACKSPACE, true);
- DisplayServerIPhone::get_singleton()->key(Key::BACKSPACE, false);
+ DisplayServerIOS::get_singleton()->key(Key::BACKSPACE, true);
+ DisplayServerIOS::get_singleton()->key(Key::BACKSPACE, false);
}
}
@@ -138,8 +138,8 @@
break;
}
- DisplayServerIPhone::get_singleton()->key((Key)character, true);
- DisplayServerIPhone::get_singleton()->key((Key)character, false);
+ DisplayServerIOS::get_singleton()->key((Key)character, true);
+ DisplayServerIOS::get_singleton()->key((Key)character, false);
}
}
diff --git a/platform/iphone/logo.png b/platform/ios/logo.png
index 966d8aa70a..966d8aa70a 100644
--- a/platform/iphone/logo.png
+++ b/platform/ios/logo.png
Binary files differ
diff --git a/platform/iphone/main.m b/platform/ios/main.m
index acfa7ab731..acfa7ab731 100644
--- a/platform/iphone/main.m
+++ b/platform/ios/main.m
diff --git a/platform/iphone/os_iphone.h b/platform/ios/os_ios.h
index d03403bbb4..cfd1771653 100644
--- a/platform/iphone/os_iphone.h
+++ b/platform/ios/os_ios.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* os_iphone.h */
+/* os_ios.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,24 +28,24 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifdef IPHONE_ENABLED
+#ifdef IOS_ENABLED
-#ifndef OS_IPHONE_H
-#define OS_IPHONE_H
+#ifndef OS_IOS_H
+#define OS_IOS_H
#include "drivers/coreaudio/audio_driver_coreaudio.h"
#include "drivers/unix/os_unix.h"
#include "ios.h"
-#include "joypad_iphone.h"
+#include "joypad_ios.h"
#include "servers/audio_server.h"
#include "servers/rendering/renderer_compositor.h"
#if defined(VULKAN_ENABLED)
#include "drivers/vulkan/rendering_device_vulkan.h"
-#include "platform/iphone/vulkan_context_iphone.h"
+#include "platform/ios/vulkan_context_ios.h"
#endif
-class OSIPhone : public OS_Unix {
+class OS_IOS : public OS_Unix {
private:
static HashMap<String, void *> dynamic_symbol_lookup_table;
friend void register_dynamic_symbol(char *name, void *address);
@@ -54,7 +54,7 @@ private:
iOS *ios = nullptr;
- JoypadIPhone *joypad_iphone = nullptr;
+ JoypadIOS *joypad_ios = nullptr;
MainLoop *main_loop = nullptr;
@@ -79,10 +79,10 @@ private:
void deinitialize_modules();
public:
- static OSIPhone *get_singleton();
+ static OS_IOS *get_singleton();
- OSIPhone(String p_data_dir, String p_cache_dir);
- ~OSIPhone();
+ OS_IOS(String p_data_dir, String p_cache_dir);
+ ~OS_IOS();
void initialize_modules();
@@ -119,6 +119,6 @@ public:
void on_focus_in();
};
-#endif // OS_IPHONE_H
+#endif // OS_IOS_H
-#endif // IPHONE_ENABLED
+#endif // OS_IOS_H
diff --git a/platform/iphone/os_iphone.mm b/platform/ios/os_ios.mm
index 95b06b728e..880315209e 100644
--- a/platform/iphone/os_iphone.mm
+++ b/platform/ios/os_ios.mm
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* os_iphone.mm */
+/* os_ios.mm */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,16 +28,16 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifdef IPHONE_ENABLED
+#ifdef IOS_ENABLED
-#include "os_iphone.h"
+#include "os_ios.h"
#import "app_delegate.h"
#include "core/config/project_settings.h"
#include "core/io/dir_access.h"
#include "core/io/file_access.h"
#include "core/io/file_access_pack.h"
-#include "display_server_iphone.h"
+#include "display_server_ios.h"
#include "drivers/unix/syslog_logger.h"
#import "godot_view.h"
#include "main/main.h"
@@ -65,7 +65,7 @@ typedef void (*init_callback)();
static init_callback *ios_init_callbacks = nullptr;
static int ios_init_callbacks_count = 0;
static int ios_init_callbacks_capacity = 0;
-HashMap<String, void *> OSIPhone::dynamic_symbol_lookup_table;
+HashMap<String, void *> OS_IOS::dynamic_symbol_lookup_table;
void add_ios_init_callback(init_callback cb) {
if (ios_init_callbacks_count == ios_init_callbacks_capacity) {
@@ -82,14 +82,14 @@ void add_ios_init_callback(init_callback cb) {
}
void register_dynamic_symbol(char *name, void *address) {
- OSIPhone::dynamic_symbol_lookup_table[String(name)] = address;
+ OS_IOS::dynamic_symbol_lookup_table[String(name)] = address;
}
-OSIPhone *OSIPhone::get_singleton() {
- return (OSIPhone *)OS::get_singleton();
+OS_IOS *OS_IOS::get_singleton() {
+ return (OS_IOS *)OS::get_singleton();
}
-OSIPhone::OSIPhone(String p_data_dir, String p_cache_dir) {
+OS_IOS::OS_IOS(String p_data_dir, String p_cache_dir) {
for (int i = 0; i < ios_init_callbacks_count; ++i) {
ios_init_callbacks[i]();
}
@@ -116,37 +116,37 @@ OSIPhone::OSIPhone(String p_data_dir, String p_cache_dir) {
AudioDriverManager::add_driver(&audio_driver);
- DisplayServerIPhone::register_iphone_driver();
+ DisplayServerIOS::register_ios_driver();
}
-OSIPhone::~OSIPhone() {}
+OS_IOS::~OS_IOS() {}
-void OSIPhone::alert(const String &p_alert, const String &p_title) {
+void OS_IOS::alert(const String &p_alert, const String &p_title) {
const CharString utf8_alert = p_alert.utf8();
const CharString utf8_title = p_title.utf8();
iOS::alert(utf8_alert.get_data(), utf8_title.get_data());
}
-void OSIPhone::initialize_core() {
+void OS_IOS::initialize_core() {
OS_Unix::initialize_core();
set_user_data_dir(user_data_dir);
}
-void OSIPhone::initialize() {
+void OS_IOS::initialize() {
initialize_core();
}
-void OSIPhone::initialize_modules() {
+void OS_IOS::initialize_modules() {
ios = memnew(iOS);
Engine::get_singleton()->add_singleton(Engine::Singleton("iOS", ios));
- joypad_iphone = memnew(JoypadIPhone);
+ joypad_ios = memnew(JoypadIOS);
}
-void OSIPhone::deinitialize_modules() {
- if (joypad_iphone) {
- memdelete(joypad_iphone);
+void OS_IOS::deinitialize_modules() {
+ if (joypad_ios) {
+ memdelete(joypad_ios);
}
if (ios) {
@@ -154,7 +154,7 @@ void OSIPhone::deinitialize_modules() {
}
}
-void OSIPhone::set_main_loop(MainLoop *p_main_loop) {
+void OS_IOS::set_main_loop(MainLoop *p_main_loop) {
main_loop = p_main_loop;
if (main_loop) {
@@ -162,11 +162,11 @@ void OSIPhone::set_main_loop(MainLoop *p_main_loop) {
}
}
-MainLoop *OSIPhone::get_main_loop() const {
+MainLoop *OS_IOS::get_main_loop() const {
return main_loop;
}
-void OSIPhone::delete_main_loop() {
+void OS_IOS::delete_main_loop() {
if (main_loop) {
main_loop->finalize();
memdelete(main_loop);
@@ -175,7 +175,7 @@ void OSIPhone::delete_main_loop() {
main_loop = nullptr;
}
-bool OSIPhone::iterate() {
+bool OS_IOS::iterate() {
if (!main_loop) {
return true;
}
@@ -187,15 +187,15 @@ bool OSIPhone::iterate() {
return Main::iteration();
}
-void OSIPhone::start() {
+void OS_IOS::start() {
Main::start();
- if (joypad_iphone) {
- joypad_iphone->start_processing();
+ if (joypad_ios) {
+ joypad_ios->start_processing();
}
}
-void OSIPhone::finalize() {
+void OS_IOS::finalize() {
deinitialize_modules();
// Already gets called
@@ -204,7 +204,7 @@ void OSIPhone::finalize() {
// MARK: Dynamic Libraries
-Error OSIPhone::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path, String *r_resolved_path) {
+Error OS_IOS::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path, String *r_resolved_path) {
if (p_path.length() == 0) {
p_library_handle = RTLD_SELF;
@@ -217,16 +217,16 @@ Error OSIPhone::open_dynamic_library(const String p_path, void *&p_library_handl
return OS_Unix::open_dynamic_library(p_path, p_library_handle, p_also_set_library_path, r_resolved_path);
}
-Error OSIPhone::close_dynamic_library(void *p_library_handle) {
+Error OS_IOS::close_dynamic_library(void *p_library_handle) {
if (p_library_handle == RTLD_SELF) {
return OK;
}
return OS_Unix::close_dynamic_library(p_library_handle);
}
-Error OSIPhone::get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional) {
+Error OS_IOS::get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional) {
if (p_library_handle == RTLD_SELF) {
- void **ptr = OSIPhone::dynamic_symbol_lookup_table.getptr(p_name);
+ void **ptr = OS_IOS::dynamic_symbol_lookup_table.getptr(p_name);
if (ptr) {
p_symbol_handle = *ptr;
return OK;
@@ -235,11 +235,11 @@ Error OSIPhone::get_dynamic_library_symbol_handle(void *p_library_handle, const
return OS_Unix::get_dynamic_library_symbol_handle(p_library_handle, p_name, p_symbol_handle, p_optional);
}
-String OSIPhone::get_name() const {
+String OS_IOS::get_name() const {
return "iOS";
}
-String OSIPhone::get_model_name() const {
+String OS_IOS::get_model_name() const {
String model = ios->get_model();
if (model != "") {
return model;
@@ -248,7 +248,7 @@ String OSIPhone::get_model_name() const {
return OS_Unix::get_model_name();
}
-Error OSIPhone::shell_open(String p_uri) {
+Error OS_IOS::shell_open(String p_uri) {
NSString *urlPath = [[NSString alloc] initWithUTF8String:p_uri.utf8().get_data()];
NSURL *url = [NSURL URLWithString:urlPath];
@@ -263,21 +263,21 @@ Error OSIPhone::shell_open(String p_uri) {
return OK;
}
-void OSIPhone::set_user_data_dir(String p_dir) {
+void OS_IOS::set_user_data_dir(String p_dir) {
Ref<DirAccess> da = DirAccess::open(p_dir);
user_data_dir = da->get_current_dir();
printf("setting data dir to %s from %s\n", user_data_dir.utf8().get_data(), p_dir.utf8().get_data());
}
-String OSIPhone::get_user_data_dir() const {
+String OS_IOS::get_user_data_dir() const {
return user_data_dir;
}
-String OSIPhone::get_cache_path() const {
+String OS_IOS::get_cache_path() const {
return cache_dir;
}
-String OSIPhone::get_locale() const {
+String OS_IOS::get_locale() const {
NSString *preferedLanguage = [NSLocale preferredLanguages].firstObject;
if (preferedLanguage) {
@@ -288,12 +288,12 @@ String OSIPhone::get_locale() const {
return String::utf8([localeIdentifier UTF8String]).replace("-", "_");
}
-String OSIPhone::get_unique_id() const {
+String OS_IOS::get_unique_id() const {
NSString *uuid = [UIDevice currentDevice].identifierForVendor.UUIDString;
return String::utf8([uuid UTF8String]);
}
-String OSIPhone::get_processor_name() const {
+String OS_IOS::get_processor_name() const {
char buffer[256];
size_t buffer_len = 256;
if (sysctlbyname("machdep.cpu.brand_string", &buffer, &buffer_len, NULL, 0) == 0) {
@@ -302,7 +302,7 @@ String OSIPhone::get_processor_name() const {
ERR_FAIL_V_MSG("", String("Couldn't get the CPU model name. Returning an empty string."));
}
-void OSIPhone::vibrate_handheld(int p_duration_ms) {
+void OS_IOS::vibrate_handheld(int p_duration_ms) {
if (ios->supports_haptic_engine()) {
ios->vibrate_haptic_engine((float)p_duration_ms / 1000.f);
} else {
@@ -311,16 +311,16 @@ void OSIPhone::vibrate_handheld(int p_duration_ms) {
}
}
-bool OSIPhone::_check_internal_feature_support(const String &p_feature) {
+bool OS_IOS::_check_internal_feature_support(const String &p_feature) {
return p_feature == "mobile";
}
-void OSIPhone::on_focus_out() {
+void OS_IOS::on_focus_out() {
if (is_focused) {
is_focused = false;
- if (DisplayServerIPhone::get_singleton()) {
- DisplayServerIPhone::get_singleton()->send_window_event(DisplayServer::WINDOW_EVENT_FOCUS_OUT);
+ if (DisplayServerIOS::get_singleton()) {
+ DisplayServerIOS::get_singleton()->send_window_event(DisplayServer::WINDOW_EVENT_FOCUS_OUT);
}
[AppDelegate.viewController.godotView stopRendering];
@@ -329,12 +329,12 @@ void OSIPhone::on_focus_out() {
}
}
-void OSIPhone::on_focus_in() {
+void OS_IOS::on_focus_in() {
if (!is_focused) {
is_focused = true;
- if (DisplayServerIPhone::get_singleton()) {
- DisplayServerIPhone::get_singleton()->send_window_event(DisplayServer::WINDOW_EVENT_FOCUS_IN);
+ if (DisplayServerIOS::get_singleton()) {
+ DisplayServerIOS::get_singleton()->send_window_event(DisplayServer::WINDOW_EVENT_FOCUS_IN);
}
[AppDelegate.viewController.godotView startRendering];
@@ -343,4 +343,4 @@ void OSIPhone::on_focus_in() {
}
}
-#endif // IPHONE_ENABLED
+#endif // IOS_ENABLED
diff --git a/platform/iphone/platform_config.h b/platform/ios/platform_config.h
index fed77d8932..fed77d8932 100644
--- a/platform/iphone/platform_config.h
+++ b/platform/ios/platform_config.h
diff --git a/platform/iphone/tts_ios.h b/platform/ios/tts_ios.h
index 064316b0b2..064316b0b2 100644
--- a/platform/iphone/tts_ios.h
+++ b/platform/ios/tts_ios.h
diff --git a/platform/iphone/tts_ios.mm b/platform/ios/tts_ios.mm
index a079d02add..a079d02add 100644
--- a/platform/iphone/tts_ios.mm
+++ b/platform/ios/tts_ios.mm
diff --git a/platform/iphone/view_controller.h b/platform/ios/view_controller.h
index c8b37a4d11..c8b37a4d11 100644
--- a/platform/iphone/view_controller.h
+++ b/platform/ios/view_controller.h
diff --git a/platform/iphone/view_controller.mm b/platform/ios/view_controller.mm
index 4f4ef4f046..43669d3f94 100644
--- a/platform/iphone/view_controller.mm
+++ b/platform/ios/view_controller.mm
@@ -30,11 +30,11 @@
#import "view_controller.h"
#include "core/config/project_settings.h"
-#include "display_server_iphone.h"
+#include "display_server_ios.h"
#import "godot_view.h"
#import "godot_view_renderer.h"
#import "keyboard_input_view.h"
-#include "os_iphone.h"
+#include "os_ios.h"
#import <AVFoundation/AVFoundation.h>
#import <GameController/GameController.h>
@@ -168,11 +168,11 @@
}
- (BOOL)shouldAutorotate {
- if (!DisplayServerIPhone::get_singleton()) {
+ if (!DisplayServerIOS::get_singleton()) {
return NO;
}
- switch (DisplayServerIPhone::get_singleton()->screen_get_orientation(DisplayServer::SCREEN_OF_MAIN_WINDOW)) {
+ switch (DisplayServerIOS::get_singleton()->screen_get_orientation(DisplayServer::SCREEN_OF_MAIN_WINDOW)) {
case DisplayServer::SCREEN_SENSOR:
case DisplayServer::SCREEN_SENSOR_LANDSCAPE:
case DisplayServer::SCREEN_SENSOR_PORTRAIT:
@@ -183,11 +183,11 @@
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
- if (!DisplayServerIPhone::get_singleton()) {
+ if (!DisplayServerIOS::get_singleton()) {
return UIInterfaceOrientationMaskAll;
}
- switch (DisplayServerIPhone::get_singleton()->screen_get_orientation(DisplayServer::SCREEN_OF_MAIN_WINDOW)) {
+ switch (DisplayServerIOS::get_singleton()->screen_get_orientation(DisplayServer::SCREEN_OF_MAIN_WINDOW)) {
case DisplayServer::SCREEN_PORTRAIT:
return UIInterfaceOrientationMaskPortrait;
case DisplayServer::SCREEN_REVERSE_LANDSCAPE:
@@ -226,14 +226,14 @@
CGRect rawFrame = [value CGRectValue];
CGRect keyboardFrame = [self.view convertRect:rawFrame fromView:nil];
- if (DisplayServerIPhone::get_singleton()) {
- DisplayServerIPhone::get_singleton()->virtual_keyboard_set_height(keyboardFrame.size.height);
+ if (DisplayServerIOS::get_singleton()) {
+ DisplayServerIOS::get_singleton()->virtual_keyboard_set_height(keyboardFrame.size.height);
}
}
- (void)keyboardHidden:(NSNotification *)notification {
- if (DisplayServerIPhone::get_singleton()) {
- DisplayServerIPhone::get_singleton()->virtual_keyboard_set_height(0);
+ if (DisplayServerIOS::get_singleton()) {
+ DisplayServerIOS::get_singleton()->virtual_keyboard_set_height(0);
}
}
diff --git a/platform/iphone/vulkan_context_iphone.h b/platform/ios/vulkan_context_ios.h
index 7576525755..e9c09e087a 100644
--- a/platform/iphone/vulkan_context_iphone.h
+++ b/platform/ios/vulkan_context_ios.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* vulkan_context_iphone.h */
+/* vulkan_context_ios.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,21 +28,21 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef VULKAN_CONTEXT_IPHONE_H
-#define VULKAN_CONTEXT_IPHONE_H
+#ifndef VULKAN_CONTEXT_IOS_H
+#define VULKAN_CONTEXT_IOS_H
#include "drivers/vulkan/vulkan_context.h"
#import <UIKit/UIKit.h>
-class VulkanContextIPhone : public VulkanContext {
+class VulkanContextIOS : public VulkanContext {
virtual const char *_get_platform_surface_extension() const;
public:
Error window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, CALayer *p_metal_layer, int p_width, int p_height);
- VulkanContextIPhone();
- ~VulkanContextIPhone();
+ VulkanContextIOS();
+ ~VulkanContextIOS();
};
-#endif // VULKAN_CONTEXT_IPHONE_H
+#endif // VULKAN_CONTEXT_IOS_H
diff --git a/platform/iphone/vulkan_context_iphone.mm b/platform/ios/vulkan_context_ios.mm
index 17cb0f6009..09cd369aa5 100644
--- a/platform/iphone/vulkan_context_iphone.mm
+++ b/platform/ios/vulkan_context_ios.mm
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* vulkan_context_iphone.mm */
+/* vulkan_context_ios.mm */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,18 +28,18 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "vulkan_context_iphone.h"
+#include "vulkan_context_ios.h"
#ifdef USE_VOLK
#include <volk.h>
#else
#include <vulkan/vulkan.h>
#endif
-const char *VulkanContextIPhone::_get_platform_surface_extension() const {
+const char *VulkanContextIOS::_get_platform_surface_extension() const {
return VK_MVK_IOS_SURFACE_EXTENSION_NAME;
}
-Error VulkanContextIPhone::window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, CALayer *p_metal_layer, int p_width, int p_height) {
+Error VulkanContextIOS::window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, CALayer *p_metal_layer, int p_width, int p_height) {
VkIOSSurfaceCreateInfoMVK createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK;
createInfo.pNext = nullptr;
@@ -54,6 +54,6 @@ Error VulkanContextIPhone::window_create(DisplayServer::WindowID p_window_id, Di
return _window_create(p_window_id, p_vsync_mode, surface, p_width, p_height);
}
-VulkanContextIPhone::VulkanContextIPhone() {}
+VulkanContextIOS::VulkanContextIOS() {}
-VulkanContextIPhone::~VulkanContextIPhone() {}
+VulkanContextIOS::~VulkanContextIOS() {}
diff --git a/platform/javascript/audio_driver_javascript.h b/platform/javascript/audio_driver_javascript.h
index b7b0b3ac96..807e2f936b 100644
--- a/platform/javascript/audio_driver_javascript.h
+++ b/platform/javascript/audio_driver_javascript.h
@@ -158,4 +158,4 @@ public:
};
#endif
-#endif
+#endif // AUDIO_DRIVER_JAVASCRIPT_H
diff --git a/platform/javascript/display_server_javascript.cpp b/platform/javascript/display_server_javascript.cpp
index a96c539a1f..4edd6c793a 100644
--- a/platform/javascript/display_server_javascript.cpp
+++ b/platform/javascript/display_server_javascript.cpp
@@ -236,7 +236,7 @@ void DisplayServerJavaScript::mouse_move_callback(double p_x, double p_y, double
const char *DisplayServerJavaScript::godot2dom_cursor(DisplayServer::CursorShape p_shape) {
switch (p_shape) {
case DisplayServer::CURSOR_ARROW:
- return "auto";
+ return "default";
case DisplayServer::CURSOR_IBEAM:
return "text";
case DisplayServer::CURSOR_POINTING_HAND:
@@ -270,7 +270,7 @@ const char *DisplayServerJavaScript::godot2dom_cursor(DisplayServer::CursorShape
case DisplayServer::CURSOR_HELP:
return "help";
default:
- return "auto";
+ return "default";
}
}
diff --git a/platform/javascript/export/export.h b/platform/javascript/export/export.h
index 41cc66cfb8..29c335ed0e 100644
--- a/platform/javascript/export/export.h
+++ b/platform/javascript/export/export.h
@@ -33,4 +33,4 @@
void register_javascript_exporter();
-#endif
+#endif // JAVASCRIPT_EXPORT_H
diff --git a/platform/javascript/export/export_plugin.cpp b/platform/javascript/export/export_plugin.cpp
index 901580c140..e2ae45627e 100644
--- a/platform/javascript/export/export_plugin.cpp
+++ b/platform/javascript/export/export_plugin.cpp
@@ -661,13 +661,8 @@ EditorExportPlatformJavaScript::EditorExportPlatformJavaScript() {
server.instantiate();
server_thread.start(_server_thread_poll, this);
- Ref<Image> img = memnew(Image(_javascript_logo));
- logo.instantiate();
- logo->create_from_image(img);
-
- img = Ref<Image>(memnew(Image(_javascript_run_icon)));
- run_icon.instantiate();
- run_icon->create_from_image(img);
+ logo = ImageTexture::create_from_image(memnew(Image(_javascript_logo)));
+ run_icon = ImageTexture::create_from_image(memnew(Image(_javascript_run_icon)));
Ref<Theme> theme = EditorNode::get_singleton()->get_editor_theme();
if (theme.is_valid()) {
diff --git a/platform/javascript/export/export_plugin.h b/platform/javascript/export/export_plugin.h
index 1aaec5454d..e6ca5976df 100644
--- a/platform/javascript/export/export_plugin.h
+++ b/platform/javascript/export/export_plugin.h
@@ -36,8 +36,8 @@
#include "core/io/stream_peer_ssl.h"
#include "core/io/tcp_server.h"
#include "core/io/zip_io.h"
-#include "editor/editor_export.h"
#include "editor/editor_node.h"
+#include "editor/export/editor_export_platform.h"
#include "main/splash.gen.h"
#include "platform/javascript/logo.gen.h"
#include "platform/javascript/run_icon.gen.h"
@@ -144,4 +144,4 @@ public:
~EditorExportPlatformJavaScript();
};
-#endif
+#endif // JAVASCRIPT_EXPORT_PLUGIN_H
diff --git a/platform/javascript/export/export_server.h b/platform/javascript/export/export_server.h
index a831b76076..ddbe3cca30 100644
--- a/platform/javascript/export/export_server.h
+++ b/platform/javascript/export/export_server.h
@@ -35,7 +35,6 @@
#include "core/io/stream_peer_ssl.h"
#include "core/io/tcp_server.h"
#include "core/io/zip_io.h"
-#include "editor/editor_export.h"
#include "editor/editor_paths.h"
class EditorHTTPServer : public RefCounted {
@@ -248,4 +247,4 @@ public:
}
};
-#endif
+#endif // JAVASCRIPT_EXPORT_SERVER_H
diff --git a/platform/javascript/godot_audio.h b/platform/javascript/godot_audio.h
index 012f8daeb7..3855b7301e 100644
--- a/platform/javascript/godot_audio.h
+++ b/platform/javascript/godot_audio.h
@@ -63,4 +63,4 @@ extern void godot_audio_script_start(float *p_in_buf, int p_in_size, float *p_ou
}
#endif
-#endif /* GODOT_AUDIO_H */
+#endif // GODOT_AUDIO_H
diff --git a/platform/javascript/godot_js.h b/platform/javascript/godot_js.h
index 1a383c9799..567b491336 100644
--- a/platform/javascript/godot_js.h
+++ b/platform/javascript/godot_js.h
@@ -127,4 +127,4 @@ extern void godot_js_display_vk_hide();
}
#endif
-#endif /* GODOT_JS_H */
+#endif // GODOT_JS_H
diff --git a/platform/javascript/godot_webgl2.h b/platform/javascript/godot_webgl2.h
index 7c357ff66d..968b70f84b 100644
--- a/platform/javascript/godot_webgl2.h
+++ b/platform/javascript/godot_webgl2.h
@@ -34,4 +34,4 @@
#include "GLES3/gl3.h"
#include "webgl/webgl2.h"
-#endif
+#endif // GODOT_WEBGL2_H
diff --git a/platform/javascript/http_client_javascript.h b/platform/javascript/http_client_javascript.h
index 096aa6a153..fcd225ffc9 100644
--- a/platform/javascript/http_client_javascript.h
+++ b/platform/javascript/http_client_javascript.h
@@ -105,4 +105,5 @@ public:
HTTPClientJavaScript();
~HTTPClientJavaScript();
};
+
#endif // HTTP_CLIENT_JAVASCRIPT_H
diff --git a/platform/javascript/js/engine/config.js b/platform/javascript/js/engine/config.js
index 2e5e1ed0d1..9c4b6c2012 100644
--- a/platform/javascript/js/engine/config.js
+++ b/platform/javascript/js/engine/config.js
@@ -334,6 +334,7 @@ const InternalConfig = function (initConfig) { // eslint-disable-line no-unused-
locale = navigator.languages ? navigator.languages[0] : navigator.language;
locale = locale.split('.')[0];
}
+ locale = locale.replace('-', '_');
const onExit = this.onExit;
// Godot configuration.
diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h
index 0c672111cc..6900a34ee3 100644
--- a/platform/javascript/os_javascript.h
+++ b/platform/javascript/os_javascript.h
@@ -107,4 +107,4 @@ public:
OS_JavaScript();
};
-#endif
+#endif // OS_JAVASCRIPT_H
diff --git a/platform/linuxbsd/SCsub b/platform/linuxbsd/SCsub
index 09a432eae2..636a3c7db2 100644
--- a/platform/linuxbsd/SCsub
+++ b/platform/linuxbsd/SCsub
@@ -12,7 +12,7 @@ common_linuxbsd = [
"freedesktop_screensaver.cpp",
]
-if "x11" in env and env["x11"]:
+if env["x11"]:
common_linuxbsd += [
"gl_manager_x11.cpp",
"detect_prime_x11.cpp",
@@ -20,13 +20,13 @@ if "x11" in env and env["x11"]:
"key_mapping_x11.cpp",
]
-if "speechd" in env and env["speechd"]:
- common_linuxbsd.append(["speechd-so_wrap.c", "tts_linux.cpp"])
+ if env["vulkan"]:
+ common_linuxbsd.append("vulkan_context_x11.cpp")
-if "vulkan" in env and env["vulkan"]:
- common_linuxbsd.append("vulkan_context_x11.cpp")
+if env["speechd"]:
+ common_linuxbsd.append(["speechd-so_wrap.c", "tts_linux.cpp"])
-if "udev" in env and env["udev"]:
+if env["udev"]:
common_linuxbsd.append("libudev-so_wrap.c")
prog = env.add_program("#bin/godot", ["godot_linuxbsd.cpp"] + common_linuxbsd)
diff --git a/platform/linuxbsd/crash_handler_linuxbsd.h b/platform/linuxbsd/crash_handler_linuxbsd.h
index 2e44476c3f..1b77352cca 100644
--- a/platform/linuxbsd/crash_handler_linuxbsd.h
+++ b/platform/linuxbsd/crash_handler_linuxbsd.h
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef CRASH_HANDLER_X11_H
-#define CRASH_HANDLER_X11_H
+#ifndef CRASH_HANDLER_LINUXBSD_H
+#define CRASH_HANDLER_LINUXBSD_H
class CrashHandler {
bool disabled;
@@ -44,4 +44,4 @@ public:
~CrashHandler();
};
-#endif // CRASH_HANDLER_X11_H
+#endif // CRASH_HANDLER_LINUXBSD_H
diff --git a/platform/linuxbsd/detect.py b/platform/linuxbsd/detect.py
index 19cf341c85..065250c40e 100644
--- a/platform/linuxbsd/detect.py
+++ b/platform/linuxbsd/detect.py
@@ -1,6 +1,7 @@
import os
import platform
import sys
+from methods import get_compiler_version, using_gcc
def is_active():
@@ -15,47 +16,11 @@ def can_build():
if os.name != "posix" or sys.platform == "darwin":
return False
- # Check the minimal dependencies
- x11_error = os.system("pkg-config --version > /dev/null")
- if x11_error:
+ pkgconf_error = os.system("pkg-config --version > /dev/null")
+ if pkgconf_error:
print("Error: pkg-config not found. Aborting.")
return False
- x11_error = os.system("pkg-config x11 --modversion > /dev/null")
- if x11_error:
- print("Error: X11 libraries not found. Aborting.")
- return False
-
- x11_error = os.system("pkg-config xcursor --modversion > /dev/null")
- if x11_error:
- print("Error: Xcursor library not found. Aborting.")
- return False
-
- x11_error = os.system("pkg-config xinerama --modversion > /dev/null")
- if x11_error:
- print("Error: Xinerama library not found. Aborting.")
- return False
-
- x11_error = os.system("pkg-config xext --modversion > /dev/null")
- if x11_error:
- print("Error: Xext library not found. Aborting.")
- return False
-
- x11_error = os.system("pkg-config xrandr --modversion > /dev/null")
- if x11_error:
- print("Error: XrandR library not found. Aborting.")
- return False
-
- x11_error = os.system("pkg-config xrender --modversion > /dev/null")
- if x11_error:
- print("Error: XRender library not found. Aborting.")
- return False
-
- x11_error = os.system("pkg-config xi --modversion > /dev/null")
- if x11_error:
- print("Error: Xi library not found. Aborting.")
- return False
-
return True
@@ -63,9 +28,9 @@ def get_opts():
from SCons.Variables import BoolVariable, EnumVariable
return [
+ EnumVariable("linker", "Linker program", "default", ("default", "bfd", "gold", "lld", "mold")),
BoolVariable("use_llvm", "Use the LLVM compiler", False),
- BoolVariable("use_lld", "Use the LLD linker", False),
- BoolVariable("use_thinlto", "Use ThinLTO", False),
+ BoolVariable("use_thinlto", "Use ThinLTO (LLVM only, requires linker=lld, implies use_lto=yes)", 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),
@@ -147,15 +112,32 @@ def configure(env):
env["CXX"] = "clang++"
env.extra_suffix = ".llvm" + env.extra_suffix
- if env["use_lld"]:
- if env["use_llvm"]:
- env.Append(LINKFLAGS=["-fuse-ld=lld"])
- if env["use_thinlto"]:
- # A convenience so you don't need to write use_lto too when using SCons
- env["use_lto"] = True
+ if env["linker"] != "default":
+ print("Using linker program: " + env["linker"])
+ if env["linker"] == "mold" and using_gcc(env): # GCC < 12.1 doesn't support -fuse-ld=mold.
+ cc_version = get_compiler_version(env)
+ cc_semver = (int(cc_version["major"]), int(cc_version["minor"]))
+ if cc_semver < (12, 1):
+ found_wrapper = False
+ for path in ["/usr/libexec", "/usr/local/libexec", "/usr/lib", "/usr/local/lib"]:
+ if os.path.isfile(path + "/mold/ld"):
+ env.Append(LINKFLAGS=["-B" + path + "/mold"])
+ found_wrapper = True
+ break
+ if not found_wrapper:
+ print("Couldn't locate mold installation path. Make sure it's installed in /usr or /usr/local.")
+ sys.exit(255)
+ else:
+ env.Append(LINKFLAGS=["-fuse-ld=mold"])
else:
- print("Using LLD with GCC is not supported yet. Try compiling with 'use_llvm=yes'.")
+ env.Append(LINKFLAGS=["-fuse-ld=%s" % env["linker"]])
+
+ if env["use_thinlto"]:
+ if not env["use_llvm"] or env["linker"] != "lld":
+ print("ThinLTO is only compatible with LLVM and the LLD linker, use `use_llvm=yes linker=lld`.")
sys.exit(255)
+ else:
+ env["use_lto"] = True # ThinLTO implies LTO
if env["use_coverage"]:
env.Append(CCFLAGS=["-ftest-coverage", "-fprofile-arcs"])
@@ -200,33 +182,32 @@ def configure(env):
env.Append(LINKFLAGS=["-fsanitize=memory"])
if env["use_lto"]:
- if not env["use_llvm"] and env.GetOption("num_jobs") > 1:
+ if env["use_thinlto"]:
+ env.Append(CCFLAGS=["-flto=thin"])
+ env.Append(LINKFLAGS=["-flto=thin"])
+ elif not env["use_llvm"] and env.GetOption("num_jobs") > 1:
env.Append(CCFLAGS=["-flto"])
env.Append(LINKFLAGS=["-flto=" + str(env.GetOption("num_jobs"))])
else:
- if env["use_lld"] and env["use_thinlto"]:
- env.Append(CCFLAGS=["-flto=thin"])
- env.Append(LINKFLAGS=["-flto=thin"])
- else:
- env.Append(CCFLAGS=["-flto"])
- env.Append(LINKFLAGS=["-flto"])
+ env.Append(CCFLAGS=["-flto"])
+ env.Append(LINKFLAGS=["-flto"])
if not env["use_llvm"]:
env["RANLIB"] = "gcc-ranlib"
env["AR"] = "gcc-ar"
env.Append(CCFLAGS=["-pipe"])
- env.Append(LINKFLAGS=["-pipe"])
## Dependencies
- env.ParseConfig("pkg-config x11 --cflags --libs")
- env.ParseConfig("pkg-config xcursor --cflags --libs")
- env.ParseConfig("pkg-config xinerama --cflags --libs")
- env.ParseConfig("pkg-config xext --cflags --libs")
- env.ParseConfig("pkg-config xrandr --cflags --libs")
- env.ParseConfig("pkg-config xrender --cflags --libs")
- env.ParseConfig("pkg-config xi --cflags --libs")
+ if env["x11"]:
+ env.ParseConfig("pkg-config x11 --cflags --libs")
+ env.ParseConfig("pkg-config xcursor --cflags --libs")
+ env.ParseConfig("pkg-config xinerama --cflags --libs")
+ env.ParseConfig("pkg-config xext --cflags --libs")
+ env.ParseConfig("pkg-config xrandr --cflags --libs")
+ env.ParseConfig("pkg-config xrender --cflags --libs")
+ env.ParseConfig("pkg-config xi --cflags --libs")
if env["touch"]:
env.Append(CPPDEFINES=["TOUCH_ENABLED"])
@@ -382,8 +363,9 @@ def configure(env):
# No pkgconfig file so far, hardcode expected lib name.
env.Append(LIBS=["glslang", "SPIRV"])
- env.Append(CPPDEFINES=["GLES3_ENABLED"])
- env.ParseConfig("pkg-config gl --cflags --libs")
+ if env["opengl3"]:
+ env.Append(CPPDEFINES=["GLES3_ENABLED"])
+ env.ParseConfig("pkg-config gl --cflags --libs")
env.Append(LIBS=["pthread"])
diff --git a/platform/linuxbsd/detect_prime_x11.h b/platform/linuxbsd/detect_prime_x11.h
index e60f9ebfdf..21ebaead32 100644
--- a/platform/linuxbsd/detect_prime_x11.h
+++ b/platform/linuxbsd/detect_prime_x11.h
@@ -34,4 +34,5 @@
int detect_prime();
#endif
-#endif
+
+#endif // DETECT_PRIME_X11_H
diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp
index 4aec111022..d4267d3c02 100644
--- a/platform/linuxbsd/display_server_x11.cpp
+++ b/platform/linuxbsd/display_server_x11.cpp
@@ -196,6 +196,7 @@ bool DisplayServerX11::_refresh_device_info() {
xi.absolute_devices.clear();
xi.touch_devices.clear();
+ xi.pen_inverted_devices.clear();
int dev_count;
XIDeviceInfo *info = XIQueryDevice(x11_display, XIAllDevices, &dev_count);
@@ -205,7 +206,7 @@ bool DisplayServerX11::_refresh_device_info() {
if (!dev->enabled) {
continue;
}
- if (!(dev->use == XIMasterPointer || dev->use == XIFloatingSlave)) {
+ if (!(dev->use == XISlavePointer || dev->use == XIFloatingSlave)) {
continue;
}
@@ -274,6 +275,7 @@ bool DisplayServerX11::_refresh_device_info() {
xi.pen_pressure_range[dev->deviceid] = Vector2(pressure_min, pressure_max);
xi.pen_tilt_x_range[dev->deviceid] = Vector2(tilt_x_min, tilt_x_max);
xi.pen_tilt_y_range[dev->deviceid] = Vector2(tilt_y_min, tilt_y_max);
+ xi.pen_inverted_devices[dev->deviceid] = String(dev->name).findn("eraser") > 0;
}
XIFreeDeviceInfo(info);
@@ -1487,8 +1489,8 @@ void DisplayServerX11::window_set_current_screen(int p_screen, WindowID p_window
XMoveResizeWindow(x11_display, wd.x11_window, position.x, position.y, size.x, size.y);
} else {
if (p_screen != window_get_current_screen(p_window)) {
- Point2i position = screen_get_position(p_screen);
- XMoveWindow(x11_display, wd.x11_window, position.x, position.y);
+ Vector2 ofs = window_get_position(p_window) - screen_get_position(window_get_current_screen(p_window));
+ window_set_position(ofs + screen_get_position(p_screen), p_window);
}
}
}
@@ -1817,6 +1819,52 @@ bool DisplayServerX11::_window_maximize_check(WindowID p_window, const char *p_a
return retval;
}
+bool DisplayServerX11::_window_fullscreen_check(WindowID p_window) const {
+ ERR_FAIL_COND_V(!windows.has(p_window), false);
+ const WindowData &wd = windows[p_window];
+
+ // Using EWMH -- Extended Window Manager Hints
+ Atom property = XInternAtom(x11_display, "_NET_WM_STATE", False);
+ Atom type;
+ int format;
+ unsigned long len;
+ unsigned long remaining;
+ unsigned char *data = nullptr;
+ bool retval = false;
+
+ if (property == None) {
+ return retval;
+ }
+
+ int result = XGetWindowProperty(
+ x11_display,
+ wd.x11_window,
+ property,
+ 0,
+ 1024,
+ False,
+ XA_ATOM,
+ &type,
+ &format,
+ &len,
+ &remaining,
+ &data);
+
+ if (result == Success) {
+ Atom *atoms = (Atom *)data;
+ Atom wm_fullscreen = XInternAtom(x11_display, "_NET_WM_STATE_FULLSCREEN", False);
+ for (uint64_t i = 0; i < len; i++) {
+ if (atoms[i] == wm_fullscreen) {
+ retval = true;
+ break;
+ }
+ }
+ XFree(data);
+ }
+
+ return retval;
+}
+
bool DisplayServerX11::window_is_maximize_allowed(WindowID p_window) const {
_THREAD_SAFE_METHOD_
return _window_maximize_check(p_window, "_NET_WM_ALLOWED_ACTIONS");
@@ -3438,7 +3486,7 @@ void DisplayServerX11::process_events() {
} break;
case XI_RawMotion: {
XIRawEvent *raw_event = (XIRawEvent *)event_data;
- int device_id = raw_event->deviceid;
+ int device_id = raw_event->sourceid;
// Determine the axis used (called valuators in XInput for some forsaken reason)
// Mask is a bitmask indicating which axes are involved.
@@ -3504,6 +3552,11 @@ void DisplayServerX11::process_events() {
values++;
}
+ HashMap<int, bool>::Iterator pen_inverted = xi.pen_inverted_devices.find(device_id);
+ if (pen_inverted) {
+ xi.pen_inverted = pen_inverted->value;
+ }
+
// https://bugs.freedesktop.org/show_bug.cgi?id=71609
// http://lists.libsdl.org/pipermail/commits-libsdl.org/2015-June/000282.html
if (raw_event->time == xi.last_relative_time && rel_x == xi.relative_motion.x && rel_y == xi.relative_motion.y) {
@@ -3604,6 +3657,8 @@ void DisplayServerX11::process_events() {
case Expose: {
DEBUG_LOG_X11("[%u] Expose window=%lu (%u), count='%u' \n", frame, event.xexpose.window, window_id, event.xexpose.count);
+ windows[window_id].fullscreen = _window_fullscreen_check(window_id);
+
Main::force_redraw();
} break;
@@ -3936,6 +3991,7 @@ void DisplayServerX11::process_events() {
mm->set_pressure(bool(mouse_get_button_state() & MouseButton::MASK_LEFT) ? 1.0f : 0.0f);
}
mm->set_tilt(xi.tilt);
+ mm->set_pen_inverted(xi.pen_inverted);
_get_key_modifier_state(event.xmotion.state, mm);
mm->set_button_mask((MouseButton)mouse_get_button_state());
@@ -4119,13 +4175,17 @@ void DisplayServerX11::process_events() {
void DisplayServerX11::release_rendering_thread() {
#if defined(GLES3_ENABLED)
- gl_manager->release_current();
+ if (gl_manager) {
+ gl_manager->release_current();
+ }
#endif
}
void DisplayServerX11::make_rendering_thread() {
#if defined(GLES3_ENABLED)
- gl_manager->make_current();
+ if (gl_manager) {
+ gl_manager->make_current();
+ }
#endif
}
diff --git a/platform/linuxbsd/display_server_x11.h b/platform/linuxbsd/display_server_x11.h
index 4beeddd3a8..9ce6a557db 100644
--- a/platform/linuxbsd/display_server_x11.h
+++ b/platform/linuxbsd/display_server_x11.h
@@ -201,10 +201,12 @@ class DisplayServerX11 : public DisplayServer {
HashMap<int, Vector2> pen_pressure_range;
HashMap<int, Vector2> pen_tilt_x_range;
HashMap<int, Vector2> pen_tilt_y_range;
+ HashMap<int, bool> pen_inverted_devices;
XIEventMask all_event_mask;
HashMap<int, Vector2> state;
double pressure;
bool pressure_supported;
+ bool pen_inverted;
Vector2 tilt;
Vector2 mouse_pos_to_filter;
Vector2 relative_motion;
@@ -265,6 +267,7 @@ class DisplayServerX11 : public DisplayServer {
void _update_real_mouse_position(const WindowData &wd);
bool _window_maximize_check(WindowID p_window, const char *p_atom_name) const;
+ bool _window_fullscreen_check(WindowID p_window) const;
void _update_size_hints(WindowID p_window);
void _set_wm_fullscreen(WindowID p_window, bool p_enabled);
void _set_wm_maximized(WindowID p_window, bool p_enabled);
diff --git a/platform/linuxbsd/export/export.cpp b/platform/linuxbsd/export/export.cpp
index 965b969ba8..bc1235bcec 100644
--- a/platform/linuxbsd/export/export.cpp
+++ b/platform/linuxbsd/export/export.cpp
@@ -30,17 +30,13 @@
#include "export.h"
+#include "editor/export/editor_export.h"
#include "export_plugin.h"
void register_linuxbsd_exporter() {
Ref<EditorExportPlatformLinuxBSD> platform;
platform.instantiate();
-
- Ref<Image> img = memnew(Image(_linuxbsd_logo));
- Ref<ImageTexture> logo;
- logo.instantiate();
- logo->create_from_image(img);
- platform->set_logo(logo);
+ platform->set_logo(ImageTexture::create_from_image(memnew(Image(_linuxbsd_logo))));
platform->set_name("Linux/X11");
platform->set_extension("x86_32");
platform->set_extension("x86_64", "binary_format/64_bits");
diff --git a/platform/linuxbsd/export/export_plugin.cpp b/platform/linuxbsd/export/export_plugin.cpp
index 4e14920e79..d54e07d8a5 100644
--- a/platform/linuxbsd/export/export_plugin.cpp
+++ b/platform/linuxbsd/export/export_plugin.cpp
@@ -84,7 +84,7 @@ void EditorExportPlatformLinuxBSD::set_extension(const String &p_extension, cons
}
String EditorExportPlatformLinuxBSD::get_template_file_name(const String &p_target, const String &p_arch) const {
- return "linux_x11_" + p_arch + "_" + p_target;
+ return "linux_" + p_target + "." + p_arch;
}
List<String> EditorExportPlatformLinuxBSD::get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const {
diff --git a/platform/linuxbsd/export/export_plugin.h b/platform/linuxbsd/export/export_plugin.h
index e04bcc20f9..98e4616035 100644
--- a/platform/linuxbsd/export/export_plugin.h
+++ b/platform/linuxbsd/export/export_plugin.h
@@ -32,8 +32,8 @@
#define LINUXBSD_EXPORT_PLUGIN_H
#include "core/io/file_access.h"
-#include "editor/editor_export.h"
#include "editor/editor_settings.h"
+#include "editor/export/editor_export_platform_pc.h"
#include "platform/linuxbsd/logo.gen.h"
#include "scene/resources/texture.h"
@@ -49,4 +49,4 @@ public:
virtual Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size) override;
};
-#endif
+#endif // LINUXBSD_EXPORT_PLUGIN_H
diff --git a/platform/linuxbsd/freedesktop_screensaver.h b/platform/linuxbsd/freedesktop_screensaver.h
index b2303791bd..1b632b9103 100644
--- a/platform/linuxbsd/freedesktop_screensaver.h
+++ b/platform/linuxbsd/freedesktop_screensaver.h
@@ -28,6 +28,9 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef FREEDESKTOP_SCREENSAVER_H
+#define FREEDESKTOP_SCREENSAVER_H
+
#ifdef DBUS_ENABLED
#include <dbus/dbus.h>
@@ -45,3 +48,5 @@ public:
};
#endif // DBUS_ENABLED
+
+#endif // FREEDESKTOP_SCREENSAVER_H
diff --git a/platform/linuxbsd/godot_linuxbsd.cpp b/platform/linuxbsd/godot_linuxbsd.cpp
index 9fe00568fb..91a260182e 100644
--- a/platform/linuxbsd/godot_linuxbsd.cpp
+++ b/platform/linuxbsd/godot_linuxbsd.cpp
@@ -61,6 +61,10 @@ int main(int argc, char *argv[]) {
Error err = Main::setup(argv[0], argc - 1, &argv[1]);
if (err != OK) {
free(cwd);
+
+ if (err == ERR_HELP) { // Returned by --help and --version, so success.
+ return 0;
+ }
return 255;
}
diff --git a/platform/linuxbsd/os_linuxbsd.h b/platform/linuxbsd/os_linuxbsd.h
index 3f97b86eae..13c07842fb 100644
--- a/platform/linuxbsd/os_linuxbsd.h
+++ b/platform/linuxbsd/os_linuxbsd.h
@@ -105,4 +105,4 @@ public:
OS_LinuxBSD();
};
-#endif
+#endif // OS_LINUXBSD_H
diff --git a/platform/linuxbsd/vulkan_context_x11.h b/platform/linuxbsd/vulkan_context_x11.h
index a89afa2eff..0c4a6cd278 100644
--- a/platform/linuxbsd/vulkan_context_x11.h
+++ b/platform/linuxbsd/vulkan_context_x11.h
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef VULKAN_DEVICE_X11_H
-#define VULKAN_DEVICE_X11_H
+#ifndef VULKAN_CONTEXT_X11_H
+#define VULKAN_CONTEXT_X11_H
#include "drivers/vulkan/vulkan_context.h"
#include <X11/Xlib.h>
@@ -44,4 +44,4 @@ public:
~VulkanContextX11();
};
-#endif // VULKAN_DEVICE_X11_H
+#endif // VULKAN_CONTEXT_X11_H
diff --git a/platform/macos/SCsub b/platform/macos/SCsub
new file mode 100644
index 0000000000..d0856c709a
--- /dev/null
+++ b/platform/macos/SCsub
@@ -0,0 +1,30 @@
+#!/usr/bin/env python
+
+Import("env")
+
+from platform_methods import run_in_subprocess
+import platform_macos_builders
+
+files = [
+ "os_macos.mm",
+ "godot_application.mm",
+ "godot_application_delegate.mm",
+ "crash_handler_macos.mm",
+ "macos_terminal_logger.mm",
+ "display_server_macos.mm",
+ "godot_content_view.mm",
+ "godot_window_delegate.mm",
+ "godot_window.mm",
+ "key_mapping_macos.mm",
+ "godot_main_macos.mm",
+ "dir_access_macos.mm",
+ "tts_macos.mm",
+ "joypad_macos.cpp",
+ "vulkan_context_macos.mm",
+ "gl_manager_macos_legacy.mm",
+]
+
+prog = env.add_program("#bin/godot", files)
+
+if env["debug_symbols"] and env["separate_debug_symbols"]:
+ env.AddPostAction(prog, run_in_subprocess(platform_macos_builders.make_debug_macos))
diff --git a/platform/osx/crash_handler_osx.h b/platform/macos/crash_handler_macos.h
index 72938e5e0a..c9b0e77dc4 100644
--- a/platform/osx/crash_handler_osx.h
+++ b/platform/macos/crash_handler_macos.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* crash_handler_osx.h */
+/* crash_handler_macos.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef CRASH_HANDLER_OSX_H
-#define CRASH_HANDLER_OSX_H
+#ifndef CRASH_HANDLER_MACOS_H
+#define CRASH_HANDLER_MACOS_H
class CrashHandler {
bool disabled;
@@ -44,4 +44,4 @@ public:
~CrashHandler();
};
-#endif // CRASH_HANDLER_OSX_H
+#endif // CRASH_HANDLER_MACOS_H
diff --git a/platform/osx/crash_handler_osx.mm b/platform/macos/crash_handler_macos.mm
index a798ba3b46..74bd012f0c 100644
--- a/platform/osx/crash_handler_osx.mm
+++ b/platform/macos/crash_handler_macos.mm
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* crash_handler_osx.mm */
+/* crash_handler_macos.mm */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,7 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "crash_handler_osx.h"
+#include "crash_handler_macos.h"
#include "core/config/project_settings.h"
#include "core/os/os.h"
diff --git a/platform/osx/detect.py b/platform/macos/detect.py
index 8d848d2094..20e7afa772 100644
--- a/platform/osx/detect.py
+++ b/platform/macos/detect.py
@@ -8,7 +8,7 @@ def is_active():
def get_name():
- return "OSX"
+ return "macOS"
def can_build():
@@ -24,7 +24,7 @@ def get_opts():
return [
("osxcross_sdk", "OSXCross SDK version", "darwin16"),
("MACOS_SDK_PATH", "Path to the macOS SDK", ""),
- ("VULKAN_SDK_PATH", "Path to the Vulkan SDK", ""),
+ ("vulkan_sdk_path", "Path to the Vulkan SDK", ""),
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),
@@ -36,7 +36,38 @@ def get_opts():
def get_flags():
- return []
+ return [
+ ("use_volk", False),
+ ]
+
+
+def get_mvk_sdk_path():
+ def int_or_zero(i):
+ try:
+ return int(i)
+ except:
+ return 0
+
+ def ver_parse(a):
+ return [int_or_zero(i) for i in a.split(".")]
+
+ dirname = os.path.expanduser("~/VulkanSDK")
+ files = os.listdir(dirname)
+
+ ver_file = "0.0.0.0"
+ ver_num = ver_parse(ver_file)
+
+ for file in files:
+ if os.path.isdir(os.path.join(dirname, file)):
+ ver_comp = ver_parse(file)
+ lib_name = os.path.join(
+ os.path.join(dirname, file), "MoltenVK/MoltenVK.xcframework/macos-arm64_x86_64/libMoltenVK.a"
+ )
+ if os.path.isfile(lib_name) and ver_comp > ver_num:
+ ver_num = ver_comp
+ ver_file = file
+
+ return os.path.join(os.path.join(dirname, ver_file), "MoltenVK/MoltenVK.xcframework/macos-arm64_x86_64/")
def configure(env):
@@ -67,7 +98,7 @@ def configure(env):
## Architecture
- # Mac OS X no longer runs on 32-bit since 10.7 which is unsupported since 2014
+ # macOS no longer runs on 32-bit since 10.7 which is unsupported since 2014
# As such, we only support 64-bit
env["bits"] = "64"
@@ -79,10 +110,12 @@ def configure(env):
if env["arch"] == "arm64":
print("Building for macOS 11.0+, platform arm64.")
+ env.Append(ASFLAGS=["-arch", "arm64", "-mmacosx-version-min=11.0"])
env.Append(CCFLAGS=["-arch", "arm64", "-mmacosx-version-min=11.0"])
env.Append(LINKFLAGS=["-arch", "arm64", "-mmacosx-version-min=11.0"])
else:
print("Building for macOS 10.12+, platform x86_64.")
+ env.Append(ASFLAGS=["-arch", "x86_64", "-mmacosx-version-min=10.12"])
env.Append(CCFLAGS=["-arch", "x86_64", "-mmacosx-version-min=10.12"])
env.Append(LINKFLAGS=["-arch", "x86_64", "-mmacosx-version-min=10.12"])
@@ -101,7 +134,7 @@ def configure(env):
env["CC"] = "clang"
env["CXX"] = "clang++"
- detect_darwin_sdk_path("osx", env)
+ detect_darwin_sdk_path("macos", env)
env.Append(CCFLAGS=["-isysroot", "$MACOS_SDK_PATH"])
env.Append(LINKFLAGS=["-isysroot", "$MACOS_SDK_PATH"])
@@ -158,8 +191,10 @@ def configure(env):
## Flags
- env.Prepend(CPPPATH=["#platform/osx"])
- env.Append(CPPDEFINES=["OSX_ENABLED", "UNIX_ENABLED", "APPLE_STYLE_KEYS", "COREAUDIO_ENABLED", "COREMIDI_ENABLED"])
+ env.Prepend(CPPPATH=["#platform/macos"])
+ env.Append(
+ CPPDEFINES=["MACOS_ENABLED", "UNIX_ENABLED", "APPLE_STYLE_KEYS", "COREAUDIO_ENABLED", "COREMIDI_ENABLED"]
+ )
env.Append(
LINKFLAGS=[
"-framework",
@@ -197,4 +232,22 @@ def configure(env):
env.Append(CPPDEFINES=["VULKAN_ENABLED"])
env.Append(LINKFLAGS=["-framework", "Metal", "-framework", "QuartzCore", "-framework", "IOSurface"])
if not env["use_volk"]:
- env.Append(LINKFLAGS=["-L$VULKAN_SDK_PATH/MoltenVK/MoltenVK.xcframework/macos-arm64_x86_64/", "-lMoltenVK"])
+ env.Append(LINKFLAGS=["-lMoltenVK"])
+ mvk_found = False
+ if env["vulkan_sdk_path"] != "":
+ mvk_path = os.path.join(
+ os.path.expanduser(env["vulkan_sdk_path"]), "MoltenVK/MoltenVK.xcframework/macos-arm64_x86_64/"
+ )
+ if os.path.isfile(os.path.join(mvk_path, "libMoltenVK.a")):
+ mvk_found = True
+ env.Append(LINKFLAGS=["-L" + mvk_path])
+ if not mvk_found:
+ mvk_path = get_mvk_sdk_path()
+ if os.path.isfile(os.path.join(mvk_path, "libMoltenVK.a")):
+ mvk_found = True
+ env.Append(LINKFLAGS=["-L" + mvk_path])
+ if not mvk_found:
+ print(
+ "MoltenVK SDK installation directory not found, use 'vulkan_sdk_path' SCons parameter to specify SDK path."
+ )
+ sys.exit(255)
diff --git a/platform/osx/dir_access_osx.h b/platform/macos/dir_access_macos.h
index 3c66c81d4f..1ac1b995de 100644
--- a/platform/osx/dir_access_osx.h
+++ b/platform/macos/dir_access_macos.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* dir_access_osx.h */
+/* dir_access_macos.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef DIR_ACCESS_OSX_H
-#define DIR_ACCESS_OSX_H
+#ifndef DIR_ACCESS_MACOS_H
+#define DIR_ACCESS_MACOS_H
#if defined(UNIX_ENABLED) || defined(LIBC_FILEIO_ENABLED)
@@ -41,7 +41,7 @@
#include "core/io/dir_access.h"
#include "drivers/unix/dir_access_unix.h"
-class DirAccessOSX : public DirAccessUnix {
+class DirAccessMacOS : public DirAccessUnix {
protected:
virtual String fix_unicode_name(const char *p_name) const;
@@ -51,5 +51,6 @@ protected:
virtual bool is_hidden(const String &p_name);
};
-#endif //UNIX ENABLED
-#endif
+#endif // UNIX ENABLED || LIBC_FILEIO_ENABLED
+
+#endif // DIR_ACCESS_MACOS_H
diff --git a/platform/osx/dir_access_osx.mm b/platform/macos/dir_access_macos.mm
index 6bafb9470d..94d937a7dc 100644
--- a/platform/osx/dir_access_osx.mm
+++ b/platform/macos/dir_access_macos.mm
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* dir_access_osx.mm */
+/* dir_access_macos.mm */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,7 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "dir_access_osx.h"
+#include "dir_access_macos.h"
#if defined(UNIX_ENABLED) || defined(LIBC_FILEIO_ENABLED)
@@ -37,7 +37,7 @@
#import <AppKit/NSWorkspace.h>
#import <Foundation/Foundation.h>
-String DirAccessOSX::fix_unicode_name(const char *p_name) const {
+String DirAccessMacOS::fix_unicode_name(const char *p_name) const {
String fname;
NSString *nsstr = [[NSString stringWithUTF8String:p_name] precomposedStringWithCanonicalMapping];
@@ -46,14 +46,14 @@ String DirAccessOSX::fix_unicode_name(const char *p_name) const {
return fname;
}
-int DirAccessOSX::get_drive_count() {
+int DirAccessMacOS::get_drive_count() {
NSArray *res_keys = [NSArray arrayWithObjects:NSURLVolumeURLKey, NSURLIsSystemImmutableKey, nil];
NSArray *vols = [[NSFileManager defaultManager] mountedVolumeURLsIncludingResourceValuesForKeys:res_keys options:NSVolumeEnumerationSkipHiddenVolumes];
return [vols count];
}
-String DirAccessOSX::get_drive(int p_drive) {
+String DirAccessMacOS::get_drive(int p_drive) {
NSArray *res_keys = [NSArray arrayWithObjects:NSURLVolumeURLKey, NSURLIsSystemImmutableKey, nil];
NSArray *vols = [[NSFileManager defaultManager] mountedVolumeURLsIncludingResourceValuesForKeys:res_keys options:NSVolumeEnumerationSkipHiddenVolumes];
int count = [vols count];
@@ -68,7 +68,7 @@ String DirAccessOSX::get_drive(int p_drive) {
return volname;
}
-bool DirAccessOSX::is_hidden(const String &p_name) {
+bool DirAccessMacOS::is_hidden(const String &p_name) {
String f = get_current_dir().plus_file(p_name);
NSURL *url = [NSURL fileURLWithPath:@(f.utf8().get_data())];
NSNumber *hidden = nil;
@@ -78,4 +78,4 @@ bool DirAccessOSX::is_hidden(const String &p_name) {
return [hidden boolValue];
}
-#endif //posix_enabled
+#endif // UNIX_ENABLED || LIBC_FILEIO_ENABLED
diff --git a/platform/osx/display_server_osx.h b/platform/macos/display_server_macos.h
index 9575cb29a2..41031ec81b 100644
--- a/platform/osx/display_server_osx.h
+++ b/platform/macos/display_server_macos.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* display_server_osx.h */
+/* display_server_macos.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef DISPLAY_SERVER_OSX_H
-#define DISPLAY_SERVER_OSX_H
+#ifndef DISPLAY_SERVER_MACOS_H
+#define DISPLAY_SERVER_MACOS_H
#define BitMap _QDBitMap // Suppress deprecated QuickDraw definition.
@@ -37,12 +37,12 @@
#include "servers/display_server.h"
#if defined(GLES3_ENABLED)
-#include "gl_manager_osx_legacy.h"
+#include "gl_manager_macos_legacy.h"
#endif // GLES3_ENABLED
#if defined(VULKAN_ENABLED)
#include "drivers/vulkan/rendering_device_vulkan.h"
-#include "platform/osx/vulkan_context_osx.h"
+#include "platform/macos/vulkan_context_macos.h"
#endif // VULKAN_ENABLED
#import <AppKit/AppKit.h>
@@ -54,15 +54,15 @@
#undef BitMap
#undef CursorShape
-class DisplayServerOSX : public DisplayServer {
- GDCLASS(DisplayServerOSX, DisplayServer)
+class DisplayServerMacOS : public DisplayServer {
+ GDCLASS(DisplayServerMacOS, DisplayServer)
_THREAD_SAFE_CLASS_
public:
struct KeyEvent {
WindowID window_id = INVALID_WINDOW_ID;
- unsigned int osx_state = false;
+ unsigned int macos_state = false;
bool pressed = false;
bool echo = false;
bool raw = false;
@@ -115,10 +115,10 @@ public:
private:
#if defined(GLES3_ENABLED)
- GLManager_OSX *gl_manager = nullptr;
+ GLManager_MacOS *gl_manager = nullptr;
#endif
#if defined(VULKAN_ENABLED)
- VulkanContextOSX *context_vulkan = nullptr;
+ VulkanContextMacOS *context_vulkan = nullptr;
RenderingDeviceVulkan *rendering_device_vulkan = nullptr;
#endif
String rendering_driver;
@@ -203,7 +203,7 @@ public:
void send_event(NSEvent *p_event);
void send_window_event(const WindowData &p_wd, WindowEvent p_event);
void release_pressed_events();
- void get_key_modifier_state(unsigned int p_osx_state, Ref<InputEventWithModifiers> r_state) const;
+ void get_key_modifier_state(unsigned int p_macos_state, Ref<InputEventWithModifiers> r_state) const;
void update_mouse_pos(WindowData &p_wd, NSPoint p_location_in_window);
void push_to_key_event_buffer(const KeyEvent &p_event);
void update_im_text(const Point2i &p_selection, const String &p_text);
@@ -397,10 +397,10 @@ public:
static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
static Vector<String> get_rendering_drivers_func();
- static void register_osx_driver();
+ static void register_macos_driver();
- DisplayServerOSX(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
- ~DisplayServerOSX();
+ DisplayServerMacOS(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
+ ~DisplayServerMacOS();
};
-#endif // DISPLAY_SERVER_OSX_H
+#endif // DISPLAY_SERVER_MACOS_H
diff --git a/platform/osx/display_server_osx.mm b/platform/macos/display_server_macos.mm
index b6a5813bd0..07ba5d7497 100644
--- a/platform/osx/display_server_osx.mm
+++ b/platform/macos/display_server_macos.mm
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* display_server_osx.mm */
+/* display_server_macos.mm */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,16 +28,16 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "display_server_osx.h"
+#include "display_server_macos.h"
#include "godot_content_view.h"
#include "godot_menu_item.h"
#include "godot_window.h"
#include "godot_window_delegate.h"
-#include "key_mapping_osx.h"
-#include "os_osx.h"
+#include "key_mapping_macos.h"
+#include "os_macos.h"
-#include "tts_osx.h"
+#include "tts_macos.h"
#include "core/io/marshalls.h"
#include "core/math/geometry_2d.h"
@@ -60,7 +60,7 @@
#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
#endif
-const NSMenu *DisplayServerOSX::_get_menu_root(const String &p_menu_root) const {
+const NSMenu *DisplayServerMacOS::_get_menu_root(const String &p_menu_root) const {
const NSMenu *menu = nullptr;
if (p_menu_root == "") {
// Main menu.
@@ -81,7 +81,7 @@ const NSMenu *DisplayServerOSX::_get_menu_root(const String &p_menu_root) const
return menu;
}
-NSMenu *DisplayServerOSX::_get_menu_root(const String &p_menu_root) {
+NSMenu *DisplayServerMacOS::_get_menu_root(const String &p_menu_root) {
NSMenu *menu = nullptr;
if (p_menu_root == "") {
// Main menu.
@@ -105,7 +105,7 @@ NSMenu *DisplayServerOSX::_get_menu_root(const String &p_menu_root) {
return menu;
}
-DisplayServerOSX::WindowID DisplayServerOSX::_create_window(WindowMode p_mode, VSyncMode p_vsync_mode, const Rect2i &p_rect) {
+DisplayServerMacOS::WindowID DisplayServerMacOS::_create_window(WindowMode p_mode, VSyncMode p_vsync_mode, const Rect2i &p_rect) {
WindowID id;
const float scale = screen_get_max_scale();
{
@@ -193,7 +193,7 @@ DisplayServerOSX::WindowID DisplayServerOSX::_create_window(WindowMode p_mode, V
return id;
}
-void DisplayServerOSX::_update_window_style(WindowData p_wd) {
+void DisplayServerMacOS::_update_window_style(WindowData p_wd) {
bool borderless_full = false;
if (p_wd.borderless) {
@@ -222,7 +222,7 @@ void DisplayServerOSX::_update_window_style(WindowData p_wd) {
}
}
-void DisplayServerOSX::_set_window_per_pixel_transparency_enabled(bool p_enabled, WindowID p_window) {
+void DisplayServerMacOS::_set_window_per_pixel_transparency_enabled(bool p_enabled, WindowID p_window) {
ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
@@ -267,7 +267,7 @@ void DisplayServerOSX::_set_window_per_pixel_transparency_enabled(bool p_enabled
}
}
-void DisplayServerOSX::_update_displays_arrangement() {
+void DisplayServerMacOS::_update_displays_arrangement() {
origin = Point2i();
for (int i = 0; i < get_screen_count(); i++) {
@@ -282,20 +282,20 @@ void DisplayServerOSX::_update_displays_arrangement() {
displays_arrangement_dirty = false;
}
-Point2i DisplayServerOSX::_get_screens_origin() const {
+Point2i DisplayServerMacOS::_get_screens_origin() const {
// Returns the native top-left screen coordinate of the smallest rectangle
// that encompasses all screens. Needed in get_screen_position(),
// window_get_position, and window_set_position()
// to convert between OS X native screen coordinates and the ones expected by Godot.
if (displays_arrangement_dirty) {
- const_cast<DisplayServerOSX *>(this)->_update_displays_arrangement();
+ const_cast<DisplayServerMacOS *>(this)->_update_displays_arrangement();
}
return origin;
}
-Point2i DisplayServerOSX::_get_native_screen_position(int p_screen) const {
+Point2i DisplayServerMacOS::_get_native_screen_position(int p_screen) const {
NSArray *screenArray = [NSScreen screens];
if ((NSUInteger)p_screen < [screenArray count]) {
NSRect nsrect = [[screenArray objectAtIndex:p_screen] frame];
@@ -306,18 +306,18 @@ Point2i DisplayServerOSX::_get_native_screen_position(int p_screen) const {
return Point2i();
}
-void DisplayServerOSX::_displays_arrangement_changed(CGDirectDisplayID display_id, CGDisplayChangeSummaryFlags flags, void *user_info) {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+void DisplayServerMacOS::_displays_arrangement_changed(CGDirectDisplayID display_id, CGDisplayChangeSummaryFlags flags, void *user_info) {
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (ds) {
ds->displays_arrangement_dirty = true;
}
}
-void DisplayServerOSX::_dispatch_input_events(const Ref<InputEvent> &p_event) {
- ((DisplayServerOSX *)(get_singleton()))->_dispatch_input_event(p_event);
+void DisplayServerMacOS::_dispatch_input_events(const Ref<InputEvent> &p_event) {
+ ((DisplayServerMacOS *)(get_singleton()))->_dispatch_input_event(p_event);
}
-void DisplayServerOSX::_dispatch_input_event(const Ref<InputEvent> &p_event) {
+void DisplayServerMacOS::_dispatch_input_event(const Ref<InputEvent> &p_event) {
_THREAD_SAFE_METHOD_
if (!in_dispatch_input_event) {
in_dispatch_input_event = true;
@@ -364,12 +364,12 @@ void DisplayServerOSX::_dispatch_input_event(const Ref<InputEvent> &p_event) {
}
}
-void DisplayServerOSX::_push_input(const Ref<InputEvent> &p_event) {
+void DisplayServerMacOS::_push_input(const Ref<InputEvent> &p_event) {
Ref<InputEvent> ev = p_event;
Input::get_singleton()->parse_input_event(ev);
}
-void DisplayServerOSX::_process_key_events() {
+void DisplayServerMacOS::_process_key_events() {
Ref<InputEventKey> k;
for (int i = 0; i < key_event_pos; i++) {
const KeyEvent &ke = key_event_buffer[i];
@@ -378,7 +378,7 @@ void DisplayServerOSX::_process_key_events() {
k.instantiate();
k->set_window_id(ke.window_id);
- get_key_modifier_state(ke.osx_state, k);
+ get_key_modifier_state(ke.macos_state, k);
k->set_pressed(ke.pressed);
k->set_echo(ke.echo);
k->set_keycode(ke.keycode);
@@ -392,7 +392,7 @@ void DisplayServerOSX::_process_key_events() {
k.instantiate();
k->set_window_id(ke.window_id);
- get_key_modifier_state(ke.osx_state, k);
+ get_key_modifier_state(ke.macos_state, k);
k->set_pressed(ke.pressed);
k->set_echo(ke.echo);
k->set_keycode(Key::NONE);
@@ -405,7 +405,7 @@ void DisplayServerOSX::_process_key_events() {
k.instantiate();
k->set_window_id(ke.window_id);
- get_key_modifier_state(ke.osx_state, k);
+ get_key_modifier_state(ke.macos_state, k);
k->set_pressed(ke.pressed);
k->set_echo(ke.echo);
k->set_keycode(ke.keycode);
@@ -423,7 +423,7 @@ void DisplayServerOSX::_process_key_events() {
key_event_pos = 0;
}
-void DisplayServerOSX::_update_keyboard_layouts() {
+void DisplayServerMacOS::_update_keyboard_layouts() {
kbd_layouts.clear();
current_layout = 0;
@@ -468,14 +468,14 @@ void DisplayServerOSX::_update_keyboard_layouts() {
keyboard_layout_dirty = false;
}
-void DisplayServerOSX::_keyboard_layout_changed(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef user_info) {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+void DisplayServerMacOS::_keyboard_layout_changed(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef user_info) {
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (ds) {
ds->keyboard_layout_dirty = true;
}
}
-NSImage *DisplayServerOSX::_convert_to_nsimg(Ref<Image> &p_image) const {
+NSImage *DisplayServerMacOS::_convert_to_nsimg(Ref<Image> &p_image) const {
p_image->convert(Image::FORMAT_RGBA8);
NSBitmapImageRep *imgrep = [[NSBitmapImageRep alloc]
initWithBitmapDataPlanes:NULL
@@ -509,7 +509,7 @@ NSImage *DisplayServerOSX::_convert_to_nsimg(Ref<Image> &p_image) const {
return nsimg;
}
-NSCursor *DisplayServerOSX::_cursor_from_selector(SEL p_selector, SEL p_fallback) {
+NSCursor *DisplayServerMacOS::_cursor_from_selector(SEL p_selector, SEL p_fallback) {
if ([NSCursor respondsToSelector:p_selector]) {
id object = [NSCursor performSelector:p_selector];
if ([object isKindOfClass:[NSCursor class]]) {
@@ -523,11 +523,11 @@ NSCursor *DisplayServerOSX::_cursor_from_selector(SEL p_selector, SEL p_fallback
return [NSCursor arrowCursor];
}
-NSMenu *DisplayServerOSX::get_dock_menu() const {
+NSMenu *DisplayServerMacOS::get_dock_menu() const {
return dock_menu;
}
-void DisplayServerOSX::menu_callback(id p_sender) {
+void DisplayServerMacOS::menu_callback(id p_sender) {
if (![p_sender representedObject]) {
return;
}
@@ -560,15 +560,15 @@ void DisplayServerOSX::menu_callback(id p_sender) {
}
}
-bool DisplayServerOSX::has_window(WindowID p_window) const {
+bool DisplayServerMacOS::has_window(WindowID p_window) const {
return windows.has(p_window);
}
-DisplayServerOSX::WindowData &DisplayServerOSX::get_window(WindowID p_window) {
+DisplayServerMacOS::WindowData &DisplayServerMacOS::get_window(WindowID p_window) {
return windows[p_window];
}
-void DisplayServerOSX::send_event(NSEvent *p_event) {
+void DisplayServerMacOS::send_event(NSEvent *p_event) {
// Special case handling of command-period, which is traditionally a special
// shortcut in macOS and doesn't arrive at our regular keyDown handler.
if ([p_event type] == NSEventTypeKeyDown) {
@@ -577,7 +577,7 @@ void DisplayServerOSX::send_event(NSEvent *p_event) {
k.instantiate();
get_key_modifier_state([p_event modifierFlags], k);
- k->set_window_id(DisplayServerOSX::INVALID_WINDOW_ID);
+ k->set_window_id(DisplayServerMacOS::INVALID_WINDOW_ID);
k->set_pressed(true);
k->set_keycode(Key::PERIOD);
k->set_physical_keycode(Key::PERIOD);
@@ -588,7 +588,7 @@ void DisplayServerOSX::send_event(NSEvent *p_event) {
}
}
-void DisplayServerOSX::send_window_event(const WindowData &wd, WindowEvent p_event) {
+void DisplayServerMacOS::send_window_event(const WindowData &wd, WindowEvent p_event) {
_THREAD_SAFE_METHOD_
if (!wd.event_callback.is_null()) {
@@ -600,21 +600,21 @@ void DisplayServerOSX::send_window_event(const WindowData &wd, WindowEvent p_eve
}
}
-void DisplayServerOSX::release_pressed_events() {
+void DisplayServerMacOS::release_pressed_events() {
_THREAD_SAFE_METHOD_
if (Input::get_singleton()) {
Input::get_singleton()->release_pressed_events();
}
}
-void DisplayServerOSX::get_key_modifier_state(unsigned int p_osx_state, Ref<InputEventWithModifiers> r_state) const {
- r_state->set_shift_pressed((p_osx_state & NSEventModifierFlagShift));
- r_state->set_ctrl_pressed((p_osx_state & NSEventModifierFlagControl));
- r_state->set_alt_pressed((p_osx_state & NSEventModifierFlagOption));
- r_state->set_meta_pressed((p_osx_state & NSEventModifierFlagCommand));
+void DisplayServerMacOS::get_key_modifier_state(unsigned int p_macos_state, Ref<InputEventWithModifiers> r_state) const {
+ r_state->set_shift_pressed((p_macos_state & NSEventModifierFlagShift));
+ r_state->set_ctrl_pressed((p_macos_state & NSEventModifierFlagControl));
+ r_state->set_alt_pressed((p_macos_state & NSEventModifierFlagOption));
+ r_state->set_meta_pressed((p_macos_state & NSEventModifierFlagCommand));
}
-void DisplayServerOSX::update_mouse_pos(DisplayServerOSX::WindowData &p_wd, NSPoint p_location_in_window) {
+void DisplayServerMacOS::update_mouse_pos(DisplayServerMacOS::WindowData &p_wd, NSPoint p_location_in_window) {
const NSRect content_rect = [p_wd.window_view frame];
const float scale = screen_get_max_scale();
p_wd.mouse_pos.x = p_location_in_window.x * scale;
@@ -622,33 +622,33 @@ void DisplayServerOSX::update_mouse_pos(DisplayServerOSX::WindowData &p_wd, NSPo
Input::get_singleton()->set_mouse_position(p_wd.mouse_pos);
}
-void DisplayServerOSX::push_to_key_event_buffer(const DisplayServerOSX::KeyEvent &p_event) {
+void DisplayServerMacOS::push_to_key_event_buffer(const DisplayServerMacOS::KeyEvent &p_event) {
if (key_event_pos >= key_event_buffer.size()) {
key_event_buffer.resize(1 + key_event_pos);
}
key_event_buffer.write[key_event_pos++] = p_event;
}
-void DisplayServerOSX::update_im_text(const Point2i &p_selection, const String &p_text) {
+void DisplayServerMacOS::update_im_text(const Point2i &p_selection, const String &p_text) {
im_selection = p_selection;
im_text = p_text;
OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_OS_IME_UPDATE);
}
-void DisplayServerOSX::set_last_focused_window(WindowID p_window) {
+void DisplayServerMacOS::set_last_focused_window(WindowID p_window) {
last_focused_window = p_window;
}
-void DisplayServerOSX::set_is_resizing(bool p_is_resizing) {
+void DisplayServerMacOS::set_is_resizing(bool p_is_resizing) {
is_resizing = p_is_resizing;
}
-bool DisplayServerOSX::get_is_resizing() const {
+bool DisplayServerMacOS::get_is_resizing() const {
return is_resizing;
}
-void DisplayServerOSX::window_update(WindowID p_window) {
+void DisplayServerMacOS::window_update(WindowID p_window) {
#if defined(GLES3_ENABLED)
if (gl_manager) {
gl_manager->window_update(p_window);
@@ -656,7 +656,7 @@ void DisplayServerOSX::window_update(WindowID p_window) {
#endif
}
-void DisplayServerOSX::window_destroy(WindowID p_window) {
+void DisplayServerMacOS::window_destroy(WindowID p_window) {
#if defined(GLES3_ENABLED)
if (gl_manager) {
gl_manager->window_destroy(p_window);
@@ -670,7 +670,7 @@ void DisplayServerOSX::window_destroy(WindowID p_window) {
windows.erase(p_window);
}
-void DisplayServerOSX::window_resize(WindowID p_window, int p_width, int p_height) {
+void DisplayServerMacOS::window_resize(WindowID p_window, int p_width, int p_height) {
#if defined(GLES3_ENABLED)
if (gl_manager) {
gl_manager->window_resize(p_window, p_width, p_height);
@@ -683,7 +683,7 @@ void DisplayServerOSX::window_resize(WindowID p_window, int p_width, int p_heigh
#endif
}
-bool DisplayServerOSX::has_feature(Feature p_feature) const {
+bool DisplayServerMacOS::has_feature(Feature p_feature) const {
switch (p_feature) {
case FEATURE_GLOBAL_MENU:
case FEATURE_SUBWINDOWS:
@@ -709,16 +709,16 @@ bool DisplayServerOSX::has_feature(Feature p_feature) const {
return false;
}
-String DisplayServerOSX::get_name() const {
- return "OSX";
+String DisplayServerMacOS::get_name() const {
+ return "macOS";
}
-void DisplayServerOSX::global_menu_add_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) {
+void DisplayServerMacOS::global_menu_add_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
if (menu) {
- String keycode = KeyMappingOSX::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK);
+ String keycode = KeyMappingMacOS::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK);
NSMenuItem *menu_item;
if (p_index != -1) {
menu_item = [menu insertItemWithTitle:[NSString stringWithUTF8String:p_label.utf8().get_data()] action:@selector(globalMenuCallback:) keyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()] atIndex:p_index];
@@ -731,17 +731,17 @@ void DisplayServerOSX::global_menu_add_item(const String &p_menu_root, const Str
obj->checkable_type = CHECKABLE_TYPE_NONE;
obj->max_states = 0;
obj->state = 0;
- [menu_item setKeyEquivalentModifierMask:KeyMappingOSX::keycode_get_native_mask(p_accel)];
+ [menu_item setKeyEquivalentModifierMask:KeyMappingMacOS::keycode_get_native_mask(p_accel)];
[menu_item setRepresentedObject:obj];
}
}
-void DisplayServerOSX::global_menu_add_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) {
+void DisplayServerMacOS::global_menu_add_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
if (menu) {
- String keycode = KeyMappingOSX::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK);
+ String keycode = KeyMappingMacOS::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK);
NSMenuItem *menu_item;
if (p_index != -1) {
menu_item = [menu insertItemWithTitle:[NSString stringWithUTF8String:p_label.utf8().get_data()] action:@selector(globalMenuCallback:) keyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()] atIndex:p_index];
@@ -754,17 +754,17 @@ void DisplayServerOSX::global_menu_add_check_item(const String &p_menu_root, con
obj->checkable_type = CHECKABLE_TYPE_CHECK_BOX;
obj->max_states = 0;
obj->state = 0;
- [menu_item setKeyEquivalentModifierMask:KeyMappingOSX::keycode_get_native_mask(p_accel)];
+ [menu_item setKeyEquivalentModifierMask:KeyMappingMacOS::keycode_get_native_mask(p_accel)];
[menu_item setRepresentedObject:obj];
}
}
-void DisplayServerOSX::global_menu_add_icon_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) {
+void DisplayServerMacOS::global_menu_add_icon_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
if (menu) {
- String keycode = KeyMappingOSX::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK);
+ String keycode = KeyMappingMacOS::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK);
NSMenuItem *menu_item;
if (p_index != -1) {
menu_item = [menu insertItemWithTitle:[NSString stringWithUTF8String:p_label.utf8().get_data()] action:@selector(globalMenuCallback:) keyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()] atIndex:p_index];
@@ -786,17 +786,17 @@ void DisplayServerOSX::global_menu_add_icon_item(const String &p_menu_root, cons
obj->img->resize(16, 16, Image::INTERPOLATE_LANCZOS);
[menu_item setImage:_convert_to_nsimg(obj->img)];
}
- [menu_item setKeyEquivalentModifierMask:KeyMappingOSX::keycode_get_native_mask(p_accel)];
+ [menu_item setKeyEquivalentModifierMask:KeyMappingMacOS::keycode_get_native_mask(p_accel)];
[menu_item setRepresentedObject:obj];
}
}
-void DisplayServerOSX::global_menu_add_icon_check_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) {
+void DisplayServerMacOS::global_menu_add_icon_check_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
if (menu) {
- String keycode = KeyMappingOSX::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK);
+ String keycode = KeyMappingMacOS::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK);
NSMenuItem *menu_item;
if (p_index != -1) {
menu_item = [menu insertItemWithTitle:[NSString stringWithUTF8String:p_label.utf8().get_data()] action:@selector(globalMenuCallback:) keyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()] atIndex:p_index];
@@ -818,17 +818,17 @@ void DisplayServerOSX::global_menu_add_icon_check_item(const String &p_menu_root
obj->img->resize(16, 16, Image::INTERPOLATE_LANCZOS);
[menu_item setImage:_convert_to_nsimg(obj->img)];
}
- [menu_item setKeyEquivalentModifierMask:KeyMappingOSX::keycode_get_native_mask(p_accel)];
+ [menu_item setKeyEquivalentModifierMask:KeyMappingMacOS::keycode_get_native_mask(p_accel)];
[menu_item setRepresentedObject:obj];
}
}
-void DisplayServerOSX::global_menu_add_radio_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) {
+void DisplayServerMacOS::global_menu_add_radio_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
if (menu) {
- String keycode = KeyMappingOSX::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK);
+ String keycode = KeyMappingMacOS::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK);
NSMenuItem *menu_item;
if (p_index != -1) {
menu_item = [menu insertItemWithTitle:[NSString stringWithUTF8String:p_label.utf8().get_data()] action:@selector(globalMenuCallback:) keyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()] atIndex:p_index];
@@ -841,17 +841,17 @@ void DisplayServerOSX::global_menu_add_radio_check_item(const String &p_menu_roo
obj->checkable_type = CHECKABLE_TYPE_RADIO_BUTTON;
obj->max_states = 0;
obj->state = 0;
- [menu_item setKeyEquivalentModifierMask:KeyMappingOSX::keycode_get_native_mask(p_accel)];
+ [menu_item setKeyEquivalentModifierMask:KeyMappingMacOS::keycode_get_native_mask(p_accel)];
[menu_item setRepresentedObject:obj];
}
}
-void DisplayServerOSX::global_menu_add_icon_radio_check_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) {
+void DisplayServerMacOS::global_menu_add_icon_radio_check_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
if (menu) {
- String keycode = KeyMappingOSX::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK);
+ String keycode = KeyMappingMacOS::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK);
NSMenuItem *menu_item;
if (p_index != -1) {
menu_item = [menu insertItemWithTitle:[NSString stringWithUTF8String:p_label.utf8().get_data()] action:@selector(globalMenuCallback:) keyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()] atIndex:p_index];
@@ -873,17 +873,17 @@ void DisplayServerOSX::global_menu_add_icon_radio_check_item(const String &p_men
obj->img->resize(16, 16, Image::INTERPOLATE_LANCZOS);
[menu_item setImage:_convert_to_nsimg(obj->img)];
}
- [menu_item setKeyEquivalentModifierMask:KeyMappingOSX::keycode_get_native_mask(p_accel)];
+ [menu_item setKeyEquivalentModifierMask:KeyMappingMacOS::keycode_get_native_mask(p_accel)];
[menu_item setRepresentedObject:obj];
}
}
-void DisplayServerOSX::global_menu_add_multistate_item(const String &p_menu_root, const String &p_label, int p_max_states, int p_default_state, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) {
+void DisplayServerMacOS::global_menu_add_multistate_item(const String &p_menu_root, const String &p_label, int p_max_states, int p_default_state, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
if (menu) {
- String keycode = KeyMappingOSX::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK);
+ String keycode = KeyMappingMacOS::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK);
NSMenuItem *menu_item;
if (p_index != -1) {
menu_item = [menu insertItemWithTitle:[NSString stringWithUTF8String:p_label.utf8().get_data()] action:@selector(globalMenuCallback:) keyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()] atIndex:p_index];
@@ -896,12 +896,12 @@ void DisplayServerOSX::global_menu_add_multistate_item(const String &p_menu_root
obj->checkable_type = CHECKABLE_TYPE_NONE;
obj->max_states = p_max_states;
obj->state = p_default_state;
- [menu_item setKeyEquivalentModifierMask:KeyMappingOSX::keycode_get_native_mask(p_accel)];
+ [menu_item setKeyEquivalentModifierMask:KeyMappingMacOS::keycode_get_native_mask(p_accel)];
[menu_item setRepresentedObject:obj];
}
}
-void DisplayServerOSX::global_menu_add_submenu_item(const String &p_menu_root, const String &p_label, const String &p_submenu, int p_index) {
+void DisplayServerMacOS::global_menu_add_submenu_item(const String &p_menu_root, const String &p_label, const String &p_submenu, int p_index) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
@@ -926,7 +926,7 @@ void DisplayServerOSX::global_menu_add_submenu_item(const String &p_menu_root, c
}
}
-void DisplayServerOSX::global_menu_add_separator(const String &p_menu_root, int p_index) {
+void DisplayServerMacOS::global_menu_add_separator(const String &p_menu_root, int p_index) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
@@ -939,7 +939,7 @@ void DisplayServerOSX::global_menu_add_separator(const String &p_menu_root, int
}
}
-int DisplayServerOSX::global_menu_get_item_index_from_text(const String &p_menu_root, const String &p_text) const {
+int DisplayServerMacOS::global_menu_get_item_index_from_text(const String &p_menu_root, const String &p_text) const {
_THREAD_SAFE_METHOD_
const NSMenu *menu = _get_menu_root(p_menu_root);
@@ -950,7 +950,7 @@ int DisplayServerOSX::global_menu_get_item_index_from_text(const String &p_menu_
return -1;
}
-int DisplayServerOSX::global_menu_get_item_index_from_tag(const String &p_menu_root, const Variant &p_tag) const {
+int DisplayServerMacOS::global_menu_get_item_index_from_tag(const String &p_menu_root, const Variant &p_tag) const {
_THREAD_SAFE_METHOD_
const NSMenu *menu = _get_menu_root(p_menu_root);
@@ -969,7 +969,7 @@ int DisplayServerOSX::global_menu_get_item_index_from_tag(const String &p_menu_r
return -1;
}
-bool DisplayServerOSX::global_menu_is_item_checked(const String &p_menu_root, int p_idx) const {
+bool DisplayServerMacOS::global_menu_is_item_checked(const String &p_menu_root, int p_idx) const {
_THREAD_SAFE_METHOD_
const NSMenu *menu = _get_menu_root(p_menu_root);
@@ -982,7 +982,7 @@ bool DisplayServerOSX::global_menu_is_item_checked(const String &p_menu_root, in
return false;
}
-bool DisplayServerOSX::global_menu_is_item_checkable(const String &p_menu_root, int p_idx) const {
+bool DisplayServerMacOS::global_menu_is_item_checkable(const String &p_menu_root, int p_idx) const {
_THREAD_SAFE_METHOD_
const NSMenu *menu = _get_menu_root(p_menu_root);
@@ -998,7 +998,7 @@ bool DisplayServerOSX::global_menu_is_item_checkable(const String &p_menu_root,
return false;
}
-bool DisplayServerOSX::global_menu_is_item_radio_checkable(const String &p_menu_root, int p_idx) const {
+bool DisplayServerMacOS::global_menu_is_item_radio_checkable(const String &p_menu_root, int p_idx) const {
_THREAD_SAFE_METHOD_
const NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1014,7 +1014,7 @@ bool DisplayServerOSX::global_menu_is_item_radio_checkable(const String &p_menu_
return false;
}
-Callable DisplayServerOSX::global_menu_get_item_callback(const String &p_menu_root, int p_idx) const {
+Callable DisplayServerMacOS::global_menu_get_item_callback(const String &p_menu_root, int p_idx) const {
_THREAD_SAFE_METHOD_
const NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1030,7 +1030,7 @@ Callable DisplayServerOSX::global_menu_get_item_callback(const String &p_menu_ro
return Callable();
}
-Variant DisplayServerOSX::global_menu_get_item_tag(const String &p_menu_root, int p_idx) const {
+Variant DisplayServerMacOS::global_menu_get_item_tag(const String &p_menu_root, int p_idx) const {
_THREAD_SAFE_METHOD_
const NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1046,7 +1046,7 @@ Variant DisplayServerOSX::global_menu_get_item_tag(const String &p_menu_root, in
return Variant();
}
-String DisplayServerOSX::global_menu_get_item_text(const String &p_menu_root, int p_idx) const {
+String DisplayServerMacOS::global_menu_get_item_text(const String &p_menu_root, int p_idx) const {
_THREAD_SAFE_METHOD_
const NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1059,7 +1059,7 @@ String DisplayServerOSX::global_menu_get_item_text(const String &p_menu_root, in
return String();
}
-String DisplayServerOSX::global_menu_get_item_submenu(const String &p_menu_root, int p_idx) const {
+String DisplayServerMacOS::global_menu_get_item_submenu(const String &p_menu_root, int p_idx) const {
_THREAD_SAFE_METHOD_
const NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1079,7 +1079,7 @@ String DisplayServerOSX::global_menu_get_item_submenu(const String &p_menu_root,
return String();
}
-Key DisplayServerOSX::global_menu_get_item_accelerator(const String &p_menu_root, int p_idx) const {
+Key DisplayServerMacOS::global_menu_get_item_accelerator(const String &p_menu_root, int p_idx) const {
_THREAD_SAFE_METHOD_
const NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1110,7 +1110,7 @@ Key DisplayServerOSX::global_menu_get_item_accelerator(const String &p_menu_root
return Key::NONE;
}
-bool DisplayServerOSX::global_menu_is_item_disabled(const String &p_menu_root, int p_idx) const {
+bool DisplayServerMacOS::global_menu_is_item_disabled(const String &p_menu_root, int p_idx) const {
_THREAD_SAFE_METHOD_
const NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1123,7 +1123,7 @@ bool DisplayServerOSX::global_menu_is_item_disabled(const String &p_menu_root, i
return false;
}
-String DisplayServerOSX::global_menu_get_item_tooltip(const String &p_menu_root, int p_idx) const {
+String DisplayServerMacOS::global_menu_get_item_tooltip(const String &p_menu_root, int p_idx) const {
_THREAD_SAFE_METHOD_
const NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1136,7 +1136,7 @@ String DisplayServerOSX::global_menu_get_item_tooltip(const String &p_menu_root,
return String();
}
-int DisplayServerOSX::global_menu_get_item_state(const String &p_menu_root, int p_idx) const {
+int DisplayServerMacOS::global_menu_get_item_state(const String &p_menu_root, int p_idx) const {
_THREAD_SAFE_METHOD_
const NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1152,7 +1152,7 @@ int DisplayServerOSX::global_menu_get_item_state(const String &p_menu_root, int
return 0;
}
-int DisplayServerOSX::global_menu_get_item_max_states(const String &p_menu_root, int p_idx) const {
+int DisplayServerMacOS::global_menu_get_item_max_states(const String &p_menu_root, int p_idx) const {
_THREAD_SAFE_METHOD_
const NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1168,7 +1168,7 @@ int DisplayServerOSX::global_menu_get_item_max_states(const String &p_menu_root,
return 0;
}
-Ref<Texture2D> DisplayServerOSX::global_menu_get_item_icon(const String &p_menu_root, int p_idx) const {
+Ref<Texture2D> DisplayServerMacOS::global_menu_get_item_icon(const String &p_menu_root, int p_idx) const {
_THREAD_SAFE_METHOD_
const NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1178,10 +1178,7 @@ Ref<Texture2D> DisplayServerOSX::global_menu_get_item_icon(const String &p_menu_
GodotMenuItem *obj = [menu_item representedObject];
if (obj) {
if (obj->img.is_valid()) {
- Ref<ImageTexture> txt;
- txt.instantiate();
- txt->create_from_image(obj->img);
- return txt;
+ return ImageTexture::create_from_image(obj->img);
}
}
}
@@ -1189,7 +1186,7 @@ Ref<Texture2D> DisplayServerOSX::global_menu_get_item_icon(const String &p_menu_
return Ref<Texture2D>();
}
-void DisplayServerOSX::global_menu_set_item_checked(const String &p_menu_root, int p_idx, bool p_checked) {
+void DisplayServerMacOS::global_menu_set_item_checked(const String &p_menu_root, int p_idx, bool p_checked) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1208,7 +1205,7 @@ void DisplayServerOSX::global_menu_set_item_checked(const String &p_menu_root, i
}
}
-void DisplayServerOSX::global_menu_set_item_checkable(const String &p_menu_root, int p_idx, bool p_checkable) {
+void DisplayServerMacOS::global_menu_set_item_checkable(const String &p_menu_root, int p_idx, bool p_checkable) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1224,7 +1221,7 @@ void DisplayServerOSX::global_menu_set_item_checkable(const String &p_menu_root,
}
}
-void DisplayServerOSX::global_menu_set_item_radio_checkable(const String &p_menu_root, int p_idx, bool p_checkable) {
+void DisplayServerMacOS::global_menu_set_item_radio_checkable(const String &p_menu_root, int p_idx, bool p_checkable) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1240,7 +1237,7 @@ void DisplayServerOSX::global_menu_set_item_radio_checkable(const String &p_menu
}
}
-void DisplayServerOSX::global_menu_set_item_callback(const String &p_menu_root, int p_idx, const Callable &p_callback) {
+void DisplayServerMacOS::global_menu_set_item_callback(const String &p_menu_root, int p_idx, const Callable &p_callback) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1256,7 +1253,7 @@ void DisplayServerOSX::global_menu_set_item_callback(const String &p_menu_root,
}
}
-void DisplayServerOSX::global_menu_set_item_tag(const String &p_menu_root, int p_idx, const Variant &p_tag) {
+void DisplayServerMacOS::global_menu_set_item_tag(const String &p_menu_root, int p_idx, const Variant &p_tag) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1272,7 +1269,7 @@ void DisplayServerOSX::global_menu_set_item_tag(const String &p_menu_root, int p
}
}
-void DisplayServerOSX::global_menu_set_item_text(const String &p_menu_root, int p_idx, const String &p_text) {
+void DisplayServerMacOS::global_menu_set_item_text(const String &p_menu_root, int p_idx, const String &p_text) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1287,7 +1284,7 @@ void DisplayServerOSX::global_menu_set_item_text(const String &p_menu_root, int
}
}
-void DisplayServerOSX::global_menu_set_item_submenu(const String &p_menu_root, int p_idx, const String &p_submenu) {
+void DisplayServerMacOS::global_menu_set_item_submenu(const String &p_menu_root, int p_idx, const String &p_submenu) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1311,7 +1308,7 @@ void DisplayServerOSX::global_menu_set_item_submenu(const String &p_menu_root, i
}
}
-void DisplayServerOSX::global_menu_set_item_accelerator(const String &p_menu_root, int p_idx, Key p_keycode) {
+void DisplayServerMacOS::global_menu_set_item_accelerator(const String &p_menu_root, int p_idx, Key p_keycode) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1321,14 +1318,14 @@ void DisplayServerOSX::global_menu_set_item_accelerator(const String &p_menu_roo
}
NSMenuItem *menu_item = [menu itemAtIndex:p_idx];
if (menu_item) {
- [menu_item setKeyEquivalentModifierMask:KeyMappingOSX::keycode_get_native_mask(p_keycode)];
- String keycode = KeyMappingOSX::keycode_get_native_string(p_keycode & KeyModifierMask::CODE_MASK);
+ [menu_item setKeyEquivalentModifierMask:KeyMappingMacOS::keycode_get_native_mask(p_keycode)];
+ String keycode = KeyMappingMacOS::keycode_get_native_string(p_keycode & KeyModifierMask::CODE_MASK);
[menu_item setKeyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()]];
}
}
}
-void DisplayServerOSX::global_menu_set_item_disabled(const String &p_menu_root, int p_idx, bool p_disabled) {
+void DisplayServerMacOS::global_menu_set_item_disabled(const String &p_menu_root, int p_idx, bool p_disabled) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1343,7 +1340,7 @@ void DisplayServerOSX::global_menu_set_item_disabled(const String &p_menu_root,
}
}
-void DisplayServerOSX::global_menu_set_item_tooltip(const String &p_menu_root, int p_idx, const String &p_tooltip) {
+void DisplayServerMacOS::global_menu_set_item_tooltip(const String &p_menu_root, int p_idx, const String &p_tooltip) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1358,7 +1355,7 @@ void DisplayServerOSX::global_menu_set_item_tooltip(const String &p_menu_root, i
}
}
-void DisplayServerOSX::global_menu_set_item_state(const String &p_menu_root, int p_idx, int p_state) {
+void DisplayServerMacOS::global_menu_set_item_state(const String &p_menu_root, int p_idx, int p_state) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1376,7 +1373,7 @@ void DisplayServerOSX::global_menu_set_item_state(const String &p_menu_root, int
}
}
-void DisplayServerOSX::global_menu_set_item_max_states(const String &p_menu_root, int p_idx, int p_max_states) {
+void DisplayServerMacOS::global_menu_set_item_max_states(const String &p_menu_root, int p_idx, int p_max_states) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1394,7 +1391,7 @@ void DisplayServerOSX::global_menu_set_item_max_states(const String &p_menu_root
}
}
-void DisplayServerOSX::global_menu_set_item_icon(const String &p_menu_root, int p_idx, const Ref<Texture2D> &p_icon) {
+void DisplayServerMacOS::global_menu_set_item_icon(const String &p_menu_root, int p_idx, const Ref<Texture2D> &p_icon) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1421,7 +1418,7 @@ void DisplayServerOSX::global_menu_set_item_icon(const String &p_menu_root, int
}
}
-int DisplayServerOSX::global_menu_get_item_count(const String &p_menu_root) const {
+int DisplayServerMacOS::global_menu_get_item_count(const String &p_menu_root) const {
_THREAD_SAFE_METHOD_
const NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1432,7 +1429,7 @@ int DisplayServerOSX::global_menu_get_item_count(const String &p_menu_root) cons
}
}
-void DisplayServerOSX::global_menu_remove_item(const String &p_menu_root, int p_idx) {
+void DisplayServerMacOS::global_menu_remove_item(const String &p_menu_root, int p_idx) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1444,7 +1441,7 @@ void DisplayServerOSX::global_menu_remove_item(const String &p_menu_root, int p_
}
}
-void DisplayServerOSX::global_menu_clear(const String &p_menu_root) {
+void DisplayServerMacOS::global_menu_clear(const String &p_menu_root) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1458,42 +1455,42 @@ void DisplayServerOSX::global_menu_clear(const String &p_menu_root) {
}
}
-bool DisplayServerOSX::tts_is_speaking() const {
+bool DisplayServerMacOS::tts_is_speaking() const {
ERR_FAIL_COND_V(!tts, false);
return [tts isSpeaking];
}
-bool DisplayServerOSX::tts_is_paused() const {
+bool DisplayServerMacOS::tts_is_paused() const {
ERR_FAIL_COND_V(!tts, false);
return [tts isPaused];
}
-Array DisplayServerOSX::tts_get_voices() const {
+Array DisplayServerMacOS::tts_get_voices() const {
ERR_FAIL_COND_V(!tts, Array());
return [tts getVoices];
}
-void DisplayServerOSX::tts_speak(const String &p_text, const String &p_voice, int p_volume, float p_pitch, float p_rate, int p_utterance_id, bool p_interrupt) {
+void DisplayServerMacOS::tts_speak(const String &p_text, const String &p_voice, int p_volume, float p_pitch, float p_rate, int p_utterance_id, bool p_interrupt) {
ERR_FAIL_COND(!tts);
[tts speak:p_text voice:p_voice volume:p_volume pitch:p_pitch rate:p_rate utterance_id:p_utterance_id interrupt:p_interrupt];
}
-void DisplayServerOSX::tts_pause() {
+void DisplayServerMacOS::tts_pause() {
ERR_FAIL_COND(!tts);
[tts pauseSpeaking];
}
-void DisplayServerOSX::tts_resume() {
+void DisplayServerMacOS::tts_resume() {
ERR_FAIL_COND(!tts);
[tts resumeSpeaking];
}
-void DisplayServerOSX::tts_stop() {
+void DisplayServerMacOS::tts_stop() {
ERR_FAIL_COND(!tts);
[tts stopSpeaking];
}
-Error DisplayServerOSX::dialog_show(String p_title, String p_description, Vector<String> p_buttons, const Callable &p_callback) {
+Error DisplayServerMacOS::dialog_show(String p_title, String p_description, Vector<String> p_buttons, const Callable &p_callback) {
_THREAD_SAFE_METHOD_
NSAlert *window = [[NSAlert alloc] init];
@@ -1531,7 +1528,7 @@ Error DisplayServerOSX::dialog_show(String p_title, String p_description, Vector
return OK;
}
-Error DisplayServerOSX::dialog_input_text(String p_title, String p_description, String p_partial, const Callable &p_callback) {
+Error DisplayServerMacOS::dialog_input_text(String p_title, String p_description, String p_partial, const Callable &p_callback) {
_THREAD_SAFE_METHOD_
NSAlert *window = [[NSAlert alloc] init];
@@ -1563,7 +1560,7 @@ Error DisplayServerOSX::dialog_input_text(String p_title, String p_description,
return OK;
}
-void DisplayServerOSX::mouse_set_mode(MouseMode p_mode) {
+void DisplayServerMacOS::mouse_set_mode(MouseMode p_mode) {
_THREAD_SAFE_METHOD_
if (p_mode == mouse_mode) {
@@ -1618,11 +1615,11 @@ void DisplayServerOSX::mouse_set_mode(MouseMode p_mode) {
}
}
-DisplayServer::MouseMode DisplayServerOSX::mouse_get_mode() const {
+DisplayServer::MouseMode DisplayServerMacOS::mouse_get_mode() const {
return mouse_mode;
}
-bool DisplayServerOSX::update_mouse_wrap(WindowData &p_wd, NSPoint &r_delta, NSPoint &r_mpos, NSTimeInterval p_timestamp) {
+bool DisplayServerMacOS::update_mouse_wrap(WindowData &p_wd, NSPoint &r_delta, NSPoint &r_mpos, NSTimeInterval p_timestamp) {
_THREAD_SAFE_METHOD_
if (ignore_warp) {
@@ -1644,7 +1641,7 @@ bool DisplayServerOSX::update_mouse_wrap(WindowData &p_wd, NSPoint &r_delta, NSP
List<WarpEvent>::Element *F = warp_events.front();
while (F) {
if (F->get().timestamp < p_timestamp) {
- List<DisplayServerOSX::WarpEvent>::Element *E = F;
+ List<DisplayServerMacOS::WarpEvent>::Element *E = F;
r_delta.x -= E->get().delta.x;
r_delta.y -= E->get().delta.y;
F = F->next();
@@ -1672,7 +1669,7 @@ bool DisplayServerOSX::update_mouse_wrap(WindowData &p_wd, NSPoint &r_delta, NSP
// Save warp data.
last_warp = [[NSProcessInfo processInfo] systemUptime];
- DisplayServerOSX::WarpEvent ev;
+ DisplayServerMacOS::WarpEvent ev;
ev.timestamp = last_warp;
ev.delta = r_delta;
warp_events.push_back(ev);
@@ -1681,7 +1678,7 @@ bool DisplayServerOSX::update_mouse_wrap(WindowData &p_wd, NSPoint &r_delta, NSP
return false;
}
-void DisplayServerOSX::warp_mouse(const Point2i &p_position) {
+void DisplayServerMacOS::warp_mouse(const Point2i &p_position) {
_THREAD_SAFE_METHOD_
if (mouse_mode != MOUSE_MODE_CAPTURED) {
@@ -1708,7 +1705,7 @@ void DisplayServerOSX::warp_mouse(const Point2i &p_position) {
}
}
-Point2i DisplayServerOSX::mouse_get_position() const {
+Point2i DisplayServerMacOS::mouse_get_position() const {
_THREAD_SAFE_METHOD_
const NSPoint mouse_pos = [NSEvent mouseLocation];
@@ -1727,15 +1724,15 @@ Point2i DisplayServerOSX::mouse_get_position() const {
return Vector2i();
}
-void DisplayServerOSX::mouse_set_button_state(MouseButton p_state) {
+void DisplayServerMacOS::mouse_set_button_state(MouseButton p_state) {
last_button_state = p_state;
}
-MouseButton DisplayServerOSX::mouse_get_button_state() const {
+MouseButton DisplayServerMacOS::mouse_get_button_state() const {
return last_button_state;
}
-void DisplayServerOSX::clipboard_set(const String &p_text) {
+void DisplayServerMacOS::clipboard_set(const String &p_text) {
_THREAD_SAFE_METHOD_
NSString *copiedString = [NSString stringWithUTF8String:p_text.utf8().get_data()];
@@ -1746,7 +1743,7 @@ void DisplayServerOSX::clipboard_set(const String &p_text) {
[pasteboard writeObjects:copiedStringArray];
}
-String DisplayServerOSX::clipboard_get() const {
+String DisplayServerMacOS::clipboard_get() const {
_THREAD_SAFE_METHOD_
NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
@@ -1767,14 +1764,14 @@ String DisplayServerOSX::clipboard_get() const {
return ret;
}
-int DisplayServerOSX::get_screen_count() const {
+int DisplayServerMacOS::get_screen_count() const {
_THREAD_SAFE_METHOD_
NSArray *screenArray = [NSScreen screens];
return [screenArray count];
}
-Point2i DisplayServerOSX::screen_get_position(int p_screen) const {
+Point2i DisplayServerMacOS::screen_get_position(int p_screen) const {
_THREAD_SAFE_METHOD_
if (p_screen == SCREEN_OF_MAIN_WINDOW) {
@@ -1788,7 +1785,7 @@ Point2i DisplayServerOSX::screen_get_position(int p_screen) const {
return position;
}
-Size2i DisplayServerOSX::screen_get_size(int p_screen) const {
+Size2i DisplayServerMacOS::screen_get_size(int p_screen) const {
_THREAD_SAFE_METHOD_
if (p_screen == SCREEN_OF_MAIN_WINDOW) {
@@ -1805,7 +1802,7 @@ Size2i DisplayServerOSX::screen_get_size(int p_screen) const {
return Size2i();
}
-int DisplayServerOSX::screen_get_dpi(int p_screen) const {
+int DisplayServerMacOS::screen_get_dpi(int p_screen) const {
_THREAD_SAFE_METHOD_
if (p_screen == SCREEN_OF_MAIN_WINDOW) {
@@ -1829,7 +1826,7 @@ int DisplayServerOSX::screen_get_dpi(int p_screen) const {
return 72;
}
-float DisplayServerOSX::screen_get_scale(int p_screen) const {
+float DisplayServerMacOS::screen_get_scale(int p_screen) const {
_THREAD_SAFE_METHOD_
if (p_screen == SCREEN_OF_MAIN_WINDOW) {
@@ -1847,14 +1844,14 @@ float DisplayServerOSX::screen_get_scale(int p_screen) const {
return 1.f;
}
-float DisplayServerOSX::screen_get_max_scale() const {
+float DisplayServerMacOS::screen_get_max_scale() const {
_THREAD_SAFE_METHOD_
// Note: Do not update max display scale on screen configuration change, existing editor windows can't be rescaled on the fly.
return display_max_scale;
}
-Rect2i DisplayServerOSX::screen_get_usable_rect(int p_screen) const {
+Rect2i DisplayServerMacOS::screen_get_usable_rect(int p_screen) const {
_THREAD_SAFE_METHOD_
if (p_screen == SCREEN_OF_MAIN_WINDOW) {
@@ -1876,7 +1873,7 @@ Rect2i DisplayServerOSX::screen_get_usable_rect(int p_screen) const {
return Rect2i();
}
-float DisplayServerOSX::screen_get_refresh_rate(int p_screen) const {
+float DisplayServerMacOS::screen_get_refresh_rate(int p_screen) const {
_THREAD_SAFE_METHOD_
if (p_screen == SCREEN_OF_MAIN_WINDOW) {
@@ -1894,7 +1891,7 @@ float DisplayServerOSX::screen_get_refresh_rate(int p_screen) const {
return SCREEN_REFRESH_RATE_FALLBACK;
}
-Vector<DisplayServer::WindowID> DisplayServerOSX::get_window_list() const {
+Vector<DisplayServer::WindowID> DisplayServerMacOS::get_window_list() const {
_THREAD_SAFE_METHOD_
Vector<int> ret;
@@ -1904,7 +1901,7 @@ Vector<DisplayServer::WindowID> DisplayServerOSX::get_window_list() const {
return ret;
}
-DisplayServer::WindowID DisplayServerOSX::create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect) {
+DisplayServer::WindowID DisplayServerMacOS::create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect) {
_THREAD_SAFE_METHOD_
WindowID id = _create_window(p_mode, p_vsync_mode, p_rect);
@@ -1917,7 +1914,7 @@ DisplayServer::WindowID DisplayServerOSX::create_sub_window(WindowMode p_mode, V
return id;
}
-void DisplayServerOSX::show_window(WindowID p_id) {
+void DisplayServerMacOS::show_window(WindowID p_id) {
WindowData &wd = windows[p_id];
popup_open(p_id);
@@ -1928,7 +1925,7 @@ void DisplayServerOSX::show_window(WindowID p_id) {
}
}
-void DisplayServerOSX::delete_sub_window(WindowID p_id) {
+void DisplayServerMacOS::delete_sub_window(WindowID p_id) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_id));
@@ -1940,7 +1937,7 @@ void DisplayServerOSX::delete_sub_window(WindowID p_id) {
[wd.window_object close];
}
-void DisplayServerOSX::window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window) {
+void DisplayServerMacOS::window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -1948,7 +1945,7 @@ void DisplayServerOSX::window_set_rect_changed_callback(const Callable &p_callab
wd.rect_changed_callback = p_callable;
}
-void DisplayServerOSX::window_set_window_event_callback(const Callable &p_callable, WindowID p_window) {
+void DisplayServerMacOS::window_set_window_event_callback(const Callable &p_callable, WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -1956,7 +1953,7 @@ void DisplayServerOSX::window_set_window_event_callback(const Callable &p_callab
wd.event_callback = p_callable;
}
-void DisplayServerOSX::window_set_input_event_callback(const Callable &p_callable, WindowID p_window) {
+void DisplayServerMacOS::window_set_input_event_callback(const Callable &p_callable, WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -1964,21 +1961,21 @@ void DisplayServerOSX::window_set_input_event_callback(const Callable &p_callabl
wd.input_event_callback = p_callable;
}
-void DisplayServerOSX::window_set_input_text_callback(const Callable &p_callable, WindowID p_window) {
+void DisplayServerMacOS::window_set_input_text_callback(const Callable &p_callable, WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
wd.input_text_callback = p_callable;
}
-void DisplayServerOSX::window_set_drop_files_callback(const Callable &p_callable, WindowID p_window) {
+void DisplayServerMacOS::window_set_drop_files_callback(const Callable &p_callable, WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
wd.drop_files_callback = p_callable;
}
-void DisplayServerOSX::window_set_title(const String &p_title, WindowID p_window) {
+void DisplayServerMacOS::window_set_title(const String &p_title, WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -1987,7 +1984,7 @@ void DisplayServerOSX::window_set_title(const String &p_title, WindowID p_window
[wd.window_object setTitle:[NSString stringWithUTF8String:p_title.utf8().get_data()]];
}
-void DisplayServerOSX::window_set_mouse_passthrough(const Vector<Vector2> &p_region, WindowID p_window) {
+void DisplayServerMacOS::window_set_mouse_passthrough(const Vector<Vector2> &p_region, WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -1996,7 +1993,7 @@ void DisplayServerOSX::window_set_mouse_passthrough(const Vector<Vector2> &p_reg
wd.mpath = p_region;
}
-int DisplayServerOSX::window_get_current_screen(WindowID p_window) const {
+int DisplayServerMacOS::window_get_current_screen(WindowID p_window) const {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!windows.has(p_window), -1);
const WindowData &wd = windows[p_window];
@@ -2005,12 +2002,16 @@ int DisplayServerOSX::window_get_current_screen(WindowID p_window) const {
return (index == NSNotFound) ? 0 : index;
}
-void DisplayServerOSX::window_set_current_screen(int p_screen, WindowID p_window) {
+void DisplayServerMacOS::window_set_current_screen(int p_screen, WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
+ if (window_get_current_screen(p_window) == p_screen) {
+ return;
+ }
+
bool was_fullscreen = false;
if (wd.fullscreen) {
// Temporary exit fullscreen mode to move window.
@@ -2027,7 +2028,7 @@ void DisplayServerOSX::window_set_current_screen(int p_screen, WindowID p_window
}
}
-void DisplayServerOSX::window_set_exclusive(WindowID p_window, bool p_exclusive) {
+void DisplayServerMacOS::window_set_exclusive(WindowID p_window, bool p_exclusive) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
@@ -2045,7 +2046,7 @@ void DisplayServerOSX::window_set_exclusive(WindowID p_window, bool p_exclusive)
}
}
-Point2i DisplayServerOSX::window_get_position(WindowID p_window) const {
+Point2i DisplayServerMacOS::window_get_position(WindowID p_window) const {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!windows.has(p_window), Point2i());
@@ -2068,7 +2069,7 @@ Point2i DisplayServerOSX::window_get_position(WindowID p_window) const {
return pos;
}
-void DisplayServerOSX::window_set_position(const Point2i &p_position, WindowID p_window) {
+void DisplayServerMacOS::window_set_position(const Point2i &p_position, WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -2096,7 +2097,7 @@ void DisplayServerOSX::window_set_position(const Point2i &p_position, WindowID p
update_mouse_pos(wd, [wd.window_object mouseLocationOutsideOfEventStream]);
}
-void DisplayServerOSX::window_set_transient(WindowID p_window, WindowID p_parent) {
+void DisplayServerMacOS::window_set_transient(WindowID p_window, WindowID p_parent) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(p_window == p_parent);
@@ -2135,7 +2136,7 @@ void DisplayServerOSX::window_set_transient(WindowID p_window, WindowID p_parent
}
}
-void DisplayServerOSX::window_set_max_size(const Size2i p_size, WindowID p_window) {
+void DisplayServerMacOS::window_set_max_size(const Size2i p_size, WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -2155,7 +2156,7 @@ void DisplayServerOSX::window_set_max_size(const Size2i p_size, WindowID p_windo
}
}
-Size2i DisplayServerOSX::window_get_max_size(WindowID p_window) const {
+Size2i DisplayServerMacOS::window_get_max_size(WindowID p_window) const {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!windows.has(p_window), Size2i());
@@ -2163,7 +2164,7 @@ Size2i DisplayServerOSX::window_get_max_size(WindowID p_window) const {
return wd.max_size;
}
-void DisplayServerOSX::window_set_min_size(const Size2i p_size, WindowID p_window) {
+void DisplayServerMacOS::window_set_min_size(const Size2i p_size, WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -2183,7 +2184,7 @@ void DisplayServerOSX::window_set_min_size(const Size2i p_size, WindowID p_windo
}
}
-Size2i DisplayServerOSX::window_get_min_size(WindowID p_window) const {
+Size2i DisplayServerMacOS::window_get_min_size(WindowID p_window) const {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!windows.has(p_window), Size2i());
@@ -2192,7 +2193,7 @@ Size2i DisplayServerOSX::window_get_min_size(WindowID p_window) const {
return wd.min_size;
}
-void DisplayServerOSX::window_set_size(const Size2i p_size, WindowID p_window) {
+void DisplayServerMacOS::window_set_size(const Size2i p_size, WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -2216,7 +2217,7 @@ void DisplayServerOSX::window_set_size(const Size2i p_size, WindowID p_window) {
_update_window_style(wd);
}
-Size2i DisplayServerOSX::window_get_size(WindowID p_window) const {
+Size2i DisplayServerMacOS::window_get_size(WindowID p_window) const {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!windows.has(p_window), Size2i());
@@ -2224,7 +2225,7 @@ Size2i DisplayServerOSX::window_get_size(WindowID p_window) const {
return wd.size;
}
-Size2i DisplayServerOSX::window_get_real_size(WindowID p_window) const {
+Size2i DisplayServerMacOS::window_get_real_size(WindowID p_window) const {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!windows.has(p_window), Size2i());
@@ -2233,7 +2234,7 @@ Size2i DisplayServerOSX::window_get_real_size(WindowID p_window) const {
return Size2i(frame.size.width, frame.size.height) * screen_get_max_scale();
}
-void DisplayServerOSX::window_set_mode(WindowMode p_mode, WindowID p_window) {
+void DisplayServerMacOS::window_set_mode(WindowMode p_mode, WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -2302,7 +2303,7 @@ void DisplayServerOSX::window_set_mode(WindowMode p_mode, WindowID p_window) {
}
}
-DisplayServer::WindowMode DisplayServerOSX::window_get_mode(WindowID p_window) const {
+DisplayServer::WindowMode DisplayServerMacOS::window_get_mode(WindowID p_window) const {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!windows.has(p_window), WINDOW_MODE_WINDOWED);
@@ -2324,11 +2325,11 @@ DisplayServer::WindowMode DisplayServerOSX::window_get_mode(WindowID p_window) c
return WINDOW_MODE_WINDOWED;
}
-bool DisplayServerOSX::window_is_maximize_allowed(WindowID p_window) const {
+bool DisplayServerMacOS::window_is_maximize_allowed(WindowID p_window) const {
return true;
}
-void DisplayServerOSX::window_set_flag(WindowFlags p_flag, bool p_enabled, WindowID p_window) {
+void DisplayServerMacOS::window_set_flag(WindowFlags p_flag, bool p_enabled, WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -2403,7 +2404,7 @@ void DisplayServerOSX::window_set_flag(WindowFlags p_flag, bool p_enabled, Windo
}
}
-bool DisplayServerOSX::window_get_flag(WindowFlags p_flag, WindowID p_window) const {
+bool DisplayServerMacOS::window_get_flag(WindowFlags p_flag, WindowID p_window) const {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!windows.has(p_window), false);
@@ -2439,12 +2440,12 @@ bool DisplayServerOSX::window_get_flag(WindowFlags p_flag, WindowID p_window) co
return false;
}
-void DisplayServerOSX::window_request_attention(WindowID p_window) {
+void DisplayServerMacOS::window_request_attention(WindowID p_window) {
// It's app global, ignore window id.
[NSApp requestUserAttention:NSCriticalRequest];
}
-void DisplayServerOSX::window_move_to_foreground(WindowID p_window) {
+void DisplayServerMacOS::window_move_to_foreground(WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -2458,11 +2459,11 @@ void DisplayServerOSX::window_move_to_foreground(WindowID p_window) {
}
}
-bool DisplayServerOSX::window_can_draw(WindowID p_window) const {
+bool DisplayServerMacOS::window_can_draw(WindowID p_window) const {
return window_get_mode(p_window) != WINDOW_MODE_MINIMIZED;
}
-bool DisplayServerOSX::can_any_window_draw() const {
+bool DisplayServerMacOS::can_any_window_draw() const {
_THREAD_SAFE_METHOD_
for (const KeyValue<WindowID, WindowData> &E : windows) {
@@ -2473,7 +2474,7 @@ bool DisplayServerOSX::can_any_window_draw() const {
return false;
}
-void DisplayServerOSX::window_set_ime_active(const bool p_active, WindowID p_window) {
+void DisplayServerMacOS::window_set_ime_active(const bool p_active, WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -2486,7 +2487,7 @@ void DisplayServerOSX::window_set_ime_active(const bool p_active, WindowID p_win
}
}
-void DisplayServerOSX::window_set_ime_position(const Point2i &p_pos, WindowID p_window) {
+void DisplayServerMacOS::window_set_ime_position(const Point2i &p_pos, WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -2495,7 +2496,7 @@ void DisplayServerOSX::window_set_ime_position(const Point2i &p_pos, WindowID p_
wd.im_position = p_pos;
}
-DisplayServer::WindowID DisplayServerOSX::get_window_at_screen_position(const Point2i &p_position) const {
+DisplayServer::WindowID DisplayServerMacOS::get_window_at_screen_position(const Point2i &p_position) const {
Point2i position = p_position;
position.y *= -1;
position += _get_screens_origin();
@@ -2510,7 +2511,7 @@ DisplayServer::WindowID DisplayServerOSX::get_window_at_screen_position(const Po
return INVALID_WINDOW_ID;
}
-int64_t DisplayServerOSX::window_get_native_handle(HandleType p_handle_type, WindowID p_window) const {
+int64_t DisplayServerMacOS::window_get_native_handle(HandleType p_handle_type, WindowID p_window) const {
ERR_FAIL_COND_V(!windows.has(p_window), 0);
switch (p_handle_type) {
case DISPLAY_HANDLE: {
@@ -2528,27 +2529,27 @@ int64_t DisplayServerOSX::window_get_native_handle(HandleType p_handle_type, Win
}
}
-void DisplayServerOSX::window_attach_instance_id(ObjectID p_instance, WindowID p_window) {
+void DisplayServerMacOS::window_attach_instance_id(ObjectID p_instance, WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
windows[p_window].instance_id = p_instance;
}
-ObjectID DisplayServerOSX::window_get_attached_instance_id(WindowID p_window) const {
+ObjectID DisplayServerMacOS::window_get_attached_instance_id(WindowID p_window) const {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!windows.has(p_window), ObjectID());
return windows[p_window].instance_id;
}
-void DisplayServerOSX::gl_window_make_current(DisplayServer::WindowID p_window_id) {
+void DisplayServerMacOS::gl_window_make_current(DisplayServer::WindowID p_window_id) {
#if defined(GLES3_ENABLED)
gl_manager->window_make_current(p_window_id);
#endif
}
-void DisplayServerOSX::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {
+void DisplayServerMacOS::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {
_THREAD_SAFE_METHOD_
#if defined(GLES3_ENABLED)
if (gl_manager) {
@@ -2562,7 +2563,7 @@ void DisplayServerOSX::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mo
#endif
}
-DisplayServer::VSyncMode DisplayServerOSX::window_get_vsync_mode(WindowID p_window) const {
+DisplayServer::VSyncMode DisplayServerMacOS::window_get_vsync_mode(WindowID p_window) const {
_THREAD_SAFE_METHOD_
#if defined(GLES3_ENABLED)
if (gl_manager) {
@@ -2577,15 +2578,15 @@ DisplayServer::VSyncMode DisplayServerOSX::window_get_vsync_mode(WindowID p_wind
return DisplayServer::VSYNC_ENABLED;
}
-Point2i DisplayServerOSX::ime_get_selection() const {
+Point2i DisplayServerMacOS::ime_get_selection() const {
return im_selection;
}
-String DisplayServerOSX::ime_get_text() const {
+String DisplayServerMacOS::ime_get_text() const {
return im_text;
}
-void DisplayServerOSX::cursor_update_shape() {
+void DisplayServerMacOS::cursor_update_shape() {
_THREAD_SAFE_METHOD_
if (cursors[cursor_shape] != nullptr) {
@@ -2649,7 +2650,7 @@ void DisplayServerOSX::cursor_update_shape() {
}
}
-void DisplayServerOSX::cursor_set_shape(CursorShape p_shape) {
+void DisplayServerMacOS::cursor_set_shape(CursorShape p_shape) {
_THREAD_SAFE_METHOD_
ERR_FAIL_INDEX(p_shape, CURSOR_MAX);
@@ -2667,11 +2668,11 @@ void DisplayServerOSX::cursor_set_shape(CursorShape p_shape) {
cursor_update_shape();
}
-DisplayServerOSX::CursorShape DisplayServerOSX::cursor_get_shape() const {
+DisplayServerMacOS::CursorShape DisplayServerMacOS::cursor_get_shape() const {
return cursor_shape;
}
-void DisplayServerOSX::cursor_set_custom_image(const Ref<Resource> &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
+void DisplayServerMacOS::cursor_set_custom_image(const Ref<Resource> &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
_THREAD_SAFE_METHOD_
if (p_cursor.is_valid()) {
@@ -2783,20 +2784,20 @@ void DisplayServerOSX::cursor_set_custom_image(const Ref<Resource> &p_cursor, Cu
}
}
-bool DisplayServerOSX::get_swap_cancel_ok() {
+bool DisplayServerMacOS::get_swap_cancel_ok() {
return false;
}
-int DisplayServerOSX::keyboard_get_layout_count() const {
+int DisplayServerMacOS::keyboard_get_layout_count() const {
if (keyboard_layout_dirty) {
- const_cast<DisplayServerOSX *>(this)->_update_keyboard_layouts();
+ const_cast<DisplayServerMacOS *>(this)->_update_keyboard_layouts();
}
return kbd_layouts.size();
}
-void DisplayServerOSX::keyboard_set_current_layout(int p_index) {
+void DisplayServerMacOS::keyboard_set_current_layout(int p_index) {
if (keyboard_layout_dirty) {
- const_cast<DisplayServerOSX *>(this)->_update_keyboard_layouts();
+ const_cast<DisplayServerMacOS *>(this)->_update_keyboard_layouts();
}
ERR_FAIL_INDEX(p_index, kbd_layouts.size());
@@ -2824,44 +2825,44 @@ void DisplayServerOSX::keyboard_set_current_layout(int p_index) {
}
}
-int DisplayServerOSX::keyboard_get_current_layout() const {
+int DisplayServerMacOS::keyboard_get_current_layout() const {
if (keyboard_layout_dirty) {
- const_cast<DisplayServerOSX *>(this)->_update_keyboard_layouts();
+ const_cast<DisplayServerMacOS *>(this)->_update_keyboard_layouts();
}
return current_layout;
}
-String DisplayServerOSX::keyboard_get_layout_language(int p_index) const {
+String DisplayServerMacOS::keyboard_get_layout_language(int p_index) const {
if (keyboard_layout_dirty) {
- const_cast<DisplayServerOSX *>(this)->_update_keyboard_layouts();
+ const_cast<DisplayServerMacOS *>(this)->_update_keyboard_layouts();
}
ERR_FAIL_INDEX_V(p_index, kbd_layouts.size(), "");
return kbd_layouts[p_index].code;
}
-String DisplayServerOSX::keyboard_get_layout_name(int p_index) const {
+String DisplayServerMacOS::keyboard_get_layout_name(int p_index) const {
if (keyboard_layout_dirty) {
- const_cast<DisplayServerOSX *>(this)->_update_keyboard_layouts();
+ const_cast<DisplayServerMacOS *>(this)->_update_keyboard_layouts();
}
ERR_FAIL_INDEX_V(p_index, kbd_layouts.size(), "");
return kbd_layouts[p_index].name;
}
-Key DisplayServerOSX::keyboard_get_keycode_from_physical(Key p_keycode) const {
+Key DisplayServerMacOS::keyboard_get_keycode_from_physical(Key p_keycode) const {
if (p_keycode == Key::PAUSE) {
return p_keycode;
}
Key modifiers = p_keycode & KeyModifierMask::MODIFIER_MASK;
Key keycode_no_mod = p_keycode & KeyModifierMask::CODE_MASK;
- unsigned int osx_keycode = KeyMappingOSX::unmap_key((Key)keycode_no_mod);
- return (Key)(KeyMappingOSX::remap_key(osx_keycode, 0) | modifiers);
+ unsigned int macos_keycode = KeyMappingMacOS::unmap_key((Key)keycode_no_mod);
+ return (Key)(KeyMappingMacOS::remap_key(macos_keycode, 0) | modifiers);
}
-void DisplayServerOSX::process_events() {
+void DisplayServerMacOS::process_events() {
_THREAD_SAFE_METHOD_
while (true) {
@@ -2904,7 +2905,7 @@ void DisplayServerOSX::process_events() {
}
}
-void DisplayServerOSX::force_process_and_drop_events() {
+void DisplayServerMacOS::force_process_and_drop_events() {
_THREAD_SAFE_METHOD_
drop_events = true;
@@ -2912,19 +2913,21 @@ void DisplayServerOSX::force_process_and_drop_events() {
drop_events = false;
}
-void DisplayServerOSX::release_rendering_thread() {
+void DisplayServerMacOS::release_rendering_thread() {
}
-void DisplayServerOSX::make_rendering_thread() {
+void DisplayServerMacOS::make_rendering_thread() {
}
-void DisplayServerOSX::swap_buffers() {
+void DisplayServerMacOS::swap_buffers() {
#if defined(GLES3_ENABLED)
- gl_manager->swap_buffers();
+ if (gl_manager) {
+ gl_manager->swap_buffers();
+ }
#endif
}
-void DisplayServerOSX::set_native_icon(const String &p_filename) {
+void DisplayServerMacOS::set_native_icon(const String &p_filename) {
_THREAD_SAFE_METHOD_
Ref<FileAccess> f = FileAccess::open(p_filename, FileAccess::READ);
@@ -2944,7 +2947,7 @@ void DisplayServerOSX::set_native_icon(const String &p_filename) {
[NSApp setApplicationIconImage:icon];
}
-void DisplayServerOSX::set_icon(const Ref<Image> &p_icon) {
+void DisplayServerMacOS::set_icon(const Ref<Image> &p_icon) {
_THREAD_SAFE_METHOD_
Ref<Image> img = p_icon;
@@ -2983,15 +2986,15 @@ void DisplayServerOSX::set_icon(const Ref<Image> &p_icon) {
[NSApp setApplicationIconImage:nsimg];
}
-DisplayServer *DisplayServerOSX::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
- DisplayServer *ds = memnew(DisplayServerOSX(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error));
+DisplayServer *DisplayServerMacOS::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
+ DisplayServer *ds = memnew(DisplayServerMacOS(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error));
if (r_error != OK) {
OS::get_singleton()->alert("Your video card driver does not support any of the supported Vulkan or OpenGL versions.", "Unable to initialize Video driver");
}
return ds;
}
-Vector<String> DisplayServerOSX::get_rendering_drivers_func() {
+Vector<String> DisplayServerMacOS::get_rendering_drivers_func() {
Vector<String> drivers;
#if defined(VULKAN_ENABLED)
@@ -3004,11 +3007,11 @@ Vector<String> DisplayServerOSX::get_rendering_drivers_func() {
return drivers;
}
-void DisplayServerOSX::register_osx_driver() {
- register_create_function("osx", create_func, get_rendering_drivers_func);
+void DisplayServerMacOS::register_macos_driver() {
+ register_create_function("macos", create_func, get_rendering_drivers_func);
}
-DisplayServer::WindowID DisplayServerOSX::window_get_active_popup() const {
+DisplayServer::WindowID DisplayServerMacOS::window_get_active_popup() const {
const List<WindowID>::Element *E = popup_list.back();
if (E) {
return E->get();
@@ -3017,7 +3020,7 @@ DisplayServer::WindowID DisplayServerOSX::window_get_active_popup() const {
}
}
-void DisplayServerOSX::window_set_popup_safe_rect(WindowID p_window, const Rect2i &p_rect) {
+void DisplayServerMacOS::window_set_popup_safe_rect(WindowID p_window, const Rect2i &p_rect) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -3025,7 +3028,7 @@ void DisplayServerOSX::window_set_popup_safe_rect(WindowID p_window, const Rect2
wd.parent_safe_rect = p_rect;
}
-Rect2i DisplayServerOSX::window_get_popup_safe_rect(WindowID p_window) const {
+Rect2i DisplayServerMacOS::window_get_popup_safe_rect(WindowID p_window) const {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!windows.has(p_window), Rect2i());
@@ -3033,7 +3036,7 @@ Rect2i DisplayServerOSX::window_get_popup_safe_rect(WindowID p_window) const {
return wd.parent_safe_rect;
}
-void DisplayServerOSX::popup_open(WindowID p_window) {
+void DisplayServerMacOS::popup_open(WindowID p_window) {
_THREAD_SAFE_METHOD_
WindowData &wd = windows[p_window];
@@ -3051,7 +3054,7 @@ void DisplayServerOSX::popup_open(WindowID p_window) {
}
}
if (C) {
- send_window_event(windows[C->get()], DisplayServerOSX::WINDOW_EVENT_CLOSE_REQUEST);
+ send_window_event(windows[C->get()], DisplayServerMacOS::WINDOW_EVENT_CLOSE_REQUEST);
}
if (was_empty && popup_list.is_empty()) {
@@ -3063,7 +3066,7 @@ void DisplayServerOSX::popup_open(WindowID p_window) {
}
}
-void DisplayServerOSX::popup_close(WindowID p_window) {
+void DisplayServerMacOS::popup_close(WindowID p_window) {
_THREAD_SAFE_METHOD_
bool was_empty = popup_list.is_empty();
@@ -3073,7 +3076,7 @@ void DisplayServerOSX::popup_close(WindowID p_window) {
WindowID win_id = E->get();
popup_list.erase(E);
- send_window_event(windows[win_id], DisplayServerOSX::WINDOW_EVENT_CLOSE_REQUEST);
+ send_window_event(windows[win_id], DisplayServerMacOS::WINDOW_EVENT_CLOSE_REQUEST);
E = F;
}
if (!was_empty && popup_list.is_empty()) {
@@ -3082,7 +3085,7 @@ void DisplayServerOSX::popup_close(WindowID p_window) {
}
}
-bool DisplayServerOSX::mouse_process_popups(bool p_close) {
+bool DisplayServerMacOS::mouse_process_popups(bool p_close) {
_THREAD_SAFE_METHOD_
bool was_empty = popup_list.is_empty();
@@ -3091,7 +3094,7 @@ bool DisplayServerOSX::mouse_process_popups(bool p_close) {
// Close all popups.
List<WindowID>::Element *E = popup_list.front();
if (E) {
- send_window_event(windows[E->get()], DisplayServerOSX::WINDOW_EVENT_CLOSE_REQUEST);
+ send_window_event(windows[E->get()], DisplayServerMacOS::WINDOW_EVENT_CLOSE_REQUEST);
closed = true;
}
if (!was_empty) {
@@ -3123,7 +3126,7 @@ bool DisplayServerOSX::mouse_process_popups(bool p_close) {
}
}
if (C) {
- send_window_event(windows[C->get()], DisplayServerOSX::WINDOW_EVENT_CLOSE_REQUEST);
+ send_window_event(windows[C->get()], DisplayServerMacOS::WINDOW_EVENT_CLOSE_REQUEST);
closed = true;
}
if (!was_empty && popup_list.is_empty()) {
@@ -3134,7 +3137,7 @@ bool DisplayServerOSX::mouse_process_popups(bool p_close) {
return closed;
}
-DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
+DisplayServerMacOS::DisplayServerMacOS(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
Input::get_singleton()->set_event_dispatch_function(_dispatch_input_events);
r_error = OK;
@@ -3161,7 +3164,7 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode
CGDisplayRegisterReconfigurationCallback(_displays_arrangement_changed, nullptr);
// Init TTS
- tts = [[TTS_OSX alloc] init];
+ tts = [[TTS_MacOS alloc] init];
NSMenuItem *menu_item;
NSString *title;
@@ -3215,8 +3218,8 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode
#if defined(GLES3_ENABLED)
if (rendering_driver == "opengl3") {
- GLManager_OSX::ContextType opengl_api_type = GLManager_OSX::GLES_3_0_COMPATIBLE;
- gl_manager = memnew(GLManager_OSX(opengl_api_type));
+ GLManager_MacOS::ContextType opengl_api_type = GLManager_MacOS::GLES_3_0_COMPATIBLE;
+ gl_manager = memnew(GLManager_MacOS(opengl_api_type));
if (gl_manager->initialize() != OK) {
memdelete(gl_manager);
gl_manager = nullptr;
@@ -3228,7 +3231,7 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode
#endif
#if defined(VULKAN_ENABLED)
if (rendering_driver == "vulkan") {
- context_vulkan = memnew(VulkanContextOSX);
+ context_vulkan = memnew(VulkanContextMacOS);
if (context_vulkan->initialize() != OK) {
memdelete(context_vulkan);
context_vulkan = nullptr;
@@ -3265,7 +3268,7 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode
#endif
}
-DisplayServerOSX::~DisplayServerOSX() {
+DisplayServerMacOS::~DisplayServerMacOS() {
// Destroy all windows.
for (HashMap<WindowID, WindowData>::Iterator E = windows.begin(); E;) {
HashMap<WindowID, WindowData>::Iterator F = E;
diff --git a/platform/osx/export/codesign.cpp b/platform/macos/export/codesign.cpp
index fd044c00cc..fd044c00cc 100644
--- a/platform/osx/export/codesign.cpp
+++ b/platform/macos/export/codesign.cpp
diff --git a/platform/osx/export/codesign.h b/platform/macos/export/codesign.h
index 3a08c0ea86..fea7b117d0 100644
--- a/platform/osx/export/codesign.h
+++ b/platform/macos/export/codesign.h
@@ -38,8 +38,8 @@
// - Requirements code generator is not implemented (only hard-coded requirements for the ad-hoc signing is supported).
// - RFC5652/CMS blob generation is not implemented, supports ad-hoc signing only.
-#ifndef CODESIGN_H
-#define CODESIGN_H
+#ifndef MACOS_CODESIGN_H
+#define MACOS_CODESIGN_H
#include "core/crypto/crypto_core.h"
#include "core/io/dir_access.h"
@@ -365,4 +365,4 @@ public:
#endif // MODULE_REGEX_ENABLED
-#endif // CODESIGN_H
+#endif // MACOS_CODESIGN_H
diff --git a/platform/osx/export/export.cpp b/platform/macos/export/export.cpp
index bd35b39e9e..ff7457081f 100644
--- a/platform/osx/export/export.cpp
+++ b/platform/macos/export/export.cpp
@@ -32,11 +32,11 @@
#include "export_plugin.h"
-void register_osx_exporter() {
+void register_macos_exporter() {
EDITOR_DEF("export/macos/force_builtin_codesign", false);
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::BOOL, "export/macos/force_builtin_codesign", PROPERTY_HINT_NONE));
- Ref<EditorExportPlatformOSX> platform;
+ Ref<EditorExportPlatformMacOS> platform;
platform.instantiate();
EditorExport::get_singleton()->add_export_platform(platform);
diff --git a/platform/iphone/export/export.h b/platform/macos/export/export.h
index adb3c23957..260c691209 100644
--- a/platform/iphone/export/export.h
+++ b/platform/macos/export/export.h
@@ -28,9 +28,9 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef IPHONE_EXPORT_H
-#define IPHONE_EXPORT_H
+#ifndef MACOS_EXPORT_H
+#define MACOS_EXPORT_H
-void register_iphone_exporter();
+void register_macos_exporter();
-#endif // IPHONE_EXPORT_H
+#endif // MACOS_EXPORT_H
diff --git a/platform/osx/export/export_plugin.cpp b/platform/macos/export/export_plugin.cpp
index 7010709123..fd0781ac50 100644
--- a/platform/osx/export/export_plugin.cpp
+++ b/platform/macos/export/export_plugin.cpp
@@ -37,7 +37,7 @@
#include "modules/modules_enabled.gen.h" // For regex.
-void EditorExportPlatformOSX::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) {
+void EditorExportPlatformMacOS::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) {
if (p_preset->get("texture_format/s3tc")) {
r_features->push_back("s3tc");
}
@@ -51,7 +51,7 @@ void EditorExportPlatformOSX::get_preset_features(const Ref<EditorExportPreset>
r_features->push_back("64");
}
-bool EditorExportPlatformOSX::get_export_option_visibility(const String &p_option, const HashMap<StringName, Variant> &p_options) const {
+bool EditorExportPlatformMacOS::get_export_option_visibility(const String &p_option, const HashMap<StringName, Variant> &p_options) const {
// These options are not supported by built-in codesign, used on non macOS host.
if (!OS::get_singleton()->has_feature("macos")) {
if (p_option == "codesign/identity" || p_option == "codesign/timestamp" || p_option == "codesign/hardened_runtime" || p_option == "codesign/custom_options" || p_option.begins_with("notarization/")) {
@@ -68,7 +68,7 @@ bool EditorExportPlatformOSX::get_export_option_visibility(const String &p_optio
return true;
}
-void EditorExportPlatformOSX::get_export_options(List<ExportOption> *r_options) {
+void EditorExportPlatformMacOS::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"), ""));
@@ -214,7 +214,7 @@ void _rgba8_to_packbits_encode(int p_ch, int p_size, Vector<uint8_t> &p_source,
memcpy(&p_dest.write[ofs], result.ptr(), res_size);
}
-void EditorExportPlatformOSX::_make_icon(const Ref<Image> &p_icon, Vector<uint8_t> &p_data) {
+void EditorExportPlatformMacOS::_make_icon(const Ref<Image> &p_icon, Vector<uint8_t> &p_data) {
Ref<ImageTexture> it = memnew(ImageTexture);
Vector<uint8_t> data;
@@ -252,7 +252,7 @@ void EditorExportPlatformOSX::_make_icon(const Ref<Image> &p_icon, Vector<uint8_
if (icon_infos[i].is_png) {
// Encode PNG icon.
- it->create_from_image(copy);
+ it->set_image(copy);
String path = EditorPaths::get_singleton()->get_cache_dir().plus_file("icon.png");
ResourceSaver::save(path, it);
@@ -320,7 +320,7 @@ void EditorExportPlatformOSX::_make_icon(const Ref<Image> &p_icon, Vector<uint8_
p_data = data;
}
-void EditorExportPlatformOSX::_fix_plist(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &plist, const String &p_binary) {
+void EditorExportPlatformMacOS::_fix_plist(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &plist, const String &p_binary) {
String str;
String strnew;
str.parse_utf8((const char *)plist.ptr(), plist.size());
@@ -407,14 +407,14 @@ void EditorExportPlatformOSX::_fix_plist(const Ref<EditorExportPreset> &p_preset
}
/**
- * If we're running the OSX version of the Godot editor we'll:
+ * If we're running the macOS version of the Godot editor we'll:
* - export our application bundle to a temporary folder
* - attempt to code sign it
* - and then wrap it up in a DMG
*/
-Error EditorExportPlatformOSX::_notarize(const Ref<EditorExportPreset> &p_preset, const String &p_path) {
-#ifdef OSX_ENABLED
+Error EditorExportPlatformMacOS::_notarize(const Ref<EditorExportPreset> &p_preset, const String &p_path) {
+#ifdef MACOS_ENABLED
List<String> args;
args.push_back("altool");
@@ -468,7 +468,7 @@ Error EditorExportPlatformOSX::_notarize(const Ref<EditorExportPreset> &p_preset
return OK;
}
-Error EditorExportPlatformOSX::_code_sign(const Ref<EditorExportPreset> &p_preset, const String &p_path, const String &p_ent_path, bool p_warn) {
+Error EditorExportPlatformMacOS::_code_sign(const Ref<EditorExportPreset> &p_preset, const String &p_path, const String &p_ent_path, bool p_warn) {
bool force_builtin_codesign = EditorSettings::get_singleton()->get("export/macos/force_builtin_codesign");
bool ad_hoc = (p_preset->get("codesign/identity") == "" || p_preset->get("codesign/identity") == "-");
@@ -476,7 +476,7 @@ Error EditorExportPlatformOSX::_code_sign(const Ref<EditorExportPreset> &p_prese
print_verbose("using built-in codesign...");
#ifdef MODULE_REGEX_ENABLED
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
if (p_preset->get("codesign/timestamp") && p_warn) {
add_message(EXPORT_MESSAGE_INFO, TTR("Code Signing"), TTR("Timestamping is not compatible with ad-hoc signature, and was disabled!"));
}
@@ -566,9 +566,9 @@ Error EditorExportPlatformOSX::_code_sign(const Ref<EditorExportPreset> &p_prese
}
}
-Error EditorExportPlatformOSX::_code_sign_directory(const Ref<EditorExportPreset> &p_preset, const String &p_path,
+Error EditorExportPlatformMacOS::_code_sign_directory(const Ref<EditorExportPreset> &p_preset, const String &p_path,
const String &p_ent_path, bool p_should_error_on_non_code) {
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
static Vector<String> extensions_to_sign;
if (extensions_to_sign.is_empty()) {
@@ -615,7 +615,7 @@ Error EditorExportPlatformOSX::_code_sign_directory(const Ref<EditorExportPreset
return OK;
}
-Error EditorExportPlatformOSX::_copy_and_sign_files(Ref<DirAccess> &dir_access, const String &p_src_path,
+Error EditorExportPlatformMacOS::_copy_and_sign_files(Ref<DirAccess> &dir_access, const String &p_src_path,
const String &p_in_app_path, bool p_sign_enabled,
const Ref<EditorExportPreset> &p_preset, const String &p_ent_path,
bool p_should_error_on_non_code_sign) {
@@ -644,14 +644,14 @@ Error EditorExportPlatformOSX::_copy_and_sign_files(Ref<DirAccess> &dir_access,
return err;
}
-Error EditorExportPlatformOSX::_export_osx_plugins_for(Ref<EditorExportPlugin> p_editor_export_plugin,
+Error EditorExportPlatformMacOS::_export_macos_plugins_for(Ref<EditorExportPlugin> p_editor_export_plugin,
const String &p_app_path_name, Ref<DirAccess> &dir_access,
bool p_sign_enabled, const Ref<EditorExportPreset> &p_preset,
const String &p_ent_path) {
Error error{ OK };
- const Vector<String> &osx_plugins{ p_editor_export_plugin->get_osx_plugin_files() };
- for (int i = 0; i < osx_plugins.size(); ++i) {
- String src_path{ ProjectSettings::get_singleton()->globalize_path(osx_plugins[i]) };
+ const Vector<String> &macos_plugins{ p_editor_export_plugin->get_macos_plugin_files() };
+ for (int i = 0; i < macos_plugins.size(); ++i) {
+ String src_path{ ProjectSettings::get_singleton()->globalize_path(macos_plugins[i]) };
String path_in_app{ p_app_path_name + "/Contents/PlugIns/" + src_path.get_file() };
error = _copy_and_sign_files(dir_access, src_path, path_in_app, p_sign_enabled, p_preset, p_ent_path, false);
if (error != OK) {
@@ -661,7 +661,7 @@ Error EditorExportPlatformOSX::_export_osx_plugins_for(Ref<EditorExportPlugin> p
return error;
}
-Error EditorExportPlatformOSX::_create_dmg(const String &p_dmg_path, const String &p_pkg_name, const String &p_app_path_name) {
+Error EditorExportPlatformMacOS::_create_dmg(const String &p_dmg_path, const String &p_pkg_name, const String &p_app_path_name) {
List<String> args;
if (FileAccess::exists(p_dmg_path)) {
@@ -697,7 +697,7 @@ Error EditorExportPlatformOSX::_create_dmg(const String &p_dmg_path, const Strin
return OK;
}
-Error EditorExportPlatformOSX::_export_debug_script(const Ref<EditorExportPreset> &p_preset, const String &p_app_name, const String &p_pkg_name, const String &p_path) {
+Error EditorExportPlatformMacOS::_export_debug_script(const Ref<EditorExportPreset> &p_preset, const String &p_app_name, const String &p_pkg_name, const String &p_path) {
Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::WRITE);
if (f.is_null()) {
add_message(EXPORT_MESSAGE_ERROR, TTR("Debug Script Export"), vformat(TTR("Could not open file \"%s\"."), p_path));
@@ -706,19 +706,30 @@ Error EditorExportPlatformOSX::_export_debug_script(const Ref<EditorExportPreset
f->store_line("#!/bin/sh");
f->store_line("echo -ne '\\033c\\033]0;" + p_app_name + "\\a'");
- f->store_line("function realpath() { python -c \"import os,sys; print(os.path.realpath(sys.argv[1]))\" \"$0\"; }");
- f->store_line("base_path=\"$(dirname \"$(realpath \"$0\")\")\"");
- f->store_line("\"$base_path/" + p_pkg_name + "\" \"$@\"");
+ f->store_line("");
+ f->store_line("function app_realpath() {");
+ f->store_line(" SOURCE=$1");
+ f->store_line(" while [ -h \"$SOURCE\" ]; do");
+ f->store_line(" DIR=$(dirname \"$SOURCE\")");
+ f->store_line(" SOURCE=$(readlink \"$SOURCE\")");
+ f->store_line(" [[ $SOURCE != /* ]] && SOURCE=$DIR/$SOURCE");
+ f->store_line(" done");
+ f->store_line(" echo \"$( cd -P \"$( dirname \"$SOURCE\" )\" >/dev/null 2>&1 && pwd )\"");
+ f->store_line("}");
+ f->store_line("");
+ f->store_line("BASE_PATH=\"$(app_realpath \"${BASH_SOURCE[0]}\")\"");
+ f->store_line("\"$BASE_PATH/" + p_pkg_name + "\" \"$@\"");
+ f->store_line("");
return OK;
}
-Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) {
+Error EditorExportPlatformMacOS::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) {
ExportNotifier notifier(*this, p_preset, p_debug, p_path, p_flags);
String src_pkg_name;
- EditorProgress ep("export", "Exporting for OSX", 3, true);
+ EditorProgress ep("export", "Exporting for macOS", 3, true);
if (p_debug) {
src_pkg_name = p_preset->get("custom_template/debug");
@@ -728,7 +739,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
if (src_pkg_name.is_empty()) {
String err;
- src_pkg_name = find_export_template("osx.zip", &err);
+ src_pkg_name = find_export_template("macos.zip", &err);
if (src_pkg_name.is_empty()) {
add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Templates"), TTR("Export template not found."));
return ERR_FILE_NOT_FOUND;
@@ -755,7 +766,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
int ret = unzGoToFirstFile(src_pkg_zip);
- String binary_to_use = "godot_osx_" + String(p_debug ? "debug" : "release") + ".64";
+ String binary_to_use = "godot_macos_" + String(p_debug ? "debug" : "release") + ".universal";
String pkg_name;
if (String(ProjectSettings::get_singleton()->get("application/config/name")) != "") {
@@ -984,7 +995,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
unzCloseCurrentFile(src_pkg_zip);
// Write.
- file = file.replace_first("osx_template.app/", "");
+ file = file.replace_first("macos_template.app/", "");
if (((info.external_fa >> 16L) & 0120000) == 0120000) {
#ifndef UNIX_ENABLED
@@ -1053,19 +1064,19 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
}
if (data.size() > 0) {
- if (file.find("/data.mono.osx.64.release_debug/") != -1) {
+ if (file.find("/data.mono.macos.release_debug.universal/") != -1) {
if (!p_debug) {
ret = unzGoToNextFile(src_pkg_zip);
continue; // skip
}
- file = file.replace("/data.mono.osx.64.release_debug/", "/GodotSharp/");
+ file = file.replace("/data.mono.macos.release_debug.universal/", "/GodotSharp/");
}
- if (file.find("/data.mono.osx.64.release/") != -1) {
+ if (file.find("/data.mono.macos.release.universal/") != -1) {
if (p_debug) {
ret = unzGoToNextFile(src_pkg_zip);
continue; // skip
}
- file = file.replace("/data.mono.osx.64.release/", "/GodotSharp/");
+ file = file.replace("/data.mono.macos.release.universal/", "/GodotSharp/");
}
if (file.ends_with(".dylib")) {
@@ -1086,6 +1097,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
Ref<FileAccess> f = FileAccess::open(file, FileAccess::WRITE);
if (f.is_valid()) {
f->store_buffer(data.ptr(), data.size());
+ f.unref();
if (is_execute) {
// chmod with 0755 if the file is executable.
FileAccess::set_unix_permissions(file, 0755);
@@ -1298,7 +1310,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
bool ad_hoc = true;
if (err == OK) {
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
String sign_identity = p_preset->get("codesign/identity");
#else
String sign_identity = "-";
@@ -1329,7 +1341,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
Vector<Ref<EditorExportPlugin>> export_plugins{ EditorExport::get_singleton()->get_export_plugins() };
for (int i = 0; i < export_plugins.size(); ++i) {
- err = _export_osx_plugins_for(export_plugins[i], tmp_app_path_name, da, sign_enabled, p_preset, ent_path);
+ err = _export_macos_plugins_for(export_plugins[i], tmp_app_path_name, da, sign_enabled, p_preset, ent_path);
if (err != OK) {
break;
}
@@ -1386,7 +1398,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
}
}
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
bool noto_enabled = p_preset->get("notarization/enable");
if (err == OK && noto_enabled) {
if (export_format == "app") {
@@ -1419,7 +1431,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
return err;
}
-void EditorExportPlatformOSX::_zip_folder_recursive(zipFile &p_zip, const String &p_root_path, const String &p_folder, const String &p_pkg_name) {
+void EditorExportPlatformMacOS::_zip_folder_recursive(zipFile &p_zip, const String &p_root_path, const String &p_folder, const String &p_pkg_name) {
String dir = p_folder.is_empty() ? p_root_path : p_root_path.plus_file(p_folder);
Ref<DirAccess> da = DirAccess::open(dir);
@@ -1536,7 +1548,7 @@ void EditorExportPlatformOSX::_zip_folder_recursive(zipFile &p_zip, const String
da->list_dir_end();
}
-bool EditorExportPlatformOSX::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const {
+bool EditorExportPlatformMacOS::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const {
String err;
bool valid = false;
@@ -1559,7 +1571,7 @@ bool EditorExportPlatformOSX::can_export(const Ref<EditorExportPreset> &p_preset
// Look for export templates (official templates, check only is custom templates are not set).
if (!dvalid || !rvalid) {
- dvalid = exists_export_template("osx.zip", &err);
+ dvalid = exists_export_template("macos.zip", &err);
rvalid = dvalid; // Both in the same ZIP.
}
@@ -1575,7 +1587,7 @@ bool EditorExportPlatformOSX::can_export(const Ref<EditorExportPreset> &p_preset
bool sign_enabled = p_preset->get("codesign/enable");
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
bool noto_enabled = p_preset->get("notarization/enable");
bool ad_hoc = ((p_preset->get("codesign/identity") == "") || (p_preset->get("codesign/identity") == "-"));
@@ -1664,11 +1676,9 @@ bool EditorExportPlatformOSX::can_export(const Ref<EditorExportPreset> &p_preset
return valid;
}
-EditorExportPlatformOSX::EditorExportPlatformOSX() {
- Ref<Image> img = memnew(Image(_osx_logo));
- logo.instantiate();
- logo->create_from_image(img);
+EditorExportPlatformMacOS::EditorExportPlatformMacOS() {
+ logo = ImageTexture::create_from_image(memnew(Image(_macos_logo)));
}
-EditorExportPlatformOSX::~EditorExportPlatformOSX() {
+EditorExportPlatformMacOS::~EditorExportPlatformMacOS() {
}
diff --git a/platform/osx/export/export_plugin.h b/platform/macos/export/export_plugin.h
index ec97d4139f..4f4b17594c 100644
--- a/platform/osx/export/export_plugin.h
+++ b/platform/macos/export/export_plugin.h
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef OSX_EXPORT_PLUGIN_H
-#define OSX_EXPORT_PLUGIN_H
+#ifndef MACOS_EXPORT_PLUGIN_H
+#define MACOS_EXPORT_PLUGIN_H
#include "core/config/project_settings.h"
#include "core/io/dir_access.h"
@@ -39,14 +39,14 @@
#include "core/io/zip_io.h"
#include "core/os/os.h"
#include "core/version.h"
-#include "editor/editor_export.h"
#include "editor/editor_settings.h"
-#include "platform/osx/logo.gen.h"
+#include "editor/export/editor_export.h"
+#include "platform/macos/logo.gen.h"
#include <sys/stat.h>
-class EditorExportPlatformOSX : public EditorExportPlatform {
- GDCLASS(EditorExportPlatformOSX, EditorExportPlatform);
+class EditorExportPlatformMacOS : public EditorExportPlatform {
+ GDCLASS(EditorExportPlatformMacOS, EditorExportPlatform);
int version_code = 0;
@@ -61,7 +61,7 @@ class EditorExportPlatformOSX : public EditorExportPlatform {
Error _copy_and_sign_files(Ref<DirAccess> &dir_access, const String &p_src_path, const String &p_in_app_path,
bool p_sign_enabled, const Ref<EditorExportPreset> &p_preset, const String &p_ent_path,
bool p_should_error_on_non_code_sign);
- Error _export_osx_plugins_for(Ref<EditorExportPlugin> p_editor_export_plugin, const String &p_app_path_name,
+ Error _export_macos_plugins_for(Ref<EditorExportPlugin> p_editor_export_plugin, const String &p_app_path_name,
Ref<DirAccess> &dir_access, bool p_sign_enabled, const Ref<EditorExportPreset> &p_preset,
const String &p_ent_path);
Error _create_dmg(const String &p_dmg_path, const String &p_pkg_name, const String &p_app_path_name);
@@ -69,7 +69,7 @@ class EditorExportPlatformOSX : public EditorExportPlatform {
Error _export_debug_script(const Ref<EditorExportPreset> &p_preset, const String &p_app_name, const String &p_pkg_name, const String &p_path);
bool use_codesign() const { return true; }
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
bool use_dmg() const { return true; }
#else
bool use_dmg() const { return false; }
@@ -130,8 +130,8 @@ public:
virtual void resolve_platform_feature_priorities(const Ref<EditorExportPreset> &p_preset, HashSet<String> &p_features) override {
}
- EditorExportPlatformOSX();
- ~EditorExportPlatformOSX();
+ EditorExportPlatformMacOS();
+ ~EditorExportPlatformMacOS();
};
-#endif
+#endif // MACOS_EXPORT_PLUGIN_H
diff --git a/platform/osx/export/lipo.cpp b/platform/macos/export/lipo.cpp
index 82baf18c52..82baf18c52 100644
--- a/platform/osx/export/lipo.cpp
+++ b/platform/macos/export/lipo.cpp
diff --git a/platform/osx/export/lipo.h b/platform/macos/export/lipo.h
index 0e419be17e..516ef99860 100644
--- a/platform/osx/export/lipo.h
+++ b/platform/macos/export/lipo.h
@@ -30,8 +30,8 @@
// Universal / Universal 2 fat binary file creator and extractor.
-#ifndef LIPO_H
-#define LIPO_H
+#ifndef MACOS_LIPO_H
+#define MACOS_LIPO_H
#include "core/io/file_access.h"
#include "core/object/ref_counted.h"
@@ -73,4 +73,4 @@ public:
#endif // MODULE_REGEX_ENABLED
-#endif // LIPO_H
+#endif // MACOS_LIPO_H
diff --git a/platform/osx/export/macho.cpp b/platform/macos/export/macho.cpp
index e6e67eff06..e6e67eff06 100644
--- a/platform/osx/export/macho.cpp
+++ b/platform/macos/export/macho.cpp
diff --git a/platform/osx/export/macho.h b/platform/macos/export/macho.h
index 6cfc3c44f5..7ef0d9067e 100644
--- a/platform/osx/export/macho.h
+++ b/platform/macos/export/macho.h
@@ -30,8 +30,8 @@
// Mach-O binary object file format parser and editor.
-#ifndef MACHO_H
-#define MACHO_H
+#ifndef MACOS_MACHO_H
+#define MACOS_MACHO_H
#include "core/crypto/crypto.h"
#include "core/crypto/crypto_core.h"
@@ -212,4 +212,4 @@ public:
#endif // MODULE_REGEX_ENABLED
-#endif // MACHO_H
+#endif // MACOS_MACHO_H
diff --git a/platform/osx/export/plist.cpp b/platform/macos/export/plist.cpp
index 36de9dd34b..36de9dd34b 100644
--- a/platform/osx/export/plist.cpp
+++ b/platform/macos/export/plist.cpp
diff --git a/platform/osx/export/plist.h b/platform/macos/export/plist.h
index ba9eaec196..79cb928d0a 100644
--- a/platform/osx/export/plist.h
+++ b/platform/macos/export/plist.h
@@ -30,8 +30,8 @@
// Property list file format (application/x-plist) parser, property list ASN-1 serialization.
-#ifndef PLIST_H
-#define PLIST_H
+#ifndef MACOS_PLIST_H
+#define MACOS_PLIST_H
#include "core/crypto/crypto_core.h"
#include "core/io/file_access.h"
@@ -113,4 +113,4 @@ public:
#endif // MODULE_REGEX_ENABLED
-#endif // PLIST_H
+#endif // MACOS_PLIST_H
diff --git a/platform/osx/gl_manager_osx_legacy.h b/platform/macos/gl_manager_macos_legacy.h
index 2d4913a7a6..8752086551 100644
--- a/platform/osx/gl_manager_osx_legacy.h
+++ b/platform/macos/gl_manager_macos_legacy.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* gl_manager_osx_legacy.h */
+/* gl_manager_macos_legacy.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,10 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef GL_MANAGER_OSX_LEGACY_H
-#define GL_MANAGER_OSX_LEGACY_H
+#ifndef GL_MANAGER_MACOS_LEGACY_H
+#define GL_MANAGER_MACOS_LEGACY_H
-#if defined(OSX_ENABLED) && defined(GLES3_ENABLED)
+#if defined(MACOS_ENABLED) && defined(GLES3_ENABLED)
#include "core/error/error_list.h"
#include "core/os/os.h"
@@ -42,7 +42,7 @@
#import <ApplicationServices/ApplicationServices.h>
#import <CoreVideo/CoreVideo.h>
-class GLManager_OSX {
+class GLManager_MacOS {
public:
enum ContextType {
GLES_3_0_COMPATIBLE,
@@ -89,9 +89,10 @@ public:
void set_use_vsync(bool p_use);
bool is_using_vsync() const;
- GLManager_OSX(ContextType p_context_type);
- ~GLManager_OSX();
+ GLManager_MacOS(ContextType p_context_type);
+ ~GLManager_MacOS();
};
-#endif // OSX_ENABLED && GLES3_ENABLED
-#endif // GL_MANAGER_OSX_LEGACY_H
+#endif // MACOS_ENABLED && GLES3_ENABLED
+
+#endif // GL_MANAGER_MACOS_LEGACY_H
diff --git a/platform/osx/gl_manager_osx_legacy.mm b/platform/macos/gl_manager_macos_legacy.mm
index c769d7f5c5..e6bb7aaa85 100644
--- a/platform/osx/gl_manager_osx_legacy.mm
+++ b/platform/macos/gl_manager_macos_legacy.mm
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* gl_manager_osx_legacy.mm */
+/* gl_manager_macos_legacy.mm */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,15 +28,15 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "gl_manager_osx_legacy.h"
+#include "gl_manager_macos_legacy.h"
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
#ifdef GLES3_ENABLED
#include <stdio.h>
#include <stdlib.h>
-Error GLManager_OSX::create_context(GLWindow &win) {
+Error GLManager_MacOS::create_context(GLWindow &win) {
NSOpenGLPixelFormatAttribute attributes[] = {
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAClosestPolicy,
@@ -62,7 +62,7 @@ Error GLManager_OSX::create_context(GLWindow &win) {
return OK;
}
-Error GLManager_OSX::window_create(DisplayServer::WindowID p_window_id, id p_view, int p_width, int p_height) {
+Error GLManager_MacOS::window_create(DisplayServer::WindowID p_window_id, id p_view, int p_width, int p_height) {
GLWindow win;
win.width = p_width;
win.height = p_height;
@@ -78,7 +78,7 @@ Error GLManager_OSX::window_create(DisplayServer::WindowID p_window_id, id p_vie
return OK;
}
-void GLManager_OSX::window_resize(DisplayServer::WindowID p_window_id, int p_width, int p_height) {
+void GLManager_MacOS::window_resize(DisplayServer::WindowID p_window_id, int p_width, int p_height) {
if (!windows.has(p_window_id)) {
return;
}
@@ -102,7 +102,7 @@ void GLManager_OSX::window_resize(DisplayServer::WindowID p_window_id, int p_wid
[win.context update];
}
-int GLManager_OSX::window_get_width(DisplayServer::WindowID p_window_id) {
+int GLManager_MacOS::window_get_width(DisplayServer::WindowID p_window_id) {
if (!windows.has(p_window_id)) {
return 0;
}
@@ -111,7 +111,7 @@ int GLManager_OSX::window_get_width(DisplayServer::WindowID p_window_id) {
return win.width;
}
-int GLManager_OSX::window_get_height(DisplayServer::WindowID p_window_id) {
+int GLManager_MacOS::window_get_height(DisplayServer::WindowID p_window_id) {
if (!windows.has(p_window_id)) {
return 0;
}
@@ -120,7 +120,7 @@ int GLManager_OSX::window_get_height(DisplayServer::WindowID p_window_id) {
return win.height;
}
-void GLManager_OSX::window_destroy(DisplayServer::WindowID p_window_id) {
+void GLManager_MacOS::window_destroy(DisplayServer::WindowID p_window_id) {
if (!windows.has(p_window_id)) {
return;
}
@@ -132,7 +132,7 @@ void GLManager_OSX::window_destroy(DisplayServer::WindowID p_window_id) {
windows.erase(p_window_id);
}
-void GLManager_OSX::release_current() {
+void GLManager_MacOS::release_current() {
if (current_window == DisplayServer::INVALID_WINDOW_ID) {
return;
}
@@ -140,7 +140,7 @@ void GLManager_OSX::release_current() {
[NSOpenGLContext clearCurrentContext];
}
-void GLManager_OSX::window_make_current(DisplayServer::WindowID p_window_id) {
+void GLManager_MacOS::window_make_current(DisplayServer::WindowID p_window_id) {
if (current_window == p_window_id) {
return;
}
@@ -154,7 +154,7 @@ void GLManager_OSX::window_make_current(DisplayServer::WindowID p_window_id) {
current_window = p_window_id;
}
-void GLManager_OSX::make_current() {
+void GLManager_MacOS::make_current() {
if (current_window == DisplayServer::INVALID_WINDOW_ID) {
return;
}
@@ -166,13 +166,13 @@ void GLManager_OSX::make_current() {
[win.context makeCurrentContext];
}
-void GLManager_OSX::swap_buffers() {
+void GLManager_MacOS::swap_buffers() {
for (const KeyValue<DisplayServer::WindowID, GLWindow> &E : windows) {
[E.value.context flushBuffer];
}
}
-void GLManager_OSX::window_update(DisplayServer::WindowID p_window_id) {
+void GLManager_MacOS::window_update(DisplayServer::WindowID p_window_id) {
if (!windows.has(p_window_id)) {
return;
}
@@ -181,7 +181,7 @@ void GLManager_OSX::window_update(DisplayServer::WindowID p_window_id) {
[win.context update];
}
-void GLManager_OSX::window_set_per_pixel_transparency_enabled(DisplayServer::WindowID p_window_id, bool p_enabled) {
+void GLManager_MacOS::window_set_per_pixel_transparency_enabled(DisplayServer::WindowID p_window_id, bool p_enabled) {
if (!windows.has(p_window_id)) {
return;
}
@@ -197,11 +197,11 @@ void GLManager_OSX::window_set_per_pixel_transparency_enabled(DisplayServer::Win
[win.context update];
}
-Error GLManager_OSX::initialize() {
+Error GLManager_MacOS::initialize() {
return OK;
}
-void GLManager_OSX::set_use_vsync(bool p_use) {
+void GLManager_MacOS::set_use_vsync(bool p_use) {
use_vsync = p_use;
CGLContextObj ctx = CGLGetCurrentContext();
@@ -212,17 +212,17 @@ void GLManager_OSX::set_use_vsync(bool p_use) {
}
}
-bool GLManager_OSX::is_using_vsync() const {
+bool GLManager_MacOS::is_using_vsync() const {
return use_vsync;
}
-GLManager_OSX::GLManager_OSX(ContextType p_context_type) {
+GLManager_MacOS::GLManager_MacOS(ContextType p_context_type) {
context_type = p_context_type;
}
-GLManager_OSX::~GLManager_OSX() {
+GLManager_MacOS::~GLManager_MacOS() {
release_current();
}
#endif // GLES3_ENABLED
-#endif // OSX
+#endif // MACOS_ENABLED
diff --git a/platform/osx/godot_application.h b/platform/macos/godot_application.h
index 8d48a659f3..8d48a659f3 100644
--- a/platform/osx/godot_application.h
+++ b/platform/macos/godot_application.h
diff --git a/platform/osx/godot_application.mm b/platform/macos/godot_application.mm
index 13313a025a..3f71c77fd1 100644
--- a/platform/osx/godot_application.mm
+++ b/platform/macos/godot_application.mm
@@ -30,12 +30,12 @@
#include "godot_application.h"
-#include "display_server_osx.h"
+#include "display_server_macos.h"
@implementation GodotApplication
- (void)sendEvent:(NSEvent *)event {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (ds) {
if ([event type] == NSEventTypeLeftMouseDown || [event type] == NSEventTypeRightMouseDown || [event type] == NSEventTypeOtherMouseDown) {
if (ds->mouse_process_popups()) {
diff --git a/platform/osx/godot_application_delegate.h b/platform/macos/godot_application_delegate.h
index 8eec762d8f..f5b67b580f 100644
--- a/platform/osx/godot_application_delegate.h
+++ b/platform/macos/godot_application_delegate.h
@@ -40,6 +40,7 @@
- (void)forceUnbundledWindowActivationHackStep1;
- (void)forceUnbundledWindowActivationHackStep2;
- (void)forceUnbundledWindowActivationHackStep3;
+- (void)handleAppleEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent;
@end
#endif // GODOT_APPLICATION_DELEGATE_H
diff --git a/platform/osx/godot_application_delegate.mm b/platform/macos/godot_application_delegate.mm
index dc82075c44..bacdcc2bc4 100644
--- a/platform/osx/godot_application_delegate.mm
+++ b/platform/macos/godot_application_delegate.mm
@@ -30,8 +30,8 @@
#include "godot_application_delegate.h"
-#include "display_server_osx.h"
-#include "os_osx.h"
+#include "display_server_macos.h"
+#include "os_macos.h"
@implementation GodotApplicationDelegate
@@ -67,8 +67,54 @@
}
}
+- (id)init {
+ self = [super init];
+
+ NSAppleEventManager *aem = [NSAppleEventManager sharedAppleEventManager];
+ [aem setEventHandler:self andSelector:@selector(handleAppleEvent:withReplyEvent:) forEventClass:kInternetEventClass andEventID:kAEGetURL];
+ [aem setEventHandler:self andSelector:@selector(handleAppleEvent:withReplyEvent:) forEventClass:kCoreEventClass andEventID:kAEOpenDocuments];
+
+ return self;
+}
+
+- (void)handleAppleEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent {
+ OS_MacOS *os = (OS_MacOS *)OS::get_singleton();
+ if (!event || !os) {
+ return;
+ }
+
+ List<String> args;
+ if (([event eventClass] == kInternetEventClass) && ([event eventID] == kAEGetURL)) {
+ // Opening URL scheme.
+ NSString *url = [[event paramDescriptorForKeyword:keyDirectObject] stringValue];
+ args.push_back(vformat("--uri=\"%s\"", String::utf8([url UTF8String])));
+ }
+
+ if (([event eventClass] == kCoreEventClass) && ([event eventID] == kAEOpenDocuments)) {
+ // Opening file association.
+ NSAppleEventDescriptor *files = [event paramDescriptorForKeyword:keyDirectObject];
+ if (files) {
+ NSInteger count = [files numberOfItems];
+ for (NSInteger i = 1; i <= count; i++) {
+ NSURL *url = [NSURL URLWithString:[[files descriptorAtIndex:i] stringValue]];
+ args.push_back(String::utf8([url.path UTF8String]));
+ }
+ }
+ }
+
+ if (!args.is_empty()) {
+ if (os->get_main_loop()) {
+ // Application is already running, open a new instance with the URL/files as command line arguments.
+ os->create_instance(args);
+ } else {
+ // Application is just started, add to the list of command line arguments and continue.
+ os->set_cmdline_platform_args(args);
+ }
+ }
+}
+
- (void)applicationDidResignActive:(NSNotification *)notification {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (ds) {
ds->mouse_process_popups(true);
}
@@ -84,14 +130,14 @@
}
- (void)globalMenuCallback:(id)sender {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (ds) {
return ds->menu_callback(sender);
}
}
- (NSMenu *)applicationDockMenu:(NSApplication *)sender {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (ds) {
return ds->get_dock_menu();
} else {
@@ -99,35 +145,16 @@
}
}
-- (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename {
- // Note: may be called called before main loop init!
- OS_OSX *os = (OS_OSX *)OS::get_singleton();
- if (os) {
- os->set_open_with_filename(String::utf8([filename UTF8String]));
- }
-
-#ifdef TOOLS_ENABLED
- // Open new instance.
- if (os && os->get_main_loop()) {
- List<String> args;
- args.push_back(os->get_open_with_filename());
- String exec = os->get_executable_path();
- os->create_process(exec, args);
- }
-#endif
- return YES;
-}
-
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (ds) {
- ds->send_window_event(ds->get_window(DisplayServerOSX::MAIN_WINDOW_ID), DisplayServerOSX::WINDOW_EVENT_CLOSE_REQUEST);
+ ds->send_window_event(ds->get_window(DisplayServerMacOS::MAIN_WINDOW_ID), DisplayServerMacOS::WINDOW_EVENT_CLOSE_REQUEST);
}
return NSTerminateCancel;
}
- (void)showAbout:(id)sender {
- OS_OSX *os = (OS_OSX *)OS::get_singleton();
+ OS_MacOS *os = (OS_MacOS *)OS::get_singleton();
if (os && os->get_main_loop()) {
os->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_ABOUT);
}
diff --git a/platform/osx/godot_content_view.h b/platform/macos/godot_content_view.h
index 7942d716dc..353305aec1 100644
--- a/platform/osx/godot_content_view.h
+++ b/platform/macos/godot_content_view.h
@@ -52,6 +52,7 @@
bool ime_input_event_in_progress;
bool mouse_down_control;
bool ignore_momentum_scroll;
+ bool last_pen_inverted;
}
- (void)processScrollEvent:(NSEvent *)event button:(MouseButton)button factor:(double)factor;
diff --git a/platform/osx/godot_content_view.mm b/platform/macos/godot_content_view.mm
index e96f0a8098..9ca7498a15 100644
--- a/platform/osx/godot_content_view.mm
+++ b/platform/macos/godot_content_view.mm
@@ -30,8 +30,8 @@
#include "godot_content_view.h"
-#include "display_server_osx.h"
-#include "key_mapping_osx.h"
+#include "display_server_macos.h"
+#include "key_mapping_macos.h"
@implementation GodotContentView
@@ -42,6 +42,7 @@
ime_input_event_in_progress = false;
mouse_down_control = false;
ignore_momentum_scroll = false;
+ last_pen_inverted = false;
[self updateTrackingAreas];
if (@available(macOS 10.13, *)) {
@@ -55,7 +56,7 @@
return self;
}
-- (void)setWindowID:(DisplayServerOSX::WindowID)wid {
+- (void)setWindowID:(DisplayServerMacOS::WindowID)wid {
window_id = wid;
}
@@ -66,7 +67,7 @@
}
- (void)updateLayer {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
ds->window_update(window_id);
[super updateLayer];
}
@@ -105,12 +106,12 @@
return;
}
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
if (wd.im_active) {
ime_input_event_in_progress = true;
ds->update_im_text(Point2i(selectedRange.location, selectedRange.length), String::utf8([[marked_text mutableString] UTF8String]));
@@ -125,12 +126,12 @@
ime_input_event_in_progress = false;
[[marked_text mutableString] setString:@""];
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
if (wd.im_active) {
ds->update_im_text(Point2i(), String());
}
@@ -149,12 +150,12 @@
}
- (NSRect)firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return NSMakeRect(0, 0, 0, 0);
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
const NSRect content_rect = [wd.window_view frame];
const float scale = ds->screen_get_max_scale();
NSRect point_in_window_rect = NSMakeRect(wd.im_position.x / scale, content_rect.size.height - (wd.im_position.y / scale) - 1, 0, 0);
@@ -190,7 +191,7 @@
return;
}
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
[self cancelComposition];
return;
@@ -209,10 +210,10 @@
continue;
}
- DisplayServerOSX::KeyEvent ke;
+ DisplayServerMacOS::KeyEvent ke;
ke.window_id = window_id;
- ke.osx_state = [event modifierFlags];
+ ke.macos_state = [event modifierFlags];
ke.pressed = true;
ke.echo = false;
ke.raw = false; // IME input event.
@@ -236,12 +237,12 @@
}
- (BOOL)performDragOperation:(id<NSDraggingInfo>)sender {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return NO;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
if (!wd.drop_files_callback.is_null()) {
Vector<String> files;
NSPasteboard *pboard = [sender draggingPasteboard];
@@ -275,12 +276,12 @@
// MARK: Focus
- (BOOL)canBecomeKeyView {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return YES;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
return !wd.no_focus && !wd.is_popup;
}
@@ -291,7 +292,7 @@
// MARK: Mouse
- (void)cursorUpdate:(NSEvent *)event {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds) {
return;
}
@@ -300,12 +301,12 @@
}
- (void)processMouseEvent:(NSEvent *)event index:(MouseButton)index mask:(MouseButton)mask pressed:(bool)pressed {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
MouseButton last_button_state = ds->mouse_get_button_state();
if (pressed) {
@@ -355,12 +356,12 @@
}
- (void)mouseMoved:(NSEvent *)event {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
NSPoint delta = NSMakePoint([event deltaX], [event deltaY]);
NSPoint mpos = [event locationInWindow];
@@ -377,9 +378,15 @@
ds->update_mouse_pos(wd, mpos);
mm->set_position(wd.mouse_pos);
mm->set_pressure([event pressure]);
- if ([event subtype] == NSEventSubtypeTabletPoint) {
+ NSEventSubtype subtype = [event subtype];
+ if (subtype == NSEventSubtypeTabletPoint) {
const NSPoint p = [event tilt];
mm->set_tilt(Vector2(p.x, p.y));
+ mm->set_pen_inverted(last_pen_inverted);
+ } else if (subtype == NSEventSubtypeTabletProximity) {
+ // Check if using the eraser end of pen only on proximity event.
+ last_pen_inverted = [event pointingDeviceType] == NSPointingDeviceTypeEraser;
+ mm->set_pen_inverted(last_pen_inverted);
}
mm->set_global_position(wd.mouse_pos);
mm->set_velocity(Input::get_singleton()->get_last_mouse_velocity());
@@ -431,38 +438,38 @@
}
- (void)mouseExited:(NSEvent *)event {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
if (ds->mouse_get_mode() != DisplayServer::MOUSE_MODE_CAPTURED) {
- ds->send_window_event(wd, DisplayServerOSX::WINDOW_EVENT_MOUSE_EXIT);
+ ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_MOUSE_EXIT);
}
}
- (void)mouseEntered:(NSEvent *)event {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
if (ds->mouse_get_mode() != DisplayServer::MOUSE_MODE_CAPTURED) {
- ds->send_window_event(wd, DisplayServerOSX::WINDOW_EVENT_MOUSE_ENTER);
+ ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_MOUSE_ENTER);
}
ds->cursor_update_shape();
}
- (void)magnifyWithEvent:(NSEvent *)event {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
Ref<InputEventMagnifyGesture> ev;
ev.instantiate();
@@ -490,12 +497,12 @@
// MARK: Keyboard
- (void)keyDown:(NSEvent *)event {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
ignore_momentum_scroll = true;
@@ -504,7 +511,7 @@
NSString *characters = [event characters];
NSUInteger length = [characters length];
- if (!wd.im_active && length > 0 && keycode_has_unicode(KeyMappingOSX::remap_key([event keyCode], [event modifierFlags]))) {
+ if (!wd.im_active && length > 0 && keycode_has_unicode(KeyMappingMacOS::remap_key([event keyCode], [event modifierFlags]))) {
// Fallback unicode character handler used if IME is not active.
Char16String text;
text.resize([characters length] + 1);
@@ -516,28 +523,28 @@
for (int i = 0; i < u32text.length(); i++) {
const char32_t codepoint = u32text[i];
- DisplayServerOSX::KeyEvent ke;
+ DisplayServerMacOS::KeyEvent ke;
ke.window_id = window_id;
- ke.osx_state = [event modifierFlags];
+ ke.macos_state = [event modifierFlags];
ke.pressed = true;
ke.echo = [event isARepeat];
- ke.keycode = KeyMappingOSX::remap_key([event keyCode], [event modifierFlags]);
- ke.physical_keycode = KeyMappingOSX::translate_key([event keyCode]);
+ ke.keycode = KeyMappingMacOS::remap_key([event keyCode], [event modifierFlags]);
+ ke.physical_keycode = KeyMappingMacOS::translate_key([event keyCode]);
ke.raw = true;
ke.unicode = codepoint;
ds->push_to_key_event_buffer(ke);
}
} else {
- DisplayServerOSX::KeyEvent ke;
+ DisplayServerMacOS::KeyEvent ke;
ke.window_id = window_id;
- ke.osx_state = [event modifierFlags];
+ ke.macos_state = [event modifierFlags];
ke.pressed = true;
ke.echo = [event isARepeat];
- ke.keycode = KeyMappingOSX::remap_key([event keyCode], [event modifierFlags]);
- ke.physical_keycode = KeyMappingOSX::translate_key([event keyCode]);
+ ke.keycode = KeyMappingMacOS::remap_key([event keyCode], [event modifierFlags]);
+ ke.physical_keycode = KeyMappingMacOS::translate_key([event keyCode]);
ke.raw = false;
ke.unicode = 0;
@@ -552,7 +559,7 @@
}
- (void)flagsChanged:(NSEvent *)event {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
@@ -560,7 +567,7 @@
// Ignore all input if IME input is in progress
if (!ime_input_event_in_progress) {
- DisplayServerOSX::KeyEvent ke;
+ DisplayServerMacOS::KeyEvent ke;
ke.window_id = window_id;
ke.echo = false;
@@ -601,9 +608,9 @@
return;
}
- ke.osx_state = mod;
- ke.keycode = KeyMappingOSX::remap_key(key, mod);
- ke.physical_keycode = KeyMappingOSX::translate_key(key);
+ ke.macos_state = mod;
+ ke.keycode = KeyMappingMacOS::remap_key(key, mod);
+ ke.physical_keycode = KeyMappingMacOS::translate_key(key);
ke.unicode = 0;
ds->push_to_key_event_buffer(ke);
@@ -611,12 +618,12 @@
}
- (void)keyUp:(NSEvent *)event {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
// Ignore all input if IME input is in progress.
if (!ime_input_event_in_progress) {
@@ -624,7 +631,7 @@
NSUInteger length = [characters length];
// Fallback unicode character handler used if IME is not active.
- if (!wd.im_active && length > 0 && keycode_has_unicode(KeyMappingOSX::remap_key([event keyCode], [event modifierFlags]))) {
+ if (!wd.im_active && length > 0 && keycode_has_unicode(KeyMappingMacOS::remap_key([event keyCode], [event modifierFlags]))) {
Char16String text;
text.resize([characters length] + 1);
[characters getCharacters:(unichar *)text.ptrw() range:NSMakeRange(0, [characters length])];
@@ -634,28 +641,28 @@
for (int i = 0; i < u32text.length(); i++) {
const char32_t codepoint = u32text[i];
- DisplayServerOSX::KeyEvent ke;
+ DisplayServerMacOS::KeyEvent ke;
ke.window_id = window_id;
- ke.osx_state = [event modifierFlags];
+ ke.macos_state = [event modifierFlags];
ke.pressed = false;
ke.echo = [event isARepeat];
- ke.keycode = KeyMappingOSX::remap_key([event keyCode], [event modifierFlags]);
- ke.physical_keycode = KeyMappingOSX::translate_key([event keyCode]);
+ ke.keycode = KeyMappingMacOS::remap_key([event keyCode], [event modifierFlags]);
+ ke.physical_keycode = KeyMappingMacOS::translate_key([event keyCode]);
ke.raw = true;
ke.unicode = codepoint;
ds->push_to_key_event_buffer(ke);
}
} else {
- DisplayServerOSX::KeyEvent ke;
+ DisplayServerMacOS::KeyEvent ke;
ke.window_id = window_id;
- ke.osx_state = [event modifierFlags];
+ ke.macos_state = [event modifierFlags];
ke.pressed = false;
ke.echo = [event isARepeat];
- ke.keycode = KeyMappingOSX::remap_key([event keyCode], [event modifierFlags]);
- ke.physical_keycode = KeyMappingOSX::translate_key([event keyCode]);
+ ke.keycode = KeyMappingMacOS::remap_key([event keyCode], [event modifierFlags]);
+ ke.physical_keycode = KeyMappingMacOS::translate_key([event keyCode]);
ke.raw = true;
ke.unicode = 0;
@@ -667,12 +674,12 @@
// MARK: Scroll and pan
- (void)processScrollEvent:(NSEvent *)event button:(MouseButton)button factor:(double)factor {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
MouseButton mask = mouse_button_to_mask(button);
Ref<InputEventMouseButton> sc;
@@ -706,12 +713,12 @@
}
- (void)processPanEvent:(NSEvent *)event dx:(double)dx dy:(double)dy {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
Ref<InputEventPanGesture> pg;
pg.instantiate();
@@ -725,12 +732,12 @@
}
- (void)scrollWheel:(NSEvent *)event {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
ds->update_mouse_pos(wd, [event locationInWindow]);
double delta_x = [event scrollingDeltaX];
diff --git a/platform/osx/godot_main_osx.mm b/platform/macos/godot_main_macos.mm
index 053a7f4a1d..66071f1404 100644
--- a/platform/osx/godot_main_osx.mm
+++ b/platform/macos/godot_main_macos.mm
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* godot_main_osx.mm */
+/* godot_main_macos.mm */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -30,7 +30,7 @@
#include "main/main.h"
-#include "os_osx.h"
+#include "os_macos.h"
#include <string.h>
#include <unistd.h>
@@ -68,22 +68,17 @@ int main(int argc, char **argv) {
printf("Current path: %s\n", cwd);
#endif
- OS_OSX os;
+ OS_MacOS os;
Error err;
// We must override main when testing is enabled.
TEST_MAIN_OVERRIDE
- if (os.get_open_with_filename() != "") {
- char *argv_c = (char *)malloc(os.get_open_with_filename().utf8().size());
- memcpy(argv_c, os.get_open_with_filename().utf8().get_data(), os.get_open_with_filename().utf8().size());
- err = Main::setup(argv[0], 1, &argv_c);
- free(argv_c);
- } else {
- err = Main::setup(argv[0], argc - first_arg, &argv[first_arg]);
- }
+ err = Main::setup(argv[0], argc - first_arg, &argv[first_arg]);
- if (err != OK) {
+ if (err == ERR_HELP) { // Returned by --help and --version, so success.
+ return 0;
+ } else if (err != OK) {
return 255;
}
diff --git a/platform/osx/godot_menu_item.h b/platform/macos/godot_menu_item.h
index 2c12897f10..2c12897f10 100644
--- a/platform/osx/godot_menu_item.h
+++ b/platform/macos/godot_menu_item.h
diff --git a/platform/osx/godot_window.h b/platform/macos/godot_window.h
index 16ff101142..9fc5599e86 100644
--- a/platform/osx/godot_window.h
+++ b/platform/macos/godot_window.h
@@ -44,4 +44,4 @@
@end
-#endif //GODOT_WINDOW_H
+#endif // GODOT_WINDOW_H
diff --git a/platform/osx/godot_window.mm b/platform/macos/godot_window.mm
index d43853a94b..e205e7546d 100644
--- a/platform/osx/godot_window.mm
+++ b/platform/macos/godot_window.mm
@@ -30,7 +30,7 @@
#include "godot_window.h"
-#include "display_server_osx.h"
+#include "display_server_macos.h"
@implementation GodotWindow
@@ -40,29 +40,29 @@
return self;
}
-- (void)setWindowID:(DisplayServerOSX::WindowID)wid {
+- (void)setWindowID:(DisplayServerMacOS::WindowID)wid {
window_id = wid;
}
- (BOOL)canBecomeKeyWindow {
// Required for NSWindowStyleMaskBorderless windows.
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return YES;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
return !wd.no_focus && !wd.is_popup;
}
- (BOOL)canBecomeMainWindow {
// Required for NSWindowStyleMaskBorderless windows.
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return YES;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
return !wd.no_focus && !wd.is_popup;
}
diff --git a/platform/osx/godot_window_delegate.h b/platform/macos/godot_window_delegate.h
index 8a1f681fcd..98c226aa2f 100644
--- a/platform/osx/godot_window_delegate.h
+++ b/platform/macos/godot_window_delegate.h
@@ -44,4 +44,4 @@
@end
-#endif //GODOT_WINDOW_DELEGATE_H
+#endif // GODOT_WINDOW_DELEGATE_H
diff --git a/platform/osx/godot_window_delegate.mm b/platform/macos/godot_window_delegate.mm
index 521127f01b..e1e88274f0 100644
--- a/platform/osx/godot_window_delegate.mm
+++ b/platform/macos/godot_window_delegate.mm
@@ -30,7 +30,7 @@
#include "godot_window_delegate.h"
-#include "display_server_osx.h"
+#include "display_server_macos.h"
@implementation GodotWindowDelegate
@@ -39,42 +39,42 @@
}
- (BOOL)windowShouldClose:(id)sender {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return YES;
}
- ds->send_window_event(ds->get_window(window_id), DisplayServerOSX::WINDOW_EVENT_CLOSE_REQUEST);
+ ds->send_window_event(ds->get_window(window_id), DisplayServerMacOS::WINDOW_EVENT_CLOSE_REQUEST);
return NO;
}
- (void)windowWillClose:(NSNotification *)notification {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
ds->popup_close(window_id);
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
while (wd.transient_children.size()) {
- ds->window_set_transient(*wd.transient_children.begin(), DisplayServerOSX::INVALID_WINDOW_ID);
+ ds->window_set_transient(*wd.transient_children.begin(), DisplayServerMacOS::INVALID_WINDOW_ID);
}
- if (wd.transient_parent != DisplayServerOSX::INVALID_WINDOW_ID) {
- ds->window_set_transient(window_id, DisplayServerOSX::INVALID_WINDOW_ID);
+ if (wd.transient_parent != DisplayServerMacOS::INVALID_WINDOW_ID) {
+ ds->window_set_transient(window_id, DisplayServerMacOS::INVALID_WINDOW_ID);
}
ds->window_destroy(window_id);
}
- (void)windowDidEnterFullScreen:(NSNotification *)notification {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
wd.fullscreen = true;
// Reset window size limits.
[wd.window_object setContentMinSize:NSMakeSize(0, 0)];
@@ -85,12 +85,12 @@
}
- (void)windowDidExitFullScreen:(NSNotification *)notification {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
wd.fullscreen = false;
// Set window size limits.
@@ -119,12 +119,12 @@
}
- (void)windowDidChangeBackingProperties:(NSNotification *)notification {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
CGFloat new_scale_factor = [wd.window_object backingScaleFactor];
CGFloat old_scale_factor = [[[notification userInfo] objectForKey:@"NSBackingPropertyOldScaleFactorKey"] doubleValue];
@@ -137,7 +137,7 @@
wd.size.width = content_rect.size.width * scale;
wd.size.height = content_rect.size.height * scale;
- ds->send_window_event(wd, DisplayServerOSX::WINDOW_EVENT_DPI_CHANGE);
+ ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_DPI_CHANGE);
CALayer *layer = [wd.window_view layer];
if (layer) {
@@ -150,26 +150,26 @@
}
- (void)windowWillStartLiveResize:(NSNotification *)notification {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (ds) {
ds->set_is_resizing(true);
}
}
- (void)windowDidEndLiveResize:(NSNotification *)notification {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (ds) {
ds->set_is_resizing(false);
}
}
- (void)windowDidResize:(NSNotification *)notification {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
const NSRect content_rect = [wd.window_view frame];
const float scale = ds->screen_get_max_scale();
wd.size.width = content_rect.size.width * scale;
@@ -192,12 +192,12 @@
}
- (void)windowDidMove:(NSNotification *)notification {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
ds->release_pressed_events();
if (!wd.rect_changed_callback.is_null()) {
@@ -210,12 +210,12 @@
}
- (void)windowDidBecomeKey:(NSNotification *)notification {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
if (ds->mouse_get_mode() == DisplayServer::MOUSE_MODE_CAPTURED) {
const NSRect content_rect = [wd.window_view frame];
@@ -228,43 +228,43 @@
}
ds->set_last_focused_window(window_id);
- ds->send_window_event(wd, DisplayServerOSX::WINDOW_EVENT_FOCUS_IN);
+ ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_FOCUS_IN);
}
- (void)windowDidResignKey:(NSNotification *)notification {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
ds->release_pressed_events();
- ds->send_window_event(wd, DisplayServerOSX::WINDOW_EVENT_FOCUS_OUT);
+ ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_FOCUS_OUT);
}
- (void)windowDidMiniaturize:(NSNotification *)notification {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
ds->release_pressed_events();
- ds->send_window_event(wd, DisplayServerOSX::WINDOW_EVENT_FOCUS_OUT);
+ ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_FOCUS_OUT);
}
- (void)windowDidDeminiaturize:(NSNotification *)notification {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
ds->set_last_focused_window(window_id);
- ds->send_window_event(wd, DisplayServerOSX::WINDOW_EVENT_FOCUS_IN);
+ ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_FOCUS_IN);
}
@end
diff --git a/platform/osx/joypad_osx.cpp b/platform/macos/joypad_macos.cpp
index be9567e17c..1ddcfec1b5 100644
--- a/platform/osx/joypad_osx.cpp
+++ b/platform/macos/joypad_macos.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* joypad_osx.cpp */
+/* joypad_macos.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,13 +28,13 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "joypad_osx.h"
+#include "joypad_macos.h"
#include <machine/endian.h>
#define GODOT_JOY_LOOP_RUN_MODE CFSTR("GodotJoypad")
-static JoypadOSX *self = nullptr;
+static JoypadMacOS *self = nullptr;
joypad::joypad() {
ff_constant_force.lMagnitude = 10000;
@@ -235,7 +235,7 @@ static bool is_joypad(IOHIDDeviceRef p_device_ref) {
return true;
}
-void JoypadOSX::_device_added(IOReturn p_res, IOHIDDeviceRef p_device) {
+void JoypadMacOS::_device_added(IOReturn p_res, IOHIDDeviceRef p_device) {
if (p_res != kIOReturnSuccess || have_device(p_device)) {
return;
}
@@ -258,7 +258,7 @@ void JoypadOSX::_device_added(IOReturn p_res, IOHIDDeviceRef p_device) {
IOHIDDeviceScheduleWithRunLoop(p_device, CFRunLoopGetCurrent(), GODOT_JOY_LOOP_RUN_MODE);
}
-void JoypadOSX::_device_removed(IOReturn p_res, IOHIDDeviceRef p_device) {
+void JoypadMacOS::_device_removed(IOReturn p_res, IOHIDDeviceRef p_device) {
int device = get_joy_ref(p_device);
ERR_FAIL_COND(device == -1);
@@ -278,7 +278,7 @@ static String _hex_str(uint8_t p_byte) {
return ret;
}
-bool JoypadOSX::configure_joypad(IOHIDDeviceRef p_device_ref, joypad *p_joy) {
+bool JoypadMacOS::configure_joypad(IOHIDDeviceRef p_device_ref, joypad *p_joy) {
p_joy->device_ref = p_device_ref;
// Get device name.
String name;
@@ -445,7 +445,7 @@ static HatMask process_hat_value(int p_min, int p_max, int p_value, bool p_offse
return hat_value;
}
-void JoypadOSX::poll_joypads() const {
+void JoypadMacOS::poll_joypads() const {
while (CFRunLoopRunInMode(GODOT_JOY_LOOP_RUN_MODE, 0, TRUE) == kCFRunLoopRunHandledSource) {
// No-op. Pending callbacks will fire.
}
@@ -456,7 +456,7 @@ static float axis_correct(int p_value, int p_min, int p_max) {
return 2.0f * (p_value - p_min) / (p_max - p_min) - 1.0f;
}
-void JoypadOSX::process_joypads() {
+void JoypadMacOS::process_joypads() {
poll_joypads();
for (int i = 0; i < device_list.size(); i++) {
@@ -494,7 +494,7 @@ void JoypadOSX::process_joypads() {
}
}
-void JoypadOSX::joypad_vibration_start(int p_id, float p_magnitude, float p_duration, uint64_t p_timestamp) {
+void JoypadMacOS::joypad_vibration_start(int p_id, float p_magnitude, float p_duration, uint64_t p_timestamp) {
joypad *joy = &device_list.write[get_joy_index(p_id)];
joy->ff_timestamp = p_timestamp;
joy->ff_effect.dwDuration = p_duration * FF_SECONDS;
@@ -503,13 +503,13 @@ void JoypadOSX::joypad_vibration_start(int p_id, float p_magnitude, float p_dura
FFEffectStart(joy->ff_object, 1, 0);
}
-void JoypadOSX::joypad_vibration_stop(int p_id, uint64_t p_timestamp) {
+void JoypadMacOS::joypad_vibration_stop(int p_id, uint64_t p_timestamp) {
joypad *joy = &device_list.write[get_joy_index(p_id)];
joy->ff_timestamp = p_timestamp;
FFEffectStop(joy->ff_object);
}
-int JoypadOSX::get_joy_index(int p_id) const {
+int JoypadMacOS::get_joy_index(int p_id) const {
for (int i = 0; i < device_list.size(); i++) {
if (device_list[i].id == p_id) {
return i;
@@ -518,7 +518,7 @@ int JoypadOSX::get_joy_index(int p_id) const {
return -1;
}
-int JoypadOSX::get_joy_ref(IOHIDDeviceRef p_device) const {
+int JoypadMacOS::get_joy_ref(IOHIDDeviceRef p_device) const {
for (int i = 0; i < device_list.size(); i++) {
if (device_list[i].device_ref == p_device) {
return i;
@@ -527,7 +527,7 @@ int JoypadOSX::get_joy_ref(IOHIDDeviceRef p_device) const {
return -1;
}
-bool JoypadOSX::have_device(IOHIDDeviceRef p_device) const {
+bool JoypadMacOS::have_device(IOHIDDeviceRef p_device) const {
for (int i = 0; i < device_list.size(); i++) {
if (device_list[i].device_ref == p_device) {
return true;
@@ -561,7 +561,7 @@ static CFDictionaryRef create_match_dictionary(const UInt32 page, const UInt32 u
return retval;
}
-void JoypadOSX::config_hid_manager(CFArrayRef p_matching_array) const {
+void JoypadMacOS::config_hid_manager(CFArrayRef p_matching_array) const {
CFRunLoopRef runloop = CFRunLoopGetCurrent();
IOReturn ret = IOHIDManagerOpen(hid_manager, kIOHIDOptionsTypeNone);
ERR_FAIL_COND(ret != kIOReturnSuccess);
@@ -576,7 +576,7 @@ void JoypadOSX::config_hid_manager(CFArrayRef p_matching_array) const {
}
}
-JoypadOSX::JoypadOSX(Input *in) {
+JoypadMacOS::JoypadMacOS(Input *in) {
self = this;
input = in;
@@ -604,7 +604,7 @@ JoypadOSX::JoypadOSX(Input *in) {
}
}
-JoypadOSX::~JoypadOSX() {
+JoypadMacOS::~JoypadMacOS() {
for (int i = 0; i < device_list.size(); i++) {
device_list.write[i].free();
}
diff --git a/platform/osx/joypad_osx.h b/platform/macos/joypad_macos.h
index 3f89048ce6..4b14fed6d5 100644
--- a/platform/osx/joypad_osx.h
+++ b/platform/macos/joypad_macos.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* joypad_osx.h */
+/* joypad_macos.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef JOYPADOSX_H
-#define JOYPADOSX_H
+#ifndef JOYPAD_MACOS_H
+#define JOYPAD_MACOS_H
#ifdef MACOS_10_0_4
#import <IOKit/hidsystem/IOHIDUsageTables.h>
@@ -88,7 +88,7 @@ struct joypad {
joypad();
};
-class JoypadOSX {
+class JoypadMacOS {
enum {
JOYPADS_MAX = 16,
};
@@ -117,8 +117,8 @@ public:
void _device_added(IOReturn p_res, IOHIDDeviceRef p_device);
void _device_removed(IOReturn p_res, IOHIDDeviceRef p_device);
- JoypadOSX(Input *in);
- ~JoypadOSX();
+ JoypadMacOS(Input *in);
+ ~JoypadMacOS();
};
-#endif // JOYPADOSX_H
+#endif // JOYPAD_MACOS_H
diff --git a/platform/osx/key_mapping_osx.h b/platform/macos/key_mapping_macos.h
index 252cc907bb..fc5b791e44 100644
--- a/platform/osx/key_mapping_osx.h
+++ b/platform/macos/key_mapping_macos.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* key_mapping_osx.h */
+/* key_mapping_macos.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,13 +28,13 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef KEY_MAPPING_OSX_H
-#define KEY_MAPPING_OSX_H
+#ifndef KEY_MAPPING_MACOS_H
+#define KEY_MAPPING_MACOS_H
#include "core/os/keyboard.h"
-class KeyMappingOSX {
- KeyMappingOSX() {}
+class KeyMappingMacOS {
+ KeyMappingMacOS() {}
static bool is_numpad_key(unsigned int key);
@@ -49,4 +49,4 @@ public:
static unsigned int keycode_get_native_mask(Key p_keycode);
};
-#endif // KEY_MAPPING_OSX_H
+#endif // KEY_MAPPING_MACOS_H
diff --git a/platform/osx/key_mapping_osx.mm b/platform/macos/key_mapping_macos.mm
index 0bf6bc7d1c..f6cff7124b 100644
--- a/platform/osx/key_mapping_osx.mm
+++ b/platform/macos/key_mapping_macos.mm
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* key_mapping_osx.mm */
+/* key_mapping_macos.mm */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,12 +28,12 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "key_mapping_osx.h"
+#include "key_mapping_macos.h"
#import <Carbon/Carbon.h>
#import <Cocoa/Cocoa.h>
-bool KeyMappingOSX::is_numpad_key(unsigned int key) {
+bool KeyMappingMacOS::is_numpad_key(unsigned int key) {
static const unsigned int table[] = {
0x41, /* kVK_ANSI_KeypadDecimal */
0x43, /* kVK_ANSI_KeypadMultiply */
@@ -65,7 +65,7 @@ bool KeyMappingOSX::is_numpad_key(unsigned int key) {
}
// Keyboard symbol translation table.
-static const Key _osx_to_godot_table[128] = {
+static const Key _macos_to_godot_table[128] = {
/* 00 */ Key::A,
/* 01 */ Key::S,
/* 02 */ Key::D,
@@ -197,18 +197,18 @@ static const Key _osx_to_godot_table[128] = {
};
// Translates a OS X keycode to a Godot keycode.
-Key KeyMappingOSX::translate_key(unsigned int key) {
+Key KeyMappingMacOS::translate_key(unsigned int key) {
if (key >= 128) {
return Key::UNKNOWN;
}
- return _osx_to_godot_table[key];
+ return _macos_to_godot_table[key];
}
-// Translates a Godot keycode back to a OSX keycode.
-unsigned int KeyMappingOSX::unmap_key(Key key) {
+// Translates a Godot keycode back to a macOS keycode.
+unsigned int KeyMappingMacOS::unmap_key(Key key) {
for (int i = 0; i <= 126; i++) {
- if (_osx_to_godot_table[i] == key) {
+ if (_macos_to_godot_table[i] == key) {
return i;
}
}
@@ -279,7 +279,7 @@ static const _KeyCodeMap _keycodes[55] = {
};
// Remap key according to current keyboard layout.
-Key KeyMappingOSX::remap_key(unsigned int key, unsigned int state) {
+Key KeyMappingMacOS::remap_key(unsigned int key, unsigned int state) {
if (is_numpad_key(key)) {
return translate_key(key);
}
@@ -463,7 +463,7 @@ static const _KeyCodeText _native_keycodes[] = {
/* clang-format on */
};
-String KeyMappingOSX::keycode_get_native_string(Key p_keycode) {
+String KeyMappingMacOS::keycode_get_native_string(Key p_keycode) {
const _KeyCodeText *kct = &_native_keycodes[0];
while (kct->text) {
@@ -475,7 +475,7 @@ String KeyMappingOSX::keycode_get_native_string(Key p_keycode) {
return String();
}
-unsigned int KeyMappingOSX::keycode_get_native_mask(Key p_keycode) {
+unsigned int KeyMappingMacOS::keycode_get_native_mask(Key p_keycode) {
unsigned int mask = 0;
if ((p_keycode & KeyModifierMask::CTRL) != Key::NONE) {
mask |= NSEventModifierFlagControl;
diff --git a/platform/osx/logo.png b/platform/macos/logo.png
index b5a660b165..b5a660b165 100644
--- a/platform/osx/logo.png
+++ b/platform/macos/logo.png
Binary files differ
diff --git a/platform/osx/osx_terminal_logger.h b/platform/macos/macos_terminal_logger.h
index 8413509c4b..a811a5cbaf 100644
--- a/platform/osx/osx_terminal_logger.h
+++ b/platform/macos/macos_terminal_logger.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* osx_terminal_logger.h */
+/* macos_terminal_logger.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,17 +28,18 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef OSX_TERMINAL_LOGGER_H
-#define OSX_TERMINAL_LOGGER_H
+#ifndef MACOS_TERMINAL_LOGGER_H
+#define MACOS_TERMINAL_LOGGER_H
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
#include "core/io/logger.h"
-class OSXTerminalLogger : public StdLogger {
+class MacOSTerminalLogger : public StdLogger {
public:
virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify = false, ErrorType p_type = ERR_ERROR) override;
};
-#endif // OSX_ENABLED
-#endif // OSX_TERMINAL_LOGGER_H
+#endif // MACOS_ENABLED
+
+#endif // MACOS_TERMINAL_LOGGER_H
diff --git a/platform/osx/osx_terminal_logger.mm b/platform/macos/macos_terminal_logger.mm
index 48e26f42bf..b5ea2938ee 100644
--- a/platform/osx/osx_terminal_logger.mm
+++ b/platform/macos/macos_terminal_logger.mm
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* osx_terminal_logger.mm */
+/* macos_terminal_logger.mm */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,13 +28,13 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "osx_terminal_logger.h"
+#include "macos_terminal_logger.h"
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
#include <os/log.h>
-void OSXTerminalLogger::log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify, ErrorType p_type) {
+void MacOSTerminalLogger::log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify, ErrorType p_type) {
if (!should_log(true)) {
return;
}
@@ -79,4 +79,4 @@ void OSXTerminalLogger::log_error(const char *p_function, const char *p_file, in
}
}
-#endif // OSX_ENABLED
+#endif // MACOS_ENABLED
diff --git a/platform/osx/os_osx.h b/platform/macos/os_macos.h
index e4ec411c96..a6c23ab71e 100644
--- a/platform/osx/os_osx.h
+++ b/platform/macos/os_macos.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* os_osx.h */
+/* os_macos.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,21 +28,21 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef OS_OSX_H
-#define OS_OSX_H
+#ifndef OS_MACOS_H
+#define OS_MACOS_H
#include "core/input/input.h"
-#include "crash_handler_osx.h"
+#include "crash_handler_macos.h"
#include "drivers/coreaudio/audio_driver_coreaudio.h"
#include "drivers/coremidi/midi_driver_coremidi.h"
#include "drivers/unix/os_unix.h"
-#include "joypad_osx.h"
+#include "joypad_macos.h"
#include "servers/audio_server.h"
-class OS_OSX : public OS_Unix {
+class OS_MacOS : public OS_Unix {
bool force_quit = false;
- JoypadOSX *joypad_osx = nullptr;
+ JoypadMacOS *joypad_macos = nullptr;
#ifdef COREAUDIO_ENABLED
AudioDriverCoreAudio audio_driver;
@@ -57,7 +57,7 @@ class OS_OSX : public OS_Unix {
MainLoop *main_loop = nullptr;
- String open_with_filename;
+ List<String> launch_service_args;
static _FORCE_INLINE_ String get_framework_executable(const String &p_path);
static void pre_wait_observer_cb(CFRunLoopObserverRef p_observer, CFRunLoopActivity p_activiy, void *p_context);
@@ -73,8 +73,8 @@ protected:
virtual void delete_main_loop() override;
public:
- String get_open_with_filename() const;
- void set_open_with_filename(const String &p_path);
+ virtual void set_cmdline_platform_args(const List<String> &p_args);
+ virtual List<String> get_cmdline_platform_args() const override;
virtual String get_name() const override;
@@ -113,8 +113,8 @@ public:
void run();
- OS_OSX();
- ~OS_OSX();
+ OS_MacOS();
+ ~OS_MacOS();
};
-#endif
+#endif // OS_MACOS_H
diff --git a/platform/osx/os_osx.mm b/platform/macos/os_macos.mm
index a8fa56e34b..2c6cd7de0b 100644
--- a/platform/osx/os_osx.mm
+++ b/platform/macos/os_macos.mm
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* os_osx.mm */
+/* os_macos.mm */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,16 +28,16 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "os_osx.h"
+#include "os_macos.h"
#include "core/version_generated.gen.h"
#include "main/main.h"
-#include "dir_access_osx.h"
-#include "display_server_osx.h"
+#include "dir_access_macos.h"
+#include "display_server_macos.h"
#include "godot_application.h"
#include "godot_application_delegate.h"
-#include "osx_terminal_logger.h"
+#include "macos_terminal_logger.h"
#include <dlfcn.h>
#include <libproc.h>
@@ -45,7 +45,7 @@
#include <os/log.h>
#include <sys/sysctl.h>
-_FORCE_INLINE_ String OS_OSX::get_framework_executable(const String &p_path) {
+_FORCE_INLINE_ String OS_MacOS::get_framework_executable(const String &p_path) {
// Append framework executable name, or return as is if p_path is not a framework.
Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
if (da->dir_exists(p_path) && da->file_exists(p_path.plus_file(p_path.get_file().get_basename()))) {
@@ -55,10 +55,10 @@ _FORCE_INLINE_ String OS_OSX::get_framework_executable(const String &p_path) {
}
}
-void OS_OSX::pre_wait_observer_cb(CFRunLoopObserverRef p_observer, CFRunLoopActivity p_activiy, void *p_context) {
+void OS_MacOS::pre_wait_observer_cb(CFRunLoopObserverRef p_observer, CFRunLoopActivity p_activiy, void *p_context) {
// Prevent main loop from sleeping and redraw window during resize / modal popups.
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (get_singleton()->get_main_loop() && ds && (get_singleton()->get_render_thread_mode() != RENDER_SEPARATE_THREAD || !ds->get_is_resizing())) {
Main::force_redraw();
if (!Main::is_iterating()) { // Avoid cyclic loop.
@@ -69,13 +69,13 @@ void OS_OSX::pre_wait_observer_cb(CFRunLoopObserverRef p_observer, CFRunLoopActi
CFRunLoopWakeUp(CFRunLoopGetCurrent()); // Prevent main loop from sleeping.
}
-void OS_OSX::initialize() {
+void OS_MacOS::initialize() {
crash_handler.initialize();
initialize_core();
}
-String OS_OSX::get_processor_name() const {
+String OS_MacOS::get_processor_name() const {
char buffer[256];
size_t buffer_len = 256;
if (sysctlbyname("machdep.cpu.brand_string", &buffer, &buffer_len, NULL, 0) == 0) {
@@ -84,35 +84,35 @@ String OS_OSX::get_processor_name() const {
ERR_FAIL_V_MSG("", String("Couldn't get the CPU model name. Returning an empty string."));
}
-void OS_OSX::initialize_core() {
+void OS_MacOS::initialize_core() {
OS_Unix::initialize_core();
- DirAccess::make_default<DirAccessOSX>(DirAccess::ACCESS_RESOURCES);
- DirAccess::make_default<DirAccessOSX>(DirAccess::ACCESS_USERDATA);
- DirAccess::make_default<DirAccessOSX>(DirAccess::ACCESS_FILESYSTEM);
+ DirAccess::make_default<DirAccessMacOS>(DirAccess::ACCESS_RESOURCES);
+ DirAccess::make_default<DirAccessMacOS>(DirAccess::ACCESS_USERDATA);
+ DirAccess::make_default<DirAccessMacOS>(DirAccess::ACCESS_FILESYSTEM);
}
-void OS_OSX::finalize() {
+void OS_MacOS::finalize() {
#ifdef COREMIDI_ENABLED
midi_driver.close();
#endif
delete_main_loop();
- if (joypad_osx) {
- memdelete(joypad_osx);
+ if (joypad_macos) {
+ memdelete(joypad_macos);
}
}
-void OS_OSX::initialize_joypads() {
- joypad_osx = memnew(JoypadOSX(Input::get_singleton()));
+void OS_MacOS::initialize_joypads() {
+ joypad_macos = memnew(JoypadMacOS(Input::get_singleton()));
}
-void OS_OSX::set_main_loop(MainLoop *p_main_loop) {
+void OS_MacOS::set_main_loop(MainLoop *p_main_loop) {
main_loop = p_main_loop;
}
-void OS_OSX::delete_main_loop() {
+void OS_MacOS::delete_main_loop() {
if (!main_loop) {
return;
}
@@ -121,19 +121,19 @@ void OS_OSX::delete_main_loop() {
main_loop = nullptr;
}
-String OS_OSX::get_open_with_filename() const {
- return open_with_filename;
+void OS_MacOS::set_cmdline_platform_args(const List<String> &p_args) {
+ launch_service_args = p_args;
}
-void OS_OSX::set_open_with_filename(const String &p_path) {
- open_with_filename = p_path;
+List<String> OS_MacOS::get_cmdline_platform_args() const {
+ return launch_service_args;
}
-String OS_OSX::get_name() const {
+String OS_MacOS::get_name() const {
return "macOS";
}
-void OS_OSX::alert(const String &p_alert, const String &p_title) {
+void OS_MacOS::alert(const String &p_alert, const String &p_title) {
NSAlert *window = [[NSAlert alloc] init];
NSString *ns_title = [NSString stringWithUTF8String:p_title.utf8().get_data()];
NSString *ns_alert = [NSString stringWithUTF8String:p_alert.utf8().get_data()];
@@ -150,7 +150,7 @@ void OS_OSX::alert(const String &p_alert, const String &p_title) {
}
}
-Error OS_OSX::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path, String *r_resolved_path) {
+Error OS_MacOS::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path, String *r_resolved_path) {
String path = get_framework_executable(p_path);
if (!FileAccess::exists(path)) {
@@ -173,11 +173,11 @@ Error OS_OSX::open_dynamic_library(const String p_path, void *&p_library_handle,
return OK;
}
-MainLoop *OS_OSX::get_main_loop() const {
+MainLoop *OS_MacOS::get_main_loop() const {
return main_loop;
}
-String OS_OSX::get_config_path() const {
+String OS_MacOS::get_config_path() const {
// The XDG Base Directory specification technically only applies on Linux/*BSD, but it doesn't hurt to support it on macOS as well.
if (has_environment("XDG_CONFIG_HOME")) {
if (get_environment("XDG_CONFIG_HOME").is_absolute_path()) {
@@ -192,7 +192,7 @@ String OS_OSX::get_config_path() const {
return ".";
}
-String OS_OSX::get_data_path() const {
+String OS_MacOS::get_data_path() const {
// The XDG Base Directory specification technically only applies on Linux/*BSD, but it doesn't hurt to support it on macOS as well.
if (has_environment("XDG_DATA_HOME")) {
if (get_environment("XDG_DATA_HOME").is_absolute_path()) {
@@ -204,7 +204,7 @@ String OS_OSX::get_data_path() const {
return get_config_path();
}
-String OS_OSX::get_cache_path() const {
+String OS_MacOS::get_cache_path() const {
// The XDG Base Directory specification technically only applies on Linux/*BSD, but it doesn't hurt to support it on macOS as well.
if (has_environment("XDG_CACHE_HOME")) {
if (get_environment("XDG_CACHE_HOME").is_absolute_path()) {
@@ -219,7 +219,7 @@ String OS_OSX::get_cache_path() const {
return get_config_path();
}
-String OS_OSX::get_bundle_resource_dir() const {
+String OS_MacOS::get_bundle_resource_dir() const {
String ret;
NSBundle *main = [NSBundle mainBundle];
@@ -230,7 +230,7 @@ String OS_OSX::get_bundle_resource_dir() const {
return ret;
}
-String OS_OSX::get_bundle_icon_path() const {
+String OS_MacOS::get_bundle_icon_path() const {
String ret;
NSBundle *main = [NSBundle mainBundle];
@@ -244,11 +244,11 @@ String OS_OSX::get_bundle_icon_path() const {
}
// Get properly capitalized engine name for system paths
-String OS_OSX::get_godot_dir_name() const {
+String OS_MacOS::get_godot_dir_name() const {
return String(VERSION_SHORT_NAME).capitalize();
}
-String OS_OSX::get_system_dir(SystemDir p_dir, bool p_shared_storage) const {
+String OS_MacOS::get_system_dir(SystemDir p_dir, bool p_shared_storage) const {
NSSearchPathDirectory id;
bool found = true;
@@ -287,7 +287,7 @@ String OS_OSX::get_system_dir(SystemDir p_dir, bool p_shared_storage) const {
return ret;
}
-Error OS_OSX::shell_open(String p_uri) {
+Error OS_MacOS::shell_open(String p_uri) {
NSString *string = [NSString stringWithUTF8String:p_uri.utf8().get_data()];
NSURL *uri = [[NSURL alloc] initWithString:string];
// Escape special characters in filenames
@@ -298,12 +298,12 @@ Error OS_OSX::shell_open(String p_uri) {
return OK;
}
-String OS_OSX::get_locale() const {
+String OS_MacOS::get_locale() const {
NSString *locale_code = [[NSLocale preferredLanguages] objectAtIndex:0];
return String([locale_code UTF8String]).replace("-", "_");
}
-String OS_OSX::get_executable_path() const {
+String OS_MacOS::get_executable_path() const {
char pathbuf[PROC_PIDPATHINFO_MAXSIZE];
int pid = getpid();
pid_t ret = proc_pidpath(pid, pathbuf, sizeof(pathbuf));
@@ -317,7 +317,7 @@ String OS_OSX::get_executable_path() const {
}
}
-Error OS_OSX::create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id, bool p_open_console) {
+Error OS_MacOS::create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id, bool p_open_console) {
// Use NSWorkspace if path is an .app bundle.
NSURL *url = [NSURL fileURLWithPath:@(p_path.utf8().get_data())];
NSBundle *bundle = [NSBundle bundleWithURL:url];
@@ -375,7 +375,7 @@ Error OS_OSX::create_process(const String &p_path, const List<String> &p_argumen
}
}
-Error OS_OSX::create_instance(const List<String> &p_arguments, ProcessID *r_child_id) {
+Error OS_MacOS::create_instance(const List<String> &p_arguments, ProcessID *r_child_id) {
// If executable is bundled, always execute editor instances as an app bundle to ensure app window is registered and activated correctly.
NSString *nsappname = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"];
if (nsappname != nil) {
@@ -387,7 +387,7 @@ Error OS_OSX::create_instance(const List<String> &p_arguments, ProcessID *r_chil
}
}
-String OS_OSX::get_unique_id() const {
+String OS_MacOS::get_unique_id() const {
static String serial_number;
if (serial_number.is_empty()) {
@@ -412,19 +412,19 @@ String OS_OSX::get_unique_id() const {
return serial_number;
}
-bool OS_OSX::_check_internal_feature_support(const String &p_feature) {
+bool OS_MacOS::_check_internal_feature_support(const String &p_feature) {
return p_feature == "pc";
}
-void OS_OSX::disable_crash_handler() {
+void OS_MacOS::disable_crash_handler() {
crash_handler.disable();
}
-bool OS_OSX::is_disable_crash_handler() const {
+bool OS_MacOS::is_disable_crash_handler() const {
return crash_handler.is_disabled();
}
-Error OS_OSX::move_to_trash(const String &p_path) {
+Error OS_MacOS::move_to_trash(const String &p_path) {
NSFileManager *fm = [NSFileManager defaultManager];
NSURL *url = [NSURL fileURLWithPath:@(p_path.utf8().get_data())];
NSError *err;
@@ -437,7 +437,7 @@ Error OS_OSX::move_to_trash(const String &p_path) {
return OK;
}
-void OS_OSX::run() {
+void OS_MacOS::run() {
force_quit = false;
if (!main_loop) {
@@ -452,7 +452,7 @@ void OS_OSX::run() {
if (DisplayServer::get_singleton()) {
DisplayServer::get_singleton()->process_events(); // Get rid of pending events.
}
- joypad_osx->process_joypads();
+ joypad_macos->process_joypads();
if (Main::iteration()) {
quit = true;
@@ -465,19 +465,19 @@ void OS_OSX::run() {
main_loop->finalize();
}
-OS_OSX::OS_OSX() {
+OS_MacOS::OS_MacOS() {
main_loop = nullptr;
force_quit = false;
Vector<Logger *> loggers;
- loggers.push_back(memnew(OSXTerminalLogger));
+ loggers.push_back(memnew(MacOSTerminalLogger));
_set_logger(memnew(CompositeLogger(loggers)));
#ifdef COREAUDIO_ENABLED
AudioDriverManager::add_driver(&audio_driver);
#endif
- DisplayServerOSX::register_osx_driver();
+ DisplayServerMacOS::register_macos_driver();
// Implicitly create shared NSApplication instance.
[GodotApplication sharedApplication];
@@ -518,7 +518,7 @@ OS_OSX::OS_OSX() {
[NSApp activateIgnoringOtherApps:YES];
}
-OS_OSX::~OS_OSX() {
+OS_MacOS::~OS_MacOS() {
CFRunLoopRemoveObserver(CFRunLoopGetCurrent(), pre_wait_observer, kCFRunLoopCommonModes);
CFRelease(pre_wait_observer);
}
diff --git a/platform/osx/platform_config.h b/platform/macos/platform_config.h
index e114606b82..e114606b82 100644
--- a/platform/osx/platform_config.h
+++ b/platform/macos/platform_config.h
diff --git a/platform/osx/platform_osx_builders.py b/platform/macos/platform_macos_builders.py
index 953ed479db..3a1cc92bd2 100644
--- a/platform/osx/platform_osx_builders.py
+++ b/platform/macos/platform_macos_builders.py
@@ -7,7 +7,7 @@ import os
from platform_methods import subprocess_main
-def make_debug_osx(target, source, env):
+def make_debug_macos(target, source, env):
if env["macports_clang"] != "no":
mpprefix = os.environ.get("MACPORTS_PREFIX", "/opt/local")
mpclangver = env["macports_clang"]
diff --git a/platform/osx/tts_osx.h b/platform/macos/tts_macos.h
index 449418e48f..344676868a 100644
--- a/platform/osx/tts_osx.h
+++ b/platform/macos/tts_macos.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* tts_osx.h */
+/* tts_macos.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef TTS_OSX_H
-#define TTS_OSX_H
+#ifndef TTS_MACOS_H
+#define TTS_MACOS_H
#include "core/string/ustring.h"
#include "core/templates/list.h"
@@ -45,7 +45,7 @@
#import <AVFoundation/AVFoundation.h>
#endif
-@interface TTS_OSX : NSObject <AVSpeechSynthesizerDelegate> {
+@interface TTS_MacOS : NSObject <AVSpeechSynthesizerDelegate> {
// AVSpeechSynthesizer
bool speaking;
HashMap<id, int> ids;
@@ -68,4 +68,4 @@
- (Array)getVoices;
@end
-#endif // TTS_OSX_H
+#endif // TTS_MACOS_H
diff --git a/platform/osx/tts_osx.mm b/platform/macos/tts_macos.mm
index e6a5236cd9..3c101b9531 100644
--- a/platform/osx/tts_osx.mm
+++ b/platform/macos/tts_macos.mm
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* tts_osx.mm */
+/* tts_macos.mm */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,9 +28,9 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "tts_osx.h"
+#include "tts_macos.h"
-@implementation TTS_OSX
+@implementation TTS_MacOS
- (id)init {
self = [super init];
diff --git a/platform/osx/vulkan_context_osx.h b/platform/macos/vulkan_context_macos.h
index ade0f4a4c9..579c42b042 100644
--- a/platform/osx/vulkan_context_osx.h
+++ b/platform/macos/vulkan_context_macos.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* vulkan_context_osx.h */
+/* vulkan_context_macos.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,20 +28,20 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef VULKAN_DEVICE_OSX_H
-#define VULKAN_DEVICE_OSX_H
+#ifndef VULKAN_CONTEXT_MACOS_H
+#define VULKAN_CONTEXT_MACOS_H
#include "drivers/vulkan/vulkan_context.h"
#import <AppKit/AppKit.h>
-class VulkanContextOSX : public VulkanContext {
+class VulkanContextMacOS : public VulkanContext {
virtual const char *_get_platform_surface_extension() const;
public:
Error window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, id p_window, int p_width, int p_height);
- VulkanContextOSX();
- ~VulkanContextOSX();
+ VulkanContextMacOS();
+ ~VulkanContextMacOS();
};
-#endif // VULKAN_DEVICE_OSX_H
+#endif // VULKAN_CONTEXT_MACOS_H
diff --git a/platform/osx/vulkan_context_osx.mm b/platform/macos/vulkan_context_macos.mm
index bdabc24c28..cf317f3c68 100644
--- a/platform/osx/vulkan_context_osx.mm
+++ b/platform/macos/vulkan_context_macos.mm
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* vulkan_context_osx.mm */
+/* vulkan_context_macos.mm */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,18 +28,18 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "vulkan_context_osx.h"
+#include "vulkan_context_macos.h"
#ifdef USE_VOLK
#include <volk.h>
#else
#include <vulkan/vulkan.h>
#endif
-const char *VulkanContextOSX::_get_platform_surface_extension() const {
+const char *VulkanContextMacOS::_get_platform_surface_extension() const {
return VK_MVK_MACOS_SURFACE_EXTENSION_NAME;
}
-Error VulkanContextOSX::window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, id p_window, int p_width, int p_height) {
+Error VulkanContextMacOS::window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, id p_window, int p_width, int p_height) {
VkMacOSSurfaceCreateInfoMVK createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK;
createInfo.pNext = nullptr;
@@ -52,8 +52,8 @@ Error VulkanContextOSX::window_create(DisplayServer::WindowID p_window_id, Displ
return _window_create(p_window_id, p_vsync_mode, surface, p_width, p_height);
}
-VulkanContextOSX::VulkanContextOSX() {
+VulkanContextMacOS::VulkanContextMacOS() {
}
-VulkanContextOSX::~VulkanContextOSX() {
+VulkanContextMacOS::~VulkanContextMacOS() {
}
diff --git a/platform/osx/SCsub b/platform/osx/SCsub
deleted file mode 100644
index 3a4c95613d..0000000000
--- a/platform/osx/SCsub
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/usr/bin/env python
-
-Import("env")
-
-from platform_methods import run_in_subprocess
-import platform_osx_builders
-
-files = [
- "os_osx.mm",
- "godot_application.mm",
- "godot_application_delegate.mm",
- "crash_handler_osx.mm",
- "osx_terminal_logger.mm",
- "display_server_osx.mm",
- "godot_content_view.mm",
- "godot_window_delegate.mm",
- "godot_window.mm",
- "key_mapping_osx.mm",
- "godot_main_osx.mm",
- "dir_access_osx.mm",
- "tts_osx.mm",
- "joypad_osx.cpp",
- "vulkan_context_osx.mm",
- "gl_manager_osx_legacy.mm",
-]
-
-prog = env.add_program("#bin/godot", files)
-
-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/register_platform_apis.h b/platform/register_platform_apis.h
index 8b6d23a7a4..9dd90d9b20 100644
--- a/platform/register_platform_apis.h
+++ b/platform/register_platform_apis.h
@@ -28,10 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef REGISTER_APIS_H
-#define REGISTER_APIS_H
+#ifndef REGISTER_PLATFORM_APIS_H
+#define REGISTER_PLATFORM_APIS_H
void register_platform_apis();
void unregister_platform_apis();
-#endif
+#endif // REGISTER_PLATFORM_APIS_H
diff --git a/platform/uwp/app_uwp.h b/platform/uwp/app_uwp.h
index 9aadcfac75..82ad3ca01a 100644
--- a/platform/uwp/app_uwp.h
+++ b/platform/uwp/app_uwp.h
@@ -112,4 +112,5 @@ namespace GodotUWP
}
/* clang-format on */
+
#endif // APP_UWP_H
diff --git a/platform/uwp/export/app_packager.h b/platform/uwp/export/app_packager.h
index dc5a5259ec..18db3eb806 100644
--- a/platform/uwp/export/app_packager.h
+++ b/platform/uwp/export/app_packager.h
@@ -40,7 +40,7 @@
#include "core/io/zip_io.h"
#include "core/object/class_db.h"
#include "core/version.h"
-#include "editor/editor_export.h"
+#include "editor/export/editor_export_platform.h"
#include "thirdparty/minizip/unzip.h"
#include "thirdparty/minizip/zip.h"
@@ -146,4 +146,4 @@ public:
~AppxPackager();
};
-#endif
+#endif // UWP_APP_PACKAGER_H
diff --git a/platform/uwp/export/export_plugin.cpp b/platform/uwp/export/export_plugin.cpp
index 01683c656c..19b43d50be 100644
--- a/platform/uwp/export/export_plugin.cpp
+++ b/platform/uwp/export/export_plugin.cpp
@@ -503,7 +503,5 @@ void EditorExportPlatformUWP::resolve_platform_feature_priorities(const Ref<Edit
}
EditorExportPlatformUWP::EditorExportPlatformUWP() {
- Ref<Image> img = memnew(Image(_uwp_logo));
- logo.instantiate();
- logo->create_from_image(img);
+ logo = ImageTexture::create_from_image(memnew(Image(_uwp_logo)));
}
diff --git a/platform/uwp/export/export_plugin.h b/platform/uwp/export/export_plugin.h
index d92687075c..c1a1f8a935 100644
--- a/platform/uwp/export/export_plugin.h
+++ b/platform/uwp/export/export_plugin.h
@@ -39,9 +39,9 @@
#include "core/io/zip_io.h"
#include "core/object/class_db.h"
#include "core/version.h"
-#include "editor/editor_export.h"
#include "editor/editor_node.h"
#include "editor/editor_paths.h"
+#include "editor/export/editor_export_platform.h"
#include "thirdparty/minizip/unzip.h"
#include "thirdparty/minizip/zip.h"
@@ -446,4 +446,4 @@ public:
EditorExportPlatformUWP();
};
-#endif
+#endif // UWP_EXPORT_PLUGIN_H
diff --git a/platform/uwp/joypad_uwp.h b/platform/uwp/joypad_uwp.h
index 0869f1961d..81f84152b9 100644
--- a/platform/uwp/joypad_uwp.h
+++ b/platform/uwp/joypad_uwp.h
@@ -78,4 +78,4 @@ private:
void joypad_vibration_stop(int p_device, uint64_t p_timestamp);
};
-#endif
+#endif // JOYPAD_UWP_H
diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp
index 1614bfdcc3..f37759c66f 100644
--- a/platform/uwp/os_uwp.cpp
+++ b/platform/uwp/os_uwp.cpp
@@ -557,6 +557,7 @@ uint64_t OS_UWP::get_ticks_usec() const {
void OS_UWP::process_events() {
joypad->process_controllers();
process_key_events();
+ input->flush_buffered_events();
}
void OS_UWP::process_key_events() {
diff --git a/platform/uwp/os_uwp.h b/platform/uwp/os_uwp.h
index bddf63ff18..b9d035ff41 100644
--- a/platform/uwp/os_uwp.h
+++ b/platform/uwp/os_uwp.h
@@ -252,4 +252,4 @@ public:
~OS_UWP();
};
-#endif
+#endif // OS_UWP_H
diff --git a/platform/windows/detect.py b/platform/windows/detect.py
index b82fe5e7ad..6a7caf4656 100644
--- a/platform/windows/detect.py
+++ b/platform/windows/detect.py
@@ -198,7 +198,6 @@ def configure_msvc(env, manual_msvc_config):
elif env["target"] == "debug":
env.AppendUnique(CCFLAGS=["/Zi", "/FS", "/Od", "/EHsc"])
# Allow big objects. Only needed for debug, see MinGW branch for rationale.
- env.AppendUnique(CCFLAGS=["/bigobj"])
env.Append(LINKFLAGS=["/DEBUG"])
if env["debug_symbols"]:
@@ -221,6 +220,10 @@ def configure_msvc(env, manual_msvc_config):
env.AppendUnique(CCFLAGS=["/Gd", "/GR", "/nologo"])
env.AppendUnique(CCFLAGS=["/utf-8"]) # Force to use Unicode encoding.
env.AppendUnique(CXXFLAGS=["/TP"]) # assume all sources are C++
+ # Once it was thought that only debug builds would be too large,
+ # but this has recently stopped being true. See the mingw function
+ # for notes on why this shouldn't be enabled for gcc
+ env.AppendUnique(CCFLAGS=["/bigobj"])
if manual_msvc_config: # should be automatic if SCons found it
if os.getenv("WindowsSdkDir") is not None:
diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp
index 998b0882b3..f9988b23bc 100644
--- a/platform/windows/display_server_windows.cpp
+++ b/platform/windows/display_server_windows.cpp
@@ -656,7 +656,9 @@ void DisplayServerWindows::delete_sub_window(WindowID p_window) {
void DisplayServerWindows::gl_window_make_current(DisplayServer::WindowID p_window_id) {
#if defined(GLES3_ENABLED)
- gl_manager->window_make_current(p_window_id);
+ if (gl_manager) {
+ gl_manager->window_make_current(p_window_id);
+ }
#endif
}
@@ -2380,7 +2382,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
}
case WM_MOUSELEAVE: {
old_invalid = true;
- outside = true;
+ windows[window_id].mouse_outside = true;
_send_window_event(windows[window_id], WINDOW_EVENT_MOUSE_EXIT);
@@ -2490,6 +2492,8 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
windows[window_id].last_tilt = Vector2();
}
+ windows[window_id].last_pen_inverted = packet.pkStatus & TPS_INVERT;
+
POINT coords;
GetCursorPos(&coords);
ScreenToClient(windows[window_id].hWnd, &coords);
@@ -2508,6 +2512,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
mm->set_pressure(windows[window_id].last_pressure);
mm->set_tilt(windows[window_id].last_tilt);
+ mm->set_pen_inverted(windows[window_id].last_pen_inverted);
mm->set_button_mask(last_button_state);
@@ -2607,7 +2612,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
}
}
- if (outside) {
+ if (windows[window_id].mouse_outside) {
// Mouse enter.
if (mouse_mode != MOUSE_MODE_CAPTURED) {
@@ -2617,7 +2622,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
CursorShape c = cursor_shape;
cursor_shape = CURSOR_MAX;
cursor_set_shape(c);
- outside = false;
+ windows[window_id].mouse_outside = false;
// Once-off notification, must call again.
track_mouse_leave_event(hWnd);
@@ -2640,6 +2645,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
if ((pen_info.penMask & PEN_MASK_TILT_X) && (pen_info.penMask & PEN_MASK_TILT_Y)) {
mm->set_tilt(Vector2((float)pen_info.tiltX / 90, (float)pen_info.tiltY / 90));
}
+ mm->set_pen_inverted(pen_info.penFlags & (PEN_FLAG_INVERTED | PEN_FLAG_ERASER));
mm->set_ctrl_pressed(GetKeyState(VK_CONTROL) < 0);
mm->set_shift_pressed(GetKeyState(VK_SHIFT) < 0);
@@ -2707,7 +2713,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
}
}
- if (outside) {
+ if (windows[window_id].mouse_outside) {
// Mouse enter.
if (mouse_mode != MOUSE_MODE_CAPTURED) {
@@ -2717,7 +2723,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
CursorShape c = cursor_shape;
cursor_shape = CURSOR_MAX;
cursor_set_shape(c);
- outside = false;
+ windows[window_id].mouse_outside = false;
// Once-off notification, must call again.
track_mouse_leave_event(hWnd);
@@ -2742,14 +2748,17 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
} else {
windows[window_id].last_tilt = Vector2();
windows[window_id].last_pressure = (wParam & MK_LBUTTON) ? 1.0f : 0.0f;
+ windows[window_id].last_pen_inverted = false;
}
} else {
windows[window_id].last_tilt = Vector2();
windows[window_id].last_pressure = (wParam & MK_LBUTTON) ? 1.0f : 0.0f;
+ windows[window_id].last_pen_inverted = false;
}
mm->set_pressure(windows[window_id].last_pressure);
mm->set_tilt(windows[window_id].last_tilt);
+ mm->set_pen_inverted(windows[window_id].last_pen_inverted);
mm->set_button_mask(last_button_state);
@@ -3360,8 +3369,8 @@ void DisplayServerWindows::_update_tablet_ctx(const String &p_old_driver, const
if ((p_new_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;
- wd.wtlc.lcMoveMask = PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE;
+ wd.wtlc.lcPktData = PK_STATUS | PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE | PK_ORIENTATION;
+ wd.wtlc.lcMoveMask = PK_STATUS | PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE;
wd.wtlc.lcPktMode = 0;
wd.wtlc.lcOutOrgX = 0;
wd.wtlc.lcOutExtX = wd.wtlc.lcInExtX;
@@ -3449,6 +3458,12 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode,
windows.erase(id);
ERR_FAIL_V_MSG(INVALID_WINDOW_ID, "Failed to create Windows OS window.");
}
+ if (p_mode == WINDOW_MODE_FULLSCREEN || p_mode == WINDOW_MODE_EXCLUSIVE_FULLSCREEN) {
+ wd.fullscreen = true;
+ if (p_mode == WINDOW_MODE_FULLSCREEN) {
+ wd.multiwindow_fs = true;
+ }
+ }
if (p_mode != WINDOW_MODE_FULLSCREEN && p_mode != WINDOW_MODE_EXCLUSIVE_FULLSCREEN) {
wd.pre_fs_valid = true;
}
@@ -3484,8 +3499,8 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode,
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;
- wd.wtlc.lcMoveMask = PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE;
+ wd.wtlc.lcPktData = PK_STATUS | PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE | PK_ORIENTATION;
+ wd.wtlc.lcMoveMask = PK_STATUS | PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE;
wd.wtlc.lcPktMode = 0;
wd.wtlc.lcOutOrgX = 0;
wd.wtlc.lcOutExtX = wd.wtlc.lcInExtX;
@@ -3599,8 +3614,6 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
old_invalid = true;
mouse_mode = MOUSE_MODE_VISIBLE;
- outside = true;
-
rendering_driver = p_rendering_driver;
// Init TTS
diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h
index fc89517774..ddbf674c64 100644
--- a/platform/windows/display_server_windows.h
+++ b/platform/windows/display_server_windows.h
@@ -82,10 +82,13 @@
#define DVC_ROTATION 18
#define CXO_MESSAGES 0x0004
+#define PK_STATUS 0x0002
#define PK_NORMAL_PRESSURE 0x0400
#define PK_TANGENT_PRESSURE 0x0800
#define PK_ORIENTATION 0x1000
+#define TPS_INVERT 0x0010 /* 1.1 */
+
typedef struct tagLOGCONTEXTW {
WCHAR lcName[40];
UINT lcOptions;
@@ -137,6 +140,7 @@ typedef struct tagORIENTATION {
} ORIENTATION;
typedef struct tagPACKET {
+ int pkStatus;
int pkNormalPressure;
int pkTangentPressure;
ORIENTATION pkOrientation;
@@ -158,6 +162,14 @@ typedef UINT32 POINTER_FLAGS;
typedef UINT32 PEN_FLAGS;
typedef UINT32 PEN_MASK;
+#ifndef PEN_FLAG_INVERTED
+#define PEN_FLAG_INVERTED 0x00000002
+#endif
+
+#ifndef PEN_FLAG_ERASER
+#define PEN_FLAG_ERASER 0x00000004
+#endif
+
#ifndef PEN_MASK_PRESSURE
#define PEN_MASK_PRESSURE 0x00000001
#endif
@@ -301,7 +313,6 @@ class DisplayServerWindows : public DisplayServer {
int key_event_pos;
bool old_invalid;
- bool outside;
int old_x, old_y;
Point2i center;
@@ -357,11 +368,13 @@ class DisplayServerWindows : public DisplayServer {
int min_pressure;
int max_pressure;
bool tilt_supported;
+ bool pen_inverted = false;
bool block_mm = false;
int last_pressure_update;
float last_pressure;
Vector2 last_tilt;
+ bool last_pen_inverted = false;
HBITMAP hBitmap; //DIB section for layered window
uint8_t *dib_data = nullptr;
@@ -373,6 +386,7 @@ class DisplayServerWindows : public DisplayServer {
Size2 window_rect;
Point2 last_pos;
+ bool mouse_outside = true;
ObjectID instance_id;
diff --git a/platform/windows/export/export.cpp b/platform/windows/export/export.cpp
index 0fa2913218..20320470b8 100644
--- a/platform/windows/export/export.cpp
+++ b/platform/windows/export/export.cpp
@@ -30,6 +30,7 @@
#include "export.h"
+#include "editor/export/editor_export.h"
#include "export_plugin.h"
void register_windows_exporter() {
@@ -48,12 +49,7 @@ void register_windows_exporter() {
Ref<EditorExportPlatformWindows> platform;
platform.instantiate();
-
- Ref<Image> img = memnew(Image(_windows_logo));
- Ref<ImageTexture> logo;
- logo.instantiate();
- logo->create_from_image(img);
- platform->set_logo(logo);
+ platform->set_logo(ImageTexture::create_from_image(memnew(Image(_windows_logo))));
platform->set_name("Windows Desktop");
platform->set_os_name("Windows");
diff --git a/platform/windows/export/export.h b/platform/windows/export/export.h
index 09399f2bee..1054e04b1e 100644
--- a/platform/windows/export/export.h
+++ b/platform/windows/export/export.h
@@ -33,4 +33,4 @@
void register_windows_exporter();
-#endif
+#endif // WINDOWS_EXPORT_H
diff --git a/platform/windows/export/export_plugin.cpp b/platform/windows/export/export_plugin.cpp
index 16c67345e0..45bfc761fe 100644
--- a/platform/windows/export/export_plugin.cpp
+++ b/platform/windows/export/export_plugin.cpp
@@ -104,7 +104,7 @@ Error EditorExportPlatformWindows::export_project(const Ref<EditorExportPreset>
}
String EditorExportPlatformWindows::get_template_file_name(const String &p_target, const String &p_arch) const {
- return "windows_" + p_arch + "_" + p_target + ".exe";
+ return "windows_" + p_target + "_" + p_arch + ".exe";
}
List<String> EditorExportPlatformWindows::get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const {
diff --git a/platform/windows/export/export_plugin.h b/platform/windows/export/export_plugin.h
index 51f98365a9..b9e59829a0 100644
--- a/platform/windows/export/export_plugin.h
+++ b/platform/windows/export/export_plugin.h
@@ -33,8 +33,8 @@
#include "core/io/file_access.h"
#include "core/os/os.h"
-#include "editor/editor_export.h"
#include "editor/editor_settings.h"
+#include "editor/export/editor_export_platform_pc.h"
#include "platform/windows/logo.gen.h"
class EditorExportPlatformWindows : public EditorExportPlatformPC {
@@ -54,4 +54,4 @@ public:
virtual Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size) override;
};
-#endif
+#endif // WINDOWS_EXPORT_PLUGIN_H
diff --git a/platform/windows/godot.natvis b/platform/windows/godot.natvis
index bb855e4ac8..899956d65a 100644
--- a/platform/windows/godot.natvis
+++ b/platform/windows/godot.natvis
@@ -41,10 +41,12 @@
<DisplayString Condition="type == Variant::AABB">{_data._aabb}</DisplayString>
<DisplayString Condition="type == Variant::BASIS">{_data._basis}</DisplayString>
<DisplayString Condition="type == Variant::TRANSFORM3D">{_data._transform}</DisplayString>
+ <DisplayString Condition="type == Variant::PROJECTION">{_data._projection}</DisplayString>
<DisplayString Condition="type == Variant::STRING">{*(String *)_data._mem}</DisplayString>
<DisplayString Condition="type == Variant::VECTOR2">{*(Vector2 *)_data._mem}</DisplayString>
<DisplayString Condition="type == Variant::RECT2">{*(Rect2 *)_data._mem}</DisplayString>
<DisplayString Condition="type == Variant::VECTOR3">{*(Vector3 *)_data._mem}</DisplayString>
+ <DisplayString Condition="type == Variant::VECTOR4">{*(Vector4 *)_data._mem}</DisplayString>
<DisplayString Condition="type == Variant::PLANE">{*(Plane *)_data._mem}</DisplayString>
<DisplayString Condition="type == Variant::QUATERNION">{*(Quaternion *)_data._mem}</DisplayString>
<DisplayString Condition="type == Variant::COLOR">{*(Color *)_data._mem}</DisplayString>
diff --git a/platform/windows/godot_windows.cpp b/platform/windows/godot_windows.cpp
index 8de3ef294a..72920d2816 100644
--- a/platform/windows/godot_windows.cpp
+++ b/platform/windows/godot_windows.cpp
@@ -166,6 +166,10 @@ int widechar_main(int argc, wchar_t **argv) {
delete[] argv_utf8[i];
}
delete[] argv_utf8;
+
+ if (err == ERR_HELP) { // Returned by --help and --version, so success.
+ return 0;
+ }
return 255;
}
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index 6f414c094c..b5423e62bf 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -951,9 +951,9 @@ String OS_Windows::get_user_data_dir() const {
}
String OS_Windows::get_unique_id() const {
- HW_PROFILE_INFO HwProfInfo;
- ERR_FAIL_COND_V(!GetCurrentHwProfile(&HwProfInfo), "");
- return String::utf16((const char16_t *)(HwProfInfo.szHwProfileGuid), HW_PROFILE_GUIDLEN);
+ HW_PROFILE_INFOA HwProfInfo;
+ ERR_FAIL_COND_V(!GetCurrentHwProfileA(&HwProfInfo), "");
+ return String((HwProfInfo.szHwProfileGuid), HW_PROFILE_GUIDLEN);
}
bool OS_Windows::_check_internal_feature_support(const String &p_feature) {
diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h
index dc702c66e1..7d2d4ae705 100644
--- a/platform/windows/os_windows.h
+++ b/platform/windows/os_windows.h
@@ -185,4 +185,4 @@ public:
~OS_Windows();
};
-#endif
+#endif // OS_WINDOWS_H
diff --git a/platform/windows/vulkan_context_win.h b/platform/windows/vulkan_context_win.h
index e68f0125ca..d5950a129a 100644
--- a/platform/windows/vulkan_context_win.h
+++ b/platform/windows/vulkan_context_win.h
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef VULKAN_DEVICE_WIN_H
-#define VULKAN_DEVICE_WIN_H
+#ifndef VULKAN_CONTEXT_WIN_H
+#define VULKAN_CONTEXT_WIN_H
#include "drivers/vulkan/vulkan_context.h"
@@ -46,4 +46,4 @@ public:
~VulkanContextWindows();
};
-#endif // VULKAN_DEVICE_WIN_H
+#endif // VULKAN_CONTEXT_WIN_H
diff --git a/platform/windows/windows_terminal_logger.h b/platform/windows/windows_terminal_logger.h
index 1045f12201..348a49c845 100644
--- a/platform/windows/windows_terminal_logger.h
+++ b/platform/windows/windows_terminal_logger.h
@@ -44,4 +44,4 @@ public:
#endif
-#endif
+#endif // WINDOWS_TERMINAL_LOGGER_H