diff options
Diffstat (limited to 'platform')
400 files changed, 37593 insertions, 15253 deletions
diff --git a/platform/android/README.md b/platform/android/README.md index f6aabab708..01eb9c03a6 100644 --- a/platform/android/README.md +++ b/platform/android/README.md @@ -5,7 +5,7 @@ using [Gradle](https://gradle.org/) as a build system. ## Documentation -- [Compiling for Android](https://docs.godotengine.org/en/latest/development/compiling/compiling_for_android.html) +- [Compiling for Android](https://docs.godotengine.org/en/latest/contributing/development/compiling/compiling_for_android.html) - Instructions on building this platform port from source. - [Exporting for Android](https://docs.godotengine.org/en/latest/tutorials/export/exporting_for_android.html) - Instructions on using the compiled export templates to export a project. diff --git a/platform/android/SCsub b/platform/android/SCsub index e4d04f1df9..dfc921cc54 100644 --- a/platform/android/SCsub +++ b/platform/android/SCsub @@ -21,7 +21,7 @@ android_files = [ "android_keys_utils.cpp", "display_server_android.cpp", "plugin/godot_plugin_jni.cpp", - "vulkan/vulkan_context_android.cpp", + "vulkan_context_android.cpp", ] env_android = env.Clone() @@ -56,7 +56,10 @@ if lib_arch_dir != "": if env.dev_build: lib_type_dir = "dev" elif env.debug_features: - lib_type_dir = "debug" + if env.editor_build and env["store_release"]: + lib_type_dir = "release" + else: + lib_type_dir = "debug" else: # Release lib_type_dir = "release" diff --git a/platform/android/android_input_handler.cpp b/platform/android/android_input_handler.cpp index c0b098cd7f..37a019eaa4 100644 --- a/platform/android/android_input_handler.cpp +++ b/platform/android/android_input_handler.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* android_input_handler.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* android_input_handler.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "android_input_handler.h" @@ -49,14 +49,22 @@ void AndroidInputHandler::process_joy_event(AndroidInputHandler::JoypadEvent p_e } } -void AndroidInputHandler::_set_key_modifier_state(Ref<InputEventWithModifiers> ev) { - ev->set_shift_pressed(shift_mem); - ev->set_alt_pressed(alt_mem); - ev->set_meta_pressed(meta_mem); - ev->set_ctrl_pressed(control_mem); +void AndroidInputHandler::_set_key_modifier_state(Ref<InputEventWithModifiers> ev, Key p_keycode) { + if (p_keycode != Key::SHIFT) { + ev->set_shift_pressed(shift_mem); + } + if (p_keycode != Key::ALT) { + ev->set_alt_pressed(alt_mem); + } + if (p_keycode != Key::META) { + ev->set_meta_pressed(meta_mem); + } + if (p_keycode != Key::CTRL) { + ev->set_ctrl_pressed(control_mem); + } } -void AndroidInputHandler::process_key_event(int p_keycode, int p_physical_keycode, int p_unicode, bool p_pressed) { +void AndroidInputHandler::process_key_event(int p_physical_keycode, int p_unicode, int p_key_label, bool p_pressed) { static char32_t prev_wc = 0; char32_t unicode = p_unicode; if ((p_unicode & 0xfffffc00) == 0xd800) { @@ -81,8 +89,18 @@ void AndroidInputHandler::process_key_event(int p_keycode, int p_physical_keycod Key physical_keycode = godot_code_from_android_code(p_physical_keycode); Key keycode = physical_keycode; - if (p_keycode != 0) { - keycode = godot_code_from_unicode(p_keycode); + if (unicode == '\b') { // 0x08 + keycode = Key::BACKSPACE; + } else if (unicode == '\t') { // 0x09 + keycode = Key::TAB; + } else if (unicode == '\n') { // 0x0A + keycode = Key::ENTER; + } else if (unicode == 0x1B) { + keycode = Key::ESCAPE; + } else if (unicode == 0x1F) { + keycode = Key::KEY_DELETE; + } else { + keycode = fix_keycode(unicode, physical_keycode); } switch (physical_keycode) { @@ -104,10 +122,11 @@ void AndroidInputHandler::process_key_event(int p_keycode, int p_physical_keycod ev->set_keycode(keycode); ev->set_physical_keycode(physical_keycode); - ev->set_unicode(unicode); + ev->set_key_label(fix_key_label(p_key_label, keycode)); + ev->set_unicode(fix_unicode(unicode)); ev->set_pressed(p_pressed); - _set_key_modifier_state(ev); + _set_key_modifier_state(ev, keycode); if (p_physical_keycode == AKEYCODE_BACK) { if (DisplayServerAndroid *dsa = Object::cast_to<DisplayServerAndroid>(DisplayServer::get_singleton())) { @@ -118,7 +137,12 @@ void AndroidInputHandler::process_key_event(int p_keycode, int p_physical_keycod Input::get_singleton()->parse_input_event(ev); } -void AndroidInputHandler::_parse_all_touch(bool p_pressed, bool p_double_tap) { +void AndroidInputHandler::_cancel_all_touch() { + _parse_all_touch(false, true); + touch.clear(); +} + +void AndroidInputHandler::_parse_all_touch(bool p_pressed, bool p_canceled, bool p_double_tap) { if (touch.size()) { //end all if exist for (int i = 0; i < touch.size(); i++) { @@ -126,6 +150,7 @@ void AndroidInputHandler::_parse_all_touch(bool p_pressed, bool p_double_tap) { ev.instantiate(); ev->set_index(touch[i].id); ev->set_pressed(p_pressed); + ev->set_canceled(p_canceled); ev->set_position(touch[i].pos); ev->set_double_tap(p_double_tap); Input::get_singleton()->parse_input_event(ev); @@ -152,7 +177,7 @@ void AndroidInputHandler::process_touch_event(int p_event, int p_pointer, const } //send touch - _parse_all_touch(true, p_double_tap); + _parse_all_touch(true, false, p_double_tap); } break; case AMOTION_EVENT_ACTION_MOVE: { //motion @@ -185,7 +210,9 @@ void AndroidInputHandler::process_touch_event(int p_event, int p_pointer, const } } break; - case AMOTION_EVENT_ACTION_CANCEL: + case AMOTION_EVENT_ACTION_CANCEL: { + _cancel_all_touch(); + } break; case AMOTION_EVENT_ACTION_UP: { //release _release_all_touch(); } break; @@ -225,14 +252,20 @@ void AndroidInputHandler::process_touch_event(int p_event, int p_pointer, const } } -void AndroidInputHandler::_parse_mouse_event_info(MouseButton event_buttons_mask, bool p_pressed, bool p_double_click, bool p_source_mouse_relative) { +void AndroidInputHandler::_cancel_mouse_event_info(bool p_source_mouse_relative) { + buttons_state = BitField<MouseButtonMask>(); + _parse_mouse_event_info(BitField<MouseButtonMask>(), false, true, false, p_source_mouse_relative); + mouse_event_info.valid = false; +} + +void AndroidInputHandler::_parse_mouse_event_info(BitField<MouseButtonMask> event_buttons_mask, bool p_pressed, bool p_canceled, bool p_double_click, bool p_source_mouse_relative) { if (!mouse_event_info.valid) { return; } Ref<InputEventMouseButton> ev; ev.instantiate(); - _set_key_modifier_state(ev); + _set_key_modifier_state(ev, Key::NONE); if (p_source_mouse_relative) { ev->set_position(hover_prev_pos); ev->set_global_position(hover_prev_pos); @@ -242,7 +275,8 @@ void AndroidInputHandler::_parse_mouse_event_info(MouseButton event_buttons_mask hover_prev_pos = mouse_event_info.pos; } ev->set_pressed(p_pressed); - MouseButton changed_button_mask = MouseButton(buttons_state ^ event_buttons_mask); + ev->set_canceled(p_canceled); + BitField<MouseButtonMask> changed_button_mask = BitField<MouseButtonMask>(buttons_state.operator int64_t() ^ event_buttons_mask.operator int64_t()); buttons_state = event_buttons_mask; @@ -253,12 +287,12 @@ void AndroidInputHandler::_parse_mouse_event_info(MouseButton event_buttons_mask } void AndroidInputHandler::_release_mouse_event_info(bool p_source_mouse_relative) { - _parse_mouse_event_info(MouseButton::NONE, false, false, p_source_mouse_relative); + _parse_mouse_event_info(BitField<MouseButtonMask>(), false, false, false, p_source_mouse_relative); mouse_event_info.valid = false; } void AndroidInputHandler::process_mouse_event(int p_event_action, int p_event_android_buttons_mask, Point2 p_event_pos, Vector2 p_delta, bool p_double_click, bool p_source_mouse_relative) { - MouseButton event_buttons_mask = _android_button_mask_to_godot_button_mask(p_event_android_buttons_mask); + BitField<MouseButtonMask> event_buttons_mask = _android_button_mask_to_godot_button_mask(p_event_android_buttons_mask); switch (p_event_action) { case AMOTION_EVENT_ACTION_HOVER_MOVE: // hover move case AMOTION_EVENT_ACTION_HOVER_ENTER: // hover enter @@ -266,7 +300,7 @@ void AndroidInputHandler::process_mouse_event(int p_event_action, int p_event_an // https://developer.android.com/reference/android/view/MotionEvent.html#ACTION_HOVER_ENTER Ref<InputEventMouseMotion> ev; ev.instantiate(); - _set_key_modifier_state(ev); + _set_key_modifier_state(ev, Key::NONE); ev->set_position(p_event_pos); ev->set_global_position(p_event_pos); ev->set_relative(p_event_pos - hover_prev_pos); @@ -282,11 +316,14 @@ void AndroidInputHandler::process_mouse_event(int p_event_action, int p_event_an mouse_event_info.valid = true; mouse_event_info.pos = p_event_pos; - _parse_mouse_event_info(event_buttons_mask, true, p_double_click, p_source_mouse_relative); + _parse_mouse_event_info(event_buttons_mask, true, false, p_double_click, p_source_mouse_relative); + } break; + + case AMOTION_EVENT_ACTION_CANCEL: { + _cancel_mouse_event_info(p_source_mouse_relative); } break; case AMOTION_EVENT_ACTION_UP: - case AMOTION_EVENT_ACTION_CANCEL: case AMOTION_EVENT_ACTION_BUTTON_RELEASE: { _release_mouse_event_info(p_source_mouse_relative); } break; @@ -298,7 +335,7 @@ void AndroidInputHandler::process_mouse_event(int p_event_action, int p_event_an Ref<InputEventMouseMotion> ev; ev.instantiate(); - _set_key_modifier_state(ev); + _set_key_modifier_state(ev, Key::NONE); if (p_source_mouse_relative) { ev->set_position(hover_prev_pos); ev->set_global_position(hover_prev_pos); @@ -317,7 +354,7 @@ void AndroidInputHandler::process_mouse_event(int p_event_action, int p_event_an case AMOTION_EVENT_ACTION_SCROLL: { Ref<InputEventMouseButton> ev; ev.instantiate(); - _set_key_modifier_state(ev); + _set_key_modifier_state(ev, Key::NONE); if (p_source_mouse_relative) { ev->set_position(hover_prev_pos); ev->set_global_position(hover_prev_pos); @@ -342,11 +379,11 @@ void AndroidInputHandler::process_mouse_event(int p_event_action, int p_event_an } } -void AndroidInputHandler::_wheel_button_click(MouseButton event_buttons_mask, const Ref<InputEventMouseButton> &ev, MouseButton wheel_button, float factor) { +void AndroidInputHandler::_wheel_button_click(BitField<MouseButtonMask> event_buttons_mask, const Ref<InputEventMouseButton> &ev, MouseButton wheel_button, float factor) { Ref<InputEventMouseButton> evd = ev->duplicate(); - _set_key_modifier_state(evd); + _set_key_modifier_state(evd, Key::NONE); evd->set_button_index(wheel_button); - evd->set_button_mask(MouseButton(event_buttons_mask ^ mouse_button_to_mask(wheel_button))); + evd->set_button_mask(BitField<MouseButtonMask>(event_buttons_mask.operator int64_t() ^ int64_t(mouse_button_to_mask(wheel_button)))); evd->set_factor(factor); Input::get_singleton()->parse_input_event(evd); Ref<InputEventMouseButton> evdd = evd->duplicate(); @@ -358,7 +395,7 @@ void AndroidInputHandler::_wheel_button_click(MouseButton event_buttons_mask, co void AndroidInputHandler::process_magnify(Point2 p_pos, float p_factor) { Ref<InputEventMagnifyGesture> magnify_event; magnify_event.instantiate(); - _set_key_modifier_state(magnify_event); + _set_key_modifier_state(magnify_event, Key::NONE); magnify_event->set_position(p_pos); magnify_event->set_factor(p_factor); Input::get_singleton()->parse_input_event(magnify_event); @@ -367,45 +404,45 @@ void AndroidInputHandler::process_magnify(Point2 p_pos, float p_factor) { void AndroidInputHandler::process_pan(Point2 p_pos, Vector2 p_delta) { Ref<InputEventPanGesture> pan_event; pan_event.instantiate(); - _set_key_modifier_state(pan_event); + _set_key_modifier_state(pan_event, Key::NONE); pan_event->set_position(p_pos); pan_event->set_delta(p_delta); Input::get_singleton()->parse_input_event(pan_event); } -MouseButton AndroidInputHandler::_button_index_from_mask(MouseButton button_mask) { - switch (button_mask) { - case MouseButton::MASK_LEFT: +MouseButton AndroidInputHandler::_button_index_from_mask(BitField<MouseButtonMask> button_mask) { + switch (MouseButtonMask(button_mask.operator int64_t())) { + case MouseButtonMask::LEFT: return MouseButton::LEFT; - case MouseButton::MASK_RIGHT: + case MouseButtonMask::RIGHT: return MouseButton::RIGHT; - case MouseButton::MASK_MIDDLE: + case MouseButtonMask::MIDDLE: return MouseButton::MIDDLE; - case MouseButton::MASK_XBUTTON1: + case MouseButtonMask::MB_XBUTTON1: return MouseButton::MB_XBUTTON1; - case MouseButton::MASK_XBUTTON2: + case MouseButtonMask::MB_XBUTTON2: return MouseButton::MB_XBUTTON2; default: return MouseButton::NONE; } } -MouseButton AndroidInputHandler::_android_button_mask_to_godot_button_mask(int android_button_mask) { - MouseButton godot_button_mask = MouseButton::NONE; +BitField<MouseButtonMask> AndroidInputHandler::_android_button_mask_to_godot_button_mask(int android_button_mask) { + BitField<MouseButtonMask> godot_button_mask; if (android_button_mask & AMOTION_EVENT_BUTTON_PRIMARY) { - godot_button_mask |= MouseButton::MASK_LEFT; + godot_button_mask.set_flag(MouseButtonMask::LEFT); } if (android_button_mask & AMOTION_EVENT_BUTTON_SECONDARY) { - godot_button_mask |= MouseButton::MASK_RIGHT; + godot_button_mask.set_flag(MouseButtonMask::RIGHT); } if (android_button_mask & AMOTION_EVENT_BUTTON_TERTIARY) { - godot_button_mask |= MouseButton::MASK_MIDDLE; + godot_button_mask.set_flag(MouseButtonMask::MIDDLE); } if (android_button_mask & AMOTION_EVENT_BUTTON_BACK) { - godot_button_mask |= MouseButton::MASK_XBUTTON1; + godot_button_mask.set_flag(MouseButtonMask::MB_XBUTTON1); } if (android_button_mask & AMOTION_EVENT_BUTTON_FORWARD) { - godot_button_mask |= MouseButton::MASK_XBUTTON2; + godot_button_mask.set_flag(MouseButtonMask::MB_XBUTTON2); } return godot_button_mask; diff --git a/platform/android/android_input_handler.h b/platform/android/android_input_handler.h index 4da8a910c0..42d1c228a8 100644 --- a/platform/android/android_input_handler.h +++ b/platform/android/android_input_handler.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* android_input_handler.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* android_input_handler.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 ANDROID_INPUT_HANDLER_H #define ANDROID_INPUT_HANDLER_H @@ -61,7 +61,7 @@ public: int index = 0; // Can be either JoyAxis or JoyButton. bool pressed = false; float value = 0; - HatMask hat = HatMask::CENTER; + BitField<HatMask> hat; }; private: @@ -70,34 +70,38 @@ private: bool control_mem = false; bool meta_mem = false; - MouseButton buttons_state = MouseButton::NONE; + BitField<MouseButtonMask> buttons_state; Vector<TouchPos> touch; MouseEventInfo mouse_event_info; Point2 hover_prev_pos; // needed to calculate the relative position on hover events - void _set_key_modifier_state(Ref<InputEventWithModifiers> ev); + void _set_key_modifier_state(Ref<InputEventWithModifiers> ev, Key p_keycode); - static MouseButton _button_index_from_mask(MouseButton button_mask); - static MouseButton _android_button_mask_to_godot_button_mask(int android_button_mask); + static MouseButton _button_index_from_mask(BitField<MouseButtonMask> button_mask); + static BitField<MouseButtonMask> _android_button_mask_to_godot_button_mask(int android_button_mask); - void _wheel_button_click(MouseButton event_buttons_mask, const Ref<InputEventMouseButton> &ev, MouseButton wheel_button, float factor); + void _wheel_button_click(BitField<MouseButtonMask> event_buttons_mask, const Ref<InputEventMouseButton> &ev, MouseButton wheel_button, float factor); - void _parse_mouse_event_info(MouseButton event_buttons_mask, bool p_pressed, bool p_double_click, bool p_source_mouse_relative); + void _parse_mouse_event_info(BitField<MouseButtonMask> event_buttons_mask, bool p_pressed, bool p_canceled, bool p_double_click, bool p_source_mouse_relative); void _release_mouse_event_info(bool p_source_mouse_relative = false); - void _parse_all_touch(bool p_pressed, bool p_double_tap); + void _cancel_mouse_event_info(bool p_source_mouse_relative = false); + + void _parse_all_touch(bool p_pressed, bool p_canceled = false, bool p_double_tap = false); void _release_all_touch(); + void _cancel_all_touch(); + public: void process_mouse_event(int p_event_action, int p_event_android_buttons_mask, Point2 p_event_pos, Vector2 p_delta, bool p_double_click, bool p_source_mouse_relative); void process_touch_event(int p_event, int p_pointer, const Vector<TouchPos> &p_points, bool p_double_tap); void process_magnify(Point2 p_pos, float p_factor); void process_pan(Point2 p_pos, Vector2 p_delta); void process_joy_event(JoypadEvent p_event); - void process_key_event(int p_keycode, int p_physical_keycode, int p_unicode, bool p_pressed); + void process_key_event(int p_physical_keycode, int p_unicode, int p_key_label, bool p_pressed); }; #endif // ANDROID_INPUT_HANDLER_H diff --git a/platform/android/android_keys_utils.cpp b/platform/android/android_keys_utils.cpp index d2c5fdfd6c..f50437e82a 100644 --- a/platform/android/android_keys_utils.cpp +++ b/platform/android/android_keys_utils.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* android_keys_utils.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* android_keys_utils.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "android_keys_utils.h" @@ -38,41 +38,3 @@ Key godot_code_from_android_code(unsigned int p_code) { } return Key::UNKNOWN; } - -Key godot_code_from_unicode(unsigned int p_code) { - unsigned int code = p_code; - if (code > 0xFF) { - return Key::UNKNOWN; - } - // Known control codes. - if (code == '\b') { // 0x08 - return Key::BACKSPACE; - } - if (code == '\t') { // 0x09 - return Key::TAB; - } - if (code == '\n') { // 0x0A - return Key::ENTER; - } - if (code == 0x1B) { - return Key::ESCAPE; - } - if (code == 0x1F) { - return Key::KEY_DELETE; - } - // Unknown control codes. - if (code <= 0x1F || (code >= 0x80 && code <= 0x9F)) { - return Key::UNKNOWN; - } - // Convert to uppercase. - if (code >= 'a' && code <= 'z') { // 0x61 - 0x7A - code -= ('a' - 'A'); - } - if (code >= u'à' && code <= u'ö') { // 0xE0 - 0xF6 - code -= (u'à' - u'À'); // 0xE0 - 0xC0 - } - if (code >= u'ø' && code <= u'þ') { // 0xF8 - 0xFF - code -= (u'ø' - u'Ø'); // 0xF8 - 0xD8 - } - return Key(code); -} diff --git a/platform/android/android_keys_utils.h b/platform/android/android_keys_utils.h index 5ec3ee17aa..5cf5628a8b 100644 --- a/platform/android/android_keys_utils.h +++ b/platform/android/android_keys_utils.h @@ -1,38 +1,39 @@ -/*************************************************************************/ -/* android_keys_utils.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* android_keys_utils.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 ANDROID_KEYS_UTILS_H #define ANDROID_KEYS_UTILS_H +#include "core/os/keyboard.h" + #include <android/input.h> -#include <core/os/keyboard.h> #define AKEYCODE_MAX 0xFFFF @@ -43,7 +44,6 @@ struct AndroidGodotCodePair { static AndroidGodotCodePair android_godot_code_pairs[] = { { AKEYCODE_UNKNOWN, Key::UNKNOWN }, // (0) Unknown key code. - { AKEYCODE_HOME, Key::HOME }, // (3) Home key. { AKEYCODE_BACK, Key::BACK }, // (4) Back key. { AKEYCODE_0, Key::KEY_0 }, // (7) '0' key. { AKEYCODE_1, Key::KEY_1 }, // (8) '1' key. @@ -61,8 +61,10 @@ static AndroidGodotCodePair android_godot_code_pairs[] = { { AKEYCODE_DPAD_DOWN, Key::DOWN }, // (20) Directional Pad Down key. { AKEYCODE_DPAD_LEFT, Key::LEFT }, // (21) Directional Pad Left key. { AKEYCODE_DPAD_RIGHT, Key::RIGHT }, // (22) Directional Pad Right key. + { AKEYCODE_DPAD_CENTER, Key::ENTER }, // (23) Directional Pad Center key. { AKEYCODE_VOLUME_UP, Key::VOLUMEUP }, // (24) Volume Up key. { AKEYCODE_VOLUME_DOWN, Key::VOLUMEDOWN }, // (25) Volume Down key. + { AKEYCODE_POWER, Key::STANDBY }, // (26) Power key. { AKEYCODE_CLEAR, Key::CLEAR }, // (28) Clear key. { AKEYCODE_A, Key::A }, // (29) 'A' key. { AKEYCODE_B, Key::B }, // (30) 'B' key. @@ -98,6 +100,7 @@ static AndroidGodotCodePair android_godot_code_pairs[] = { { AKEYCODE_SHIFT_RIGHT, Key::SHIFT }, // (60) Right Shift modifier key. { AKEYCODE_TAB, Key::TAB }, // (61) Tab key. { AKEYCODE_SPACE, Key::SPACE }, // (62) Space key. + { AKEYCODE_ENVELOPE, Key::LAUNCHMAIL }, // (65) Envelope special function key. { AKEYCODE_ENTER, Key::ENTER }, // (66) Enter key. { AKEYCODE_DEL, Key::BACKSPACE }, // (67) Backspace key. { AKEYCODE_GRAVE, Key::QUOTELEFT }, // (68) '`' (backtick) key. @@ -114,6 +117,7 @@ static AndroidGodotCodePair android_godot_code_pairs[] = { { AKEYCODE_MENU, Key::MENU }, // (82) Menu key. { AKEYCODE_SEARCH, Key::SEARCH }, // (84) Search key. { AKEYCODE_MEDIA_STOP, Key::MEDIASTOP }, // (86) Stop media key. + { AKEYCODE_MEDIA_NEXT, Key::MEDIANEXT }, // (87) Play Next media key. { AKEYCODE_MEDIA_PREVIOUS, Key::MEDIAPREVIOUS }, // (88) Play Previous media key. { AKEYCODE_PAGE_UP, Key::PAGEUP }, // (92) Page Up key. { AKEYCODE_PAGE_DOWN, Key::PAGEDOWN }, // (93) Page Down key. @@ -127,6 +131,8 @@ static AndroidGodotCodePair android_godot_code_pairs[] = { { AKEYCODE_META_RIGHT, Key::META }, // (118) Right Meta modifier key. { AKEYCODE_SYSRQ, Key::PRINT }, // (120) System Request / Print Screen key. { AKEYCODE_BREAK, Key::PAUSE }, // (121) Break / Pause key. + { AKEYCODE_MOVE_HOME, Key::HOME }, // (122) Home Movement key. + { AKEYCODE_MOVE_END, Key::END }, // (123) End Movement key. { AKEYCODE_INSERT, Key::INSERT }, // (124) Insert key. { AKEYCODE_FORWARD, Key::FORWARD }, // (125) Forward key. { AKEYCODE_MEDIA_PLAY, Key::MEDIAPLAY }, // (126) Play media key. @@ -161,13 +167,14 @@ static AndroidGodotCodePair android_godot_code_pairs[] = { { AKEYCODE_NUMPAD_DOT, Key::KP_PERIOD }, // (158) Numeric keypad '.' key (for decimals or digit grouping). { AKEYCODE_NUMPAD_ENTER, Key::KP_ENTER }, // (160) Numeric keypad Enter key. { AKEYCODE_VOLUME_MUTE, Key::VOLUMEMUTE }, // (164) Volume Mute key. + { AKEYCODE_EISU, Key::JIS_EISU }, // (212) JIS EISU key. { AKEYCODE_YEN, Key::YEN }, // (216) Japanese Yen key. + { AKEYCODE_KANA, Key::JIS_KANA }, // (218) JIS KANA key. { AKEYCODE_HELP, Key::HELP }, // (259) Help key. { AKEYCODE_REFRESH, Key::REFRESH }, // (285) Refresh key. { AKEYCODE_MAX, Key::UNKNOWN } }; Key godot_code_from_android_code(unsigned int p_code); -Key godot_code_from_unicode(unsigned int p_code); #endif // ANDROID_KEYS_UTILS_H diff --git a/platform/android/api/api.cpp b/platform/android/api/api.cpp index f80f1e3051..60c369951c 100644 --- a/platform/android/api/api.cpp +++ b/platform/android/api/api.cpp @@ -1,39 +1,40 @@ -/*************************************************************************/ -/* api.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* api.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "api.h" -#include "core/config/engine.h" #include "java_class_wrapper.h" #include "jni_singleton.h" +#include "core/config/engine.h" + #if !defined(ANDROID_ENABLED) static JavaClassWrapper *java_class_wrapper = nullptr; #endif diff --git a/platform/android/api/api.h b/platform/android/api/api.h index a4ee27cf81..c744e464d5 100644 --- a/platform/android/api/api.h +++ b/platform/android/api/api.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* api.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* api.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 ANDROID_API_H #define ANDROID_API_H diff --git a/platform/android/api/java_class_wrapper.h b/platform/android/api/java_class_wrapper.h index ac8d6585d3..b1481ebf7b 100644 --- a/platform/android/api/java_class_wrapper.h +++ b/platform/android/api/java_class_wrapper.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* java_class_wrapper.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* java_class_wrapper.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 JAVA_CLASS_WRAPPER_H #define JAVA_CLASS_WRAPPER_H diff --git a/platform/android/api/jni_singleton.h b/platform/android/api/jni_singleton.h index 895bc70103..a2d1c08168 100644 --- a/platform/android/api/jni_singleton.h +++ b/platform/android/api/jni_singleton.h @@ -1,40 +1,41 @@ -/*************************************************************************/ -/* jni_singleton.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* jni_singleton.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 JNI_SINGLETON_H #define JNI_SINGLETON_H #include "core/config/engine.h" #include "core/variant/variant.h" + #ifdef ANDROID_ENABLED -#include "platform/android/jni_utils.h" +#include "jni_utils.h" #endif class JNISingleton : public Object { @@ -137,6 +138,18 @@ public: ret = sarr; env->DeleteLocalRef(arr); } break; + case Variant::PACKED_INT64_ARRAY: { + jlongArray arr = (jlongArray)env->CallObjectMethodA(instance, E->get().method, v); + + int fCount = env->GetArrayLength(arr); + Vector<int64_t> sarr; + sarr.resize(fCount); + + int64_t *w = sarr.ptrw(); + env->GetLongArrayRegion(arr, 0, fCount, w); + ret = sarr; + env->DeleteLocalRef(arr); + } break; case Variant::PACKED_FLOAT32_ARRAY: { jfloatArray arr = (jfloatArray)env->CallObjectMethodA(instance, E->get().method, v); @@ -149,9 +162,18 @@ public: ret = sarr; env->DeleteLocalRef(arr); } break; + case Variant::PACKED_FLOAT64_ARRAY: { + jdoubleArray arr = (jdoubleArray)env->CallObjectMethodA(instance, E->get().method, v); - // TODO: This is missing 64 bits arrays, I have no idea how to do it in JNI. + int fCount = env->GetArrayLength(arr); + Vector<double> sarr; + sarr.resize(fCount); + double *w = sarr.ptrw(); + env->GetDoubleArrayRegion(arr, 0, fCount, w); + ret = sarr; + env->DeleteLocalRef(arr); + } break; case Variant::DICTIONARY: { jobject obj = env->CallObjectMethodA(instance, E->get().method, v); ret = _jobject_to_variant(env, obj); diff --git a/platform/android/audio_driver_opensl.cpp b/platform/android/audio_driver_opensl.cpp index 6b22a0ffa1..51e89c720d 100644 --- a/platform/android/audio_driver_opensl.cpp +++ b/platform/android/audio_driver_opensl.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* audio_driver_opensl.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* audio_driver_opensl.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "audio_driver_opensl.h" @@ -44,7 +44,7 @@ void AudioDriverOpenSL::_buffer_callback( if (pause) { mix = false; } else { - mix = mutex.try_lock() == OK; + mix = mutex.try_lock(); } if (mix) { @@ -80,10 +80,6 @@ void AudioDriverOpenSL::_buffer_callbacks( ad->_buffer_callback(queueItf); } -const char *AudioDriverOpenSL::get_name() const { - return "Android"; -} - Error AudioDriverOpenSL::init() { SLresult res; SLEngineOption EngineOption[] = { @@ -204,7 +200,7 @@ void AudioDriverOpenSL::_record_buffer_callbacks(SLAndroidSimpleBufferQueueItf q ad->_record_buffer_callback(queueItf); } -Error AudioDriverOpenSL::capture_init_device() { +Error AudioDriverOpenSL::init_input_device() { SLDataLocator_IODevice loc_dev = { SL_DATALOCATOR_IODEVICE, SL_IODEVICE_AUDIOINPUT, @@ -271,15 +267,16 @@ Error AudioDriverOpenSL::capture_init_device() { return OK; } -Error AudioDriverOpenSL::capture_start() { +Error AudioDriverOpenSL::input_start() { if (OS::get_singleton()->request_permission("RECORD_AUDIO")) { - return capture_init_device(); + return init_input_device(); } - return OK; + WARN_PRINT("Unable to start audio capture - No RECORD_AUDIO permission"); + return ERR_UNAUTHORIZED; } -Error AudioDriverOpenSL::capture_stop() { +Error AudioDriverOpenSL::input_stop() { SLuint32 state; SLresult res = (*recordItf)->GetRecordState(recordItf, &state); ERR_FAIL_COND_V(res != SL_RESULT_SUCCESS, ERR_CANT_OPEN); diff --git a/platform/android/audio_driver_opensl.h b/platform/android/audio_driver_opensl.h index 7b09438858..6ea0f77def 100644 --- a/platform/android/audio_driver_opensl.h +++ b/platform/android/audio_driver_opensl.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* audio_driver_opensl.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* audio_driver_opensl.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 AUDIO_DRIVER_OPENSL_H #define AUDIO_DRIVER_OPENSL_H @@ -84,23 +84,26 @@ class AudioDriverOpenSL : public AudioDriver { SLAndroidSimpleBufferQueueItf queueItf, void *pContext); - virtual Error capture_init_device(); + Error init_input_device(); public: - virtual const char *get_name() const; + virtual const char *get_name() const override { + return "Android"; + } - virtual Error init(); - virtual void start(); - virtual int get_mix_rate() const; - virtual SpeakerMode get_speaker_mode() const; - virtual void lock(); - virtual void unlock(); - virtual void finish(); + virtual Error init() override; + virtual void start() override; + virtual int get_mix_rate() const override; + virtual SpeakerMode get_speaker_mode() const override; - virtual void set_pause(bool p_pause); + virtual void lock() override; + virtual void unlock() override; + virtual void finish() override; - virtual Error capture_start(); - virtual Error capture_stop(); + virtual Error input_start() override; + virtual Error input_stop() override; + + void set_pause(bool p_pause); AudioDriverOpenSL(); }; diff --git a/platform/android/detect.py b/platform/android/detect.py index 6eb8ba34ed..20aced3524 100644 --- a/platform/android/detect.py +++ b/platform/android/detect.py @@ -22,12 +22,29 @@ def can_build(): def get_opts(): + from SCons.Variables import BoolVariable + return [ ("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"), + ( + "ndk_platform", + 'Target platform (android-<api>, e.g. "android-' + str(get_min_target_api()) + '")', + "android-" + str(get_min_target_api()), + ), + BoolVariable("store_release", "Editor build for Google Play Store (for official builds only)", False), + ] + + +def get_doc_classes(): + return [ + "EditorExportPlatformAndroid", ] +def get_doc_path(): + return "doc_classes" + + # Return the ANDROID_SDK_ROOT environment variable. def get_env_android_sdk_root(): return os.environ.get("ANDROID_SDK_ROOT", -1) @@ -46,6 +63,11 @@ def get_ndk_version(): return "23.2.8568313" +# This is kept in sync with the value in 'platform/android/java/app/config.gradle'. +def get_min_target_api(): + return 21 + + def get_flags(): return [ ("arch", "arm64"), # Default for convenience. @@ -87,30 +109,26 @@ def configure(env: "Environment"): ) sys.exit() + if get_min_sdk_version(env["ndk_platform"]) < get_min_target_api(): + print( + "WARNING: minimum supported Android target api is %d. Forcing target api %d." + % (get_min_target_api(), get_min_target_api()) + ) + env["ndk_platform"] = "android-" + str(get_min_target_api()) + install_ndk_if_needed(env) ndk_root = env["ANDROID_NDK_ROOT"] # Architecture - if get_min_sdk_version(env["ndk_platform"]) < 21 and env["arch"] in ["x86_64", "arm64"]: - print( - 'WARNING: arch="%s" is not supported with "ndk_platform" lower than "android-21". Forcing platform 21.' - % env["arch"] - ) - env["ndk_platform"] = "android-21" - if env["arch"] == "arm32": target_triple = "armv7a-linux-androideabi" - env.extra_suffix = ".armv7" + env.extra_suffix elif env["arch"] == "arm64": target_triple = "aarch64-linux-android" - env.extra_suffix = ".armv8" + env.extra_suffix elif env["arch"] == "x86_32": target_triple = "i686-linux-android" - env.extra_suffix = ".x86" + env.extra_suffix elif env["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"]) @@ -165,7 +183,6 @@ def configure(env: "Environment"): "-fpic -ffunction-sections -funwind-tables -fstack-protector-strong -fvisibility=hidden -fno-strict-aliasing".split() ) ) - env.Append(CPPDEFINES=["GLES_ENABLED"]) if get_min_sdk_version(env["ndk_platform"]) >= 24: env.Append(CPPDEFINES=[("_FILE_OFFSET_BITS", 64)]) @@ -188,9 +205,13 @@ def configure(env: "Environment"): env.Prepend(CPPPATH=["#platform/android"]) env.Append(CPPDEFINES=["ANDROID_ENABLED", "UNIX_ENABLED"]) - env.Append(LIBS=["OpenSLES", "EGL", "GLESv2", "android", "log", "z", "dl"]) + env.Append(LIBS=["OpenSLES", "EGL", "android", "log", "z", "dl"]) if env["vulkan"]: env.Append(CPPDEFINES=["VULKAN_ENABLED"]) if not env["use_volk"]: env.Append(LIBS=["vulkan"]) + + if env["opengl3"]: + env.Append(CPPDEFINES=["GLES3_ENABLED"]) + env.Append(LIBS=["GLESv3"]) diff --git a/platform/android/dir_access_jandroid.cpp b/platform/android/dir_access_jandroid.cpp index 4f1ac16975..6bd09fe00a 100644 --- a/platform/android/dir_access_jandroid.cpp +++ b/platform/android/dir_access_jandroid.cpp @@ -1,39 +1,40 @@ -/*************************************************************************/ -/* dir_access_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. */ -/*************************************************************************/ +/**************************************************************************/ +/* dir_access_jandroid.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "dir_access_jandroid.h" -#include "core/string/print_string.h" #include "string_android.h" #include "thread_jandroid.h" +#include "core/string/print_string.h" + jobject DirAccessJAndroid::dir_access_handler = nullptr; jclass DirAccessJAndroid::cls = nullptr; jmethodID DirAccessJAndroid::_dir_open = nullptr; diff --git a/platform/android/dir_access_jandroid.h b/platform/android/dir_access_jandroid.h index 5c4f1852a9..5ee4c85659 100644 --- a/platform/android/dir_access_jandroid.h +++ b/platform/android/dir_access_jandroid.h @@ -1,39 +1,41 @@ -/*************************************************************************/ -/* dir_access_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. */ -/*************************************************************************/ +/**************************************************************************/ +/* dir_access_jandroid.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 DIR_ACCESS_JANDROID_H #define DIR_ACCESS_JANDROID_H +#include "java_godot_lib_jni.h" + #include "core/io/dir_access.h" #include "drivers/unix/dir_access_unix.h" -#include "java_godot_lib_jni.h" + #include <stdio.h> /// Android implementation of the DirAccess interface used to provide access to diff --git a/platform/android/display_server_android.cpp b/platform/android/display_server_android.cpp index 08369e735d..f02b292868 100644 --- a/platform/android/display_server_android.cpp +++ b/platform/android/display_server_android.cpp @@ -1,47 +1,55 @@ -/*************************************************************************/ -/* display_server_android.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* display_server_android.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "display_server_android.h" -#include "core/config/project_settings.h" #include "java_godot_io_wrapper.h" #include "java_godot_wrapper.h" #include "os_android.h" #include "tts_android.h" +#include "core/config/project_settings.h" + #if defined(VULKAN_ENABLED) +#include "vulkan_context_android.h" + #include "drivers/vulkan/rendering_device_vulkan.h" -#include "platform/android/vulkan/vulkan_context_android.h" #include "servers/rendering/renderer_rd/renderer_compositor_rd.h" #endif +#ifdef GLES3_ENABLED +#include "drivers/gles3/rasterizer_gles3.h" + +#include <EGL/egl.h> +#endif + DisplayServerAndroid *DisplayServerAndroid::get_singleton() { return static_cast<DisplayServerAndroid *>(DisplayServer::get_singleton()); } @@ -180,6 +188,10 @@ int DisplayServerAndroid::get_screen_count() const { return 1; } +int DisplayServerAndroid::get_primary_screen() const { + return 0; +} + Point2i DisplayServerAndroid::screen_get_position(int p_screen) const { return Point2i(0, 0); } @@ -204,7 +216,18 @@ float DisplayServerAndroid::screen_get_scale(int p_screen) const { GodotIOJavaWrapper *godot_io_java = OS_Android::get_singleton()->get_godot_io_java(); ERR_FAIL_NULL_V(godot_io_java, 1.0f); - return godot_io_java->get_scaled_density(); + float screen_scale = godot_io_java->get_scaled_density(); + + // Update the scale to avoid cropping. + Size2i screen_size = screen_get_size(p_screen); + if (screen_size != Size2i()) { + float width_scale = screen_size.width / (float)OS_Android::DEFAULT_WINDOW_WIDTH; + float height_scale = screen_size.height / (float)OS_Android::DEFAULT_WINDOW_HEIGHT; + screen_scale = MIN(screen_scale, MIN(width_scale, height_scale)); + } + + print_line("Selected screen scale: ", screen_scale); + return screen_scale; } float DisplayServerAndroid::screen_get_refresh_rate(int p_screen) const { @@ -217,7 +240,7 @@ float DisplayServerAndroid::screen_get_refresh_rate(int p_screen) const { return godot_io_java->get_screen_refresh_rate(SCREEN_REFRESH_RATE_FALLBACK); } -bool DisplayServerAndroid::screen_is_touchscreen(int p_screen) const { +bool DisplayServerAndroid::is_touchscreen_available() const { return true; } @@ -312,15 +335,26 @@ DisplayServer::WindowID DisplayServerAndroid::get_window_at_screen_position(cons int64_t DisplayServerAndroid::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: { - return 0; // Not supported. - } case WINDOW_HANDLE: { return reinterpret_cast<int64_t>(static_cast<OS_Android *>(OS::get_singleton())->get_godot_java()->get_activity()); } case WINDOW_VIEW: { return 0; // Not supported. } +#ifdef GLES3_ENABLED + case DISPLAY_HANDLE: { + if (rendering_driver == "opengl3") { + return reinterpret_cast<int64_t>(eglGetCurrentDisplay()); + } + return 0; + } + case OPENGL_CONTEXT: { + if (rendering_driver == "opengl3") { + return reinterpret_cast<int64_t>(eglGetCurrentContext()); + } + return 0; + } +#endif default: { return 0; } @@ -351,6 +385,10 @@ Point2i DisplayServerAndroid::window_get_position(DisplayServer::WindowID p_wind return Point2i(); } +Point2i DisplayServerAndroid::window_get_position_with_decorations(DisplayServer::WindowID p_window) const { + return Point2i(); +} + void DisplayServerAndroid::window_set_position(const Point2i &p_position, DisplayServer::WindowID p_window) { // Not supported on Android. } @@ -383,7 +421,7 @@ Size2i DisplayServerAndroid::window_get_size(DisplayServer::WindowID p_window) c return OS_Android::get_singleton()->get_display_size(); } -Size2i DisplayServerAndroid::window_get_real_size(DisplayServer::WindowID p_window) const { +Size2i DisplayServerAndroid::window_get_size_with_decorations(DisplayServer::WindowID p_window) const { return OS_Android::get_singleton()->get_display_size(); } @@ -415,6 +453,10 @@ void DisplayServerAndroid::window_move_to_foreground(DisplayServer::WindowID p_w // Not supported on Android. } +bool DisplayServerAndroid::window_is_focused(WindowID p_window) const { + return true; +} + bool DisplayServerAndroid::window_can_draw(DisplayServer::WindowID p_window) const { return true; } @@ -440,10 +482,19 @@ Vector<String> DisplayServerAndroid::get_rendering_drivers_func() { return drivers; } -DisplayServer *DisplayServerAndroid::create_func(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error) { - DisplayServer *ds = memnew(DisplayServerAndroid(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, r_error)); +DisplayServer *DisplayServerAndroid::create_func(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error) { + DisplayServer *ds = memnew(DisplayServerAndroid(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, p_screen, r_error)); if (r_error != OK) { - OS::get_singleton()->alert("Your video card driver does not support any of the supported Vulkan versions.", "Unable to initialize Video driver"); + if (p_rendering_driver == "vulkan") { + OS::get_singleton()->alert( + "Your device seems not to support the required Vulkan version.\n\n" + "Please try exporting your game using the 'gl_compatibility' renderer.", + "Unable to initialize Vulkan video driver"); + } else { + OS::get_singleton()->alert( + "Your device seems not to support the required OpenGL ES 3.0 version.", + "Unable to initialize OpenGL video driver"); + } } return ds; } @@ -485,31 +536,14 @@ void DisplayServerAndroid::notify_surface_changed(int p_width, int p_height) { rect_changed_callback.callp(reinterpret_cast<const Variant **>(&sizep), 1, ret, ce); } -DisplayServerAndroid::DisplayServerAndroid(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error) { +DisplayServerAndroid::DisplayServerAndroid(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error) { rendering_driver = p_rendering_driver; - // TODO: rendering_driver is broken, change when different drivers are supported again - rendering_driver = "vulkan"; - keep_screen_on = GLOBAL_GET("display/window/energy_saving/keep_screen_on"); #if defined(GLES3_ENABLED) if (rendering_driver == "opengl3") { - bool gl_initialization_error = false; - - if (RasterizerGLES3::is_viable() == OK) { - RasterizerGLES3::register_config(); - RasterizerGLES3::make_current(); - } else { - gl_initialization_error = true; - } - - if (gl_initialization_error) { - OS::get_singleton()->alert("Your device does not support any of the supported OpenGL versions.\n" - "Please try updating your Android version.", - "Unable to initialize video driver"); - return; - } + RasterizerGLES3::make_current(); } #endif @@ -610,15 +644,15 @@ Point2i DisplayServerAndroid::mouse_get_position() const { return Input::get_singleton()->get_mouse_position(); } -MouseButton DisplayServerAndroid::mouse_get_button_state() const { - return (MouseButton)Input::get_singleton()->get_mouse_button_mask(); +BitField<MouseButtonMask> DisplayServerAndroid::mouse_get_button_state() const { + return Input::get_singleton()->get_mouse_button_mask(); } -void DisplayServerAndroid::cursor_set_shape(DisplayServer::CursorShape p_shape) { +void DisplayServerAndroid::_cursor_set_shape_helper(CursorShape p_shape, bool force) { if (!OS_Android::get_singleton()->get_godot_java()->get_godot_view()->can_update_pointer_icon()) { return; } - if (cursor_shape == p_shape) { + if (cursor_shape == p_shape && !force) { return; } @@ -629,20 +663,58 @@ void DisplayServerAndroid::cursor_set_shape(DisplayServer::CursorShape p_shape) } } +void DisplayServerAndroid::cursor_set_shape(DisplayServer::CursorShape p_shape) { + ERR_FAIL_INDEX(p_shape, CURSOR_MAX); + _cursor_set_shape_helper(p_shape); +} + DisplayServer::CursorShape DisplayServerAndroid::cursor_get_shape() const { return cursor_shape; } +void DisplayServerAndroid::cursor_set_custom_image(const Ref<Resource> &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { + ERR_FAIL_INDEX(p_shape, CURSOR_MAX); + String cursor_path = p_cursor.is_valid() ? p_cursor->get_path() : ""; + if (!cursor_path.is_empty()) { + cursor_path = ProjectSettings::get_singleton()->globalize_path(cursor_path); + } + OS_Android::get_singleton()->get_godot_java()->get_godot_view()->configure_pointer_icon(android_cursors[cursor_shape], cursor_path, p_hotspot); + _cursor_set_shape_helper(p_shape, true); +} + void DisplayServerAndroid::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) { #if defined(VULKAN_ENABLED) - context_vulkan->set_vsync_mode(p_window, p_vsync_mode); + if (context_vulkan) { + context_vulkan->set_vsync_mode(p_window, p_vsync_mode); + } #endif } DisplayServer::VSyncMode DisplayServerAndroid::window_get_vsync_mode(WindowID p_window) const { #if defined(VULKAN_ENABLED) - return context_vulkan->get_vsync_mode(p_window); -#else - return DisplayServer::VSYNC_ENABLED; + if (context_vulkan) { + return context_vulkan->get_vsync_mode(p_window); + } #endif + return DisplayServer::VSYNC_ENABLED; +} + +void DisplayServerAndroid::reset_swap_buffers_flag() { + swap_buffers_flag = false; +} + +bool DisplayServerAndroid::should_swap_buffers() const { + return swap_buffers_flag; +} + +void DisplayServerAndroid::swap_buffers() { + swap_buffers_flag = true; +} + +void DisplayServerAndroid::set_native_icon(const String &p_filename) { + // NOT SUPPORTED +} + +void DisplayServerAndroid::set_icon(const Ref<Image> &p_icon) { + // NOT SUPPORTED } diff --git a/platform/android/display_server_android.h b/platform/android/display_server_android.h index a6bc88e048..e0ad2cb916 100644 --- a/platform/android/display_server_android.h +++ b/platform/android/display_server_android.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* display_server_android.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* display_server_android.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 DISPLAY_SERVER_ANDROID_H #define DISPLAY_SERVER_ANDROID_H @@ -39,6 +39,8 @@ class RenderingDeviceVulkan; #endif class DisplayServerAndroid : public DisplayServer { + // No need to register with GDCLASS, it's platform-specific and nothing is added. + String rendering_driver; // https://developer.android.com/reference/android/view/PointerIcon @@ -66,6 +68,7 @@ class DisplayServerAndroid : public DisplayServer { MouseMode mouse_mode = MouseMode::MOUSE_MODE_VISIBLE; bool keep_screen_on; + bool swap_buffers_flag; CursorShape cursor_shape = CursorShape::CURSOR_ARROW; @@ -114,13 +117,14 @@ public: virtual ScreenOrientation screen_get_orientation(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; virtual int get_screen_count() const override; + virtual int get_primary_screen() const override; virtual Point2i screen_get_position(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; virtual Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; virtual Rect2i screen_get_usable_rect(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; virtual int screen_get_dpi(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; virtual float screen_get_scale(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; virtual float screen_get_refresh_rate(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; - virtual bool screen_is_touchscreen(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; + virtual bool is_touchscreen_available() const override; virtual void virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), VirtualKeyboardType p_type = KEYBOARD_TYPE_DEFAULT, int p_max_length = -1, int p_cursor_start = -1, int p_cursor_end = -1) override; virtual void virtual_keyboard_hide() override; @@ -149,6 +153,7 @@ public: virtual void window_set_current_screen(int p_screen, WindowID p_window = MAIN_WINDOW_ID) override; virtual Point2i window_get_position(WindowID p_window = MAIN_WINDOW_ID) const override; + virtual Point2i window_get_position_with_decorations(WindowID p_window = MAIN_WINDOW_ID) const override; virtual void window_set_position(const Point2i &p_position, WindowID p_window = MAIN_WINDOW_ID) override; virtual void window_set_transient(WindowID p_window, WindowID p_parent) override; @@ -161,7 +166,7 @@ public: virtual void window_set_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID) override; virtual Size2i window_get_size(WindowID p_window = MAIN_WINDOW_ID) const override; - virtual Size2i window_get_real_size(WindowID p_window = MAIN_WINDOW_ID) const override; + virtual Size2i window_get_size_with_decorations(WindowID p_window = MAIN_WINDOW_ID) const override; virtual void window_set_mode(WindowMode p_mode, WindowID p_window = MAIN_WINDOW_ID) override; virtual WindowMode window_get_mode(WindowID p_window = MAIN_WINDOW_ID) const override; @@ -173,6 +178,7 @@ public: virtual void window_request_attention(WindowID p_window = MAIN_WINDOW_ID) override; virtual void window_move_to_foreground(WindowID p_window = MAIN_WINDOW_ID) override; + virtual bool window_is_focused(WindowID p_window = MAIN_WINDOW_ID) const override; virtual bool window_can_draw(WindowID p_window = MAIN_WINDOW_ID) const override; @@ -188,13 +194,15 @@ public: void process_magnetometer(const Vector3 &p_magnetometer); void process_gyroscope(const Vector3 &p_gyroscope); + void _cursor_set_shape_helper(CursorShape p_shape, bool force = false); virtual void cursor_set_shape(CursorShape p_shape) override; virtual CursorShape cursor_get_shape() const override; + virtual void cursor_set_custom_image(const Ref<Resource> &p_cursor, CursorShape p_shape = CURSOR_ARROW, const Vector2 &p_hotspot = Vector2()) override; virtual void mouse_set_mode(MouseMode p_mode) override; virtual MouseMode mouse_get_mode() const override; - static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error); + static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error); static Vector<String> get_rendering_drivers_func(); static void register_android_driver(); @@ -202,9 +210,16 @@ public: void notify_surface_changed(int p_width, int p_height); virtual Point2i mouse_get_position() const override; - virtual MouseButton mouse_get_button_state() const override; + virtual BitField<MouseButtonMask> mouse_get_button_state() const override; + + void reset_swap_buffers_flag(); + bool should_swap_buffers() const; + virtual void swap_buffers() override; + + virtual void set_native_icon(const String &p_filename) override; + virtual void set_icon(const Ref<Image> &p_icon) override; - DisplayServerAndroid(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error); + DisplayServerAndroid(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error); ~DisplayServerAndroid(); }; diff --git a/platform/android/doc_classes/EditorExportPlatformAndroid.xml b/platform/android/doc_classes/EditorExportPlatformAndroid.xml new file mode 100644 index 0000000000..9d68cb78f6 --- /dev/null +++ b/platform/android/doc_classes/EditorExportPlatformAndroid.xml @@ -0,0 +1,590 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="EditorExportPlatformAndroid" inherits="EditorExportPlatform" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> + <brief_description> + Exporter for Android. + </brief_description> + <description> + </description> + <tutorials> + <link title="Exporting for Android">$DOCS_URL/tutorials/export/exporting_for_android.html</link> + <link title="Custom builds for Android">$DOCS_URL/tutorials/export/android_custom_build.html</link> + </tutorials> + <members> + <member name="apk_expansion/SALT" type="String" setter="" getter=""> + Array of random bytes that the licensing Policy uses to create an [url=https://developer.android.com/google/play/licensing/adding-licensing#impl-Obfuscator]Obfuscator[/url]. + </member> + <member name="apk_expansion/enable" type="bool" setter="" getter=""> + If [code]true[/code], project resources are stored in the separate APK expansion file, instead APK. + [b]Note:[/b] APK expansion should be enabled to use PCK encryption. + </member> + <member name="apk_expansion/public_key" type="String" setter="" getter=""> + Base64 encoded RSA public key for your publisher account, available from the profile page on the "Play Console". + </member> + <member name="architectures/arm64-v8a" type="bool" setter="" getter=""> + If [code]true[/code], [code]arm64[/code] binaries are included into exported project. + </member> + <member name="architectures/armeabi-v7a" type="bool" setter="" getter=""> + If [code]true[/code], [code]arm32[/code] binaries are included into exported project. + </member> + <member name="architectures/x86" type="bool" setter="" getter=""> + If [code]true[/code], [code]x86_32[/code] binaries are included into exported project. + </member> + <member name="architectures/x86_64" type="bool" setter="" getter=""> + If [code]true[/code], [code]x86_64[/code] binaries are included into exported project. + </member> + <member name="command_line/extra_args" type="String" setter="" getter=""> + A list of additional command line arguments, exported project will receive when started. + </member> + <member name="custom_template/debug" type="String" setter="" getter=""> + Path to the custom export template. If left empty, default template is used. + </member> + <member name="custom_template/release" type="String" setter="" getter=""> + Path to the custom export template. If left empty, default template is used. + </member> + <member name="gradle_build/export_format" type="int" setter="" getter=""> + Export format for Gradle build. + </member> + <member name="gradle_build/min_sdk" type="String" setter="" getter=""> + Minimal Android SDK version for Gradle build. + </member> + <member name="gradle_build/target_sdk" type="String" setter="" getter=""> + Target Android SDK version for Gradle build. + </member> + <member name="gradle_build/use_gradle_build" type="bool" setter="" getter=""> + If [code]true[/code], Gradle build is used instead of pre-built APK. + </member> + <member name="graphics/opengl_debug" type="bool" setter="" getter=""> + If [code]true[/code], OpenGL ES debug context will be created (additional runtime checking, validation, and logging). + </member> + <member name="keystore/debug" type="String" setter="" getter=""> + Path of the debug keystore file. + Can be overridden with the environment variable [code]GODOT_ANDROID_KEYSTORE_DEBUG_PATH[/code]. + Fallbacks to [code]EditorSettings.export/android/debug_keystore[/code] if empty. + </member> + <member name="keystore/debug_password" type="String" setter="" getter=""> + Password for the debug keystore file. + Can be overridden with the environment variable [code]GODOT_ANDROID_KEYSTORE_DEBUG_PASSWORD[/code]. + Fallbacks to [code]EditorSettings.export/android/debug_keystore_pass[/code] if both it and [member keystore/debug] are empty. + </member> + <member name="keystore/debug_user" type="String" setter="" getter=""> + User name for the debug keystore file. + Can be overridden with the environment variable [code]GODOT_ANDROID_KEYSTORE_DEBUG_USER[/code]. + Fallbacks to [code]EditorSettings.export/android/debug_keystore_user[/code] if both it and [member keystore/debug] are empty. + </member> + <member name="keystore/release" type="String" setter="" getter=""> + Path of the release keystore file. + Can be overridden with the environment variable [code]GODOT_ANDROID_KEYSTORE_RELEASE_PATH[/code]. + </member> + <member name="keystore/release_password" type="String" setter="" getter=""> + Password for the release keystore file. + Can be overridden with the environment variable [code]GODOT_ANDROID_KEYSTORE_RELEASE_PASSWORD[/code]. + </member> + <member name="keystore/release_user" type="String" setter="" getter=""> + User name for the release keystore file. + Can be overridden with the environment variable [code]GODOT_ANDROID_KEYSTORE_RELEASE_USER[/code]. + </member> + <member name="launcher_icons/adaptive_background_432x432" type="String" setter="" getter=""> + Background layer of the application adaptive icon file. + </member> + <member name="launcher_icons/adaptive_foreground_432x432" type="String" setter="" getter=""> + Foreground layer of the application adaptive icon file. + </member> + <member name="launcher_icons/main_192x192" type="String" setter="" getter=""> + Application icon file. If left empty, it will fallback to [member ProjectSettings.application/config/icon]. + </member> + <member name="package/app_category" type="int" setter="" getter=""> + Application category for the Play Store. + </member> + <member name="package/exclude_from_recents" type="bool" setter="" getter=""> + If [code]true[/code], task initiated by main activity will be excluded from the list of recently used applications. + </member> + <member name="package/name" type="String" setter="" getter=""> + Name of the application. + </member> + <member name="package/retain_data_on_uninstall" type="bool" setter="" getter=""> + If [code]true[/code], when the user uninstalls an app, a prompt to keep the app's data will be shown. + </member> + <member name="package/signed" type="bool" setter="" getter=""> + If [code]true[/code], package signing is enabled. + </member> + <member name="package/unique_name" type="String" setter="" getter=""> + Unique application identifier in a reverse-DNS format, can only contain alphanumeric characters ([code]A-Z[/code], [code]a-z[/code], and [code]0-9[/code]), hyphens ([code]-[/code]), and periods ([code].[/code]). + </member> + <member name="permissions/access_checkin_properties" type="bool" setter="" getter=""> + Allows read/write access to the "properties" table in the checkin database. See [url=https://developer.android.com/reference/android/Manifest.permission#ACCESS_CHECKIN_PROPERTIES]ACCESS_CHECKIN_PROPERTIES[/url]. + </member> + <member name="permissions/access_coarse_location" type="bool" setter="" getter=""> + Allows access to the approximate location information. See [url=https://developer.android.com/reference/android/Manifest.permission#ACCESS_COARSE_LOCATION]ACCESS_COARSE_LOCATION[/url]. + </member> + <member name="permissions/access_fine_location" type="bool" setter="" getter=""> + Allows access to the precise location information. See [url=https://developer.android.com/reference/android/Manifest.permission#ACCESS_FINE_LOCATION]ACCESS_FINE_LOCATION[/url]. + </member> + <member name="permissions/access_location_extra_commands" type="bool" setter="" getter=""> + Allows access to the extra location provider commands. See [url=https://developer.android.com/reference/android/Manifest.permission#ACCESS_LOCATION_EXTRA_COMMANDS]ACCESS_LOCATION_EXTRA_COMMANDS[/url]. + </member> + <member name="permissions/access_mock_location" type="bool" setter="" getter=""> + Allows an application to create mock location providers for testing. + </member> + <member name="permissions/access_network_state" type="bool" setter="" getter=""> + Allows access to the information about networks. See [url=https://developer.android.com/reference/android/Manifest.permission#ACCESS_NETWORK_STATE]ACCESS_NETWORK_STATE[/url]. + </member> + <member name="permissions/access_surface_flinger" type="bool" setter="" getter=""> + Allows an application to use SurfaceFlinger's low level features. + </member> + <member name="permissions/access_wifi_state" type="bool" setter="" getter=""> + Allows access to the information about Wi-Fi networks. See [url=https://developer.android.com/reference/android/Manifest.permission#ACCESS_WIFI_STATE]ACCESS_WIFI_STATE[/url]. + </member> + <member name="permissions/account_manager" type="bool" setter="" getter=""> + Allows applications to call into AccountAuthenticators. See [url=https://developer.android.com/reference/android/Manifest.permission#ACCOUNT_MANAGER]ACCOUNT_MANAGER[/url]. + </member> + <member name="permissions/add_voicemail" type="bool" setter="" getter=""> + Allows an application to add voicemails into the system. See [url=https://developer.android.com/reference/android/Manifest.permission#ADD_VOICEMAIL]ADD_VOICEMAIL[/url]. + </member> + <member name="permissions/authenticate_accounts" type="bool" setter="" getter=""> + Allows an application to act as an AccountAuthenticator for the AccountManager. + </member> + <member name="permissions/battery_stats" type="bool" setter="" getter=""> + Allows an application to collect battery statistics. Sett [url=https://developer.android.com/reference/android/Manifest.permission#BATTERY_STATS]BATTERY_STATS[/url]. + </member> + <member name="permissions/bind_accessibility_service" type="bool" setter="" getter=""> + Must be required by an AccessibilityService, to ensure that only the system can bind to it. See [url=https://developer.android.com/reference/android/Manifest.permission#BIND_ACCESSIBILITY_SERVICE]BIND_ACCESSIBILITY_SERVICE[/url]. + </member> + <member name="permissions/bind_appwidget" type="bool" setter="" getter=""> + Allows an application to tell the AppWidget service which application can access AppWidget's data. See [url=https://developer.android.com/reference/android/Manifest.permission#BIND_APPWIDGET]BIND_APPWIDGET[/url]. + </member> + <member name="permissions/bind_device_admin" type="bool" setter="" getter=""> + Must be required by device administration receiver, to ensure that only the system can interact with it. See [url=https://developer.android.com/reference/android/Manifest.permission#BIND_DEVICE_ADMIN]BIND_DEVICE_ADMIN[/url]. + </member> + <member name="permissions/bind_input_method" type="bool" setter="" getter=""> + Must be required by an InputMethodService, to ensure that only the system can bind to it. See [url=https://developer.android.com/reference/android/Manifest.permission#BIND_INPUT_METHOD]BIND_INPUT_METHOD[/url]. + </member> + <member name="permissions/bind_nfc_service" type="bool" setter="" getter=""> + Must be required by a HostApduService or OffHostApduService to ensure that only the system can bind to it. See [url=https://developer.android.com/reference/android/Manifest.permission#BIND_NFC_SERVICE]BIND_NFC_SERVICE[/url]. + </member> + <member name="permissions/bind_notification_listener_service" type="bool" setter="" getter=""> + Must be required by a NotificationListenerService, to ensure that only the system can bind to it. See [url=https://developer.android.com/reference/android/Manifest.permission#BIND_NOTIFICATION_LISTENER_SERVICE]BIND_NOTIFICATION_LISTENER_SERVICE[/url]. + </member> + <member name="permissions/bind_print_service" type="bool" setter="" getter=""> + Must be required by a PrintService, to ensure that only the system can bind to it. See [url=https://developer.android.com/reference/android/Manifest.permission#BIND_PRINT_SERVICE]BIND_PRINT_SERVICE[/url]. + </member> + <member name="permissions/bind_remoteviews" type="bool" setter="" getter=""> + Must be required by a RemoteViewsService, to ensure that only the system can bind to it. See [url=https://developer.android.com/reference/android/Manifest.permission#BIND_REMOTEVIEWS]BIND_REMOTEVIEWS[/url]. + </member> + <member name="permissions/bind_text_service" type="bool" setter="" getter=""> + Must be required by a TextService (e.g. SpellCheckerService) to ensure that only the system can bind to it. See [url=https://developer.android.com/reference/android/Manifest.permission#BIND_TEXT_SERVICE]BIND_TEXT_SERVICE[/url]. + </member> + <member name="permissions/bind_vpn_service" type="bool" setter="" getter=""> + Must be required by a VpnService, to ensure that only the system can bind to it. See [url=https://developer.android.com/reference/android/Manifest.permission#BIND_VPN_SERVICE]BIND_VPN_SERVICE[/url]. + </member> + <member name="permissions/bind_wallpaper" type="bool" setter="" getter=""> + Must be required by a WallpaperService, to ensure that only the system can bind to it. See [url=https://developer.android.com/reference/android/Manifest.permission#BIND_WALLPAPER]BIND_WALLPAPER[/url]. + </member> + <member name="permissions/bluetooth" type="bool" setter="" getter=""> + Allows applications to connect to paired bluetooth devices. See [url=https://developer.android.com/reference/android/Manifest.permission#BLUETOOTH]BLUETOOTH[/url]. + </member> + <member name="permissions/bluetooth_admin" type="bool" setter="" getter=""> + Allows applications to discover and pair bluetooth devices. See [url=https://developer.android.com/reference/android/Manifest.permission#BLUETOOTH_ADMIN]BLUETOOTH_ADMIN[/url]. + </member> + <member name="permissions/bluetooth_privileged" type="bool" setter="" getter=""> + Allows applications to pair bluetooth devices without user interaction, and to allow or disallow phonebook access or message access. See [url=https://developer.android.com/reference/android/Manifest.permission#BLUETOOTH_PRIVILEGED]BLUETOOTH_PRIVILEGED[/url]. + </member> + <member name="permissions/brick" type="bool" setter="" getter=""> + Required to be able to disable the device (very dangerous!). + </member> + <member name="permissions/broadcast_package_removed" type="bool" setter="" getter=""> + Allows an application to broadcast a notification that an application package has been removed. See [url=https://developer.android.com/reference/android/Manifest.permission#BROADCAST_PACKAGE_REMOVED]BROADCAST_PACKAGE_REMOVED[/url]. + </member> + <member name="permissions/broadcast_sms" type="bool" setter="" getter=""> + Allows an application to broadcast an SMS receipt notification. See [url=https://developer.android.com/reference/android/Manifest.permission#BROADCAST_SMS]BROADCAST_SMS[/url]. + </member> + <member name="permissions/broadcast_sticky" type="bool" setter="" getter=""> + Allows an application to broadcast sticky intents. See [url=https://developer.android.com/reference/android/Manifest.permission#BROADCAST_STICKY]BROADCAST_STICKY[/url]. + </member> + <member name="permissions/broadcast_wap_push" type="bool" setter="" getter=""> + Allows an application to broadcast a WAP PUSH receipt notification. See [url=https://developer.android.com/reference/android/Manifest.permission#BROADCAST_WAP_PUSH]BROADCAST_WAP_PUSH[/url]. + </member> + <member name="permissions/call_phone" type="bool" setter="" getter=""> + Allows an application to initiate a phone call without going through the Dialer user interface. See [url=https://developer.android.com/reference/android/Manifest.permission#CALL_PHONE]CALL_PHONE[/url]. + </member> + <member name="permissions/call_privileged" type="bool" setter="" getter=""> + Allows an application to call any phone number, including emergency numbers, without going through the Dialer user interface. See [url=https://developer.android.com/reference/android/Manifest.permission#CALL_PRIVILEGED]CALL_PRIVILEGED[/url]. + </member> + <member name="permissions/camera" type="bool" setter="" getter=""> + Required to be able to access the camera device. See [url=https://developer.android.com/reference/android/Manifest.permission#CAMERA]CAMERA[/url]. + </member> + <member name="permissions/capture_audio_output" type="bool" setter="" getter=""> + Allows an application to capture audio output. See [url=https://developer.android.com/reference/android/Manifest.permission#CAPTURE_AUDIO_OUTPUT]CAPTURE_AUDIO_OUTPUT[/url]. + </member> + <member name="permissions/capture_secure_video_output" type="bool" setter="" getter=""> + Allows an application to capture secure video output. + </member> + <member name="permissions/capture_video_output" type="bool" setter="" getter=""> + Allows an application to capture video output. + </member> + <member name="permissions/change_component_enabled_state" type="bool" setter="" getter=""> + Allows an application to change whether an application component (other than its own) is enabled or not. See [url=https://developer.android.com/reference/android/Manifest.permission#CHANGE_COMPONENT_ENABLED_STATE]CHANGE_COMPONENT_ENABLED_STATE[/url]. + </member> + <member name="permissions/change_configuration" type="bool" setter="" getter=""> + Allows an application to modify the current configuration, such as locale. See [url=https://developer.android.com/reference/android/Manifest.permission#CHANGE_CONFIGURATION]CHANGE_CONFIGURATION[/url]. + </member> + <member name="permissions/change_network_state" type="bool" setter="" getter=""> + Allows applications to change network connectivity state. See [url=https://developer.android.com/reference/android/Manifest.permission#CHANGE_NETWORK_STATE]CHANGE_NETWORK_STATE[/url]. + </member> + <member name="permissions/change_wifi_multicast_state" type="bool" setter="" getter=""> + Allows applications to enter Wi-Fi Multicast mode. See [url=https://developer.android.com/reference/android/Manifest.permission#CHANGE_WIFI_MULTICAST_STATE]CHANGE_WIFI_MULTICAST_STATE[/url]. + </member> + <member name="permissions/change_wifi_state" type="bool" setter="" getter=""> + Allows applications to change Wi-Fi connectivity state. See [url=https://developer.android.com/reference/android/Manifest.permission#CHANGE_WIFI_STATE]CHANGE_WIFI_STATE[/url]. + </member> + <member name="permissions/clear_app_cache" type="bool" setter="" getter=""> + Allows an application to clear the caches of all installed applications on the device. See [url=https://developer.android.com/reference/android/Manifest.permission#CLEAR_APP_CACHE]CLEAR_APP_CACHE[/url]. + </member> + <member name="permissions/clear_app_user_data" type="bool" setter="" getter=""> + Allows an application to clear user data. + </member> + <member name="permissions/control_location_updates" type="bool" setter="" getter=""> + Allows enabling/disabling location update notifications from the radio. See [url=https://developer.android.com/reference/android/Manifest.permission#CONTROL_LOCATION_UPDATES]CONTROL_LOCATION_UPDATES[/url]. + </member> + <member name="permissions/custom_permissions" type="PackedStringArray" setter="" getter=""> + Array of custom permission strings. + </member> + <member name="permissions/delete_cache_files" type="bool" setter="" getter=""> + Deprecated. + </member> + <member name="permissions/delete_packages" type="bool" setter="" getter=""> + Allows an application to delete packages. See [url=https://developer.android.com/reference/android/Manifest.permission#DELETE_PACKAGES]DELETE_PACKAGES[/url]. + </member> + <member name="permissions/device_power" type="bool" setter="" getter=""> + Allows low-level access to power management. + </member> + <member name="permissions/diagnostic" type="bool" setter="" getter=""> + Allows applications to RW to diagnostic resources. See [url=https://developer.android.com/reference/android/Manifest.permission#DIAGNOSTIC]DIAGNOSTIC[/url]. + </member> + <member name="permissions/disable_keyguard" type="bool" setter="" getter=""> + Allows applications to disable the keyguard if it is not secure. See [url=https://developer.android.com/reference/android/Manifest.permission#DISABLE_KEYGUARD]DISABLE_KEYGUARD[/url]. + </member> + <member name="permissions/dump" type="bool" setter="" getter=""> + Allows an application to retrieve state dump information from system services. See [url=https://developer.android.com/reference/android/Manifest.permission#DUMP]DUMP[/url]. + </member> + <member name="permissions/expand_status_bar" type="bool" setter="" getter=""> + Allows an application to expand or collapse the status bar. See [url=https://developer.android.com/reference/android/Manifest.permission#EXPAND_STATUS_BAR]EXPAND_STATUS_BAR[/url]. + </member> + <member name="permissions/factory_test" type="bool" setter="" getter=""> + Run as a manufacturer test application, running as the root user. See [url=https://developer.android.com/reference/android/Manifest.permission#FACTORY_TEST]FACTORY_TEST[/url]. + </member> + <member name="permissions/flashlight" type="bool" setter="" getter=""> + Allows access to the flashlight. + </member> + <member name="permissions/force_back" type="bool" setter="" getter=""> + Allows an application to force a BACK operation on whatever is the top activity. + </member> + <member name="permissions/get_accounts" type="bool" setter="" getter=""> + Allows access to the list of accounts in the Accounts Service. See [url=https://developer.android.com/reference/android/Manifest.permission#GET_ACCOUNTS]GET_ACCOUNTS[/url]. + </member> + <member name="permissions/get_package_size" type="bool" setter="" getter=""> + Allows an application to find out the space used by any package. See [url=https://developer.android.com/reference/android/Manifest.permission#GET_PACKAGE_SIZE]GET_PACKAGE_SIZE[/url]. + </member> + <member name="permissions/get_tasks" type="bool" setter="" getter=""> + Deprecated in API level 21. + </member> + <member name="permissions/get_top_activity_info" type="bool" setter="" getter=""> + Allows an application to retrieve private information about the current top activity. + </member> + <member name="permissions/global_search" type="bool" setter="" getter=""> + Used on content providers to allow the global search system to access their data. See [url=https://developer.android.com/reference/android/Manifest.permission#GLOBAL_SEARCH]GLOBAL_SEARCH[/url]. + </member> + <member name="permissions/hardware_test" type="bool" setter="" getter=""> + Allows access to hardware peripherals. + </member> + <member name="permissions/inject_events" type="bool" setter="" getter=""> + Allows an application to inject user events (keys, touch, trackball) into the event stream and deliver them to ANY window. + </member> + <member name="permissions/install_location_provider" type="bool" setter="" getter=""> + Allows an application to install a location provider into the Location Manager. See [url=https://developer.android.com/reference/android/Manifest.permission#INSTALL_LOCATION_PROVIDER]INSTALL_LOCATION_PROVIDER[/url]. + </member> + <member name="permissions/install_packages" type="bool" setter="" getter=""> + Allows an application to install packages. See [url=https://developer.android.com/reference/android/Manifest.permission#INSTALL_PACKAGES]INSTALL_PACKAGES[/url]. + </member> + <member name="permissions/install_shortcut" type="bool" setter="" getter=""> + Allows an application to install a shortcut in Launcher. See [url=https://developer.android.com/reference/android/Manifest.permission#INSTALL_SHORTCUT]INSTALL_SHORTCUT[/url]. + </member> + <member name="permissions/internal_system_window" type="bool" setter="" getter=""> + Allows an application to open windows that are for use by parts of the system user interface. + </member> + <member name="permissions/internet" type="bool" setter="" getter=""> + Allows applications to open network sockets. See [url=https://developer.android.com/reference/android/Manifest.permission#INTERNET]INTERNET[/url]. + </member> + <member name="permissions/kill_background_processes" type="bool" setter="" getter=""> + Allows an application to call ActivityManager.killBackgroundProcesses(String). See [url=https://developer.android.com/reference/android/Manifest.permission#KILL_BACKGROUND_PROCESSES]KILL_BACKGROUND_PROCESSES[/url]. + </member> + <member name="permissions/location_hardware" type="bool" setter="" getter=""> + Allows an application to use location features in hardware, such as the geofencing api. See [url=https://developer.android.com/reference/android/Manifest.permission#LOCATION_HARDWARE]LOCATION_HARDWARE[/url]. + </member> + <member name="permissions/manage_accounts" type="bool" setter="" getter=""> + Allows an application to manage the list of accounts in the AccountManager. + </member> + <member name="permissions/manage_app_tokens" type="bool" setter="" getter=""> + Allows an application to manage (create, destroy, Z-order) application tokens in the window manager. + </member> + <member name="permissions/manage_documents" type="bool" setter="" getter=""> + Allows an application to manage access to documents, usually as part of a document picker. See [url=https://developer.android.com/reference/android/Manifest.permission#MANAGE_DOCUMENTS]MANAGE_DOCUMENTS[/url]. + </member> + <member name="permissions/manage_external_storage" type="bool" setter="" getter=""> + Allows an application a broad access to external storage in scoped storage. See [url=https://developer.android.com/reference/android/Manifest.permission#MANAGE_EXTERNAL_STORAGE]MANAGE_EXTERNAL_STORAGE[/url]. + </member> + <member name="permissions/master_clear" type="bool" setter="" getter=""> + See [url=https://developer.android.com/reference/android/Manifest.permission#MASTER_CLEAR]MASTER_CLEAR[/url]. + </member> + <member name="permissions/media_content_control" type="bool" setter="" getter=""> + Allows an application to know what content is playing and control its playback. See [url=https://developer.android.com/reference/android/Manifest.permission#MEDIA_CONTENT_CONTROL]MEDIA_CONTENT_CONTROL[/url]. + </member> + <member name="permissions/modify_audio_settings" type="bool" setter="" getter=""> + Allows an application to modify global audio settings. See [url=https://developer.android.com/reference/android/Manifest.permission#MODIFY_AUDIO_SETTINGS]MODIFY_AUDIO_SETTINGS[/url]. + </member> + <member name="permissions/modify_phone_state" type="bool" setter="" getter=""> + Allows modification of the telephony state - power on, mmi, etc. Does not include placing calls. See [url=https://developer.android.com/reference/android/Manifest.permission#MODIFY_PHONE_STATE]MODIFY_PHONE_STATE[/url]. + </member> + <member name="permissions/mount_format_filesystems" type="bool" setter="" getter=""> + Allows formatting file systems for removable storage. See [url=https://developer.android.com/reference/android/Manifest.permission#MOUNT_FORMAT_FILESYSTEMS]MOUNT_FORMAT_FILESYSTEMS[/url]. + </member> + <member name="permissions/mount_unmount_filesystems" type="bool" setter="" getter=""> + Allows mounting and unmounting file systems for removable storage. See [url=https://developer.android.com/reference/android/Manifest.permission#MOUNT_UNMOUNT_FILESYSTEMS]MOUNT_UNMOUNT_FILESYSTEMS[/url]. + </member> + <member name="permissions/nfc" type="bool" setter="" getter=""> + Allows applications to perform I/O operations over NFC. See [url=https://developer.android.com/reference/android/Manifest.permission#NFC]NFC[/url]. + </member> + <member name="permissions/persistent_activity" type="bool" setter="" getter=""> + Allow an application to make its activities persistent. + Deprecated in API level 15. + </member> + <member name="permissions/process_outgoing_calls" type="bool" setter="" getter=""> + Allows an application to see the number being dialed during an outgoing call with the option to redirect the call to a different number or abort the call altogether. See [url=https://developer.android.com/reference/android/Manifest.permission#PROCESS_OUTGOING_CALLS]PROCESS_OUTGOING_CALLS[/url]. + Deprecated in API level 29. + </member> + <member name="permissions/read_calendar" type="bool" setter="" getter=""> + Allows an application to read the user's calendar data. See [url=https://developer.android.com/reference/android/Manifest.permission#READ_CALENDAR]READ_CALENDAR[/url]. + </member> + <member name="permissions/read_call_log" type="bool" setter="" getter=""> + Allows an application to read the user's call log. See [url=https://developer.android.com/reference/android/Manifest.permission#READ_CALL_LOG]READ_CALL_LOG[/url]. + </member> + <member name="permissions/read_contacts" type="bool" setter="" getter=""> + Allows an application to read the user's contacts data. See [url=https://developer.android.com/reference/android/Manifest.permission#READ_CONTACTS]READ_CONTACTS[/url]. + </member> + <member name="permissions/read_external_storage" type="bool" setter="" getter=""> + Allows an application to read from external storage. See [url=https://developer.android.com/reference/android/Manifest.permission#READ_EXTERNAL_STORAGE]READ_EXTERNAL_STORAGE[/url]. + Deprecated in API level 33. + </member> + <member name="permissions/read_frame_buffer" type="bool" setter="" getter=""> + Allows an application to take screen shots and more generally get access to the frame buffer data. + </member> + <member name="permissions/read_history_bookmarks" type="bool" setter="" getter=""> + Allows an application to read (but not write) the user's browsing history and bookmarks. + </member> + <member name="permissions/read_input_state" type="bool" setter="" getter=""> + Deprecated in API level 16. + </member> + <member name="permissions/read_logs" type="bool" setter="" getter=""> + Allows an application to read the low-level system log files. See [url=https://developer.android.com/reference/android/Manifest.permission#READ_LOGS]READ_LOGS[/url]. + </member> + <member name="permissions/read_phone_state" type="bool" setter="" getter=""> + Allows read only access to phone state. See [url=https://developer.android.com/reference/android/Manifest.permission#READ_PHONE_STATE]READ_PHONE_STATE[/url]. + </member> + <member name="permissions/read_profile" type="bool" setter="" getter=""> + Allows an application to read the user's personal profile data. + </member> + <member name="permissions/read_sms" type="bool" setter="" getter=""> + Allows an application to read SMS messages. See [url=https://developer.android.com/reference/android/Manifest.permission#READ_SMS]READ_SMS[/url]. + </member> + <member name="permissions/read_social_stream" type="bool" setter="" getter=""> + Allows an application to read from the user's social stream. + </member> + <member name="permissions/read_sync_settings" type="bool" setter="" getter=""> + Allows applications to read the sync settings. See [url=https://developer.android.com/reference/android/Manifest.permission#READ_SYNC_SETTINGS]READ_SYNC_SETTINGS[/url]. + </member> + <member name="permissions/read_sync_stats" type="bool" setter="" getter=""> + Allows applications to read the sync stats. See [url=https://developer.android.com/reference/android/Manifest.permission#READ_SYNC_STATS]READ_SYNC_STATS[/url]. + </member> + <member name="permissions/read_user_dictionary" type="bool" setter="" getter=""> + Allows an application to read the user dictionary. + </member> + <member name="permissions/reboot" type="bool" setter="" getter=""> + Required to be able to reboot the device. See [url=https://developer.android.com/reference/android/Manifest.permission#REBOOT]REBOOT[/url]. + </member> + <member name="permissions/receive_boot_completed" type="bool" setter="" getter=""> + Allows an application to receive the Intent.ACTION_BOOT_COMPLETED that is broadcast after the system finishes booting. See [url=https://developer.android.com/reference/android/Manifest.permission#RECEIVE_BOOT_COMPLETED]RECEIVE_BOOT_COMPLETED[/url]. + </member> + <member name="permissions/receive_mms" type="bool" setter="" getter=""> + Allows an application to monitor incoming MMS messages. See [url=https://developer.android.com/reference/android/Manifest.permission#RECEIVE_MMS]RECEIVE_MMS[/url]. + </member> + <member name="permissions/receive_sms" type="bool" setter="" getter=""> + Allows an application to receive SMS messages. See [url=https://developer.android.com/reference/android/Manifest.permission#RECEIVE_SMS]RECEIVE_SMS[/url]. + </member> + <member name="permissions/receive_wap_push" type="bool" setter="" getter=""> + Allows an application to receive WAP push messages. See [url=https://developer.android.com/reference/android/Manifest.permission#RECEIVE_WAP_PUSH]RECEIVE_WAP_PUSH[/url]. + </member> + <member name="permissions/record_audio" type="bool" setter="" getter=""> + Allows an application to record audio. See [url=https://developer.android.com/reference/android/Manifest.permission#RECORD_AUDIO]RECORD_AUDIO[/url]. + </member> + <member name="permissions/reorder_tasks" type="bool" setter="" getter=""> + Allows an application to change the Z-order of tasks. See [url=https://developer.android.com/reference/android/Manifest.permission#REORDER_TASKS]REORDER_TASKS[/url]. + </member> + <member name="permissions/restart_packages" type="bool" setter="" getter=""> + Deprecated in API level 15. + </member> + <member name="permissions/send_respond_via_message" type="bool" setter="" getter=""> + Allows an application (Phone) to send a request to other applications to handle the respond-via-message action during incoming calls. See [url=https://developer.android.com/reference/android/Manifest.permission#SEND_RESPOND_VIA_MESSAGE]SEND_RESPOND_VIA_MESSAGE[/url]. + </member> + <member name="permissions/send_sms" type="bool" setter="" getter=""> + Allows an application to send SMS messages. See [url=https://developer.android.com/reference/android/Manifest.permission#SEND_SMS]SEND_SMS[/url]. + </member> + <member name="permissions/set_activity_watcher" type="bool" setter="" getter=""> + Allows an application to watch and control how activities are started globally in the system. + </member> + <member name="permissions/set_alarm" type="bool" setter="" getter=""> + Allows an application to broadcast an Intent to set an alarm for the user. See [url=https://developer.android.com/reference/android/Manifest.permission#SET_ALARM]SET_ALARM[/url]. + </member> + <member name="permissions/set_always_finish" type="bool" setter="" getter=""> + Allows an application to control whether activities are immediately finished when put in the background. See [url=https://developer.android.com/reference/android/Manifest.permission#SET_ALWAYS_FINISH]SET_ALWAYS_FINISH[/url]. + </member> + <member name="permissions/set_animation_scale" type="bool" setter="" getter=""> + Allows to modify the global animation scaling factor. See [url=https://developer.android.com/reference/android/Manifest.permission#SET_ANIMATION_SCALE]SET_ANIMATION_SCALE[/url]. + </member> + <member name="permissions/set_debug_app" type="bool" setter="" getter=""> + Configure an application for debugging. See [url=https://developer.android.com/reference/android/Manifest.permission#SET_DEBUG_APP]SET_DEBUG_APP[/url]. + </member> + <member name="permissions/set_orientation" type="bool" setter="" getter=""> + Allows low-level access to setting the orientation (actually rotation) of the screen. + </member> + <member name="permissions/set_pointer_speed" type="bool" setter="" getter=""> + Allows low-level access to setting the pointer speed. + </member> + <member name="permissions/set_preferred_applications" type="bool" setter="" getter=""> + Deprecated in API level 15. + </member> + <member name="permissions/set_process_limit" type="bool" setter="" getter=""> + Allows an application to set the maximum number of (not needed) application processes that can be running. See [url=https://developer.android.com/reference/android/Manifest.permission#SET_PROCESS_LIMIT]SET_PROCESS_LIMIT[/url]. + </member> + <member name="permissions/set_time" type="bool" setter="" getter=""> + Allows applications to set the system time directly. See [url=https://developer.android.com/reference/android/Manifest.permission#SET_TIME]SET_TIME[/url]. + </member> + <member name="permissions/set_time_zone" type="bool" setter="" getter=""> + Allows applications to set the system time zone directly. See [url=https://developer.android.com/reference/android/Manifest.permission#SET_TIME_ZONE]SET_TIME_ZONE[/url]. + </member> + <member name="permissions/set_wallpaper" type="bool" setter="" getter=""> + Allows applications to set the wallpaper. See [url=https://developer.android.com/reference/android/Manifest.permission#SET_WALLPAPER]SET_WALLPAPER[/url]. + </member> + <member name="permissions/set_wallpaper_hints" type="bool" setter="" getter=""> + Allows applications to set the wallpaper hints. See [url=https://developer.android.com/reference/android/Manifest.permission#SET_WALLPAPER_HINTS]SET_WALLPAPER_HINTS[/url]. + </member> + <member name="permissions/signal_persistent_processes" type="bool" setter="" getter=""> + Allow an application to request that a signal be sent to all persistent processes. See [url=https://developer.android.com/reference/android/Manifest.permission#SIGNAL_PERSISTENT_PROCESSES]SIGNAL_PERSISTENT_PROCESSES[/url]. + </member> + <member name="permissions/status_bar" type="bool" setter="" getter=""> + Allows an application to open, close, or disable the status bar and its icons. See [url=https://developer.android.com/reference/android/Manifest.permission#STATUS_BAR]STATUS_BAR[/url]. + </member> + <member name="permissions/subscribed_feeds_read" type="bool" setter="" getter=""> + Allows an application to allow access the subscribed feeds ContentProvider. + </member> + <member name="permissions/subscribed_feeds_write" type="bool" setter="" getter=""> + Deprecated. + </member> + <member name="permissions/system_alert_window" type="bool" setter="" getter=""> + Allows an app to create windows using the type WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY, shown on top of all other apps. See [url=https://developer.android.com/reference/android/Manifest.permission#SYSTEM_ALERT_WINDOW]SYSTEM_ALERT_WINDOW[/url]. + </member> + <member name="permissions/transmit_ir" type="bool" setter="" getter=""> + Allows using the device's IR transmitter, if available. See [url=https://developer.android.com/reference/android/Manifest.permission#TRANSMIT_IR]TRANSMIT_IR[/url]. + </member> + <member name="permissions/uninstall_shortcut" type="bool" setter="" getter=""> + Deprecated. + </member> + <member name="permissions/update_device_stats" type="bool" setter="" getter=""> + Allows an application to update device statistics. See [url=https://developer.android.com/reference/android/Manifest.permission#UPDATE_DEVICE_STATS]UPDATE_DEVICE_STATS[/url]. + </member> + <member name="permissions/use_credentials" type="bool" setter="" getter=""> + Allows an application to request authtokens from the AccountManager. + </member> + <member name="permissions/use_sip" type="bool" setter="" getter=""> + Allows an application to use SIP service. See [url=https://developer.android.com/reference/android/Manifest.permission#USE_SIP]USE_SIP[/url]. + </member> + <member name="permissions/vibrate" type="bool" setter="" getter=""> + Allows access to the vibrator. See [url=https://developer.android.com/reference/android/Manifest.permission#VIBRATE]VIBRATE[/url]. + </member> + <member name="permissions/wake_lock" type="bool" setter="" getter=""> + Allows using PowerManager WakeLocks to keep processor from sleeping or screen from dimming. See [url=https://developer.android.com/reference/android/Manifest.permission#WAKE_LOCK]WAKE_LOCK[/url]. + </member> + <member name="permissions/write_apn_settings" type="bool" setter="" getter=""> + Allows applications to write the apn settings and read sensitive fields of an existing apn settings like user and password. See [url=https://developer.android.com/reference/android/Manifest.permission#WRITE_APN_SETTINGS]WRITE_APN_SETTINGS[/url]. + </member> + <member name="permissions/write_calendar" type="bool" setter="" getter=""> + Allows an application to write the user's calendar data. See [url=https://developer.android.com/reference/android/Manifest.permission#WRITE_CALENDAR]WRITE_CALENDAR[/url]. + </member> + <member name="permissions/write_call_log" type="bool" setter="" getter=""> + Allows an application to write (but not read) the user's call log data. See [url=https://developer.android.com/reference/android/Manifest.permission#WRITE_CALL_LOG]WRITE_CALL_LOG[/url]. + </member> + <member name="permissions/write_contacts" type="bool" setter="" getter=""> + Allows an application to write the user's contacts data. See [url=https://developer.android.com/reference/android/Manifest.permission#WRITE_CONTACTS]WRITE_CONTACTS[/url]. + </member> + <member name="permissions/write_external_storage" type="bool" setter="" getter=""> + Allows an application to write to external storage. See [url=https://developer.android.com/reference/android/Manifest.permission#WRITE_EXTERNAL_STORAGE]WRITE_EXTERNAL_STORAGE[/url]. + </member> + <member name="permissions/write_gservices" type="bool" setter="" getter=""> + Allows an application to modify the Google service map. See [url=https://developer.android.com/reference/android/Manifest.permission#WRITE_GSERVICES]WRITE_GSERVICES[/url]. + </member> + <member name="permissions/write_history_bookmarks" type="bool" setter="" getter=""> + Allows an application to write (but not read) the user's browsing history and bookmarks. + </member> + <member name="permissions/write_profile" type="bool" setter="" getter=""> + Allows an application to write (but not read) the user's personal profile data. + </member> + <member name="permissions/write_secure_settings" type="bool" setter="" getter=""> + Allows an application to read or write the secure system settings. See [url=https://developer.android.com/reference/android/Manifest.permission#WRITE_SECURE_SETTINGS]WRITE_SECURE_SETTINGS[/url]. + </member> + <member name="permissions/write_settings" type="bool" setter="" getter=""> + Allows an application to read or write the system settings. See [url=https://developer.android.com/reference/android/Manifest.permission#WRITE_SETTINGS]WRITE_SETTINGS[/url]. + </member> + <member name="permissions/write_sms" type="bool" setter="" getter=""> + Allows an application to write SMS messages. + </member> + <member name="permissions/write_social_stream" type="bool" setter="" getter=""> + Allows an application to write (but not read) the user's social stream data. + </member> + <member name="permissions/write_sync_settings" type="bool" setter="" getter=""> + Allows applications to write the sync settings. See [url=https://developer.android.com/reference/android/Manifest.permission#WRITE_SYNC_SETTINGS]WRITE_SYNC_SETTINGS[/url]. + </member> + <member name="permissions/write_user_dictionary" type="bool" setter="" getter=""> + Allows an application to write to the user dictionary. + </member> + <member name="screen/immersive_mode" type="bool" setter="" getter=""> + If [code]true[/code], hides navigation and status bar. + </member> + <member name="screen/support_large" type="bool" setter="" getter=""> + Indicates whether the application supports larger screen form-factors. + </member> + <member name="screen/support_normal" type="bool" setter="" getter=""> + Indicates whether an application supports the "normal" screen form-factors. + </member> + <member name="screen/support_small" type="bool" setter="" getter=""> + Indicates whether the application supports smaller screen form-factors. + </member> + <member name="screen/support_xlarge" type="bool" setter="" getter=""> + Indicates whether the application supports extra large screen form-factors. + </member> + <member name="user_data_backup/allow" type="bool" setter="" getter=""> + If [code]true[/code], allows the application to participate in the backup and restore infrastructure. + </member> + <member name="version/code" type="int" setter="" getter=""> + Machine-readable application version. + </member> + <member name="version/name" type="String" setter="" getter=""> + Application version visible to the user. + </member> + <member name="xr_features/hand_tracking" type="int" setter="" getter=""> + </member> + <member name="xr_features/hand_tracking_frequency" type="int" setter="" getter=""> + </member> + <member name="xr_features/passthrough" type="int" setter="" getter=""> + </member> + <member name="xr_features/xr_mode" type="int" setter="" getter=""> + </member> + </members> +</class> diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index f4c4e985fe..32b46271fd 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -1,39 +1,44 @@ -/*************************************************************************/ -/* export.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* export.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "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_types() { + GDREGISTER_VIRTUAL_CLASS(EditorExportPlatformAndroid); +} void register_android_exporter() { #ifndef ANDROID_ENABLED diff --git a/platform/android/export/export.h b/platform/android/export/export.h index 82ce40f95d..bd689a400d 100644 --- a/platform/android/export/export.h +++ b/platform/android/export/export.h @@ -1,36 +1,37 @@ -/*************************************************************************/ -/* export.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* export.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 ANDROID_EXPORT_H #define ANDROID_EXPORT_H +void register_android_exporter_types(); void register_android_exporter(); #endif // ANDROID_EXPORT_H diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp index 3bfdd3b881..6030239695 100644 --- a/platform/android/export/export_plugin.cpp +++ b/platform/android/export/export_plugin.cpp @@ -1,35 +1,37 @@ -/*************************************************************************/ -/* export_plugin.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* export_plugin.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "export_plugin.h" +#include "../logo_svg.gen.h" +#include "../run_icon_svg.gen.h" #include "gradle_export_util.h" #include "core/config/project_settings.h" @@ -43,10 +45,14 @@ #include "editor/editor_log.h" #include "editor/editor_node.h" #include "editor/editor_paths.h" +#include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "main/splash.gen.h" -#include "platform/android/logo.gen.h" -#include "platform/android/run_icon.gen.h" + +#include "modules/modules_enabled.gen.h" // For svg. +#ifdef MODULE_SVG_ENABLED +#include "modules/svg/image_loader_svg.h" +#endif #include <string.h> @@ -205,7 +211,7 @@ static const char *LEGACY_BUILD_SPLASH_IMAGE_EXPORT_PATH = "res/drawable-nodpi-v static const char *SPLASH_BG_COLOR_PATH = "res/drawable-nodpi/splash_bg_color.png"; static const char *LEGACY_BUILD_SPLASH_BG_COLOR_PATH = "res/drawable-nodpi-v4/splash_bg_color.png"; static const char *SPLASH_CONFIG_PATH = "res://android/build/res/drawable/splash_drawable.xml"; -static const char *GDNATIVE_LIBS_PATH = "res://android/build/libs/gdnativelibs.json"; +static const char *GDEXTENSION_LIBS_PATH = "res://android/build/libs/gdextensionlibs.json"; static const int icon_densities_count = 6; static const char *launcher_icon_option = PNAME("launcher_icons/main_192x192"); @@ -245,8 +251,9 @@ static const int EXPORT_FORMAT_AAB = 1; 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 = 32; // Should match the value in 'platform/android/java/app/config.gradle#targetSdk' +static const int OPENGL_MIN_SDK_VERSION = 21; // Should match the value in 'platform/android/java/app/config.gradle#minSdk' +static const int VULKAN_MIN_SDK_VERSION = 24; +static const int DEFAULT_TARGET_SDK_VERSION = 33; // Should match the value in 'platform/android/java/app/config.gradle#targetSdk' #ifndef ANDROID_ENABLED void EditorExportPlatformAndroid::_check_for_changes_poll_thread(void *ud) { @@ -431,6 +438,14 @@ String EditorExportPlatformAndroid::get_project_name(const String &p_name) const String EditorExportPlatformAndroid::get_package_name(const String &p_package) const { String pname = p_package; + String name = get_valid_basename(); + pname = pname.replace("$genname", name); + return pname; +} + +// Returns the project name without invalid characters +// or the "noname" string if all characters are invalid. +String EditorExportPlatformAndroid::get_valid_basename() const { String basename = GLOBAL_GET("application/config/name"); basename = basename.to_lower(); @@ -446,13 +461,12 @@ String EditorExportPlatformAndroid::get_package_name(const String &p_package) co first = false; } } + if (name.is_empty()) { name = "noname"; } - pname = pname.replace("$genname", name); - - return pname; + return name; } String EditorExportPlatformAndroid::get_assets_directory(const Ref<EditorExportPreset> &p_preset, int p_export_format) const { @@ -460,7 +474,7 @@ String EditorExportPlatformAndroid::get_assets_directory(const Ref<EditorExportP } bool EditorExportPlatformAndroid::is_package_name_valid(const String &p_package, String *r_error) const { - String pname = p_package; + String pname = get_package_name(p_package); if (pname.length() == 0) { if (r_error) { @@ -519,6 +533,24 @@ bool EditorExportPlatformAndroid::is_package_name_valid(const String &p_package, return false; } + if (p_package.find("$genname") >= 0 && !is_project_name_valid()) { + if (r_error) { + *r_error = TTR("The project name does not meet the requirement for the package name format. Please explicitly specify the package name."); + } + return false; + } + + return true; +} + +bool EditorExportPlatformAndroid::is_project_name_valid() const { + // Get the original project name and convert to lowercase. + String basename = GLOBAL_GET("application/config/name"); + basename = basename.to_lower(); + // Check if there are invalid characters. + if (basename != get_valid_basename()) { + return false; + } return true; } @@ -585,12 +617,13 @@ zip_fileinfo EditorExportPlatformAndroid::get_zip_fileinfo() { return zipfi; } -Vector<String> EditorExportPlatformAndroid::get_abis() { - Vector<String> abis; - abis.push_back("armeabi-v7a"); - abis.push_back("arm64-v8a"); - abis.push_back("x86"); - abis.push_back("x86_64"); +Vector<EditorExportPlatformAndroid::ABI> EditorExportPlatformAndroid::get_abis() { + // Should have the same order and size as get_archs. + Vector<ABI> abis; + abis.push_back(ABI("armeabi-v7a", "arm32")); + abis.push_back(ABI("arm64-v8a", "arm64")); + abis.push_back(ABI("x86", "x86_32")); + abis.push_back(ABI("x86_64", "x86_64")); return abis; } @@ -687,24 +720,28 @@ Error EditorExportPlatformAndroid::save_apk_so(void *p_userdata, const SharedObj return FAILED; } APKExportData *ed = static_cast<APKExportData *>(p_userdata); - Vector<String> abis = get_abis(); + Vector<ABI> abis = get_abis(); bool exported = false; for (int i = 0; i < p_so.tags.size(); ++i) { // shared objects can be fat (compatible with multiple ABIs) - int abi_index = abis.find(p_so.tags[i]); + int abi_index = -1; + for (int j = 0; j < abis.size(); ++j) { + if (abis[j].abi == p_so.tags[i] || abis[j].arch == p_so.tags[i]) { + abi_index = j; + break; + } + } if (abi_index != -1) { exported = true; - String abi = abis[abi_index]; + String abi = abis[abi_index].abi; String dst_path = String("lib").path_join(abi).path_join(p_so.path.get_file()); - Vector<uint8_t> array = FileAccess::get_file_as_array(p_so.path); + Vector<uint8_t> array = FileAccess::get_file_as_bytes(p_so.path); Error store_err = store_in_apk(ed, dst_path, array); ERR_FAIL_COND_V_MSG(store_err, store_err, "Cannot store in apk file '" + dst_path + "'."); } } if (!exported) { - String abis_string = String(" ").join(abis); - String err = "Cannot determine ABI for library \"" + p_so.path + "\". One of the supported ABIs must be used as a tag: " + abis_string; - ERR_PRINT(err); + ERR_PRINT("Cannot determine architecture for library \"" + p_so.path + "\". One of the supported architectures must be used as a tag: " + join_abis(abis, " ", true)); return FAILED; } return OK; @@ -725,19 +762,25 @@ Error EditorExportPlatformAndroid::ignore_apk_file(void *p_userdata, const Strin Error EditorExportPlatformAndroid::copy_gradle_so(void *p_userdata, const SharedObject &p_so) { ERR_FAIL_COND_V_MSG(!p_so.path.get_file().begins_with("lib"), FAILED, "Android .so file names must start with \"lib\", but got: " + p_so.path); - Vector<String> abis = get_abis(); + Vector<ABI> abis = get_abis(); CustomExportData *export_data = static_cast<CustomExportData *>(p_userdata); bool exported = false; for (int i = 0; i < p_so.tags.size(); ++i) { - int abi_index = abis.find(p_so.tags[i]); + int abi_index = -1; + for (int j = 0; j < abis.size(); ++j) { + if (abis[j].abi == p_so.tags[i] || abis[j].arch == p_so.tags[i]) { + abi_index = j; + break; + } + } if (abi_index != -1) { exported = true; String base = "res://android/build/libs"; String type = export_data->debug ? "debug" : "release"; - String abi = abis[abi_index]; + String abi = abis[abi_index].abi; String filename = p_so.path.get_file(); String dst_path = base.path_join(type).path_join(abi).path_join(filename); - Vector<uint8_t> data = FileAccess::get_file_as_array(p_so.path); + Vector<uint8_t> data = FileAccess::get_file_as_bytes(p_so.path); print_verbose("Copying .so file from " + p_so.path + " to " + dst_path); Error err = store_file_at_path(dst_path, data); ERR_FAIL_COND_V_MSG(err, err, "Failed to copy .so file from " + p_so.path + " to " + dst_path); @@ -745,7 +788,7 @@ Error EditorExportPlatformAndroid::copy_gradle_so(void *p_userdata, const Shared } } ERR_FAIL_COND_V_MSG(!exported, FAILED, - "Cannot determine ABI for library \"" + p_so.path + "\". One of the supported ABIs must be used as a tag: " + String(" ").join(abis)); + "Cannot determine architecture for library \"" + p_so.path + "\". One of the supported architectures must be used as a tag:" + join_abis(abis, " ", true)); return OK; } @@ -757,6 +800,12 @@ bool EditorExportPlatformAndroid::_has_manage_external_storage_permission(const return p_permissions.find("android.permission.MANAGE_EXTERNAL_STORAGE") != -1; } +bool EditorExportPlatformAndroid::_uses_vulkan() { + String current_renderer = GLOBAL_GET("rendering/renderer/rendering_method.mobile"); + bool uses_vulkan = (current_renderer == "forward_plus" || current_renderer == "mobile") && GLOBAL_GET("rendering/rendering_device/driver.android") == "vulkan"; + return uses_vulkan; +} + void EditorExportPlatformAndroid::_get_permissions(const Ref<EditorExportPreset> &p_preset, bool p_give_internet, Vector<String> &r_permissions) { const char **aperms = android_perms; while (*aperms) { @@ -791,7 +840,7 @@ void EditorExportPlatformAndroid::_get_permissions(const Ref<EditorExportPreset> } void EditorExportPlatformAndroid::_write_tmp_manifest(const Ref<EditorExportPreset> &p_preset, bool p_give_internet, bool p_debug) { - print_verbose("Building temporary manifest.."); + print_verbose("Building temporary manifest..."); String manifest_text = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" @@ -811,7 +860,7 @@ void EditorExportPlatformAndroid::_write_tmp_manifest(const Ref<EditorExportPres } } - manifest_text += _get_xr_features_tag(p_preset); + manifest_text += _get_xr_features_tag(p_preset, _uses_vulkan()); 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")); @@ -857,12 +906,8 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref<EditorExportPreset> &p bool screen_support_large = p_preset->get("screen/support_large"); bool screen_support_xlarge = p_preset->get("screen/support_xlarge"); - int xr_mode_index = p_preset->get("xr_features/xr_mode"); - int hand_tracking_index = p_preset->get("xr_features/hand_tracking"); - int hand_tracking_frequency_index = p_preset->get("xr_features/hand_tracking_frequency"); - bool backup_allowed = p_preset->get("user_data_backup/allow"); - bool classify_as_game = p_preset->get("package/classify_as_game"); + int app_category = p_preset->get("package/app_category"); bool retain_data_on_uninstall = p_preset->get("package/retain_data_on_uninstall"); bool exclude_from_recents = p_preset->get("package/exclude_from_recents"); bool is_resizeable = bool(GLOBAL_GET("display/window/size/resizable")); @@ -961,8 +1006,12 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref<EditorExportPreset> &p encode_uint32(backup_allowed, &p_manifest.write[iofs + 16]); } + if (tname == "application" && attrname == "appCategory") { + encode_uint32(_get_app_category_value(app_category), &p_manifest.write[iofs + 16]); + } + if (tname == "application" && attrname == "isGame") { - encode_uint32(classify_as_game, &p_manifest.write[iofs + 16]); + encode_uint32(app_category == APP_CATEGORY_GAME, &p_manifest.write[iofs + 16]); } if (tname == "application" && attrname == "hasFragileUserData") { @@ -981,6 +1030,10 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref<EditorExportPreset> &p encode_uint32(is_resizeable, &p_manifest.write[iofs + 16]); } + if (tname == "provider" && attrname == "authorities") { + string_table.write[attr_value] = get_package_name(package_name) + String(".fileprovider"); + } + if (tname == "supports-screens") { if (attrname == "smallScreens") { encode_uint32(screen_support_small ? 0xFFFFFFFF : 0, &p_manifest.write[iofs + 16]); @@ -996,25 +1049,6 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref<EditorExportPreset> &p } } - // Hand tracking related configurations - if (xr_mode_index == XR_MODE_OPENXR && hand_tracking_index > XR_HAND_TRACKING_NONE) { - if (tname == "meta-data" && attrname == "name" && value == "xr_hand_tracking_metadata_name") { - string_table.write[attr_value] = "com.oculus.handtracking.frequency"; - } - - if (tname == "meta-data" && attrname == "value" && value == "xr_hand_tracking_metadata_value") { - string_table.write[attr_value] = (hand_tracking_frequency_index == XR_HAND_TRACKING_FREQUENCY_LOW ? "LOW" : "HIGH"); - } - - if (tname == "meta-data" && attrname == "name" && value == "xr_hand_tracking_version_name") { - string_table.write[attr_value] = "com.oculus.handtracking.version"; - } - - if (tname == "meta-data" && attrname == "name" && value == "xr_hand_tracking_version_value") { - string_table.write[attr_value] = "V2.0"; - } - } - iofs += 20; } @@ -1029,26 +1063,16 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref<EditorExportPreset> &p Vector<bool> feature_required_list; Vector<int> feature_versions; - if (xr_mode_index == XR_MODE_OPENXR) { - // Set degrees of freedom - feature_names.push_back("android.hardware.vr.headtracking"); - feature_required_list.push_back(true); + if (_uses_vulkan()) { + // Require vulkan hardware level 1 support + feature_names.push_back("android.hardware.vulkan.level"); + feature_required_list.push_back(false); feature_versions.push_back(1); - // Check for hand tracking - if (hand_tracking_index > XR_HAND_TRACKING_NONE) { - feature_names.push_back("oculus.software.handtracking"); - feature_required_list.push_back(hand_tracking_index == XR_HAND_TRACKING_REQUIRED); - feature_versions.push_back(-1); // no version attribute should be added. - } - - // Check for passthrough - int passthrough_mode = p_preset->get("xr_features/passthrough"); - if (passthrough_mode > XR_PASSTHROUGH_NONE) { - feature_names.push_back("com.oculus.feature.PASSTHROUGH"); - feature_required_list.push_back(passthrough_mode == XR_PASSTHROUGH_REQUIRED); - feature_versions.push_back(-1); - } + // Require vulkan version 1.0 + feature_names.push_back("android.hardware.vulkan.version"); + feature_required_list.push_back(true); + feature_versions.push_back(0x400003); // Encoded value for api version 1.0 } if (feature_names.size() > 0) { @@ -1656,11 +1680,11 @@ void EditorExportPlatformAndroid::_copy_icons_to_gradle_project(const Ref<Editor } } -Vector<String> EditorExportPlatformAndroid::get_enabled_abis(const Ref<EditorExportPreset> &p_preset) { - Vector<String> abis = get_abis(); - Vector<String> enabled_abis; +Vector<EditorExportPlatformAndroid::ABI> EditorExportPlatformAndroid::get_enabled_abis(const Ref<EditorExportPreset> &p_preset) { + Vector<ABI> abis = get_abis(); + Vector<ABI> enabled_abis; for (int i = 0; i < abis.size(); ++i) { - bool is_enabled = p_preset->get("architectures/" + abis[i]); + bool is_enabled = p_preset->get("architectures/" + abis[i].abi); if (is_enabled) { enabled_abis.push_back(abis[i]); } @@ -1670,23 +1694,118 @@ Vector<String> EditorExportPlatformAndroid::get_enabled_abis(const Ref<EditorExp void EditorExportPlatformAndroid::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const { r_features->push_back("etc2"); + r_features->push_back("astc"); - Vector<String> abis = get_enabled_abis(p_preset); + Vector<ABI> abis = get_enabled_abis(p_preset); for (int i = 0; i < abis.size(); ++i) { - r_features->push_back(abis[i]); + r_features->push_back(abis[i].arch); + r_features->push_back(abis[i].abi); + } +} + +String EditorExportPlatformAndroid::get_export_option_warning(const EditorExportPreset *p_preset, const StringName &p_name) const { + if (p_preset) { + if (p_name == ("apk_expansion/public_key")) { + bool apk_expansion = p_preset->get("apk_expansion/enable"); + String apk_expansion_pkey = p_preset->get("apk_expansion/public_key"); + if (apk_expansion && apk_expansion_pkey.is_empty()) { + return TTR("Invalid public key for APK expansion."); + } + } else if (p_name == "package/unique_name") { + String pn = p_preset->get("package/unique_name"); + String pn_err; + + if (!is_package_name_valid(pn, &pn_err)) { + return TTR("Invalid package name:") + " " + pn_err; + } + } else if (p_name == "gradle_build/use_gradle_build") { + bool gradle_build_enabled = p_preset->get("gradle_build/use_gradle_build"); + String enabled_plugins_names = PluginConfigAndroid::get_plugins_names(get_enabled_plugins(Ref<EditorExportPreset>(p_preset))); + if (!enabled_plugins_names.is_empty() && !gradle_build_enabled) { + return TTR("\"Use Gradle Build\" must be enabled to use the plugins."); + } + } else if (p_name == "xr_features/xr_mode") { + bool gradle_build_enabled = p_preset->get("gradle_build/use_gradle_build"); + int xr_mode_index = p_preset->get("xr_features/xr_mode"); + if (xr_mode_index == XR_MODE_OPENXR && !gradle_build_enabled) { + return TTR("OpenXR requires \"Use Gradle Build\" to be enabled"); + } + } else if (p_name == "xr_features/hand_tracking") { + int xr_mode_index = p_preset->get("xr_features/xr_mode"); + int hand_tracking = p_preset->get("xr_features/hand_tracking"); + if (xr_mode_index != XR_MODE_OPENXR) { + if (hand_tracking > XR_HAND_TRACKING_NONE) { + return TTR("\"Hand Tracking\" is only valid when \"XR Mode\" is \"OpenXR\"."); + } + } + } else if (p_name == "xr_features/passthrough") { + int xr_mode_index = p_preset->get("xr_features/xr_mode"); + int passthrough_mode = p_preset->get("xr_features/passthrough"); + if (xr_mode_index != XR_MODE_OPENXR) { + if (passthrough_mode > XR_PASSTHROUGH_NONE) { + return TTR("\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."); + } + } + } else if (p_name == "gradle_build/export_format") { + bool gradle_build_enabled = p_preset->get("gradle_build/use_gradle_build"); + if (int(p_preset->get("gradle_build/export_format")) == EXPORT_FORMAT_AAB && !gradle_build_enabled) { + return TTR("\"Export AAB\" is only valid when \"Use Gradle Build\" is enabled."); + } + } else if (p_name == "gradle_build/min_sdk") { + String min_sdk_str = p_preset->get("gradle_build/min_sdk"); + int min_sdk_int = VULKAN_MIN_SDK_VERSION; + bool gradle_build_enabled = p_preset->get("gradle_build/use_gradle_build"); + if (!min_sdk_str.is_empty()) { // Empty means no override, nothing to do. + if (!gradle_build_enabled) { + return TTR("\"Min SDK\" can only be overridden when \"Use Gradle Build\" is enabled."); + } + if (!min_sdk_str.is_valid_int()) { + return vformat(TTR("\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."), min_sdk_str); + } else { + min_sdk_int = min_sdk_str.to_int(); + if (min_sdk_int < OPENGL_MIN_SDK_VERSION) { + return vformat(TTR("\"Min SDK\" cannot be lower than %d, which is the version needed by the Godot library."), OPENGL_MIN_SDK_VERSION); + } + } + } + } else if (p_name == "gradle_build/target_sdk") { + String target_sdk_str = p_preset->get("gradle_build/target_sdk"); + int target_sdk_int = DEFAULT_TARGET_SDK_VERSION; + + String min_sdk_str = p_preset->get("gradle_build/min_sdk"); + int min_sdk_int = VULKAN_MIN_SDK_VERSION; + if (min_sdk_str.is_valid_int()) { + min_sdk_int = min_sdk_str.to_int(); + } + bool gradle_build_enabled = p_preset->get("gradle_build/use_gradle_build"); + if (!target_sdk_str.is_empty()) { // Empty means no override, nothing to do. + if (!gradle_build_enabled) { + return TTR("\"Target SDK\" can only be overridden when \"Use Gradle Build\" is enabled."); + } + if (!target_sdk_str.is_valid_int()) { + return vformat(TTR("\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."), target_sdk_str); + } else { + target_sdk_int = target_sdk_str.to_int(); + if (target_sdk_int < min_sdk_int) { + return TTR("\"Target SDK\" version must be greater or equal to \"Min SDK\" version."); + } + } + } + } } + return String(); } -void EditorExportPlatformAndroid::get_export_options(List<ExportOption> *r_options) { +void EditorExportPlatformAndroid::get_export_options(List<ExportOption> *r_options) const { 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_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)); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "gradle_build/use_gradle_build"), false, false, true)); + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "gradle_build/export_format", PROPERTY_HINT_ENUM, "Export APK,Export AAB"), EXPORT_FORMAT_APK, false, true)); // 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)), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "gradle_build/min_sdk", PROPERTY_HINT_PLACEHOLDER_TEXT, vformat("%d (default)", VULKAN_MIN_SDK_VERSION)), "", false, true)); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "gradle_build/target_sdk", PROPERTY_HINT_PLACEHOLDER_TEXT, vformat("%d (default)", DEFAULT_TARGET_SDK_VERSION)), "", false, true)); Vector<PluginConfigAndroid> plugins_configs = get_plugins(); for (int i = 0; i < plugins_configs.size(); i++) { @@ -1697,29 +1816,29 @@ void EditorExportPlatformAndroid::get_export_options(List<ExportOption> *r_optio // Android supports multiple architectures in an app bundle, so // we expose each option as a checkbox in the export dialog. - const Vector<String> abis = get_abis(); + const Vector<ABI> abis = get_abis(); for (int i = 0; i < abis.size(); ++i) { - const String abi = abis[i]; + const String abi = abis[i].abi; // All Android devices supporting Vulkan run 64-bit Android, // so there is usually no point in exporting for 32-bit Android. const bool is_default = abi == "arm64-v8a"; r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, vformat("%s/%s", PNAME("architectures"), abi)), is_default)); } - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/debug", PROPERTY_HINT_GLOBAL_FILE, "*.keystore,*.jks"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/debug_user"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/debug_password"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/release", PROPERTY_HINT_GLOBAL_FILE, "*.keystore,*.jks"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/release_user"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/release_password"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/debug", PROPERTY_HINT_GLOBAL_FILE, "*.keystore,*.jks", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/debug_user", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/debug_password", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/release", PROPERTY_HINT_GLOBAL_FILE, "*.keystore,*.jks", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/release_user", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/release_password", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), "")); 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::STRING, "package/unique_name", PROPERTY_HINT_PLACEHOLDER_TEXT, "ext.domain.name"), "org.godotengine.$genname")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/unique_name", PROPERTY_HINT_PLACEHOLDER_TEXT, "ext.domain.name"), "org.godotengine.$genname", false, true)); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Game Name [default if blank]"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "package/signed"), true)); - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "package/classify_as_game"), true)); + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "package/app_category", PROPERTY_HINT_ENUM, "Accessibility,Audio,Game,Image,Maps,News,Productivity,Social,Video"), APP_CATEGORY_GAME)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "package/retain_data_on_uninstall"), false)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "package/exclude_from_recents"), false)); @@ -1729,10 +1848,10 @@ void EditorExportPlatformAndroid::get_export_options(List<ExportOption> *r_optio r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "graphics/opengl_debug"), false)); - r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "xr_features/xr_mode", PROPERTY_HINT_ENUM, "Regular,OpenXR"), XR_MODE_REGULAR)); - r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "xr_features/hand_tracking", PROPERTY_HINT_ENUM, "None,Optional,Required"), XR_HAND_TRACKING_NONE)); + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "xr_features/xr_mode", PROPERTY_HINT_ENUM, "Regular,OpenXR"), XR_MODE_REGULAR, false, true)); + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "xr_features/hand_tracking", PROPERTY_HINT_ENUM, "None,Optional,Required"), XR_HAND_TRACKING_NONE, false, true)); r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "xr_features/hand_tracking_frequency", PROPERTY_HINT_ENUM, "Low,High"), XR_HAND_TRACKING_FREQUENCY_LOW)); - r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "xr_features/passthrough", PROPERTY_HINT_ENUM, "None,Optional,Required"), XR_PASSTHROUGH_NONE)); + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "xr_features/passthrough", PROPERTY_HINT_ENUM, "None,Optional,Required"), XR_PASSTHROUGH_NONE, false, true)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/immersive_mode"), true)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/support_small"), true)); @@ -1744,9 +1863,9 @@ void EditorExportPlatformAndroid::get_export_options(List<ExportOption> *r_optio r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "command_line/extra_args"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "apk_expansion/enable"), false)); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "apk_expansion/enable"), false, false, true)); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "apk_expansion/SALT"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "apk_expansion/public_key", PROPERTY_HINT_MULTILINE_TEXT), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "apk_expansion/public_key", PROPERTY_HINT_MULTILINE_TEXT), "", false, true)); r_options->push_back(ExportOption(PropertyInfo(Variant::PACKED_STRING_ARRAY, "permissions/custom_permissions"), PackedStringArray())); @@ -1999,7 +2118,10 @@ String EditorExportPlatformAndroid::get_adb_path() { return sdk_path.path_join("platform-tools/adb" + exe_ext); } -String EditorExportPlatformAndroid::get_apksigner_path() { +String EditorExportPlatformAndroid::get_apksigner_path(int p_target_sdk, bool p_check_executes) { + if (p_target_sdk == -1) { + p_target_sdk = DEFAULT_TARGET_SDK_VERSION; + } String exe_ext = ""; if (OS::get_singleton()->get_name() == "Windows") { exe_ext = ".bat"; @@ -2017,23 +2139,89 @@ String EditorExportPlatformAndroid::get_apksigner_path() { } // There are additional versions directories we need to go through. - da->list_dir_begin(); - String sub_dir = da->get_next(); - while (!sub_dir.is_empty()) { - if (!sub_dir.begins_with(".") && da->current_is_dir()) { - // Check if the tool is here. - String tool_path = build_tools_dir.path_join(sub_dir).path_join(apksigner_command_name); - if (FileAccess::exists(tool_path)) { - apksigner_path = tool_path; - break; + Vector<String> dir_list = da->get_directories(); + + // We need to use the version of build_tools that matches the Target SDK + // If somehow we can't find that, we see if a version between 28 and the default target SDK exists. + // We need to avoid versions <= 27 because they fail on Java versions >9 + // If we can't find that, we just use the first valid version. + Vector<String> ideal_versions; + Vector<String> other_versions; + Vector<String> versions; + bool found_target_sdk = false; + // We only allow for versions <= 27 if specifically set + int min_version = p_target_sdk <= 27 ? p_target_sdk : 28; + for (String sub_dir : dir_list) { + if (!sub_dir.begins_with(".")) { + Vector<String> ver_numbers = sub_dir.split("."); + // Dir not a version number, will use as last resort + if (!ver_numbers.size() || !ver_numbers[0].is_valid_int()) { + other_versions.push_back(sub_dir); + continue; + } + int ver_number = ver_numbers[0].to_int(); + if (ver_number == p_target_sdk) { + found_target_sdk = true; + //ensure this is in front of the ones we check + versions.push_back(sub_dir); + } else { + if (ver_number >= min_version && ver_number <= DEFAULT_TARGET_SDK_VERSION) { + ideal_versions.push_back(sub_dir); + } else { + other_versions.push_back(sub_dir); + } } } - sub_dir = da->get_next(); } - da->list_dir_end(); + // we will check ideal versions first, then other versions. + versions.append_array(ideal_versions); + versions.append_array(other_versions); - if (apksigner_path.is_empty()) { + if (!versions.size()) { print_error("Unable to find the 'apksigner' tool."); + return apksigner_path; + } + + int i; + bool failed = false; + String version_to_use; + + List<String> args; + args.push_back("--version"); + String output; + int retval; + Error err; + for (i = 0; i < versions.size(); i++) { + // Check if the tool is here. + apksigner_path = build_tools_dir.path_join(versions[i]).path_join(apksigner_command_name); + if (FileAccess::exists(apksigner_path)) { + version_to_use = versions[i]; + // If we aren't exporting, just break here. + if (!p_check_executes) { + break; + } + // we only check to see if it executes on export because it is slow to load + err = OS::get_singleton()->execute(apksigner_path, args, &output, &retval, false); + if (err || retval) { + failed = true; + } else { + break; + } + } + } + if (i == versions.size()) { + if (failed) { + print_error("All located 'apksigner' tools in " + build_tools_dir + " failed to execute"); + return "<FAILED>"; + } else { + print_error("Unable to find the 'apksigner' tool."); + return ""; + } + } + if (!found_target_sdk) { + print_line("Could not find version of build tools that matches Target SDK, using " + version_to_use); + } else if (failed && found_target_sdk) { + print_line("Version of build tools that matches Target SDK failed to execute, using " + version_to_use); } return apksigner_path; @@ -2042,11 +2230,11 @@ String EditorExportPlatformAndroid::get_apksigner_path() { bool EditorExportPlatformAndroid::has_valid_export_configuration(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_build/use_custom_build"); + const bool gradle_build_enabled = p_preset->get("gradle_build/use_gradle_build"); // Look for export templates (first official, and if defined custom templates). - if (!custom_build_enabled) { + if (!gradle_build_enabled) { String template_err; bool dvalid = false; bool rvalid = false; @@ -2089,9 +2277,9 @@ bool EditorExportPlatformAndroid::has_valid_export_configuration(const Ref<Edito // Validate the rest of the export configuration. - String dk = p_preset->get("keystore/debug"); - String dk_user = p_preset->get("keystore/debug_user"); - String dk_password = p_preset->get("keystore/debug_password"); + String dk = p_preset->get_or_env("keystore/debug", ENV_ANDROID_KEYSTORE_DEBUG_PATH); + String dk_user = p_preset->get_or_env("keystore/debug_user", ENV_ANDROID_KEYSTORE_DEBUG_USER); + String dk_password = p_preset->get_or_env("keystore/debug_password", ENV_ANDROID_KEYSTORE_DEBUG_PASS); if ((dk.is_empty() || dk_user.is_empty() || dk_password.is_empty()) && (!dk.is_empty() || !dk_user.is_empty() || !dk_password.is_empty())) { valid = false; @@ -2106,9 +2294,9 @@ bool EditorExportPlatformAndroid::has_valid_export_configuration(const Ref<Edito } } - String rk = p_preset->get("keystore/release"); - String rk_user = p_preset->get("keystore/release_user"); - String rk_password = p_preset->get("keystore/release_password"); + String rk = p_preset->get_or_env("keystore/release", ENV_ANDROID_KEYSTORE_RELEASE_PATH); + String rk_user = p_preset->get_or_env("keystore/release_user", ENV_ANDROID_KEYSTORE_RELEASE_USER); + String rk_password = p_preset->get_or_env("keystore/release_password", ENV_ANDROID_KEYSTORE_RELEASE_PASS); if ((rk.is_empty() || rk_user.is_empty() || rk_password.is_empty()) && (!rk.is_empty() || !rk_user.is_empty() || !rk_password.is_empty())) { valid = false; @@ -2153,8 +2341,12 @@ bool EditorExportPlatformAndroid::has_valid_export_configuration(const Ref<Edito valid = false; } + String target_sdk_version = p_preset->get("gradle_build/target_sdk"); + if (!target_sdk_version.is_valid_int()) { + target_sdk_version = itos(DEFAULT_TARGET_SDK_VERSION); + } // Validate that apksigner is available - String apksigner_path = get_apksigner_path(); + String apksigner_path = get_apksigner_path(target_sdk_version.to_int()); if (!FileAccess::exists(apksigner_path)) { err += TTR("Unable to find Android SDK build-tools' apksigner command."); err += TTR("Please check in the Android SDK directory specified in Editor Settings."); @@ -2173,105 +2365,39 @@ bool EditorExportPlatformAndroid::has_valid_export_configuration(const Ref<Edito bool EditorExportPlatformAndroid::has_valid_project_configuration(const Ref<EditorExportPreset> &p_preset, String &r_error) const { String err; bool valid = true; - const bool custom_build_enabled = p_preset->get("custom_build/use_custom_build"); - - // Validate the project configuration. - bool apk_expansion = p_preset->get("apk_expansion/enable"); - - if (apk_expansion) { - String apk_expansion_pkey = p_preset->get("apk_expansion/public_key"); - - if (apk_expansion_pkey.is_empty()) { - valid = false; - err += TTR("Invalid public key for APK expansion.") + "\n"; + List<ExportOption> options; + get_export_options(&options); + for (const EditorExportPlatform::ExportOption &E : options) { + if (get_export_option_visibility(p_preset.ptr(), E.option.name)) { + String warn = get_export_option_warning(p_preset.ptr(), E.option.name); + if (!warn.is_empty()) { + err += warn + "\n"; + if (E.required) { + valid = false; + } + } } } - String pn = p_preset->get("package/unique_name"); - String pn_err; - - if (!is_package_name_valid(get_package_name(pn), &pn_err)) { - valid = false; - err += TTR("Invalid package name:") + " " + pn_err + "\n"; - } - String etc_error = test_etc2(); if (!etc_error.is_empty()) { valid = false; err += etc_error; } - // Ensure that `Use Custom Build` is enabled if a plugin is selected. - String enabled_plugins_names = PluginConfigAndroid::get_plugins_names(get_enabled_plugins(p_preset)); - if (!enabled_plugins_names.is_empty() && !custom_build_enabled) { - valid = false; - err += TTR("\"Use Custom Build\" must be enabled to use the plugins."); - err += "\n"; - } - - // Validate the Xr features are properly populated - int xr_mode_index = p_preset->get("xr_features/xr_mode"); - int hand_tracking = p_preset->get("xr_features/hand_tracking"); - int passthrough_mode = p_preset->get("xr_features/passthrough"); - 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 += "\n"; - } - - if (passthrough_mode > XR_PASSTHROUGH_NONE) { - valid = false; - err += TTR("\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."); - err += "\n"; - } - } - - 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. - String min_sdk_str = p_preset->get("custom_build/min_sdk"); - int min_sdk_int = DEFAULT_MIN_SDK_VERSION; + String min_sdk_str = p_preset->get("gradle_build/min_sdk"); + int min_sdk_int = VULKAN_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 { + if (min_sdk_str.is_valid_int()) { 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. - String target_sdk_str = p_preset->get("custom_build/target_sdk"); + String target_sdk_str = p_preset->get("gradle_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 { + if (target_sdk_str.is_valid_int()) { target_sdk_int = target_sdk_str.to_int(); if (target_sdk_int > DEFAULT_TARGET_SDK_VERSION) { // Warning only, so don't override `valid`. @@ -2281,9 +2407,16 @@ bool EditorExportPlatformAndroid::has_valid_project_configuration(const Ref<Edit } } - if (target_sdk_int < min_sdk_int) { - valid = false; - err += TTR("\"Target SDK\" version must be greater or equal to \"Min SDK\" version."); + String current_renderer = GLOBAL_GET("rendering/renderer/rendering_method.mobile"); + if (current_renderer == "forward_plus") { + // Warning only, so don't override `valid`. + err += vformat(TTR("The \"%s\" renderer is designed for Desktop devices, and is not suitable for Android devices."), current_renderer); + err += "\n"; + } + + if (_uses_vulkan() && min_sdk_int < VULKAN_MIN_SDK_VERSION) { + // Warning only, so don't override `valid`. + err += vformat(TTR("\"Min SDK\" should be greater or equal to %d for the \"%s\" renderer."), VULKAN_MIN_SDK_VERSION, current_renderer); err += "\n"; } @@ -2372,14 +2505,21 @@ 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_build/export_format")); + int export_format = int(p_preset->get("gradle_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"); - String release_password = p_preset->get("keystore/release_password"); - - String apksigner = get_apksigner_path(); + String release_keystore = p_preset->get_or_env("keystore/release", ENV_ANDROID_KEYSTORE_RELEASE_PATH); + String release_username = p_preset->get_or_env("keystore/release_user", ENV_ANDROID_KEYSTORE_RELEASE_USER); + String release_password = p_preset->get_or_env("keystore/release_password", ENV_ANDROID_KEYSTORE_RELEASE_PASS); + String target_sdk_version = p_preset->get("gradle_build/target_sdk"); + if (!target_sdk_version.is_valid_int()) { + target_sdk_version = itos(DEFAULT_TARGET_SDK_VERSION); + } + String apksigner = get_apksigner_path(target_sdk_version.to_int(), true); print_verbose("Starting signing of the " + export_label + " binary using " + apksigner); + if (apksigner == "<FAILED>") { + add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), vformat(TTR("All 'apksigner' tools located in Android SDK 'build-tools' directory failed to execute. Please check that you have the correct version installed for your target sdk version. The resulting %s is unsigned."), export_label)); + return OK; + } if (!FileAccess::exists(apksigner)) { add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), vformat(TTR("'apksigner' could not be found. Please check that the command is available in the Android SDK build-tools directory. The resulting %s is unsigned."), export_label)); return OK; @@ -2389,9 +2529,9 @@ Error EditorExportPlatformAndroid::sign_apk(const Ref<EditorExportPreset> &p_pre String password; String user; if (p_debug) { - keystore = p_preset->get("keystore/debug"); - password = p_preset->get("keystore/debug_password"); - user = p_preset->get("keystore/debug_user"); + keystore = p_preset->get_or_env("keystore/debug", ENV_ANDROID_KEYSTORE_DEBUG_PATH); + password = p_preset->get_or_env("keystore/debug_password", ENV_ANDROID_KEYSTORE_DEBUG_PASS); + user = p_preset->get_or_env("keystore/debug_user", ENV_ANDROID_KEYSTORE_DEBUG_USER); if (keystore.is_empty()) { keystore = EDITOR_GET("export/android/debug_keystore"); @@ -2402,7 +2542,6 @@ Error EditorExportPlatformAndroid::sign_apk(const Ref<EditorExportPreset> &p_pre if (ep.step(vformat(TTR("Signing debug %s..."), export_label), 104)) { return ERR_SKIP; } - } else { keystore = release_keystore; password = release_password; @@ -2429,20 +2568,27 @@ Error EditorExportPlatformAndroid::sign_apk(const Ref<EditorExportPreset> &p_pre args.push_back("--ks-key-alias"); args.push_back(user); args.push_back(export_path); - if (p_debug) { - // We only print verbose logs for debug builds to avoid leaking release keystore credentials. + if (OS::get_singleton()->is_stdout_verbose() && p_debug) { + // We only print verbose logs with credentials for debug builds to avoid leaking release keystore credentials. print_verbose("Signing debug binary using: " + String("\n") + apksigner + " " + join_list(args, String(" "))); + } else { + List<String> redacted_args = List<String>(args); + redacted_args.find(keystore)->set("<REDACTED>"); + redacted_args.find("pass:" + password)->set("pass:<REDACTED>"); + redacted_args.find(user)->set("<REDACTED>"); + print_line("Signing binary using: " + String("\n") + apksigner + " " + join_list(redacted_args, String(" "))); } int retval; - output.clear(); Error err = OS::get_singleton()->execute(apksigner, args, &output, &retval, true); if (err != OK) { add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), TTR("Could not start apksigner executable.")); return err; } - print_verbose(output); + // By design, apksigner does not output credentials in its output unless --verbose is used + print_line(output); if (retval) { add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), vformat(TTR("'apksigner' returned with error #%d"), retval)); + add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), vformat(TTR("output: \n%s"), output)); return ERR_CANT_CREATE; } @@ -2467,6 +2613,7 @@ Error EditorExportPlatformAndroid::sign_apk(const Ref<EditorExportPreset> &p_pre print_verbose(output); if (retval) { add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), vformat(TTR("'apksigner' verification of %s failed."), export_label)); + add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), vformat(TTR("output: \n%s"), output)); return ERR_CANT_CREATE; } @@ -2479,7 +2626,7 @@ void EditorExportPlatformAndroid::_clear_assets_directory() { // Clear the APK assets directory if (da_res->dir_exists(APK_ASSETS_DIRECTORY)) { - print_verbose("Clearing APK assets directory.."); + print_verbose("Clearing APK assets directory..."); Ref<DirAccess> da_assets = DirAccess::open(APK_ASSETS_DIRECTORY); da_assets->erase_contents_recursive(); da_res->remove(APK_ASSETS_DIRECTORY); @@ -2487,7 +2634,7 @@ void EditorExportPlatformAndroid::_clear_assets_directory() { // Clear the AAB assets directory if (da_res->dir_exists(AAB_ASSETS_DIRECTORY)) { - print_verbose("Clearing AAB assets directory.."); + print_verbose("Clearing AAB assets directory..."); Ref<DirAccess> da_assets = DirAccess::open(AAB_ASSETS_DIRECTORY); da_assets->erase_contents_recursive(); da_res->remove(AAB_ASSETS_DIRECTORY); @@ -2497,7 +2644,7 @@ void EditorExportPlatformAndroid::_clear_assets_directory() { void EditorExportPlatformAndroid::_remove_copied_libs() { print_verbose("Removing previously installed libraries..."); Error error; - String libs_json = FileAccess::get_file_as_string(GDNATIVE_LIBS_PATH, &error); + String libs_json = FileAccess::get_file_as_string(GDEXTENSION_LIBS_PATH, &error); if (error || libs_json.is_empty()) { print_verbose("No previously installed libraries found"); return; @@ -2513,22 +2660,33 @@ void EditorExportPlatformAndroid::_remove_copied_libs() { print_verbose("Removing previously installed library " + libs[i]); da->remove(libs[i]); } - da->remove(GDNATIVE_LIBS_PATH); + da->remove(GDEXTENSION_LIBS_PATH); } -String EditorExportPlatformAndroid::join_list(List<String> parts, const String &separator) const { +String EditorExportPlatformAndroid::join_list(const List<String> &p_parts, const String &p_separator) { String ret; - for (int i = 0; i < parts.size(); ++i) { + for (int i = 0; i < p_parts.size(); ++i) { if (i > 0) { - ret += separator; + ret += p_separator; } - ret += parts[i]; + ret += p_parts[i]; + } + return ret; +} + +String EditorExportPlatformAndroid::join_abis(const Vector<EditorExportPlatformAndroid::ABI> &p_parts, const String &p_separator, bool p_use_arch) { + String ret; + for (int i = 0; i < p_parts.size(); ++i) { + if (i > 0) { + ret += p_separator; + } + ret += (p_use_arch) ? p_parts[i].arch : p_parts[i].abi; } return ret; } 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_build/export_format")); + int export_format = int(p_preset->get("gradle_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); } @@ -2541,19 +2699,19 @@ 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_build/use_custom_build")); + bool use_gradle_build = bool(p_preset->get("gradle_build/use_gradle_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); + Vector<ABI> enabled_abis = get_enabled_abis(p_preset); print_verbose("Exporting for Android..."); print_verbose("- debug build: " + bool_to_string(p_debug)); print_verbose("- export path: " + p_path); print_verbose("- export format: " + itos(export_format)); print_verbose("- sign build: " + bool_to_string(should_sign)); - print_verbose("- custom build enabled: " + bool_to_string(use_custom_build)); + print_verbose("- gradle build enabled: " + bool_to_string(use_gradle_build)); print_verbose("- apk expansion enabled: " + bool_to_string(apk_expansion)); - print_verbose("- enabled abis: " + String(",").join(enabled_abis)); + print_verbose("- enabled abis: " + join_abis(enabled_abis, ",", false)); print_verbose("- export filter: " + itos(p_preset->get_export_filter())); print_verbose("- include filter: " + p_preset->get_include_filter()); print_verbose("- exclude filter: " + p_preset->get_exclude_filter()); @@ -2591,14 +2749,14 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP return ERR_UNCONFIGURED; } - if (use_custom_build) { - print_verbose("Starting custom build.."); + if (use_gradle_build) { + print_verbose("Starting gradle build..."); //test that installed build version is alright { - print_verbose("Checking build version.."); + print_verbose("Checking build version..."); Ref<FileAccess> f = FileAccess::open("res://android/.build_version", FileAccess::READ); if (f.is_null()) { - add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), TTR("Trying to build from a custom built template, but no version info for it exists. Please reinstall from the 'Project' menu.")); + add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), TTR("Trying to build from a gradle built template, but no version info for it exists. Please reinstall from the 'Project' menu.")); return ERR_UNCONFIGURED; } String version = f->get_line().strip_edges(); @@ -2628,28 +2786,32 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP _clear_assets_directory(); _remove_copied_libs(); if (!apk_expansion) { - print_verbose("Exporting project files.."); + print_verbose("Exporting project files..."); CustomExportData user_data; user_data.assets_directory = assets_directory; user_data.debug = p_debug; - err = export_project_files(p_preset, p_debug, rename_and_store_file_in_gradle_project, &user_data, copy_gradle_so); + if (p_flags & DEBUG_FLAG_DUMB_CLIENT) { + err = export_project_files(p_preset, p_debug, ignore_apk_file, &user_data, copy_gradle_so); + } else { + err = export_project_files(p_preset, p_debug, rename_and_store_file_in_gradle_project, &user_data, copy_gradle_so); + } if (err != OK) { add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), TTR("Could not export project files to gradle project.")); return err; } if (user_data.libs.size() > 0) { - Ref<FileAccess> fa = FileAccess::open(GDNATIVE_LIBS_PATH, FileAccess::WRITE); + Ref<FileAccess> fa = FileAccess::open(GDEXTENSION_LIBS_PATH, FileAccess::WRITE); fa->store_string(JSON::stringify(user_data.libs, "\t")); } } else { - print_verbose("Saving apk expansion file.."); + print_verbose("Saving apk expansion file..."); err = save_apk_expansion_file(p_preset, p_debug, p_path); if (err != OK) { add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), TTR("Could not write expansion package file!")); return err; } } - print_verbose("Storing command line flags.."); + print_verbose("Storing command line flags..."); store_file_at_path(assets_directory + "/_cl_", command_line_flags); print_verbose("Updating ANDROID_HOME environment to " + sdk_path); @@ -2668,15 +2830,15 @@ 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 = p_preset->get("custom_build/min_sdk"); + String min_sdk_version = p_preset->get("gradle_build/min_sdk"); if (!min_sdk_version.is_valid_int()) { - min_sdk_version = itos(DEFAULT_MIN_SDK_VERSION); + min_sdk_version = itos(VULKAN_MIN_SDK_VERSION); } - String target_sdk_version = p_preset->get("custom_build/target_sdk"); + String target_sdk_version = p_preset->get("gradle_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 enabled_abi_string = join_abis(enabled_abis, "|", false); String sign_flag = should_sign ? "true" : "false"; String zipalign_flag = "true"; @@ -2723,9 +2885,9 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP if (should_sign) { if (p_debug) { - String debug_keystore = p_preset->get("keystore/debug"); - String debug_password = p_preset->get("keystore/debug_password"); - String debug_user = p_preset->get("keystore/debug_user"); + String debug_keystore = p_preset->get_or_env("keystore/debug", ENV_ANDROID_KEYSTORE_DEBUG_PATH); + String debug_password = p_preset->get_or_env("keystore/debug_password", ENV_ANDROID_KEYSTORE_DEBUG_PASS); + String debug_user = p_preset->get_or_env("keystore/debug_user", ENV_ANDROID_KEYSTORE_DEBUG_USER); if (debug_keystore.is_empty()) { debug_keystore = EDITOR_GET("export/android/debug_keystore"); @@ -2745,9 +2907,9 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP cmdline.push_back("-Pdebug_keystore_password=" + debug_password); // argument to specify the debug keystore password. } else { // Pass the release keystore info as well - String release_keystore = p_preset->get("keystore/release"); - String release_username = p_preset->get("keystore/release_user"); - String release_password = p_preset->get("keystore/release_password"); + String release_keystore = p_preset->get_or_env("keystore/release", ENV_ANDROID_KEYSTORE_RELEASE_PATH); + String release_username = p_preset->get_or_env("keystore/release_user", ENV_ANDROID_KEYSTORE_RELEASE_USER); + String release_password = p_preset->get_or_env("keystore/release_password", ENV_ANDROID_KEYSTORE_RELEASE_PASS); if (release_keystore.is_relative_path()) { release_keystore = OS::get_singleton()->get_resource_dir().path_join(release_keystore).simplify_path(); } @@ -2798,11 +2960,11 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP return ERR_CANT_CREATE; } - print_verbose("Successfully completed Android custom build."); + print_verbose("Successfully completed Android gradle build."); return OK; } // This is the start of the Legacy build system - print_verbose("Starting legacy build system.."); + print_verbose("Starting legacy build system..."); if (p_debug) { src_apk = p_preset->get("custom_template/debug"); } else { @@ -2861,7 +3023,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP String apk_expansion_pkey = p_preset->get("apk_expansion/public_key"); - Vector<String> invalid_abis(enabled_abis); + Vector<ABI> invalid_abis(enabled_abis); while (ret == UNZ_OK) { //get filename unz_file_info info; @@ -2924,7 +3086,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP if (file.ends_with(".so")) { bool enabled = false; for (int i = 0; i < enabled_abis.size(); ++i) { - if (file.begins_with("lib/" + enabled_abis[i] + "/")) { + if (file.begins_with("lib/" + enabled_abis[i].abi + "/")) { invalid_abis.erase(enabled_abis[i]); enabled = true; break; @@ -2966,8 +3128,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP } if (!invalid_abis.is_empty()) { - String unsupported_arch = String(", ").join(invalid_abis); - add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Missing libraries in the export template for the selected architectures: %s. Please build a template with all required libraries, or uncheck the missing architectures in the export preset."), unsupported_arch)); + add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Missing libraries in the export template for the selected architectures: %s. Please build a template with all required libraries, or uncheck the missing architectures in the export preset."), join_abis(invalid_abis, ", ", false))); CLEANUP_AND_RETURN(ERR_FILE_NOT_FOUND); } @@ -3124,19 +3285,32 @@ void EditorExportPlatformAndroid::resolve_platform_feature_priorities(const Ref< } EditorExportPlatformAndroid::EditorExportPlatformAndroid() { - logo = ImageTexture::create_from_image(memnew(Image(_android_logo))); - run_icon = ImageTexture::create_from_image(memnew(Image(_android_run_icon))); + if (EditorNode::get_singleton()) { +#ifdef MODULE_SVG_ENABLED + Ref<Image> img = memnew(Image); + const bool upsample = !Math::is_equal_approx(Math::round(EDSCALE), EDSCALE); - devices_changed.set(); - plugins_changed.set(); + ImageLoaderSVG img_loader; + img_loader.create_image_from_string(img, _android_logo_svg, EDSCALE, upsample, false); + logo = ImageTexture::create_from_image(img); + + img_loader.create_image_from_string(img, _android_run_icon_svg, EDSCALE, upsample, false); + run_icon = ImageTexture::create_from_image(img); +#endif + + devices_changed.set(); + plugins_changed.set(); #ifndef ANDROID_ENABLED - check_for_changes_thread.start(_check_for_changes_poll_thread, this); + check_for_changes_thread.start(_check_for_changes_poll_thread, this); #endif + } } EditorExportPlatformAndroid::~EditorExportPlatformAndroid() { #ifndef ANDROID_ENABLED quit_request.set(); - check_for_changes_thread.wait_to_finish(); + if (check_for_changes_thread.is_started()) { + check_for_changes_thread.wait_to_finish(); + } #endif } diff --git a/platform/android/export/export_plugin.h b/platform/android/export/export_plugin.h index 46012bd46c..390b8c6465 100644 --- a/platform/android/export/export_plugin.h +++ b/platform/android/export/export_plugin.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* export_plugin.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* export_plugin.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 ANDROID_EXPORT_PLUGIN_H #define ANDROID_EXPORT_PLUGIN_H @@ -49,6 +49,15 @@ const String SPLASH_CONFIG_XML_CONTENT = R"SPLASH(<?xml version="1.0" encoding=" </layer-list> )SPLASH"; +// Optional environment variables for defining confidential information. If any +// of these is set, they will override the values set in the credentials file. +const String ENV_ANDROID_KEYSTORE_DEBUG_PATH = "GODOT_ANDROID_KEYSTORE_DEBUG_PATH"; +const String ENV_ANDROID_KEYSTORE_DEBUG_USER = "GODOT_ANDROID_KEYSTORE_DEBUG_USER"; +const String ENV_ANDROID_KEYSTORE_DEBUG_PASS = "GODOT_ANDROID_KEYSTORE_DEBUG_PASSWORD"; +const String ENV_ANDROID_KEYSTORE_RELEASE_PATH = "GODOT_ANDROID_KEYSTORE_RELEASE_PATH"; +const String ENV_ANDROID_KEYSTORE_RELEASE_USER = "GODOT_ANDROID_KEYSTORE_RELEASE_USER"; +const String ENV_ANDROID_KEYSTORE_RELEASE_PASS = "GODOT_ANDROID_KEYSTORE_RELEASE_PASSWORD"; + struct LauncherIcon { const char *export_path; int dimensions = 0; @@ -72,10 +81,10 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { EditorProgress *ep = nullptr; }; - Vector<PluginConfigAndroid> plugins; + mutable Vector<PluginConfigAndroid> plugins; String last_plugin_names; - uint64_t last_custom_build_time = 0; - SafeFlag plugins_changed; + uint64_t last_gradle_build_time = 0; + mutable SafeFlag plugins_changed; Mutex plugins_lock; Vector<Device> devices; SafeFlag devices_changed; @@ -91,15 +100,33 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { String get_package_name(const String &p_package) const; + String get_valid_basename() const; + String get_assets_directory(const Ref<EditorExportPreset> &p_preset, int p_export_format) const; bool is_package_name_valid(const String &p_package, String *r_error = nullptr) const; + bool is_project_name_valid() const; static bool _should_compress_asset(const String &p_path, const Vector<uint8_t> &p_data); static zip_fileinfo get_zip_fileinfo(); - static Vector<String> get_abis(); + struct ABI { + String abi; + String arch; + + bool operator==(const ABI &p_a) const { + return p_a.abi == abi; + } + + ABI(const String &p_abi, const String &p_arch) { + abi = p_abi; + arch = p_arch; + } + ABI() {} + }; + + static Vector<ABI> get_abis(); /// List the gdap files in the directory specified by the p_path parameter. static Vector<String> list_gdap_files(const String &p_path); @@ -152,7 +179,9 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { const Ref<Image> &foreground, const Ref<Image> &background); - static Vector<String> get_enabled_abis(const Ref<EditorExportPreset> &p_preset); + static Vector<ABI> get_enabled_abis(const Ref<EditorExportPreset> &p_preset); + + static bool _uses_vulkan(); public: typedef Error (*EditorExportSaveFunction)(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key); @@ -160,7 +189,9 @@ public: public: virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const override; - virtual void get_export_options(List<ExportOption> *r_options) override; + virtual void get_export_options(List<ExportOption> *r_options) const override; + + virtual String get_export_option_warning(const EditorExportPreset *p_preset, const StringName &p_name) const override; virtual String get_name() const override; @@ -186,7 +217,7 @@ public: static String get_adb_path(); - static String get_apksigner_path(); + static String get_apksigner_path(int p_target_sdk = -1, bool p_check_executes = false); virtual bool has_valid_export_configuration(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const override; virtual bool has_valid_project_configuration(const Ref<EditorExportPreset> &p_preset, String &r_error) const override; @@ -195,14 +226,14 @@ public: inline bool is_clean_build_required(Vector<PluginConfigAndroid> enabled_plugins) { String plugin_names = PluginConfigAndroid::get_plugins_names(enabled_plugins); - bool first_build = last_custom_build_time == 0; + bool first_build = last_gradle_build_time == 0; bool have_plugins_changed = false; if (!first_build) { have_plugins_changed = plugin_names != last_plugin_names; if (!have_plugins_changed) { for (int i = 0; i < enabled_plugins.size(); i++) { - if (enabled_plugins.get(i).last_updated > last_custom_build_time) { + if (enabled_plugins.get(i).last_updated > last_gradle_build_time) { have_plugins_changed = true; break; } @@ -210,7 +241,7 @@ public: } } - last_custom_build_time = OS::get_singleton()->get_unix_time(); + last_gradle_build_time = OS::get_singleton()->get_unix_time(); last_plugin_names = plugin_names; return have_plugins_changed || first_build; @@ -228,7 +259,8 @@ public: void _remove_copied_libs(); - String join_list(List<String> parts, const String &separator) const; + static String join_list(const List<String> &p_parts, const String &p_separator); + static String join_abis(const Vector<ABI> &p_parts, const String &p_separator, bool p_use_arch); virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0) override; diff --git a/platform/android/export/godot_plugin_config.cpp b/platform/android/export/godot_plugin_config.cpp index 21580ae907..b64cca3254 100644 --- a/platform/android/export/godot_plugin_config.cpp +++ b/platform/android/export/godot_plugin_config.cpp @@ -1,34 +1,35 @@ -/*************************************************************************/ -/* godot_plugin_config.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* godot_plugin_config.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "godot_plugin_config.h" + /* * Set of prebuilt plugins. * Currently unused, this is just for future reference: diff --git a/platform/android/export/godot_plugin_config.h b/platform/android/export/godot_plugin_config.h index 5188f615d4..bef00979a9 100644 --- a/platform/android/export/godot_plugin_config.h +++ b/platform/android/export/godot_plugin_config.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* godot_plugin_config.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* godot_plugin_config.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 ANDROID_GODOT_PLUGIN_CONFIG_H #define ANDROID_GODOT_PLUGIN_CONFIG_H diff --git a/platform/android/export/gradle_export_util.cpp b/platform/android/export/gradle_export_util.cpp index 8d016d3fac..ba4487cc4d 100644 --- a/platform/android/export/gradle_export_util.cpp +++ b/platform/android/export/gradle_export_util.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* gradle_export_util.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* gradle_export_util.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "gradle_export_util.h" @@ -72,6 +72,54 @@ String _get_android_orientation_label(DisplayServer::ScreenOrientation screen_or } } +int _get_app_category_value(int category_index) { + switch (category_index) { + case APP_CATEGORY_ACCESSIBILITY: + return 8; + case APP_CATEGORY_AUDIO: + return 1; + case APP_CATEGORY_IMAGE: + return 3; + case APP_CATEGORY_MAPS: + return 6; + case APP_CATEGORY_NEWS: + return 5; + case APP_CATEGORY_PRODUCTIVITY: + return 7; + case APP_CATEGORY_SOCIAL: + return 4; + case APP_CATEGORY_VIDEO: + return 2; + case APP_CATEGORY_GAME: + default: + return 0; + } +} + +String _get_app_category_label(int category_index) { + switch (category_index) { + case APP_CATEGORY_ACCESSIBILITY: + return "accessibility"; + case APP_CATEGORY_AUDIO: + return "audio"; + case APP_CATEGORY_IMAGE: + return "image"; + case APP_CATEGORY_MAPS: + return "maps"; + case APP_CATEGORY_NEWS: + return "news"; + case APP_CATEGORY_PRODUCTIVITY: + return "productivity"; + case APP_CATEGORY_SOCIAL: + return "social"; + case APP_CATEGORY_VIDEO: + return "video"; + case APP_CATEGORY_GAME: + default: + return "game"; + } +} + // Utility method used to create a directory. Error create_directory(const String &p_dir) { if (!DirAccess::exists(p_dir)) { @@ -118,7 +166,7 @@ Error store_string_at_path(const String &p_path, const String &p_data) { // This method will only be called as an input to export_project_files. // It is used by the export_project_files method to save all the asset files into the gradle project. // It's functionality mirrors that of the method save_apk_file. -// This method will be called ONLY when custom build is enabled. +// This method will be called ONLY when gradle build is enabled. Error rename_and_store_file_in_gradle_project(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key) { CustomExportData *export_data = static_cast<CustomExportData *>(p_userdata); String dst_path = p_path.replace_first("res://", export_data->assets_directory + "/"); @@ -206,13 +254,11 @@ String _get_screen_sizes_tag(const Ref<EditorExportPreset> &p_preset) { return manifest_screen_sizes; } -String _get_xr_features_tag(const Ref<EditorExportPreset> &p_preset) { +String _get_xr_features_tag(const Ref<EditorExportPreset> &p_preset, bool p_uses_vulkan) { String manifest_xr_features; int xr_mode_index = (int)(p_preset->get("xr_features/xr_mode")); bool uses_xr = xr_mode_index == XR_MODE_OPENXR; if (uses_xr) { - manifest_xr_features += " <uses-feature tools:node=\"replace\" android:name=\"android.hardware.vr.headtracking\" android:required=\"true\" android:version=\"1\" />\n"; - int hand_tracking_index = p_preset->get("xr_features/hand_tracking"); // 0: none, 1: optional, 2: required if (hand_tracking_index == XR_HAND_TRACKING_OPTIONAL) { manifest_xr_features += " <uses-feature tools:node=\"replace\" android:name=\"oculus.software.handtracking\" android:required=\"false\" />\n"; @@ -227,47 +273,74 @@ String _get_xr_features_tag(const Ref<EditorExportPreset> &p_preset) { manifest_xr_features += " <uses-feature tools:node=\"replace\" android:name=\"com.oculus.feature.PASSTHROUGH\" android:required=\"true\" />\n"; } } + + if (p_uses_vulkan) { + manifest_xr_features += " <uses-feature tools:node=\"replace\" android:name=\"android.hardware.vulkan.level\" android:required=\"false\" android:version=\"1\" />\n"; + manifest_xr_features += " <uses-feature tools:node=\"replace\" android:name=\"android.hardware.vulkan.version\" android:required=\"true\" android:version=\"0x400003\" />\n"; + } return manifest_xr_features; } -String _get_activity_tag(const Ref<EditorExportPreset> &p_preset) { - int xr_mode_index = (int)(p_preset->get("xr_features/xr_mode")); - bool uses_xr = xr_mode_index == XR_MODE_OPENXR; +String _get_activity_tag(const Ref<EditorExportPreset> &p_preset, bool p_uses_xr) { String orientation = _get_android_orientation_label(DisplayServer::ScreenOrientation(int(GLOBAL_GET("display/window/handheld/orientation")))); String manifest_activity_text = vformat( " <activity android:name=\"com.godot.game.GodotApp\" " "tools:replace=\"android:screenOrientation,android:excludeFromRecents,android:resizeableActivity\" " + "tools:node=\"mergeOnlyAttributes\" " "android:excludeFromRecents=\"%s\" " "android:screenOrientation=\"%s\" " "android:resizeableActivity=\"%s\">\n", bool_to_string(p_preset->get("package/exclude_from_recents")), orientation, bool_to_string(bool(GLOBAL_GET("display/window/size/resizable")))); - if (uses_xr) { - manifest_activity_text += " <meta-data tools:node=\"replace\" android:name=\"com.oculus.vr.focusaware\" android:value=\"true\" />\n"; + + if (p_uses_xr) { + manifest_activity_text += " <intent-filter>\n" + " <action android:name=\"android.intent.action.MAIN\" />\n" + " <category android:name=\"android.intent.category.LAUNCHER\" />\n" + "\n" + " <!-- Enable access to OpenXR on Oculus mobile devices, no-op on other Android\n" + " platforms. -->\n" + " <category android:name=\"com.oculus.intent.category.VR\" />\n" + "\n" + " <!-- OpenXR category tag to indicate the activity starts in an immersive OpenXR mode. \n" + " See https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#android-runtime-category. -->\n" + " <category android:name=\"org.khronos.openxr.intent.category.IMMERSIVE_HMD\" />\n" + "\n" + " <!-- Enable VR access on HTC Vive Focus devices. -->\n" + " <category android:name=\"com.htc.intent.category.VRAPP\" />\n" + " </intent-filter>\n"; } else { - manifest_activity_text += " <meta-data tools:node=\"remove\" android:name=\"com.oculus.vr.focusaware\" />\n"; + manifest_activity_text += " <intent-filter>\n" + " <action android:name=\"android.intent.action.MAIN\" />\n" + " <category android:name=\"android.intent.category.LAUNCHER\" />\n" + " </intent-filter>\n"; } + manifest_activity_text += " </activity>\n"; return manifest_activity_text; } String _get_application_tag(const Ref<EditorExportPreset> &p_preset, bool p_has_read_write_storage_permission) { + int app_category_index = (int)(p_preset->get("package/app_category")); + bool is_game = app_category_index == APP_CATEGORY_GAME; + 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( " <application android:label=\"@string/godot_project_name_string\"\n" " android:allowBackup=\"%s\"\n" " android:icon=\"@mipmap/icon\"\n" + " android:appCategory=\"%s\"\n" " android:isGame=\"%s\"\n" " android:hasFragileUserData=\"%s\"\n" " android:requestLegacyExternalStorage=\"%s\"\n" - " tools:replace=\"android:allowBackup,android:isGame,android:hasFragileUserData,android:requestLegacyExternalStorage\"\n" - " tools:ignore=\"GoogleAppIndexingWarning\">\n\n" - " <meta-data tools:node=\"remove\" android:name=\"xr_hand_tracking_version_name\" />\n" - " <meta-data tools:node=\"remove\" android:name=\"xr_hand_tracking_metadata_name\" />\n", + " tools:replace=\"android:allowBackup,android:appCategory,android:isGame,android:hasFragileUserData,android:requestLegacyExternalStorage\"\n" + " tools:ignore=\"GoogleAppIndexingWarning\">\n\n", bool_to_string(p_preset->get("user_data_backup/allow")), - bool_to_string(p_preset->get("package/classify_as_game")), + _get_app_category_label(app_category_index), + bool_to_string(is_game), bool_to_string(p_preset->get("package/retain_data_on_uninstall")), bool_to_string(p_has_read_write_storage_permission)); @@ -281,10 +354,8 @@ String _get_application_tag(const Ref<EditorExportPreset> &p_preset, bool p_has_ hand_tracking_frequency); manifest_application_text += " <meta-data tools:node=\"replace\" android:name=\"com.oculus.handtracking.version\" android:value=\"V2.0\" />\n"; } - } else { - manifest_application_text += " <meta-data tools:node=\"remove\" android:name=\"com.oculus.supportedDevices\" />\n"; } - manifest_application_text += _get_activity_tag(p_preset); + manifest_application_text += _get_activity_tag(p_preset, uses_xr); manifest_application_text += " </application>\n"; return manifest_application_text; } diff --git a/platform/android/export/gradle_export_util.h b/platform/android/export/gradle_export_util.h index 232b4458c6..8a885a0d12 100644 --- a/platform/android/export/gradle_export_util.h +++ b/platform/android/export/gradle_export_util.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* gradle_export_util.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* gradle_export_util.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 ANDROID_GRADLE_EXPORT_UTIL_H #define ANDROID_GRADLE_EXPORT_UTIL_H @@ -44,6 +44,18 @@ const String godot_project_name_xml_string = R"(<?xml version="1.0" encoding="ut </resources> )"; +// Application category. +// See https://developer.android.com/guide/topics/manifest/application-element#appCategory for standards +static const int APP_CATEGORY_ACCESSIBILITY = 0; +static const int APP_CATEGORY_AUDIO = 1; +static const int APP_CATEGORY_GAME = 2; +static const int APP_CATEGORY_IMAGE = 3; +static const int APP_CATEGORY_MAPS = 4; +static const int APP_CATEGORY_NEWS = 5; +static const int APP_CATEGORY_PRODUCTIVITY = 6; +static const int APP_CATEGORY_SOCIAL = 7; +static const int APP_CATEGORY_VIDEO = 8; + // Supported XR modes. // This should match the entries in 'platform/android/java/lib/src/org/godotengine/godot/xr/XRMode.java' static const int XR_MODE_REGULAR = 0; @@ -73,6 +85,10 @@ int _get_android_orientation_value(DisplayServer::ScreenOrientation screen_orien String _get_android_orientation_label(DisplayServer::ScreenOrientation screen_orientation); +int _get_app_category_value(int category_index); + +String _get_app_category_label(int category_index); + // Utility method used to create a directory. Error create_directory(const String &p_dir); @@ -88,7 +104,7 @@ Error store_string_at_path(const String &p_path, const String &p_data); // This method will only be called as an input to export_project_files. // It is used by the export_project_files method to save all the asset files into the gradle project. // It's functionality mirrors that of the method save_apk_file. -// This method will be called ONLY when custom build is enabled. +// This method will be called ONLY when gradle build is enabled. Error rename_and_store_file_in_gradle_project(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key); // Creates strings.xml files inside the gradle project for different locales. @@ -100,9 +116,9 @@ String _get_gles_tag(); String _get_screen_sizes_tag(const Ref<EditorExportPreset> &p_preset); -String _get_xr_features_tag(const Ref<EditorExportPreset> &p_preset); +String _get_xr_features_tag(const Ref<EditorExportPreset> &p_preset, bool p_uses_vulkan); -String _get_activity_tag(const Ref<EditorExportPreset> &p_preset); +String _get_activity_tag(const Ref<EditorExportPreset> &p_preset, bool p_uses_xr); String _get_application_tag(const Ref<EditorExportPreset> &p_preset, bool p_has_read_write_storage_permission); diff --git a/platform/android/file_access_android.cpp b/platform/android/file_access_android.cpp index d6cd62e9f5..1249f2219f 100644 --- a/platform/android/file_access_android.cpp +++ b/platform/android/file_access_android.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* file_access_android.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* file_access_android.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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_android.h" @@ -169,6 +169,10 @@ bool FileAccessAndroid::file_exists(const String &p_path) { return true; } +void FileAccessAndroid::close() { + _close(); +} + FileAccessAndroid::~FileAccessAndroid() { _close(); } diff --git a/platform/android/file_access_android.h b/platform/android/file_access_android.h index 55f8fbe0f4..7ff5c4d117 100644 --- a/platform/android/file_access_android.h +++ b/platform/android/file_access_android.h @@ -1,37 +1,38 @@ -/*************************************************************************/ -/* file_access_android.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* file_access_android.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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_ANDROID_H #define FILE_ACCESS_ANDROID_H #include "core/io/file_access.h" + #include <android/asset_manager.h> #include <android/log.h> #include <stdio.h> @@ -78,6 +79,8 @@ public: 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; } + virtual void close() override; + ~FileAccessAndroid(); }; diff --git a/platform/android/file_access_filesystem_jandroid.cpp b/platform/android/file_access_filesystem_jandroid.cpp index c2ee3389ae..a1865fb1d4 100644 --- a/platform/android/file_access_filesystem_jandroid.cpp +++ b/platform/android/file_access_filesystem_jandroid.cpp @@ -1,38 +1,39 @@ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* file_access_filesystem_jandroid.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "thread_jandroid.h" + #include "core/os/os.h" #include "core/templates/local_vector.h" -#include "thread_jandroid.h" #include <unistd.h> @@ -333,6 +334,12 @@ void FileAccessFilesystemJAndroid::setup(jobject p_file_access_handler) { _file_last_modified = env->GetMethodID(cls, "fileLastModified", "(Ljava/lang/String;)J"); } +void FileAccessFilesystemJAndroid::close() { + if (is_open()) { + _close(); + } +} + FileAccessFilesystemJAndroid::FileAccessFilesystemJAndroid() { id = 0; } diff --git a/platform/android/file_access_filesystem_jandroid.h b/platform/android/file_access_filesystem_jandroid.h index 815ab36516..739c8a0925 100644 --- a/platform/android/file_access_filesystem_jandroid.h +++ b/platform/android/file_access_filesystem_jandroid.h @@ -1,39 +1,40 @@ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* file_access_filesystem_jandroid.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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" +#include "core/io/file_access.h" + class FileAccessFilesystemJAndroid : public FileAccess { static jobject file_access_handler; static jclass cls; @@ -93,6 +94,8 @@ public: 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; } + virtual void close() override; + FileAccessFilesystemJAndroid(); ~FileAccessFilesystemJAndroid(); }; diff --git a/platform/android/java/app/AndroidManifest.xml b/platform/android/java/app/AndroidManifest.xml index 2d4c4763a2..542ab51660 100644 --- a/platform/android/java/app/AndroidManifest.xml +++ b/platform/android/java/app/AndroidManifest.xml @@ -13,13 +13,14 @@ android:xlargeScreens="true" /> <uses-feature - android:glEsVersion="0x00020000" + android:glEsVersion="0x00030000" android:required="true" /> <application android:label="@string/godot_project_name_string" android:allowBackup="false" android:icon="@mipmap/icon" + android:appCategory="game" android:isGame="true" android:hasFragileUserData="false" android:requestLegacyExternalStorage="false" @@ -30,34 +31,11 @@ android:name="org.godotengine.editor.version" android:value="${godotEditorVersion}" /> - <!-- The following metadata values are replaced when Godot exports, modifying them here has no effect. --> - <!-- Do these changes in the export preset. Adding new ones is fine. --> - - <!-- XR hand tracking metadata --> - <!-- This is modified by the exporter based on the selected xr mode. DO NOT CHANGE the values here. --> - <!-- Removed at export time if the xr mode is not VR or hand tracking is disabled. --> - <meta-data - android:name="xr_hand_tracking_metadata_name" - android:value="xr_hand_tracking_metadata_value"/> - - <!-- XR hand tracking version --> - <!-- This is modified by the exporter based on the selected xr mode. DO NOT CHANGE the values here. --> - <!-- Removed at export time if the xr mode is not VR or hand tracking is disabled. --> - <meta-data - android:name="xr_hand_tracking_version_name" - android:value="xr_hand_tracking_version_value"/> - - <!-- Supported Meta devices --> - <!-- This is removed by the exporter if the xr mode is not VR. --> - <meta-data - android:name="com.oculus.supportedDevices" - android:value="all" /> - <activity android:name=".GodotApp" android:label="@string/godot_project_name_string" android:theme="@style/GodotAppSplashTheme" - android:launchMode="singleTask" + android:launchMode="singleInstance" android:excludeFromRecents="false" android:exported="true" android:screenOrientation="landscape" @@ -65,16 +43,9 @@ android:resizeableActivity="false" tools:ignore="UnusedAttribute" > - <!-- Focus awareness metadata is removed at export time if the xr mode is not VR. --> - <meta-data android:name="com.oculus.vr.focusaware" android:value="true" /> - <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> - - <!-- Enable access to OpenXR on Oculus mobile devices, no-op on other Android - platforms. --> - <category android:name="com.oculus.intent.category.VR" /> </intent-filter> </activity> diff --git a/platform/android/java/app/build.gradle b/platform/android/java/app/build.gradle index 63b10e62b1..01b148aeef 100644 --- a/platform/android/java/app/build.gradle +++ b/platform/android/java/app/build.gradle @@ -50,7 +50,7 @@ dependencies { } else if (rootProject.findProject(":godot:lib")) { implementation project(":godot:lib") } else { - // Custom build mode. In this scenario this project is the only one around and the Godot + // Godot gradle build mode. In this scenario this project is the only one around and the Godot // library is available through the pre-generated godot-lib.*.aar android archive files. debugImplementation fileTree(dir: 'libs/debug', include: ['*.jar', '*.aar']) devImplementation fileTree(dir: 'libs/dev', include: ['*.jar', '*.aar']) @@ -153,7 +153,7 @@ android { debug { // Signing and zip-aligning are skipped for prebuilt builds, but - // performed for custom builds. + // performed for Godot gradle builds. zipAlignEnabled shouldZipAlign() if (shouldSign()) { signingConfig signingConfigs.debug @@ -165,7 +165,7 @@ android { dev { initWith debug // Signing and zip-aligning are skipped for prebuilt builds, but - // performed for custom builds. + // performed for Godot gradle builds. zipAlignEnabled shouldZipAlign() if (shouldSign()) { signingConfig signingConfigs.debug @@ -176,7 +176,7 @@ android { release { // Signing and zip-aligning are skipped for prebuilt builds, but - // performed for custom builds. + // performed for Godot gradle builds. zipAlignEnabled shouldZipAlign() if (shouldSign()) { signingConfig signingConfigs.release diff --git a/platform/android/java/app/config.gradle b/platform/android/java/app/config.gradle index 0346625e4b..e7c06628c8 100644 --- a/platform/android/java/app/config.gradle +++ b/platform/android/java/app/config.gradle @@ -1,14 +1,17 @@ ext.versions = [ - androidGradlePlugin: '7.0.3', - compileSdk : 32, - minSdk : 19, // Also update 'platform/android/java/lib/AndroidManifest.xml#minSdkVersion' & 'platform/android/export/export_plugin.cpp#DEFAULT_MIN_SDK_VERSION' - 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', + androidGradlePlugin: '7.2.1', + compileSdk : 33, + // Also update 'platform/android/export/export_plugin.cpp#OPENGL_MIN_SDK_VERSION' + minSdk : 21, + // Also update 'platform/android/export/export_plugin.cpp#DEFAULT_TARGET_SDK_VERSION' + targetSdk : 33, + buildTools : '33.0.2', + kotlinVersion : '1.7.0', fragmentVersion : '1.3.6', nexusPublishVersion: '1.1.0', javaVersion : 11, - ndkVersion : '23.2.8568313' // Also update 'platform/android/detect.py#get_ndk_version()' when this is updated. + // Also update 'platform/android/detect.py#get_ndk_version()' when this is updated. + ndkVersion : '23.2.8568313' ] @@ -132,14 +135,16 @@ ext.generateGodotLibraryVersion = { List<String> requiredKeys -> String statusValue = map["status"] if (statusValue == null) { statusCode = 0 - } else if (statusValue.startsWith("alpha")) { + } else if (statusValue.startsWith("dev")) { statusCode = 1 - } else if (statusValue.startsWith("beta")) { + } else if (statusValue.startsWith("alpha")) { statusCode = 2 - } else if (statusValue.startsWith("rc")) { + } else if (statusValue.startsWith("beta")) { statusCode = 3 - } else if (statusValue.startsWith("stable")) { + } else if (statusValue.startsWith("rc")) { statusCode = 4 + } else if (statusValue.startsWith("stable")) { + statusCode = 5 } else { statusCode = 0 } @@ -186,6 +191,9 @@ ext.getGodotPublishVersion = { -> String versionName = "" int versionCode = 1 (versionName, versionCode) = generateGodotLibraryVersion(requiredKeys) + if (!versionName.endsWith("stable")) { + versionName += "-SNAPSHOT" + } return versionName } diff --git a/platform/android/java/app/gradle.properties b/platform/android/java/app/gradle.properties index 0ad8e611ca..d9f79b6818 100644 --- a/platform/android/java/app/gradle.properties +++ b/platform/android/java/app/gradle.properties @@ -1,5 +1,5 @@ -# Godot custom build Gradle settings. -# These properties apply when running custom build from the Godot editor. +# Godot gradle build settings. +# These properties apply when running a gradle build from the Godot editor. # NOTE: This should be kept in sync with 'godot/platform/android/java/gradle.properties' except # where otherwise specified. diff --git a/platform/android/java/app/settings.gradle b/platform/android/java/app/settings.gradle index ba53aefe7f..b4524a3f60 100644 --- a/platform/android/java/app/settings.gradle +++ b/platform/android/java/app/settings.gradle @@ -1,4 +1,4 @@ -// This is the root directory of the Godot custom build. +// This is the root directory of the Godot Android gradle build. pluginManagement { apply from: 'config.gradle' diff --git a/platform/android/java/app/src/com/godot/game/GodotApp.java b/platform/android/java/app/src/com/godot/game/GodotApp.java index c9684bce14..1d2cc05715 100644 --- a/platform/android/java/app/src/com/godot/game/GodotApp.java +++ b/platform/android/java/app/src/com/godot/game/GodotApp.java @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* GodotApp.java */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* GodotApp.java */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 com.godot.game; @@ -35,7 +35,7 @@ import org.godotengine.godot.FullScreenGodotApp; import android.os.Bundle; /** - * Template activity for Godot Android custom builds. + * Template activity for Godot Android builds. * Feel free to extend and modify this class for your custom logic. */ public class GodotApp extends FullScreenGodotApp { diff --git a/platform/android/java/build.gradle b/platform/android/java/build.gradle index 5a91e5ce32..f94454e2a7 100644 --- a/platform/android/java/build.gradle +++ b/platform/android/java/build.gradle @@ -9,7 +9,7 @@ buildscript { dependencies { classpath libraries.androidGradlePlugin classpath libraries.kotlinGradlePlugin - classpath 'io.github.gradle-nexus:publish-plugin:1.1.0' + classpath 'io.github.gradle-nexus:publish-plugin:1.3.0' } } @@ -20,6 +20,13 @@ plugins { apply from: 'app/config.gradle' apply from: 'scripts/publish-root.gradle' +ext { + PUBLISH_VERSION = getGodotPublishVersion() +} + +group = ossrhGroupId +version = PUBLISH_VERSION + allprojects { repositories { google() @@ -31,9 +38,7 @@ ext { supportedAbis = ["arm32", "arm64", "x86_32", "x86_64"] supportedFlavors = ["editor", "template"] supportedFlavorsBuildTypes = [ - // The editor can't be used with target=release as debugging tools are then not - // included, and it would crash on errors instead of reporting them. - "editor": ["dev", "debug"], + "editor": ["dev", "debug", "release"], "template": ["dev", "debug", "release"] ] @@ -47,6 +52,7 @@ ext { def rootDir = "../../.." def binDir = "$rootDir/bin/" +def androidEditorBuildsDir = "$binDir/android_editor_builds/" def getSconsTaskName(String flavor, String buildType, String abi) { return "compileGodotNativeLibs" + flavor.capitalize() + buildType.capitalize() + abi.capitalize() @@ -152,14 +158,14 @@ task copyReleaseAARToBin(type: Copy) { } /** - * Generate Godot custom build template by zipping the source files from the app directory, as well + * Generate Godot gradle build template by zipping the source files from the app directory, as well * as the AAR files generated by 'copyDebugAAR', 'copyDevAAR' and 'copyReleaseAAR'. - * The zip file also includes some gradle tools to allow building of the custom build. + * The zip file also includes some gradle tools to enable gradle builds from the Godot Editor. */ -task zipCustomBuild(type: Zip) { +task zipGradleBuild(type: Zip) { onlyIf { generateGodotTemplates.state.executed || generateDevTemplate.state.executed } doFirst { - logger.lifecycle("Generating Godot custom build template") + logger.lifecycle("Generating Godot gradle build template") } from(fileTree(dir: 'app', excludes: ['**/build/**', '**/.gradle/**', '**/*.iml']), fileTree(dir: '.', includes: ['gradlew', 'gradlew.bat', 'gradle/**'])) include '**/*' @@ -195,7 +201,7 @@ def templateBuildTasks() { && targetLibs.listFiles() != null && targetLibs.listFiles().length > 0) { String capitalizedTarget = target.capitalize() - // Copy the generated aar library files to the custom build directory. + // Copy the generated aar library files to the build directory. tasks += "copy" + capitalizedTarget + "AARToAppModule" // Copy the generated aar library files to the bin directory. tasks += "copy" + capitalizedTarget + "AARToBin" @@ -214,18 +220,46 @@ def isAndroidStudio() { return sysProps != null && sysProps['idea.platform.prefix'] != null } -task copyEditorDebugBinaryToBin(type: Copy) { +task copyEditorReleaseApkToBin(type: Copy) { + dependsOn ':editor:assembleRelease' + from('editor/build/outputs/apk/release') + into(androidEditorBuildsDir) + include('android_editor-release*.apk') +} + +task copyEditorReleaseAabToBin(type: Copy) { + dependsOn ':editor:bundleRelease' + from('editor/build/outputs/bundle/release') + into(androidEditorBuildsDir) + include('android_editor-release*.aab') +} + +task copyEditorDebugApkToBin(type: Copy) { dependsOn ':editor:assembleDebug' from('editor/build/outputs/apk/debug') - into(binDir) - include('android_editor.apk') + into(androidEditorBuildsDir) + include('android_editor-debug.apk') +} + +task copyEditorDebugAabToBin(type: Copy) { + dependsOn ':editor:bundleDebug' + from('editor/build/outputs/bundle/debug') + into(androidEditorBuildsDir) + include('android_editor-debug.aab') } -task copyEditorDevBinaryToBin(type: Copy) { +task copyEditorDevApkToBin(type: Copy) { dependsOn ':editor:assembleDev' from('editor/build/outputs/apk/dev') - into(binDir) - include('android_editor_dev.apk') + into(androidEditorBuildsDir) + include('android_editor-dev.apk') +} + +task copyEditorDevAabToBin(type: Copy) { + dependsOn ':editor:bundleDev' + from('editor/build/outputs/bundle/dev') + into(androidEditorBuildsDir) + include('android_editor-dev.aab') } /** @@ -246,7 +280,8 @@ task generateGodotEditor { && targetLibs.isDirectory() && targetLibs.listFiles() != null && targetLibs.listFiles().length > 0) { - tasks += "copyEditor${target.capitalize()}BinaryToBin" + tasks += "copyEditor${target.capitalize()}ApkToBin" + tasks += "copyEditor${target.capitalize()}AabToBin" } } @@ -260,7 +295,7 @@ task generateGodotTemplates { gradle.startParameter.excludedTaskNames += templateExcludedBuildTask() dependsOn = templateBuildTasks() - finalizedBy 'zipCustomBuild' + finalizedBy 'zipGradleBuild' } /** @@ -273,7 +308,7 @@ task generateDevTemplate { gradle.startParameter.excludedTaskNames += templateExcludedBuildTask() dependsOn = templateBuildTasks() - finalizedBy 'zipCustomBuild' + finalizedBy 'zipGradleBuild' } task clean(type: Delete) { @@ -294,9 +329,11 @@ task cleanGodotEditor(type: Delete) { // Delete the generated binary apks delete("editor/build/outputs/apk") - // Delete the Godot editor apks in the Godot bin directory - delete("$binDir/android_editor.apk") - delete("$binDir/android_editor_dev.apk") + // Delete the generated aab binaries + delete("editor/build/outputs/bundle") + + // Delete the Godot editor apks & aabs in the Godot bin directory + delete(androidEditorBuildsDir) } /** diff --git a/platform/android/java/editor/build.gradle b/platform/android/java/editor/build.gradle index 9152492e9d..38034aa47c 100644 --- a/platform/android/java/editor/build.gradle +++ b/platform/android/java/editor/build.gradle @@ -13,22 +13,67 @@ dependencies { } ext { - // Build number added as a suffix to the version code, and incremented for each build/upload to - // the Google Play store. - // This should be reset on each stable release of Godot. - editorBuildNumber = 0 + // Retrieve the build number from the environment variable; default to 0 if none is specified. + // The build number is added as a suffix to the version code for upload to the Google Play store. + getEditorBuildNumber = { -> + int buildNumber = 0 + String versionStatus = System.getenv("GODOT_VERSION_STATUS") + if (versionStatus != null && !versionStatus.isEmpty()) { + try { + buildNumber = Integer.parseInt(versionStatus.replaceAll("[^0-9]", "")); + } catch (NumberFormatException ignored) { + buildNumber = 0 + } + } + + return buildNumber + } // Value by which the Godot version code should be offset by to make room for the build number editorBuildNumberOffset = 100 + + // Return the keystore file used for signing the release build. + getGodotKeystoreFile = { -> + def keyStore = System.getenv("GODOT_ANDROID_SIGN_KEYSTORE") + if (keyStore == null) { + return null + } + return file(keyStore) + } + + // Return the key alias used for signing the release build. + getGodotKeyAlias = { -> + def kAlias = System.getenv("GODOT_ANDROID_KEYSTORE_ALIAS") + return kAlias + } + + // Return the password for the key used for signing the release build. + getGodotSigningPassword = { -> + def signingPassword = System.getenv("GODOT_ANDROID_SIGN_PASSWORD") + return signingPassword + } + + // Returns true if the environment variables contains the configuration for signing the release + // build. + hasReleaseSigningConfigs = { -> + def keystoreFile = getGodotKeystoreFile() + def keyAlias = getGodotKeyAlias() + def signingPassword = getGodotSigningPassword() + + return keystoreFile != null && keystoreFile.isFile() + && keyAlias != null && !keyAlias.isEmpty() + && signingPassword != null && !signingPassword.isEmpty() + } } def generateVersionCode() { int libraryVersionCode = getGodotLibraryVersionCode() - return (libraryVersionCode * editorBuildNumberOffset) + editorBuildNumber + return (libraryVersionCode * editorBuildNumberOffset) + getEditorBuildNumber() } def generateVersionName() { String libraryVersionName = getGodotLibraryVersionName() - return libraryVersionName + ".$editorBuildNumber" + int buildNumber = getEditorBuildNumber() + return buildNumber == 0 ? libraryVersionName : libraryVersionName + ".$buildNumber" } android { @@ -45,6 +90,7 @@ android { targetSdkVersion versions.targetSdk missingDimensionStrategy 'products', 'editor' + setProperty("archivesBaseName", "android_editor") } compileOptions { @@ -56,6 +102,15 @@ android { jvmTarget = versions.javaVersion } + signingConfigs { + release { + storeFile getGodotKeystoreFile() + storePassword getGodotSigningPassword() + keyAlias getGodotKeyAlias() + keyPassword getGodotSigningPassword() + } + } + buildTypes { dev { initWith debug @@ -64,15 +119,14 @@ android { debug { initWith release - - // Need to swap with the release signing config when this is ready for public release. + applicationIdSuffix ".debug" signingConfig signingConfigs.debug } release { - // This buildtype is disabled below. - // The editor can't be used with target=release only, as debugging tools are then not - // included, and it would crash on errors instead of reporting them. + if (hasReleaseSigningConfigs()) { + signingConfig signingConfigs.release + } } } @@ -82,20 +136,4 @@ android { doNotStrip '**/*.so' } } - - // Disable 'release' buildtype. - // The editor can't be used with target=release only, as debugging tools are then not - // included, and it would crash on errors instead of reporting them. - variantFilter { variant -> - if (variant.buildType.name == "release") { - setIgnore(true) - } - } - - applicationVariants.all { variant -> - variant.outputs.all { output -> - def suffix = variant.name == "dev" ? "_dev" : "" - output.outputFileName = "android_editor${suffix}.apk" - } - } } diff --git a/platform/android/java/editor/src/debug/res/values/strings.xml b/platform/android/java/editor/src/debug/res/values/strings.xml new file mode 100644 index 0000000000..09ee2d77e1 --- /dev/null +++ b/platform/android/java/editor/src/debug/res/values/strings.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="godot_editor_name_string">Godot Editor 4 (debug)</string> +</resources> diff --git a/platform/android/java/editor/src/dev/res/values/strings.xml b/platform/android/java/editor/src/dev/res/values/strings.xml index 45fae3fd39..215f2c7d0a 100644 --- a/platform/android/java/editor/src/dev/res/values/strings.xml +++ b/platform/android/java/editor/src/dev/res/values/strings.xml @@ -1,4 +1,4 @@ <?xml version="1.0" encoding="utf-8"?> <resources> - <string name="godot_editor_name_string">Godot Editor 4.x (dev)</string> + <string name="godot_editor_name_string">Godot Editor 4 (dev)</string> </resources> diff --git a/platform/android/java/editor/src/main/AndroidManifest.xml b/platform/android/java/editor/src/main/AndroidManifest.xml index 6aa5f06f31..c7b2c8ad67 100644 --- a/platform/android/java/editor/src/main/AndroidManifest.xml +++ b/platform/android/java/editor/src/main/AndroidManifest.xml @@ -11,7 +11,7 @@ android:xlargeScreens="true" /> <uses-feature - android:glEsVersion="0x00020000" + android:glEsVersion="0x00030000" android:required="true" /> <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" @@ -21,21 +21,23 @@ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="29"/> <uses-permission android:name="android.permission.INTERNET" /> + <uses-permission android:name="android.permission.RECORD_AUDIO" /> + <uses-permission android:name="android.permission.VIBRATE" /> <application android:allowBackup="false" android:icon="@mipmap/icon" android:label="@string/godot_editor_name_string" tools:ignore="GoogleAppIndexingWarning" + android:theme="@style/GodotEditorTheme" android:requestLegacyExternalStorage="true"> <activity android:name=".GodotProjectManager" android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize|density|keyboard|navigation|screenLayout|uiMode" - android:launchMode="singleTask" + android:launchMode="singleInstance" android:screenOrientation="userLandscape" android:exported="true" - android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen" android:process=":GodotProjectManager"> <layout android:defaultHeight="@dimen/editor_default_window_height" @@ -51,10 +53,9 @@ android:name=".GodotEditor" android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize|density|keyboard|navigation|screenLayout|uiMode" android:process=":GodotEditor" - android:launchMode="singleTask" + android:launchMode="singleInstance" android:screenOrientation="userLandscape" - android:exported="false" - android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"> + android:exported="false"> <layout android:defaultHeight="@dimen/editor_default_window_height" android:defaultWidth="@dimen/editor_default_window_width" /> </activity> @@ -64,10 +65,9 @@ android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize|density|keyboard|navigation|screenLayout|uiMode" android:label="@string/godot_project_name_string" android:process=":GodotGame" - android:launchMode="singleTask" + android:launchMode="singleInstance" android:exported="false" - android:screenOrientation="userLandscape" - android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"> + android:screenOrientation="userLandscape"> <layout android:defaultHeight="@dimen/editor_default_window_height" android:defaultWidth="@dimen/editor_default_window_width" /> </activity> 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 489a81fc1a..64d3d4eca1 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 @@ -1,46 +1,48 @@ -/*************************************************************************/ -/* GodotEditor.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* GodotEditor.kt */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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.editor import android.Manifest +import android.app.ActivityManager +import android.content.Context 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.os.* +import android.util.Log import android.widget.Toast import androidx.window.layout.WindowMetricsCalculator import org.godotengine.godot.FullScreenGodotApp +import org.godotengine.godot.GodotLib import org.godotengine.godot.utils.PermissionsUtil +import org.godotengine.godot.utils.ProcessPhoenix import java.util.* import kotlin.math.min @@ -56,20 +58,45 @@ import kotlin.math.min open class GodotEditor : FullScreenGodotApp() { companion object { + private val TAG = GodotEditor::class.java.simpleName + private const val WAIT_FOR_DEBUGGER = false - private const val COMMAND_LINE_PARAMS = "command_line_params" + private const val EXTRA_COMMAND_LINE_PARAMS = "command_line_params" + private const val EDITOR_ID = 777 private const val EDITOR_ARG = "--editor" + private const val EDITOR_ARG_SHORT = "-e" + private const val EDITOR_PROCESS_NAME_SUFFIX = ":GodotEditor" + + private const val GAME_ID = 667 + private const val GAME_PROCESS_NAME_SUFFIX = ":GodotGame" + + private const val PROJECT_MANAGER_ID = 555 private const val PROJECT_MANAGER_ARG = "--project-manager" + private const val PROJECT_MANAGER_ARG_SHORT = "-p" + private const val PROJECT_MANAGER_PROCESS_NAME_SUFFIX = ":GodotProjectManager" + + /** + * Sets of constants to specify the window to use to run the project. + * + * Should match the values in 'editor/editor_settings.cpp' for the + * 'run/window_placement/android_window' setting. + */ + private const val ANDROID_WINDOW_AUTO = 0 + private const val ANDROID_WINDOW_SAME_AS_EDITOR = 1 + private const val ANDROID_WINDOW_SIDE_BY_SIDE_WITH_EDITOR = 2 } private val commandLineParams = ArrayList<String>() override fun onCreate(savedInstanceState: Bundle?) { - PermissionsUtil.requestManifestPermissions(this) + // We exclude certain permissions from the set we request at startup, as they'll be + // requested on demand based on use-cases. + PermissionsUtil.requestManifestPermissions(this, setOf(Manifest.permission.RECORD_AUDIO)) - val params = intent.getStringArrayExtra(COMMAND_LINE_PARAMS) + val params = intent.getStringArrayExtra(EXTRA_COMMAND_LINE_PARAMS) + Log.d(TAG, "Received parameters ${params.contentToString()}") updateCommandLineParams(params) if (BuildConfig.BUILD_TYPE == "dev" && WAIT_FOR_DEBUGGER) { @@ -77,43 +104,69 @@ open class GodotEditor : FullScreenGodotApp() { } super.onCreate(savedInstanceState) + } + + override fun onGodotSetupCompleted() { + super.onGodotSetupCompleted() + val longPressEnabled = enableLongPressGestures() + val panScaleEnabled = enablePanAndScaleGestures() + + checkForProjectPermissionsToEnable() + + runOnUiThread { + // Enable long press, panning and scaling gestures + godotFragment?.renderView?.inputHandler?.apply { + enableLongPress(longPressEnabled) + enablePanningAndScalingGestures(panScaleEnabled) + } + } + } - // Enable long press, panning and scaling gestures - godotFragment?.renderView?.inputHandler?.apply { - enableLongPress(enableLongPressGestures()) - enablePanningAndScalingGestures(enablePanAndScaleGestures()) + /** + * Check for project permissions to enable + */ + protected open fun checkForProjectPermissionsToEnable() { + // Check for RECORD_AUDIO permission + val audioInputEnabled = java.lang.Boolean.parseBoolean(GodotLib.getGlobal("audio/driver/enable_input")); + if (audioInputEnabled) { + PermissionsUtil.requestPermission(Manifest.permission.RECORD_AUDIO, this) } } private fun updateCommandLineParams(args: Array<String>?) { // Update the list of command line params with the new args commandLineParams.clear() - if (args != null && args.isNotEmpty()) { + if (!args.isNullOrEmpty()) { commandLineParams.addAll(listOf(*args)) } + if (BuildConfig.BUILD_TYPE == "dev") { + commandLineParams.add("--benchmark") + } } override fun getCommandLine() = commandLineParams - override fun onNewGodotInstanceRequested(args: Array<String>) { + override fun onNewGodotInstanceRequested(args: Array<String>): Int { // Parse the arguments to figure out which activity to start. var targetClass: Class<*> = GodotGame::class.java + var instanceId = GAME_ID // Whether we should launch the new godot instance in an adjacent window // https://developer.android.com/reference/android/content/Intent#FLAG_ACTIVITY_LAUNCH_ADJACENT - var launchAdjacent = - Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && (isInMultiWindowMode || isLargeScreen) + var launchAdjacent = shouldGameLaunchAdjacent() for (arg in args) { - if (EDITOR_ARG == arg) { + if (EDITOR_ARG == arg || EDITOR_ARG_SHORT == arg) { targetClass = GodotEditor::class.java launchAdjacent = false + instanceId = EDITOR_ID break } - if (PROJECT_MANAGER_ARG == arg) { + if (PROJECT_MANAGER_ARG == arg || PROJECT_MANAGER_ARG_SHORT == arg) { targetClass = GodotProjectManager::class.java launchAdjacent = false + instanceId = PROJECT_MANAGER_ID break } } @@ -121,11 +174,72 @@ open class GodotEditor : FullScreenGodotApp() { // Launch a new activity val newInstance = Intent(this, targetClass) .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - .putExtra(COMMAND_LINE_PARAMS, args) + .putExtra(EXTRA_COMMAND_LINE_PARAMS, args) if (launchAdjacent) { newInstance.addFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT) } - startActivity(newInstance) + if (targetClass == javaClass) { + Log.d(TAG, "Restarting $targetClass with parameters ${args.contentToString()}") + ProcessPhoenix.triggerRebirth(this, newInstance) + } else { + Log.d(TAG, "Starting $targetClass with parameters ${args.contentToString()}") + newInstance.putExtra(EXTRA_NEW_LAUNCH, true) + startActivity(newInstance) + } + return instanceId + } + + override fun onGodotForceQuit(godotInstanceId: Int): Boolean { + val targetClass: Class<*>? + val processNameSuffix: String + when (godotInstanceId) { + GAME_ID -> { + processNameSuffix = GAME_PROCESS_NAME_SUFFIX + targetClass = GodotGame::class.java + } + EDITOR_ID -> { + processNameSuffix = EDITOR_PROCESS_NAME_SUFFIX + targetClass = GodotEditor::class.java + } + PROJECT_MANAGER_ID -> { + processNameSuffix = PROJECT_MANAGER_PROCESS_NAME_SUFFIX + targetClass = GodotProjectManager::class.java + } + else -> { + processNameSuffix = "" + targetClass = null + } + } + + if (targetClass == javaClass) { + Log.d(TAG, "Force quitting $targetClass") + ProcessPhoenix.forceQuit(this) + return true + } + + if (processNameSuffix.isBlank()) { + return false + } + + val activityManager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager + val runningProcesses = activityManager.runningAppProcesses + for (runningProcess in runningProcesses) { + if (runningProcess.processName.endsWith(processNameSuffix)) { + if (targetClass == null) { + // Killing process directly + Log.v(TAG, "Killing Godot process ${runningProcess.processName}") + Process.killProcess(runningProcess.pid) + } else { + // Activity is running; sending a request for self termination. + Log.v(TAG, "Sending force quit request to $targetClass running on process ${runningProcess.processName}") + val forceQuitIntent = Intent(this, targetClass).putExtra(EXTRA_FORCE_QUIT, true) + startActivity(forceQuitIntent) + } + return true + } + } + + return false } // Get the screen's density scale @@ -157,12 +271,34 @@ open class GodotEditor : FullScreenGodotApp() { /** * Enable long press gestures for the Godot Android editor. */ - protected open fun enableLongPressGestures() = true + protected open fun enableLongPressGestures() = + java.lang.Boolean.parseBoolean(GodotLib.getEditorSetting("interface/touchscreen/enable_long_press_as_right_click")) /** * Enable pan and scale gestures for the Godot Android editor. */ - protected open fun enablePanAndScaleGestures() = true + protected open fun enablePanAndScaleGestures() = + java.lang.Boolean.parseBoolean(GodotLib.getEditorSetting("interface/touchscreen/enable_pan_and_scale_gestures")) + + private fun shouldGameLaunchAdjacent(): Boolean { + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + try { + when (Integer.parseInt(GodotLib.getEditorSetting("run/window_placement/android_window"))) { + ANDROID_WINDOW_SAME_AS_EDITOR -> false + ANDROID_WINDOW_SIDE_BY_SIDE_WITH_EDITOR -> true + else -> { + // ANDROID_WINDOW_AUTO + isInMultiWindowMode || isLargeScreen + } + } + } catch (e: NumberFormatException) { + // Fall-back to the 'Auto' behavior + isInMultiWindowMode || isLargeScreen + } + } else { + false + } + } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) diff --git a/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotGame.kt b/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotGame.kt index b9536a7066..aa4d02b5b2 100644 --- a/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotGame.kt +++ b/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotGame.kt @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* GodotGame.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* GodotGame.kt */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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.editor @@ -39,4 +39,9 @@ class GodotGame : GodotEditor() { override fun enableLongPressGestures() = false override fun enablePanAndScaleGestures() = false + + override fun checkForProjectPermissionsToEnable() { + // Nothing to do.. by the time we get here, the project permissions will have already + // been requested by the Editor window. + } } diff --git a/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotProjectManager.kt b/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotProjectManager.kt index bcf4659603..d0e4279eeb 100644 --- a/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotProjectManager.kt +++ b/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotProjectManager.kt @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* GodotProjectManager.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* GodotProjectManager.kt */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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.editor @@ -37,4 +37,9 @@ package org.godotengine.editor * Upon selection of a project, this activity (via its parent logic) starts the * [GodotEditor] activity. */ -class GodotProjectManager : GodotEditor() +class GodotProjectManager : GodotEditor() { + override fun checkForProjectPermissionsToEnable() { + // Nothing to do here.. we have yet to select a project to load. + } +} + diff --git a/platform/android/java/editor/src/main/res/values/dimens.xml b/platform/android/java/editor/src/main/res/values/dimens.xml index 03fb6184d2..98bfe40179 100644 --- a/platform/android/java/editor/src/main/res/values/dimens.xml +++ b/platform/android/java/editor/src/main/res/values/dimens.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> <resources> <dimen name="editor_default_window_height">600dp</dimen> - <dimen name="editor_default_window_width">800dp</dimen> + <dimen name="editor_default_window_width">1024dp</dimen> </resources> 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 837a5d62e1..216d02d9c7 100644 --- a/platform/android/java/editor/src/main/res/values/strings.xml +++ b/platform/android/java/editor/src/main/res/values/strings.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <resources> - <string name="godot_editor_name_string">Godot Editor 4.x</string> + <string name="godot_editor_name_string">Godot Editor 4</string> <string name="denied_storage_permission_error_msg">Missing storage access permission!</string> </resources> diff --git a/platform/android/java/editor/src/main/res/values/themes.xml b/platform/android/java/editor/src/main/res/values/themes.xml new file mode 100644 index 0000000000..fda04d6dc7 --- /dev/null +++ b/platform/android/java/editor/src/main/res/values/themes.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <style name="GodotEditorTheme" parent="@android:style/Theme.Black.NoTitleBar.Fullscreen"> + </style> +</resources> diff --git a/platform/android/java/gradle.properties b/platform/android/java/gradle.properties index 5cd94e85d9..39a0dcda16 100644 --- a/platform/android/java/gradle.properties +++ b/platform/android/java/gradle.properties @@ -24,5 +24,5 @@ org.gradle.jvmargs=-Xmx4536m org.gradle.warning.mode=all # Disable resource optimizations for template release build. -# NOTE: This is turned on for custom build in order to improve the release build. +# NOTE: This is turned on for Godot Editor's gradle builds in order to improve the release build. android.enableResourceOptimizations=false diff --git a/platform/android/java/gradle/wrapper/gradle-wrapper.properties b/platform/android/java/gradle/wrapper/gradle-wrapper.properties index ffed3a254e..aa991fceae 100644 --- a/platform/android/java/gradle/wrapper/gradle-wrapper.properties +++ b/platform/android/java/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/platform/android/java/lib/AndroidManifest.xml b/platform/android/java/lib/AndroidManifest.xml index 79b5aadf2a..f03a1dd47a 100644 --- a/platform/android/java/lib/AndroidManifest.xml +++ b/platform/android/java/lib/AndroidManifest.xml @@ -4,9 +4,6 @@ android:versionCode="1" 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="32" /> - <application> <!-- Records the version of the Godot library --> @@ -23,6 +20,16 @@ android:exported="false" /> + <provider + android:name="androidx.core.content.FileProvider" + android:authorities="${applicationId}.fileprovider" + android:exported="false" + android:grantUriPermissions="true"> + <meta-data + android:name="android.support.FILE_PROVIDER_PATHS" + android:resource="@xml/godot_provider_paths" /> + </provider> + </application> </manifest> diff --git a/platform/android/java/lib/build.gradle b/platform/android/java/lib/build.gradle index c9e2a5d7d2..4340250ad3 100644 --- a/platform/android/java/lib/build.gradle +++ b/platform/android/java/lib/build.gradle @@ -4,7 +4,6 @@ plugins { } ext { - PUBLISH_VERSION = getGodotPublishVersion() PUBLISH_ARTIFACT_ID = 'godot' } @@ -81,19 +80,11 @@ android { release.jniLibs.srcDirs = ['libs/release'] // Editor jni library + editorRelease.jniLibs.srcDirs = ['libs/tools/release'] editorDebug.jniLibs.srcDirs = ['libs/tools/debug'] editorDev.jniLibs.srcDirs = ['libs/tools/dev'] } - // Disable 'editorRelease'. - // The editor can't be used with target=release as debugging tools are then not - // included, and it would crash on errors instead of reporting them. - variantFilter { variant -> - if (variant.name == "editorRelease") { - setIgnore(true) - } - } - libraryVariants.all { variant -> def flavorName = variant.getFlavorName() if (flavorName == null || flavorName == "") { @@ -106,9 +97,14 @@ android { } boolean devBuild = buildType == "dev" + boolean runTests = devBuild + boolean productionBuild = !devBuild + boolean storeRelease = buildType == "release" def sconsTarget = flavorName if (sconsTarget == "template") { + // Tests are not supported on template builds + runTests = false switch (buildType) { case "release": sconsTarget += "_release" @@ -136,10 +132,10 @@ android { def sconsExts = (org.gradle.internal.os.OperatingSystem.current().isWindows() ? [".bat", ".cmd", ".ps1", ".exe"] : [""]) - logger.lifecycle("Looking for $sconsName executable path") + logger.debug("Looking for $sconsName executable path") for (ext in sconsExts) { String sconsNameExt = sconsName + ext - logger.lifecycle("Checking $sconsNameExt") + logger.debug("Checking $sconsNameExt") sconsExecutableFile = org.gradle.internal.os.OperatingSystem.current().findInPath(sconsNameExt) if (sconsExecutableFile != null) { // We're done! @@ -156,7 +152,7 @@ android { if (sconsExecutableFile == null) { throw new GradleException("Unable to find executable path for the '$sconsName' command.") } else { - logger.lifecycle("Found executable path for $sconsName: ${sconsExecutableFile.absolutePath}") + logger.debug("Found executable path for $sconsName: ${sconsExecutableFile.absolutePath}") } for (String selectedAbi : selectedAbis) { @@ -168,7 +164,7 @@ android { def taskName = getSconsTaskName(flavorName, buildType, selectedAbi) tasks.create(name: taskName, type: Exec) { executable sconsExecutableFile.absolutePath - args "--directory=${pathToRootDir}", "platform=android", "dev_mode=${devBuild}", "dev_build=${devBuild}", "target=${sconsTarget}", "arch=${selectedAbi}", "-j" + Runtime.runtime.availableProcessors() + args "--directory=${pathToRootDir}", "platform=android", "store_release=${storeRelease}", "production=${productionBuild}", "dev_mode=${devBuild}", "dev_build=${devBuild}", "tests=${runTests}", "target=${sconsTarget}", "arch=${selectedAbi}", "-j" + Runtime.runtime.availableProcessors() } // Schedule the tasks so the generated libs are present before the aar file is packaged. @@ -176,11 +172,10 @@ android { } } - // TODO: Enable when issues with AGP 7.1+ are resolved (https://github.com/GodotVR/godot_openxr/issues/187). -// publishing { -// singleVariant("templateRelease") { -// withSourcesJar() -// withJavadocJar() -// } -// } + publishing { + singleVariant("templateRelease") { + withSourcesJar() + withJavadocJar() + } + } } diff --git a/platform/android/java/lib/res/values/strings.xml b/platform/android/java/lib/res/values/strings.xml index f5a4ab1071..03752e092e 100644 --- a/platform/android/java/lib/res/values/strings.xml +++ b/platform/android/java/lib/res/values/strings.xml @@ -14,6 +14,7 @@ <string name="text_button_cancel_verify">Cancel Verification</string> <string name="text_error_title">Error!</string> <string name="error_engine_setup_message">Unable to setup the Godot Engine! Aborting…</string> + <string name="error_missing_vulkan_requirements_message">Warning - this device does not meet the requirements for Vulkan support</string> <!-- APK Expansion Strings --> @@ -48,7 +49,7 @@ <string name="state_failed_unlicensed">Download failed because you may not have purchased this app</string> <string name="state_failed_fetching_url">Download failed because the resources could not be found</string> <string name="state_failed_sdcard_full">Download failed because the external storage is full</string> - <string name="state_failed_cancelled">Download cancelled</string> + <string name="state_failed_cancelled">Download canceled</string> <string name="state_failed">Download failed</string> <string name="kilobytes_per_second">%1$s KB/s</string> diff --git a/platform/android/java/lib/res/xml/godot_provider_paths.xml b/platform/android/java/lib/res/xml/godot_provider_paths.xml new file mode 100644 index 0000000000..8ad16da879 --- /dev/null +++ b/platform/android/java/lib/res/xml/godot_provider_paths.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8"?> +<paths xmlns:android="http://schemas.android.com/apk/res/android"> + + <files-path + name="filesRoot" + path="/" /> + + <external-path + name="public" + path="." /> + + <external-files-path + name="app" + path="." /> +</paths> diff --git a/platform/android/java/lib/src/org/godotengine/godot/Dictionary.java b/platform/android/java/lib/src/org/godotengine/godot/Dictionary.java index afe82cd8f3..699e19fcf0 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/Dictionary.java +++ b/platform/android/java/lib/src/org/godotengine/godot/Dictionary.java @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* Dictionary.java */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* Dictionary.java */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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; diff --git a/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java b/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java index f21f88db0a..3e975449d8 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java +++ b/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* FullScreenGodotApp.java */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* FullScreenGodotApp.java */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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; @@ -51,6 +51,9 @@ import androidx.fragment.app.FragmentActivity; public abstract class FullScreenGodotApp extends FragmentActivity implements GodotHost { private static final String TAG = FullScreenGodotApp.class.getSimpleName(); + protected static final String EXTRA_FORCE_QUIT = "force_quit_requested"; + protected static final String EXTRA_NEW_LAUNCH = "new_launch_requested"; + @Nullable private Godot godotFragment; @@ -59,6 +62,8 @@ public abstract class FullScreenGodotApp extends FragmentActivity implements God super.onCreate(savedInstanceState); setContentView(R.layout.godot_app_layout); + handleStartIntent(getIntent(), true); + Fragment currentFragment = getSupportFragmentManager().findFragmentById(R.id.godot_fragment_container); if (currentFragment instanceof Godot) { Log.v(TAG, "Reusing existing Godot fragment instance."); @@ -74,38 +79,70 @@ public abstract class FullScreenGodotApp extends FragmentActivity implements God public void onDestroy() { Log.v(TAG, "Destroying Godot app..."); super.onDestroy(); - onGodotForceQuit(godotFragment); + terminateGodotInstance(godotFragment); } @Override public final void onGodotForceQuit(Godot instance) { + runOnUiThread(() -> { + terminateGodotInstance(instance); + }); + } + + private void terminateGodotInstance(Godot instance) { if (instance == godotFragment) { Log.v(TAG, "Force quitting Godot instance"); - ProcessPhoenix.forceQuit(this); + ProcessPhoenix.forceQuit(FullScreenGodotApp.this); } } @Override public final void onGodotRestartRequested(Godot instance) { - if (instance == godotFragment) { - // It's very hard to properly de-initialize Godot on Android to restart the game - // from scratch. Therefore, we need to kill the whole app process and relaunch it. - // - // Restarting only the activity, wouldn't be enough unless it did proper cleanup (including - // releasing and reloading native libs or resetting their state somehow and clearing statics). - Log.v(TAG, "Restarting Godot instance..."); - ProcessPhoenix.triggerRebirth(this); - } + runOnUiThread(() -> { + if (instance == godotFragment) { + // It's very hard to properly de-initialize Godot on Android to restart the game + // from scratch. Therefore, we need to kill the whole app process and relaunch it. + // + // Restarting only the activity, wouldn't be enough unless it did proper cleanup (including + // releasing and reloading native libs or resetting their state somehow and clearing static data). + Log.v(TAG, "Restarting Godot instance..."); + ProcessPhoenix.triggerRebirth(FullScreenGodotApp.this); + } + }); } @Override public void onNewIntent(Intent intent) { super.onNewIntent(intent); + setIntent(intent); + + handleStartIntent(intent, false); + if (godotFragment != null) { godotFragment.onNewIntent(intent); } } + private void handleStartIntent(Intent intent, boolean newLaunch) { + boolean forceQuitRequested = intent.getBooleanExtra(EXTRA_FORCE_QUIT, false); + if (forceQuitRequested) { + Log.d(TAG, "Force quit requested, terminating.."); + ProcessPhoenix.forceQuit(this); + return; + } + + if (!newLaunch) { + boolean newLaunchRequested = intent.getBooleanExtra(EXTRA_NEW_LAUNCH, false); + if (newLaunchRequested) { + Log.d(TAG, "New launch requested, restarting.."); + + Intent restartIntent = new Intent(intent).putExtra(EXTRA_NEW_LAUNCH, false); + ProcessPhoenix.triggerRebirth(this, restartIntent); + return; + } + } + } + @CallSuper @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { 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 92e5e59496..748a1c41fd 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/Godot.java +++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.java @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* Godot.java */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* Godot.java */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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; @@ -39,6 +39,7 @@ 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; +import org.godotengine.godot.utils.BenchmarkUtils; import org.godotengine.godot.utils.GodotNetUtils; import org.godotengine.godot.utils.PermissionsUtil; import org.godotengine.godot.xr.XRMode; @@ -74,15 +75,20 @@ import android.util.Log; import android.view.Display; import android.view.LayoutInflater; import android.view.Surface; +import android.view.SurfaceView; import android.view.View; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; +import android.view.ViewTreeObserver; import android.view.Window; +import android.view.WindowInsets; +import android.view.WindowInsetsAnimation; import android.view.WindowManager; import android.widget.Button; import android.widget.FrameLayout; import android.widget.ProgressBar; import android.widget.TextView; +import android.widget.Toast; import androidx.annotation.CallSuper; import androidx.annotation.Keep; @@ -175,6 +181,8 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC public GodotIO io; public GodotNetUtils netUtils; public GodotTTS tts; + private DirectoryAccessHandler directoryAccessHandler; + private FileAccessHandler fileAccessHandler; public interface ResultCallback { void callback(int requestCode, int resultCode, Intent data); @@ -257,28 +265,34 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC */ @Keep private boolean onVideoInit() { - final Activity activity = getActivity(); + final Activity activity = requireActivity(); containerLayout = new FrameLayout(activity); containerLayout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); // GodotEditText layout GodotEditText editText = new GodotEditText(activity); - editText.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, + editText.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, (int)getResources().getDimension(R.dimen.text_edit_height))); // ...add to FrameLayout containerLayout.addView(editText); - if (!GodotLib.setup(command_line)) { + tts = new GodotTTS(activity); + + if (!GodotLib.setup(command_line, tts)) { Log.e(TAG, "Unable to setup the Godot engine! Aborting..."); alert(R.string.error_engine_setup_message, R.string.text_error_title, this::forceQuit); return false; } - final String renderer = GodotLib.getGlobal("rendering/renderer/rendering_method"); - if (renderer.equals("gl_compatibility")) { - mRenderView = new GodotGLRenderView(activity, this, xrMode, use_debug_opengl); - } else { + if (usesVulkan()) { + if (!meetsVulkanRequirements(activity.getPackageManager())) { + alert(R.string.error_missing_vulkan_requirements_message, R.string.text_error_title, this::forceQuit); + return false; + } mRenderView = new GodotVulkanRenderView(activity, this); + } else { + // Fallback to openGl + mRenderView = new GodotGLRenderView(activity, this, xrMode, use_debug_opengl); } View view = mRenderView.getView(); @@ -286,20 +300,70 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC editText.setView(mRenderView); io.setEdit(editText); - view.getViewTreeObserver().addOnGlobalLayoutListener(() -> { - Point fullSize = new Point(); - activity.getWindowManager().getDefaultDisplay().getSize(fullSize); - Rect gameSize = new Rect(); - mRenderView.getView().getWindowVisibleDisplayFrame(gameSize); - final int keyboardHeight = fullSize.y - gameSize.bottom; - GodotLib.setVirtualKeyboardHeight(keyboardHeight); - }); + // Listeners for keyboard height. + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + // Report the height of virtual keyboard as it changes during the animation. + final View decorView = activity.getWindow().getDecorView(); + decorView.setWindowInsetsAnimationCallback(new WindowInsetsAnimation.Callback(WindowInsetsAnimation.Callback.DISPATCH_MODE_STOP) { + int startBottom, endBottom; + @Override + public void onPrepare(@NonNull WindowInsetsAnimation animation) { + startBottom = decorView.getRootWindowInsets().getInsets(WindowInsets.Type.ime()).bottom; + } + + @NonNull + @Override + public WindowInsetsAnimation.Bounds onStart(@NonNull WindowInsetsAnimation animation, @NonNull WindowInsetsAnimation.Bounds bounds) { + endBottom = decorView.getRootWindowInsets().getInsets(WindowInsets.Type.ime()).bottom; + return bounds; + } + + @NonNull + @Override + public WindowInsets onProgress(@NonNull WindowInsets windowInsets, @NonNull List<WindowInsetsAnimation> list) { + // Find the IME animation. + WindowInsetsAnimation imeAnimation = null; + for (WindowInsetsAnimation animation : list) { + if ((animation.getTypeMask() & WindowInsets.Type.ime()) != 0) { + imeAnimation = animation; + break; + } + } + // Update keyboard height based on IME animation. + if (imeAnimation != null) { + float interpolatedFraction = imeAnimation.getInterpolatedFraction(); + // Linear interpolation between start and end values. + float keyboardHeight = startBottom * (1.0f - interpolatedFraction) + endBottom * interpolatedFraction; + GodotLib.setVirtualKeyboardHeight((int)keyboardHeight); + } + return windowInsets; + } + + @Override + public void onEnd(@NonNull WindowInsetsAnimation animation) { + } + }); + } else { + // Infer the virtual keyboard height using visible area. + view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { + // Don't allocate a new Rect every time the callback is called. + final Rect visibleSize = new Rect(); + + @Override + public void onGlobalLayout() { + final SurfaceView view = mRenderView.getView(); + view.getWindowVisibleDisplayFrame(visibleSize); + final int keyboardHeight = view.getHeight() - visibleSize.bottom; + GodotLib.setVirtualKeyboardHeight(keyboardHeight); + } + }); + } mRenderView.queueOnRenderThread(() -> { for (GodotPlugin plugin : pluginRegistry.getAllPlugins()) { plugin.onRegisterPluginWithGodotNative(); } - setKeepScreenOn("True".equals(GodotLib.getGlobal("display/window/energy_saving/keep_screen_on"))); + setKeepScreenOn(Boolean.parseBoolean(GodotLib.getGlobal("display/window/energy_saving/keep_screen_on"))); }); // Include the returned non-null views in the Godot view hierarchy. @@ -316,6 +380,36 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC return true; } + /** + * Returns true if `Vulkan` is used for rendering. + */ + private boolean usesVulkan() { + final String renderer = GodotLib.getGlobal("rendering/renderer/rendering_method"); + final String renderingDevice = GodotLib.getGlobal("rendering/rendering_device/driver"); + return ("forward_plus".equals(renderer) || "mobile".equals(renderer)) && "vulkan".equals(renderingDevice); + } + + /** + * Returns true if the device meets the base requirements for Vulkan support, false otherwise. + */ + private boolean meetsVulkanRequirements(@Nullable PackageManager packageManager) { + if (packageManager == null) { + return false; + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + if (!packageManager.hasSystemFeature(PackageManager.FEATURE_VULKAN_HARDWARE_LEVEL, 1)) { + // Optional requirements.. log as warning if missing + Log.w(TAG, "The vulkan hardware level does not meet the minimum requirement: 1"); + } + + // Check for api version 1.0 + return packageManager.hasSystemFeature(PackageManager.FEATURE_VULKAN_HARDWARE_VERSION, 0x400003); + } + + return false; + } + public void setKeepScreenOn(final boolean p_enabled) { runOnUiThread(() -> { if (p_enabled) { @@ -347,11 +441,9 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC } public void restart() { - runOnUiThread(() -> { - if (godotHost != null) { - godotHost.onGodotRestartRequested(this); - } - }); + if (godotHost != null) { + godotHost.onGodotRestartRequested(this); + } } public void alert(final String message, final String title) { @@ -432,7 +524,7 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC } return cmdline; } catch (Exception e) { - e.printStackTrace(); + // The _cl_ file can be missing with no adverse effect return new String[0]; } } @@ -486,10 +578,9 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC final Activity activity = getActivity(); io = new GodotIO(activity); netUtils = new GodotNetUtils(activity); - tts = new GodotTTS(activity); Context context = getContext(); - DirectoryAccessHandler directoryAccessHandler = new DirectoryAccessHandler(context); - FileAccessHandler fileAccessHandler = new FileAccessHandler(context); + directoryAccessHandler = new DirectoryAccessHandler(context); + fileAccessHandler = new FileAccessHandler(context); mSensorManager = (SensorManager)activity.getSystemService(Context.SENSOR_SERVICE); mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); mGravity = mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY); @@ -503,8 +594,7 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC netUtils, directoryAccessHandler, fileAccessHandler, - use_apk_expansion, - tts); + use_apk_expansion); result_callback = null; } @@ -517,6 +607,7 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC @Override public void onCreate(Bundle icicle) { + BenchmarkUtils.beginBenchmarkMeasure("Godot::onCreate"); super.onCreate(icicle); final Activity activity = getActivity(); @@ -565,6 +656,18 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC editor.apply(); i++; + } else if (command_line[i].equals("--benchmark")) { + BenchmarkUtils.setUseBenchmark(true); + new_args.add(command_line[i]); + } else if (has_extra && command_line[i].equals("--benchmark-file")) { + BenchmarkUtils.setUseBenchmark(true); + new_args.add(command_line[i]); + + // Retrieve the filepath + BenchmarkUtils.setBenchmarkFile(command_line[i + 1]); + new_args.add(command_line[i + 1]); + + i++; } else if (command_line[i].trim().length() != 0) { new_args.add(command_line[i]); } @@ -635,6 +738,7 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC mCurrentIntent = activity.getIntent(); initializeGodot(); + BenchmarkUtils.endBenchmarkMeasure("Godot::onCreate"); } @Override @@ -840,20 +944,6 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC // Do something here if sensor accuracy changes. } - /* - @Override public boolean dispatchKeyEvent(KeyEvent event) { - if (event.getKeyCode()==KeyEvent.KEYCODE_BACK) { - System.out.printf("** BACK REQUEST!\n"); - - GodotLib.quit(); - return true; - } - System.out.printf("** OTHER KEY!\n"); - - return false; - } - */ - public void onBackPressed() { boolean shouldQuit = true; @@ -888,11 +978,20 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC private void forceQuit() { // TODO: This is a temp solution. The proper fix will involve tracking down and properly shutting down each // native Godot components that is started in Godot#onVideoInit. - runOnUiThread(() -> { - if (godotHost != null) { - godotHost.onGodotForceQuit(this); - } - }); + forceQuit(0); + } + + @Keep + private boolean forceQuit(int instanceId) { + if (godotHost == null) { + return false; + } + if (instanceId == 0) { + godotHost.onGodotForceQuit(this); + return true; + } else { + return godotHost.onGodotForceQuit(instanceId); + } } private boolean obbIsCorrupted(String f, String main_pack_md5) { @@ -947,6 +1046,11 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC return PermissionsUtil.getGrantedPermissions(getActivity()); } + @Keep + private String getCACertificates() { + return GodotNetUtils.getCACertificates(); + } + /** * The download state should trigger changes in the UI --- it may be useful * to show the state as being indeterminate at times. This sample can be @@ -1051,11 +1155,35 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC } @Keep - private void createNewGodotInstance(String[] args) { - runOnUiThread(() -> { - if (godotHost != null) { - godotHost.onNewGodotInstanceRequested(args); - } - }); + public DirectoryAccessHandler getDirectoryAccessHandler() { + return directoryAccessHandler; + } + + @Keep + public FileAccessHandler getFileAccessHandler() { + return fileAccessHandler; + } + + @Keep + private int createNewGodotInstance(String[] args) { + if (godotHost != null) { + return godotHost.onNewGodotInstanceRequested(args); + } + return 0; + } + + @Keep + private void beginBenchmarkMeasure(String label) { + BenchmarkUtils.beginBenchmarkMeasure(label); + } + + @Keep + private void endBenchmarkMeasure(String label) { + BenchmarkUtils.endBenchmarkMeasure(label); + } + + @Keep + private void dumpBenchmark(String benchmarkFile) { + BenchmarkUtils.dumpBenchmark(fileAccessHandler, benchmarkFile); } } diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java b/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java index c6c5b4953d..d447e449e1 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* GodotDownloaderAlarmReceiver.java */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* GodotDownloaderAlarmReceiver.java */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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; diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderService.java b/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderService.java index 90a046a7a7..8e3fb85cde 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderService.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderService.java @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* GodotDownloaderService.java */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* GodotDownloaderService.java */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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; diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java b/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java index 3dfc37f6b0..b465377743 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* GodotGLRenderView.java */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* GodotGLRenderView.java */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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; import org.godotengine.godot.gl.GLSurfaceView; @@ -43,8 +43,13 @@ import org.godotengine.godot.xr.regular.RegularFallbackConfigChooser; import android.annotation.SuppressLint; import android.content.Context; +import android.content.res.AssetManager; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; import android.graphics.PixelFormat; import android.os.Build; +import android.text.TextUtils; +import android.util.SparseArray; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.PointerIcon; @@ -52,6 +57,8 @@ import android.view.SurfaceView; import androidx.annotation.Keep; +import java.io.InputStream; + /** * A simple GLSurfaceView sub-class that demonstrate how to perform * OpenGL ES 2.0 rendering into a GL Surface. Note the following important @@ -61,7 +68,7 @@ import androidx.annotation.Keep; * See ContextFactory class definition below. * * - The class must use a custom EGLConfigChooser to be able to select - * an EGLConfig that supports 2.0. This is done by providing a config + * an EGLConfig that supports 3.0. This is done by providing a config * specification to eglChooseConfig() that has the attribute * EGL10.ELG_RENDERABLE_TYPE containing the EGL_OPENGL_ES2_BIT flag * set. See ConfigChooser class definition below. @@ -74,6 +81,7 @@ public class GodotGLRenderView extends GLSurfaceView implements GodotRenderView private final Godot godot; private final GodotInputHandler inputHandler; private final GodotRenderer godotRenderer; + private final SparseArray<PointerIcon> customPointerIcons = new SparseArray<>(); public GodotGLRenderView(Context context, Godot godot, XRMode xrMode, boolean p_use_debug_opengl) { super(context); @@ -158,8 +166,10 @@ public class GodotGLRenderView extends GLSurfaceView implements GodotRenderView @Override public void requestPointerCapture() { - super.requestPointerCapture(); - inputHandler.onPointerCaptureChange(true); + if (canCapturePointer()) { + super.requestPointerCapture(); + inputHandler.onPointerCaptureChange(true); + } } @Override @@ -169,12 +179,49 @@ public class GodotGLRenderView extends GLSurfaceView implements GodotRenderView } /** + * Used to configure the PointerIcon for the given type. + * + * Called from JNI + */ + @Keep + @Override + public void configurePointerIcon(int pointerType, String imagePath, float hotSpotX, float hotSpotY) { + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) { + try { + Bitmap bitmap = null; + if (!TextUtils.isEmpty(imagePath)) { + if (godot.getDirectoryAccessHandler().filesystemFileExists(imagePath)) { + // Try to load the bitmap from the file system + bitmap = BitmapFactory.decodeFile(imagePath); + } else if (godot.getDirectoryAccessHandler().assetsFileExists(imagePath)) { + // Try to load the bitmap from the assets directory + AssetManager am = getContext().getAssets(); + InputStream imageInputStream = am.open(imagePath); + bitmap = BitmapFactory.decodeStream(imageInputStream); + } + } + + PointerIcon customPointerIcon = PointerIcon.create(bitmap, hotSpotX, hotSpotY); + customPointerIcons.put(pointerType, customPointerIcon); + } catch (Exception e) { + // Reset the custom pointer icon + customPointerIcons.delete(pointerType); + } + } + } + + /** * called from JNI to change pointer icon */ @Keep + @Override public void setPointerIcon(int pointerType) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - setPointerIcon(PointerIcon.getSystemIcon(getContext(), pointerType)); + PointerIcon pointerIcon = customPointerIcons.get(pointerType); + if (pointerIcon == null) { + pointerIcon = PointerIcon.getSystemIcon(getContext(), pointerType); + } + setPointerIcon(pointerIcon); } } diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotHost.java b/platform/android/java/lib/src/org/godotengine/godot/GodotHost.java index 2e7b67194f..7700b9b628 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotHost.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotHost.java @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* GodotHost.java */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* GodotHost.java */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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; @@ -55,21 +55,35 @@ public interface GodotHost { default void onGodotMainLoopStarted() {} /** - * Invoked on the UI thread as the last step of the Godot instance clean up phase. + * Invoked on the render thread to terminate the given Godot instance. */ default void onGodotForceQuit(Godot instance) {} /** - * Invoked on the UI thread when the Godot instance wants to be restarted. It's up to the host + * Invoked on the render thread to terminate the Godot instance with the given id. + * @param godotInstanceId id of the Godot instance to terminate. See {@code onNewGodotInstanceRequested} + * + * @return true if successful, false otherwise. + */ + default boolean onGodotForceQuit(int godotInstanceId) { + return false; + } + + /** + * Invoked on the render thread when the Godot instance wants to be restarted. It's up to the host * to perform the appropriate action(s). */ default void onGodotRestartRequested(Godot instance) {} /** - * Invoked on the UI thread when a new Godot instance is requested. It's up to the host to + * Invoked on the render thread when a new Godot instance is requested. It's up to the host to * perform the appropriate action(s). * * @param args Arguments used to initialize the new instance. + * + * @return the id of the new instance. See {@code onGodotForceQuit} */ - default void onNewGodotInstanceRequested(String[] args) {} + default int onNewGodotInstanceRequested(String[] args) { + return 0; + } } 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 d283de8ce8..edcd9c4d1f 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* GodotIO.java */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* GodotIO.java */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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; @@ -49,6 +49,9 @@ import android.view.Display; import android.view.DisplayCutout; import android.view.WindowInsets; +import androidx.core.content.FileProvider; + +import java.io.File; import java.util.List; import java.util.Locale; @@ -84,29 +87,42 @@ public class GodotIO { // MISCELLANEOUS OS IO ///////////////////////// - public int openURI(String p_uri) { + public int openURI(String uriString) { try { - String path = p_uri; - String type = ""; - if (path.startsWith("/")) { - //absolute path to filesystem, prepend file:// - path = "file://" + path; - if (p_uri.endsWith(".png") || p_uri.endsWith(".jpg") || p_uri.endsWith(".gif") || p_uri.endsWith(".webp")) { - type = "image/*"; + Uri dataUri; + String dataType = ""; + boolean grantReadUriPermission = false; + + if (uriString.startsWith("/") || uriString.startsWith("file://")) { + String filePath = uriString; + // File uris needs to be provided via the FileProvider + grantReadUriPermission = true; + if (filePath.startsWith("file://")) { + filePath = filePath.replace("file://", ""); } + + File targetFile = new File(filePath); + dataUri = FileProvider.getUriForFile(activity, activity.getPackageName() + ".fileprovider", targetFile); + dataType = activity.getContentResolver().getType(dataUri); + } else { + dataUri = Uri.parse(uriString); } Intent intent = new Intent(); intent.setAction(Intent.ACTION_VIEW); - if (!type.equals("")) { - intent.setDataAndType(Uri.parse(path), type); + if (TextUtils.isEmpty(dataType)) { + intent.setData(dataUri); } else { - intent.setData(Uri.parse(path)); + intent.setDataAndType(dataUri, dataType); + } + if (grantReadUriPermission) { + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); } activity.startActivity(intent); return 0; } catch (ActivityNotFoundException e) { + Log.e(TAG, "Unable to open uri " + uriString, e); return 1; } } @@ -150,7 +166,6 @@ public class GodotIO { } else { selectedScaledDensity = 0.75f; } - Log.d(TAG, "Selected scaled density: " + selectedScaledDensity); return selectedScaledDensity; } 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 33896ecb95..c725b1a7c9 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* GodotLib.java */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* GodotLib.java */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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; @@ -61,8 +61,7 @@ public class GodotLib { GodotNetUtils netUtils, DirectoryAccessHandler directoryAccessHandler, FileAccessHandler fileAccessHandler, - boolean use_apk_expansion, - GodotTTS tts); + boolean use_apk_expansion); /** * Invoked on the main thread to clean up Godot native layer. @@ -74,7 +73,7 @@ public class GodotLib { * Invoked on the GL thread to complete setup for the Godot native layer logic. * @param p_cmdline Command line arguments used to configure Godot native layer components. */ - public static native boolean setup(String[] p_cmdline); + public static native boolean setup(String[] p_cmdline, GodotTTS tts); /** * Invoked on the GL thread when the underlying Android surface has changed size. @@ -148,7 +147,7 @@ public class GodotLib { /** * Forward regular key events. */ - public static native void key(int p_keycode, int p_physical_keycode, int p_unicode, boolean p_pressed); + public static native void key(int p_physical_keycode, int p_unicode, int p_key_label, boolean p_pressed); /** * Forward game device's key events. @@ -190,6 +189,13 @@ public class GodotLib { public static native String getGlobal(String p_key); /** + * Used to access Godot's editor settings. + * @param settingKey Setting key + * @return String value of the setting + */ + public static native String getEditorSetting(String settingKey); + + /** * Invoke method |p_method| on the Godot object specified by |p_id| * @param p_id Id of the Godot object to invoke * @param p_method Name of the method to invoke diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java b/platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java index cb63fd885f..00243dab2a 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* GodotRenderView.java */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* GodotRenderView.java */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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; @@ -48,5 +48,11 @@ public interface GodotRenderView { GodotInputHandler getInputHandler(); + void configurePointerIcon(int pointerType, String imagePath, float hotSpotX, float hotSpotY); + void setPointerIcon(int pointerType); + + default boolean canCapturePointer() { + return getInputHandler().canCapturePointer(); + } } diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java b/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java index 0becf00d93..681e182adb 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* GodotVulkanRenderView.java */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* GodotVulkanRenderView.java */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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; @@ -36,7 +36,12 @@ import org.godotengine.godot.vulkan.VkSurfaceView; import android.annotation.SuppressLint; import android.content.Context; +import android.content.res.AssetManager; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; import android.os.Build; +import android.text.TextUtils; +import android.util.SparseArray; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.PointerIcon; @@ -44,10 +49,13 @@ import android.view.SurfaceView; import androidx.annotation.Keep; +import java.io.InputStream; + public class GodotVulkanRenderView extends VkSurfaceView implements GodotRenderView { private final Godot godot; private final GodotInputHandler mInputHandler; private final VkRenderer mRenderer; + private final SparseArray<PointerIcon> customPointerIcons = new SparseArray<>(); public GodotVulkanRenderView(Context context, Godot godot) { super(context); @@ -126,8 +134,10 @@ public class GodotVulkanRenderView extends VkSurfaceView implements GodotRenderV @Override public void requestPointerCapture() { - super.requestPointerCapture(); - mInputHandler.onPointerCaptureChange(true); + if (canCapturePointer()) { + super.requestPointerCapture(); + mInputHandler.onPointerCaptureChange(true); + } } @Override @@ -143,12 +153,49 @@ public class GodotVulkanRenderView extends VkSurfaceView implements GodotRenderV } /** + * Used to configure the PointerIcon for the given type. + * + * Called from JNI + */ + @Keep + @Override + public void configurePointerIcon(int pointerType, String imagePath, float hotSpotX, float hotSpotY) { + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) { + try { + Bitmap bitmap = null; + if (!TextUtils.isEmpty(imagePath)) { + if (godot.getDirectoryAccessHandler().filesystemFileExists(imagePath)) { + // Try to load the bitmap from the file system + bitmap = BitmapFactory.decodeFile(imagePath); + } else if (godot.getDirectoryAccessHandler().assetsFileExists(imagePath)) { + // Try to load the bitmap from the assets directory + AssetManager am = getContext().getAssets(); + InputStream imageInputStream = am.open(imagePath); + bitmap = BitmapFactory.decodeStream(imageInputStream); + } + } + + PointerIcon customPointerIcon = PointerIcon.create(bitmap, hotSpotX, hotSpotY); + customPointerIcons.put(pointerType, customPointerIcon); + } catch (Exception e) { + // Reset the custom pointer icon + customPointerIcons.delete(pointerType); + } + } + } + + /** * called from JNI to change pointer icon */ @Keep + @Override public void setPointerIcon(int pointerType) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - setPointerIcon(PointerIcon.getSystemIcon(getContext(), pointerType)); + PointerIcon pointerIcon = customPointerIcons.get(pointerType); + if (pointerIcon == null) { + pointerIcon = PointerIcon.getSystemIcon(getContext(), pointerType); + } + setPointerIcon(pointerIcon); } } diff --git a/platform/android/java/lib/src/org/godotengine/godot/gl/GodotRenderer.java b/platform/android/java/lib/src/org/godotengine/godot/gl/GodotRenderer.java index 5c4fd00f6d..9d44d8826c 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/gl/GodotRenderer.java +++ b/platform/android/java/lib/src/org/godotengine/godot/gl/GodotRenderer.java @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* GodotRenderer.java */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* GodotRenderer.java */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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.gl; diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java index 7925b54fc4..a7064dfc1d 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* GodotEditText.java */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* GodotEditText.java */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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.input; @@ -127,7 +127,9 @@ public class GodotEditText extends EditText { edit.setText(""); edit.append(text); if (msg.arg2 != -1) { - edit.setSelection(msg.arg1, msg.arg2); + int selectionStart = Math.min(msg.arg1, edit.length()); + int selectionEnd = Math.min(msg.arg2, edit.length()); + edit.setSelection(selectionStart, selectionEnd); edit.mInputWrapper.setSelection(true); } else { edit.mInputWrapper.setSelection(false); diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.kt b/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.kt index a7a57621de..e26c9d39c2 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.kt +++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.kt @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* GodotGestureHandler.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* GodotGestureHandler.kt */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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.input @@ -77,7 +77,7 @@ internal class GodotGestureHandler : SimpleOnGestureListener(), OnScaleGestureLi } private fun contextClickRouter(event: MotionEvent) { - if (scaleInProgress) { + if (scaleInProgress || nextDownIsDoubleTap) { return } @@ -134,40 +134,24 @@ internal class GodotGestureHandler : SimpleOnGestureListener(), OnScaleGestureLi } private fun onActionUp(event: MotionEvent): Boolean { + if (event.actionMasked == MotionEvent.ACTION_CANCEL && pointerCaptureInProgress) { + // Don't dispatch the ACTION_CANCEL while a capture is in progress + return true + } + val sourceMouseRelative = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { event.isFromSource(InputDevice.SOURCE_MOUSE_RELATIVE) } else { false } - when { - pointerCaptureInProgress -> { - return if (event.actionMasked == MotionEvent.ACTION_CANCEL) { - // Don't dispatch the ACTION_CANCEL while a capture is in progress - true - } else { - GodotInputHandler.handleMouseEvent( - MotionEvent.ACTION_UP, - event.buttonState, - event.x, - event.y, - 0f, - 0f, - false, - sourceMouseRelative - ) - pointerCaptureInProgress = false - true - } - } - dragInProgress -> { - GodotInputHandler.handleMotionEvent(event) - dragInProgress = false - return true - } - contextClickInProgress -> { + + if (pointerCaptureInProgress || dragInProgress || contextClickInProgress) { + if (contextClickInProgress || GodotInputHandler.isMouseEvent(event)) { + // This may be an ACTION_BUTTON_RELEASE event which we don't handle, + // so we convert it to an ACTION_UP event. GodotInputHandler.handleMouseEvent( - event.actionMasked, - 0, + MotionEvent.ACTION_UP, + event.buttonState, event.x, event.y, 0f, @@ -175,11 +159,16 @@ internal class GodotGestureHandler : SimpleOnGestureListener(), OnScaleGestureLi false, sourceMouseRelative ) - contextClickInProgress = false - return true + } else { + GodotInputHandler.handleTouchEvent(event) } - else -> return false + pointerCaptureInProgress = false + dragInProgress = false + contextClickInProgress = false + return true } + + return false } private fun onActionMove(event: MotionEvent): Boolean { @@ -208,7 +197,10 @@ internal class GodotGestureHandler : SimpleOnGestureListener(), OnScaleGestureLi if (event.actionMasked == MotionEvent.ACTION_UP) { nextDownIsDoubleTap = false GodotInputHandler.handleMotionEvent(event) + } else if (event.actionMasked == MotionEvent.ACTION_MOVE && panningAndScalingEnabled == false) { + GodotInputHandler.handleMotionEvent(event) } + return true } @@ -235,42 +227,43 @@ internal class GodotGestureHandler : SimpleOnGestureListener(), OnScaleGestureLi ) dragInProgress = false } - return true } - dragInProgress = true - val x = terminusEvent.x val y = terminusEvent.y - if (terminusEvent.pointerCount >= 2 && panningAndScalingEnabled) { + if (terminusEvent.pointerCount >= 2 && panningAndScalingEnabled && !pointerCaptureInProgress && !dragInProgress) { GodotLib.pan(x, y, distanceX / 5f, distanceY / 5f) - } else { + } else if (!scaleInProgress){ + dragInProgress = true GodotInputHandler.handleMotionEvent(terminusEvent) } return true } - override fun onScale(detector: ScaleGestureDetector?): Boolean { - if (detector == null || !panningAndScalingEnabled) { + override fun onScale(detector: ScaleGestureDetector): Boolean { + if (!panningAndScalingEnabled || pointerCaptureInProgress || dragInProgress) { return false } - GodotLib.magnify( - detector.focusX, - detector.focusY, - detector.scaleFactor - ) + + if (detector.scaleFactor >= 0.8f && detector.scaleFactor != 1f && detector.scaleFactor <= 1.2f) { + GodotLib.magnify( + detector.focusX, + detector.focusY, + detector.scaleFactor + ) + } return true } - override fun onScaleBegin(detector: ScaleGestureDetector?): Boolean { - if (detector == null || !panningAndScalingEnabled) { + override fun onScaleBegin(detector: ScaleGestureDetector): Boolean { + if (!panningAndScalingEnabled || pointerCaptureInProgress || dragInProgress) { return false } scaleInProgress = true return true } - override fun onScaleEnd(detector: ScaleGestureDetector?) { + override fun onScaleEnd(detector: ScaleGestureDetector) { scaleInProgress = false } } diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java index d2f3c5aed2..317344f2a5 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* GodotInputHandler.java */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* GodotInputHandler.java */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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.input; @@ -66,6 +66,11 @@ public class GodotInputHandler implements InputManager.InputDeviceListener { private final ScaleGestureDetector scaleGestureDetector; private final GodotGestureHandler godotGestureHandler; + /** + * Used to decide whether mouse capture can be enabled. + */ + private int lastSeenToolType = MotionEvent.TOOL_TYPE_UNKNOWN; + public GodotInputHandler(GodotRenderView godotView) { final Context context = godotView.getView().getContext(); mRenderView = godotView; @@ -105,6 +110,10 @@ public class GodotInputHandler implements InputManager.InputDeviceListener { return (source & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK || (source & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD || (source & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD; } + public boolean canCapturePointer() { + return lastSeenToolType == MotionEvent.TOOL_TYPE_MOUSE; + } + public void onPointerCaptureChange(boolean hasCapture) { godotGestureHandler.onPointerCaptureChange(hasCapture); } @@ -129,12 +138,10 @@ public class GodotInputHandler implements InputManager.InputDeviceListener { } } else { // getKeyCode(): The physical key that was pressed. - // Godot's keycodes match the ASCII codes, so for single byte unicode characters, - // we can use the unmodified unicode character to determine Godot's keycode. - final int keycode = event.getUnicodeChar(0); final int physical_keycode = event.getKeyCode(); final int unicode = event.getUnicodeChar(); - GodotLib.key(keycode, physical_keycode, unicode, false); + final int key_label = event.getDisplayLabel(); + GodotLib.key(physical_keycode, unicode, key_label, false); }; return true; @@ -166,16 +173,18 @@ public class GodotInputHandler implements InputManager.InputDeviceListener { GodotLib.joybutton(godotJoyId, button, true); } } else { - final int keycode = event.getUnicodeChar(0); final int physical_keycode = event.getKeyCode(); final int unicode = event.getUnicodeChar(); - GodotLib.key(keycode, physical_keycode, unicode, true); + final int key_label = event.getDisplayLabel(); + GodotLib.key(physical_keycode, unicode, key_label, true); } return true; } public boolean onTouchEvent(final MotionEvent event) { + lastSeenToolType = event.getToolType(0); + this.scaleGestureDetector.onTouchEvent(event); if (this.gestureDetector.onTouchEvent(event)) { // The gesture detector has handled the event. @@ -200,6 +209,8 @@ public class GodotInputHandler implements InputManager.InputDeviceListener { } public boolean onGenericMotionEvent(MotionEvent event) { + lastSeenToolType = event.getToolType(0); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && gestureDetector.onGenericMotionEvent(event)) { // The gesture detector has handled the event. return true; @@ -245,7 +256,7 @@ public class GodotInputHandler implements InputManager.InputDeviceListener { } return true; } - } else if (isMouseEvent(event)) { + } else { return handleMouseEvent(event); } @@ -422,7 +433,7 @@ public class GodotInputHandler implements InputManager.InputDeviceListener { } private static boolean isMouseEvent(int eventSource) { - boolean mouseSource = ((eventSource & InputDevice.SOURCE_MOUSE) == InputDevice.SOURCE_MOUSE) || ((eventSource & InputDevice.SOURCE_STYLUS) == InputDevice.SOURCE_STYLUS); + boolean mouseSource = ((eventSource & InputDevice.SOURCE_MOUSE) == InputDevice.SOURCE_MOUSE) || ((eventSource & (InputDevice.SOURCE_TOUCHSCREEN | InputDevice.SOURCE_STYLUS)) == InputDevice.SOURCE_STYLUS); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { mouseSource = mouseSource || ((eventSource & InputDevice.SOURCE_MOUSE_RELATIVE) == InputDevice.SOURCE_MOUSE_RELATIVE); } @@ -473,12 +484,27 @@ public class GodotInputHandler implements InputManager.InputDeviceListener { } static boolean handleMouseEvent(int eventAction, int buttonsMask, float x, float y, float deltaX, float deltaY, boolean doubleClick, boolean sourceMouseRelative) { + // Fix the buttonsMask switch (eventAction) { case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: // Zero-up the button state buttonsMask = 0; - // FALL THROUGH + break; + case MotionEvent.ACTION_DOWN: + case MotionEvent.ACTION_MOVE: + if (buttonsMask == 0) { + buttonsMask = MotionEvent.BUTTON_PRIMARY; + } + break; + } + + // We don't handle ACTION_BUTTON_PRESS and ACTION_BUTTON_RELEASE events as they typically + // follow ACTION_DOWN and ACTION_UP events. As such, handling them would result in duplicate + // stream of events to the engine. + switch (eventAction) { + case MotionEvent.ACTION_CANCEL: + case MotionEvent.ACTION_UP: case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_HOVER_ENTER: case MotionEvent.ACTION_HOVER_EXIT: diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java index 01ad5ee415..f48dba56df 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* GodotTextInputWrapper.java */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* GodotTextInputWrapper.java */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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.input; @@ -93,8 +93,8 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene @Override public void beforeTextChanged(final CharSequence pCharSequence, final int start, final int count, final int after) { for (int i = 0; i < count; ++i) { - GodotLib.key(0, KeyEvent.KEYCODE_DEL, 0, true); - GodotLib.key(0, KeyEvent.KEYCODE_DEL, 0, false); + GodotLib.key(KeyEvent.KEYCODE_DEL, 0, 0, true); + GodotLib.key(KeyEvent.KEYCODE_DEL, 0, 0, false); if (mHasSelection) { mHasSelection = false; @@ -110,13 +110,13 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene newChars[i - start] = pCharSequence.charAt(i); } for (int i = 0; i < count; ++i) { - int key = newChars[i]; - if ((key == '\n') && !(mEdit.getKeyboardType() == GodotEditText.VirtualKeyboardType.KEYBOARD_TYPE_MULTILINE)) { + final int character = newChars[i]; + if ((character == '\n') && !(mEdit.getKeyboardType() == GodotEditText.VirtualKeyboardType.KEYBOARD_TYPE_MULTILINE)) { // Return keys are handled through action events continue; } - GodotLib.key(key, 0, key, true); - GodotLib.key(key, 0, key, false); + GodotLib.key(0, character, 0, true); + GodotLib.key(0, character, 0, false); } } @@ -124,19 +124,20 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene public boolean onEditorAction(final TextView pTextView, final int pActionID, final KeyEvent pKeyEvent) { if (mEdit == pTextView && isFullScreenEdit() && pKeyEvent != null) { final String characters = pKeyEvent.getCharacters(); - - for (int i = 0; i < characters.length(); i++) { - final int ch = characters.codePointAt(i); - GodotLib.key(ch, 0, ch, true); - GodotLib.key(ch, 0, ch, false); + if (characters != null) { + for (int i = 0; i < characters.length(); i++) { + final int character = characters.codePointAt(i); + GodotLib.key(0, character, 0, true); + GodotLib.key(0, character, 0, false); + } } } if (pActionID == EditorInfo.IME_ACTION_DONE) { // Enter key has been pressed mRenderView.queueOnRenderThread(() -> { - GodotLib.key(0, KeyEvent.KEYCODE_ENTER, 0, true); - GodotLib.key(0, KeyEvent.KEYCODE_ENTER, 0, false); + GodotLib.key(KeyEvent.KEYCODE_ENTER, 0, 0, true); + GodotLib.key(KeyEvent.KEYCODE_ENTER, 0, 0, false); }); mRenderView.getView().requestFocus(); return true; diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/Joystick.java b/platform/android/java/lib/src/org/godotengine/godot/input/Joystick.java index bace516b33..9e13a1aca6 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/Joystick.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/Joystick.java @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* Joystick.java */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* Joystick.java */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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.input; 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 index c9282dd247..8ee3d5f48f 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/io/StorageScope.kt +++ b/platform/android/java/lib/src/org/godotengine/godot/io/StorageScope.kt @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* StorageScope.kt */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 @@ -76,6 +76,13 @@ internal enum class StorageScope { return UNKNOWN } + // If we have 'All Files Access' permission, we can access all directories without + // restriction. + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R + && Environment.isExternalStorageManager()) { + return APP + } + val canonicalPathFile = pathFile.canonicalPath if (internalAppDir != null && canonicalPathFile.startsWith(internalAppDir)) { @@ -90,6 +97,11 @@ internal enum class StorageScope { return APP } + val rootDir: String? = System.getenv("ANDROID_ROOT") + if (rootDir != null && canonicalPathFile.startsWith(rootDir)) { + 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 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 index 098b10ae36..b9b7ebac6e 100644 --- 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 @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* AssetsDirectoryAccess.kt */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 @@ -64,7 +64,7 @@ internal class AssetsDirectoryAccess(context: Context) : DirectoryAccessHandler. override fun hasDirId(dirId: Int) = dirs.indexOfKey(dirId) >= 0 override fun dirOpen(path: String): Int { - val assetsPath = getAssetsPath(path) ?: return INVALID_DIR_ID + val assetsPath = getAssetsPath(path) try { val files = assetManager.list(assetsPath) ?: return INVALID_DIR_ID // Empty directories don't get added to the 'assets' directory, so @@ -99,7 +99,7 @@ internal class AssetsDirectoryAccess(context: Context) : DirectoryAccessHandler. } override fun fileExists(path: String): Boolean { - val assetsPath = getAssetsPath(path) ?: return false + val assetsPath = getAssetsPath(path) try { val files = assetManager.list(assetsPath) ?: return false // Empty directories don't get added to the 'assets' directory, so 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 index fedcf4843f..dd6d5180c5 100644 --- 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 @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* DirectoryAccessHandler.kt */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 @@ -79,6 +79,9 @@ class DirectoryAccessHandler(context: Context) { private val assetsDirAccess = AssetsDirectoryAccess(context) private val fileSystemDirAccess = FilesystemDirectoryAccess(context) + fun assetsFileExists(assetsPath: String) = assetsDirAccess.fileExists(assetsPath) + fun filesystemFileExists(path: String) = fileSystemDirAccess.fileExists(path) + private fun hasDirId(accessType: AccessType, dirId: Int): Boolean { return when (accessType) { ACCESS_RESOURCES -> assetsDirAccess.hasDirId(dirId) 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 index 54fc56fa3e..c8b4f79f30 100644 --- 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 @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* FilesystemDirectoryAccess.kt */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 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 index f23537a29e..0f447f0b05 100644 --- 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 @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* DataAccess.kt */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 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 index c6b242a4b6..38974af753 100644 --- 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 @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* FileAccessFlags.kt */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 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 index 83da3a24b3..984bf607d0 100644 --- 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 @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* FileAccessHandler.kt */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 @@ -46,7 +46,7 @@ class FileAccessHandler(val context: Context) { private val TAG = FileAccessHandler::class.java.simpleName private const val FILE_NOT_FOUND_ERROR_ID = -1 - private const val INVALID_FILE_ID = 0 + internal const val INVALID_FILE_ID = 0 private const val STARTING_FILE_ID = 1 internal fun fileExists(context: Context, storageScopeIdentifier: StorageScope.Identifier, path: String?): Boolean { @@ -96,13 +96,17 @@ class FileAccessHandler(val context: Context) { private fun hasFileId(fileId: Int) = files.indexOfKey(fileId) >= 0 fun fileOpen(path: String?, modeFlags: Int): Int { + val accessFlag = FileAccessFlags.fromNativeModeFlags(modeFlags) ?: return INVALID_FILE_ID + return fileOpen(path, accessFlag) + } + + internal fun fileOpen(path: String?, accessFlag: FileAccessFlags): 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) 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 index 5af694ad99..f2c0577c21 100644 --- 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 @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* FileData.kt */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 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 index 81a7dd1705..5410eed727 100644 --- 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 @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* MediaStoreData.kt */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 diff --git a/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java b/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java index bb5042fa09..48aa231c7a 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java +++ b/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* GodotPlugin.java */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* GodotPlugin.java */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ package org.godotengine.godot.plugin; @@ -71,11 +71,11 @@ import javax.microedition.khronos.opengles.GL10; * - 'plugin.init.ClassFullName' is the full name (package + class name) of the plugin class * extending {@link GodotPlugin}. * - * A plugin can also define and provide c/c++ gdnative libraries and nativescripts for the target + * A plugin can also define and provide c/c++ gdextension libraries and nativescripts for the target * app/game to leverage. - * The shared library for the gdnative library will be automatically bundled by the aar build + * The shared library for the gdextension library will be automatically bundled by the aar build * system. - * Godot '*.gdnlib' and '*.gdns' resource files must however be manually defined in the project + * Godot '*.gdextension' resource files must however be manually defined in the project * 'assets' directory. The recommended path for these resources in the 'assets' directory should be: * 'godot/plugin/v1/[PluginName]/' */ @@ -112,7 +112,7 @@ public abstract class GodotPlugin { public final void onRegisterPluginWithGodotNative() { registeredSignals.putAll( registerPluginWithGodotNative(this, getPluginName(), getPluginMethods(), getPluginSignals(), - getPluginGDNativeLibrariesPaths())); + getPluginGDExtensionLibrariesPaths())); } /** @@ -124,7 +124,7 @@ public abstract class GodotPlugin { GodotPluginInfoProvider pluginInfoProvider) { registerPluginWithGodotNative(pluginObject, pluginInfoProvider.getPluginName(), Collections.emptyList(), pluginInfoProvider.getPluginSignals(), - pluginInfoProvider.getPluginGDNativeLibrariesPaths()); + pluginInfoProvider.getPluginGDExtensionLibrariesPaths()); // Notify that registration is complete. pluginInfoProvider.onPluginRegistered(); @@ -132,7 +132,7 @@ public abstract class GodotPlugin { private static Map<String, SignalInfo> registerPluginWithGodotNative(Object pluginObject, String pluginName, List<String> pluginMethods, Set<SignalInfo> pluginSignals, - Set<String> pluginGDNativeLibrariesPaths) { + Set<String> pluginGDExtensionLibrariesPaths) { nativeRegisterSingleton(pluginName, pluginObject); Set<Method> filteredMethods = new HashSet<>(); @@ -176,9 +176,9 @@ public abstract class GodotPlugin { registeredSignals.put(signalName, signalInfo); } - // Get the list of gdnative libraries to register. - if (!pluginGDNativeLibrariesPaths.isEmpty()) { - nativeRegisterGDNativeLibraries(pluginGDNativeLibrariesPaths.toArray(new String[0])); + // Get the list of gdextension libraries to register. + if (!pluginGDExtensionLibrariesPaths.isEmpty()) { + nativeRegisterGDExtensionLibraries(pluginGDExtensionLibrariesPaths.toArray(new String[0])); } return registeredSignals; @@ -304,12 +304,12 @@ public abstract class GodotPlugin { } /** - * Returns the paths for the plugin's gdnative libraries. + * Returns the paths for the plugin's gdextension libraries. * - * The paths must be relative to the 'assets' directory and point to a '*.gdnlib' file. + * The paths must be relative to the 'assets' directory and point to a '*.gdextension' file. */ @NonNull - protected Set<String> getPluginGDNativeLibrariesPaths() { + protected Set<String> getPluginGDExtensionLibrariesPaths() { return Collections.emptySet(); } @@ -420,10 +420,10 @@ public abstract class GodotPlugin { private static native void nativeRegisterMethod(String p_sname, String p_name, String p_ret, String[] p_params); /** - * Used to register gdnative libraries bundled by the plugin. - * @param gdnlibPaths Paths to the libraries relative to the 'assets' directory. + * Used to register gdextension libraries bundled by the plugin. + * @param gdextensionPaths Paths to the libraries relative to the 'assets' directory. */ - private static native void nativeRegisterGDNativeLibraries(String[] gdnlibPaths); + private static native void nativeRegisterGDExtensionLibraries(String[] gdextensionPaths); /** * Used to complete registration of the {@link GodotPlugin} instance's methods. diff --git a/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginInfoProvider.java b/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginInfoProvider.java index cfb84c3931..63999a8321 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginInfoProvider.java +++ b/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginInfoProvider.java @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* GodotPluginInfoProvider.java */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* GodotPluginInfoProvider.java */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ package org.godotengine.godot.plugin; @@ -54,12 +54,12 @@ public interface GodotPluginInfoProvider { } /** - * Returns the paths for the plugin's gdnative libraries (if any). + * Returns the paths for the plugin's gdextension libraries (if any). * - * The paths must be relative to the 'assets' directory and point to a '*.gdnlib' file. + * The paths must be relative to the 'assets' directory and point to a '*.gdextension' file. */ @NonNull - default Set<String> getPluginGDNativeLibrariesPaths() { + default Set<String> getPluginGDExtensionLibrariesPaths() { return Collections.emptySet(); } diff --git a/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginRegistry.java b/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginRegistry.java index 502ea0507d..c2428de2e1 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginRegistry.java +++ b/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginRegistry.java @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* GodotPluginRegistry.java */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* GodotPluginRegistry.java */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ package org.godotengine.godot.plugin; diff --git a/platform/android/java/lib/src/org/godotengine/godot/plugin/SignalInfo.java b/platform/android/java/lib/src/org/godotengine/godot/plugin/SignalInfo.java index 8c7faaa75e..4a166112ab 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/plugin/SignalInfo.java +++ b/platform/android/java/lib/src/org/godotengine/godot/plugin/SignalInfo.java @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* SignalInfo.java */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* SignalInfo.java */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ package org.godotengine.godot.plugin; diff --git a/platform/android/java/lib/src/org/godotengine/godot/plugin/UsedByGodot.java b/platform/android/java/lib/src/org/godotengine/godot/plugin/UsedByGodot.java index dc912af63c..8beb28ab9a 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/plugin/UsedByGodot.java +++ b/platform/android/java/lib/src/org/godotengine/godot/plugin/UsedByGodot.java @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* UsedByGodot.java */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* UsedByGodot.java */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ package org.godotengine.godot.plugin; diff --git a/platform/android/java/lib/src/org/godotengine/godot/tts/GodotTTS.java b/platform/android/java/lib/src/org/godotengine/godot/tts/GodotTTS.java index 2239ddac8e..edace53e7f 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/tts/GodotTTS.java +++ b/platform/android/java/lib/src/org/godotengine/godot/tts/GodotTTS.java @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* GodotTTS.java */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* GodotTTS.java */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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.tts; @@ -62,8 +62,9 @@ public class GodotTTS extends UtteranceProgressListener { final private static int EVENT_CANCEL = 2; final private static int EVENT_BOUNDARY = 3; - final private TextToSpeech synth; - final private LinkedList<GodotUtterance> queue; + final private Activity activity; + private TextToSpeech synth; + private LinkedList<GodotUtterance> queue; final private Object lock = new Object(); private GodotUtterance lastUtterance; @@ -71,10 +72,7 @@ public class GodotTTS extends UtteranceProgressListener { private boolean paused; public GodotTTS(Activity p_activity) { - synth = new TextToSpeech(p_activity, null); - queue = new LinkedList<GodotUtterance>(); - - synth.setOnUtteranceProgressListener(this); + activity = p_activity; } private void updateTTS() { @@ -187,6 +185,16 @@ public class GodotTTS extends UtteranceProgressListener { } /** + * Initialize synth and query. + */ + public void init() { + synth = new TextToSpeech(activity, null); + queue = new LinkedList<GodotUtterance>(); + + synth.setOnUtteranceProgressListener(this); + } + + /** * Adds an utterance to the queue. */ public void speak(String text, String voice, int volume, float pitch, float rate, int utterance_id, boolean interrupt) { diff --git a/platform/android/java/lib/src/org/godotengine/godot/tts/GodotUtterance.java b/platform/android/java/lib/src/org/godotengine/godot/tts/GodotUtterance.java index bde37e7315..8128716f8c 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/tts/GodotUtterance.java +++ b/platform/android/java/lib/src/org/godotengine/godot/tts/GodotUtterance.java @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* GodotUtterance.java */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* GodotUtterance.java */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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.tts; diff --git a/platform/android/java/lib/src/org/godotengine/godot/utils/BenchmarkUtils.kt b/platform/android/java/lib/src/org/godotengine/godot/utils/BenchmarkUtils.kt new file mode 100644 index 0000000000..1552c8f082 --- /dev/null +++ b/platform/android/java/lib/src/org/godotengine/godot/utils/BenchmarkUtils.kt @@ -0,0 +1,122 @@ +/**************************************************************************/ +/* BenchmarkUtils.kt */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ + +@file:JvmName("BenchmarkUtils") + +package org.godotengine.godot.utils + +import android.os.Build +import android.os.SystemClock +import android.os.Trace +import android.util.Log +import org.godotengine.godot.BuildConfig +import org.godotengine.godot.io.file.FileAccessFlags +import org.godotengine.godot.io.file.FileAccessHandler +import org.json.JSONObject +import java.nio.ByteBuffer +import java.util.concurrent.ConcurrentSkipListMap + +/** + * Contains benchmark related utilities methods + */ +private const val TAG = "GodotBenchmark" + +var useBenchmark = false +var benchmarkFile = "" + +private val startBenchmarkFrom = ConcurrentSkipListMap<String, Long>() +private val benchmarkTracker = ConcurrentSkipListMap<String, Double>() + +/** + * Start measuring and tracing the execution of a given section of code using the given label. + * + * Must be followed by a call to [endBenchmarkMeasure]. + * + * Note: Only enabled on 'editorDev' build variant. + */ +fun beginBenchmarkMeasure(label: String) { + if (BuildConfig.FLAVOR != "editor" || BuildConfig.BUILD_TYPE != "dev") { + return + } + startBenchmarkFrom[label] = SystemClock.elapsedRealtime() + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + Trace.beginAsyncSection(label, 0) + } +} + +/** + * End measuring and tracing of the section of code with the given label. + * + * Must be preceded by a call [beginBenchmarkMeasure] + * + * * Note: Only enabled on 'editorDev' build variant. + */ +fun endBenchmarkMeasure(label: String) { + if (BuildConfig.FLAVOR != "editor" || BuildConfig.BUILD_TYPE != "dev") { + return + } + val startTime = startBenchmarkFrom[label] ?: return + val total = SystemClock.elapsedRealtime() - startTime + benchmarkTracker[label] = total / 1000.0 + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + Trace.endAsyncSection(label, 0) + } +} + +/** + * Dump the benchmark measurements. + * If [filepath] is valid, the data is also written in json format to the specified file. + * + * * Note: Only enabled on 'editorDev' build variant. + */ +@JvmOverloads +fun dumpBenchmark(fileAccessHandler: FileAccessHandler?, filepath: String? = benchmarkFile) { + if (BuildConfig.FLAVOR != "editor" || BuildConfig.BUILD_TYPE != "dev") { + return + } + if (!useBenchmark) { + return + } + + val printOut = + benchmarkTracker.map { "\t- ${it.key} : ${it.value} sec." }.joinToString("\n") + Log.i(TAG, "BENCHMARK:\n$printOut") + + if (fileAccessHandler != null && !filepath.isNullOrBlank()) { + val fileId = fileAccessHandler.fileOpen(filepath, FileAccessFlags.WRITE) + if (fileId != FileAccessHandler.INVALID_FILE_ID) { + val jsonOutput = JSONObject(benchmarkTracker.toMap()).toString(4) + fileAccessHandler.fileWrite(fileId, ByteBuffer.wrap(jsonOutput.toByteArray())) + fileAccessHandler.fileClose(fileId) + } + } +} diff --git a/platform/android/java/lib/src/org/godotengine/godot/utils/Crypt.java b/platform/android/java/lib/src/org/godotengine/godot/utils/Crypt.java index 47df23fe1a..315ca2b25d 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/utils/Crypt.java +++ b/platform/android/java/lib/src/org/godotengine/godot/utils/Crypt.java @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* Crypt.java */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* Crypt.java */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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.utils; diff --git a/platform/android/java/lib/src/org/godotengine/godot/utils/GLUtils.java b/platform/android/java/lib/src/org/godotengine/godot/utils/GLUtils.java index 4525c5c212..7db02968bb 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/utils/GLUtils.java +++ b/platform/android/java/lib/src/org/godotengine/godot/utils/GLUtils.java @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* GLUtils.java */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* GLUtils.java */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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.utils; diff --git a/platform/android/java/lib/src/org/godotengine/godot/utils/GodotNetUtils.java b/platform/android/java/lib/src/org/godotengine/godot/utils/GodotNetUtils.java index a17092d3bd..c31d56a3e1 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/utils/GodotNetUtils.java +++ b/platform/android/java/lib/src/org/godotengine/godot/utils/GodotNetUtils.java @@ -1,43 +1,49 @@ -/*************************************************************************/ -/* GodotNetUtils.java */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* GodotNetUtils.java */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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.utils; import android.app.Activity; import android.content.Context; import android.net.wifi.WifiManager; +import android.util.Base64; import android.util.Log; +import java.io.StringWriter; +import java.security.KeyStore; +import java.security.cert.X509Certificate; +import java.util.Enumeration; + /** * This class handles Android-specific networking functions. - * For now, it only provides access to WifiManager.MulticastLock, which is needed on some devices + * It provides access to the CA certificates KeyStore, and the WifiManager.MulticastLock, which is needed on some devices * to receive broadcast and multicast packets. */ public class GodotNetUtils { @@ -79,4 +85,34 @@ public class GodotNetUtils { Log.e("Godot", "Exception during multicast lock release: " + e); } } + + /** + * Retrieves the list of trusted CA certificates from the "AndroidCAStore" and returns them in PRM format. + * @see https://developer.android.com/reference/java/security/KeyStore . + * @return A string of concatenated X509 certificates in PEM format. + */ + public static String getCACertificates() { + try { + KeyStore ks = KeyStore.getInstance("AndroidCAStore"); + StringBuilder writer = new StringBuilder(); + + if (ks != null) { + ks.load(null, null); + Enumeration<String> aliases = ks.aliases(); + + while (aliases.hasMoreElements()) { + String alias = (String)aliases.nextElement(); + + X509Certificate cert = (X509Certificate)ks.getCertificate(alias); + writer.append("-----BEGIN CERTIFICATE-----\n"); + writer.append(Base64.encodeToString(cert.getEncoded(), Base64.DEFAULT)); + writer.append("-----END CERTIFICATE-----\n"); + } + } + return writer.toString(); + } catch (Exception e) { + Log.e("Godot", "Exception while reading CA certificates: " + e); + return ""; + } + } } diff --git a/platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java b/platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java index 57db0709f0..a94188c405 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 @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* PermissionsUtil.java */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* PermissionsUtil.java */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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.utils; @@ -42,10 +42,12 @@ import android.os.Environment; import android.provider.Settings; import android.util.Log; +import androidx.annotation.Nullable; import androidx.core.content.ContextCompat; import java.util.ArrayList; import java.util.List; +import java.util.Set; /** * This class includes utility functions for Android permissions related operations. @@ -58,6 +60,7 @@ public final class PermissionsUtil { static final int REQUEST_CAMERA_PERMISSION = 2; static final int REQUEST_VIBRATE_PERMISSION = 3; public static final int REQUEST_ALL_PERMISSION_REQ_CODE = 1001; + public static final int REQUEST_SINGLE_PERMISSION_REQ_CODE = 1002; public static final int REQUEST_MANAGE_EXTERNAL_STORAGE_REQ_CODE = 2002; private PermissionsUtil() { @@ -65,31 +68,57 @@ public final class PermissionsUtil { /** * Request a dangerous permission. name must be specified in <a href="https://github.com/aosp-mirror/platform_frameworks_base/blob/master/core/res/AndroidManifest.xml">this</a> - * @param name the name of the requested permission. + * @param permissionName the name of the requested permission. * @param activity the caller activity for this method. * @return true/false. "true" if permission was granted otherwise returns "false". */ - public static boolean requestPermission(String name, Activity activity) { + public static boolean requestPermission(String permissionName, Activity activity) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { // Not necessary, asked on install already return true; } - if (name.equals("RECORD_AUDIO") && ContextCompat.checkSelfPermission(activity, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) { - activity.requestPermissions(new String[] { Manifest.permission.RECORD_AUDIO }, REQUEST_RECORD_AUDIO_PERMISSION); - return false; - } + switch (permissionName) { + case "RECORD_AUDIO": + case Manifest.permission.RECORD_AUDIO: + if (ContextCompat.checkSelfPermission(activity, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) { + activity.requestPermissions(new String[] { Manifest.permission.RECORD_AUDIO }, REQUEST_RECORD_AUDIO_PERMISSION); + return false; + } + return true; - if (name.equals("CAMERA") && ContextCompat.checkSelfPermission(activity, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { - activity.requestPermissions(new String[] { Manifest.permission.CAMERA }, REQUEST_CAMERA_PERMISSION); - return false; - } + case "CAMERA": + case Manifest.permission.CAMERA: + if (ContextCompat.checkSelfPermission(activity, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { + activity.requestPermissions(new String[] { Manifest.permission.CAMERA }, REQUEST_CAMERA_PERMISSION); + return false; + } + return true; - if (name.equals("VIBRATE") && ContextCompat.checkSelfPermission(activity, Manifest.permission.VIBRATE) != PackageManager.PERMISSION_GRANTED) { - activity.requestPermissions(new String[] { Manifest.permission.VIBRATE }, REQUEST_VIBRATE_PERMISSION); - return false; + case "VIBRATE": + case Manifest.permission.VIBRATE: + if (ContextCompat.checkSelfPermission(activity, Manifest.permission.VIBRATE) != PackageManager.PERMISSION_GRANTED) { + activity.requestPermissions(new String[] { Manifest.permission.VIBRATE }, REQUEST_VIBRATE_PERMISSION); + return false; + } + return true; + + default: + // Check if the given permission is a dangerous permission + try { + PermissionInfo permissionInfo = getPermissionInfo(activity, permissionName); + int protectionLevel = Build.VERSION.SDK_INT >= Build.VERSION_CODES.P ? permissionInfo.getProtection() : permissionInfo.protectionLevel; + if (protectionLevel == PermissionInfo.PROTECTION_DANGEROUS && ContextCompat.checkSelfPermission(activity, permissionName) != PackageManager.PERMISSION_GRANTED) { + activity.requestPermissions(new String[] { permissionName }, REQUEST_SINGLE_PERMISSION_REQ_CODE); + return false; + } + } catch (PackageManager.NameNotFoundException e) { + // Unknown permission - return false as it can't be granted. + Log.w(TAG, "Unable to identify permission " + permissionName, e); + return false; + } + return true; } - return true; } /** @@ -98,6 +127,16 @@ public final class PermissionsUtil { * @return true/false. "true" if all permissions were granted otherwise returns "false". */ public static boolean requestManifestPermissions(Activity activity) { + return requestManifestPermissions(activity, null); + } + + /** + * Request dangerous permissions which are defined in the Android manifest file from the user. + * @param activity the caller activity for this method. + * @param excludes Set of permissions to exclude from the request + * @return true/false. "true" if all permissions were granted otherwise returns "false". + */ + public static boolean requestManifestPermissions(Activity activity, @Nullable Set<String> excludes) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { return true; } @@ -115,6 +154,9 @@ public final class PermissionsUtil { List<String> requestedPermissions = new ArrayList<>(); for (String manifestPermission : manifestPermissions) { + if (excludes != null && excludes.contains(manifestPermission)) { + continue; + } try { if (manifestPermission.equals(Manifest.permission.MANAGE_EXTERNAL_STORAGE)) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && !Environment.isExternalStorageManager()) { diff --git a/platform/android/java/lib/src/org/godotengine/godot/utils/ProcessPhoenix.java b/platform/android/java/lib/src/org/godotengine/godot/utils/ProcessPhoenix.java index 2cc37b627a..b1bce45fbb 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/utils/ProcessPhoenix.java +++ b/platform/android/java/lib/src/org/godotengine/godot/utils/ProcessPhoenix.java @@ -90,7 +90,7 @@ public final class ProcessPhoenix extends Activity { */ public static void forceQuit(Activity activity, int pid) { Process.killProcess(pid); // Kill original main process - activity.finish(); + activity.finishAndRemoveTask(); Runtime.getRuntime().exit(0); // Kill kill kill! } @@ -120,7 +120,7 @@ public final class ProcessPhoenix extends Activity { /** * Checks if the current process is a temporary Phoenix Process. - * This can be used to avoid initialisation of unused resources or to prevent running code that + * This can be used to avoid initialization of unused resources or to prevent running code that * is not multi-process ready. * * @return true if the current process is a temporary Phoenix Process diff --git a/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkRenderer.kt b/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkRenderer.kt index 07e22bbcd2..6f09f51d4c 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkRenderer.kt +++ b/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkRenderer.kt @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* VkRenderer.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* VkRenderer.kt */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ @file:JvmName("VkRenderer") package org.godotengine.godot.vulkan diff --git a/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkSurfaceView.kt b/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkSurfaceView.kt index 1581665195..3828004198 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkSurfaceView.kt +++ b/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkSurfaceView.kt @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* VkSurfaceView.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* VkSurfaceView.kt */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ @file:JvmName("VkSurfaceView") package org.godotengine.godot.vulkan diff --git a/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkThread.kt b/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkThread.kt index 5ab437f364..4aba0c370d 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkThread.kt +++ b/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkThread.kt @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* VkThread.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* VkThread.kt */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ @file:JvmName("VkThread") package org.godotengine.godot.vulkan diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/XRMode.java b/platform/android/java/lib/src/org/godotengine/godot/xr/XRMode.java index 2cc049de15..2c2c9f39d6 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/xr/XRMode.java +++ b/platform/android/java/lib/src/org/godotengine/godot/xr/XRMode.java @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* XRMode.java */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* XRMode.java */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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.xr; diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrConfigChooser.java b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrConfigChooser.java index e35d4f5828..942e57308c 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrConfigChooser.java +++ b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrConfigChooser.java @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* OvrConfigChooser.java */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* OvrConfigChooser.java */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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.xr.ovr; diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrContextFactory.java b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrContextFactory.java index deb9c4bb1d..1f1034dacf 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrContextFactory.java +++ b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrContextFactory.java @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* OvrContextFactory.java */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* OvrContextFactory.java */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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.xr.ovr; diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrWindowSurfaceFactory.java b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrWindowSurfaceFactory.java index f087b7dc74..60774eb241 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrWindowSurfaceFactory.java +++ b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrWindowSurfaceFactory.java @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* OvrWindowSurfaceFactory.java */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* OvrWindowSurfaceFactory.java */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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.xr.ovr; diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java index 445238b1c2..147b4ea676 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java +++ b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* RegularConfigChooser.java */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* RegularConfigChooser.java */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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.xr.regular; @@ -45,20 +45,18 @@ public class RegularConfigChooser implements GLSurfaceView.EGLConfigChooser { private int[] mValue = new int[1]; - // FIXME: Add support for Vulkan. - - /* This EGL config specification is used to specify 2.0 rendering. + /* This EGL config specification is used to specify 3.0 rendering. * We use a minimum size of 4 bits for red/green/blue, but will * perform actual matching in chooseConfig() below. */ private static int EGL_OPENGL_ES2_BIT = 4; - private static int[] s_configAttribs2 = { + private static int[] s_configAttribs = { EGL10.EGL_RED_SIZE, 4, EGL10.EGL_GREEN_SIZE, 4, EGL10.EGL_BLUE_SIZE, 4, - // EGL10.EGL_DEPTH_SIZE, 16, + // EGL10.EGL_DEPTH_SIZE, 16, // EGL10.EGL_STENCIL_SIZE, EGL10.EGL_DONT_CARE, - EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, //apparently there is no EGL_OPENGL_ES3_BIT EGL10.EGL_NONE }; @@ -75,7 +73,7 @@ public class RegularConfigChooser implements GLSurfaceView.EGLConfigChooser { /* Get the number of minimally matching EGL configurations */ int[] num_config = new int[1]; - egl.eglChooseConfig(display, s_configAttribs2, null, 0, num_config); + egl.eglChooseConfig(display, s_configAttribs, null, 0, num_config); int numConfigs = num_config[0]; @@ -86,7 +84,7 @@ public class RegularConfigChooser implements GLSurfaceView.EGLConfigChooser { /* Allocate then read the array of minimally matching EGL configs */ EGLConfig[] configs = new EGLConfig[numConfigs]; - egl.eglChooseConfig(display, s_configAttribs2, configs, numConfigs, num_config); + egl.eglChooseConfig(display, s_configAttribs, configs, numConfigs, num_config); if (GLUtils.DEBUG) { GLUtils.printConfigs(egl, display, configs); diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java index 5d62723170..1a126ff765 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java +++ b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* RegularContextFactory.java */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* RegularContextFactory.java */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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.xr.regular; @@ -52,17 +52,16 @@ public class RegularContextFactory implements GLSurfaceView.EGLContextFactory { private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098; public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) { - // FIXME: Add support for Vulkan. - Log.w(TAG, "creating OpenGL ES 2.0 context :"); + Log.w(TAG, "creating OpenGL ES 3.0 context :"); GLUtils.checkEglError(TAG, "Before eglCreateContext", egl); EGLContext context; if (GLUtils.use_debug_opengl) { - int[] attrib_list2 = { EGL_CONTEXT_CLIENT_VERSION, 2, _EGL_CONTEXT_FLAGS_KHR, _EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR, EGL10.EGL_NONE }; - context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list2); + int[] attrib_list = { EGL_CONTEXT_CLIENT_VERSION, 3, _EGL_CONTEXT_FLAGS_KHR, _EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR, EGL10.EGL_NONE }; + context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list); } else { - int[] attrib_list2 = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE }; - context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list2); + int[] attrib_list = { EGL_CONTEXT_CLIENT_VERSION, 3, EGL10.EGL_NONE }; + context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list); } GLUtils.checkEglError(TAG, "After eglCreateContext", egl); return context; diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularFallbackConfigChooser.java b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularFallbackConfigChooser.java index 68329c5c49..ed5e5ec561 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularFallbackConfigChooser.java +++ b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularFallbackConfigChooser.java @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* RegularFallbackConfigChooser.java */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* RegularFallbackConfigChooser.java */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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.xr.regular; diff --git a/platform/android/java/nativeSrcsConfigs/CMakeLists.txt b/platform/android/java/nativeSrcsConfigs/CMakeLists.txt index 711f7cd502..e1534c7685 100644 --- a/platform/android/java/nativeSrcsConfigs/CMakeLists.txt +++ b/platform/android/java/nativeSrcsConfigs/CMakeLists.txt @@ -17,4 +17,4 @@ target_include_directories(${PROJECT_NAME} SYSTEM PUBLIC ${GODOT_ROOT_DIR}) -add_definitions(-DUNIX_ENABLED -DVULKAN_ENABLED -DANDROID_ENABLED) +add_definitions(-DUNIX_ENABLED -DVULKAN_ENABLED -DANDROID_ENABLED -DGLES3_ENABLED -DTOOLS_ENABLED) diff --git a/platform/android/java_class_wrapper.cpp b/platform/android/java_class_wrapper.cpp index 349ae704f9..edc934e927 100644 --- a/platform/android/java_class_wrapper.cpp +++ b/platform/android/java_class_wrapper.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* java_class_wrapper.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* java_class_wrapper.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "api/java_class_wrapper.h" diff --git a/platform/android/java_godot_io_wrapper.cpp b/platform/android/java_godot_io_wrapper.cpp index cea64a7f22..10716a5c79 100644 --- a/platform/android/java_godot_io_wrapper.cpp +++ b/platform/android/java_godot_io_wrapper.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* java_godot_io_wrapper.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* java_godot_io_wrapper.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "java_godot_io_wrapper.h" diff --git a/platform/android/java_godot_io_wrapper.h b/platform/android/java_godot_io_wrapper.h index 24995147d4..c113a13040 100644 --- a/platform/android/java_godot_io_wrapper.h +++ b/platform/android/java_godot_io_wrapper.h @@ -1,42 +1,43 @@ -/*************************************************************************/ -/* java_godot_io_wrapper.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* java_godot_io_wrapper.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 JAVA_GODOT_IO_WRAPPER_H #define JAVA_GODOT_IO_WRAPPER_H -#include <android/log.h> -#include <jni.h> +#include "string_android.h" #include "core/math/rect2i.h" #include "core/variant/typed_array.h" -#include "string_android.h" + +#include <android/log.h> +#include <jni.h> // Class that makes functions in java/src/org/godotengine/godot/GodotIO.java callable from C++ class GodotIOJavaWrapper { diff --git a/platform/android/java_godot_lib_jni.cpp b/platform/android/java_godot_lib_jni.cpp index b5cb9d341d..7c1b6023c7 100644 --- a/platform/android/java_godot_lib_jni.cpp +++ b/platform/android/java_godot_lib_jni.cpp @@ -1,61 +1,64 @@ -/*************************************************************************/ -/* java_godot_lib_jni.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* java_godot_lib_jni.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "java_godot_lib_jni.h" -#include "java_godot_io_wrapper.h" -#include "java_godot_wrapper.h" - -#include "android/asset_manager_jni.h" #include "android_input_handler.h" #include "api/java_class_wrapper.h" #include "api/jni_singleton.h" -#include "core/config/engine.h" -#include "core/config/project_settings.h" -#include "core/input/input.h" #include "dir_access_jandroid.h" #include "display_server_android.h" #include "file_access_android.h" #include "file_access_filesystem_jandroid.h" +#include "java_godot_io_wrapper.h" +#include "java_godot_wrapper.h" #include "jni_utils.h" -#include "main/main.h" #include "net_socket_android.h" #include "os_android.h" #include "string_android.h" #include "thread_jandroid.h" #include "tts_android.h" -#include <android/input.h> -#include <unistd.h> +#include "core/config/engine.h" +#include "core/config/project_settings.h" +#include "core/input/input.h" +#include "main/main.h" +#ifdef TOOLS_ENABLED +#include "editor/editor_settings.h" +#endif + +#include <android/asset_manager_jni.h> +#include <android/input.h> #include <android/native_window_jni.h> +#include <unistd.h> static JavaClassWrapper *java_class_wrapper = nullptr; static OS_Android *os_android = nullptr; @@ -71,6 +74,39 @@ static Vector3 gravity; static Vector3 magnetometer; static Vector3 gyroscope; +static void _terminate(JNIEnv *env, bool p_restart = false) { + step.set(-1); // Ensure no further steps are attempted and no further events are sent + + // lets cleanup + if (java_class_wrapper) { + memdelete(java_class_wrapper); + } + if (input_handler) { + delete input_handler; + } + // Whether restarting is handled by 'Main::cleanup()' + bool restart_on_cleanup = false; + if (os_android) { + restart_on_cleanup = os_android->is_restart_on_exit_set(); + os_android->main_loop_end(); + Main::cleanup(); + delete os_android; + } + if (godot_io_java) { + delete godot_io_java; + } + if (godot_java) { + if (!restart_on_cleanup) { + if (p_restart) { + godot_java->restart(env); + } else { + godot_java->force_quit(env); + } + } + delete godot_java; + } +} + extern "C" { JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setVirtualKeyboardHeight(JNIEnv *env, jclass clazz, jint p_height) { @@ -79,7 +115,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setVirtualKeyboardHei } } -JNIEXPORT jboolean 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 jboolean 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) { JavaVM *jvm; env->GetJavaVM(&jvm); @@ -96,7 +132,6 @@ JNIEXPORT jboolean JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv 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); @@ -104,26 +139,10 @@ JNIEXPORT jboolean JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ondestroy(JNIEnv *env, jclass clazz) { - // lets cleanup - if (java_class_wrapper) { - memdelete(java_class_wrapper); - } - if (godot_io_java) { - delete godot_io_java; - } - if (godot_java) { - delete godot_java; - } - if (input_handler) { - delete input_handler; - } - if (os_android) { - os_android->main_loop_end(); - delete os_android; - } + _terminate(env, false); } -JNIEXPORT jboolean JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jclass clazz, jobjectArray p_cmdline) { +JNIEXPORT jboolean JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jclass clazz, jobjectArray p_cmdline, jobject p_godot_tts) { setup_android_thread(); const char **cmdline = nullptr; @@ -164,6 +183,8 @@ JNIEXPORT jboolean JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env return false; } + TTS_Android::setup(p_godot_tts); + java_class_wrapper = memnew(JavaClassWrapper(godot_java->get_activity())); GDREGISTER_CLASS(JNISingleton); return true; @@ -178,10 +199,9 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, j if (p_surface) { ANativeWindow *native_window = ANativeWindow_fromSurface(env, p_surface); os_android->set_native_window(native_window); - - DisplayServerAndroid::get_singleton()->reset_window(); - DisplayServerAndroid::get_singleton()->notify_surface_changed(p_width, p_height); } + DisplayServerAndroid::get_singleton()->reset_window(); + DisplayServerAndroid::get_singleton()->notify_surface_changed(p_width, p_height); } } } @@ -196,9 +216,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *en } } else { // Rendering context recreated because it was lost; restart app to let it reload everything - step.set(-1); // Ensure no further steps are attempted and no further events are sent - os_android->main_loop_end(); - godot_java->restart(env); + _terminate(env, true); } } } @@ -225,7 +243,7 @@ JNIEXPORT jboolean JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, if (step.get() == 0) { // Since Godot is initialized on the UI thread, main_thread_id was set to that thread's id, // but for Godot purposes, the main thread is the one running the game loop - Main::setup2(Thread::get_caller_id()); + Main::setup2(); input_handler = new AndroidInputHandler(); step.increment(); return true; @@ -249,7 +267,7 @@ JNIEXPORT jboolean JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, bool should_swap_buffers = false; if (os_android->main_loop_iterate(&should_swap_buffers)) { - godot_java->force_quit(env); + _terminate(env, false); } return should_swap_buffers; @@ -338,19 +356,19 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyhat(JNIEnv *env, j AndroidInputHandler::JoypadEvent jevent; jevent.device = p_device; jevent.type = AndroidInputHandler::JOY_EVENT_HAT; - HatMask hat = HatMask::CENTER; + BitField<HatMask> hat; if (p_hat_x != 0) { if (p_hat_x < 0) { - hat |= HatMask::LEFT; + hat.set_flag(HatMask::LEFT); } else { - hat |= HatMask::RIGHT; + hat.set_flag(HatMask::RIGHT); } } if (p_hat_y != 0) { if (p_hat_y < 0) { - hat |= HatMask::UP; + hat.set_flag(HatMask::UP); } else { - hat |= HatMask::DOWN; + hat.set_flag(HatMask::DOWN); } } jevent.hat = hat; @@ -367,11 +385,11 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyconnectionchanged( } // Called on the UI thread -JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jclass clazz, jint p_keycode, jint p_physical_keycode, jint p_unicode, jboolean p_pressed) { +JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jclass clazz, jint p_physical_keycode, jint p_unicode, jint p_key_label, jboolean p_pressed) { if (step.get() <= 0) { return; } - input_handler->process_key_event(p_keycode, p_physical_keycode, p_unicode, p_pressed); + input_handler->process_key_event(p_physical_keycode, p_unicode, p_key_label, p_pressed); } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_accelerometer(JNIEnv *env, jclass clazz, jfloat x, jfloat y, jfloat z) { @@ -412,43 +430,45 @@ JNIEXPORT jstring JNICALL Java_org_godotengine_godot_GodotLib_getGlobal(JNIEnv * return env->NewStringUTF(GLOBAL_GET(js).operator String().utf8().get_data()); } +JNIEXPORT jstring JNICALL Java_org_godotengine_godot_GodotLib_getEditorSetting(JNIEnv *env, jclass clazz, jstring p_setting_key) { + String editor_setting = ""; +#ifdef TOOLS_ENABLED + String godot_setting_key = jstring_to_string(p_setting_key, env); + editor_setting = EDITOR_GET(godot_setting_key).operator String(); +#else + WARN_PRINT("Access to the Editor Settings in only available on Editor builds"); +#endif + + return env->NewStringUTF(editor_setting.utf8().get_data()); +} + JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_callobject(JNIEnv *env, jclass clazz, jlong ID, jstring method, jobjectArray params) { Object *obj = ObjectDB::get_instance(ObjectID(ID)); ERR_FAIL_NULL(obj); - int res = env->PushLocalFrame(16); - ERR_FAIL_COND(res != 0); - String str_method = jstring_to_string(method, env); int count = env->GetArrayLength(params); + Variant *vlist = (Variant *)alloca(sizeof(Variant) * count); - Variant **vptr = (Variant **)alloca(sizeof(Variant *) * count); + const Variant **vptr = (const Variant **)alloca(sizeof(Variant *) * count); + for (int i = 0; i < count; i++) { jobject jobj = env->GetObjectArrayElement(params, i); - Variant v; - if (jobj) { - v = _jobject_to_variant(env, jobj); - } - memnew_placement(&vlist[i], Variant); - vlist[i] = v; + ERR_FAIL_NULL(jobj); + memnew_placement(&vlist[i], Variant(_jobject_to_variant(env, jobj))); vptr[i] = &vlist[i]; env->DeleteLocalRef(jobj); } Callable::CallError err; - obj->callp(str_method, (const Variant **)vptr, count, err); - - env->PopLocalFrame(nullptr); + obj->callp(str_method, vptr, count, err); } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_calldeferred(JNIEnv *env, jclass clazz, jlong ID, jstring method, jobjectArray params) { Object *obj = ObjectDB::get_instance(ObjectID(ID)); ERR_FAIL_NULL(obj); - int res = env->PushLocalFrame(16); - ERR_FAIL_COND(res != 0); - String str_method = jstring_to_string(method, env); int count = env->GetArrayLength(params); @@ -458,22 +478,19 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_calldeferred(JNIEnv * for (int i = 0; i < count; i++) { jobject jobj = env->GetObjectArrayElement(params, i); - if (jobj) { - args[i] = _jobject_to_variant(env, jobj); - } - env->DeleteLocalRef(jobj); + ERR_FAIL_NULL(jobj); + memnew_placement(&args[i], Variant(_jobject_to_variant(env, jobj))); argptrs[i] = &args[i]; + env->DeleteLocalRef(jobj); } - MessageQueue::get_singleton()->push_callp(obj, str_method, (const Variant **)argptrs, count); - - env->PopLocalFrame(nullptr); + MessageQueue::get_singleton()->push_callp(obj, str_method, argptrs, count); } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_requestPermissionResult(JNIEnv *env, jclass clazz, jstring p_permission, jboolean p_result) { String permission = jstring_to_string(p_permission, env); if (permission == "android.permission.RECORD_AUDIO" && p_result) { - AudioDriver::get_singleton()->capture_start(); + AudioDriver::get_singleton()->input_start(); } if (os_android->get_main_loop()) { diff --git a/platform/android/java_godot_lib_jni.h b/platform/android/java_godot_lib_jni.h index f3f2646bfb..9158e89c13 100644 --- a/platform/android/java_godot_lib_jni.h +++ b/platform/android/java_godot_lib_jni.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* java_godot_lib_jni.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* java_godot_lib_jni.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 JAVA_GODOT_LIB_JNI_H #define JAVA_GODOT_LIB_JNI_H @@ -37,9 +37,9 @@ // 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 jboolean 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 jboolean 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); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ondestroy(JNIEnv *env, jclass clazz); -JNIEXPORT jboolean JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jclass clazz, jobjectArray p_cmdline); +JNIEXPORT jboolean JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jclass clazz, jobjectArray p_cmdline, jobject p_godot_tts); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, jclass clazz, jobject p_surface, jint p_width, jint p_height); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jclass clazz, jobject p_surface); JNIEXPORT jboolean JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, jclass clazz); @@ -49,7 +49,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_dispatchMouseEvent(JN JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_dispatchTouchEvent(JNIEnv *env, jclass clazz, jint ev, jint pointer, jint pointer_count, jfloatArray positions, jboolean p_double_tap); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_magnify(JNIEnv *env, jclass clazz, jfloat p_x, jfloat p_y, jfloat p_factor); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_pan(JNIEnv *env, jclass clazz, jfloat p_x, jfloat p_y, jfloat p_delta_x, jfloat p_delta_y); -JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jclass clazz, jint p_keycode, jint p_physical_keycode, jint p_unicode, jboolean p_pressed); +JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jclass clazz, jint p_physical_keycode, jint p_unicode, jint p_key_label, 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); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyhat(JNIEnv *env, jclass clazz, jint p_device, jint p_hat_x, jint p_hat_y); @@ -61,6 +61,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_gyroscope(JNIEnv *env JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_focusin(JNIEnv *env, jclass clazz); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_focusout(JNIEnv *env, jclass clazz); JNIEXPORT jstring JNICALL Java_org_godotengine_godot_GodotLib_getGlobal(JNIEnv *env, jclass clazz, jstring path); +JNIEXPORT jstring JNICALL Java_org_godotengine_godot_GodotLib_getEditorSetting(JNIEnv *env, jclass clazz, jstring p_setting_key); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_callobject(JNIEnv *env, jclass clazz, jlong ID, jstring method, jobjectArray params); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_calldeferred(JNIEnv *env, jclass clazz, jlong ID, jstring method, jobjectArray params); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setVirtualKeyboardHeight(JNIEnv *env, jclass clazz, jint p_height); diff --git a/platform/android/java_godot_view_wrapper.cpp b/platform/android/java_godot_view_wrapper.cpp index 762840a4b1..a95f762e01 100644 --- a/platform/android/java_godot_view_wrapper.cpp +++ b/platform/android/java_godot_view_wrapper.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* java_godot_view_wrapper.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* java_godot_view_wrapper.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "java_godot_view_wrapper.h" @@ -42,20 +42,32 @@ GodotJavaViewWrapper::GodotJavaViewWrapper(jobject godot_view) { int android_device_api_level = android_get_device_api_level(); if (android_device_api_level >= __ANDROID_API_N__) { + _configure_pointer_icon = env->GetMethodID(_cls, "configurePointerIcon", "(ILjava/lang/String;FF)V"); _set_pointer_icon = env->GetMethodID(_cls, "setPointerIcon", "(I)V"); } if (android_device_api_level >= __ANDROID_API_O__) { _request_pointer_capture = env->GetMethodID(_cls, "requestPointerCapture", "()V"); _release_pointer_capture = env->GetMethodID(_cls, "releasePointerCapture", "()V"); } + + _can_capture_pointer = env->GetMethodID(_cls, "canCapturePointer", "()Z"); } bool GodotJavaViewWrapper::can_update_pointer_icon() const { - return _set_pointer_icon != nullptr; + return _configure_pointer_icon != nullptr && _set_pointer_icon != nullptr; } bool GodotJavaViewWrapper::can_capture_pointer() const { - return _request_pointer_capture != nullptr && _release_pointer_capture != nullptr; + // We can capture the pointer if the other jni capture method ids are initialized, + // and GodotView#canCapturePointer() returns true. + if (_request_pointer_capture != nullptr && _release_pointer_capture != nullptr && _can_capture_pointer != nullptr) { + JNIEnv *env = get_jni_env(); + ERR_FAIL_NULL_V(env, false); + + return env->CallBooleanMethod(_godot_view, _can_capture_pointer); + } + + return false; } void GodotJavaViewWrapper::request_pointer_capture() { @@ -68,7 +80,7 @@ void GodotJavaViewWrapper::request_pointer_capture() { } void GodotJavaViewWrapper::release_pointer_capture() { - if (_request_pointer_capture != nullptr) { + if (_release_pointer_capture != nullptr) { JNIEnv *env = get_jni_env(); ERR_FAIL_NULL(env); @@ -76,6 +88,16 @@ void GodotJavaViewWrapper::release_pointer_capture() { } } +void GodotJavaViewWrapper::configure_pointer_icon(int pointer_type, const String &image_path, const Vector2 &p_hotspot) { + if (_configure_pointer_icon != nullptr) { + JNIEnv *env = get_jni_env(); + ERR_FAIL_NULL(env); + + jstring jImagePath = env->NewStringUTF(image_path.utf8().get_data()); + env->CallVoidMethod(_godot_view, _configure_pointer_icon, pointer_type, jImagePath, p_hotspot.x, p_hotspot.y); + } +} + void GodotJavaViewWrapper::set_pointer_icon(int pointer_type) { if (_set_pointer_icon != nullptr) { JNIEnv *env = get_jni_env(); diff --git a/platform/android/java_godot_view_wrapper.h b/platform/android/java_godot_view_wrapper.h index b398c73cac..e5b04e4866 100644 --- a/platform/android/java_godot_view_wrapper.h +++ b/platform/android/java_godot_view_wrapper.h @@ -1,41 +1,43 @@ -/*************************************************************************/ -/* java_godot_view_wrapper.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* java_godot_view_wrapper.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 JAVA_GODOT_VIEW_WRAPPER_H #define JAVA_GODOT_VIEW_WRAPPER_H +#include "string_android.h" + +#include "core/math/vector2.h" + #include <android/log.h> #include <jni.h> -#include "string_android.h" - // Class that makes functions in java/src/org/godotengine/godot/GodotView.java callable from C++ class GodotJavaViewWrapper { private: @@ -43,8 +45,11 @@ private: jobject _godot_view; + jmethodID _can_capture_pointer = 0; jmethodID _request_pointer_capture = 0; jmethodID _release_pointer_capture = 0; + + jmethodID _configure_pointer_icon = 0; jmethodID _set_pointer_icon = 0; public: @@ -55,6 +60,8 @@ public: void request_pointer_capture(); void release_pointer_capture(); + + void configure_pointer_icon(int pointer_type, const String &image_path, const Vector2 &p_hotspot); void set_pointer_icon(int pointer_type); ~GodotJavaViewWrapper(); diff --git a/platform/android/java_godot_wrapper.cpp b/platform/android/java_godot_wrapper.cpp index 416b98c895..862d9f0436 100644 --- a/platform/android/java_godot_wrapper.cpp +++ b/platform/android/java_godot_wrapper.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* java_godot_wrapper.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* java_godot_wrapper.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "java_godot_wrapper.h" @@ -60,7 +60,7 @@ GodotJavaWrapper::GodotJavaWrapper(JNIEnv *p_env, jobject p_activity, jobject p_ // get some Godot method pointers... _on_video_init = p_env->GetMethodID(godot_class, "onVideoInit", "()Z"); _restart = p_env->GetMethodID(godot_class, "restart", "()V"); - _finish = p_env->GetMethodID(godot_class, "forceQuit", "()V"); + _finish = p_env->GetMethodID(godot_class, "forceQuit", "(I)Z"); _set_keep_screen_on = p_env->GetMethodID(godot_class, "setKeepScreenOn", "(Z)V"); _alert = p_env->GetMethodID(godot_class, "alert", "(Ljava/lang/String;Ljava/lang/String;)V"); _get_GLES_version_code = p_env->GetMethodID(godot_class, "getGLESVersionCode", "()I"); @@ -70,6 +70,7 @@ GodotJavaWrapper::GodotJavaWrapper(JNIEnv *p_env, jobject p_activity, jobject p_ _request_permission = p_env->GetMethodID(godot_class, "requestPermission", "(Ljava/lang/String;)Z"); _request_permissions = p_env->GetMethodID(godot_class, "requestPermissions", "()Z"); _get_granted_permissions = p_env->GetMethodID(godot_class, "getGrantedPermissions", "()[Ljava/lang/String;"); + _get_ca_certificates = p_env->GetMethodID(godot_class, "getCACertificates", "()Ljava/lang/String;"); _init_input_devices = p_env->GetMethodID(godot_class, "initInputDevices", "()V"); _get_surface = p_env->GetMethodID(godot_class, "getSurface", "()Landroid/view/Surface;"); _is_activity_resumed = p_env->GetMethodID(godot_class, "isActivityResumed", "()Z"); @@ -77,8 +78,11 @@ GodotJavaWrapper::GodotJavaWrapper(JNIEnv *p_env, jobject p_activity, jobject p_ _get_input_fallback_mapping = p_env->GetMethodID(godot_class, "getInputFallbackMapping", "()Ljava/lang/String;"); _on_godot_setup_completed = p_env->GetMethodID(godot_class, "onGodotSetupCompleted", "()V"); _on_godot_main_loop_started = p_env->GetMethodID(godot_class, "onGodotMainLoopStarted", "()V"); - _create_new_godot_instance = p_env->GetMethodID(godot_class, "createNewGodotInstance", "([Ljava/lang/String;)V"); + _create_new_godot_instance = p_env->GetMethodID(godot_class, "createNewGodotInstance", "([Ljava/lang/String;)I"); _get_render_view = p_env->GetMethodID(godot_class, "getRenderView", "()Lorg/godotengine/godot/GodotRenderView;"); + _begin_benchmark_measure = p_env->GetMethodID(godot_class, "beginBenchmarkMeasure", "(Ljava/lang/String;)V"); + _end_benchmark_measure = p_env->GetMethodID(godot_class, "endBenchmarkMeasure", "(Ljava/lang/String;)V"); + _dump_benchmark = p_env->GetMethodID(godot_class, "dumpBenchmark", "(Ljava/lang/String;)V"); // get some Activity method pointers... _get_class_loader = p_env->GetMethodID(activity_class, "getClassLoader", "()Ljava/lang/ClassLoader;"); @@ -179,14 +183,15 @@ void GodotJavaWrapper::restart(JNIEnv *p_env) { } } -void GodotJavaWrapper::force_quit(JNIEnv *p_env) { +bool GodotJavaWrapper::force_quit(JNIEnv *p_env, int p_instance_id) { if (_finish) { if (p_env == nullptr) { p_env = get_jni_env(); } - ERR_FAIL_NULL(p_env); - p_env->CallVoidMethod(godot_instance, _finish); + ERR_FAIL_NULL_V(p_env, false); + return p_env->CallBooleanMethod(godot_instance, _finish, p_instance_id); } + return false; } void GodotJavaWrapper::set_keep_screen_on(bool p_enabled) { @@ -309,6 +314,17 @@ Vector<String> GodotJavaWrapper::get_granted_permissions() const { return permissions_list; } +String GodotJavaWrapper::get_ca_certificates() const { + if (_get_ca_certificates) { + JNIEnv *env = get_jni_env(); + ERR_FAIL_NULL_V(env, String()); + jstring s = (jstring)env->CallObjectMethod(godot_instance, _get_ca_certificates); + return jstring_to_string(s, env); + } else { + return String(); + } +} + void GodotJavaWrapper::init_input_devices() { if (_init_input_devices) { JNIEnv *env = get_jni_env(); @@ -345,14 +361,43 @@ void GodotJavaWrapper::vibrate(int p_duration_ms) { } } -void GodotJavaWrapper::create_new_godot_instance(List<String> args) { +int GodotJavaWrapper::create_new_godot_instance(List<String> args) { if (_create_new_godot_instance) { JNIEnv *env = get_jni_env(); - ERR_FAIL_NULL(env); + ERR_FAIL_NULL_V(env, 0); jobjectArray jargs = env->NewObjectArray(args.size(), env->FindClass("java/lang/String"), env->NewStringUTF("")); for (int i = 0; i < args.size(); i++) { env->SetObjectArrayElement(jargs, i, env->NewStringUTF(args[i].utf8().get_data())); } - env->CallVoidMethod(godot_instance, _create_new_godot_instance, jargs); + return env->CallIntMethod(godot_instance, _create_new_godot_instance, jargs); + } else { + return 0; + } +} + +void GodotJavaWrapper::begin_benchmark_measure(const String &p_label) { + if (_begin_benchmark_measure) { + JNIEnv *env = get_jni_env(); + ERR_FAIL_NULL(env); + jstring j_label = env->NewStringUTF(p_label.utf8().get_data()); + env->CallVoidMethod(godot_instance, _begin_benchmark_measure, j_label); + } +} + +void GodotJavaWrapper::end_benchmark_measure(const String &p_label) { + if (_end_benchmark_measure) { + JNIEnv *env = get_jni_env(); + ERR_FAIL_NULL(env); + jstring j_label = env->NewStringUTF(p_label.utf8().get_data()); + env->CallVoidMethod(godot_instance, _end_benchmark_measure, j_label); + } +} + +void GodotJavaWrapper::dump_benchmark(const String &benchmark_file) { + if (_dump_benchmark) { + JNIEnv *env = get_jni_env(); + ERR_FAIL_NULL(env); + jstring j_benchmark_file = env->NewStringUTF(benchmark_file.utf8().get_data()); + env->CallVoidMethod(godot_instance, _dump_benchmark, j_benchmark_file); } } diff --git a/platform/android/java_godot_wrapper.h b/platform/android/java_godot_wrapper.h index fb9c4c77fc..1efdffd71b 100644 --- a/platform/android/java_godot_wrapper.h +++ b/platform/android/java_godot_wrapper.h @@ -1,43 +1,44 @@ -/*************************************************************************/ -/* java_godot_wrapper.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* java_godot_wrapper.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 JAVA_GODOT_WRAPPER_H #define JAVA_GODOT_WRAPPER_H -#include <android/log.h> -#include <jni.h> - -#include "core/templates/list.h" #include "java_godot_view_wrapper.h" #include "string_android.h" +#include "core/templates/list.h" + +#include <android/log.h> +#include <jni.h> + // Class that makes functions in java/src/org/godotengine/godot/Godot.java callable from C++ class GodotJavaWrapper { private: @@ -60,6 +61,7 @@ private: jmethodID _request_permission = nullptr; jmethodID _request_permissions = nullptr; jmethodID _get_granted_permissions = nullptr; + jmethodID _get_ca_certificates = nullptr; jmethodID _init_input_devices = nullptr; jmethodID _get_surface = nullptr; jmethodID _is_activity_resumed = nullptr; @@ -70,6 +72,9 @@ private: jmethodID _get_class_loader = nullptr; jmethodID _create_new_godot_instance = nullptr; jmethodID _get_render_view = nullptr; + jmethodID _begin_benchmark_measure = nullptr; + jmethodID _end_benchmark_measure = nullptr; + jmethodID _dump_benchmark = nullptr; public: GodotJavaWrapper(JNIEnv *p_env, jobject p_activity, jobject p_godot_instance); @@ -85,7 +90,7 @@ public: void on_godot_setup_completed(JNIEnv *p_env = nullptr); void on_godot_main_loop_started(JNIEnv *p_env = nullptr); void restart(JNIEnv *p_env = nullptr); - void force_quit(JNIEnv *p_env = nullptr); + bool force_quit(JNIEnv *p_env = nullptr, int p_instance_id = 0); void set_keep_screen_on(bool p_enabled); void alert(const String &p_message, const String &p_title); int get_gles_version_code(); @@ -98,12 +103,16 @@ public: bool request_permission(const String &p_name); bool request_permissions(); Vector<String> get_granted_permissions() const; + String get_ca_certificates() const; void init_input_devices(); jobject get_surface(); bool is_activity_resumed(); void vibrate(int p_duration_ms); String get_input_fallback_mapping(); - void create_new_godot_instance(List<String> args); + int create_new_godot_instance(List<String> args); + void begin_benchmark_measure(const String &p_label); + void end_benchmark_measure(const String &p_label); + void dump_benchmark(const String &benchmark_file); }; #endif // JAVA_GODOT_WRAPPER_H diff --git a/platform/android/jni_utils.cpp b/platform/android/jni_utils.cpp index 2b0ee50570..fc97d6eca4 100644 --- a/platform/android/jni_utils.cpp +++ b/platform/android/jni_utils.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* jni_utils.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* jni_utils.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "jni_utils.h" @@ -149,6 +149,15 @@ jvalret _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant *p_a v.obj = arr; } break; + case Variant::PACKED_INT64_ARRAY: { + Vector<int64_t> array = *p_arg; + jlongArray arr = env->NewLongArray(array.size()); + const int64_t *r = array.ptr(); + env->SetLongArrayRegion(arr, 0, array.size(), r); + v.val.l = arr; + v.obj = arr; + + } break; case Variant::PACKED_BYTE_ARRAY: { Vector<uint8_t> array = *p_arg; jbyteArray arr = env->NewByteArray(array.size()); @@ -167,8 +176,15 @@ jvalret _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant *p_a v.obj = arr; } break; + case Variant::PACKED_FLOAT64_ARRAY: { + Vector<double> array = *p_arg; + jdoubleArray arr = env->NewDoubleArray(array.size()); + const double *r = array.ptr(); + env->SetDoubleArrayRegion(arr, 0, array.size(), r); + v.val.l = arr; + v.obj = arr; - // TODO: This is missing 64 bits arrays, I have no idea how to do it in JNI. + } break; default: { v.val.i = 0; @@ -244,6 +260,17 @@ Variant _jobject_to_variant(JNIEnv *env, jobject obj) { return sarr; } + if (name == "[J") { + jlongArray arr = (jlongArray)obj; + int fCount = env->GetArrayLength(arr); + Vector<int64_t> sarr; + sarr.resize(fCount); + + int64_t *w = sarr.ptrw(); + env->GetLongArrayRegion(arr, 0, fCount, w); + return sarr; + } + if (name == "[B") { jbyteArray arr = (jbyteArray)obj; int fCount = env->GetArrayLength(arr); @@ -344,12 +371,15 @@ Variant::Type get_jni_type(const String &p_type) { { "void", Variant::NIL }, { "boolean", Variant::BOOL }, { "int", Variant::INT }, + { "long", Variant::INT }, { "float", Variant::FLOAT }, { "double", Variant::FLOAT }, { "java.lang.String", Variant::STRING }, { "[I", Variant::PACKED_INT32_ARRAY }, + { "[J", Variant::PACKED_INT64_ARRAY }, { "[B", Variant::PACKED_BYTE_ARRAY }, { "[F", Variant::PACKED_FLOAT32_ARRAY }, + { "[D", Variant::PACKED_FLOAT64_ARRAY }, { "[Ljava.lang.String;", Variant::PACKED_STRING_ARRAY }, { "org.godotengine.godot.Dictionary", Variant::DICTIONARY }, { nullptr, Variant::NIL } @@ -376,13 +406,16 @@ const char *get_jni_sig(const String &p_type) { { "void", "V" }, { "boolean", "Z" }, { "int", "I" }, + { "long", "J" }, { "float", "F" }, { "double", "D" }, { "java.lang.String", "Ljava/lang/String;" }, { "org.godotengine.godot.Dictionary", "Lorg/godotengine/godot/Dictionary;" }, { "[I", "[I" }, + { "[J", "[J" }, { "[B", "[B" }, { "[F", "[F" }, + { "[D", "[D" }, { "[Ljava.lang.String;", "[Ljava/lang/String;" }, { nullptr, "V" } }; diff --git a/platform/android/jni_utils.h b/platform/android/jni_utils.h index 7d5da29a65..c608f9ebaa 100644 --- a/platform/android/jni_utils.h +++ b/platform/android/jni_utils.h @@ -1,39 +1,41 @@ -/*************************************************************************/ -/* jni_utils.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* jni_utils.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 JNI_UTILS_H #define JNI_UTILS_H #include "string_android.h" -#include <core/config/engine.h> -#include <core/variant/variant.h> + +#include "core/config/engine.h" +#include "core/variant/variant.h" + #include <jni.h> struct jvalret { diff --git a/platform/android/logo.png b/platform/android/logo.png Binary files differdeleted file mode 100644 index 9c8be93646..0000000000 --- a/platform/android/logo.png +++ /dev/null diff --git a/platform/android/logo.svg b/platform/android/logo.svg new file mode 100644 index 0000000000..f154e55d11 --- /dev/null +++ b/platform/android/logo.svg @@ -0,0 +1 @@ +<svg height="32" width="32" xmlns="http://www.w3.org/2000/svg"><path d="M22.904 20.192a1.25 1.25 0 1 1 1.25-1.25 1.25 1.25 0 0 1-1.25 1.25m-13.808 0a1.25 1.25 0 1 1 1.25-1.25 1.25 1.25 0 0 1-1.25 1.25m14.256-7.525 2.496-4.323a.52.52 0 1 0-.899-.52l-2.528 4.378a15.69 15.69 0 0 0-12.842 0L7.051 7.823a.52.52 0 1 0-.9.521l2.497 4.323C4.361 15 1.43 19.34 1 24.467h30c-.43-5.128-3.361-9.468-7.648-11.8" fill="#56d881"/></svg> diff --git a/platform/android/net_socket_android.cpp b/platform/android/net_socket_android.cpp index 225a1132fe..1299ad032a 100644 --- a/platform/android/net_socket_android.cpp +++ b/platform/android/net_socket_android.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* net_socket_android.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* net_socket_android.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "net_socket_android.h" diff --git a/platform/android/net_socket_android.h b/platform/android/net_socket_android.h index 97a611cb04..f0c2b70529 100644 --- a/platform/android/net_socket_android.h +++ b/platform/android/net_socket_android.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* net_socket_android.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* net_socket_android.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 NET_SOCKET_ANDROID_H #define NET_SOCKET_ANDROID_H diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp index 4469c7a0f7..c3a7d70034 100644 --- a/platform/android/os_android.cpp +++ b/platform/android/os_android.cpp @@ -1,54 +1,53 @@ -/*************************************************************************/ -/* os_android.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* os_android.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "os_android.h" +#include "dir_access_jandroid.h" +#include "display_server_android.h" +#include "file_access_android.h" +#include "file_access_filesystem_jandroid.h" +#include "java_godot_io_wrapper.h" +#include "java_godot_wrapper.h" +#include "net_socket_android.h" + #include "core/config/project_settings.h" #include "drivers/unix/dir_access_unix.h" #include "drivers/unix/file_access_unix.h" #include "main/main.h" -#include "platform/android/display_server_android.h" #include "scene/main/scene_tree.h" #include "servers/rendering_server.h" -#include "dir_access_jandroid.h" -#include "file_access_android.h" -#include "file_access_filesystem_jandroid.h" -#include "net_socket_android.h" - #include <dlfcn.h> #include <sys/system_properties.h> -#include "java_godot_io_wrapper.h" -#include "java_godot_wrapper.h" - const char *OS_Android::ANDROID_EXEC_PATH = "apk"; String _remove_symlink(const String &dir) { @@ -162,11 +161,16 @@ Vector<String> OS_Android::get_granted_permissions() const { } Error OS_Android::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path, String *r_resolved_path) { - p_library_handle = dlopen(p_path.utf8().get_data(), RTLD_NOW); + String path = p_path; + if (!FileAccess::exists(path)) { + path = p_path.get_file(); + } + + p_library_handle = dlopen(path.utf8().get_data(), RTLD_NOW); ERR_FAIL_NULL_V_MSG(p_library_handle, ERR_CANT_OPEN, "Can't open dynamic library: " + p_path + ", error: " + dlerror() + "."); if (r_resolved_path != nullptr) { - *r_resolved_path = p_path; + *r_resolved_path = path; } return OK; @@ -177,7 +181,7 @@ String OS_Android::get_name() const { } String OS_Android::get_system_property(const char *key) const { - static String value; + String value; char value_str[PROP_VALUE_MAX]; if (__system_property_get(key, value_str)) { value = String(value_str); @@ -225,20 +229,20 @@ String OS_Android::get_version() const { "ro.potato.version", "ro.xtended.version", "org.evolution.version", "ro.corvus.version", "ro.pa.version", "ro.crdroid.version", "ro.syberia.version", "ro.arrow.version", "ro.lineage.version" }; for (int i = 0; i < roms.size(); i++) { - static String rom_version = get_system_property(roms[i]); + String rom_version = get_system_property(roms[i]); if (!rom_version.is_empty()) { return rom_version; } } - static String mod_version = get_system_property("ro.modversion"); // Handles other Android custom ROMs. + String mod_version = get_system_property("ro.modversion"); // Handles other Android custom ROMs. if (!mod_version.is_empty()) { return mod_version; } // Handles stock Android. - static String sdk_version = get_system_property("ro.build.version.sdk_int"); - static String build = get_system_property("ro.build.version.incremental"); + String sdk_version = get_system_property("ro.build.version.sdk_int"); + String build = get_system_property("ro.build.version.incremental"); if (!sdk_version.is_empty()) { if (!build.is_empty()) { return vformat("%s.%s", sdk_version, build); @@ -263,12 +267,16 @@ bool OS_Android::main_loop_iterate(bool *r_should_swap_buffers) { if (!main_loop) { return false; } + DisplayServerAndroid::get_singleton()->reset_swap_buffers_flag(); DisplayServerAndroid::get_singleton()->process_events(); uint64_t current_frames_drawn = Engine::get_singleton()->get_frames_drawn(); bool exit = Main::iteration(); if (r_should_swap_buffers) { - *r_should_swap_buffers = !is_in_low_processor_usage_mode() || RenderingServer::get_singleton()->has_changed() || current_frames_drawn != Engine::get_singleton()->get_frames_drawn(); + *r_should_swap_buffers = !is_in_low_processor_usage_mode() || + DisplayServerAndroid::get_singleton()->should_swap_buffers() || + RenderingServer::get_singleton()->has_changed() || + current_frames_drawn != Engine::get_singleton()->get_frames_drawn(); } return exit; @@ -302,7 +310,11 @@ String OS_Android::get_resource_dir() const { #ifdef TOOLS_ENABLED return OS_Unix::get_resource_dir(); #else - return "/"; //android has its own filesystem for resources inside the APK + if (remote_fs_dir.is_empty()) { + return "/"; // Android has its own filesystem for resources inside the APK + } else { + return remote_fs_dir; + } #endif } @@ -328,6 +340,229 @@ String OS_Android::get_data_path() const { return get_user_data_dir(); } +void OS_Android::_load_system_font_config() { + font_aliases.clear(); + fonts.clear(); + font_names.clear(); + + Ref<XMLParser> parser; + parser.instantiate(); + + Error err = parser->open(String(getenv("ANDROID_ROOT")).path_join("/etc/fonts.xml")); + if (err == OK) { + bool in_font_node = false; + String fb, fn; + FontInfo fi; + + while (parser->read() == OK) { + if (parser->get_node_type() == XMLParser::NODE_ELEMENT) { + in_font_node = false; + if (parser->get_node_name() == "familyset") { + int ver = parser->has_attribute("version") ? parser->get_named_attribute_value("version").to_int() : 0; + if (ver < 21) { + ERR_PRINT(vformat("Unsupported font config version %s", ver)); + break; + } + } else if (parser->get_node_name() == "alias") { + String name = parser->has_attribute("name") ? parser->get_named_attribute_value("name").strip_edges() : String(); + String to = parser->has_attribute("to") ? parser->get_named_attribute_value("to").strip_edges() : String(); + if (!name.is_empty() && !to.is_empty()) { + font_aliases[name] = to; + } + } else if (parser->get_node_name() == "family") { + fn = parser->has_attribute("name") ? parser->get_named_attribute_value("name").strip_edges() : String(); + String lang_code = parser->has_attribute("lang") ? parser->get_named_attribute_value("lang").strip_edges() : String(); + Vector<String> lang_codes = lang_code.split(","); + for (int i = 0; i < lang_codes.size(); i++) { + Vector<String> lang_code_elements = lang_codes[i].split("-"); + if (lang_code_elements.size() >= 1 && lang_code_elements[0] != "und") { + // Add missing script codes. + if (lang_code_elements[0] == "ko") { + fi.script.insert("Hani"); + fi.script.insert("Hang"); + } + if (lang_code_elements[0] == "ja") { + fi.script.insert("Hani"); + fi.script.insert("Kana"); + fi.script.insert("Hira"); + } + if (!lang_code_elements[0].is_empty()) { + fi.lang.insert(lang_code_elements[0]); + } + } + if (lang_code_elements.size() >= 2) { + // Add common codes for variants and remove variants not supported by HarfBuzz/ICU. + if (lang_code_elements[1] == "Aran") { + fi.script.insert("Arab"); + } + if (lang_code_elements[1] == "Cyrs") { + fi.script.insert("Cyrl"); + } + if (lang_code_elements[1] == "Hanb") { + fi.script.insert("Hani"); + fi.script.insert("Bopo"); + } + if (lang_code_elements[1] == "Hans" || lang_code_elements[1] == "Hant") { + fi.script.insert("Hani"); + } + if (lang_code_elements[1] == "Syrj" || lang_code_elements[1] == "Syre" || lang_code_elements[1] == "Syrn") { + fi.script.insert("Syrc"); + } + if (!lang_code_elements[1].is_empty() && lang_code_elements[1] != "Zsym" && lang_code_elements[1] != "Zsye" && lang_code_elements[1] != "Zmth") { + fi.script.insert(lang_code_elements[1]); + } + } + } + } else if (parser->get_node_name() == "font") { + in_font_node = true; + fb = parser->has_attribute("fallbackFor") ? parser->get_named_attribute_value("fallbackFor").strip_edges() : String(); + fi.weight = parser->has_attribute("weight") ? parser->get_named_attribute_value("weight").to_int() : 400; + fi.italic = parser->has_attribute("style") && parser->get_named_attribute_value("style").strip_edges() == "italic"; + } + } + if (parser->get_node_type() == XMLParser::NODE_TEXT) { + if (in_font_node) { + fi.filename = parser->get_node_data().strip_edges(); + fi.font_name = fn; + if (!fb.is_empty() && fn.is_empty()) { + fi.font_name = fb; + fi.priority = 2; + } + if (fi.font_name.is_empty()) { + fi.font_name = "sans-serif"; + fi.priority = 5; + } + if (fi.font_name.ends_with("-condensed")) { + fi.stretch = 75; + fi.font_name = fi.font_name.trim_suffix("-condensed"); + } + fonts.push_back(fi); + font_names.insert(fi.font_name); + } + } + if (parser->get_node_type() == XMLParser::NODE_ELEMENT_END) { + in_font_node = false; + if (parser->get_node_name() == "font") { + fb = String(); + fi.font_name = String(); + fi.priority = 0; + fi.weight = 400; + fi.stretch = 100; + fi.italic = false; + } else if (parser->get_node_name() == "family") { + fi = FontInfo(); + fn = String(); + } + } + } + parser->close(); + } else { + ERR_PRINT("Unable to load font config"); + } + + font_config_loaded = true; +} + +Vector<String> OS_Android::get_system_fonts() const { + if (!font_config_loaded) { + const_cast<OS_Android *>(this)->_load_system_font_config(); + } + Vector<String> ret; + for (const String &E : font_names) { + ret.push_back(E); + } + return ret; +} + +Vector<String> OS_Android::get_system_font_path_for_text(const String &p_font_name, const String &p_text, const String &p_locale, const String &p_script, int p_weight, int p_stretch, bool p_italic) const { + if (!font_config_loaded) { + const_cast<OS_Android *>(this)->_load_system_font_config(); + } + String font_name = p_font_name.to_lower(); + if (font_aliases.has(font_name)) { + font_name = font_aliases[font_name]; + } + String root = String(getenv("ANDROID_ROOT")).path_join("fonts"); + String lang_prefix = p_locale.split("_")[0]; + Vector<String> ret; + int best_score = 0; + for (const List<FontInfo>::Element *E = fonts.front(); E; E = E->next()) { + int score = 0; + if (!E->get().script.is_empty() && !p_script.is_empty() && !E->get().script.has(p_script)) { + continue; + } + float sim = E->get().font_name.similarity(font_name); + if (sim > 0.0) { + score += (60 * sim + 5 - E->get().priority); + } + if (E->get().lang.has(p_locale)) { + score += 120; + } else if (E->get().lang.has(lang_prefix)) { + score += 115; + } + if (E->get().script.has(p_script)) { + score += 240; + } + score += (20 - Math::abs(E->get().weight - p_weight) / 50); + score += (20 - Math::abs(E->get().stretch - p_stretch) / 10); + if (E->get().italic == p_italic) { + score += 30; + } + if (score > best_score) { + best_score = score; + if (ret.find(root.path_join(E->get().filename)) < 0) { + ret.insert(0, root.path_join(E->get().filename)); + } + } else if (score == best_score || E->get().script.is_empty()) { + if (ret.find(root.path_join(E->get().filename)) < 0) { + ret.push_back(root.path_join(E->get().filename)); + } + } + if (score >= 490) { + break; // Perfect match. + } + } + + return ret; +} + +String OS_Android::get_system_font_path(const String &p_font_name, int p_weight, int p_stretch, bool p_italic) const { + if (!font_config_loaded) { + const_cast<OS_Android *>(this)->_load_system_font_config(); + } + String font_name = p_font_name.to_lower(); + if (font_aliases.has(font_name)) { + font_name = font_aliases[font_name]; + } + String root = String(getenv("ANDROID_ROOT")).path_join("fonts"); + + int best_score = 0; + const List<FontInfo>::Element *best_match = nullptr; + + for (const List<FontInfo>::Element *E = fonts.front(); E; E = E->next()) { + int score = 0; + if (E->get().font_name == font_name) { + score += (65 - E->get().priority); + } + score += (20 - Math::abs(E->get().weight - p_weight) / 50); + score += (20 - Math::abs(E->get().stretch - p_stretch) / 10); + if (E->get().italic == p_italic) { + score += 30; + } + if (score >= 60 && score > best_score) { + best_score = score; + best_match = E; + } + if (score >= 140) { + break; // Perfect match. + } + } + if (best_match) { + return root.path_join(best_match->get().filename); + } + return String(); +} + String OS_Android::get_executable_path() const { // Since unix process creation is restricted on Android, we bypass // OS_Unix::get_executable_path() so we can return ANDROID_EXEC_PATH. @@ -439,7 +674,31 @@ String OS_Android::get_config_path() const { return get_user_data_dir().path_join("config"); } +void OS_Android::benchmark_begin_measure(const String &p_what) { +#ifdef TOOLS_ENABLED + godot_java->begin_benchmark_measure(p_what); +#endif +} + +void OS_Android::benchmark_end_measure(const String &p_what) { +#ifdef TOOLS_ENABLED + godot_java->end_benchmark_measure(p_what); +#endif +} + +void OS_Android::benchmark_dump() { +#ifdef TOOLS_ENABLED + if (!is_use_benchmark_set()) { + return; + } + godot_java->dump_benchmark(get_benchmark_file()); +#endif +} + bool OS_Android::_check_internal_feature_support(const String &p_feature) { + if (p_feature == "system_fonts") { + return true; + } if (p_feature == "mobile") { return true; } @@ -460,8 +719,8 @@ bool OS_Android::_check_internal_feature_support(const String &p_feature) { } OS_Android::OS_Android(GodotJavaWrapper *p_godot_java, GodotIOJavaWrapper *p_godot_io_java, bool p_use_apk_expansion) { - display_size.width = 800; - display_size.height = 600; + display_size.width = DEFAULT_WINDOW_WIDTH; + display_size.height = DEFAULT_WINDOW_HEIGHT; use_apk_expansion = p_use_apk_expansion; @@ -469,7 +728,6 @@ OS_Android::OS_Android(GodotJavaWrapper *p_godot_java, GodotIOJavaWrapper *p_god #if defined(GLES3_ENABLED) gl_extensions = nullptr; - use_gl2 = false; #endif #if defined(VULKAN_ENABLED) @@ -505,9 +763,33 @@ Error OS_Android::create_process(const String &p_path, const List<String> &p_arg } Error OS_Android::create_instance(const List<String> &p_arguments, ProcessID *r_child_id) { - godot_java->create_new_godot_instance(p_arguments); + int instance_id = godot_java->create_new_godot_instance(p_arguments); + if (r_child_id) { + *r_child_id = instance_id; + } return OK; } +Error OS_Android::kill(const ProcessID &p_pid) { + if (godot_java->force_quit(nullptr, p_pid)) { + return OK; + } + return OS_Unix::kill(p_pid); +} + +String OS_Android::get_system_ca_certificates() { + return godot_java->get_ca_certificates(); +} + +Error OS_Android::setup_remote_filesystem(const String &p_server_host, int p_port, const String &p_password, String &r_project_path) { + r_project_path = get_user_data_dir(); + Error err = OS_Unix::setup_remote_filesystem(p_server_host, p_port, p_password, r_project_path); + if (err == OK) { + remote_fs_dir = r_project_path; + FileAccess::make_default<FileAccessFilesystemJAndroid>(FileAccess::ACCESS_RESOURCES); + } + return err; +} + OS_Android::~OS_Android() { } diff --git a/platform/android/os_android.h b/platform/android/os_android.h index d6546a3507..abcc412588 100644 --- a/platform/android/os_android.h +++ b/platform/android/os_android.h @@ -1,37 +1,38 @@ -/*************************************************************************/ -/* os_android.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* os_android.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 OS_ANDROID_H #define OS_ANDROID_H #include "audio_driver_opensl.h" + #include "core/os/main_loop.h" #include "drivers/unix/os_unix.h" #include "servers/audio_server.h" @@ -57,18 +58,38 @@ private: mutable String data_dir_cache; mutable String cache_dir_cache; + mutable String remote_fs_dir; AudioDriverOpenSL audio_driver_android; MainLoop *main_loop = nullptr; + struct FontInfo { + String font_name; + HashSet<String> lang; + HashSet<String> script; + int weight = 400; + int stretch = 100; + bool italic = false; + int priority = 0; + String filename; + }; + + HashMap<String, String> font_aliases; + List<FontInfo> fonts; + HashSet<String> font_names; + bool font_config_loaded = false; + GodotJavaWrapper *godot_java = nullptr; GodotIOJavaWrapper *godot_io_java = nullptr; + void _load_system_font_config(); String get_system_property(const char *key) const; public: static const char *ANDROID_EXEC_PATH; + static const int DEFAULT_WINDOW_WIDTH = 800; + static const int DEFAULT_WINDOW_HEIGHT = 600; virtual void initialize_core() override; virtual void initialize() override; @@ -114,6 +135,10 @@ public: ANativeWindow *get_native_window() const; virtual Error shell_open(String p_uri) override; + + virtual Vector<String> get_system_fonts() const override; + virtual String get_system_font_path(const String &p_font_name, int p_weight = 400, int p_stretch = 100, bool p_italic = false) const override; + virtual Vector<String> get_system_font_path_for_text(const String &p_font_name, const String &p_text, const String &p_locale = String(), const String &p_script = String(), int p_weight = 400, int p_stretch = 100, bool p_italic = false) const override; virtual String get_executable_path() const override; virtual String get_user_data_dir() const override; virtual String get_data_path() const override; @@ -135,6 +160,14 @@ public: virtual Error execute(const String &p_path, const List<String> &p_arguments, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr, bool p_open_console = false) override; virtual Error create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id = nullptr, bool p_open_console = false) override; virtual Error create_instance(const List<String> &p_arguments, ProcessID *r_child_id = nullptr) override; + virtual Error kill(const ProcessID &p_pid) override; + virtual String get_system_ca_certificates() override; + + virtual Error setup_remote_filesystem(const String &p_server_host, int p_port, const String &p_password, String &r_project_path) override; + + virtual void benchmark_begin_measure(const String &p_what) override; + virtual void benchmark_end_measure(const String &p_what) override; + virtual void benchmark_dump() override; virtual bool _check_internal_feature_support(const String &p_feature) override; OS_Android(GodotJavaWrapper *p_godot_java, GodotIOJavaWrapper *p_godot_io_java, bool p_use_apk_expansion); diff --git a/platform/android/platform_config.h b/platform/android/platform_config.h index 40bee40180..d2376d2de7 100644 --- a/platform/android/platform_config.h +++ b/platform/android/platform_config.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* platform_config.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* platform_config.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 <alloca.h> #include <malloc.h> diff --git a/platform/android/plugin/godot_plugin_jni.cpp b/platform/android/plugin/godot_plugin_jni.cpp index 498977ad49..5d48c4e248 100644 --- a/platform/android/plugin/godot_plugin_jni.cpp +++ b/platform/android/plugin/godot_plugin_jni.cpp @@ -1,41 +1,42 @@ -/*************************************************************************/ -/* godot_plugin_jni.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* godot_plugin_jni.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "godot_plugin_jni.h" -#include <core/config/engine.h> -#include <core/config/project_settings.h> -#include <core/error/error_macros.h> -#include <platform/android/api/jni_singleton.h> -#include <platform/android/jni_utils.h> -#include <platform/android/string_android.h> +#include "api/jni_singleton.h" +#include "jni_utils.h" +#include "string_android.h" + +#include "core/config/engine.h" +#include "core/config/project_settings.h" +#include "core/error/error_macros.h" static HashMap<String, JNISingleton *> jni_singletons; @@ -120,7 +121,8 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeEmitS for (int i = 0; i < count; i++) { jobject j_param = env->GetObjectArrayElement(j_signal_params, i); - variant_params[i] = _jobject_to_variant(env, j_param); + ERR_FAIL_NULL(j_param); + memnew_placement(&variant_params[i], Variant(_jobject_to_variant(env, j_param))); args[i] = &variant_params[i]; env->DeleteLocalRef(j_param); } @@ -128,21 +130,21 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeEmitS singleton->emit_signalp(StringName(signal_name), args, count); } -JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterGDNativeLibraries(JNIEnv *env, jclass clazz, jobjectArray gdnlib_paths) { - int gdnlib_count = env->GetArrayLength(gdnlib_paths); - if (gdnlib_count == 0) { +JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterGDExtensionLibraries(JNIEnv *env, jclass clazz, jobjectArray gdextension_paths) { + int gdextension_count = env->GetArrayLength(gdextension_paths); + if (gdextension_count == 0) { return; } - // Retrieve the current list of gdnative libraries. - Array singletons = Array(); - if (ProjectSettings::get_singleton()->has_setting("gdnative/singletons")) { - singletons = GLOBAL_GET("gdnative/singletons"); + // Retrieve the current list of gdextension libraries. + Array singletons; + if (ProjectSettings::get_singleton()->has_setting("gdextension/singletons")) { + singletons = GLOBAL_GET("gdextension/singletons"); } // Insert the libraries provided by the plugin - for (int i = 0; i < gdnlib_count; i++) { - jstring relative_path = (jstring)env->GetObjectArrayElement(gdnlib_paths, i); + for (int i = 0; i < gdextension_count; i++) { + jstring relative_path = (jstring)env->GetObjectArrayElement(gdextension_paths, i); String path = "res://" + jstring_to_string(relative_path, env); if (!singletons.has(path)) { @@ -152,6 +154,6 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegis } // Insert the updated list back into project settings. - ProjectSettings::get_singleton()->set("gdnative/singletons", singletons); + ProjectSettings::get_singleton()->set("gdextension/singletons", singletons); } } diff --git a/platform/android/plugin/godot_plugin_jni.h b/platform/android/plugin/godot_plugin_jni.h index 35f9d5b513..36a992246d 100644 --- a/platform/android/plugin/godot_plugin_jni.h +++ b/platform/android/plugin/godot_plugin_jni.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* godot_plugin_jni.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* godot_plugin_jni.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 GODOT_PLUGIN_JNI_H #define GODOT_PLUGIN_JNI_H @@ -39,7 +39,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegis JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterMethod(JNIEnv *env, jclass clazz, jstring sname, jstring name, jstring ret, jobjectArray args); JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterSignal(JNIEnv *env, jclass clazz, jstring j_plugin_name, jstring j_signal_name, jobjectArray j_signal_param_types); JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeEmitSignal(JNIEnv *env, jclass clazz, jstring j_plugin_name, jstring j_signal_name, jobjectArray j_signal_params); -JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterGDNativeLibraries(JNIEnv *env, jclass clazz, jobjectArray gdnlib_paths); +JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterGDExtensionLibraries(JNIEnv *env, jclass clazz, jobjectArray gdextension_paths); } #endif // GODOT_PLUGIN_JNI_H diff --git a/platform/android/run_icon.png b/platform/android/run_icon.png Binary files differdeleted file mode 100644 index b687c9ac31..0000000000 --- a/platform/android/run_icon.png +++ /dev/null diff --git a/platform/android/run_icon.svg b/platform/android/run_icon.svg new file mode 100644 index 0000000000..24d930fece --- /dev/null +++ b/platform/android/run_icon.svg @@ -0,0 +1 @@ +<svg height="16" width="16" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><path d="M11.187 9.936a.577.577 0 1 1 .578-.578.577.577 0 0 1-.578.578m-6.374 0a.577.577 0 1 1 .577-.578.577.577 0 0 1-.577.578m6.581-3.475 1.153-1.996a.24.24 0 1 0-.415-.24l-1.167 2.021a7.244 7.244 0 0 0-5.93 0L3.868 4.225a.24.24 0 1 0-.415.24l1.153 1.996a6.806 6.806 0 0 0-3.532 5.448h13.852a6.807 6.807 0 0 0-3.532-5.448" fill="#56d881" style="fill:#e0e0e0;fill-opacity:1"/></svg> diff --git a/platform/android/string_android.h b/platform/android/string_android.h index 79c71b5d04..3f30b8ec3d 100644 --- a/platform/android/string_android.h +++ b/platform/android/string_android.h @@ -1,38 +1,40 @@ -/*************************************************************************/ -/* string_android.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* string_android.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 STRING_ANDROID_H #define STRING_ANDROID_H -#include "core/string/ustring.h" #include "thread_jandroid.h" + +#include "core/string/ustring.h" + #include <jni.h> /** diff --git a/platform/android/thread_jandroid.cpp b/platform/android/thread_jandroid.cpp index 9f87303341..9f4140f70f 100644 --- a/platform/android/thread_jandroid.cpp +++ b/platform/android/thread_jandroid.cpp @@ -1,39 +1,39 @@ -/*************************************************************************/ -/* thread_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. */ -/*************************************************************************/ +/**************************************************************************/ +/* thread_jandroid.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "thread_jandroid.h" -#include <android/log.h> - #include "core/os/thread.h" +#include <android/log.h> + static JavaVM *java_vm = nullptr; static thread_local JNIEnv *env = nullptr; diff --git a/platform/android/thread_jandroid.h b/platform/android/thread_jandroid.h index 3b000517fd..e3d1df5e59 100644 --- a/platform/android/thread_jandroid.h +++ b/platform/android/thread_jandroid.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* thread_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. */ -/*************************************************************************/ +/**************************************************************************/ +/* thread_jandroid.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 THREAD_JANDROID_H #define THREAD_JANDROID_H diff --git a/platform/android/tts_android.cpp b/platform/android/tts_android.cpp index 27ba8da448..aef59c2584 100644 --- a/platform/android/tts_android.cpp +++ b/platform/android/tts_android.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* tts_android.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* tts_android.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "tts_android.h" @@ -35,9 +35,11 @@ #include "string_android.h" #include "thread_jandroid.h" +bool TTS_Android::initialized = false; jobject TTS_Android::tts = nullptr; jclass TTS_Android::cls = nullptr; +jmethodID TTS_Android::_init = nullptr; jmethodID TTS_Android::_is_speaking = nullptr; jmethodID TTS_Android::_is_paused = nullptr; jmethodID TTS_Android::_get_voices = nullptr; @@ -49,23 +51,34 @@ jmethodID TTS_Android::_stop_speaking = nullptr; HashMap<int, Char16String> TTS_Android::ids; void TTS_Android::setup(jobject p_tts) { - JNIEnv *env = get_jni_env(); + bool tts_enabled = GLOBAL_GET("audio/general/text_to_speech"); + if (tts_enabled) { + JNIEnv *env = get_jni_env(); + ERR_FAIL_COND(env == nullptr); + + tts = env->NewGlobalRef(p_tts); - tts = env->NewGlobalRef(p_tts); + jclass c = env->GetObjectClass(tts); + cls = (jclass)env->NewGlobalRef(c); - jclass c = env->GetObjectClass(tts); - cls = (jclass)env->NewGlobalRef(c); + _init = env->GetMethodID(cls, "init", "()V"); + _is_speaking = env->GetMethodID(cls, "isSpeaking", "()Z"); + _is_paused = env->GetMethodID(cls, "isPaused", "()Z"); + _get_voices = env->GetMethodID(cls, "getVoices", "()[Ljava/lang/String;"); + _speak = env->GetMethodID(cls, "speak", "(Ljava/lang/String;Ljava/lang/String;IFFIZ)V"); + _pause_speaking = env->GetMethodID(cls, "pauseSpeaking", "()V"); + _resume_speaking = env->GetMethodID(cls, "resumeSpeaking", "()V"); + _stop_speaking = env->GetMethodID(cls, "stopSpeaking", "()V"); - _is_speaking = env->GetMethodID(cls, "isSpeaking", "()Z"); - _is_paused = env->GetMethodID(cls, "isPaused", "()Z"); - _get_voices = env->GetMethodID(cls, "getVoices", "()[Ljava/lang/String;"); - _speak = env->GetMethodID(cls, "speak", "(Ljava/lang/String;Ljava/lang/String;IFFIZ)V"); - _pause_speaking = env->GetMethodID(cls, "pauseSpeaking", "()V"); - _resume_speaking = env->GetMethodID(cls, "resumeSpeaking", "()V"); - _stop_speaking = env->GetMethodID(cls, "stopSpeaking", "()V"); + if (_init) { + env->CallVoidMethod(tts, _init); + initialized = true; + } + } } void TTS_Android::_java_utterance_callback(int p_event, int p_id, int p_pos) { + ERR_FAIL_COND_MSG(!initialized, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); if (ids.has(p_id)) { int pos = 0; if ((DisplayServer::TTSUtteranceEvent)p_event == DisplayServer::TTS_UTTERANCE_BOUNDARY) { @@ -86,6 +99,7 @@ void TTS_Android::_java_utterance_callback(int p_event, int p_id, int p_pos) { } bool TTS_Android::is_speaking() { + ERR_FAIL_COND_V_MSG(!initialized, false, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); if (_is_speaking) { JNIEnv *env = get_jni_env(); @@ -97,6 +111,7 @@ bool TTS_Android::is_speaking() { } bool TTS_Android::is_paused() { + ERR_FAIL_COND_V_MSG(!initialized, false, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); if (_is_paused) { JNIEnv *env = get_jni_env(); @@ -108,6 +123,7 @@ bool TTS_Android::is_paused() { } Array TTS_Android::get_voices() { + ERR_FAIL_COND_V_MSG(!initialized, Array(), "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); Array list; if (_get_voices) { JNIEnv *env = get_jni_env(); @@ -135,6 +151,7 @@ Array TTS_Android::get_voices() { } void TTS_Android::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_MSG(!initialized, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); if (p_interrupt) { stop(); } @@ -157,6 +174,7 @@ void TTS_Android::speak(const String &p_text, const String &p_voice, int p_volum } void TTS_Android::pause() { + ERR_FAIL_COND_MSG(!initialized, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); if (_pause_speaking) { JNIEnv *env = get_jni_env(); @@ -166,6 +184,7 @@ void TTS_Android::pause() { } void TTS_Android::resume() { + ERR_FAIL_COND_MSG(!initialized, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); if (_resume_speaking) { JNIEnv *env = get_jni_env(); @@ -175,6 +194,7 @@ void TTS_Android::resume() { } void TTS_Android::stop() { + ERR_FAIL_COND_MSG(!initialized, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); for (const KeyValue<int, Char16String> &E : ids) { DisplayServer::get_singleton()->tts_post_utterance_event(DisplayServer::TTS_UTTERANCE_CANCELED, E.key); } diff --git a/platform/android/tts_android.h b/platform/android/tts_android.h index bc0cdb8d55..39efef6ed1 100644 --- a/platform/android/tts_android.h +++ b/platform/android/tts_android.h @@ -1,46 +1,50 @@ -/*************************************************************************/ -/* tts_android.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* tts_android.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 TTS_ANDROID_H #define TTS_ANDROID_H +#include "core/config/project_settings.h" #include "core/string/ustring.h" +#include "core/templates/hash_map.h" #include "core/variant/array.h" #include "servers/display_server.h" #include <jni.h> class TTS_Android { + static bool initialized; static jobject tts; static jclass cls; + static jmethodID _init; static jmethodID _is_speaking; static jmethodID _is_paused; static jmethodID _get_voices; diff --git a/platform/android/vulkan/vulkan_context_android.cpp b/platform/android/vulkan_context_android.cpp index 948292c3af..01e6d14438 100644 --- a/platform/android/vulkan/vulkan_context_android.cpp +++ b/platform/android/vulkan_context_android.cpp @@ -1,37 +1,37 @@ -/*************************************************************************/ -/* vulkan_context_android.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. */ -/*************************************************************************/ - -#ifdef VULKAN_ENABLED +/**************************************************************************/ +/* vulkan_context_android.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "vulkan_context_android.h" +#ifdef VULKAN_ENABLED + #ifdef USE_VOLK #include <volk.h> #else diff --git a/platform/android/vulkan/vulkan_context_android.h b/platform/android/vulkan_context_android.h index fe9a033e1c..f253149ef6 100644 --- a/platform/android/vulkan/vulkan_context_android.h +++ b/platform/android/vulkan_context_android.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* vulkan_context_android.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* vulkan_context_android.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 VULKAN_CONTEXT_ANDROID_H #define VULKAN_CONTEXT_ANDROID_H diff --git a/platform/ios/README.md b/platform/ios/README.md index 82c275ad31..0e1d6802cb 100644 --- a/platform/ios/README.md +++ b/platform/ios/README.md @@ -8,7 +8,7 @@ project template used for packaging the iOS export templates. ## Documentation -- [Compiling for iOS](https://docs.godotengine.org/en/latest/development/compiling/compiling_for_ios.html) +- [Compiling for iOS](https://docs.godotengine.org/en/latest/contributing/development/compiling/compiling_for_ios.html) - Instructions on building this platform port from source. - [Exporting for iOS](https://docs.godotengine.org/en/latest/tutorials/export/exporting_for_ios.html) - Instructions on using the compiled export templates to export a project. diff --git a/platform/ios/SCsub b/platform/ios/SCsub index bf12ab6dd7..18ba6617af 100644 --- a/platform/ios/SCsub +++ b/platform/ios/SCsub @@ -17,9 +17,9 @@ ios_lib = [ "display_layer.mm", "godot_app_delegate.m", "godot_view_renderer.mm", - "godot_view_gesture_recognizer.mm", "device_metrics.m", "keyboard_input_view.mm", + "key_mapping_ios.mm", ] env_ios = env.Clone() diff --git a/platform/ios/api/api.cpp b/platform/ios/api/api.cpp index 00c76a9256..b8c9e7e9aa 100644 --- a/platform/ios/api/api.cpp +++ b/platform/ios/api/api.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* api.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* api.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "api.h" @@ -45,4 +45,4 @@ void unregister_ios_api() { void register_ios_api() {} void unregister_ios_api() {} -#endif +#endif // IOS_ENABLED diff --git a/platform/ios/api/api.h b/platform/ios/api/api.h index c7fd4ce77b..15634722bf 100644 --- a/platform/ios/api/api.h +++ b/platform/ios/api/api.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* api.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* api.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 IOS_API_H #define IOS_API_H diff --git a/platform/ios/app_delegate.h b/platform/ios/app_delegate.h index 0ec1dc071b..d8310792aa 100644 --- a/platform/ios/app_delegate.h +++ b/platform/ios/app_delegate.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* app_delegate.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* app_delegate.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ #import <UIKit/UIKit.h> diff --git a/platform/ios/app_delegate.mm b/platform/ios/app_delegate.mm index fb183d52d4..38846e7508 100644 --- a/platform/ios/app_delegate.mm +++ b/platform/ios/app_delegate.mm @@ -1,42 +1,43 @@ -/*************************************************************************/ -/* app_delegate.mm */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* app_delegate.mm */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ #import "app_delegate.h" -#include "core/config/project_settings.h" -#include "drivers/coreaudio/audio_driver_coreaudio.h" #import "godot_view.h" -#include "main/main.h" -#include "os_ios.h" +#import "os_ios.h" #import "view_controller.h" +#include "core/config/project_settings.h" +#import "drivers/coreaudio/audio_driver_coreaudio.h" +#include "main/main.h" + #import <AVFoundation/AVFoundation.h> #import <AudioToolbox/AudioServices.h> @@ -45,7 +46,7 @@ extern int gargc; extern char **gargv; -extern int ios_main(int, char **, String, String); +extern int ios_main(int, char **); extern void ios_finish(); @implementation AppDelegate @@ -66,12 +67,7 @@ static ViewController *mainViewController = nil; // Create a full-screen window self.window = [[UIWindow alloc] initWithFrame:windowBounds]; - NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); - NSString *documentsDirectory = [paths objectAtIndex:0]; - paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); - NSString *cacheDirectory = [paths objectAtIndex:0]; - - int err = ios_main(gargc, gargv, String::utf8([documentsDirectory UTF8String]), String::utf8([cacheDirectory UTF8String])); + int err = ios_main(gargc, gargv); if (err != 0) { // bail, things did not go very well for us, should probably output a message on screen with our error code... diff --git a/platform/ios/detect.py b/platform/ios/detect.py index 38e62134b5..bab055dbd5 100644 --- a/platform/ios/detect.py +++ b/platform/ios/detect.py @@ -39,6 +39,16 @@ def get_opts(): ] +def get_doc_classes(): + return [ + "EditorExportPlatformIOS", + ] + + +def get_doc_path(): + return "doc_classes" + + def get_flags(): return [ ("arch", "arm64"), # Default for convenience. @@ -99,8 +109,8 @@ def configure(env: "Environment"): if env["ios_simulator"]: 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.Append(ASFLAGS=["-mios-simulator-version-min=11.0"]) + env.Append(CCFLAGS=["-mios-simulator-version-min=11.0"]) env.extra_suffix = ".simulator" + env.extra_suffix else: detect_darwin_sdk_path("ios", env) @@ -153,3 +163,11 @@ def configure(env: "Environment"): if env["vulkan"]: env.Append(CPPDEFINES=["VULKAN_ENABLED"]) + + if env["opengl3"]: + env.Append(CPPDEFINES=["GLES3_ENABLED"]) + env.Prepend( + CPPPATH=[ + "$IOS_SDK_PATH/System/Library/Frameworks/OpenGLES.framework/Headers", + ] + ) diff --git a/platform/ios/device_metrics.h b/platform/ios/device_metrics.h index b9fb9b2fd9..2eb9e003a0 100644 --- a/platform/ios/device_metrics.h +++ b/platform/ios/device_metrics.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* device_metrics.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* device_metrics.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ #import <Foundation/Foundation.h> diff --git a/platform/ios/device_metrics.m b/platform/ios/device_metrics.m index ec4dd8130d..d6f5ec8e42 100644 --- a/platform/ios/device_metrics.m +++ b/platform/ios/device_metrics.m @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* device_metrics.m */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* device_metrics.m */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ #import "device_metrics.h" @@ -35,117 +35,159 @@ + (NSDictionary *)dpiList { return @{ @[ - @"iPad1,1", - @"iPad2,1", - @"iPad2,2", - @"iPad2,3", - @"iPad2,4", + @"iPad1,1", // iPad 1th Gen + @"iPad1,2", // iPad 1th Gen (3G) + @"iPad2,1", // iPad 2nd Gen + @"iPad2,2", // iPad 2nd Gen (GSM) + @"iPad2,3", // iPad 2nd Gen (CDMA) + @"iPad2,4", // iPad 2nd Gen ] : @132, @[ - @"iPhone1,1", - @"iPhone1,2", - @"iPhone2,1", - @"iPad2,5", - @"iPad2,6", - @"iPad2,7", - @"iPod1,1", - @"iPod2,1", - @"iPod3,1", + @"iPhone1,1", // iPhone 1st Gen + @"iPhone1,2", // iPhone 3G + @"iPhone2,1", // iPhone 3GS + @"iPad2,5", // iPad mini + @"iPad2,6", // iPad mini (GSM+LTE) + @"iPad2,7", // iPad mini (CDMA+LTE) + @"iPod1,1", // iPod 1st Gen + @"iPod2,1", // iPod 2nd Gen + @"iPod3,1", // iPod 3rd Gen ] : @163, @[ - @"iPad3,1", - @"iPad3,2", - @"iPad3,3", - @"iPad3,4", - @"iPad3,5", - @"iPad3,6", - @"iPad4,1", - @"iPad4,2", - @"iPad4,3", - @"iPad5,3", - @"iPad5,4", - @"iPad6,3", - @"iPad6,4", - @"iPad6,7", - @"iPad6,8", - @"iPad6,11", - @"iPad6,12", - @"iPad7,1", - @"iPad7,2", - @"iPad7,3", - @"iPad7,4", - @"iPad7,5", - @"iPad7,6", - @"iPad7,11", - @"iPad7,12", - @"iPad8,1", - @"iPad8,2", - @"iPad8,3", - @"iPad8,4", - @"iPad8,5", - @"iPad8,6", - @"iPad8,7", - @"iPad8,8", - @"iPad8,9", - @"iPad8,10", - @"iPad8,11", - @"iPad8,12", - @"iPad11,3", - @"iPad11,4", + @"iPad3,1", // iPad 3rd Gen + @"iPad3,2", // iPad 3rd Gen (CDMA) + @"iPad3,3", // iPad 3rd Gen (GSM) + @"iPad3,4", // iPad 4th Gen + @"iPad3,5", // iPad 4th Gen (GSM+LTE) + @"iPad3,6", // iPad 4th Gen (CDMA+LTE) + @"iPad4,1", // iPad Air (WiFi) + @"iPad4,2", // iPad Air (GSM+CDMA) + @"iPad4,3", // iPad Air (China) + @"iPad4,7", // iPad mini 3 (WiFi) + @"iPad4,8", // iPad mini 3 (GSM+CDMA) + @"iPad4,9", // iPad Mini 3 (China) + @"iPad6,3", // iPad Pro (9.7 inch, WiFi) + @"iPad6,4", // iPad Pro (9.7 inch, WiFi+LTE) + @"iPad6,7", // iPad Pro (12.9 inch, WiFi) + @"iPad6,8", // iPad Pro (12.9 inch, WiFi+LTE) + @"iPad6,11", // iPad 5th Gen (2017) + @"iPad6,12", // iPad 5th Gen (2017) + @"iPad7,1", // iPad Pro 2nd Gen (WiFi) + @"iPad7,2", // iPad Pro 2nd Gen (WiFi+Cellular) + @"iPad7,3", // iPad Pro 10.5-inch 2nd Gen + @"iPad7,4", // iPad Pro 10.5-inch 2nd Gen + @"iPad7,5", // iPad 6th Gen (WiFi) + @"iPad7,6", // iPad 6th Gen (WiFi+Cellular) + @"iPad7,11", // iPad 7th Gen 10.2-inch (WiFi) + @"iPad7,12", // iPad 7th Gen 10.2-inch (WiFi+Cellular) + @"iPad8,1", // iPad Pro 11 inch 3rd Gen (WiFi) + @"iPad8,2", // iPad Pro 11 inch 3rd Gen (1TB, WiFi) + @"iPad8,3", // iPad Pro 11 inch 3rd Gen (WiFi+Cellular) + @"iPad8,4", // iPad Pro 11 inch 3rd Gen (1TB, WiFi+Cellular) + @"iPad8,5", // iPad Pro 12.9 inch 3rd Gen (WiFi) + @"iPad8,6", // iPad Pro 12.9 inch 3rd Gen (1TB, WiFi) + @"iPad8,7", // iPad Pro 12.9 inch 3rd Gen (WiFi+Cellular) + @"iPad8,8", // iPad Pro 12.9 inch 3rd Gen (1TB, WiFi+Cellular) + @"iPad8,9", // iPad Pro 11 inch 4th Gen (WiFi) + @"iPad8,10", // iPad Pro 11 inch 4th Gen (WiFi+Cellular) + @"iPad8,11", // iPad Pro 12.9 inch 4th Gen (WiFi) + @"iPad8,12", // iPad Pro 12.9 inch 4th Gen (WiFi+Cellular) + @"iPad11,3", // iPad Air 3rd Gen (WiFi) + @"iPad11,4", // iPad Air 3rd Gen + @"iPad11,6", // iPad 8th Gen (WiFi) + @"iPad11,7", // iPad 8th Gen (WiFi+Cellular) + @"iPad12,1", // iPad 9th Gen (WiFi) + @"iPad12,2", // iPad 9th Gen (WiFi+Cellular) + @"iPad13,1", // iPad Air 4th Gen (WiFi) + @"iPad13,2", // iPad Air 4th Gen (WiFi+Cellular) + @"iPad13,4", // iPad Pro 11 inch 5th Gen + @"iPad13,5", // iPad Pro 11 inch 5th Gen + @"iPad13,6", // iPad Pro 11 inch 5th Gen + @"iPad13,7", // iPad Pro 11 inch 5th Gen + @"iPad13,8", // iPad Pro 12.9 inch 5th Gen + @"iPad13,9", // iPad Pro 12.9 inch 5th Gen + @"iPad13,10", // iPad Pro 12.9 inch 5th Gen + @"iPad13,11", // iPad Pro 12.9 inch 5th Gen + @"iPad13,16", // iPad Air 5th Gen (WiFi) + @"iPad13,17", // iPad Air 5th Gen (WiFi+Cellular) + @"iPad13,18", // iPad 10th Gen + @"iPad13,19", // iPad 10th Gen + @"iPad14,3", // iPad Pro 11 inch 6th Gen + @"iPad14,4", // iPad Pro 11 inch 6th Gen + @"iPad14,5", // iPad Pro 12.9 inch 6th Gen + @"iPad14,6", // iPad Pro 12.9 inch 6th Gen ] : @264, @[ - @"iPhone3,1", - @"iPhone3,2", - @"iPhone3,3", - @"iPhone4,1", - @"iPhone5,1", - @"iPhone5,2", - @"iPhone5,3", - @"iPhone5,4", - @"iPhone6,1", - @"iPhone6,2", - @"iPhone7,2", - @"iPhone8,1", - @"iPhone8,4", - @"iPhone9,1", - @"iPhone9,3", - @"iPhone10,1", - @"iPhone10,4", - @"iPhone11,8", - @"iPhone12,1", - @"iPhone12,8", - @"iPad4,4", - @"iPad4,5", - @"iPad4,6", - @"iPad4,7", - @"iPad4,8", - @"iPad4,9", - @"iPad5,1", - @"iPad5,2", - @"iPad11,1", - @"iPad11,2", - @"iPod4,1", - @"iPod5,1", - @"iPod7,1", - @"iPod9,1", + @"iPhone3,1", // iPhone 4 + @"iPhone3,2", // iPhone 4 (GSM) + @"iPhone3,3", // iPhone 4 (CDMA) + @"iPhone4,1", // iPhone 4S + @"iPhone5,1", // iPhone 5 (GSM) + @"iPhone5,2", // iPhone 5 (GSM+CDMA) + @"iPhone5,3", // iPhone 5C (GSM) + @"iPhone5,4", // iPhone 5C (Global) + @"iPhone6,1", // iPhone 5S (GSM) + @"iPhone6,2", // iPhone 5S (Global) + @"iPhone7,2", // iPhone 6 + @"iPhone8,1", // iPhone 6s + @"iPhone8,4", // iPhone SE (GSM) + @"iPhone9,1", // iPhone 7 + @"iPhone9,3", // iPhone 7 + @"iPhone10,1", // iPhone 8 + @"iPhone10,4", // iPhone 8 + @"iPhone11,8", // iPhone XR + @"iPhone12,1", // iPhone 11 + @"iPhone12,8", // iPhone SE 2nd gen + @"iPhone14,6", // iPhone SE 3rd gen + @"iPad4,4", // iPad mini Retina (WiFi) + @"iPad4,5", // iPad mini Retina (GSM+CDMA) + @"iPad4,6", // iPad mini Retina (China) + @"iPad5,1", // iPad mini 4th Gen (WiFi) + @"iPad5,2", // iPad mini 4th Gen + @"iPad5,3", // iPad Air 2 (WiFi) + @"iPad5,4", // iPad Air 2 + @"iPad11,1", // iPad mini 5th Gen (WiFi) + @"iPad11,2", // iPad mini 5th Gen + @"iPad14,1", // iPad mini 6th Gen (WiFi) + @"iPad14,2", // iPad mini 6th Gen + @"iPod4,1", // iPod 4th Gen + @"iPod5,1", // iPod 5th Gen + @"iPod7,1", // iPod 6th Gen + @"iPod9,1", // iPod 7th Gen ] : @326, @[ - @"iPhone7,1", - @"iPhone8,2", - @"iPhone9,2", - @"iPhone9,4", - @"iPhone10,2", - @"iPhone10,5", + @"iPhone7,1", // iPhone 6 Plus + @"iPhone8,2", // iPhone 6s Plus + @"iPhone9,2", // iPhone 7 Plus + @"iPhone9,4", // iPhone 7 Plus + @"iPhone10,2", // iPhone 8 Plus + @"iPhone10,5", // iPhone 8 Plus ] : @401, @[ - @"iPhone10,3", - @"iPhone10,6", - @"iPhone11,2", - @"iPhone11,4", - @"iPhone11,6", - @"iPhone12,3", - @"iPhone12,5", + @"iPhone10,3", // iPhone X Global + @"iPhone10,6", // iPhone X GSM + @"iPhone11,2", // iPhone XS + @"iPhone11,4", // iPhone XS Max + @"iPhone11,6", // iPhone XS Max Global + @"iPhone12,3", // iPhone 11 Pro + @"iPhone12,5", // iPhone 11 Pro Max + @"iPhone13,4", // iPhone 12 Pro Max + @"iPhone14,3", // iPhone 13 Pro Max + @"iPhone14,8", // iPhone 14 Plus ] : @458, + @[ + @"iPhone13,2", // iPhone 12 + @"iPhone13,3", // iPhone 12 Pro + @"iPhone14,2", // iPhone 13 Pro + @"iPhone14,5", // iPhone 13 + @"iPhone14,7", // iPhone 14 + @"iPhone15,2", // iPhone 14 Pro + @"iPhone15,3", // iPhone 14 Pro Max + ] : @460, + @[ + @"iPhone13,1", // iPhone 12 Mini + @"iPhone14,4", // iPhone 13 Mini + ] : @476 }; } diff --git a/platform/ios/display_layer.h b/platform/ios/display_layer.h index a17c75dba1..e719a42cd9 100644 --- a/platform/ios/display_layer.h +++ b/platform/ios/display_layer.h @@ -1,39 +1,40 @@ -/*************************************************************************/ -/* display_layer.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* display_layer.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ #import <OpenGLES/EAGLDrawable.h> #import <QuartzCore/QuartzCore.h> @protocol DisplayLayer <NSObject> -- (void)renderDisplayLayer; +- (void)startRenderDisplayLayer; +- (void)stopRenderDisplayLayer; - (void)initializeDisplayLayer; - (void)layoutDisplayLayer; diff --git a/platform/ios/display_layer.mm b/platform/ios/display_layer.mm index 74c760ae9a..27cde1c6c2 100644 --- a/platform/ios/display_layer.mm +++ b/platform/ios/display_layer.mm @@ -1,40 +1,41 @@ -/*************************************************************************/ -/* display_layer.mm */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* display_layer.mm */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ #import "display_layer.h" +#import "display_server_ios.h" +#import "os_ios.h" + #include "core/config/project_settings.h" #include "core/os/keyboard.h" -#include "display_server_ios.h" #include "main/main.h" -#include "os_ios.h" #include "servers/audio_server.h" #import <AudioToolbox/AudioServices.h> @@ -60,7 +61,10 @@ - (void)layoutDisplayLayer { } -- (void)renderDisplayLayer { +- (void)startRenderDisplayLayer { +} + +- (void)stopRenderDisplayLayer { } @end @@ -76,8 +80,6 @@ } - (void)initializeDisplayLayer { - // Get our backing layer - // Configure it so that it is opaque, does not retain the contents of the backbuffer when displayed, and uses RGBA8888 color. self.opaque = YES; self.drawableProperties = [NSDictionary @@ -87,8 +89,6 @@ kEAGLDrawablePropertyColorFormat, nil]; - // FIXME: Add Vulkan support via MoltenVK. Add fallback code back? - // Create GL ES 3 context if (GLOBAL_GET("rendering/renderer/rendering_method") == "gl_compatibility") { context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3]; @@ -115,8 +115,22 @@ [self createFramebuffer]; } -- (void)renderDisplayLayer { +- (void)startRenderDisplayLayer { [EAGLContext setCurrentContext:context]; + + glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); +} + +- (void)stopRenderDisplayLayer { + glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); + [context presentRenderbuffer:GL_RENDERBUFFER_OES]; + +#ifdef DEBUG_ENABLED + GLenum err = glGetError(); + if (err) { + NSLog(@"DrawView: %x error", err); + } +#endif } - (void)dealloc { @@ -154,11 +168,15 @@ return NO; } + GLES3::TextureStorage::system_fbo = viewFramebuffer; + return YES; } // Clean up any buffers we have allocated. - (void)destroyFramebuffer { + GLES3::TextureStorage::system_fbo = 0; + glDeleteFramebuffersOES(1, &viewFramebuffer); viewFramebuffer = 0; glDeleteRenderbuffersOES(1, &viewRenderbuffer); diff --git a/platform/ios/display_server_ios.h b/platform/ios/display_server_ios.h index 447f919139..da16449c61 100644 --- a/platform/ios/display_server_ios.h +++ b/platform/ios/display_server_ios.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* display_server_ios.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* display_server_ios.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 DISPLAY_SERVER_IOS_H #define DISPLAY_SERVER_IOS_H @@ -35,23 +35,27 @@ #include "servers/display_server.h" #if defined(VULKAN_ENABLED) +#import "vulkan_context_ios.h" + #include "drivers/vulkan/rendering_device_vulkan.h" #include "servers/rendering/renderer_rd/renderer_compositor_rd.h" -#include "vulkan_context_ios.h" - #ifdef USE_VOLK #include <volk.h> #else #include <vulkan/vulkan.h> #endif -#endif +#endif // VULKAN_ENABLED + +#if defined(GLES3_ENABLED) +#include "drivers/gles3/rasterizer_gles3.h" +#endif // GLES3_ENABLED #import <Foundation/Foundation.h> #import <QuartzCore/CAMetalLayer.h> class DisplayServerIOS : public DisplayServer { - GDCLASS(DisplayServerIOS, DisplayServer) + // No need to register with GDCLASS, it's platform-specific and nothing is added. _THREAD_SAFE_CLASS_ @@ -75,7 +79,7 @@ class DisplayServerIOS : public DisplayServer { void perform_event(const Ref<InputEvent> &p_event); - DisplayServerIOS(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error); + DisplayServerIOS(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error); ~DisplayServerIOS(); public: @@ -84,7 +88,7 @@ public: static DisplayServerIOS *get_singleton(); 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_position, const Vector2i &p_resolution, Error &r_error); + static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error); static Vector<String> get_rendering_drivers_func(); // MARK: - Events @@ -105,15 +109,16 @@ public: // MARK: - Input - // MARK: Touches + // MARK: Touches and Apple Pencil void touch_press(int p_idx, int p_x, int p_y, bool p_pressed, bool p_double_click); - void touch_drag(int p_idx, int p_prev_x, int p_prev_y, int p_x, int p_y); - void touches_cancelled(int p_idx); + void touch_drag(int p_idx, int p_prev_x, int p_prev_y, int p_x, int p_y, float p_pressure, Vector2 p_tilt); + void touches_canceled(int p_idx); // MARK: Keyboard - void key(Key p_key, bool p_pressed); + void key(Key p_key, char32_t p_char, Key p_unshifted, Key p_physical, NSInteger p_modifier, bool p_pressed); + bool is_keyboard_active() const; // MARK: Motion @@ -139,6 +144,7 @@ public: virtual Rect2i get_display_safe_area() const override; virtual int get_screen_count() const override; + virtual int get_primary_screen() const override; virtual Point2i screen_get_position(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; virtual Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; virtual Rect2i screen_get_usable_rect(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; @@ -162,6 +168,7 @@ public: virtual void window_set_current_screen(int p_screen, WindowID p_window = MAIN_WINDOW_ID) override; virtual Point2i window_get_position(WindowID p_window = MAIN_WINDOW_ID) const override; + virtual Point2i window_get_position_with_decorations(WindowID p_window = MAIN_WINDOW_ID) const override; virtual void window_set_position(const Point2i &p_position, WindowID p_window = MAIN_WINDOW_ID) override; virtual void window_set_transient(WindowID p_window, WindowID p_parent) override; @@ -174,7 +181,7 @@ public: virtual void window_set_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID) override; virtual Size2i window_get_size(WindowID p_window = MAIN_WINDOW_ID) const override; - virtual Size2i window_get_real_size(WindowID p_window = MAIN_WINDOW_ID) const override; + virtual Size2i window_get_size_with_decorations(WindowID p_window = MAIN_WINDOW_ID) const override; virtual void window_set_mode(WindowMode p_mode, WindowID p_window = MAIN_WINDOW_ID) override; virtual WindowMode window_get_mode(WindowID p_window = MAIN_WINDOW_ID) const override; @@ -186,6 +193,7 @@ public: virtual void window_request_attention(WindowID p_window = MAIN_WINDOW_ID) override; virtual void window_move_to_foreground(WindowID p_window = MAIN_WINDOW_ID) override; + virtual bool window_is_focused(WindowID p_window = MAIN_WINDOW_ID) const override; virtual float screen_get_max_scale() const override; @@ -199,7 +207,7 @@ public: virtual void window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window = MAIN_WINDOW_ID) override; virtual DisplayServer::VSyncMode window_get_vsync_mode(WindowID p_vsync_mode) const override; - virtual bool screen_is_touchscreen(int p_screen) const override; + virtual bool is_touchscreen_available() const override; virtual void virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect, VirtualKeyboardType p_type, int p_max_length, int p_cursor_start, int p_cursor_end) override; virtual void virtual_keyboard_hide() override; @@ -214,6 +222,7 @@ public: virtual bool screen_is_kept_on() const override; void resize_window(CGSize size); + virtual void swap_buffers() override {} }; #endif // DISPLAY_SERVER_IOS_H diff --git a/platform/ios/display_server_ios.mm b/platform/ios/display_server_ios.mm index 8808d8e842..7d91274a0c 100644 --- a/platform/ios/display_server_ios.mm +++ b/platform/ios/display_server_ios.mm @@ -1,46 +1,48 @@ -/*************************************************************************/ -/* display_server_ios.mm */ -/*************************************************************************/ -/* 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 "display_server_ios.h" +/**************************************************************************/ +/* display_server_ios.mm */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ + +#import "display_server_ios.h" #import "app_delegate.h" -#include "core/config/project_settings.h" -#include "core/io/file_access_pack.h" #import "device_metrics.h" #import "godot_view.h" -#include "ios.h" +#import "ios.h" +#import "key_mapping_ios.h" #import "keyboard_input_view.h" -#include "os_ios.h" -#include "tts_ios.h" +#import "os_ios.h" +#import "tts_ios.h" #import "view_controller.h" +#include "core/config/project_settings.h" +#include "core/io/file_access_pack.h" + #import <sys/utsname.h> static const float kDisplayServerIOSAcceleration = 1.f; @@ -49,53 +51,18 @@ DisplayServerIOS *DisplayServerIOS::get_singleton() { return (DisplayServerIOS *)DisplayServer::get_singleton(); } -DisplayServerIOS::DisplayServerIOS(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, 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_position, const Vector2i &p_resolution, int p_screen, Error &r_error) { + KeyMappingIOS::initialize(); + rendering_driver = p_rendering_driver; // Init TTS - tts = [[TTS_IOS alloc] init]; - -#if defined(GLES3_ENABLED) - // FIXME: Add support for both OpenGL and Vulkan when OpenGL is implemented - // again, - // Note that we should be checking "opengl3" as the driver, might never enable this seeing OpenGL is deprecated on iOS - // We are hardcoding the rendering_driver to "vulkan" down below - - if (rendering_driver == "opengl3") { - bool gl_initialization_error = false; - - // FIXME: Add Vulkan support via MoltenVK. Add fallback code back? - - if (RasterizerGLES3::is_viable() == OK) { - RasterizerGLES3::register_config(); - RasterizerGLES3::make_current(); - } else { - gl_initialization_error = true; - } - - if (gl_initialization_error) { - OS::get_singleton()->alert("Your device does not support any of the supported OpenGL versions.", "Unable to initialize video driver"); - // return ERR_UNAVAILABLE; - } - - // rendering_server = memnew(RenderingServerDefault); - // // FIXME: Reimplement threaded rendering - // if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) { - // rendering_server = memnew(RenderingServerWrapMT(rendering_server, - // false)); - // } - // rendering_server->init(); - // rendering_server->cursor_set_visible(false, 0); - - // reset this to what it should be, it will have been set to 0 after - // rendering_server->init() is called - // RasterizerStorageGLES3system_fbo = gl_view_base_fb; + bool tts_enabled = GLOBAL_GET("audio/general/text_to_speech"); + if (tts_enabled) { + tts = [[TTS_IOS alloc] init]; } -#endif #if defined(VULKAN_ENABLED) - rendering_driver = "vulkan"; - context_vulkan = nullptr; rendering_device_vulkan = nullptr; @@ -110,13 +77,14 @@ DisplayServerIOS::DisplayServerIOS(const String &p_rendering_driver, WindowMode CALayer *layer = [AppDelegate.viewController.godotView initializeRenderingForDriver:@"vulkan"]; if (!layer) { - ERR_FAIL_MSG("Failed to create iOS rendering layer."); + ERR_FAIL_MSG("Failed to create iOS Vulkan rendering layer."); } Size2i size = Size2i(layer.bounds.size.width, layer.bounds.size.height) * screen_get_max_scale(); if (context_vulkan->window_create(MAIN_WINDOW_ID, p_vsync_mode, layer, size.width, size.height) != OK) { memdelete(context_vulkan); context_vulkan = nullptr; + r_error = ERR_UNAVAILABLE; ERR_FAIL_MSG("Failed to create Vulkan window."); } @@ -127,6 +95,18 @@ DisplayServerIOS::DisplayServerIOS(const String &p_rendering_driver, WindowMode } #endif +#if defined(GLES3_ENABLED) + if (rendering_driver == "opengl3") { + CALayer *layer = [AppDelegate.viewController.godotView initializeRenderingForDriver:@"opengl3"]; + + if (!layer) { + ERR_FAIL_MSG("Failed to create iOS OpenGLES rendering layer."); + } + + RasterizerGLES3::make_current(); + } +#endif + bool keep_screen_on = bool(GLOBAL_GET("display/window/energy_saving/keep_screen_on")); screen_set_keep_on(keep_screen_on); @@ -151,8 +131,8 @@ DisplayServerIOS::~DisplayServerIOS() { #endif } -DisplayServer *DisplayServerIOS::create_func(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error) { - return memnew(DisplayServerIOS(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, 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_position, const Vector2i &p_resolution, int p_screen, Error &r_error) { + return memnew(DisplayServerIOS(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, p_screen, r_error)); } Vector<String> DisplayServerIOS::get_rendering_drivers_func() { @@ -227,47 +207,60 @@ void DisplayServerIOS::_window_callback(const Callable &p_callable, const Varian // MARK: Touches 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(); - - ev->set_index(p_idx); - ev->set_pressed(p_pressed); - ev->set_position(Vector2(p_x, p_y)); - ev->set_double_tap(p_double_click); - perform_event(ev); - } + Ref<InputEventScreenTouch> ev; + ev.instantiate(); + + ev->set_index(p_idx); + ev->set_pressed(p_pressed); + ev->set_position(Vector2(p_x, p_y)); + ev->set_double_tap(p_double_click); + perform_event(ev); } -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(); - ev->set_index(p_idx); - ev->set_position(Vector2(p_x, p_y)); - ev->set_relative(Vector2(p_x - p_prev_x, p_y - p_prev_y)); - perform_event(ev); - } +void DisplayServerIOS::touch_drag(int p_idx, int p_prev_x, int p_prev_y, int p_x, int p_y, float p_pressure, Vector2 p_tilt) { + Ref<InputEventScreenDrag> ev; + ev.instantiate(); + ev->set_index(p_idx); + ev->set_pressure(p_pressure); + ev->set_tilt(p_tilt); + ev->set_position(Vector2(p_x, p_y)); + ev->set_relative(Vector2(p_x - p_prev_x, p_y - p_prev_y)); + perform_event(ev); } void DisplayServerIOS::perform_event(const Ref<InputEvent> &p_event) { Input::get_singleton()->parse_input_event(p_event); } -void DisplayServerIOS::touches_cancelled(int p_idx) { +void DisplayServerIOS::touches_canceled(int p_idx) { touch_press(p_idx, -1, -1, false, false); } // MARK: Keyboard -void DisplayServerIOS::key(Key p_key, bool p_pressed) { +void DisplayServerIOS::key(Key p_key, char32_t p_char, Key p_unshifted, Key p_physical, NSInteger p_modifier, bool p_pressed) { Ref<InputEventKey> ev; ev.instantiate(); ev->set_echo(false); ev->set_pressed(p_pressed); - ev->set_keycode(p_key); - ev->set_physical_keycode(p_key); - ev->set_unicode((char32_t)p_key); + ev->set_keycode(fix_keycode(p_char, p_key)); + if (@available(iOS 13.4, *)) { + if (p_key != Key::SHIFT) { + ev->set_shift_pressed(p_modifier & UIKeyModifierShift); + } + if (p_key != Key::CTRL) { + ev->set_ctrl_pressed(p_modifier & UIKeyModifierControl); + } + if (p_key != Key::ALT) { + ev->set_alt_pressed(p_modifier & UIKeyModifierAlternate); + } + if (p_key != Key::META) { + ev->set_meta_pressed(p_modifier & UIKeyModifierCommand); + } + } + ev->set_key_label(p_unshifted); + ev->set_physical_keycode(p_physical); + ev->set_unicode(fix_unicode(p_char)); perform_event(ev); } @@ -327,37 +320,37 @@ String DisplayServerIOS::get_name() const { } bool DisplayServerIOS::tts_is_speaking() const { - ERR_FAIL_COND_V(!tts, false); + ERR_FAIL_COND_V_MSG(!tts, false, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); return [tts isSpeaking]; } bool DisplayServerIOS::tts_is_paused() const { - ERR_FAIL_COND_V(!tts, false); + ERR_FAIL_COND_V_MSG(!tts, false, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); return [tts isPaused]; } TypedArray<Dictionary> DisplayServerIOS::tts_get_voices() const { - ERR_FAIL_COND_V(!tts, TypedArray<Dictionary>()); + ERR_FAIL_COND_V_MSG(!tts, TypedArray<Dictionary>(), "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); return [tts getVoices]; } 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); + ERR_FAIL_COND_MSG(!tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); [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 DisplayServerIOS::tts_pause() { - ERR_FAIL_COND(!tts); + ERR_FAIL_COND_MSG(!tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); [tts pauseSpeaking]; } void DisplayServerIOS::tts_resume() { - ERR_FAIL_COND(!tts); + ERR_FAIL_COND_MSG(!tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); [tts resumeSpeaking]; } void DisplayServerIOS::tts_stop() { - ERR_FAIL_COND(!tts); + ERR_FAIL_COND_MSG(!tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); [tts stopSpeaking]; } @@ -381,6 +374,10 @@ int DisplayServerIOS::get_screen_count() const { return 1; } +int DisplayServerIOS::get_primary_screen() const { + return 0; +} + Point2i DisplayServerIOS::screen_get_position(int p_screen) const { return Size2i(); } @@ -441,7 +438,7 @@ float DisplayServerIOS::screen_get_refresh_rate(int p_screen) const { } float DisplayServerIOS::screen_get_scale(int p_screen) const { - return [UIScreen mainScreen].nativeScale; + return [UIScreen mainScreen].scale; } Vector<DisplayServer::WindowID> DisplayServerIOS::get_window_list() const { @@ -496,6 +493,10 @@ Point2i DisplayServerIOS::window_get_position(WindowID p_window) const { return Point2i(); } +Point2i DisplayServerIOS::window_get_position_with_decorations(WindowID p_window) const { + return Point2i(); +} + void DisplayServerIOS::window_set_position(const Point2i &p_position, WindowID p_window) { // Probably not supported for single window iOS app } @@ -529,7 +530,7 @@ Size2i DisplayServerIOS::window_get_size(WindowID p_window) const { return Size2i(screenBounds.size.width, screenBounds.size.height) * screen_get_max_scale(); } -Size2i DisplayServerIOS::window_get_real_size(WindowID p_window) const { +Size2i DisplayServerIOS::window_get_size_with_decorations(WindowID p_window) const { return window_get_size(p_window); } @@ -561,12 +562,21 @@ void DisplayServerIOS::window_move_to_foreground(WindowID p_window) { // Probably not supported for iOS } +bool DisplayServerIOS::window_is_focused(WindowID p_window) const { + return true; +} + float DisplayServerIOS::screen_get_max_scale() const { return screen_get_scale(SCREEN_OF_MAIN_WINDOW); } void DisplayServerIOS::screen_set_orientation(DisplayServer::ScreenOrientation p_orientation, int p_screen) { screen_orientation = p_orientation; + if (@available(iOS 16.0, *)) { + [AppDelegate.viewController setNeedsUpdateOfSupportedInterfaceOrientations]; + } else { + [UIViewController attemptRotationToDeviceOrientation]; + } } DisplayServer::ScreenOrientation DisplayServerIOS::screen_get_orientation(int p_screen) const { @@ -581,10 +591,20 @@ bool DisplayServerIOS::can_any_window_draw() const { return true; } -bool DisplayServerIOS::screen_is_touchscreen(int p_screen) const { +bool DisplayServerIOS::is_touchscreen_available() const { return true; } +_FORCE_INLINE_ int _convert_utf32_offset_to_utf16(const String &p_existing_text, int p_pos) { + int limit = p_pos; + for (int i = 0; i < MIN(p_existing_text.length(), p_pos); i++) { + if (p_existing_text[i] > 0xffff) { + limit++; + } + } + return limit; +} + void DisplayServerIOS::virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect, VirtualKeyboardType p_type, int p_max_length, int p_cursor_start, int p_cursor_end) { NSString *existingString = [[NSString alloc] initWithUTF8String:p_existing_text.utf8().get_data()]; @@ -623,8 +643,12 @@ void DisplayServerIOS::virtual_keyboard_show(const String &p_existing_text, cons [AppDelegate.viewController.keyboardView becomeFirstResponderWithString:existingString - cursorStart:p_cursor_start - cursorEnd:p_cursor_end]; + cursorStart:_convert_utf32_offset_to_utf16(p_existing_text, p_cursor_start) + cursorEnd:_convert_utf32_offset_to_utf16(p_existing_text, p_cursor_end)]; +} + +bool DisplayServerIOS::is_keyboard_active() const { + return [AppDelegate.viewController.keyboardView isFirstResponder]; } void DisplayServerIOS::virtual_keyboard_hide() { @@ -673,15 +697,18 @@ void DisplayServerIOS::resize_window(CGSize viewSize) { 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); + if (context_vulkan) { + context_vulkan->set_vsync_mode(p_window, p_vsync_mode); + } #endif } 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); -#else - return DisplayServer::VSYNC_ENABLED; + if (context_vulkan) { + return context_vulkan->get_vsync_mode(p_window); + } #endif + return DisplayServer::VSYNC_ENABLED; } diff --git a/platform/ios/doc_classes/EditorExportPlatformIOS.xml b/platform/ios/doc_classes/EditorExportPlatformIOS.xml new file mode 100644 index 0000000000..b37868e543 --- /dev/null +++ b/platform/ios/doc_classes/EditorExportPlatformIOS.xml @@ -0,0 +1,183 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="EditorExportPlatformIOS" inherits="EditorExportPlatform" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> + <brief_description> + Exporter for iOS. + </brief_description> + <description> + </description> + <tutorials> + <link title="Exporting for iOS">$DOCS_URL/tutorials/export/exporting_for_ios.html</link> + </tutorials> + <members> + <member name="application/app_store_team_id" type="String" setter="" getter=""> + Apple Team ID, unique 10-character string. To locate your Team ID check "Membership details" section in your Apple developer account dashboard, or "Organizational Unit" of your code signing certificate. See [url=https://developer.apple.com/help/account/manage-your-team/locate-your-team-id]Locate your Team ID[/url]. + </member> + <member name="application/bundle_identifier" type="String" setter="" getter=""> + Unique application identifier in a reverse-DNS format, can only contain alphanumeric characters ([code]A-Z[/code], [code]a-z[/code], and [code]0-9[/code]), hyphens ([code]-[/code]), and periods ([code].[/code]). + </member> + <member name="application/code_sign_identity_debug" type="String" setter="" getter=""> + The "Full Name", "Common Name" or SHA-1 hash of the signing identity used for debug export. + </member> + <member name="application/code_sign_identity_release" type="String" setter="" getter=""> + The "Full Name", "Common Name" or SHA-1 hash of the signing identity used for release export. + </member> + <member name="application/export_method_debug" type="int" setter="" getter=""> + Application distribution target (debug export). + </member> + <member name="application/export_method_release" type="int" setter="" getter=""> + Application distribution target (release export). + </member> + <member name="application/icon_interpolation" type="int" setter="" getter=""> + Interpolation method used to resize application icon. + </member> + <member name="application/launch_screens_interpolation" type="int" setter="" getter=""> + Interpolation method used to resize launch screen images. + </member> + <member name="application/provisioning_profile_uuid_debug" type="String" setter="" getter=""> + UUID of the provisioning profile. If left empty, Xcode will download or create a provisioning profile automatically. See [url=https://developer.apple.com/help/account/manage-profiles/edit-download-or-delete-profiles]Edit, download, or delete provisioning profiles[/url]. + Can be overridden with the environment variable [code]GODOT_IOS_PROVISIONING_PROFILE_UUID_DEBUG[/code]. + </member> + <member name="application/provisioning_profile_uuid_release" type="String" setter="" getter=""> + UUID of the provisioning profile. If left empty, Xcode will download or create a provisioning profile automatically. See [url=https://developer.apple.com/help/account/manage-profiles/edit-download-or-delete-profiles]Edit, download, or delete provisioning profiles[/url]. + Can be overridden with the environment variable [code]GODOT_IOS_PROVISIONING_PROFILE_UUID_RELEASE[/code]. + </member> + <member name="application/short_version" type="String" setter="" getter=""> + Application version visible to the user, can only contain numeric characters ([code]0-9[/code]) and periods ([code].[/code]). + </member> + <member name="application/signature" type="String" setter="" getter=""> + A four-character creator code that is specific to the bundle. Optional. + </member> + <member name="application/targeted_device_family" type="int" setter="" getter=""> + Supported device family. + </member> + <member name="application/version" type="String" setter="" getter=""> + Machine-readable application version, in the [code]major.minor.patch[/code] format, can only contain numeric characters ([code]0-9[/code]) and periods ([code].[/code]). + </member> + <member name="architectures/arm64" type="bool" setter="" getter=""> + If [code]true[/code], [code]arm64[/code] binaries are included into exported project. + </member> + <member name="capabilities/access_wifi" type="bool" setter="" getter=""> + If [code]true[/code], networking features related to Wi-Fi access are enabled. See [url=https://developer.apple.com/support/required-device-capabilities/]Required Device Capabilities[/url]. + </member> + <member name="capabilities/push_notifications" type="bool" setter="" getter=""> + If [code]true[/code], push notifications are enabled. See [url=https://developer.apple.com/support/required-device-capabilities/]Required Device Capabilities[/url]. + </member> + <member name="custom_template/debug" type="String" setter="" getter=""> + Path to the custom export template. If left empty, default template is used. + </member> + <member name="custom_template/release" type="String" setter="" getter=""> + Path to the custom export template. If left empty, default template is used. + </member> + <member name="icons/app_store_1024x1024" type="String" setter="" getter=""> + App Store application icon file. If left empty, it will fallback to [member ProjectSettings.application/config/icon]. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url]. + </member> + <member name="icons/ipad_76x76" type="String" setter="" getter=""> + Home screen application icon file on iPad (1x DPI). If left empty, it will fallback to [member ProjectSettings.application/config/icon]. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url]. + </member> + <member name="icons/ipad_152x152" type="String" setter="" getter=""> + Home screen application icon file on iPad (2x DPI). If left empty, it will fallback to [member ProjectSettings.application/config/icon]. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url]. + </member> + <member name="icons/ipad_167x167" type="String" setter="" getter=""> + Home screen application icon file on iPad (3x DPI). If left empty, it will fallback to [member ProjectSettings.application/config/icon]. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url]. + </member> + <member name="icons/iphone_120x120" type="String" setter="" getter=""> + Home screen application icon file on iPhone (2x DPI). If left empty, it will fallback to [member ProjectSettings.application/config/icon]. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url]. + </member> + <member name="icons/iphone_180x180" type="String" setter="" getter=""> + Home screen application icon file on iPhone (3x DPI). If left empty, it will fallback to [member ProjectSettings.application/config/icon]. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url]. + </member> + <member name="icons/notification_40x40" type="String" setter="" getter=""> + Notification icon file on iPad and iPhone (2x DPI). If left empty, it will fallback to [member ProjectSettings.application/config/icon]. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url]. + </member> + <member name="icons/notification_60x60" type="String" setter="" getter=""> + Notification icon file on iPhone (3x DPI). If left empty, it will fallback to [member ProjectSettings.application/config/icon]. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url]. + </member> + <member name="icons/settings_58x58" type="String" setter="" getter=""> + Application settings icon file on iPad and iPhone (2x DPI). If left empty, it will fallback to [member ProjectSettings.application/config/icon]. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url]. + </member> + <member name="icons/settings_87x87" type="String" setter="" getter=""> + Application settings icon file on iPhone (3x DPI). If left empty, it will fallback to [member ProjectSettings.application/config/icon]. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url]. + </member> + <member name="icons/spotlight_40x40" type="String" setter="" getter=""> + Spotlight icon file on iPad (1x DPI). If left empty, it will fallback to [member ProjectSettings.application/config/icon]. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url]. + </member> + <member name="icons/spotlight_80x80" type="String" setter="" getter=""> + Spotlight icon file on iPad and iPhone (2x DPI). If left empty, it will fallback to [member ProjectSettings.application/config/icon]. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url]. + </member> + <member name="landscape_launch_screens/ipad_1024x768" type="String" setter="" getter=""> + Application launch screen image file. If left empty, it will fallback to [member ProjectSettings.application/boot_splash/image]. + </member> + <member name="landscape_launch_screens/ipad_2048x1536" type="String" setter="" getter=""> + Application launch screen image file. If left empty, it will fallback to [member ProjectSettings.application/boot_splash/image]. + </member> + <member name="landscape_launch_screens/iphone_2208x1242" type="String" setter="" getter=""> + Application launch screen image file. If left empty, it will fallback to [member ProjectSettings.application/boot_splash/image]. + </member> + <member name="landscape_launch_screens/iphone_2436x1125" type="String" setter="" getter=""> + Application launch screen image file. If left empty, it will fallback to [member ProjectSettings.application/boot_splash/image]. + </member> + <member name="portrait_launch_screens/ipad_768x1024" type="String" setter="" getter=""> + Application launch screen image file. If left empty, it will fallback to [member ProjectSettings.application/boot_splash/image]. + </member> + <member name="portrait_launch_screens/ipad_1536x2048" type="String" setter="" getter=""> + Application launch screen image file. If left empty, it will fallback to [member ProjectSettings.application/boot_splash/image]. + </member> + <member name="portrait_launch_screens/iphone_640x960" type="String" setter="" getter=""> + Application launch screen image file. If left empty, it will fallback to [member ProjectSettings.application/boot_splash/image]. + </member> + <member name="portrait_launch_screens/iphone_640x1136" type="String" setter="" getter=""> + Application launch screen image file. If left empty, it will fallback to [member ProjectSettings.application/boot_splash/image]. + </member> + <member name="portrait_launch_screens/iphone_750x1334" type="String" setter="" getter=""> + Application launch screen image file. If left empty, it will fallback to [member ProjectSettings.application/boot_splash/image]. + </member> + <member name="portrait_launch_screens/iphone_1125x2436" type="String" setter="" getter=""> + Application launch screen image file. If left empty, it will fallback to [member ProjectSettings.application/boot_splash/image]. + </member> + <member name="portrait_launch_screens/iphone_1242x2208" type="String" setter="" getter=""> + Application launch screen image file. If left empty, it will fallback to [member ProjectSettings.application/boot_splash/image]. + </member> + <member name="privacy/camera_usage_description" type="String" setter="" getter=""> + A message displayed when requesting access to the device's camera (in English). + </member> + <member name="privacy/camera_usage_description_localized" type="Dictionary" setter="" getter=""> + A message displayed when requesting access to the device's camera (localized). + </member> + <member name="privacy/microphone_usage_description" type="String" setter="" getter=""> + A message displayed when requesting access to the device's microphone (in English). + </member> + <member name="privacy/microphone_usage_description_localized" type="Dictionary" setter="" getter=""> + A message displayed when requesting access to the device's microphone (localized). + </member> + <member name="privacy/photolibrary_usage_description" type="String" setter="" getter=""> + A message displayed when requesting access to the user's photo library (in English). + </member> + <member name="privacy/photolibrary_usage_description_localized" type="Dictionary" setter="" getter=""> + A message displayed when requesting access to the user's photo library (localized). + </member> + <member name="storyboard/custom_bg_color" type="Color" setter="" getter=""> + A custom background color of the storyboard launch screen. + </member> + <member name="storyboard/custom_image@2x" type="String" setter="" getter=""> + Application launch screen image file (2x DPI). If left empty, it will fallback to [member ProjectSettings.application/boot_splash/image]. + </member> + <member name="storyboard/custom_image@3x" type="String" setter="" getter=""> + Application launch screen image file (3x DPI). If left empty, it will fallback to [member ProjectSettings.application/boot_splash/image]. + </member> + <member name="storyboard/image_scale_mode" type="int" setter="" getter=""> + Launch screen image scaling mode. + </member> + <member name="storyboard/use_custom_bg_color" type="bool" setter="" getter=""> + If [code]true[/code], [member storyboard/custom_bg_color] is used as a launch screen background color, otherwise [code]application/boot_splash/bg_color[/code] project setting is used. + </member> + <member name="storyboard/use_launch_screen_storyboard" type="bool" setter="" getter=""> + If [code]true[/code], storyboard launch screen is used instead of launch screen images. + </member> + <member name="user_data/accessible_from_files_app" type="bool" setter="" getter=""> + If [code]true[/code], the app "Documents" folder can be accessed via "Files" app. See [url=https://developer.apple.com/documentation/bundleresources/information_property_list/lssupportsopeningdocumentsinplace]LSSupportsOpeningDocumentsInPlace[/url]. + </member> + <member name="user_data/accessible_from_itunes_sharing" type="bool" setter="" getter=""> + If [code]true[/code], the app "Documents" folder can be accessed via iTunes file sharing. See [url=https://developer.apple.com/documentation/bundleresources/information_property_list/uifilesharingenabled]UIFileSharingEnabled[/url]. + </member> + </members> +</class> diff --git a/platform/ios/export/export.cpp b/platform/ios/export/export.cpp index 6024db2f2c..e07a135861 100644 --- a/platform/ios/export/export.cpp +++ b/platform/ios/export/export.cpp @@ -1,38 +1,43 @@ -/*************************************************************************/ -/* export.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* export.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "export.h" -#include "editor/export/editor_export.h" #include "export_plugin.h" +#include "editor/export/editor_export.h" + +void register_ios_exporter_types() { + GDREGISTER_VIRTUAL_CLASS(EditorExportPlatformIOS); +} + void register_ios_exporter() { Ref<EditorExportPlatformIOS> platform; platform.instantiate(); diff --git a/platform/ios/export/export.h b/platform/ios/export/export.h index 756a1356ea..355811054a 100644 --- a/platform/ios/export/export.h +++ b/platform/ios/export/export.h @@ -1,36 +1,37 @@ -/*************************************************************************/ -/* export.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* export.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 IOS_EXPORT_H #define IOS_EXPORT_H +void register_ios_exporter_types(); void register_ios_exporter(); #endif // IOS_EXPORT_H diff --git a/platform/ios/export/export_plugin.cpp b/platform/ios/export/export_plugin.cpp index 8e4d91ac50..ae0d120513 100644 --- a/platform/ios/export/export_plugin.cpp +++ b/platform/ios/export/export_plugin.cpp @@ -1,41 +1,51 @@ -/*************************************************************************/ -/* export_plugin.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* export_plugin.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "export_plugin.h" +#include "../logo_svg.gen.h" + #include "core/string/translation.h" #include "editor/editor_node.h" +#include "editor/editor_scale.h" +#include "editor/export/editor_export.h" + +#include "modules/modules_enabled.gen.h" // For svg. +#ifdef MODULE_SVG_ENABLED +#include "modules/svg/image_loader_svg.h" +#endif void EditorExportPlatformIOS::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const { // Vulkan and OpenGL ES 3.0 both mandate ETC2 support. r_features->push_back("etc2"); + r_features->push_back("astc"); Vector<String> architectures = _get_preset_architectures(p_preset); for (int i = 0; i < architectures.size(); ++i) { @@ -49,6 +59,46 @@ Vector<EditorExportPlatformIOS::ExportArchitecture> EditorExportPlatformIOS::_ge return archs; } +struct IconInfo { + const char *preset_key; + const char *idiom; + const char *export_name; + const char *actual_size_side; + const char *scale; + const char *unscaled_size; + const bool force_opaque; +}; + +static const IconInfo icon_infos[] = { + // Home screen on iPhone + { PNAME("icons/iphone_120x120"), "iphone", "Icon-120.png", "120", "2x", "60x60", false }, + { PNAME("icons/iphone_120x120"), "iphone", "Icon-120.png", "120", "3x", "40x40", false }, + { PNAME("icons/iphone_180x180"), "iphone", "Icon-180.png", "180", "3x", "60x60", false }, + + // Home screen on iPad + { PNAME("icons/ipad_76x76"), "ipad", "Icon-76.png", "76", "1x", "76x76", false }, + { PNAME("icons/ipad_152x152"), "ipad", "Icon-152.png", "152", "2x", "76x76", false }, + { PNAME("icons/ipad_167x167"), "ipad", "Icon-167.png", "167", "2x", "83.5x83.5", false }, + + // App Store + { PNAME("icons/app_store_1024x1024"), "ios-marketing", "Icon-1024.png", "1024", "1x", "1024x1024", true }, + + // Spotlight + { PNAME("icons/spotlight_40x40"), "ipad", "Icon-40.png", "40", "1x", "40x40", false }, + { PNAME("icons/spotlight_80x80"), "iphone", "Icon-80.png", "80", "2x", "40x40", false }, + { PNAME("icons/spotlight_80x80"), "ipad", "Icon-80.png", "80", "2x", "40x40", false }, + + // Settings + { PNAME("icons/settings_58x58"), "iphone", "Icon-58.png", "58", "2x", "29x29", false }, + { PNAME("icons/settings_58x58"), "ipad", "Icon-58.png", "58", "2x", "29x29", false }, + { PNAME("icons/settings_87x87"), "iphone", "Icon-87.png", "87", "3x", "29x29", false }, + + // Notification + { PNAME("icons/notification_40x40"), "iphone", "Icon-40.png", "40", "2x", "20x20", false }, + { PNAME("icons/notification_40x40"), "ipad", "Icon-40.png", "40", "2x", "20x20", false }, + { PNAME("icons/notification_60x60"), "iphone", "Icon-60.png", "60", "3x", "20x20", false } +}; + struct LoadingScreenInfo { const char *preset_key; const char *export_name; @@ -63,16 +113,44 @@ static const LoadingScreenInfo loading_screen_infos[] = { { PNAME("landscape_launch_screens/ipad_1024x768"), "Default-Landscape.png", 1024, 768, false }, { PNAME("landscape_launch_screens/ipad_2048x1536"), "Default-Landscape@2x.png", 2048, 1536, false }, - { PNAME("portrait_launch_screens/iphone_640x960"), "Default-480h@2x.png", 640, 960, true }, - { PNAME("portrait_launch_screens/iphone_640x1136"), "Default-568h@2x.png", 640, 1136, true }, - { PNAME("portrait_launch_screens/iphone_750x1334"), "Default-667h@2x.png", 750, 1334, true }, - { PNAME("portrait_launch_screens/iphone_1125x2436"), "Default-Portrait-X.png", 1125, 2436, true }, - { PNAME("portrait_launch_screens/ipad_768x1024"), "Default-Portrait.png", 768, 1024, true }, - { PNAME("portrait_launch_screens/ipad_1536x2048"), "Default-Portrait@2x.png", 1536, 2048, true }, - { PNAME("portrait_launch_screens/iphone_1242x2208"), "Default-Portrait-736h@3x.png", 1242, 2208, true } + { PNAME("portrait_launch_screens/iphone_640x960"), "Default-480h@2x.png", 640, 960, false }, + { PNAME("portrait_launch_screens/iphone_640x1136"), "Default-568h@2x.png", 640, 1136, false }, + { PNAME("portrait_launch_screens/iphone_750x1334"), "Default-667h@2x.png", 750, 1334, false }, + { PNAME("portrait_launch_screens/iphone_1125x2436"), "Default-Portrait-X.png", 1125, 2436, false }, + { PNAME("portrait_launch_screens/ipad_768x1024"), "Default-Portrait.png", 768, 1024, false }, + { PNAME("portrait_launch_screens/ipad_1536x2048"), "Default-Portrait@2x.png", 1536, 2048, false }, + { PNAME("portrait_launch_screens/iphone_1242x2208"), "Default-Portrait-736h@3x.png", 1242, 2208, false } }; -void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options) { +String EditorExportPlatformIOS::get_export_option_warning(const EditorExportPreset *p_preset, const StringName &p_name) const { + if (p_preset) { + if (p_name == "application/app_store_team_id") { + String team_id = p_preset->get("application/app_store_team_id"); + if (team_id.is_empty()) { + return TTR("App Store Team ID not specified.") + "\n"; + } + } else if (p_name == "application/bundle_identifier") { + String identifier = p_preset->get("application/bundle_identifier"); + String pn_err; + if (!is_package_name_valid(identifier, &pn_err)) { + return TTR("Invalid Identifier:") + " " + pn_err; + } + } + } + return String(); +} + +bool EditorExportPlatformIOS::get_export_option_visibility(const EditorExportPreset *p_preset, const String &p_option) const { + if (p_preset) { + bool sb = p_preset->get("storyboard/use_launch_screen_storyboard"); + if (!sb && p_option != "storyboard/use_launch_screen_storyboard" && p_option.begins_with("storyboard/")) { + return false; + } + } + return true; +} + +void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options) const { 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"), "")); @@ -81,22 +159,25 @@ void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options) r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, vformat("%s/%s", PNAME("architectures"), architectures[i].name)), architectures[i].is_default)); } - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/app_store_team_id"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/app_store_team_id"), "", false, true)); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/provisioning_profile_uuid_debug"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/provisioning_profile_uuid_debug", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/code_sign_identity_debug", PROPERTY_HINT_PLACEHOLDER_TEXT, "iPhone Developer"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "application/export_method_debug", PROPERTY_HINT_ENUM, "App Store,Development,Ad-Hoc,Enterprise"), 1)); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/provisioning_profile_uuid_release"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/provisioning_profile_uuid_release", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/code_sign_identity_release", PROPERTY_HINT_PLACEHOLDER_TEXT, "iPhone Distribution"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "application/export_method_release", PROPERTY_HINT_ENUM, "App Store,Development,Ad-Hoc,Enterprise"), 0)); r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "application/targeted_device_family", PROPERTY_HINT_ENUM, "iPhone,iPad,iPhone & iPad"), 2)); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/bundle_identifier", PROPERTY_HINT_PLACEHOLDER_TEXT, "com.example.game"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/bundle_identifier", PROPERTY_HINT_PLACEHOLDER_TEXT, "com.example.game"), "", false, true)); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/signature"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/short_version"), "1.0")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/version"), "1.0")); + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "application/icon_interpolation", PROPERTY_HINT_ENUM, "Nearest neighbor,Bilinear,Cubic,Trilinear,Lanczos"), 4)); + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "application/launch_screens_interpolation", PROPERTY_HINT_ENUM, "Nearest neighbor,Bilinear,Cubic,Trilinear,Lanczos"), 4)); + Vector<PluginConfigIOS> found_plugins = get_plugins(); for (int i = 0; i < found_plugins.size(); i++) { r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, vformat("%s/%s", PNAME("plugins"), found_plugins[i].name)), false)); @@ -139,19 +220,14 @@ void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options) r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/photolibrary_usage_description", PROPERTY_HINT_PLACEHOLDER_TEXT, "Provide a message if you need access to the photo library"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::DICTIONARY, "privacy/photolibrary_usage_description_localized", PROPERTY_HINT_LOCALIZABLE_STRING), Dictionary())); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "icons/iphone_120x120", PROPERTY_HINT_FILE, "*.png,*.jpg,*.jpeg"), "")); // Home screen on iPhone/iPod Touch with Retina display - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "icons/iphone_180x180", PROPERTY_HINT_FILE, "*.png,*.jpg,*.jpeg"), "")); // Home screen on iPhone with Retina HD display - - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "icons/ipad_76x76", PROPERTY_HINT_FILE, "*.png,*.jpg,*.jpeg"), "")); // Home screen on iPad - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "icons/ipad_152x152", PROPERTY_HINT_FILE, "*.png,*.jpg,*.jpeg"), "")); // Home screen on iPad with Retina display - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "icons/ipad_167x167", PROPERTY_HINT_FILE, "*.png,*.jpg,*.jpeg"), "")); // Home screen on iPad Pro - - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "icons/app_store_1024x1024", PROPERTY_HINT_FILE, "*.png,*.jpg,*.jpeg"), "")); // App Store - - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "icons/spotlight_40x40", PROPERTY_HINT_FILE, "*.png,*.jpg,*.jpeg"), "")); // Spotlight - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "icons/spotlight_80x80", PROPERTY_HINT_FILE, "*.png,*.jpg,*.jpeg"), "")); // Spotlight on devices with Retina display - - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "storyboard/use_launch_screen_storyboard"), false)); + HashSet<String> used_names; + for (uint64_t i = 0; i < sizeof(icon_infos) / sizeof(icon_infos[0]); ++i) { + if (!used_names.has(icon_infos[i].preset_key)) { + used_names.insert(icon_infos[i].preset_key); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, icon_infos[i].preset_key, PROPERTY_HINT_FILE, "*.png,*.jpg,*.jpeg"), "")); + } + } + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "storyboard/use_launch_screen_storyboard"), false, true)); r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "storyboard/image_scale_mode", PROPERTY_HINT_ENUM, "Same as Logo,Center,Scale to Fit,Scale to Fill,Scale"), 0)); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "storyboard/custom_image@2x", PROPERTY_HINT_FILE, "*.png,*.jpg,*.jpeg"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "storyboard/custom_image@3x", PROPERTY_HINT_FILE, "*.png,*.jpg,*.jpeg"), "")); @@ -178,8 +254,8 @@ void EditorExportPlatformIOS::_fix_config_file(const Ref<EditorExportPreset> &p_ }; String dbg_sign_id = p_preset->get("application/code_sign_identity_debug").operator String().is_empty() ? "iPhone Developer" : p_preset->get("application/code_sign_identity_debug"); String rel_sign_id = p_preset->get("application/code_sign_identity_release").operator String().is_empty() ? "iPhone Distribution" : p_preset->get("application/code_sign_identity_release"); - bool dbg_manual = !p_preset->get("application/provisioning_profile_uuid_debug").operator String().is_empty() || (dbg_sign_id != "iPhone Developer"); - bool rel_manual = !p_preset->get("application/provisioning_profile_uuid_release").operator String().is_empty() || (rel_sign_id != "iPhone Distribution"); + bool dbg_manual = !p_preset->get_or_env("application/provisioning_profile_uuid_debug", ENV_IOS_PROFILE_UUID_DEBUG).operator String().is_empty() || (dbg_sign_id != "iPhone Developer"); + bool rel_manual = !p_preset->get_or_env("application/provisioning_profile_uuid_release", ENV_IOS_PROFILE_UUID_RELEASE).operator String().is_empty() || (rel_sign_id != "iPhone Distribution"); String str; String strnew; str.parse_utf8((const char *)pfile.ptr(), pfile.size()); @@ -213,9 +289,9 @@ void EditorExportPlatformIOS::_fix_config_file(const Ref<EditorExportPreset> &p_ int export_method = p_preset->get(p_debug ? "application/export_method_debug" : "application/export_method_release"); strnew += lines[i].replace("$export_method", export_method_string[export_method]) + "\n"; } else if (lines[i].find("$provisioning_profile_uuid_release") != -1) { - strnew += lines[i].replace("$provisioning_profile_uuid_release", p_preset->get("application/provisioning_profile_uuid_release")) + "\n"; + strnew += lines[i].replace("$provisioning_profile_uuid_release", p_preset->get_or_env("application/provisioning_profile_uuid_release", ENV_IOS_PROFILE_UUID_RELEASE)) + "\n"; } else if (lines[i].find("$provisioning_profile_uuid_debug") != -1) { - strnew += lines[i].replace("$provisioning_profile_uuid_debug", p_preset->get("application/provisioning_profile_uuid_debug")) + "\n"; + strnew += lines[i].replace("$provisioning_profile_uuid_debug", p_preset->get_or_env("application/provisioning_profile_uuid_debug", ENV_IOS_PROFILE_UUID_DEBUG)) + "\n"; } else if (lines[i].find("$code_sign_style_debug") != -1) { if (dbg_manual) { strnew += lines[i].replace("$code_sign_style_debug", "Manual") + "\n"; @@ -229,7 +305,7 @@ void EditorExportPlatformIOS::_fix_config_file(const Ref<EditorExportPreset> &p_ strnew += lines[i].replace("$code_sign_style_release", "Automatic") + "\n"; } } else if (lines[i].find("$provisioning_profile_uuid") != -1) { - String uuid = p_debug ? p_preset->get("application/provisioning_profile_uuid_debug") : p_preset->get("application/provisioning_profile_uuid_release"); + String uuid = p_debug ? p_preset->get_or_env("application/provisioning_profile_uuid_debug", ENV_IOS_PROFILE_UUID_DEBUG) : p_preset->get_or_env("application/provisioning_profile_uuid_release", ENV_IOS_PROFILE_UUID_RELEASE); strnew += lines[i].replace("$provisioning_profile_uuid", uuid) + "\n"; } else if (lines[i].find("$code_sign_identity_debug") != -1) { strnew += lines[i].replace("$code_sign_identity_debug", dbg_sign_id) + "\n"; @@ -531,36 +607,6 @@ void EditorExportPlatformIOS::_blend_and_rotate(Ref<Image> &p_dst, Ref<Image> &p } } -struct IconInfo { - const char *preset_key; - const char *idiom; - const char *export_name; - const char *actual_size_side; - const char *scale; - const char *unscaled_size; - const bool force_opaque; -}; - -static const IconInfo icon_infos[] = { - // Home screen on iPhone - { "icons/iphone_120x120", "iphone", "Icon-120.png", "120", "2x", "60x60", false }, - { "icons/iphone_120x120", "iphone", "Icon-120.png", "120", "3x", "40x40", false }, - { "icons/iphone_180x180", "iphone", "Icon-180.png", "180", "3x", "60x60", false }, - - // Home screen on iPad - { "icons/ipad_76x76", "ipad", "Icon-76.png", "76", "1x", "76x76", false }, - { "icons/ipad_152x152", "ipad", "Icon-152.png", "152", "2x", "76x76", false }, - { "icons/ipad_167x167", "ipad", "Icon-167.png", "167", "2x", "83.5x83.5", false }, - - // App Store - { "icons/app_store_1024x1024", "ios-marketing", "Icon-1024.png", "1024", "1x", "1024x1024", true }, - - // Spotlight - { "icons/spotlight_40x40", "ipad", "Icon-40.png", "40", "1x", "40x40", false }, - { "icons/spotlight_80x80", "iphone", "Icon-80.png", "80", "2x", "40x40", false }, - { "icons/spotlight_80x80", "ipad", "Icon-80.png", "80", "2x", "40x40", false } -}; - Error EditorExportPlatformIOS::_export_icons(const Ref<EditorExportPreset> &p_preset, const String &p_iconset_dir) { String json_description = "{\"images\":["; String sizes; @@ -568,6 +614,8 @@ Error EditorExportPlatformIOS::_export_icons(const Ref<EditorExportPreset> &p_pr Ref<DirAccess> da = DirAccess::open(p_iconset_dir); ERR_FAIL_COND_V_MSG(da.is_null(), ERR_CANT_OPEN, "Cannot open directory '" + p_iconset_dir + "'."); + Color boot_bg_color = GLOBAL_GET("application/boot_splash/bg_color"); + for (uint64_t i = 0; i < (sizeof(icon_infos) / sizeof(icon_infos[0])); ++i) { IconInfo info = icon_infos[i]; int side_size = String(info.actual_size_side).to_int(); @@ -580,13 +628,17 @@ Error EditorExportPlatformIOS::_export_icons(const Ref<EditorExportPreset> &p_pr if (err != OK) { add_message(EXPORT_MESSAGE_ERROR, TTR("Export Icons"), vformat("Invalid icon (%s): '%s'.", info.preset_key, icon_path)); return ERR_UNCONFIGURED; + } else if (info.force_opaque && img->detect_alpha() != Image::ALPHA_NONE) { + add_message(EXPORT_MESSAGE_WARNING, TTR("Export Icons"), vformat("Icon (%s) must be opaque.", info.preset_key)); + img->resize(side_size, side_size, (Image::Interpolation)(p_preset->get("application/icon_interpolation").operator int())); + Ref<Image> new_img = Image::create_empty(side_size, side_size, false, Image::FORMAT_RGBA8); + new_img->fill(boot_bg_color); + _blend_and_rotate(new_img, img, false); + err = new_img->save_png(p_iconset_dir + info.export_name); + } else { + img->resize(side_size, side_size, (Image::Interpolation)(p_preset->get("application/icon_interpolation").operator int())); + err = img->save_png(p_iconset_dir + info.export_name); } - if (info.force_opaque && img->detect_alpha() != Image::ALPHA_NONE) { - add_message(EXPORT_MESSAGE_ERROR, TTR("Export Icons"), vformat("Icon (%s) must be opaque.", info.preset_key)); - return ERR_UNCONFIGURED; - } - img->resize(side_size, side_size); - err = img->save_png(p_iconset_dir + info.export_name); if (err) { add_message(EXPORT_MESSAGE_ERROR, TTR("Export Icons"), vformat("Failed to export icon (%s): '%s'.", info.preset_key, icon_path)); return err; @@ -598,14 +650,16 @@ Error EditorExportPlatformIOS::_export_icons(const Ref<EditorExportPreset> &p_pr if (err != OK) { add_message(EXPORT_MESSAGE_ERROR, TTR("Export Icons"), vformat("Invalid icon (%s): '%s'.", info.preset_key, icon_path)); return ERR_UNCONFIGURED; - } - if (info.force_opaque && img->detect_alpha() != Image::ALPHA_NONE) { - add_message(EXPORT_MESSAGE_ERROR, TTR("Export Icons"), vformat("Icon (%s) must be opaque.", info.preset_key)); - return ERR_UNCONFIGURED; - } - if (img->get_width() != side_size || img->get_height() != side_size) { + } else if (info.force_opaque && img->detect_alpha() != Image::ALPHA_NONE) { + add_message(EXPORT_MESSAGE_WARNING, TTR("Export Icons"), vformat("Icon (%s) must be opaque.", info.preset_key)); + img->resize(side_size, side_size, (Image::Interpolation)(p_preset->get("application/icon_interpolation").operator int())); + Ref<Image> new_img = Image::create_empty(side_size, side_size, false, Image::FORMAT_RGBA8); + new_img->fill(boot_bg_color); + _blend_and_rotate(new_img, img, false); + err = new_img->save_png(p_iconset_dir + info.export_name); + } else if (img->get_width() != side_size || img->get_height() != side_size) { add_message(EXPORT_MESSAGE_WARNING, TTR("Export Icons"), vformat("Icon (%s): '%s' has incorrect size %s and was automatically resized to %s.", info.preset_key, icon_path, img->get_size(), Vector2i(side_size, side_size))); - img->resize(side_size, side_size); + img->resize(side_size, side_size, (Image::Interpolation)(p_preset->get("application/icon_interpolation").operator int())); err = img->save_png(p_iconset_dir + info.export_name); } else { err = da->copy(icon_path, p_iconset_dir + info.export_name); @@ -650,7 +704,7 @@ Error EditorExportPlatformIOS::_export_loading_screen_file(const Ref<EditorExpor Ref<Image> image; String image_path = p_dest_dir.path_join("splash@2x.png"); image.instantiate(); - Error err = image->load(custom_launch_image_2x); + Error err = ImageLoader::load_image(custom_launch_image_2x, image); if (err) { image.unref(); @@ -664,7 +718,7 @@ Error EditorExportPlatformIOS::_export_loading_screen_file(const Ref<EditorExpor image.unref(); image_path = p_dest_dir.path_join("splash@3x.png"); image.instantiate(); - err = image->load(custom_launch_image_3x); + err = ImageLoader::load_image(custom_launch_image_3x, image); if (err) { image.unref(); @@ -681,7 +735,7 @@ Error EditorExportPlatformIOS::_export_loading_screen_file(const Ref<EditorExpor if (!splash_path.is_empty()) { splash.instantiate(); - const Error err = splash->load(splash_path); + const Error err = ImageLoader::load_image(splash_path, splash); if (err) { splash.unref(); } @@ -735,9 +789,9 @@ Error EditorExportPlatformIOS::_export_loading_screen_images(const Ref<EditorExp float aspect_ratio = (float)img->get_width() / (float)img->get_height(); if (boot_logo_scale) { if (info.height * aspect_ratio <= info.width) { - img->resize(info.height * aspect_ratio, info.height); + img->resize(info.height * aspect_ratio, info.height, (Image::Interpolation)(p_preset->get("application/launch_screens_interpolation").operator int())); } else { - img->resize(info.width, info.width / aspect_ratio); + img->resize(info.width, info.width / aspect_ratio, (Image::Interpolation)(p_preset->get("application/launch_screens_interpolation").operator int())); } } Ref<Image> new_img = Image::create_empty(info.width, info.height, false, Image::FORMAT_RGBA8); @@ -771,17 +825,17 @@ Error EditorExportPlatformIOS::_export_loading_screen_images(const Ref<EditorExp if (info.rotate) { if (boot_logo_scale) { if (info.width * aspect_ratio <= info.height) { - img_bs->resize(info.width * aspect_ratio, info.width); + img_bs->resize(info.width * aspect_ratio, info.width, (Image::Interpolation)(p_preset->get("application/launch_screens_interpolation").operator int())); } else { - img_bs->resize(info.height, info.height / aspect_ratio); + img_bs->resize(info.height, info.height / aspect_ratio, (Image::Interpolation)(p_preset->get("application/launch_screens_interpolation").operator int())); } } } else { if (boot_logo_scale) { if (info.height * aspect_ratio <= info.width) { - img_bs->resize(info.height * aspect_ratio, info.height); + img_bs->resize(info.height * aspect_ratio, info.height, (Image::Interpolation)(p_preset->get("application/launch_screens_interpolation").operator int())); } else { - img_bs->resize(info.width, info.width / aspect_ratio); + img_bs->resize(info.width, info.width / aspect_ratio, (Image::Interpolation)(p_preset->get("application/launch_screens_interpolation").operator int())); } } } @@ -1118,7 +1172,7 @@ Error EditorExportPlatformIOS::_copy_asset(const String &p_out_dir, const String "<key>CFBundleShortVersionString</key>\n" "<string>1.0</string>\n" "<key>CFBundleIdentifier</key>\n" - "<string>com.gdnative.framework.$name</string>\n" + "<string>com.gdextension.framework.$name</string>\n" "<key>CFBundleName</key>\n" "<string>$name</string>\n" "<key>CFBundleExecutable</key>\n" @@ -1549,7 +1603,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(MACOS_ENABLED) || defined(X11_ENABLED) +#if defined(MACOS_ENABLED) || defined(LINUXBSD_ENABLED) bool is_execute = false; #endif @@ -1582,7 +1636,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p continue; //ignore! } found_library = true; -#if defined(MACOS_ENABLED) || defined(X11_ENABLED) +#if defined(MACOS_ENABLED) || defined(LINUXBSD_ENABLED) is_execute = true; #endif file = file.replace(library_to_use, binary_name + ".xcframework"); @@ -1625,7 +1679,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p f->store_buffer(data.ptr(), data.size()); } -#if defined(MACOS_ENABLED) || defined(X11_ENABLED) +#if defined(MACOS_ENABLED) || defined(LINUXBSD_ENABLED) if (is_execute) { // we need execute rights on this file chmod(file.utf8().get_data(), 0755); @@ -1783,7 +1837,10 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p ERR_FAIL_COND_V(dylibs_dir.is_null(), ERR_CANT_OPEN); CodesignData codesign_data(p_preset, p_debug); err = _walk_dir_recursive(dylibs_dir, _codesign, &codesign_data); - ERR_FAIL_COND_V(err, err); + if (err != OK) { + add_message(EXPORT_MESSAGE_ERROR, TTR("Code Signing"), TTR("Code signing failed, see editor log for details.")); + return err; + } } if (ep.step("Making .xcarchive", 3)) { @@ -1809,6 +1866,10 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p err = OS::get_singleton()->execute("xcodebuild", archive_args, &archive_str, nullptr, true); ERR_FAIL_COND_V(err, err); print_line("xcodebuild (.xcarchive):\n" + archive_str); + if (!archive_str.contains("** ARCHIVE SUCCEEDED **")) { + add_message(EXPORT_MESSAGE_ERROR, TTR("Xcode Build"), TTR("Xcode project build failed, see editor log for details.")); + return FAILED; + } if (ep.step("Making .ipa", 4)) { return ERR_SKIP; @@ -1825,9 +1886,14 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p String export_str; err = OS::get_singleton()->execute("xcodebuild", export_args, &export_str, nullptr, true); ERR_FAIL_COND_V(err, err); + print_line("xcodebuild (.ipa):\n" + export_str); + if (!export_str.contains("** EXPORT SUCCEEDED **")) { + add_message(EXPORT_MESSAGE_ERROR, TTR("Xcode Build"), TTR(".ipa export failed, see editor log for details.")); + return FAILED; + } #else - print_line(".ipa can only be built on macOS. Leaving Xcode project without building the package."); + add_message(EXPORT_MESSAGE_WARNING, TTR("Xcode Build"), TTR(".ipa can only be built on macOS. Leaving Xcode project without building the package.")); #endif return OK; @@ -1871,17 +1937,18 @@ bool EditorExportPlatformIOS::has_valid_project_configuration(const Ref<EditorEx // Validate the project configuration. - String team_id = p_preset->get("application/app_store_team_id"); - if (team_id.length() == 0) { - err += TTR("App Store Team ID not specified - cannot configure the project.") + "\n"; - valid = false; - } - - String identifier = p_preset->get("application/bundle_identifier"); - String pn_err; - if (!is_package_name_valid(identifier, &pn_err)) { - err += TTR("Invalid Identifier:") + " " + pn_err + "\n"; - valid = false; + List<ExportOption> options; + get_export_options(&options); + for (const EditorExportPlatform::ExportOption &E : options) { + if (get_export_option_visibility(p_preset.ptr(), E.option.name)) { + String warn = get_export_option_warning(p_preset.ptr(), E.option.name); + if (!warn.is_empty()) { + err += warn + "\n"; + if (E.required) { + valid = false; + } + } + } } const String etc_error = test_etc2(); @@ -1898,16 +1965,28 @@ bool EditorExportPlatformIOS::has_valid_project_configuration(const Ref<EditorEx } EditorExportPlatformIOS::EditorExportPlatformIOS() { - logo = ImageTexture::create_from_image(memnew(Image(_ios_logo))); - plugins_changed.set(); + if (EditorNode::get_singleton()) { +#ifdef MODULE_SVG_ENABLED + Ref<Image> img = memnew(Image); + const bool upsample = !Math::is_equal_approx(Math::round(EDSCALE), EDSCALE); + + ImageLoaderSVG img_loader; + img_loader.create_image_from_string(img, _ios_logo_svg, EDSCALE, upsample, false); + logo = ImageTexture::create_from_image(img); +#endif + + plugins_changed.set(); #ifndef ANDROID_ENABLED - check_for_changes_thread.start(_check_for_changes_poll_thread, this); + check_for_changes_thread.start(_check_for_changes_poll_thread, this); #endif + } } EditorExportPlatformIOS::~EditorExportPlatformIOS() { #ifndef ANDROID_ENABLED quit_request.set(); - check_for_changes_thread.wait_to_finish(); + if (check_for_changes_thread.is_started()) { + check_for_changes_thread.wait_to_finish(); + } #endif } diff --git a/platform/ios/export/export_plugin.h b/platform/ios/export/export_plugin.h index 639f2416a5..2e461c8ed6 100644 --- a/platform/ios/export/export_plugin.h +++ b/platform/ios/export/export_plugin.h @@ -1,36 +1,38 @@ -/*************************************************************************/ -/* export_plugin.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* export_plugin.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 IOS_EXPORT_PLUGIN_H #define IOS_EXPORT_PLUGIN_H +#include "godot_plugin_config.h" + #include "core/config/project_settings.h" #include "core/io/file_access.h" #include "core/io/image_loader.h" @@ -43,26 +45,28 @@ #include "editor/editor_settings.h" #include "editor/export/editor_export_platform.h" #include "main/splash.gen.h" -#include "platform/ios/logo.gen.h" -#include "string.h" - -#include "godot_plugin_config.h" +#include <string.h> #include <sys/stat.h> +// Optional environment variables for defining confidential information. If any +// of these is set, they will override the values set in the credentials file. +const String ENV_IOS_PROFILE_UUID_DEBUG = "GODOT_IOS_PROVISIONING_PROFILE_UUID_DEBUG"; +const String ENV_IOS_PROFILE_UUID_RELEASE = "GODOT_IOS_PROVISIONING_PROFILE_UUID_RELEASE"; + class EditorExportPlatformIOS : public EditorExportPlatform { GDCLASS(EditorExportPlatformIOS, EditorExportPlatform); Ref<ImageTexture> logo; // Plugins - SafeFlag plugins_changed; + mutable SafeFlag plugins_changed; #ifndef ANDROID_ENABLED Thread check_for_changes_thread; SafeFlag quit_request; #endif Mutex plugins_lock; - Vector<PluginConfigIOS> plugins; + mutable Vector<PluginConfigIOS> plugins; typedef Error (*FileHandler)(String p_file, void *p_userdata); static Error _walk_dir_recursive(Ref<DirAccess> &p_da, FileHandler p_handler, void *p_userdata); @@ -179,7 +183,9 @@ class EditorExportPlatformIOS : public EditorExportPlatform { protected: virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const override; - virtual void get_export_options(List<ExportOption> *r_options) override; + virtual void get_export_options(List<ExportOption> *r_options) const override; + virtual bool get_export_option_visibility(const EditorExportPreset *p_preset, const String &p_option) const override; + virtual String get_export_option_warning(const EditorExportPreset *p_preset, const StringName &p_name) const override; public: virtual String get_name() const override { return "iOS"; } diff --git a/platform/ios/export/godot_plugin_config.cpp b/platform/ios/export/godot_plugin_config.cpp index 42797d449b..86d5c7ef5b 100644 --- a/platform/ios/export/godot_plugin_config.cpp +++ b/platform/ios/export/godot_plugin_config.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* godot_plugin_config.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* godot_plugin_config.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "godot_plugin_config.h" diff --git a/platform/ios/export/godot_plugin_config.h b/platform/ios/export/godot_plugin_config.h index 98e8456ed5..5ff5b26ab3 100644 --- a/platform/ios/export/godot_plugin_config.h +++ b/platform/ios/export/godot_plugin_config.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* godot_plugin_config.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* godot_plugin_config.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 IOS_GODOT_PLUGIN_CONFIG_H #define IOS_GODOT_PLUGIN_CONFIG_H diff --git a/platform/ios/godot_app_delegate.h b/platform/ios/godot_app_delegate.h index 703a906bda..a9bfcbb0b2 100644 --- a/platform/ios/godot_app_delegate.h +++ b/platform/ios/godot_app_delegate.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* godot_app_delegate.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* godot_app_delegate.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ #import <UIKit/UIKit.h> diff --git a/platform/ios/godot_app_delegate.m b/platform/ios/godot_app_delegate.m index 84347f9a30..74e8705bc3 100644 --- a/platform/ios/godot_app_delegate.m +++ b/platform/ios/godot_app_delegate.m @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* godot_app_delegate.m */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* godot_app_delegate.m */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ #import "godot_app_delegate.h" diff --git a/platform/ios/godot_ios.mm b/platform/ios/godot_ios.mm index 5f3e786b8a..5e66c8b47b 100644 --- a/platform/ios/godot_ios.mm +++ b/platform/ios/godot_ios.mm @@ -1,36 +1,37 @@ -/*************************************************************************/ -/* godot_ios.mm */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* godot_ios.mm */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ + +#import "os_ios.h" #include "core/string/ustring.h" #include "main/main.h" -#include "os_ios.h" #include <stdio.h> #include <string.h> @@ -38,10 +39,6 @@ static OS_IOS *os = nullptr; -int add_path(int, char **); -int add_cmdline(int, char **); -int ios_main(int, char **, String); - int add_path(int p_argc, char **p_args) { NSString *str = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"godot_path"]; if (!str) { @@ -74,7 +71,7 @@ int add_cmdline(int p_argc, char **p_args) { return p_argc; } -int ios_main(int argc, char **argv, String data_dir, String cache_dir) { +int ios_main(int argc, char **argv) { size_t len = strlen(argv[0]); while (len--) { @@ -87,15 +84,10 @@ int ios_main(int argc, char **argv, String data_dir, String cache_dir) { char path[512]; memcpy(path, argv[0], len > sizeof(path) ? sizeof(path) : len); path[len] = 0; - printf("Path: %s\n", path); chdir(path); } - printf("godot_ios %s\n", argv[0]); - char cwd[512]; - getcwd(cwd, sizeof(cwd)); - printf("cwd %s\n", cwd); - os = new OS_IOS(data_dir, cache_dir); + os = new OS_IOS(); // We must override main when testing is enabled TEST_MAIN_OVERRIDE @@ -108,10 +100,7 @@ int ios_main(int argc, char **argv, String data_dir, String cache_dir) { argc = add_path(argc, fargv); argc = add_cmdline(argc, fargv); - printf("os created\n"); - Error err = Main::setup(fargv[0], argc - 1, &fargv[1], false); - printf("setup %i\n", err); if (err == ERR_HELP) { // Returned by --help and --version, so success. return 0; @@ -125,7 +114,6 @@ int ios_main(int argc, char **argv, String data_dir, String cache_dir) { } void ios_finish() { - printf("ios_finish\n"); Main::cleanup(); delete os; } diff --git a/platform/ios/godot_view.h b/platform/ios/godot_view.h index fcb97fa63a..b00ca37ebe 100644 --- a/platform/ios/godot_view.h +++ b/platform/ios/godot_view.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* godot_view.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* godot_view.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ #import <UIKit/UIKit.h> @@ -59,9 +59,4 @@ class String; - (void)stopRendering; - (void)startRendering; -- (void)godotTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event; -- (void)godotTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event; -- (void)godotTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event; -- (void)godotTouchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event; - @end diff --git a/platform/ios/godot_view.mm b/platform/ios/godot_view.mm index 4537dc2985..4c9a75fdc0 100644 --- a/platform/ios/godot_view.mm +++ b/platform/ios/godot_view.mm @@ -1,46 +1,46 @@ -/*************************************************************************/ -/* godot_view.mm */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* godot_view.mm */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ #import "godot_view.h" +#import "display_layer.h" +#import "display_server_ios.h" +#import "godot_view_renderer.h" + #include "core/config/project_settings.h" #include "core/os/keyboard.h" #include "core/string/ustring.h" -#import "display_layer.h" -#include "display_server_ios.h" -#import "godot_view_gesture_recognizer.h" -#import "godot_view_renderer.h" #import <CoreMotion/CoreMotion.h> -static const int max_touches = 8; +static const int max_touches = 32; static const float earth_gravity = 9.80665; @interface GodotView () { @@ -60,8 +60,6 @@ static const float earth_gravity = 9.80665; @property(strong, nonatomic) CMMotionManager *motionManager; -@property(strong, nonatomic) GodotViewGestureRecognizer *delayGestureRecognizer; - @end @implementation GodotView @@ -74,16 +72,20 @@ static const float earth_gravity = 9.80665; CALayer<DisplayLayer> *layer; if ([driverName isEqualToString:@"vulkan"]) { +#if defined(TARGET_OS_SIMULATOR) && TARGET_OS_SIMULATOR + if (@available(iOS 13, *)) { + layer = [GodotMetalLayer layer]; + } else { + return nil; + } +#else layer = [GodotMetalLayer layer]; +#endif } else if ([driverName isEqualToString:@"opengl3"]) { if (@available(iOS 13, *)) { NSLog(@"OpenGL ES is deprecated on iOS 13"); } -#if defined(TARGET_OS_SIMULATOR) && TARGET_OS_SIMULATOR - return nil; -#else layer = [GodotOpenGLLayer layer]; -#endif } else { return nil; } @@ -144,14 +146,10 @@ static const float earth_gravity = 9.80665; [self.animationTimer invalidate]; self.animationTimer = nil; } - - if (self.delayGestureRecognizer) { - self.delayGestureRecognizer = nil; - } } - (void)godot_commonInit { - self.contentScaleFactor = [UIScreen mainScreen].nativeScale; + self.contentScaleFactor = [UIScreen mainScreen].scale; [self initTouches]; @@ -167,11 +165,6 @@ static const float earth_gravity = 9.80665; self.motionManager = nil; } } - - // Initialize delay gesture recognizer - GodotViewGestureRecognizer *gestureRecognizer = [[GodotViewGestureRecognizer alloc] init]; - self.delayGestureRecognizer = gestureRecognizer; - [self addGestureRecognizer:self.delayGestureRecognizer]; } - (void)stopRendering { @@ -181,7 +174,7 @@ static const float earth_gravity = 9.80665; self.isActive = NO; - printf("******** stop animation!\n"); + print_verbose("Stop animation!"); if (self.useCADisplayLink) { [self.displayLink invalidate]; @@ -201,7 +194,7 @@ static const float earth_gravity = 9.80665; self.isActive = YES; - printf("start animation!\n"); + print_verbose("Start animation!"); if (self.useCADisplayLink) { self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(drawView)]; @@ -221,7 +214,7 @@ static const float earth_gravity = 9.80665; - (void)drawView { if (!self.isActive) { - printf("draw view not active!\n"); + print_verbose("Draw view not active!"); return; } @@ -238,7 +231,7 @@ static const float earth_gravity = 9.80665; [self.displayLink setPaused:NO]; } - [self.renderingLayer renderDisplayLayer]; + [self.renderingLayer startRenderDisplayLayer]; if (!self.renderer) { return; @@ -258,6 +251,8 @@ static const float earth_gravity = 9.80665; [self handleMotion]; [self.renderer renderOnView:self]; + + [self.renderingLayer stopRenderDisplayLayer]; } - (BOOL)canRender { @@ -341,56 +336,42 @@ static const float earth_gravity = 9.80665; } } -- (void)godotTouchesBegan:(NSSet *)touchesSet withEvent:(UIEvent *)event { - NSArray *tlist = [event.allTouches allObjects]; - for (unsigned int i = 0; i < [tlist count]; i++) { - if ([touchesSet containsObject:[tlist objectAtIndex:i]]) { - UITouch *touch = [tlist objectAtIndex:i]; - int tid = [self getTouchIDForTouch:touch]; - ERR_FAIL_COND(tid == -1); - CGPoint touchPoint = [touch locationInView:self]; - DisplayServerIOS::get_singleton()->touch_press(tid, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, true, touch.tapCount > 1); - } +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { + for (UITouch *touch in touches) { + int tid = [self getTouchIDForTouch:touch]; + ERR_FAIL_COND(tid == -1); + CGPoint touchPoint = [touch locationInView:self]; + DisplayServerIOS::get_singleton()->touch_press(tid, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, true, touch.tapCount > 1); } } -- (void)godotTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { - NSArray *tlist = [event.allTouches allObjects]; - for (unsigned int i = 0; i < [tlist count]; i++) { - if ([touches containsObject:[tlist objectAtIndex:i]]) { - UITouch *touch = [tlist objectAtIndex:i]; - int tid = [self getTouchIDForTouch:touch]; - ERR_FAIL_COND(tid == -1); - CGPoint touchPoint = [touch locationInView:self]; - CGPoint prev_point = [touch previousLocationInView:self]; - DisplayServerIOS::get_singleton()->touch_drag(tid, prev_point.x * self.contentScaleFactor, prev_point.y * self.contentScaleFactor, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor); - } +- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { + for (UITouch *touch in touches) { + int tid = [self getTouchIDForTouch:touch]; + ERR_FAIL_COND(tid == -1); + CGPoint touchPoint = [touch locationInView:self]; + CGPoint prev_point = [touch previousLocationInView:self]; + CGFloat alt = [touch altitudeAngle]; + CGVector azim = [touch azimuthUnitVectorInView:self]; + DisplayServerIOS::get_singleton()->touch_drag(tid, prev_point.x * self.contentScaleFactor, prev_point.y * self.contentScaleFactor, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, [touch force] / [touch maximumPossibleForce], Vector2(azim.dx, azim.dy) * Math::cos(alt)); } } -- (void)godotTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { - NSArray *tlist = [event.allTouches allObjects]; - for (unsigned int i = 0; i < [tlist count]; i++) { - if ([touches containsObject:[tlist objectAtIndex:i]]) { - UITouch *touch = [tlist objectAtIndex:i]; - int tid = [self getTouchIDForTouch:touch]; - ERR_FAIL_COND(tid == -1); - [self removeTouch:touch]; - CGPoint touchPoint = [touch locationInView:self]; - DisplayServerIOS::get_singleton()->touch_press(tid, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, false, false); - } +- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { + for (UITouch *touch in touches) { + int tid = [self getTouchIDForTouch:touch]; + ERR_FAIL_COND(tid == -1); + [self removeTouch:touch]; + CGPoint touchPoint = [touch locationInView:self]; + DisplayServerIOS::get_singleton()->touch_press(tid, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, false, false); } } -- (void)godotTouchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { - NSArray *tlist = [event.allTouches allObjects]; - for (unsigned int i = 0; i < [tlist count]; i++) { - if ([touches containsObject:[tlist objectAtIndex:i]]) { - UITouch *touch = [tlist objectAtIndex:i]; - int tid = [self getTouchIDForTouch:touch]; - ERR_FAIL_COND(tid == -1); - DisplayServerIOS::get_singleton()->touches_cancelled(tid); - } +- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { + for (UITouch *touch in touches) { + int tid = [self getTouchIDForTouch:touch]; + ERR_FAIL_COND(tid == -1); + DisplayServerIOS::get_singleton()->touches_canceled(tid); } [self clearTouches]; } diff --git a/platform/ios/godot_view_gesture_recognizer.mm b/platform/ios/godot_view_gesture_recognizer.mm deleted file mode 100644 index 49a92add5e..0000000000 --- a/platform/ios/godot_view_gesture_recognizer.mm +++ /dev/null @@ -1,186 +0,0 @@ -/*************************************************************************/ -/* godot_view_gesture_recognizer.mm */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ - -#import "godot_view_gesture_recognizer.h" - -#import "godot_view.h" - -#include "core/config/project_settings.h" - -// Minimum distance for touches to move to fire -// a delay timer before scheduled time. -// Should be the low enough to not cause issues with dragging -// but big enough to allow click to work. -const CGFloat kGLGestureMovementDistance = 0.5; - -@interface GodotViewGestureRecognizer () - -@property(nonatomic, readwrite, assign) NSTimeInterval delayTimeInterval; - -@end - -@interface GodotViewGestureRecognizer () - -// Timer used to delay begin touch message. -// Should work as simple emulation of UIDelayedAction -@property(strong, nonatomic) NSTimer *delayTimer; - -// Delayed touch parameters -@property(strong, nonatomic) NSSet *delayedTouches; -@property(strong, nonatomic) UIEvent *delayedEvent; - -@end - -@implementation GodotViewGestureRecognizer - -- (GodotView *)godotView { - return (GodotView *)self.view; -} - -- (instancetype)init { - self = [super init]; - - self.cancelsTouchesInView = YES; - self.delaysTouchesBegan = YES; - self.delaysTouchesEnded = YES; - self.requiresExclusiveTouchType = NO; - - self.delayTimeInterval = GLOBAL_GET("input_devices/pointing/ios/touch_delay"); - - return self; -} - -- (void)dealloc { - if (self.delayTimer) { - [self.delayTimer invalidate]; - self.delayTimer = nil; - } - - if (self.delayedTouches) { - self.delayedTouches = nil; - } - - if (self.delayedEvent) { - self.delayedEvent = nil; - } -} - -- (void)delayTouches:(NSSet *)touches andEvent:(UIEvent *)event { - [self.delayTimer fire]; - - self.delayedTouches = touches; - self.delayedEvent = event; - - self.delayTimer = [NSTimer - scheduledTimerWithTimeInterval:self.delayTimeInterval - target:self - selector:@selector(fireDelayedTouches:) - userInfo:nil - repeats:NO]; -} - -- (void)fireDelayedTouches:(id)timer { - [self.delayTimer invalidate]; - self.delayTimer = nil; - - if (self.delayedTouches) { - [self.godotView godotTouchesBegan:self.delayedTouches withEvent:self.delayedEvent]; - } - - self.delayedTouches = nil; - self.delayedEvent = nil; -} - -- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { - NSSet *cleared = [self copyClearedTouches:touches phase:UITouchPhaseBegan]; - [self delayTouches:cleared andEvent:event]; - - [super touchesBegan:touches withEvent:event]; -} - -- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { - NSSet *cleared = [self copyClearedTouches:touches phase:UITouchPhaseMoved]; - - if (self.delayTimer) { - // We should check if movement was significant enough to fire an event - // for dragging to work correctly. - for (UITouch *touch in cleared) { - CGPoint from = [touch locationInView:self.godotView]; - CGPoint to = [touch previousLocationInView:self.godotView]; - CGFloat xDistance = from.x - to.x; - CGFloat yDistance = from.y - to.y; - - CGFloat distance = sqrt(xDistance * xDistance + yDistance * yDistance); - - // Early exit, since one of touches has moved enough to fire a drag event. - if (distance > kGLGestureMovementDistance) { - [self.delayTimer fire]; - [self.godotView godotTouchesMoved:cleared withEvent:event]; - return; - } - } - - return; - } - - [self.godotView godotTouchesMoved:cleared withEvent:event]; - - [super touchesMoved:touches withEvent:event]; -} - -- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { - [self.delayTimer fire]; - - NSSet *cleared = [self copyClearedTouches:touches phase:UITouchPhaseEnded]; - [self.godotView godotTouchesEnded:cleared withEvent:event]; - - [super touchesEnded:touches withEvent:event]; -} - -- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { - [self.delayTimer fire]; - [self.godotView godotTouchesCancelled:touches withEvent:event]; - - [super touchesCancelled:touches withEvent:event]; -} - -- (NSSet *)copyClearedTouches:(NSSet *)touches phase:(UITouchPhase)phaseToSave { - NSMutableSet *cleared = [touches mutableCopy]; - - for (UITouch *touch in touches) { - if (touch.view != self.view || touch.phase != phaseToSave) { - [cleared removeObject:touch]; - } - } - - return cleared; -} - -@end diff --git a/platform/ios/godot_view_renderer.h b/platform/ios/godot_view_renderer.h index b3ee23ae4f..47e615ca02 100644 --- a/platform/ios/godot_view_renderer.h +++ b/platform/ios/godot_view_renderer.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* godot_view_renderer.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* godot_view_renderer.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ #import <UIKit/UIKit.h> diff --git a/platform/ios/godot_view_renderer.mm b/platform/ios/godot_view_renderer.mm index 140410fbef..9c56ca342f 100644 --- a/platform/ios/godot_view_renderer.mm +++ b/platform/ios/godot_view_renderer.mm @@ -1,40 +1,41 @@ -/*************************************************************************/ -/* godot_view_renderer.mm */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* godot_view_renderer.mm */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ #import "godot_view_renderer.h" +#import "display_server_ios.h" +#import "os_ios.h" + #include "core/config/project_settings.h" #include "core/os/keyboard.h" -#import "display_server_ios.h" #include "main/main.h" -#include "os_ios.h" #include "servers/audio_server.h" #import <AudioToolbox/AudioServices.h> diff --git a/platform/ios/ios.h b/platform/ios/ios.h index 0b3842b233..d488cde257 100644 --- a/platform/ios/ios.h +++ b/platform/ios/ios.h @@ -1,37 +1,38 @@ -/*************************************************************************/ -/* ios.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* ios.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 IOS_H #define IOS_H #include "core/object/class_db.h" + #import <CoreHaptics/CoreHaptics.h> class iOS : public Object { diff --git a/platform/ios/ios.mm b/platform/ios/ios.mm index 79baae028a..0a2e1fd5cd 100644 --- a/platform/ios/ios.mm +++ b/platform/ios/ios.mm @@ -1,34 +1,34 @@ -/*************************************************************************/ -/* ios.mm */ -/*************************************************************************/ -/* 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 "ios.h" +/**************************************************************************/ +/* ios.mm */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ + +#import "ios.h" #import "app_delegate.h" #import "view_controller.h" @@ -72,8 +72,8 @@ CHHapticEngine *iOS::get_haptic_engine_instance() API_AVAILABLE(ios(13)) { void iOS::vibrate_haptic_engine(float p_duration_seconds) API_AVAILABLE(ios(13)) { if (@available(iOS 13, *)) { // We need the @available check every time to make the compiler happy... if (supports_haptic_engine()) { - CHHapticEngine *haptic_engine = get_haptic_engine_instance(); - if (haptic_engine) { + CHHapticEngine *cur_haptic_engine = get_haptic_engine_instance(); + if (cur_haptic_engine) { NSDictionary *hapticDict = @{ CHHapticPatternKeyPattern : @[ @{CHHapticPatternKeyEvent : @{ @@ -88,7 +88,7 @@ void iOS::vibrate_haptic_engine(float p_duration_seconds) API_AVAILABLE(ios(13)) NSError *error; CHHapticPattern *pattern = [[CHHapticPattern alloc] initWithDictionary:hapticDict error:&error]; - [[haptic_engine createPlayerWithPattern:pattern error:&error] startAtTime:0 error:&error]; + [[cur_haptic_engine createPlayerWithPattern:pattern error:&error] startAtTime:0 error:&error]; NSLog(@"Could not vibrate using haptic engine: %@", error); } @@ -103,9 +103,9 @@ void iOS::vibrate_haptic_engine(float p_duration_seconds) API_AVAILABLE(ios(13)) void iOS::start_haptic_engine() { if (@available(iOS 13, *)) { if (supports_haptic_engine()) { - CHHapticEngine *haptic_engine = get_haptic_engine_instance(); - if (haptic_engine) { - [haptic_engine startWithCompletionHandler:^(NSError *returnedError) { + CHHapticEngine *cur_haptic_engine = get_haptic_engine_instance(); + if (cur_haptic_engine) { + [cur_haptic_engine startWithCompletionHandler:^(NSError *returnedError) { if (returnedError) { NSLog(@"Could not start haptic engine: %@", returnedError); } @@ -122,9 +122,9 @@ void iOS::start_haptic_engine() { void iOS::stop_haptic_engine() { if (@available(iOS 13, *)) { if (supports_haptic_engine()) { - CHHapticEngine *haptic_engine = get_haptic_engine_instance(); - if (haptic_engine) { - [haptic_engine stopWithCompletionHandler:^(NSError *returnedError) { + CHHapticEngine *cur_haptic_engine = get_haptic_engine_instance(); + if (cur_haptic_engine) { + [cur_haptic_engine stopWithCompletionHandler:^(NSError *returnedError) { if (returnedError) { NSLog(@"Could not stop haptic engine: %@", returnedError); } @@ -173,7 +173,7 @@ String iOS::get_rate_url(int p_app_id) const { String ret = app_url_path.replace("APP_ID", String::num(p_app_id)); - printf("returning rate url %s\n", ret.utf8().get_data()); + print_verbose(vformat("Returning rate url %s", ret)); return ret; } diff --git a/platform/ios/joypad_ios.h b/platform/ios/joypad_ios.h index 66c4b090bc..a61e9afafb 100644 --- a/platform/ios/joypad_ios.h +++ b/platform/ios/joypad_ios.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* joypad_ios.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* joypad_ios.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ #import <GameController/GameController.h> diff --git a/platform/ios/joypad_ios.mm b/platform/ios/joypad_ios.mm index e147cb2527..38d3ce728a 100644 --- a/platform/ios/joypad_ios.mm +++ b/platform/ios/joypad_ios.mm @@ -1,42 +1,41 @@ -/*************************************************************************/ -/* joypad_ios.mm */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* joypad_ios.mm */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ #import "joypad_ios.h" -#include "core/config/project_settings.h" -#include "drivers/coreaudio/audio_driver_coreaudio.h" -#include "main/main.h" - #import "godot_view.h" +#import "os_ios.h" -#include "os_ios.h" +#include "core/config/project_settings.h" +#import "drivers/coreaudio/audio_driver_coreaudio.h" +#include "main/main.h" JoypadIOS::JoypadIOS() { observer = [[JoypadIOSObserver alloc] init]; @@ -150,7 +149,7 @@ void JoypadIOS::start_processing() { int joy_id = Input::get_singleton()->get_unused_joy_id(); if (joy_id == -1) { - printf("Couldn't retrieve new joy id\n"); + print_verbose("Couldn't retrieve new joy ID."); return; } @@ -174,12 +173,12 @@ void JoypadIOS::start_processing() { GCController *controller = (GCController *)notification.object; if (!controller) { - printf("Couldn't retrieve new controller\n"); + print_verbose("Couldn't retrieve new controller."); return; } if ([[self.connectedJoypads allKeysForObject:controller] count] > 0) { - printf("Controller is already registered\n"); + print_verbose("Controller is already registered."); } else if (!self.isProcessing) { [self.joypadsQueue addObject:controller]; } else { @@ -305,6 +304,25 @@ void JoypadIOS::start_processing() { float value = gamepad.rightTrigger.value; Input::get_singleton()->joy_axis(joy_id, JoyAxis::TRIGGER_RIGHT, value); } + + if (@available(iOS 13, *)) { + // iOS uses 'buttonOptions' and 'buttonMenu' names for BACK and START joy buttons. + if (element == gamepad.buttonOptions) { + Input::get_singleton()->joy_button(joy_id, JoyButton::BACK, + gamepad.buttonOptions.isPressed); + } else if (element == gamepad.buttonMenu) { + Input::get_singleton()->joy_button(joy_id, JoyButton::START, + gamepad.buttonMenu.isPressed); + } + } + + if (@available(iOS 14, *)) { + // iOS uses 'buttonHome' for the GUIDE joy button. + if (element == gamepad.buttonHome) { + Input::get_singleton()->joy_button(joy_id, JoyButton::GUIDE, + gamepad.buttonHome.isPressed); + } + } }; } else if (controller.microGamepad != nil) { // micro gamepads were added in OS 9 and feature just 2 buttons and a d-pad diff --git a/platform/ios/godot_view_gesture_recognizer.h b/platform/ios/key_mapping_ios.h index 9fd8a6b222..6cc61175bb 100644 --- a/platform/ios/godot_view_gesture_recognizer.h +++ b/platform/ios/key_mapping_ios.h @@ -1,46 +1,46 @@ -/*************************************************************************/ -/* godot_view_gesture_recognizer.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* key_mapping_ios.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ -// GLViewGestureRecognizer allows iOS gestures to work correctly by -// emulating UIScrollView's UIScrollViewDelayedTouchesBeganGestureRecognizer. -// It catches all gestures incoming to UIView and delays them for 150ms -// (the same value used by UIScrollViewDelayedTouchesBeganGestureRecognizer) -// If touch cancellation or end message is fired it fires delayed -// begin touch immediately as well as last touch signal +#ifndef KEY_MAPPING_IOS_H +#define KEY_MAPPING_IOS_H -#import <UIKit/UIKit.h> +#include "core/os/keyboard.h" -@interface GodotViewGestureRecognizer : UIGestureRecognizer +#import <UIKit/UIKit.h> -@property(nonatomic, readonly, assign) NSTimeInterval delayTimeInterval; +class KeyMappingIOS { + KeyMappingIOS() {} -- (instancetype)init; +public: + static void initialize(); + static Key remap_key(CFIndex p_keycode); +}; -@end +#endif // KEY_MAPPING_IOS_H diff --git a/platform/ios/key_mapping_ios.mm b/platform/ios/key_mapping_ios.mm new file mode 100644 index 0000000000..d2c84884d1 --- /dev/null +++ b/platform/ios/key_mapping_ios.mm @@ -0,0 +1,186 @@ +/**************************************************************************/ +/* key_mapping_ios.mm */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ + +#import "key_mapping_ios.h" + +#include "core/templates/hash_map.h" + +struct HashMapHasherKeys { + static _FORCE_INLINE_ uint32_t hash(const Key p_key) { return hash_fmix32(static_cast<uint32_t>(p_key)); } + static _FORCE_INLINE_ uint32_t hash(const CFIndex p_key) { return hash_fmix32(p_key); } +}; + +HashMap<CFIndex, Key, HashMapHasherKeys> keyusage_map; + +void KeyMappingIOS::initialize() { + if (@available(iOS 13.4, *)) { + keyusage_map[UIKeyboardHIDUsageKeyboardA] = Key::A; + keyusage_map[UIKeyboardHIDUsageKeyboardB] = Key::B; + keyusage_map[UIKeyboardHIDUsageKeyboardC] = Key::C; + keyusage_map[UIKeyboardHIDUsageKeyboardD] = Key::D; + keyusage_map[UIKeyboardHIDUsageKeyboardE] = Key::E; + keyusage_map[UIKeyboardHIDUsageKeyboardF] = Key::F; + keyusage_map[UIKeyboardHIDUsageKeyboardG] = Key::G; + keyusage_map[UIKeyboardHIDUsageKeyboardH] = Key::H; + keyusage_map[UIKeyboardHIDUsageKeyboardI] = Key::I; + keyusage_map[UIKeyboardHIDUsageKeyboardJ] = Key::J; + keyusage_map[UIKeyboardHIDUsageKeyboardK] = Key::K; + keyusage_map[UIKeyboardHIDUsageKeyboardL] = Key::L; + keyusage_map[UIKeyboardHIDUsageKeyboardM] = Key::M; + keyusage_map[UIKeyboardHIDUsageKeyboardN] = Key::N; + keyusage_map[UIKeyboardHIDUsageKeyboardO] = Key::O; + keyusage_map[UIKeyboardHIDUsageKeyboardP] = Key::P; + keyusage_map[UIKeyboardHIDUsageKeyboardQ] = Key::Q; + keyusage_map[UIKeyboardHIDUsageKeyboardR] = Key::R; + keyusage_map[UIKeyboardHIDUsageKeyboardS] = Key::S; + keyusage_map[UIKeyboardHIDUsageKeyboardT] = Key::T; + keyusage_map[UIKeyboardHIDUsageKeyboardU] = Key::U; + keyusage_map[UIKeyboardHIDUsageKeyboardV] = Key::V; + keyusage_map[UIKeyboardHIDUsageKeyboardW] = Key::W; + keyusage_map[UIKeyboardHIDUsageKeyboardX] = Key::X; + keyusage_map[UIKeyboardHIDUsageKeyboardY] = Key::Y; + keyusage_map[UIKeyboardHIDUsageKeyboardZ] = Key::Z; + keyusage_map[UIKeyboardHIDUsageKeyboard0] = Key::KEY_0; + keyusage_map[UIKeyboardHIDUsageKeyboard1] = Key::KEY_1; + keyusage_map[UIKeyboardHIDUsageKeyboard2] = Key::KEY_2; + keyusage_map[UIKeyboardHIDUsageKeyboard3] = Key::KEY_3; + keyusage_map[UIKeyboardHIDUsageKeyboard4] = Key::KEY_4; + keyusage_map[UIKeyboardHIDUsageKeyboard5] = Key::KEY_5; + keyusage_map[UIKeyboardHIDUsageKeyboard6] = Key::KEY_6; + keyusage_map[UIKeyboardHIDUsageKeyboard7] = Key::KEY_7; + keyusage_map[UIKeyboardHIDUsageKeyboard8] = Key::KEY_8; + keyusage_map[UIKeyboardHIDUsageKeyboard9] = Key::KEY_9; + keyusage_map[UIKeyboardHIDUsageKeyboardBackslash] = Key::BACKSLASH; + keyusage_map[UIKeyboardHIDUsageKeyboardCloseBracket] = Key::BRACKETRIGHT; + keyusage_map[UIKeyboardHIDUsageKeyboardComma] = Key::COMMA; + keyusage_map[UIKeyboardHIDUsageKeyboardEqualSign] = Key::EQUAL; + keyusage_map[UIKeyboardHIDUsageKeyboardHyphen] = Key::MINUS; + keyusage_map[UIKeyboardHIDUsageKeyboardNonUSBackslash] = Key::SECTION; + keyusage_map[UIKeyboardHIDUsageKeyboardNonUSPound] = Key::ASCIITILDE; + keyusage_map[UIKeyboardHIDUsageKeyboardOpenBracket] = Key::BRACKETLEFT; + keyusage_map[UIKeyboardHIDUsageKeyboardPeriod] = Key::PERIOD; + keyusage_map[UIKeyboardHIDUsageKeyboardQuote] = Key::QUOTEDBL; + keyusage_map[UIKeyboardHIDUsageKeyboardSemicolon] = Key::SEMICOLON; + keyusage_map[UIKeyboardHIDUsageKeyboardSeparator] = Key::SECTION; + keyusage_map[UIKeyboardHIDUsageKeyboardSlash] = Key::SLASH; + keyusage_map[UIKeyboardHIDUsageKeyboardSpacebar] = Key::SPACE; + keyusage_map[UIKeyboardHIDUsageKeyboardCapsLock] = Key::CAPSLOCK; + keyusage_map[UIKeyboardHIDUsageKeyboardLeftAlt] = Key::ALT; + keyusage_map[UIKeyboardHIDUsageKeyboardLeftControl] = Key::CTRL; + keyusage_map[UIKeyboardHIDUsageKeyboardLeftShift] = Key::SHIFT; + keyusage_map[UIKeyboardHIDUsageKeyboardRightAlt] = Key::ALT; + keyusage_map[UIKeyboardHIDUsageKeyboardRightControl] = Key::CTRL; + keyusage_map[UIKeyboardHIDUsageKeyboardRightShift] = Key::SHIFT; + keyusage_map[UIKeyboardHIDUsageKeyboardScrollLock] = Key::SCROLLLOCK; + keyusage_map[UIKeyboardHIDUsageKeyboardLeftArrow] = Key::LEFT; + keyusage_map[UIKeyboardHIDUsageKeyboardRightArrow] = Key::RIGHT; + keyusage_map[UIKeyboardHIDUsageKeyboardUpArrow] = Key::UP; + keyusage_map[UIKeyboardHIDUsageKeyboardDownArrow] = Key::DOWN; + keyusage_map[UIKeyboardHIDUsageKeyboardPageUp] = Key::PAGEUP; + keyusage_map[UIKeyboardHIDUsageKeyboardPageDown] = Key::PAGEDOWN; + keyusage_map[UIKeyboardHIDUsageKeyboardHome] = Key::HOME; + keyusage_map[UIKeyboardHIDUsageKeyboardEnd] = Key::END; + keyusage_map[UIKeyboardHIDUsageKeyboardDeleteForward] = Key::KEY_DELETE; + keyusage_map[UIKeyboardHIDUsageKeyboardDeleteOrBackspace] = Key::BACKSPACE; + keyusage_map[UIKeyboardHIDUsageKeyboardEscape] = Key::ESCAPE; + keyusage_map[UIKeyboardHIDUsageKeyboardInsert] = Key::INSERT; + keyusage_map[UIKeyboardHIDUsageKeyboardReturn] = Key::ENTER; + keyusage_map[UIKeyboardHIDUsageKeyboardTab] = Key::TAB; + keyusage_map[UIKeyboardHIDUsageKeyboardF1] = Key::F1; + keyusage_map[UIKeyboardHIDUsageKeyboardF2] = Key::F2; + keyusage_map[UIKeyboardHIDUsageKeyboardF3] = Key::F3; + keyusage_map[UIKeyboardHIDUsageKeyboardF4] = Key::F4; + keyusage_map[UIKeyboardHIDUsageKeyboardF5] = Key::F5; + keyusage_map[UIKeyboardHIDUsageKeyboardF6] = Key::F6; + keyusage_map[UIKeyboardHIDUsageKeyboardF7] = Key::F7; + keyusage_map[UIKeyboardHIDUsageKeyboardF8] = Key::F8; + keyusage_map[UIKeyboardHIDUsageKeyboardF9] = Key::F9; + keyusage_map[UIKeyboardHIDUsageKeyboardF10] = Key::F10; + keyusage_map[UIKeyboardHIDUsageKeyboardF11] = Key::F11; + keyusage_map[UIKeyboardHIDUsageKeyboardF12] = Key::F12; + keyusage_map[UIKeyboardHIDUsageKeyboardF13] = Key::F13; + keyusage_map[UIKeyboardHIDUsageKeyboardF14] = Key::F14; + keyusage_map[UIKeyboardHIDUsageKeyboardF15] = Key::F15; + keyusage_map[UIKeyboardHIDUsageKeyboardF16] = Key::F16; + keyusage_map[UIKeyboardHIDUsageKeyboardF17] = Key::F17; + keyusage_map[UIKeyboardHIDUsageKeyboardF18] = Key::F18; + keyusage_map[UIKeyboardHIDUsageKeyboardF19] = Key::F19; + keyusage_map[UIKeyboardHIDUsageKeyboardF20] = Key::F20; + keyusage_map[UIKeyboardHIDUsageKeyboardF21] = Key::F21; + keyusage_map[UIKeyboardHIDUsageKeyboardF22] = Key::F22; + keyusage_map[UIKeyboardHIDUsageKeyboardF23] = Key::F23; + keyusage_map[UIKeyboardHIDUsageKeyboardF24] = Key::F24; + keyusage_map[UIKeyboardHIDUsageKeypad0] = Key::KP_0; + keyusage_map[UIKeyboardHIDUsageKeypad1] = Key::KP_1; + keyusage_map[UIKeyboardHIDUsageKeypad2] = Key::KP_2; + keyusage_map[UIKeyboardHIDUsageKeypad3] = Key::KP_3; + keyusage_map[UIKeyboardHIDUsageKeypad4] = Key::KP_4; + keyusage_map[UIKeyboardHIDUsageKeypad5] = Key::KP_5; + keyusage_map[UIKeyboardHIDUsageKeypad6] = Key::KP_6; + keyusage_map[UIKeyboardHIDUsageKeypad7] = Key::KP_7; + keyusage_map[UIKeyboardHIDUsageKeypad8] = Key::KP_8; + keyusage_map[UIKeyboardHIDUsageKeypad9] = Key::KP_9; + keyusage_map[UIKeyboardHIDUsageKeypadAsterisk] = Key::KP_MULTIPLY; + keyusage_map[UIKeyboardHIDUsageKeyboardGraveAccentAndTilde] = Key::BAR; + keyusage_map[UIKeyboardHIDUsageKeypadEnter] = Key::KP_ENTER; + keyusage_map[UIKeyboardHIDUsageKeypadHyphen] = Key::KP_SUBTRACT; + keyusage_map[UIKeyboardHIDUsageKeypadNumLock] = Key::NUMLOCK; + keyusage_map[UIKeyboardHIDUsageKeypadPeriod] = Key::KP_PERIOD; + keyusage_map[UIKeyboardHIDUsageKeypadPlus] = Key::KP_ADD; + keyusage_map[UIKeyboardHIDUsageKeypadSlash] = Key::KP_DIVIDE; + keyusage_map[UIKeyboardHIDUsageKeyboardPause] = Key::PAUSE; + keyusage_map[UIKeyboardHIDUsageKeyboardStop] = Key::STOP; + keyusage_map[UIKeyboardHIDUsageKeyboardMute] = Key::VOLUMEMUTE; + keyusage_map[UIKeyboardHIDUsageKeyboardVolumeUp] = Key::VOLUMEUP; + keyusage_map[UIKeyboardHIDUsageKeyboardVolumeDown] = Key::VOLUMEDOWN; + keyusage_map[UIKeyboardHIDUsageKeyboardFind] = Key::SEARCH; + keyusage_map[UIKeyboardHIDUsageKeyboardHelp] = Key::HELP; + keyusage_map[UIKeyboardHIDUsageKeyboardLeftGUI] = Key::META; + keyusage_map[UIKeyboardHIDUsageKeyboardRightGUI] = Key::META; + keyusage_map[UIKeyboardHIDUsageKeyboardMenu] = Key::MENU; + keyusage_map[UIKeyboardHIDUsageKeyboardPrintScreen] = Key::PRINT; + keyusage_map[UIKeyboardHIDUsageKeyboardReturnOrEnter] = Key::ENTER; + keyusage_map[UIKeyboardHIDUsageKeyboardSysReqOrAttention] = Key::SYSREQ; + keyusage_map[0x01AE] = Key::KEYBOARD; // On-screen keyboard key on smart connector keyboard. + keyusage_map[0x029D] = Key::GLOBE; // "Globe" key on smart connector / Mac keyboard. + keyusage_map[UIKeyboardHIDUsageKeyboardLANG1] = Key::JIS_EISU; + keyusage_map[UIKeyboardHIDUsageKeyboardLANG2] = Key::JIS_KANA; + } +} + +Key KeyMappingIOS::remap_key(CFIndex p_keycode) { + if (@available(iOS 13.4, *)) { + const Key *key = keyusage_map.getptr(p_keycode); + if (key) { + return *key; + } + } + return Key::NONE; +} diff --git a/platform/ios/keyboard_input_view.h b/platform/ios/keyboard_input_view.h index fc34e6a11b..4132afe641 100644 --- a/platform/ios/keyboard_input_view.h +++ b/platform/ios/keyboard_input_view.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* keyboard_input_view.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* keyboard_input_view.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ #import <UIKit/UIKit.h> diff --git a/platform/ios/keyboard_input_view.mm b/platform/ios/keyboard_input_view.mm index f031a1de22..bc6eb63ed5 100644 --- a/platform/ios/keyboard_input_view.mm +++ b/platform/ios/keyboard_input_view.mm @@ -1,38 +1,39 @@ -/*************************************************************************/ -/* keyboard_input_view.mm */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* keyboard_input_view.mm */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ #import "keyboard_input_view.h" +#import "display_server_ios.h" +#import "os_ios.h" + #include "core/os/keyboard.h" -#include "display_server_ios.h" -#include "os_ios.h" @interface GodotKeyboardInputView () <UITextViewDelegate> @@ -115,8 +116,8 @@ - (void)deleteText:(NSInteger)charactersToDelete { for (int i = 0; i < charactersToDelete; i++) { - DisplayServerIOS::get_singleton()->key(Key::BACKSPACE, true); - DisplayServerIOS::get_singleton()->key(Key::BACKSPACE, false); + DisplayServerIOS::get_singleton()->key(Key::BACKSPACE, 0, Key::BACKSPACE, Key::NONE, 0, true); + DisplayServerIOS::get_singleton()->key(Key::BACKSPACE, 0, Key::BACKSPACE, Key::NONE, 0, false); } } @@ -126,20 +127,18 @@ for (int i = 0; i < characters.size(); i++) { int character = characters[i]; - - switch (character) { - case 10: - character = (int)Key::ENTER; - break; - case 8198: - character = (int)Key::SPACE; - break; - default: - break; + Key key = Key::NONE; + + if (character == '\t') { // 0x09 + key = Key::TAB; + } else if (character == '\n') { // 0x0A + key = Key::ENTER; + } else if (character == 0x2006) { + key = Key::SPACE; } - DisplayServerIOS::get_singleton()->key((Key)character, true); - DisplayServerIOS::get_singleton()->key((Key)character, false); + DisplayServerIOS::get_singleton()->key(key, character, key, Key::NONE, 0, true); + DisplayServerIOS::get_singleton()->key(key, character, key, Key::NONE, 0, false); } } diff --git a/platform/ios/logo.png b/platform/ios/logo.png Binary files differdeleted file mode 100644 index 966d8aa70a..0000000000 --- a/platform/ios/logo.png +++ /dev/null diff --git a/platform/ios/logo.svg b/platform/ios/logo.svg new file mode 100644 index 0000000000..47a72bcf49 --- /dev/null +++ b/platform/ios/logo.svg @@ -0,0 +1 @@ +<svg height="32" width="32" xmlns="http://www.w3.org/2000/svg"><path d="M1 23.27h2.504V12.61H1zm1.247-12.057c.784 0 1.398-.603 1.398-1.358 0-.764-.614-1.367-1.398-1.367-.774 0-1.388.603-1.388 1.367 0 .755.614 1.358 1.388 1.358zm9.594-2.695c-4.233 0-6.888 2.886-6.888 7.502s2.654 7.492 6.888 7.492c4.224 0 6.88-2.876 6.88-7.492s-2.656-7.502-6.88-7.502zm0 2.212c2.585 0 4.234 2.052 4.234 5.29 0 3.228-1.649 5.28-4.234 5.28-2.594 0-4.233-2.052-4.233-5.28 0-3.238 1.639-5.29 4.233-5.29zm7.936 8.458c.11 2.675 2.303 4.324 5.641 4.324 3.51 0 5.723-1.73 5.723-4.485 0-2.162-1.247-3.379-4.194-4.053l-1.67-.382c-1.78-.422-2.513-.985-2.513-1.95 0-1.208 1.106-2.012 2.745-2.012 1.66 0 2.796.814 2.916 2.172H30.9c-.06-2.554-2.172-4.284-5.37-4.284-3.158 0-5.4 1.74-5.4 4.314 0 2.072 1.267 3.36 3.942 3.973l1.88.442c1.83.433 2.575 1.036 2.575 2.082 0 1.207-1.217 2.072-2.967 2.072-1.77 0-3.107-.875-3.268-2.213h-2.514z" fill="#bfbfbf"/></svg> diff --git a/platform/ios/main.m b/platform/ios/main.m index acfa7ab731..33b1034d98 100644 --- a/platform/ios/main.m +++ b/platform/ios/main.m @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* main.m */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* main.m */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ #import "godot_app_delegate.h" @@ -42,15 +42,12 @@ int main(int argc, char *argv[]) { setenv("MVK_CONFIG_FULL_IMAGE_VIEW_SWIZZLE", "1", 1); #endif - printf("*********** main.m\n"); gargc = argc; gargv = argv; - printf("running app main\n"); @autoreleasepool { NSString *className = NSStringFromClass([GodotApplicalitionDelegate class]); UIApplicationMain(argc, argv, nil, className); } - printf("main done\n"); return 0; } diff --git a/platform/ios/os_ios.h b/platform/ios/os_ios.h index 400040875f..9dc5e11497 100644 --- a/platform/ios/os_ios.h +++ b/platform/ios/os_ios.h @@ -1,48 +1,50 @@ -/*************************************************************************/ -/* os_ios.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* os_ios.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 OS_IOS_H #define OS_IOS_H #ifdef IOS_ENABLED -#include "drivers/coreaudio/audio_driver_coreaudio.h" +#import "ios.h" +#import "joypad_ios.h" + +#import "drivers/coreaudio/audio_driver_coreaudio.h" #include "drivers/unix/os_unix.h" -#include "ios.h" -#include "joypad_ios.h" #include "servers/audio_server.h" #include "servers/rendering/renderer_compositor.h" #if defined(VULKAN_ENABLED) +#import "vulkan_context_ios.h" + #include "drivers/vulkan/rendering_device_vulkan.h" -#include "platform/ios/vulkan_context_ios.h" #endif class OS_IOS : public OS_Unix { @@ -71,17 +73,20 @@ private: virtual void finalize() override; - String user_data_dir; - String cache_dir; - bool is_focused = false; + CGFloat _weight_to_ct(int p_weight) const; + CGFloat _stretch_to_ct(int p_stretch) const; + String _get_default_fontname(const String &p_font_name) const; + + static _FORCE_INLINE_ String get_framework_executable(const String &p_path); + void deinitialize_modules(); public: static OS_IOS *get_singleton(); - OS_IOS(String p_data_dir, String p_cache_dir); + OS_IOS(); ~OS_IOS(); void initialize_modules(); @@ -93,7 +98,8 @@ public: virtual void alert(const String &p_alert, const String &p_title = "ALERT!") override; virtual Vector<String> get_system_fonts() const override; - virtual String get_system_font_path(const String &p_font_name, bool p_bold = false, bool p_italic = false) const override; + virtual Vector<String> get_system_font_path_for_text(const String &p_font_name, const String &p_text, const String &p_locale = String(), const String &p_script = String(), int p_weight = 400, int p_stretch = 100, bool p_italic = false) const override; + virtual String get_system_font_path(const String &p_font_name, int p_weight = 400, int p_stretch = 100, bool p_italic = false) const override; virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false, String *r_resolved_path = nullptr) override; virtual Error close_dynamic_library(void *p_library_handle) override; @@ -106,7 +112,6 @@ public: virtual Error shell_open(String p_uri) override; - void set_user_data_dir(String p_dir); virtual String get_user_data_dir() const override; virtual String get_cache_path() const override; diff --git a/platform/ios/os_ios.mm b/platform/ios/os_ios.mm index b6b94d2f5e..461c226070 100644 --- a/platform/ios/os_ios.mm +++ b/platform/ios/os_ios.mm @@ -1,47 +1,48 @@ -/*************************************************************************/ -/* os_ios.mm */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* os_ios.mm */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ + +#import "os_ios.h" #ifdef IOS_ENABLED -#include "os_ios.h" - #import "app_delegate.h" +#import "display_server_ios.h" +#import "godot_view.h" +#import "view_controller.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_ios.h" #include "drivers/unix/syslog_logger.h" -#import "godot_view.h" #include "main/main.h" -#import "view_controller.h" #import <AudioToolbox/AudioServices.h> #import <CoreText/CoreText.h> @@ -51,6 +52,7 @@ #if defined(VULKAN_ENABLED) #include "servers/rendering/renderer_rd/renderer_compositor_rd.h" + #import <QuartzCore/CAMetalLayer.h> #ifdef USE_VOLK #include <volk.h> @@ -90,7 +92,7 @@ OS_IOS *OS_IOS::get_singleton() { return (OS_IOS *)OS::get_singleton(); } -OS_IOS::OS_IOS(String p_data_dir, String p_cache_dir) { +OS_IOS::OS_IOS() { for (int i = 0; i < ios_init_callbacks_count; ++i) { ios_init_callbacks[i](); } @@ -101,11 +103,6 @@ OS_IOS::OS_IOS(String p_data_dir, String p_cache_dir) { main_loop = nullptr; - // can't call set_data_dir from here, since it requires DirAccess - // which is initialized in initialize_core - user_data_dir = p_data_dir; - cache_dir = p_cache_dir; - Vector<Logger *> loggers; loggers.push_back(memnew(SyslogLogger)); #ifdef DEBUG_ENABLED @@ -130,8 +127,6 @@ void OS_IOS::alert(const String &p_alert, const String &p_title) { void OS_IOS::initialize_core() { OS_Unix::initialize_core(); - - set_user_data_dir(user_data_dir); } void OS_IOS::initialize() { @@ -205,8 +200,31 @@ void OS_IOS::finalize() { // MARK: Dynamic Libraries +_FORCE_INLINE_ String OS_IOS::get_framework_executable(const String &p_path) { + Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + + // Read framework bundle to get executable name. + NSURL *url = [NSURL fileURLWithPath:@(p_path.utf8().get_data())]; + NSBundle *bundle = [NSBundle bundleWithURL:url]; + if (bundle) { + String exe_path = String::utf8([[bundle executablePath] UTF8String]); + if (da->file_exists(exe_path)) { + return exe_path; + } + } + + // Try default executable name (invalid framework). + if (da->dir_exists(p_path) && da->file_exists(p_path.path_join(p_path.get_file().get_basename()))) { + return p_path.path_join(p_path.get_file().get_basename()); + } + + // Not a framework, try loading as .dylib. + return p_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) { + // Static xcframework. p_library_handle = RTLD_SELF; if (r_resolved_path != nullptr) { @@ -215,7 +233,37 @@ Error OS_IOS::open_dynamic_library(const String p_path, void *&p_library_handle, return OK; } - return OS_Unix::open_dynamic_library(p_path, p_library_handle, p_also_set_library_path, r_resolved_path); + + String path = get_framework_executable(p_path); + + if (!FileAccess::exists(path)) { + // Load .dylib or framework from within the executable path. + path = get_framework_executable(get_executable_path().get_base_dir().path_join(p_path.get_file())); + } + + if (!FileAccess::exists(path)) { + // Load .dylib converted to framework from within the executable path. + path = get_framework_executable(get_executable_path().get_base_dir().path_join(p_path.get_file().get_basename() + ".framework")); + } + + if (!FileAccess::exists(path)) { + // Load .dylib or framework from a standard iOS location. + path = get_framework_executable(get_executable_path().get_base_dir().path_join("Frameworks").path_join(p_path.get_file())); + } + + if (!FileAccess::exists(path)) { + // Load .dylib converted to framework from a standard iOS location. + path = get_framework_executable(get_executable_path().get_base_dir().path_join("Frameworks").path_join(p_path.get_file().get_basename() + ".framework")); + } + + p_library_handle = dlopen(path.utf8().get_data(), RTLD_NOW); + ERR_FAIL_COND_V_MSG(!p_library_handle, ERR_CANT_OPEN, "Can't open dynamic library: " + p_path + ", error: " + dlerror() + "."); + + if (r_resolved_path != nullptr) { + *r_resolved_path = path; + } + + return OK; } Error OS_IOS::close_dynamic_library(void *p_library_handle) { @@ -266,25 +314,33 @@ Error OS_IOS::shell_open(String p_uri) { return ERR_CANT_OPEN; } - printf("opening url %s\n", p_uri.utf8().get_data()); + print_verbose(vformat("Opening URL %s", p_uri)); [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil]; return OK; } -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 OS_IOS::get_user_data_dir() const { - return user_data_dir; + static String ret; + if (ret.is_empty()) { + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); + if (paths && [paths count] >= 1) { + ret.parse_utf8([[paths firstObject] UTF8String]); + } + } + return ret; } String OS_IOS::get_cache_path() const { - return cache_dir; + static String ret; + if (ret.is_empty()) { + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); + if (paths && [paths count] >= 1) { + ret.parse_utf8([[paths firstObject] UTF8String]); + } + } + return ret; } String OS_IOS::get_locale() const { @@ -333,9 +389,7 @@ Vector<String> OS_IOS::get_system_fonts() const { return ret; } -String OS_IOS::get_system_font_path(const String &p_font_name, bool p_bold, bool p_italic) const { - String ret; - +String OS_IOS::_get_default_fontname(const String &p_font_name) const { String font_name = p_font_name; if (font_name.to_lower() == "sans-serif") { font_name = "Helvetica"; @@ -348,21 +402,153 @@ String OS_IOS::get_system_font_path(const String &p_font_name, bool p_bold, bool } else if (font_name.to_lower() == "cursive") { font_name = "Apple Chancery"; }; + return font_name; +} + +CGFloat OS_IOS::_weight_to_ct(int p_weight) const { + if (p_weight < 150) { + return -0.80; + } else if (p_weight < 250) { + return -0.60; + } else if (p_weight < 350) { + return -0.40; + } else if (p_weight < 450) { + return 0.0; + } else if (p_weight < 550) { + return 0.23; + } else if (p_weight < 650) { + return 0.30; + } else if (p_weight < 750) { + return 0.40; + } else if (p_weight < 850) { + return 0.56; + } else if (p_weight < 925) { + return 0.62; + } else { + return 1.00; + } +} + +CGFloat OS_IOS::_stretch_to_ct(int p_stretch) const { + if (p_stretch < 56) { + return -0.5; + } else if (p_stretch < 69) { + return -0.37; + } else if (p_stretch < 81) { + return -0.25; + } else if (p_stretch < 93) { + return -0.13; + } else if (p_stretch < 106) { + return 0.0; + } else if (p_stretch < 137) { + return 0.13; + } else if (p_stretch < 144) { + return 0.25; + } else if (p_stretch < 162) { + return 0.37; + } else { + return 0.5; + } +} + +Vector<String> OS_IOS::get_system_font_path_for_text(const String &p_font_name, const String &p_text, const String &p_locale, const String &p_script, int p_weight, int p_stretch, bool p_italic) const { + Vector<String> ret; + String font_name = _get_default_fontname(p_font_name); + + CFStringRef name = CFStringCreateWithCString(kCFAllocatorDefault, font_name.utf8().get_data(), kCFStringEncodingUTF8); + CTFontSymbolicTraits traits = 0; + if (p_weight >= 700) { + traits |= kCTFontBoldTrait; + } + if (p_italic) { + traits |= kCTFontItalicTrait; + } + if (p_stretch < 100) { + traits |= kCTFontCondensedTrait; + } else if (p_stretch > 100) { + traits |= kCTFontExpandedTrait; + } + + CFNumberRef sym_traits = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &traits); + CFMutableDictionaryRef traits_dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, nullptr, nullptr); + CFDictionaryAddValue(traits_dict, kCTFontSymbolicTrait, sym_traits); + + CGFloat weight = _weight_to_ct(p_weight); + CFNumberRef font_weight = CFNumberCreate(kCFAllocatorDefault, kCFNumberCGFloatType, &weight); + CFDictionaryAddValue(traits_dict, kCTFontWeightTrait, font_weight); + + CGFloat stretch = _stretch_to_ct(p_stretch); + CFNumberRef font_stretch = CFNumberCreate(kCFAllocatorDefault, kCFNumberCGFloatType, &stretch); + CFDictionaryAddValue(traits_dict, kCTFontWidthTrait, font_stretch); + + CFMutableDictionaryRef attributes = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, nullptr, nullptr); + CFDictionaryAddValue(attributes, kCTFontFamilyNameAttribute, name); + CFDictionaryAddValue(attributes, kCTFontTraitsAttribute, traits_dict); + + CTFontDescriptorRef font = CTFontDescriptorCreateWithAttributes(attributes); + if (font) { + CTFontRef family = CTFontCreateWithFontDescriptor(font, 0, nullptr); + CFStringRef string = CFStringCreateWithCString(kCFAllocatorDefault, p_text.utf8().get_data(), kCFStringEncodingUTF8); + CFRange range = CFRangeMake(0, CFStringGetLength(string)); + CTFontRef fallback_family = CTFontCreateForString(family, string, range); + if (fallback_family) { + CTFontDescriptorRef fallback_font = CTFontCopyFontDescriptor(fallback_family); + if (fallback_font) { + CFURLRef url = (CFURLRef)CTFontDescriptorCopyAttribute(fallback_font, kCTFontURLAttribute); + if (url) { + NSString *font_path = [NSString stringWithString:[(__bridge NSURL *)url path]]; + ret.push_back(String::utf8([font_path UTF8String])); + CFRelease(url); + } + CFRelease(fallback_font); + } + CFRelease(fallback_family); + } + CFRelease(string); + CFRelease(font); + } + + CFRelease(attributes); + CFRelease(traits_dict); + CFRelease(sym_traits); + CFRelease(font_stretch); + CFRelease(font_weight); + CFRelease(name); + + return ret; +} + +String OS_IOS::get_system_font_path(const String &p_font_name, int p_weight, int p_stretch, bool p_italic) const { + String ret; + String font_name = _get_default_fontname(p_font_name); CFStringRef name = CFStringCreateWithCString(kCFAllocatorDefault, font_name.utf8().get_data(), kCFStringEncodingUTF8); CTFontSymbolicTraits traits = 0; - if (p_bold) { + if (p_weight >= 700) { traits |= kCTFontBoldTrait; } if (p_italic) { traits |= kCTFontItalicTrait; } + if (p_stretch < 100) { + traits |= kCTFontCondensedTrait; + } else if (p_stretch > 100) { + traits |= kCTFontExpandedTrait; + } CFNumberRef sym_traits = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &traits); CFMutableDictionaryRef traits_dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, nullptr, nullptr); CFDictionaryAddValue(traits_dict, kCTFontSymbolicTrait, sym_traits); + CGFloat weight = _weight_to_ct(p_weight); + CFNumberRef font_weight = CFNumberCreate(kCFAllocatorDefault, kCFNumberCGFloatType, &weight); + CFDictionaryAddValue(traits_dict, kCTFontWeightTrait, font_weight); + + CGFloat stretch = _stretch_to_ct(p_stretch); + CFNumberRef font_stretch = CFNumberCreate(kCFAllocatorDefault, kCFNumberCGFloatType, &stretch); + CFDictionaryAddValue(traits_dict, kCTFontWidthTrait, font_stretch); + CFMutableDictionaryRef attributes = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, nullptr, nullptr); CFDictionaryAddValue(attributes, kCTFontFamilyNameAttribute, name); CFDictionaryAddValue(attributes, kCTFontTraitsAttribute, traits_dict); @@ -381,6 +567,8 @@ String OS_IOS::get_system_font_path(const String &p_font_name, bool p_bold, bool CFRelease(attributes); CFRelease(traits_dict); CFRelease(sym_traits); + CFRelease(font_stretch); + CFRelease(font_weight); CFRelease(name); return ret; diff --git a/platform/ios/platform_config.h b/platform/ios/platform_config.h index 3af08b0d65..fc0e165d6b 100644 --- a/platform/ios/platform_config.h +++ b/platform/ios/platform_config.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* platform_config.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* platform_config.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 <alloca.h> diff --git a/platform/ios/tts_ios.h b/platform/ios/tts_ios.h index 064316b0b2..217f55da66 100644 --- a/platform/ios/tts_ios.h +++ b/platform/ios/tts_ios.h @@ -1,48 +1,48 @@ -/*************************************************************************/ -/* tts_ios.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* tts_ios.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 TTS_IOS_H #define TTS_IOS_H +#include "core/string/ustring.h" +#include "core/templates/hash_map.h" +#include "core/templates/list.h" +#include "core/variant/array.h" +#include "servers/display_server.h" + #if __has_include(<AVFAudio/AVSpeechSynthesis.h>) #import <AVFAudio/AVSpeechSynthesis.h> #else #import <AVFoundation/AVFoundation.h> #endif -#include "core/string/ustring.h" -#include "core/templates/list.h" -#include "core/templates/rb_map.h" -#include "core/variant/array.h" -#include "servers/display_server.h" - @interface TTS_IOS : NSObject <AVSpeechSynthesizerDelegate> { bool speaking; HashMap<id, int> ids; diff --git a/platform/ios/tts_ios.mm b/platform/ios/tts_ios.mm index 8319cad117..33b30b17c9 100644 --- a/platform/ios/tts_ios.mm +++ b/platform/ios/tts_ios.mm @@ -1,34 +1,34 @@ -/*************************************************************************/ -/* tts_ios.mm */ -/*************************************************************************/ -/* 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 "tts_ios.h" +/**************************************************************************/ +/* tts_ios.mm */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ + +#import "tts_ios.h" @implementation TTS_IOS diff --git a/platform/ios/view_controller.h b/platform/ios/view_controller.h index c8b37a4d11..e641d761d9 100644 --- a/platform/ios/view_controller.h +++ b/platform/ios/view_controller.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* view_controller.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* view_controller.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ #import <UIKit/UIKit.h> diff --git a/platform/ios/view_controller.mm b/platform/ios/view_controller.mm index 53c5d3d0b4..0ef61da646 100644 --- a/platform/ios/view_controller.mm +++ b/platform/ios/view_controller.mm @@ -1,40 +1,43 @@ -/*************************************************************************/ -/* view_controller.mm */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* view_controller.mm */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ #import "view_controller.h" -#include "core/config/project_settings.h" -#include "display_server_ios.h" + +#import "display_server_ios.h" #import "godot_view.h" #import "godot_view_renderer.h" +#import "key_mapping_ios.h" #import "keyboard_input_view.h" -#include "os_ios.h" +#import "os_ios.h" + +#include "core/config/project_settings.h" #import <AVFoundation/AVFoundation.h> #import <GameController/GameController.h> @@ -54,6 +57,64 @@ return (GodotView *)self.view; } +- (void)pressesBegan:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event { + [super pressesBegan:presses withEvent:event]; + + if (!DisplayServerIOS::get_singleton() || DisplayServerIOS::get_singleton()->is_keyboard_active()) { + return; + } + if (@available(iOS 13.4, *)) { + for (UIPress *press in presses) { + String u32lbl = String::utf8([press.key.charactersIgnoringModifiers UTF8String]); + String u32text = String::utf8([press.key.characters UTF8String]); + Key key = KeyMappingIOS::remap_key(press.key.keyCode); + + if (press.key.keyCode == 0 && u32text.is_empty() && u32lbl.is_empty()) { + continue; + } + + char32_t us = 0; + if (!u32lbl.is_empty() && !u32lbl.begins_with("UIKey")) { + us = u32lbl[0]; + } + + if (!u32text.is_empty() && !u32text.begins_with("UIKey")) { + for (int i = 0; i < u32text.length(); i++) { + const char32_t c = u32text[i]; + DisplayServerIOS::get_singleton()->key(fix_keycode(us, key), c, fix_key_label(us, key), key, press.key.modifierFlags, true); + } + } else { + DisplayServerIOS::get_singleton()->key(fix_keycode(us, key), 0, fix_key_label(us, key), key, press.key.modifierFlags, true); + } + } + } +} + +- (void)pressesEnded:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event { + [super pressesEnded:presses withEvent:event]; + + if (!DisplayServerIOS::get_singleton() || DisplayServerIOS::get_singleton()->is_keyboard_active()) { + return; + } + if (@available(iOS 13.4, *)) { + for (UIPress *press in presses) { + String u32lbl = String::utf8([press.key.charactersIgnoringModifiers UTF8String]); + Key key = KeyMappingIOS::remap_key(press.key.keyCode); + + if (press.key.keyCode == 0 && u32lbl.is_empty()) { + continue; + } + + char32_t us = 0; + if (!u32lbl.is_empty() && !u32lbl.begins_with("UIKey")) { + us = u32lbl[0]; + } + + DisplayServerIOS::get_singleton()->key(fix_keycode(us, key), 0, fix_key_label(us, key), key, press.key.modifierFlags, false); + } + } +} + - (void)loadView { GodotView *view = [[GodotView alloc] init]; GodotViewRenderer *renderer = [[GodotViewRenderer alloc] init]; @@ -91,7 +152,7 @@ - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; - printf("*********** did receive memory warning!\n"); + print_verbose("Did receive memory warning!"); } - (void)viewDidLoad { @@ -106,11 +167,11 @@ } - (void)observeKeyboard { - printf("******** setting up keyboard input view\n"); + print_verbose("Setting up keyboard input view."); self.keyboardView = [GodotKeyboardInputView new]; [self.view addSubview:self.keyboardView]; - printf("******** adding observer for keyboard show/hide\n"); + print_verbose("Adding observer for keyboard show/hide."); [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardOnScreen:) diff --git a/platform/ios/vulkan_context_ios.h b/platform/ios/vulkan_context_ios.h index 3849c8ba8a..58dad4aad6 100644 --- a/platform/ios/vulkan_context_ios.h +++ b/platform/ios/vulkan_context_ios.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* vulkan_context_ios.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* vulkan_context_ios.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 VULKAN_CONTEXT_IOS_H #define VULKAN_CONTEXT_IOS_H diff --git a/platform/ios/vulkan_context_ios.mm b/platform/ios/vulkan_context_ios.mm index 81b021e758..56f1894e06 100644 --- a/platform/ios/vulkan_context_ios.mm +++ b/platform/ios/vulkan_context_ios.mm @@ -1,36 +1,37 @@ -/*************************************************************************/ -/* vulkan_context_ios.mm */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* vulkan_context_ios.mm */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ + +#import "vulkan_context_ios.h" #ifdef VULKAN_ENABLED -#include "vulkan_context_ios.h" #ifdef USE_VOLK #include <volk.h> #else diff --git a/platform/linuxbsd/README.md b/platform/linuxbsd/README.md index efa8682062..c4f287cc6c 100644 --- a/platform/linuxbsd/README.md +++ b/platform/linuxbsd/README.md @@ -7,7 +7,7 @@ used by this platform. ## Documentation -- [Compiling for Linux/*BSD](https://docs.godotengine.org/en/latest/development/compiling/compiling_for_linuxbsd.html) +- [Compiling for Linux/*BSD](https://docs.godotengine.org/en/latest/contributing/development/compiling/compiling_for_linuxbsd.html) - Instructions on building this platform port from source. - [Exporting for Linux/*BSD](https://docs.godotengine.org/en/latest/tutorials/export/exporting_for_linux.html) - Instructions on using the compiled export templates to export a project. diff --git a/platform/linuxbsd/SCsub b/platform/linuxbsd/SCsub index fcd739cdc9..4dd74ff9d0 100644 --- a/platform/linuxbsd/SCsub +++ b/platform/linuxbsd/SCsub @@ -13,20 +13,28 @@ common_linuxbsd = [ "freedesktop_screensaver.cpp", ] +if env["use_sowrap"]: + common_linuxbsd.append("xkbcommon-so_wrap.c") + if env["x11"]: common_linuxbsd += SConscript("x11/SCsub") if env["speechd"]: - common_linuxbsd.append(["speechd-so_wrap.c", "tts_linux.cpp"]) + common_linuxbsd.append("tts_linux.cpp") + if env["use_sowrap"]: + common_linuxbsd.append("speechd-so_wrap.c") if env["fontconfig"]: - common_linuxbsd.append("fontconfig-so_wrap.c") + if env["use_sowrap"]: + common_linuxbsd.append("fontconfig-so_wrap.c") if env["udev"]: - common_linuxbsd.append("libudev-so_wrap.c") + if env["use_sowrap"]: + common_linuxbsd.append("libudev-so_wrap.c") if env["dbus"]: - common_linuxbsd.append("dbus-so_wrap.c") + if env["use_sowrap"]: + common_linuxbsd.append("dbus-so_wrap.c") prog = env.add_program("#bin/godot", ["godot_linuxbsd.cpp"] + common_linuxbsd) diff --git a/platform/linuxbsd/crash_handler_linuxbsd.cpp b/platform/linuxbsd/crash_handler_linuxbsd.cpp index 8c8c8588b8..3a245460b4 100644 --- a/platform/linuxbsd/crash_handler_linuxbsd.cpp +++ b/platform/linuxbsd/crash_handler_linuxbsd.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* crash_handler_linuxbsd.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* crash_handler_linuxbsd.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "crash_handler_linuxbsd.h" @@ -44,6 +44,7 @@ #include <cxxabi.h> #include <dlfcn.h> #include <execinfo.h> +#include <link.h> #include <signal.h> #include <stdlib.h> @@ -79,7 +80,33 @@ static void handle_crash(int sig) { } print_error(vformat("Dumping the backtrace. %s", msg)); char **strings = backtrace_symbols(bt_buffer, size); + // PIE executable relocation, zero for non-PIE executables +#ifdef __GLIBC__ + // This is a glibc only thing apparently. + uintptr_t relocation = _r_debug.r_map->l_addr; +#else + // Non glibc systems apparently don't give PIE relocation info. + uintptr_t relocation = 0; +#endif //__GLIBC__ if (strings) { + List<String> args; + for (size_t i = 0; i < size; i++) { + char str[1024]; + snprintf(str, 1024, "%p", (void *)((uintptr_t)bt_buffer[i] - relocation)); + args.push_back(str); + } + args.push_back("-e"); + args.push_back(_execpath); + + // Try to get the file/line number using addr2line + int ret; + String output = ""; + Error err = OS::get_singleton()->execute(String("addr2line"), args, &output, &ret); + Vector<String> addr2line_results; + if (err == OK) { + addr2line_results = output.substr(0, output.length() - 1).split("\n", false); + } + for (size_t i = 1; i < size; i++) { char fname[1024]; Dl_info info; @@ -102,24 +129,7 @@ static void handle_crash(int sig) { } } - List<String> args; - - char str[1024]; - snprintf(str, 1024, "%p", bt_buffer[i]); - args.push_back(str); - args.push_back("-e"); - args.push_back(_execpath); - - String output = ""; - - // Try to get the file/line number using addr2line - int ret; - Error err = OS::get_singleton()->execute(String("addr2line"), args, &output, &ret); - if (err == OK) { - output = output.substr(0, output.length() - 1); - } - - print_error(vformat("[%d] %s (%s)", (int64_t)i, fname, output)); + print_error(vformat("[%d] %s (%s)", (int64_t)i, fname, err == OK ? addr2line_results[i] : "")); } free(strings); diff --git a/platform/linuxbsd/crash_handler_linuxbsd.h b/platform/linuxbsd/crash_handler_linuxbsd.h index 1b77352cca..684f62b249 100644 --- a/platform/linuxbsd/crash_handler_linuxbsd.h +++ b/platform/linuxbsd/crash_handler_linuxbsd.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* crash_handler_linuxbsd.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* crash_handler_linuxbsd.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 CRASH_HANDLER_LINUXBSD_H #define CRASH_HANDLER_LINUXBSD_H diff --git a/platform/linuxbsd/dbus-so_wrap.c b/platform/linuxbsd/dbus-so_wrap.c index 0876bc88b0..4aec9dc48f 100644 --- a/platform/linuxbsd/dbus-so_wrap.c +++ b/platform/linuxbsd/dbus-so_wrap.c @@ -1,7 +1,7 @@ // This file is generated. Do not edit! // see https://github.com/hpvb/dynload-wrapper for details -// generated by ./generate-wrapper.py 0.3 on 2022-07-29 07:23:21 -// flags: ./generate-wrapper.py --include /usr/include/dbus-1.0/dbus/dbus.h --sys-include <dbus/dbus.h> --soname libdbus-1.so --init-name dbus --output-header dbus-so_wrap.h --output-implementation dbus-so_wrap.c +// generated by generate-wrapper.py 0.3 on 2023-01-12 10:26:35 +// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/dbus/dbus.h --sys-include "thirdparty/linuxbsd_headers/dbus/dbus.h" --soname libdbus-1.so.3 --init-name dbus --output-header ./platform/linuxbsd/dbus-so_wrap.h --output-implementation ./platform/linuxbsd/dbus-so_wrap.c // #include <stdint.h> @@ -243,7 +243,7 @@ #define dbus_validate_utf8 dbus_validate_utf8_dylibloader_orig_dbus #define dbus_threads_init dbus_threads_init_dylibloader_orig_dbus #define dbus_threads_init_default dbus_threads_init_default_dylibloader_orig_dbus -#include <dbus/dbus.h> +#include "thirdparty/linuxbsd_headers/dbus/dbus.h" #undef dbus_error_init #undef dbus_error_free #undef dbus_set_error @@ -725,7 +725,7 @@ dbus_bool_t (*dbus_threads_init_default_dylibloader_wrapper_dbus)( void); int initialize_dbus(int verbose) { void *handle; char *error; - handle = dlopen("libdbus-1.so", RTLD_LAZY); + handle = dlopen("libdbus-1.so.3", RTLD_LAZY); if (!handle) { if (verbose) { fprintf(stderr, "%s\n", dlerror()); diff --git a/platform/linuxbsd/dbus-so_wrap.h b/platform/linuxbsd/dbus-so_wrap.h index 52e1dd300c..2c63757932 100644 --- a/platform/linuxbsd/dbus-so_wrap.h +++ b/platform/linuxbsd/dbus-so_wrap.h @@ -2,8 +2,8 @@ #define DYLIBLOAD_WRAPPER_DBUS // This file is generated. Do not edit! // see https://github.com/hpvb/dynload-wrapper for details -// generated by ./generate-wrapper.py 0.3 on 2022-07-29 07:23:21 -// flags: ./generate-wrapper.py --include /usr/include/dbus-1.0/dbus/dbus.h --sys-include <dbus/dbus.h> --soname libdbus-1.so --init-name dbus --output-header dbus-so_wrap.h --output-implementation dbus-so_wrap.c +// generated by generate-wrapper.py 0.3 on 2023-01-12 10:26:35 +// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/dbus/dbus.h --sys-include "thirdparty/linuxbsd_headers/dbus/dbus.h" --soname libdbus-1.so.3 --init-name dbus --output-header ./platform/linuxbsd/dbus-so_wrap.h --output-implementation ./platform/linuxbsd/dbus-so_wrap.c // #include <stdint.h> @@ -245,7 +245,7 @@ #define dbus_validate_utf8 dbus_validate_utf8_dylibloader_orig_dbus #define dbus_threads_init dbus_threads_init_dylibloader_orig_dbus #define dbus_threads_init_default dbus_threads_init_default_dylibloader_orig_dbus -#include <dbus/dbus.h> +#include "thirdparty/linuxbsd_headers/dbus/dbus.h" #undef dbus_error_init #undef dbus_error_free #undef dbus_set_error diff --git a/platform/linuxbsd/detect.py b/platform/linuxbsd/detect.py index ac69f3806b..dadc03685b 100644 --- a/platform/linuxbsd/detect.py +++ b/platform/linuxbsd/detect.py @@ -43,10 +43,12 @@ def get_opts(): BoolVariable("use_lsan", "Use LLVM/GCC compiler leak sanitizer (LSAN)", False), BoolVariable("use_tsan", "Use LLVM/GCC compiler thread sanitizer (TSAN)", False), BoolVariable("use_msan", "Use LLVM compiler memory sanitizer (MSAN)", False), - BoolVariable("pulseaudio", "Detect and use PulseAudio", True), - BoolVariable("dbus", "Detect and use D-Bus to handle screensaver and portal desktop settings", True), - BoolVariable("speechd", "Detect and use Speech Dispatcher for Text-to-Speech support", True), - BoolVariable("fontconfig", "Detect and use fontconfig for system fonts support", True), + BoolVariable("use_sowrap", "Dynamically load system libraries", True), + BoolVariable("alsa", "Use ALSA", True), + BoolVariable("pulseaudio", "Use PulseAudio", True), + BoolVariable("dbus", "Use D-Bus to handle screensaver and portal desktop settings", True), + BoolVariable("speechd", "Use Speech Dispatcher for Text-to-Speech support", True), + BoolVariable("fontconfig", "Use fontconfig for system fonts support", True), BoolVariable("udev", "Use udev for gamepad connection callbacks", True), BoolVariable("x11", "Enable X11 display", True), BoolVariable("touch", "Enable touch events", True), @@ -54,6 +56,16 @@ def get_opts(): ] +def get_doc_classes(): + return [ + "EditorExportPlatformLinuxBSD", + ] + + +def get_doc_path(): + return "doc_classes" + + def get_flags(): return [ ("arch", detect_arch()), @@ -68,7 +80,7 @@ def configure(env: "Environment"): 'Unsupported CPU architecture "%s" for Linux / *BSD. Supported architectures are: %s.' % (env["arch"], ", ".join(supported_arches)) ) - sys.exit() + sys.exit(255) ## Build type @@ -183,14 +195,8 @@ def configure(env: "Environment"): ## Dependencies - 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["use_sowrap"]: + env.Append(CPPDEFINES=["SOWRAP_ENABLED"]) if env["touch"]: env.Append(CPPDEFINES=["TOUCH_ENABLED"]) @@ -198,19 +204,21 @@ def configure(env: "Environment"): # FIXME: Check for existence of the libs before parsing their flags with pkg-config # freetype depends on libpng and zlib, so bundling one of them while keeping others - # as shared libraries leads to weird issues - if ( - env["builtin_freetype"] - or env["builtin_libpng"] - or env["builtin_zlib"] - or env["builtin_graphite"] - or env["builtin_harfbuzz"] - ): - env["builtin_freetype"] = True - env["builtin_libpng"] = True - env["builtin_zlib"] = True - env["builtin_graphite"] = True - env["builtin_harfbuzz"] = True + # as shared libraries leads to weird issues. And graphite and harfbuzz need freetype. + ft_linked_deps = [ + env["builtin_freetype"], + env["builtin_libpng"], + env["builtin_zlib"], + env["builtin_graphite"], + env["builtin_harfbuzz"], + ] + if (not all(ft_linked_deps)) and any(ft_linked_deps): # All or nothing. + print( + "These libraries should be either all builtin, or all system provided:\n" + "freetype, libpng, zlib, graphite, harfbuzz.\n" + "Please specify `builtin_<name>=no` for all of them, or none." + ) + sys.exit(255) if not env["builtin_freetype"]: env.ParseConfig("pkg-config freetype2 --cflags --libs") @@ -218,8 +226,8 @@ def configure(env: "Environment"): if not env["builtin_graphite"]: env.ParseConfig("pkg-config graphite2 --cflags --libs") - if not env["builtin_icu"]: - env.ParseConfig("pkg-config icu-uc --cflags --libs") + if not env["builtin_icu4c"]: + env.ParseConfig("pkg-config icu-i18n icu-uc --cflags --libs") if not env["builtin_harfbuzz"]: env.ParseConfig("pkg-config harfbuzz harfbuzz-icu --cflags --libs") @@ -270,64 +278,97 @@ def configure(env: "Environment"): env.Append(LIBS=["miniupnpc"]) # On Linux wchar_t should be 32-bits - # 16-bit library shouldn't be required due to compiler optimisations + # 16-bit library shouldn't be required due to compiler optimizations if not env["builtin_pcre2"]: env.ParseConfig("pkg-config libpcre2-32 --cflags --libs") - if not env["builtin_embree"]: + if not env["builtin_recastnavigation"]: + # No pkgconfig file so far, hardcode default paths. + env.Prepend(CPPPATH=["/usr/include/recastnavigation"]) + env.Append(LIBS=["Recast"]) + + if not env["builtin_embree"] and env["arch"] in ["x86_64", "arm64"]: # No pkgconfig file so far, hardcode expected lib name. env.Append(LIBS=["embree3"]) - ## Flags - if env["fontconfig"]: - if os.system("pkg-config --exists fontconfig") == 0: # 0 means found - env.Append(CPPDEFINES=["FONTCONFIG_ENABLED"]) - env.ParseConfig("pkg-config fontconfig --cflags") # Only cflags, we dlopen the library. + if not env["use_sowrap"]: + if os.system("pkg-config --exists fontconfig") == 0: # 0 means found + env.ParseConfig("pkg-config fontconfig --cflags --libs") + env.Append(CPPDEFINES=["FONTCONFIG_ENABLED"]) + else: + print("Warning: fontconfig development libraries not found. Disabling the system fonts support.") + env["fontconfig"] = False else: - env["fontconfig"] = False - print("Warning: fontconfig libraries not found. Disabling the system fonts support.") + env.Append(CPPDEFINES=["FONTCONFIG_ENABLED"]) - if os.system("pkg-config --exists alsa") == 0: # 0 means found - env["alsa"] = True - env.Append(CPPDEFINES=["ALSA_ENABLED", "ALSAMIDI_ENABLED"]) - env.ParseConfig("pkg-config alsa --cflags") # Only cflags, we dlopen the library. - else: - print("Warning: ALSA libraries not found. Disabling the ALSA audio driver.") + if env["alsa"]: + if not env["use_sowrap"]: + if os.system("pkg-config --exists alsa") == 0: # 0 means found + env.ParseConfig("pkg-config alsa --cflags --libs") + env.Append(CPPDEFINES=["ALSA_ENABLED", "ALSAMIDI_ENABLED"]) + else: + print("Warning: ALSA development libraries not found. Disabling the ALSA audio driver.") + env["alsa"] = False + else: + env.Append(CPPDEFINES=["ALSA_ENABLED", "ALSAMIDI_ENABLED"]) if env["pulseaudio"]: - if os.system("pkg-config --exists libpulse") == 0: # 0 means found - env.Append(CPPDEFINES=["PULSEAUDIO_ENABLED"]) - env.ParseConfig("pkg-config libpulse --cflags") # Only cflags, we dlopen the library. + if not env["use_sowrap"]: + if os.system("pkg-config --exists libpulse") == 0: # 0 means found + env.ParseConfig("pkg-config libpulse --cflags --libs") + env.Append(CPPDEFINES=["PULSEAUDIO_ENABLED"]) + else: + print("Warning: PulseAudio development libraries not found. Disabling the PulseAudio audio driver.") + env["pulseaudio"] = False else: - env["pulseaudio"] = False - print("Warning: PulseAudio development libraries not found. Disabling the PulseAudio audio driver.") + env.Append(CPPDEFINES=["PULSEAUDIO_ENABLED", "_REENTRANT"]) if env["dbus"]: - if os.system("pkg-config --exists dbus-1") == 0: # 0 means found - env.Append(CPPDEFINES=["DBUS_ENABLED"]) - env.ParseConfig("pkg-config dbus-1 --cflags") # Only cflags, we dlopen the library. + if not env["use_sowrap"]: + if os.system("pkg-config --exists dbus-1") == 0: # 0 means found + env.ParseConfig("pkg-config dbus-1 --cflags --libs") + env.Append(CPPDEFINES=["DBUS_ENABLED"]) + else: + print("Warning: D-Bus development libraries not found. Disabling screensaver prevention.") + env["dbus"] = False else: - env["dbus"] = False - print("Warning: D-Bus development libraries not found. Disabling screensaver prevention.") + env.Append(CPPDEFINES=["DBUS_ENABLED"]) if env["speechd"]: - if os.system("pkg-config --exists speech-dispatcher") == 0: # 0 means found + if not env["use_sowrap"]: + if os.system("pkg-config --exists speech-dispatcher") == 0: # 0 means found + env.ParseConfig("pkg-config speech-dispatcher --cflags --libs") + env.Append(CPPDEFINES=["SPEECHD_ENABLED"]) + else: + print("Warning: speech-dispatcher development libraries not found. Disabling text to speech support.") + env["speechd"] = False + else: env.Append(CPPDEFINES=["SPEECHD_ENABLED"]) - env.ParseConfig("pkg-config speech-dispatcher --cflags") # Only cflags, we dlopen the library. + + if not env["use_sowrap"]: + if os.system("pkg-config --exists xkbcommon") == 0: # 0 means found + env.ParseConfig("pkg-config xkbcommon --cflags --libs") + env.Append(CPPDEFINES=["XKB_ENABLED"]) else: - env["speechd"] = False - print("Warning: Speech Dispatcher development libraries not found. Disabling Text-to-Speech support.") + print( + "Warning: libxkbcommon development libraries not found. Disabling dead key composition and key label support." + ) + else: + env.Append(CPPDEFINES=["XKB_ENABLED"]) if platform.system() == "Linux": env.Append(CPPDEFINES=["JOYDEV_ENABLED"]) if env["udev"]: - if os.system("pkg-config --exists libudev") == 0: # 0 means found - env.Append(CPPDEFINES=["UDEV_ENABLED"]) - env.ParseConfig("pkg-config libudev --cflags") # Only cflags, we dlopen the library. + if not env["use_sowrap"]: + if os.system("pkg-config --exists libudev") == 0: # 0 means found + env.ParseConfig("pkg-config libudev --cflags --libs") + env.Append(CPPDEFINES=["UDEV_ENABLED"]) + else: + print("Warning: libudev development libraries not found. Disabling controller hotplugging support.") + env["udev"] = False else: - env["udev"] = False - print("Warning: libudev development libraries not found. Disabling controller hotplugging support.") + env.Append(CPPDEFINES=["UDEV_ENABLED"]) else: env["udev"] = False # Linux specific @@ -336,16 +377,49 @@ def configure(env: "Environment"): env.ParseConfig("pkg-config zlib --cflags --libs") env.Prepend(CPPPATH=["#platform/linuxbsd"]) + if env["use_sowrap"]: + env.Prepend(CPPPATH=["#thirdparty/linuxbsd_headers"]) + + env.Append( + CPPDEFINES=[ + "LINUXBSD_ENABLED", + "UNIX_ENABLED", + ("_FILE_OFFSET_BITS", 64), + ] + ) if env["x11"]: - if not env["vulkan"]: - print("Error: X11 support requires vulkan=yes") - env.Exit(255) + if not env["use_sowrap"]: + if os.system("pkg-config --exists x11"): + print("Error: X11 libraries not found. Aborting.") + sys.exit(255) + env.ParseConfig("pkg-config x11 --cflags --libs") + if os.system("pkg-config --exists xcursor"): + print("Error: Xcursor library not found. Aborting.") + sys.exit(255) + env.ParseConfig("pkg-config xcursor --cflags --libs") + if os.system("pkg-config --exists xinerama"): + print("Error: Xinerama library not found. Aborting.") + sys.exit(255) + env.ParseConfig("pkg-config xinerama --cflags --libs") + if os.system("pkg-config --exists xext"): + print("Error: Xext library not found. Aborting.") + sys.exit(255) + env.ParseConfig("pkg-config xext --cflags --libs") + if os.system("pkg-config --exists xrandr"): + print("Error: XrandR library not found. Aborting.") + sys.exit(255) + env.ParseConfig("pkg-config xrandr --cflags --libs") + if os.system("pkg-config --exists xrender"): + print("Error: XRender library not found. Aborting.") + sys.exit(255) + env.ParseConfig("pkg-config xrender --cflags --libs") + if os.system("pkg-config --exists xi"): + print("Error: Xi library not found. Aborting.") + sys.exit(255) + env.ParseConfig("pkg-config xi --cflags --libs") env.Append(CPPDEFINES=["X11_ENABLED"]) - env.Append(CPPDEFINES=["UNIX_ENABLED"]) - env.Append(CPPDEFINES=[("_FILE_OFFSET_BITS", 64)]) - if env["vulkan"]: env.Append(CPPDEFINES=["VULKAN_ENABLED"]) if not env["use_volk"]: @@ -356,7 +430,6 @@ def configure(env: "Environment"): if env["opengl3"]: env.Append(CPPDEFINES=["GLES3_ENABLED"]) - env.ParseConfig("pkg-config gl --cflags --libs") env.Append(LIBS=["pthread"]) @@ -382,7 +455,7 @@ def configure(env: "Environment"): gnu_ld_version = re.search("^GNU ld [^$]*(\d+\.\d+)$", linker_version_str, re.MULTILINE) if not gnu_ld_version: print( - "Warning: Creating template binaries enabled for PCK embedding is currently only supported with GNU ld, not gold or LLD." + "Warning: Creating export template binaries enabled for PCK embedding is currently only supported with GNU ld, not gold, LLD or mold." ) else: if float(gnu_ld_version.group(1)) >= 2.30: @@ -390,6 +463,9 @@ def configure(env: "Environment"): else: env.Append(LINKFLAGS=["-T", "platform/linuxbsd/pck_embed.legacy.ld"]) + if platform.system() == "FreeBSD": + env.Append(LINKFLAGS=["-lkvm"]) + ## Cross-compilation # TODO: Support cross-compilation on architectures other than x86. host_is_64_bit = sys.maxsize > 2**32 @@ -403,9 +479,9 @@ def configure(env: "Environment"): # Link those statically for portability if env["use_static_cpp"]: env.Append(LINKFLAGS=["-static-libgcc", "-static-libstdc++"]) - if env["use_llvm"]: + if env["use_llvm"] and platform.system() != "FreeBSD": env["LINKCOM"] = env["LINKCOM"] + " -l:libatomic.a" else: - if env["use_llvm"]: + if env["use_llvm"] and platform.system() != "FreeBSD": env.Append(LIBS=["atomic"]) diff --git a/platform/linuxbsd/doc_classes/EditorExportPlatformLinuxBSD.xml b/platform/linuxbsd/doc_classes/EditorExportPlatformLinuxBSD.xml new file mode 100644 index 0000000000..77a6ece756 --- /dev/null +++ b/platform/linuxbsd/doc_classes/EditorExportPlatformLinuxBSD.xml @@ -0,0 +1,73 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="EditorExportPlatformLinuxBSD" inherits="EditorExportPlatformPC" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> + <brief_description> + Exporter for Linux/BSD. + </brief_description> + <description> + </description> + <tutorials> + <link title="Exporting for Linux">$DOCS_URL/tutorials/export/exporting_for_linux.html</link> + </tutorials> + <members> + <member name="binary_format/architecture" type="String" setter="" getter=""> + Application executable architecture. + Supported architectures: [code]x86_32[/code], [code]x86_64[/code], [code]arm64[/code], [code]arm32[/code], [code]rv64[/code], [code]ppc64[/code], and [code]ppc32[/code]. + Official export templates include [code]x86_32[/code] and [code]x86_64[/code] binaries only. + </member> + <member name="binary_format/embed_pck" type="bool" setter="" getter=""> + If [code]true[/code], project resources are embedded into the executable. + </member> + <member name="custom_template/debug" type="String" setter="" getter=""> + Path to the custom export template. If left empty, default template is used. + </member> + <member name="custom_template/release" type="String" setter="" getter=""> + Path to the custom export template. If left empty, default template is used. + </member> + <member name="debug/export_console_wrapper" type="int" setter="" getter=""> + If [code]true[/code], a console wrapper is exported alongside the main executable, which allows running the project with enabled console output. + </member> + <member name="ssh_remote_deploy/cleanup_script" type="String" setter="" getter=""> + Script code to execute on the remote host when app is finished. + The following variables can be used in the script: + - [code]{temp_dir}[/code] - Path of temporary folder on the remote, used to upload app and scripts to. + - [code]{archive_name}[/code] - Name of the ZIP containing uploaded application. + - [code]{exe_name}[/code] - Name of application executable. + - [code]{cmd_args}[/code] - Array of the command line argument for the application. + </member> + <member name="ssh_remote_deploy/enabled" type="bool" setter="" getter=""> + Enables remote deploy using SSH/SCP. + </member> + <member name="ssh_remote_deploy/extra_args_scp" type="String" setter="" getter=""> + Array of the additional command line arguments passed to the SCP. + </member> + <member name="ssh_remote_deploy/extra_args_ssh" type="String" setter="" getter=""> + Array of the additional command line arguments passed to the SSH. + </member> + <member name="ssh_remote_deploy/host" type="String" setter="" getter=""> + Remote host SSH user name and address, in [code]user@address[/code] format. + </member> + <member name="ssh_remote_deploy/port" type="String" setter="" getter=""> + Remote host SSH port number. + </member> + <member name="ssh_remote_deploy/run_script" type="String" setter="" getter=""> + Script code to execute on the remote host when running the app. + The following variables can be used in the script: + - [code]{temp_dir}[/code] - Path of temporary folder on the remote, used to upload app and scripts to. + - [code]{archive_name}[/code] - Name of the ZIP containing uploaded application. + - [code]{exe_name}[/code] - Name of application executable. + - [code]{cmd_args}[/code] - Array of the command line argument for the application. + </member> + <member name="texture_format/bptc" type="bool" setter="" getter=""> + If [code]true[/code], project textures are exported in the BPTC format. + </member> + <member name="texture_format/etc" type="bool" setter="" getter=""> + If [code]true[/code], project textures are exported in the ETC format. + </member> + <member name="texture_format/etc2" type="bool" setter="" getter=""> + If [code]true[/code], project textures are exported in the ETC2 format. + </member> + <member name="texture_format/s3tc" type="bool" setter="" getter=""> + If [code]true[/code], project textures are exported in the S3TC format. + </member> + </members> +</class> diff --git a/platform/linuxbsd/export/export.cpp b/platform/linuxbsd/export/export.cpp index 990351d13f..f72c079d1d 100644 --- a/platform/linuxbsd/export/export.cpp +++ b/platform/linuxbsd/export/export.cpp @@ -1,42 +1,46 @@ -/*************************************************************************/ -/* export.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* export.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "export.h" -#include "editor/export/editor_export.h" #include "export_plugin.h" +#include "editor/export/editor_export.h" + +void register_linuxbsd_exporter_types() { + GDREGISTER_VIRTUAL_CLASS(EditorExportPlatformLinuxBSD); +} + void register_linuxbsd_exporter() { Ref<EditorExportPlatformLinuxBSD> platform; platform.instantiate(); - platform->set_logo(ImageTexture::create_from_image(memnew(Image(_linuxbsd_logo)))); platform->set_name("Linux/X11"); platform->set_os_name("Linux"); platform->set_chmod_flags(0755); diff --git a/platform/linuxbsd/export/export.h b/platform/linuxbsd/export/export.h index f06d781da6..f493047815 100644 --- a/platform/linuxbsd/export/export.h +++ b/platform/linuxbsd/export/export.h @@ -1,36 +1,37 @@ -/*************************************************************************/ -/* export.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* export.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 LINUXBSD_EXPORT_H #define LINUXBSD_EXPORT_H +void register_linuxbsd_exporter_types(); void register_linuxbsd_exporter(); #endif // LINUXBSD_EXPORT_H diff --git a/platform/linuxbsd/export/export_plugin.cpp b/platform/linuxbsd/export/export_plugin.cpp index 8277bb1505..082040c8d6 100644 --- a/platform/linuxbsd/export/export_plugin.cpp +++ b/platform/linuxbsd/export/export_plugin.cpp @@ -1,37 +1,48 @@ -/*************************************************************************/ -/* export_plugin.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* export_plugin.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "export_plugin.h" +#include "../logo_svg.gen.h" +#include "../run_icon_svg.gen.h" + #include "core/config/project_settings.h" #include "editor/editor_node.h" +#include "editor/editor_paths.h" +#include "editor/editor_scale.h" +#include "editor/export/editor_export.h" + +#include "modules/modules_enabled.gen.h" // For svg. +#ifdef MODULE_SVG_ENABLED +#include "modules/svg/image_loader_svg.h" +#endif Error EditorExportPlatformLinuxBSD::_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); @@ -49,33 +60,75 @@ Error EditorExportPlatformLinuxBSD::_export_debug_script(const Ref<EditorExportP } Error EditorExportPlatformLinuxBSD::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) { - Error err = EditorExportPlatformPC::export_project(p_preset, p_debug, p_path, p_flags); - - if (err != OK) { - return err; - } + bool export_as_zip = p_path.ends_with("zip"); - String app_name; + String pkg_name; if (String(GLOBAL_GET("application/config/name")) != "") { - app_name = String(GLOBAL_GET("application/config/name")); + pkg_name = String(GLOBAL_GET("application/config/name")); } else { - app_name = "Unnamed"; + pkg_name = "Unnamed"; + } + + pkg_name = OS::get_singleton()->get_safe_dir_name(pkg_name); + + // Setup temp folder. + String path = p_path; + String tmp_dir_path = EditorPaths::get_singleton()->get_cache_dir().path_join(pkg_name); + + Ref<DirAccess> tmp_app_dir = DirAccess::create_for_path(tmp_dir_path); + if (export_as_zip) { + if (tmp_app_dir.is_null()) { + return ERR_CANT_CREATE; + } + if (DirAccess::exists(tmp_dir_path)) { + if (tmp_app_dir->change_dir(tmp_dir_path) == OK) { + tmp_app_dir->erase_contents_recursive(); + } + } + tmp_app_dir->make_dir_recursive(tmp_dir_path); + path = tmp_dir_path.path_join(p_path.get_file().get_basename()); + } + + // Export project. + Error err = EditorExportPlatformPC::export_project(p_preset, p_debug, path, p_flags); + if (err != OK) { + return err; } - app_name = OS::get_singleton()->get_safe_dir_name(app_name); - // Save console script. + // Save console wrapper. if (err == OK) { - int con_scr = p_preset->get("debug/export_console_script"); + int con_scr = p_preset->get("debug/export_console_wrapper"); if ((con_scr == 1 && p_debug) || (con_scr == 2)) { - String scr_path = p_path.get_basename() + ".sh"; - err = _export_debug_script(p_preset, app_name, p_path.get_file(), scr_path); + String scr_path = path.get_basename() + ".sh"; + err = _export_debug_script(p_preset, pkg_name, path.get_file(), scr_path); FileAccess::set_unix_permissions(scr_path, 0755); if (err != OK) { - add_message(EXPORT_MESSAGE_ERROR, TTR("Debug Script Export"), TTR("Could not create console script.")); + add_message(EXPORT_MESSAGE_ERROR, TTR("Debug Console Export"), TTR("Could not create console wrapper.")); } } } + // ZIP project. + if (export_as_zip) { + if (FileAccess::exists(p_path)) { + OS::get_singleton()->move_to_trash(p_path); + } + + Ref<FileAccess> io_fa_dst; + zlib_filefunc_def io_dst = zipio_create_io(&io_fa_dst); + zipFile zip = zipOpen2(p_path.utf8().get_data(), APPEND_STATUS_CREATE, nullptr, &io_dst); + + zip_folder_recursive(zip, tmp_dir_path, "", pkg_name); + + zipClose(zip, nullptr); + + if (tmp_app_dir->change_dir(tmp_dir_path) == OK) { + tmp_app_dir->erase_contents_recursive(); + tmp_app_dir->change_dir(".."); + tmp_app_dir->remove(pkg_name); + } + } + return err; } @@ -86,12 +139,62 @@ String EditorExportPlatformLinuxBSD::get_template_file_name(const String &p_targ List<String> EditorExportPlatformLinuxBSD::get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const { List<String> list; list.push_back(p_preset->get("binary_format/architecture")); + list.push_back("zip"); + return list; } -void EditorExportPlatformLinuxBSD::get_export_options(List<ExportOption> *r_options) { +bool EditorExportPlatformLinuxBSD::get_export_option_visibility(const EditorExportPreset *p_preset, const String &p_option) const { + if (p_preset) { + // Hide SSH options. + bool ssh = p_preset->get("ssh_remote_deploy/enabled"); + if (!ssh && p_option != "ssh_remote_deploy/enabled" && p_option.begins_with("ssh_remote_deploy/")) { + return false; + } + } + return true; +} + +void EditorExportPlatformLinuxBSD::get_export_options(List<ExportOption> *r_options) const { EditorExportPlatformPC::get_export_options(r_options); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "binary_format/architecture", PROPERTY_HINT_ENUM, "x86_64,x86_32,arm64,arm32,rv64,ppc64,ppc32"), "x86_64")); + + String run_script = "#!/usr/bin/env bash\n" + "export DISPLAY=:0\n" + "unzip -o -q \"{temp_dir}/{archive_name}\" -d \"{temp_dir}\"\n" + "\"{temp_dir}/{exe_name}\" {cmd_args}"; + + String cleanup_script = "#!/usr/bin/env bash\n" + "kill $(pgrep -x -f \"{temp_dir}/{exe_name} {cmd_args}\")\n" + "rm -rf \"{temp_dir}\""; + + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "ssh_remote_deploy/enabled"), false, true)); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "ssh_remote_deploy/host"), "user@host_ip")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "ssh_remote_deploy/port"), "22")); + + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "ssh_remote_deploy/extra_args_ssh", PROPERTY_HINT_MULTILINE_TEXT), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "ssh_remote_deploy/extra_args_scp", PROPERTY_HINT_MULTILINE_TEXT), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "ssh_remote_deploy/run_script", PROPERTY_HINT_MULTILINE_TEXT), run_script)); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "ssh_remote_deploy/cleanup_script", PROPERTY_HINT_MULTILINE_TEXT), cleanup_script)); +} + +bool EditorExportPlatformLinuxBSD::is_elf(const String &p_path) const { + Ref<FileAccess> fb = FileAccess::open(p_path, FileAccess::READ); + ERR_FAIL_COND_V_MSG(fb.is_null(), false, vformat("Can't open file: \"%s\".", p_path)); + uint32_t magic = fb->get_32(); + return (magic == 0x464c457f); +} + +bool EditorExportPlatformLinuxBSD::is_shebang(const String &p_path) const { + Ref<FileAccess> fb = FileAccess::open(p_path, FileAccess::READ); + ERR_FAIL_COND_V_MSG(fb.is_null(), false, vformat("Can't open file: \"%s\".", p_path)); + uint16_t magic = fb->get_16(); + return (magic == 0x2123); +} + +bool EditorExportPlatformLinuxBSD::is_executable(const String &p_path) const { + return is_elf(p_path) || is_shebang(p_path); } Error EditorExportPlatformLinuxBSD::fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size) { @@ -200,3 +303,237 @@ Error EditorExportPlatformLinuxBSD::fixup_embedded_pck(const String &p_path, int } return OK; } + +Ref<Texture2D> EditorExportPlatformLinuxBSD::get_run_icon() const { + return run_icon; +} + +bool EditorExportPlatformLinuxBSD::poll_export() { + Ref<EditorExportPreset> preset; + + for (int i = 0; i < EditorExport::get_singleton()->get_export_preset_count(); i++) { + Ref<EditorExportPreset> ep = EditorExport::get_singleton()->get_export_preset(i); + if (ep->is_runnable() && ep->get_platform() == this) { + preset = ep; + break; + } + } + + int prev = menu_options; + menu_options = (preset.is_valid() && preset->get("ssh_remote_deploy/enabled").operator bool()); + if (ssh_pid != 0 || !cleanup_commands.is_empty()) { + if (menu_options == 0) { + cleanup(); + } else { + menu_options += 1; + } + } + return menu_options != prev; +} + +Ref<ImageTexture> EditorExportPlatformLinuxBSD::get_option_icon(int p_index) const { + return p_index == 1 ? stop_icon : EditorExportPlatform::get_option_icon(p_index); +} + +int EditorExportPlatformLinuxBSD::get_options_count() const { + return menu_options; +} + +String EditorExportPlatformLinuxBSD::get_option_label(int p_index) const { + return (p_index) ? TTR("Stop and uninstall") : TTR("Run on remote Linux/BSD system"); +} + +String EditorExportPlatformLinuxBSD::get_option_tooltip(int p_index) const { + return (p_index) ? TTR("Stop and uninstall running project from the remote system") : TTR("Run exported project on remote Linux/BSD system"); +} + +void EditorExportPlatformLinuxBSD::cleanup() { + if (ssh_pid != 0 && OS::get_singleton()->is_process_running(ssh_pid)) { + print_line("Terminating connection..."); + OS::get_singleton()->kill(ssh_pid); + OS::get_singleton()->delay_usec(1000); + } + + if (!cleanup_commands.is_empty()) { + print_line("Stopping and deleting previous version..."); + for (const SSHCleanupCommand &cmd : cleanup_commands) { + if (cmd.wait) { + ssh_run_on_remote(cmd.host, cmd.port, cmd.ssh_args, cmd.cmd_args); + } else { + ssh_run_on_remote_no_wait(cmd.host, cmd.port, cmd.ssh_args, cmd.cmd_args); + } + } + } + ssh_pid = 0; + cleanup_commands.clear(); +} + +Error EditorExportPlatformLinuxBSD::run(const Ref<EditorExportPreset> &p_preset, int p_device, int p_debug_flags) { + cleanup(); + if (p_device) { // Stop command, cleanup only. + return OK; + } + + EditorProgress ep("run", TTR("Running..."), 5); + + const String dest = EditorPaths::get_singleton()->get_cache_dir().path_join("linuxbsd"); + Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + if (!da->dir_exists(dest)) { + Error err = da->make_dir_recursive(dest); + if (err != OK) { + EditorNode::get_singleton()->show_warning(TTR("Could not create temp directory:") + "\n" + dest); + return err; + } + } + + String host = p_preset->get("ssh_remote_deploy/host").operator String(); + String port = p_preset->get("ssh_remote_deploy/port").operator String(); + if (port.is_empty()) { + port = "22"; + } + Vector<String> extra_args_ssh = p_preset->get("ssh_remote_deploy/extra_args_ssh").operator String().split(" ", false); + Vector<String> extra_args_scp = p_preset->get("ssh_remote_deploy/extra_args_scp").operator String().split(" ", false); + + const String basepath = dest.path_join("tmp_linuxbsd_export"); + +#define CLEANUP_AND_RETURN(m_err) \ + { \ + if (da->file_exists(basepath + ".zip")) { \ + da->remove(basepath + ".zip"); \ + } \ + if (da->file_exists(basepath + "_start.sh")) { \ + da->remove(basepath + "_start.sh"); \ + } \ + if (da->file_exists(basepath + "_clean.sh")) { \ + da->remove(basepath + "_clean.sh"); \ + } \ + return m_err; \ + } \ + ((void)0) + + if (ep.step(TTR("Exporting project..."), 1)) { + return ERR_SKIP; + } + Error err = export_project(p_preset, true, basepath + ".zip", p_debug_flags); + if (err != OK) { + DirAccess::remove_file_or_error(basepath + ".zip"); + return err; + } + + String cmd_args; + { + Vector<String> cmd_args_list; + gen_debug_flags(cmd_args_list, p_debug_flags); + for (int i = 0; i < cmd_args_list.size(); i++) { + if (i != 0) { + cmd_args += " "; + } + cmd_args += cmd_args_list[i]; + } + } + + const bool use_remote = (p_debug_flags & DEBUG_FLAG_REMOTE_DEBUG) || (p_debug_flags & DEBUG_FLAG_DUMB_CLIENT); + int dbg_port = EditorSettings::get_singleton()->get("network/debug/remote_port"); + + print_line("Creating temporary directory..."); + ep.step(TTR("Creating temporary directory..."), 2); + String temp_dir; + err = ssh_run_on_remote(host, port, extra_args_ssh, "mktemp -d", &temp_dir); + if (err != OK || temp_dir.is_empty()) { + CLEANUP_AND_RETURN(err); + } + + print_line("Uploading archive..."); + ep.step(TTR("Uploading archive..."), 3); + err = ssh_push_to_remote(host, port, extra_args_scp, basepath + ".zip", temp_dir); + if (err != OK) { + CLEANUP_AND_RETURN(err); + } + + { + String run_script = p_preset->get("ssh_remote_deploy/run_script"); + run_script = run_script.replace("{temp_dir}", temp_dir); + run_script = run_script.replace("{archive_name}", basepath.get_file() + ".zip"); + run_script = run_script.replace("{exe_name}", basepath.get_file()); + run_script = run_script.replace("{cmd_args}", cmd_args); + + Ref<FileAccess> f = FileAccess::open(basepath + "_start.sh", FileAccess::WRITE); + if (f.is_null()) { + CLEANUP_AND_RETURN(err); + } + + f->store_string(run_script); + } + + { + String clean_script = p_preset->get("ssh_remote_deploy/cleanup_script"); + clean_script = clean_script.replace("{temp_dir}", temp_dir); + clean_script = clean_script.replace("{archive_name}", basepath.get_file() + ".zip"); + clean_script = clean_script.replace("{exe_name}", basepath.get_file()); + clean_script = clean_script.replace("{cmd_args}", cmd_args); + + Ref<FileAccess> f = FileAccess::open(basepath + "_clean.sh", FileAccess::WRITE); + if (f.is_null()) { + CLEANUP_AND_RETURN(err); + } + + f->store_string(clean_script); + } + + print_line("Uploading scripts..."); + ep.step(TTR("Uploading scripts..."), 4); + err = ssh_push_to_remote(host, port, extra_args_scp, basepath + "_start.sh", temp_dir); + if (err != OK) { + CLEANUP_AND_RETURN(err); + } + err = ssh_run_on_remote(host, port, extra_args_ssh, vformat("chmod +x \"%s/%s\"", temp_dir, basepath.get_file() + "_start.sh")); + if (err != OK || temp_dir.is_empty()) { + CLEANUP_AND_RETURN(err); + } + err = ssh_push_to_remote(host, port, extra_args_scp, basepath + "_clean.sh", temp_dir); + if (err != OK) { + CLEANUP_AND_RETURN(err); + } + err = ssh_run_on_remote(host, port, extra_args_ssh, vformat("chmod +x \"%s/%s\"", temp_dir, basepath.get_file() + "_clean.sh")); + if (err != OK || temp_dir.is_empty()) { + CLEANUP_AND_RETURN(err); + } + + print_line("Starting project..."); + ep.step(TTR("Starting project..."), 5); + err = ssh_run_on_remote_no_wait(host, port, extra_args_ssh, vformat("\"%s/%s\"", temp_dir, basepath.get_file() + "_start.sh"), &ssh_pid, (use_remote) ? dbg_port : -1); + if (err != OK) { + CLEANUP_AND_RETURN(err); + } + + cleanup_commands.clear(); + cleanup_commands.push_back(SSHCleanupCommand(host, port, extra_args_ssh, vformat("\"%s/%s\"", temp_dir, basepath.get_file() + "_clean.sh"))); + + print_line("Project started."); + + CLEANUP_AND_RETURN(OK); +#undef CLEANUP_AND_RETURN +} + +EditorExportPlatformLinuxBSD::EditorExportPlatformLinuxBSD() { + if (EditorNode::get_singleton()) { +#ifdef MODULE_SVG_ENABLED + Ref<Image> img = memnew(Image); + const bool upsample = !Math::is_equal_approx(Math::round(EDSCALE), EDSCALE); + + ImageLoaderSVG img_loader; + img_loader.create_image_from_string(img, _linuxbsd_logo_svg, EDSCALE, upsample, false); + set_logo(ImageTexture::create_from_image(img)); + + img_loader.create_image_from_string(img, _linuxbsd_run_icon_svg, EDSCALE, upsample, false); + run_icon = ImageTexture::create_from_image(img); +#endif + + Ref<Theme> theme = EditorNode::get_singleton()->get_editor_theme(); + if (theme.is_valid()) { + stop_icon = theme->get_icon(SNAME("Stop"), SNAME("EditorIcons")); + } else { + stop_icon.instantiate(); + } + } +} diff --git a/platform/linuxbsd/export/export_plugin.h b/platform/linuxbsd/export/export_plugin.h index 4d6737498b..cef714e86e 100644 --- a/platform/linuxbsd/export/export_plugin.h +++ b/platform/linuxbsd/export/export_plugin.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* export_plugin.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* export_plugin.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 LINUXBSD_EXPORT_PLUGIN_H #define LINUXBSD_EXPORT_PLUGIN_H @@ -34,19 +34,61 @@ #include "core/io/file_access.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" class EditorExportPlatformLinuxBSD : public EditorExportPlatformPC { + GDCLASS(EditorExportPlatformLinuxBSD, EditorExportPlatformPC); + + HashMap<String, String> extensions; + + struct SSHCleanupCommand { + String host; + String port; + Vector<String> ssh_args; + String cmd_args; + bool wait = false; + + SSHCleanupCommand(){}; + SSHCleanupCommand(const String &p_host, const String &p_port, const Vector<String> &p_ssh_arg, const String &p_cmd_args, bool p_wait = false) { + host = p_host; + port = p_port; + ssh_args = p_ssh_arg; + cmd_args = p_cmd_args; + wait = p_wait; + }; + }; + + Ref<ImageTexture> run_icon; + Ref<ImageTexture> stop_icon; + + Vector<SSHCleanupCommand> cleanup_commands; + OS::ProcessID ssh_pid = 0; + int menu_options = 0; + + bool is_elf(const String &p_path) const; + bool is_shebang(const String &p_path) const; + Error _export_debug_script(const Ref<EditorExportPreset> &p_preset, const String &p_app_name, const String &p_pkg_name, const String &p_path); public: - void set_extension(const String &p_extension, const String &p_feature_key = "default"); + virtual void get_export_options(List<ExportOption> *r_options) const override; virtual List<String> get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const override; - virtual void get_export_options(List<ExportOption> *r_options) override; + virtual bool get_export_option_visibility(const EditorExportPreset *p_preset, const String &p_option) const override; virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0) override; virtual String get_template_file_name(const String &p_target, const String &p_arch) const override; virtual Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size) override; + virtual bool is_executable(const String &p_path) const override; + + virtual Ref<Texture2D> get_run_icon() const override; + virtual bool poll_export() override; + virtual Ref<ImageTexture> get_option_icon(int p_index) const override; + virtual int get_options_count() const override; + virtual String get_option_label(int p_index) const override; + virtual String get_option_tooltip(int p_index) const override; + virtual Error run(const Ref<EditorExportPreset> &p_preset, int p_device, int p_debug_flags) override; + virtual void cleanup() override; + + EditorExportPlatformLinuxBSD(); }; #endif // LINUXBSD_EXPORT_PLUGIN_H diff --git a/platform/linuxbsd/fontconfig-so_wrap.c b/platform/linuxbsd/fontconfig-so_wrap.c index 1a915faf98..86aacbc647 100644 --- a/platform/linuxbsd/fontconfig-so_wrap.c +++ b/platform/linuxbsd/fontconfig-so_wrap.c @@ -1,7 +1,7 @@ // This file is generated. Do not edit! // see https://github.com/hpvb/dynload-wrapper for details -// generated by ./generate-wrapper.py 0.3 on 2022-07-29 05:40:07 -// flags: ./generate-wrapper.py --include /usr/include/fontconfig/fontconfig.h --sys-include <fontconfig/fontconfig.h> --soname libfontconfig.so --init-name fontconfig --output-header fontconfig-so_wrap.h --output-implementation fontconfig-so_wrap.c --omit-prefix FcCharSet +// generated by generate-wrapper.py 0.3 on 2023-01-12 10:15:54 +// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/fontconfig/fontconfig.h --sys-include "thirdparty/linuxbsd_headers/fontconfig/fontconfig.h" --soname libfontconfig.so.1 --init-name fontconfig --omit-prefix FcCharSetFirst --omit-prefix FcCharSetNext --output-header ./platform/linuxbsd/fontconfig-so_wrap.h --output-implementation ./platform/linuxbsd/fontconfig-so_wrap.c // #include <stdint.h> @@ -44,6 +44,23 @@ #define FcConfigSubstitute FcConfigSubstitute_dylibloader_orig_fontconfig #define FcConfigGetSysRoot FcConfigGetSysRoot_dylibloader_orig_fontconfig #define FcConfigSetSysRoot FcConfigSetSysRoot_dylibloader_orig_fontconfig +#define FcCharSetCreate FcCharSetCreate_dylibloader_orig_fontconfig +#define FcCharSetNew FcCharSetNew_dylibloader_orig_fontconfig +#define FcCharSetDestroy FcCharSetDestroy_dylibloader_orig_fontconfig +#define FcCharSetAddChar FcCharSetAddChar_dylibloader_orig_fontconfig +#define FcCharSetDelChar FcCharSetDelChar_dylibloader_orig_fontconfig +#define FcCharSetCopy FcCharSetCopy_dylibloader_orig_fontconfig +#define FcCharSetEqual FcCharSetEqual_dylibloader_orig_fontconfig +#define FcCharSetIntersect FcCharSetIntersect_dylibloader_orig_fontconfig +#define FcCharSetUnion FcCharSetUnion_dylibloader_orig_fontconfig +#define FcCharSetSubtract FcCharSetSubtract_dylibloader_orig_fontconfig +#define FcCharSetMerge FcCharSetMerge_dylibloader_orig_fontconfig +#define FcCharSetHasChar FcCharSetHasChar_dylibloader_orig_fontconfig +#define FcCharSetCount FcCharSetCount_dylibloader_orig_fontconfig +#define FcCharSetIntersectCount FcCharSetIntersectCount_dylibloader_orig_fontconfig +#define FcCharSetSubtractCount FcCharSetSubtractCount_dylibloader_orig_fontconfig +#define FcCharSetIsSubset FcCharSetIsSubset_dylibloader_orig_fontconfig +#define FcCharSetCoverage FcCharSetCoverage_dylibloader_orig_fontconfig #define FcValuePrint FcValuePrint_dylibloader_orig_fontconfig #define FcPatternPrint FcPatternPrint_dylibloader_orig_fontconfig #define FcFontSetPrint FcFontSetPrint_dylibloader_orig_fontconfig @@ -193,7 +210,7 @@ #define FcStrListDone FcStrListDone_dylibloader_orig_fontconfig #define FcConfigParseAndLoad FcConfigParseAndLoad_dylibloader_orig_fontconfig #define FcConfigParseAndLoadFromMemory FcConfigParseAndLoadFromMemory_dylibloader_orig_fontconfig -#include <fontconfig/fontconfig.h> +#include "thirdparty/linuxbsd_headers/fontconfig/fontconfig.h" #undef FcBlanksCreate #undef FcBlanksDestroy #undef FcBlanksAdd @@ -233,6 +250,23 @@ #undef FcConfigSubstitute #undef FcConfigGetSysRoot #undef FcConfigSetSysRoot +#undef FcCharSetCreate +#undef FcCharSetNew +#undef FcCharSetDestroy +#undef FcCharSetAddChar +#undef FcCharSetDelChar +#undef FcCharSetCopy +#undef FcCharSetEqual +#undef FcCharSetIntersect +#undef FcCharSetUnion +#undef FcCharSetSubtract +#undef FcCharSetMerge +#undef FcCharSetHasChar +#undef FcCharSetCount +#undef FcCharSetIntersectCount +#undef FcCharSetSubtractCount +#undef FcCharSetIsSubset +#undef FcCharSetCoverage #undef FcValuePrint #undef FcPatternPrint #undef FcFontSetPrint @@ -423,6 +457,23 @@ FcBool (*FcConfigSubstituteWithPat_dylibloader_wrapper_fontconfig)( FcConfig*, F FcBool (*FcConfigSubstitute_dylibloader_wrapper_fontconfig)( FcConfig*, FcPattern*, FcMatchKind); const FcChar8* (*FcConfigGetSysRoot_dylibloader_wrapper_fontconfig)(const FcConfig*); void (*FcConfigSetSysRoot_dylibloader_wrapper_fontconfig)( FcConfig*,const FcChar8*); +FcCharSet* (*FcCharSetCreate_dylibloader_wrapper_fontconfig)( void); +FcCharSet* (*FcCharSetNew_dylibloader_wrapper_fontconfig)( void); +void (*FcCharSetDestroy_dylibloader_wrapper_fontconfig)( FcCharSet*); +FcBool (*FcCharSetAddChar_dylibloader_wrapper_fontconfig)( FcCharSet*, FcChar32); +FcBool (*FcCharSetDelChar_dylibloader_wrapper_fontconfig)( FcCharSet*, FcChar32); +FcCharSet* (*FcCharSetCopy_dylibloader_wrapper_fontconfig)( FcCharSet*); +FcBool (*FcCharSetEqual_dylibloader_wrapper_fontconfig)(const FcCharSet*,const FcCharSet*); +FcCharSet* (*FcCharSetIntersect_dylibloader_wrapper_fontconfig)(const FcCharSet*,const FcCharSet*); +FcCharSet* (*FcCharSetUnion_dylibloader_wrapper_fontconfig)(const FcCharSet*,const FcCharSet*); +FcCharSet* (*FcCharSetSubtract_dylibloader_wrapper_fontconfig)(const FcCharSet*,const FcCharSet*); +FcBool (*FcCharSetMerge_dylibloader_wrapper_fontconfig)( FcCharSet*,const FcCharSet*, FcBool*); +FcBool (*FcCharSetHasChar_dylibloader_wrapper_fontconfig)(const FcCharSet*, FcChar32); +FcChar32 (*FcCharSetCount_dylibloader_wrapper_fontconfig)(const FcCharSet*); +FcChar32 (*FcCharSetIntersectCount_dylibloader_wrapper_fontconfig)(const FcCharSet*,const FcCharSet*); +FcChar32 (*FcCharSetSubtractCount_dylibloader_wrapper_fontconfig)(const FcCharSet*,const FcCharSet*); +FcBool (*FcCharSetIsSubset_dylibloader_wrapper_fontconfig)(const FcCharSet*,const FcCharSet*); +FcChar32 (*FcCharSetCoverage_dylibloader_wrapper_fontconfig)(const FcCharSet*, FcChar32, FcChar32*); void (*FcValuePrint_dylibloader_wrapper_fontconfig)(const FcValue); void (*FcPatternPrint_dylibloader_wrapper_fontconfig)(const FcPattern*); void (*FcFontSetPrint_dylibloader_wrapper_fontconfig)(const FcFontSet*); @@ -575,7 +626,7 @@ FcBool (*FcConfigParseAndLoadFromMemory_dylibloader_wrapper_fontconfig)( FcConfi int initialize_fontconfig(int verbose) { void *handle; char *error; - handle = dlopen("libfontconfig.so", RTLD_LAZY); + handle = dlopen("libfontconfig.so.1", RTLD_LAZY); if (!handle) { if (verbose) { fprintf(stderr, "%s\n", dlerror()); @@ -895,6 +946,142 @@ int initialize_fontconfig(int verbose) { fprintf(stderr, "%s\n", error); } } +// FcCharSetCreate + *(void **) (&FcCharSetCreate_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcCharSetCreate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcCharSetNew + *(void **) (&FcCharSetNew_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcCharSetNew"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcCharSetDestroy + *(void **) (&FcCharSetDestroy_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcCharSetDestroy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcCharSetAddChar + *(void **) (&FcCharSetAddChar_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcCharSetAddChar"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcCharSetDelChar + *(void **) (&FcCharSetDelChar_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcCharSetDelChar"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcCharSetCopy + *(void **) (&FcCharSetCopy_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcCharSetCopy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcCharSetEqual + *(void **) (&FcCharSetEqual_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcCharSetEqual"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcCharSetIntersect + *(void **) (&FcCharSetIntersect_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcCharSetIntersect"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcCharSetUnion + *(void **) (&FcCharSetUnion_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcCharSetUnion"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcCharSetSubtract + *(void **) (&FcCharSetSubtract_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcCharSetSubtract"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcCharSetMerge + *(void **) (&FcCharSetMerge_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcCharSetMerge"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcCharSetHasChar + *(void **) (&FcCharSetHasChar_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcCharSetHasChar"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcCharSetCount + *(void **) (&FcCharSetCount_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcCharSetCount"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcCharSetIntersectCount + *(void **) (&FcCharSetIntersectCount_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcCharSetIntersectCount"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcCharSetSubtractCount + *(void **) (&FcCharSetSubtractCount_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcCharSetSubtractCount"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcCharSetIsSubset + *(void **) (&FcCharSetIsSubset_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcCharSetIsSubset"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcCharSetCoverage + *(void **) (&FcCharSetCoverage_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcCharSetCoverage"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } // FcValuePrint *(void **) (&FcValuePrint_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcValuePrint"); if (verbose) { diff --git a/platform/linuxbsd/fontconfig-so_wrap.h b/platform/linuxbsd/fontconfig-so_wrap.h index f0794cce8b..956c094711 100644 --- a/platform/linuxbsd/fontconfig-so_wrap.h +++ b/platform/linuxbsd/fontconfig-so_wrap.h @@ -2,8 +2,8 @@ #define DYLIBLOAD_WRAPPER_FONTCONFIG // This file is generated. Do not edit! // see https://github.com/hpvb/dynload-wrapper for details -// generated by ./generate-wrapper.py 0.3 on 2022-07-29 05:40:07 -// flags: ./generate-wrapper.py --include /usr/include/fontconfig/fontconfig.h --sys-include <fontconfig/fontconfig.h> --soname libfontconfig.so --init-name fontconfig --output-header fontconfig-so_wrap.h --output-implementation fontconfig-so_wrap.c --omit-prefix FcCharSet +// generated by generate-wrapper.py 0.3 on 2023-01-12 10:15:54 +// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/fontconfig/fontconfig.h --sys-include "thirdparty/linuxbsd_headers/fontconfig/fontconfig.h" --soname libfontconfig.so.1 --init-name fontconfig --omit-prefix FcCharSetFirst --omit-prefix FcCharSetNext --output-header ./platform/linuxbsd/fontconfig-so_wrap.h --output-implementation ./platform/linuxbsd/fontconfig-so_wrap.c // #include <stdint.h> @@ -46,6 +46,23 @@ #define FcConfigSubstitute FcConfigSubstitute_dylibloader_orig_fontconfig #define FcConfigGetSysRoot FcConfigGetSysRoot_dylibloader_orig_fontconfig #define FcConfigSetSysRoot FcConfigSetSysRoot_dylibloader_orig_fontconfig +#define FcCharSetCreate FcCharSetCreate_dylibloader_orig_fontconfig +#define FcCharSetNew FcCharSetNew_dylibloader_orig_fontconfig +#define FcCharSetDestroy FcCharSetDestroy_dylibloader_orig_fontconfig +#define FcCharSetAddChar FcCharSetAddChar_dylibloader_orig_fontconfig +#define FcCharSetDelChar FcCharSetDelChar_dylibloader_orig_fontconfig +#define FcCharSetCopy FcCharSetCopy_dylibloader_orig_fontconfig +#define FcCharSetEqual FcCharSetEqual_dylibloader_orig_fontconfig +#define FcCharSetIntersect FcCharSetIntersect_dylibloader_orig_fontconfig +#define FcCharSetUnion FcCharSetUnion_dylibloader_orig_fontconfig +#define FcCharSetSubtract FcCharSetSubtract_dylibloader_orig_fontconfig +#define FcCharSetMerge FcCharSetMerge_dylibloader_orig_fontconfig +#define FcCharSetHasChar FcCharSetHasChar_dylibloader_orig_fontconfig +#define FcCharSetCount FcCharSetCount_dylibloader_orig_fontconfig +#define FcCharSetIntersectCount FcCharSetIntersectCount_dylibloader_orig_fontconfig +#define FcCharSetSubtractCount FcCharSetSubtractCount_dylibloader_orig_fontconfig +#define FcCharSetIsSubset FcCharSetIsSubset_dylibloader_orig_fontconfig +#define FcCharSetCoverage FcCharSetCoverage_dylibloader_orig_fontconfig #define FcValuePrint FcValuePrint_dylibloader_orig_fontconfig #define FcPatternPrint FcPatternPrint_dylibloader_orig_fontconfig #define FcFontSetPrint FcFontSetPrint_dylibloader_orig_fontconfig @@ -195,7 +212,7 @@ #define FcStrListDone FcStrListDone_dylibloader_orig_fontconfig #define FcConfigParseAndLoad FcConfigParseAndLoad_dylibloader_orig_fontconfig #define FcConfigParseAndLoadFromMemory FcConfigParseAndLoadFromMemory_dylibloader_orig_fontconfig -#include <fontconfig/fontconfig.h> +#include "thirdparty/linuxbsd_headers/fontconfig/fontconfig.h" #undef FcBlanksCreate #undef FcBlanksDestroy #undef FcBlanksAdd @@ -235,6 +252,23 @@ #undef FcConfigSubstitute #undef FcConfigGetSysRoot #undef FcConfigSetSysRoot +#undef FcCharSetCreate +#undef FcCharSetNew +#undef FcCharSetDestroy +#undef FcCharSetAddChar +#undef FcCharSetDelChar +#undef FcCharSetCopy +#undef FcCharSetEqual +#undef FcCharSetIntersect +#undef FcCharSetUnion +#undef FcCharSetSubtract +#undef FcCharSetMerge +#undef FcCharSetHasChar +#undef FcCharSetCount +#undef FcCharSetIntersectCount +#undef FcCharSetSubtractCount +#undef FcCharSetIsSubset +#undef FcCharSetCoverage #undef FcValuePrint #undef FcPatternPrint #undef FcFontSetPrint @@ -426,6 +460,23 @@ extern "C" { #define FcConfigSubstitute FcConfigSubstitute_dylibloader_wrapper_fontconfig #define FcConfigGetSysRoot FcConfigGetSysRoot_dylibloader_wrapper_fontconfig #define FcConfigSetSysRoot FcConfigSetSysRoot_dylibloader_wrapper_fontconfig +#define FcCharSetCreate FcCharSetCreate_dylibloader_wrapper_fontconfig +#define FcCharSetNew FcCharSetNew_dylibloader_wrapper_fontconfig +#define FcCharSetDestroy FcCharSetDestroy_dylibloader_wrapper_fontconfig +#define FcCharSetAddChar FcCharSetAddChar_dylibloader_wrapper_fontconfig +#define FcCharSetDelChar FcCharSetDelChar_dylibloader_wrapper_fontconfig +#define FcCharSetCopy FcCharSetCopy_dylibloader_wrapper_fontconfig +#define FcCharSetEqual FcCharSetEqual_dylibloader_wrapper_fontconfig +#define FcCharSetIntersect FcCharSetIntersect_dylibloader_wrapper_fontconfig +#define FcCharSetUnion FcCharSetUnion_dylibloader_wrapper_fontconfig +#define FcCharSetSubtract FcCharSetSubtract_dylibloader_wrapper_fontconfig +#define FcCharSetMerge FcCharSetMerge_dylibloader_wrapper_fontconfig +#define FcCharSetHasChar FcCharSetHasChar_dylibloader_wrapper_fontconfig +#define FcCharSetCount FcCharSetCount_dylibloader_wrapper_fontconfig +#define FcCharSetIntersectCount FcCharSetIntersectCount_dylibloader_wrapper_fontconfig +#define FcCharSetSubtractCount FcCharSetSubtractCount_dylibloader_wrapper_fontconfig +#define FcCharSetIsSubset FcCharSetIsSubset_dylibloader_wrapper_fontconfig +#define FcCharSetCoverage FcCharSetCoverage_dylibloader_wrapper_fontconfig #define FcValuePrint FcValuePrint_dylibloader_wrapper_fontconfig #define FcPatternPrint FcPatternPrint_dylibloader_wrapper_fontconfig #define FcFontSetPrint FcFontSetPrint_dylibloader_wrapper_fontconfig @@ -614,6 +665,23 @@ extern FcBool (*FcConfigSubstituteWithPat_dylibloader_wrapper_fontconfig)( FcCon extern FcBool (*FcConfigSubstitute_dylibloader_wrapper_fontconfig)( FcConfig*, FcPattern*, FcMatchKind); extern const FcChar8* (*FcConfigGetSysRoot_dylibloader_wrapper_fontconfig)(const FcConfig*); extern void (*FcConfigSetSysRoot_dylibloader_wrapper_fontconfig)( FcConfig*,const FcChar8*); +extern FcCharSet* (*FcCharSetCreate_dylibloader_wrapper_fontconfig)( void); +extern FcCharSet* (*FcCharSetNew_dylibloader_wrapper_fontconfig)( void); +extern void (*FcCharSetDestroy_dylibloader_wrapper_fontconfig)( FcCharSet*); +extern FcBool (*FcCharSetAddChar_dylibloader_wrapper_fontconfig)( FcCharSet*, FcChar32); +extern FcBool (*FcCharSetDelChar_dylibloader_wrapper_fontconfig)( FcCharSet*, FcChar32); +extern FcCharSet* (*FcCharSetCopy_dylibloader_wrapper_fontconfig)( FcCharSet*); +extern FcBool (*FcCharSetEqual_dylibloader_wrapper_fontconfig)(const FcCharSet*,const FcCharSet*); +extern FcCharSet* (*FcCharSetIntersect_dylibloader_wrapper_fontconfig)(const FcCharSet*,const FcCharSet*); +extern FcCharSet* (*FcCharSetUnion_dylibloader_wrapper_fontconfig)(const FcCharSet*,const FcCharSet*); +extern FcCharSet* (*FcCharSetSubtract_dylibloader_wrapper_fontconfig)(const FcCharSet*,const FcCharSet*); +extern FcBool (*FcCharSetMerge_dylibloader_wrapper_fontconfig)( FcCharSet*,const FcCharSet*, FcBool*); +extern FcBool (*FcCharSetHasChar_dylibloader_wrapper_fontconfig)(const FcCharSet*, FcChar32); +extern FcChar32 (*FcCharSetCount_dylibloader_wrapper_fontconfig)(const FcCharSet*); +extern FcChar32 (*FcCharSetIntersectCount_dylibloader_wrapper_fontconfig)(const FcCharSet*,const FcCharSet*); +extern FcChar32 (*FcCharSetSubtractCount_dylibloader_wrapper_fontconfig)(const FcCharSet*,const FcCharSet*); +extern FcBool (*FcCharSetIsSubset_dylibloader_wrapper_fontconfig)(const FcCharSet*,const FcCharSet*); +extern FcChar32 (*FcCharSetCoverage_dylibloader_wrapper_fontconfig)(const FcCharSet*, FcChar32, FcChar32*); extern void (*FcValuePrint_dylibloader_wrapper_fontconfig)(const FcValue); extern void (*FcPatternPrint_dylibloader_wrapper_fontconfig)(const FcPattern*); extern void (*FcFontSetPrint_dylibloader_wrapper_fontconfig)(const FcFontSet*); diff --git a/platform/linuxbsd/freedesktop_portal_desktop.cpp b/platform/linuxbsd/freedesktop_portal_desktop.cpp index ed54084694..c3cb0f411d 100644 --- a/platform/linuxbsd/freedesktop_portal_desktop.cpp +++ b/platform/linuxbsd/freedesktop_portal_desktop.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* freedesktop_portal_desktop.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* freedesktop_portal_desktop.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "freedesktop_portal_desktop.h" @@ -35,10 +35,13 @@ #include "core/error/error_macros.h" #include "core/os/os.h" #include "core/string/ustring.h" +#include "core/variant/variant.h" +#ifdef SOWRAP_ENABLED #include "dbus-so_wrap.h" - -#include "core/variant/variant.h" +#else +#include <dbus/dbus.h> +#endif #define BUS_OBJECT_NAME "org.freedesktop.portal.Desktop" #define BUS_OBJECT_PATH "/org/freedesktop/portal/desktop" @@ -124,12 +127,32 @@ uint32_t FreeDesktopPortalDesktop::get_appearance_color_scheme() { } FreeDesktopPortalDesktop::FreeDesktopPortalDesktop() { +#ifdef SOWRAP_ENABLED #ifdef DEBUG_ENABLED int dylibloader_verbose = 1; #else int dylibloader_verbose = 0; #endif unsupported = (initialize_dbus(dylibloader_verbose) != 0); +#else + unsupported = false; +#endif + + if (unsupported) { + return; + } + + bool ver_ok = false; + int version_major = 0; + int version_minor = 0; + int version_rev = 0; + dbus_get_version(&version_major, &version_minor, &version_rev); + ver_ok = (version_major == 1 && version_minor >= 10) || (version_major > 1); // 1.10.0 + print_verbose(vformat("PortalDesktop: DBus %d.%d.%d detected.", version_major, version_minor, version_rev)); + if (!ver_ok) { + print_verbose("PortalDesktop: Unsupported DBus library version!"); + unsupported = true; + } } #endif // DBUS_ENABLED diff --git a/platform/linuxbsd/freedesktop_portal_desktop.h b/platform/linuxbsd/freedesktop_portal_desktop.h index 3d976b1ede..1520ab3a1f 100644 --- a/platform/linuxbsd/freedesktop_portal_desktop.h +++ b/platform/linuxbsd/freedesktop_portal_desktop.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* freedesktop_portal_desktop.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* freedesktop_portal_desktop.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 FREEDESKTOP_PORTAL_DESKTOP_H #define FREEDESKTOP_PORTAL_DESKTOP_H diff --git a/platform/linuxbsd/freedesktop_screensaver.cpp b/platform/linuxbsd/freedesktop_screensaver.cpp index 88ec37c456..cf179b5735 100644 --- a/platform/linuxbsd/freedesktop_screensaver.cpp +++ b/platform/linuxbsd/freedesktop_screensaver.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* freedesktop_screensaver.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* freedesktop_screensaver.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "freedesktop_screensaver.h" @@ -34,7 +34,11 @@ #include "core/config/project_settings.h" +#ifdef SOWRAP_ENABLED #include "dbus-so_wrap.h" +#else +#include <dbus/dbus.h> +#endif #define BUS_OBJECT_NAME "org.freedesktop.ScreenSaver" #define BUS_OBJECT_PATH "/org/freedesktop/ScreenSaver" @@ -127,12 +131,32 @@ void FreeDesktopScreenSaver::uninhibit() { } FreeDesktopScreenSaver::FreeDesktopScreenSaver() { +#ifdef SOWRAP_ENABLED #ifdef DEBUG_ENABLED int dylibloader_verbose = 1; #else int dylibloader_verbose = 0; #endif unsupported = (initialize_dbus(dylibloader_verbose) != 0); +#else + unsupported = false; +#endif + + if (unsupported) { + return; + } + + bool ver_ok = false; + int version_major = 0; + int version_minor = 0; + int version_rev = 0; + dbus_get_version(&version_major, &version_minor, &version_rev); + ver_ok = (version_major == 1 && version_minor >= 10) || (version_major > 1); // 1.10.0 + print_verbose(vformat("ScreenSaver: DBus %d.%d.%d detected.", version_major, version_minor, version_rev)); + if (!ver_ok) { + print_verbose("ScreenSaver:: Unsupported DBus library version!"); + unsupported = true; + } } #endif // DBUS_ENABLED diff --git a/platform/linuxbsd/freedesktop_screensaver.h b/platform/linuxbsd/freedesktop_screensaver.h index 1a8b010cd5..e9f0c566a5 100644 --- a/platform/linuxbsd/freedesktop_screensaver.h +++ b/platform/linuxbsd/freedesktop_screensaver.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* freedesktop_screensaver.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* freedesktop_screensaver.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 FREEDESKTOP_SCREENSAVER_H #define FREEDESKTOP_SCREENSAVER_H diff --git a/platform/linuxbsd/godot_linuxbsd.cpp b/platform/linuxbsd/godot_linuxbsd.cpp index fa5e20891c..d059d60b72 100644 --- a/platform/linuxbsd/godot_linuxbsd.cpp +++ b/platform/linuxbsd/godot_linuxbsd.cpp @@ -1,32 +1,36 @@ -/*************************************************************************/ -/* godot_linuxbsd.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* godot_linuxbsd.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "os_linuxbsd.h" + +#include "main/main.h" #include <limits.h> #include <locale.h> @@ -37,9 +41,6 @@ #include <sys/resource.h> #endif -#include "main/main.h" -#include "os_linuxbsd.h" - int main(int argc, char *argv[]) { #if defined(SANITIZERS_ENABLED) // Note: Set stack size to be at least 30 MB (vs 8 MB default) to avoid overflow, address sanitizer can increase stack usage up to 3 times. diff --git a/platform/linuxbsd/joypad_linux.cpp b/platform/linuxbsd/joypad_linux.cpp index bc018e366b..ab79885fb4 100644 --- a/platform/linuxbsd/joypad_linux.cpp +++ b/platform/linuxbsd/joypad_linux.cpp @@ -1,37 +1,39 @@ -/*************************************************************************/ -/* joypad_linux.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* joypad_linux.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ #ifdef JOYDEV_ENABLED #include "joypad_linux.h" +#include "core/os/os.h" + #include <dirent.h> #include <errno.h> #include <fcntl.h> @@ -39,7 +41,11 @@ #include <unistd.h> #ifdef UDEV_ENABLED +#ifdef SOWRAP_ENABLED #include "libudev-so_wrap.h" +#else +#include <libudev.h> +#endif #endif #define LONG_BITS (sizeof(long) * 8) @@ -59,7 +65,7 @@ JoypadLinux::Joypad::~Joypad() { } void JoypadLinux::Joypad::reset() { - dpad = HatMask::CENTER; + dpad = 0; fd = -1; for (int i = 0; i < MAX_ABS; i++) { abs_map[i] = -1; @@ -68,19 +74,57 @@ void JoypadLinux::Joypad::reset() { events.clear(); } +#ifdef UDEV_ENABLED +// This function is derived from SDL: +// https://github.com/libsdl-org/SDL/blob/main/src/core/linux/SDL_sandbox.c#L28-L45 +static bool detect_sandbox() { + if (access("/.flatpak-info", F_OK) == 0) { + return true; + } + + // For Snap, we check multiple variables because they might be set for + // unrelated reasons. This is the same thing WebKitGTK does. + if (OS::get_singleton()->has_environment("SNAP") && OS::get_singleton()->has_environment("SNAP_NAME") && OS::get_singleton()->has_environment("SNAP_REVISION")) { + return true; + } + + if (access("/run/host/container-manager", F_OK) == 0) { + return true; + } + + return false; +} +#endif // UDEV_ENABLED + JoypadLinux::JoypadLinux(Input *in) { #ifdef UDEV_ENABLED +#ifdef SOWRAP_ENABLED #ifdef DEBUG_ENABLED int dylibloader_verbose = 1; #else int dylibloader_verbose = 0; #endif - use_udev = initialize_libudev(dylibloader_verbose) == 0; - if (use_udev) { - print_verbose("JoypadLinux: udev enabled and loaded successfully."); + if (detect_sandbox()) { + // Linux binaries in sandboxes / containers need special handling because + // libudev doesn't work there. So we need to fallback to manual parsing + // of /dev/input in such case. + use_udev = false; + print_verbose("JoypadLinux: udev enabled, but detected incompatible sandboxed mode. Falling back to /dev/input to detect joypads."); } else { - print_verbose("JoypadLinux: udev enabled, but couldn't be loaded. Falling back to /dev/input to detect joypads."); + use_udev = initialize_libudev(dylibloader_verbose) == 0; + if (use_udev) { + if (!udev_new || !udev_unref || !udev_enumerate_new || !udev_enumerate_add_match_subsystem || !udev_enumerate_scan_devices || !udev_enumerate_get_list_entry || !udev_list_entry_get_next || !udev_list_entry_get_name || !udev_device_new_from_syspath || !udev_device_get_devnode || !udev_device_get_action || !udev_device_unref || !udev_enumerate_unref || !udev_monitor_new_from_netlink || !udev_monitor_filter_add_match_subsystem_devtype || !udev_monitor_enable_receiving || !udev_monitor_get_fd || !udev_monitor_receive_device || !udev_monitor_unref) { + // There's no API to check version, check if functions are available instead. + use_udev = false; + print_verbose("JoypadLinux: Unsupported udev library version!"); + } else { + print_verbose("JoypadLinux: udev enabled and loaded successfully."); + } + } else { + print_verbose("JoypadLinux: udev enabled, but couldn't be loaded. Falling back to /dev/input to detect joypads."); + } } +#endif #else print_verbose("JoypadLinux: udev disabled, parsing /dev/input to detect joypads."); #endif @@ -218,8 +262,8 @@ void JoypadLinux::monitor_joypads() { } } closedir(input_directory); + usleep(1000000); // 1s } - usleep(1000000); // 1s } void JoypadLinux::close_joypads() { @@ -485,27 +529,33 @@ void JoypadLinux::process_joypads() { case ABS_HAT0X: if (joypad_event.value != 0) { if (joypad_event.value < 0) { - joypad.dpad = (HatMask)((joypad.dpad | HatMask::LEFT) & ~HatMask::RIGHT); + joypad.dpad.set_flag(HatMask::LEFT); + joypad.dpad.clear_flag(HatMask::RIGHT); } else { - joypad.dpad = (HatMask)((joypad.dpad | HatMask::RIGHT) & ~HatMask::LEFT); + joypad.dpad.set_flag(HatMask::RIGHT); + joypad.dpad.clear_flag(HatMask::LEFT); } } else { - joypad.dpad &= ~(HatMask::LEFT | HatMask::RIGHT); + joypad.dpad.clear_flag(HatMask::LEFT); + joypad.dpad.clear_flag(HatMask::RIGHT); } - input->joy_hat(i, (HatMask)joypad.dpad); + input->joy_hat(i, joypad.dpad); break; case ABS_HAT0Y: if (joypad_event.value != 0) { if (joypad_event.value < 0) { - joypad.dpad = (HatMask)((joypad.dpad | HatMask::UP) & ~HatMask::DOWN); + joypad.dpad.set_flag(HatMask::UP); + joypad.dpad.clear_flag(HatMask::DOWN); } else { - joypad.dpad = (HatMask)((joypad.dpad | HatMask::DOWN) & ~HatMask::UP); + joypad.dpad.set_flag(HatMask::DOWN); + joypad.dpad.clear_flag(HatMask::UP); } } else { - joypad.dpad &= ~(HatMask::UP | HatMask::DOWN); + joypad.dpad.clear_flag(HatMask::UP); + joypad.dpad.clear_flag(HatMask::DOWN); } - input->joy_hat(i, (HatMask)joypad.dpad); + input->joy_hat(i, joypad.dpad); break; default: diff --git a/platform/linuxbsd/joypad_linux.h b/platform/linuxbsd/joypad_linux.h index 4afc261ce7..26a9908d4e 100644 --- a/platform/linuxbsd/joypad_linux.h +++ b/platform/linuxbsd/joypad_linux.h @@ -1,37 +1,38 @@ -/*************************************************************************/ -/* joypad_linux.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* joypad_linux.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 JOYPAD_LINUX_H #define JOYPAD_LINUX_H #ifdef JOYDEV_ENABLED + #include "core/input/input.h" #include "core/os/mutex.h" #include "core/os/thread.h" @@ -62,7 +63,7 @@ private: float curr_axis[MAX_ABS]; int key_map[MAX_KEY]; int abs_map[MAX_ABS]; - HatMask dpad = HatMask::CENTER; + BitField<HatMask> dpad; int fd = -1; String devpath; diff --git a/platform/linuxbsd/libudev-so_wrap.c b/platform/linuxbsd/libudev-so_wrap.c index a9fa4a494a..5455c1ab4e 100644 --- a/platform/linuxbsd/libudev-so_wrap.c +++ b/platform/linuxbsd/libudev-so_wrap.c @@ -1,7 +1,7 @@ // This file is generated. Do not edit! // see https://github.com/hpvb/dynload-wrapper for details -// generated by /home/hp/Projects/godot/pulse/generate-wrapper.py 0.3 on 2021-02-20 00:08:59 -// flags: /home/hp/Projects/godot/pulse/generate-wrapper.py --include /usr/include/libudev.h --sys-include <libudev.h> --soname libudev.so.1 --init-name libudev --omit-prefix gnu_ --output-header libudev-so_wrap.h --output-implementation libudev-so_wrap.c +// generated by generate-wrapper.py 0.3 on 2023-01-12 10:23:01 +// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/udev/libudev.h --sys-include "thirdparty/linuxbsd_headers/udev/libudev.h" --soname libudev.so.1 --init-name libudev --omit-prefix gnu_ --output-header ./platform/linuxbsd/libudev-so_wrap.h --output-implementation ./platform/linuxbsd/libudev-so_wrap.c // #include <stdint.h> @@ -95,7 +95,7 @@ #define udev_hwdb_unref udev_hwdb_unref_dylibloader_orig_libudev #define udev_hwdb_get_properties_list_entry udev_hwdb_get_properties_list_entry_dylibloader_orig_libudev #define udev_util_encode_string udev_util_encode_string_dylibloader_orig_libudev -#include <libudev.h> +#include "thirdparty/linuxbsd_headers/udev/libudev.h" #undef udev_ref #undef udev_unref #undef udev_new @@ -229,7 +229,7 @@ const char* (*udev_device_get_action_dylibloader_wrapper_libudev)(struct udev_de unsigned long long int (*udev_device_get_seqnum_dylibloader_wrapper_libudev)(struct udev_device*); unsigned long long int (*udev_device_get_usec_since_initialized_dylibloader_wrapper_libudev)(struct udev_device*); const char* (*udev_device_get_sysattr_value_dylibloader_wrapper_libudev)(struct udev_device*,const char*); -int (*udev_device_set_sysattr_value_dylibloader_wrapper_libudev)(struct udev_device*,const char*,const char*); +int (*udev_device_set_sysattr_value_dylibloader_wrapper_libudev)(struct udev_device*,const char*, char*); int (*udev_device_has_tag_dylibloader_wrapper_libudev)(struct udev_device*,const char*); struct udev_monitor* (*udev_monitor_ref_dylibloader_wrapper_libudev)(struct udev_monitor*); struct udev_monitor* (*udev_monitor_unref_dylibloader_wrapper_libudev)(struct udev_monitor*); @@ -276,7 +276,7 @@ struct udev_list_entry* (*udev_queue_get_queued_list_entry_dylibloader_wrapper_l struct udev_hwdb* (*udev_hwdb_new_dylibloader_wrapper_libudev)(struct udev*); struct udev_hwdb* (*udev_hwdb_ref_dylibloader_wrapper_libudev)(struct udev_hwdb*); struct udev_hwdb* (*udev_hwdb_unref_dylibloader_wrapper_libudev)(struct udev_hwdb*); -struct udev_list_entry* (*udev_hwdb_get_properties_list_entry_dylibloader_wrapper_libudev)(struct udev_hwdb*,const char*, unsigned); +struct udev_list_entry* (*udev_hwdb_get_properties_list_entry_dylibloader_wrapper_libudev)(struct udev_hwdb*,const char*, unsigned int); int (*udev_util_encode_string_dylibloader_wrapper_libudev)(const char*, char*, size_t); int initialize_libudev(int verbose) { void *handle; diff --git a/platform/linuxbsd/libudev-so_wrap.h b/platform/linuxbsd/libudev-so_wrap.h index dd43fd1191..174a3663d4 100644 --- a/platform/linuxbsd/libudev-so_wrap.h +++ b/platform/linuxbsd/libudev-so_wrap.h @@ -2,8 +2,8 @@ #define DYLIBLOAD_WRAPPER_LIBUDEV // This file is generated. Do not edit! // see https://github.com/hpvb/dynload-wrapper for details -// generated by /home/hp/Projects/godot/pulse/generate-wrapper.py 0.3 on 2021-02-20 00:08:59 -// flags: /home/hp/Projects/godot/pulse/generate-wrapper.py --include /usr/include/libudev.h --sys-include <libudev.h> --soname libudev.so.1 --init-name libudev --omit-prefix gnu_ --output-header libudev-so_wrap.h --output-implementation libudev-so_wrap.c +// generated by generate-wrapper.py 0.3 on 2023-01-12 10:23:01 +// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/udev/libudev.h --sys-include "thirdparty/linuxbsd_headers/udev/libudev.h" --soname libudev.so.1 --init-name libudev --omit-prefix gnu_ --output-header ./platform/linuxbsd/libudev-so_wrap.h --output-implementation ./platform/linuxbsd/libudev-so_wrap.c // #include <stdint.h> @@ -97,7 +97,7 @@ #define udev_hwdb_unref udev_hwdb_unref_dylibloader_orig_libudev #define udev_hwdb_get_properties_list_entry udev_hwdb_get_properties_list_entry_dylibloader_orig_libudev #define udev_util_encode_string udev_util_encode_string_dylibloader_orig_libudev -#include <libudev.h> +#include "thirdparty/linuxbsd_headers/udev/libudev.h" #undef udev_ref #undef udev_unref #undef udev_new @@ -322,7 +322,7 @@ extern const char* (*udev_device_get_action_dylibloader_wrapper_libudev)(struct extern unsigned long long int (*udev_device_get_seqnum_dylibloader_wrapper_libudev)(struct udev_device*); extern unsigned long long int (*udev_device_get_usec_since_initialized_dylibloader_wrapper_libudev)(struct udev_device*); extern const char* (*udev_device_get_sysattr_value_dylibloader_wrapper_libudev)(struct udev_device*,const char*); -extern int (*udev_device_set_sysattr_value_dylibloader_wrapper_libudev)(struct udev_device*,const char*,const char*); +extern int (*udev_device_set_sysattr_value_dylibloader_wrapper_libudev)(struct udev_device*,const char*, char*); extern int (*udev_device_has_tag_dylibloader_wrapper_libudev)(struct udev_device*,const char*); extern struct udev_monitor* (*udev_monitor_ref_dylibloader_wrapper_libudev)(struct udev_monitor*); extern struct udev_monitor* (*udev_monitor_unref_dylibloader_wrapper_libudev)(struct udev_monitor*); @@ -369,7 +369,7 @@ extern struct udev_list_entry* (*udev_queue_get_queued_list_entry_dylibloader_wr extern struct udev_hwdb* (*udev_hwdb_new_dylibloader_wrapper_libudev)(struct udev*); extern struct udev_hwdb* (*udev_hwdb_ref_dylibloader_wrapper_libudev)(struct udev_hwdb*); extern struct udev_hwdb* (*udev_hwdb_unref_dylibloader_wrapper_libudev)(struct udev_hwdb*); -extern struct udev_list_entry* (*udev_hwdb_get_properties_list_entry_dylibloader_wrapper_libudev)(struct udev_hwdb*,const char*, unsigned); +extern struct udev_list_entry* (*udev_hwdb_get_properties_list_entry_dylibloader_wrapper_libudev)(struct udev_hwdb*,const char*, unsigned int); extern int (*udev_util_encode_string_dylibloader_wrapper_libudev)(const char*, char*, size_t); int initialize_libudev(int verbose); #ifdef __cplusplus diff --git a/platform/linuxbsd/logo.png b/platform/linuxbsd/logo.png Binary files differdeleted file mode 100644 index 078654b757..0000000000 --- a/platform/linuxbsd/logo.png +++ /dev/null diff --git a/platform/linuxbsd/logo.svg b/platform/linuxbsd/logo.svg new file mode 100644 index 0000000000..e5f9f03e0c --- /dev/null +++ b/platform/linuxbsd/logo.svg @@ -0,0 +1 @@ +<svg height="32" width="32"><path d="M13 31h6s3 0 6-6c2.864-5.727-6-17-6-17h-6S3.775 18.55 7 25c3 6 6 6 6 6z" fill="#fff"/><path d="M15.876 28.636c-.05.322-.116.637-.204.941-.142.496-.35.993-.659 1.416.32.02.649.023.985.007a9.1 9.1 0 0 0 .985-.007c-.309-.423-.516-.92-.659-1.416a7.666 7.666 0 0 1-.203-.94l-.123.003c-.04 0-.081-.003-.122-.004z" fill="#333"/><path d="M21.693 21.916c-.629.01-.934.633-1.497.7-.694.08-1.128-.722-2.11-.123-.98.6-1.826 7.473.45 8.409 2.274.935 6.506-4.545 6.23-5.662-.275-1.116-1.146-.853-1.582-1.399-.436-.545.003-1.41-.995-1.82a1.246 1.246 0 0 0-.496-.105zm-11.461 0a1.315 1.315 0 0 0-.421.105c-.998.41-.56 1.275-.995 1.82-.436.546-1.31.283-1.586 1.4-.275 1.116 3.956 6.596 6.232 5.66 2.275-.935 1.429-7.808.448-8.408-.981-.6-1.415.204-2.11.122-.584-.068-.888-.739-1.568-.7z" fill="#f4bb37"/><path d="M15.998.99c-2.934 0-4.657 1.79-4.982 4.204-.324 2.414.198 2.856-.614 5.328-.813 2.472-4.456 6.71-4.37 10.62.026 1.217.166 2.27.41 3.192.3-.496.743-.846 1.066-.995.253-.117.375-.173.432-.194.008-.062.04-.205.098-.485.08-.386.387-.99.91-1.386-.005-.12-.01-.239-.013-.363-.06-3.033 3.073-6.318 3.65-8.236.577-1.917.326-2.114.421-2.59.096-.477.463-1.032.992-1.475a.23.23 0 0 1 .15-.06c.482-.005.965 1.75 1.898 1.752.933 0 1.419-2.141 1.956-1.692.529.443.896.998.992 1.474.095.477-.156.674.42 2.591.578 1.918 3.708 5.203 3.648 8.236-.003.123-.008.24-.014.36.526.396.834 1.002.914 1.389.058.28.09.423.098.485.057.021.18.08.432.197.323.15.764.499 1.063.995.244-.922.387-1.976.414-3.195.085-3.91-3.562-8.148-4.374-10.62-.813-2.472-.287-2.914-.611-5.328C20.659 2.78 18.933.99 15.998.99z" fill="#333"/></svg> diff --git a/platform/linuxbsd/os_linuxbsd.cpp b/platform/linuxbsd/os_linuxbsd.cpp index 22c5f063c3..35807875a5 100644 --- a/platform/linuxbsd/os_linuxbsd.cpp +++ b/platform/linuxbsd/os_linuxbsd.cpp @@ -1,50 +1,47 @@ -/*************************************************************************/ -/* os_linuxbsd.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* os_linuxbsd.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "os_linuxbsd.h" +#include "core/io/certs_compressed.gen.h" #include "core/io/dir_access.h" #include "main/main.h" #include "servers/display_server.h" -#include "modules/modules_enabled.gen.h" // For regex. -#ifdef MODULE_REGEX_ENABLED -#include "modules/regex/regex.h" -#endif - #ifdef X11_ENABLED #include "x11/display_server_x11.h" #endif -#ifdef HAVE_MNTENT -#include <mntent.h> +#include "modules/modules_enabled.gen.h" // For regex. +#ifdef MODULE_REGEX_ENABLED +#include "modules/regex/regex.h" #endif #include <dlfcn.h> @@ -56,8 +53,8 @@ #include <sys/utsname.h> #include <unistd.h> -#ifdef FONTCONFIG_ENABLED -#include "fontconfig-so_wrap.h" +#ifdef HAVE_MNTENT +#include <mntent.h> #endif void OS_LinuxBSD::alert(const String &p_alert, const String &p_title) { @@ -85,7 +82,7 @@ void OS_LinuxBSD::alert(const String &p_alert, const String &p_title) { List<String> args; if (program.ends_with("zenity")) { - args.push_back("--error"); + args.push_back("--warning"); args.push_back("--width"); args.push_back("500"); args.push_back("--title"); @@ -95,7 +92,9 @@ void OS_LinuxBSD::alert(const String &p_alert, const String &p_title) { } if (program.ends_with("kdialog")) { - args.push_back("--error"); + // `--sorry` uses the same icon as `--warning` in Zenity. + // As of KDialog 22.12.1, its `--warning` options are only available for yes/no questions. + args.push_back("--sorry"); args.push_back(p_alert); args.push_back("--title"); args.push_back(p_title); @@ -128,6 +127,8 @@ void OS_LinuxBSD::initialize() { crash_handler.initialize(); OS_Unix::initialize_core(); + + system_dir_desktop_cache = get_system_dir(SYSTEM_DIR_DESKTOP); } void OS_LinuxBSD::initialize_joypads() { @@ -195,6 +196,10 @@ void OS_LinuxBSD::set_main_loop(MainLoop *p_main_loop) { main_loop = p_main_loop; } +String OS_LinuxBSD::get_identifier() const { + return "linuxbsd"; +} + String OS_LinuxBSD::get_name() const { #ifdef __linux__ return "Linux"; @@ -210,48 +215,54 @@ String OS_LinuxBSD::get_name() const { } String OS_LinuxBSD::get_systemd_os_release_info_value(const String &key) const { - static String info; - if (info.is_empty()) { - Ref<FileAccess> f = FileAccess::open("/etc/os-release", FileAccess::READ); - if (f.is_valid()) { - while (!f->eof_reached()) { - const String line = f->get_line(); - if (line.find(key) != -1) { - return line.split("=")[1].strip_edges(); - } + Ref<FileAccess> f = FileAccess::open("/etc/os-release", FileAccess::READ); + if (f.is_valid()) { + while (!f->eof_reached()) { + const String line = f->get_line(); + if (line.find(key) != -1) { + String value = line.split("=")[1].strip_edges(); + value = value.trim_prefix("\""); + return value.trim_suffix("\""); } } } - return info; + return ""; } String OS_LinuxBSD::get_distribution_name() const { - static String systemd_name = get_systemd_os_release_info_value("NAME"); // returns a value for systemd users, otherwise an empty string. - if (!systemd_name.is_empty()) { - return systemd_name; + static String distribution_name = get_systemd_os_release_info_value("NAME"); // returns a value for systemd users, otherwise an empty string. + if (!distribution_name.is_empty()) { + return distribution_name; } struct utsname uts; // returns a decent value for BSD family. uname(&uts); - return uts.sysname; + distribution_name = uts.sysname; + return distribution_name; } String OS_LinuxBSD::get_version() const { - static String systemd_version = get_systemd_os_release_info_value("VERSION"); // returns a value for systemd users, otherwise an empty string. - if (!systemd_version.is_empty()) { - return systemd_version; + static String release_version = get_systemd_os_release_info_value("VERSION"); // returns a value for systemd users, otherwise an empty string. + if (!release_version.is_empty()) { + return release_version; } struct utsname uts; // returns a decent value for BSD family. uname(&uts); - return uts.version; + release_version = uts.version; + return release_version; } Vector<String> OS_LinuxBSD::get_video_adapter_driver_info() const { - if (RenderingServer::get_singleton()->get_rendering_device() == nullptr) { + if (RenderingServer::get_singleton() == nullptr) { return Vector<String>(); } - const String rendering_device_name = RenderingServer::get_singleton()->get_rendering_device()->get_device_name(); // e.g. `NVIDIA GeForce GTX 970` - const String rendering_device_vendor = RenderingServer::get_singleton()->get_rendering_device()->get_device_vendor_name(); // e.g. `NVIDIA` + static Vector<String> info; + if (!info.is_empty()) { + return info; + } + + const String rendering_device_name = RenderingServer::get_singleton()->get_video_adapter_name(); // e.g. `NVIDIA GeForce GTX 970` + const String rendering_device_vendor = RenderingServer::get_singleton()->get_video_adapter_vendor(); // e.g. `NVIDIA` const String card_name = rendering_device_name.trim_prefix(rendering_device_vendor).strip_edges(); // -> `GeForce GTX 970` String vendor_device_id_mappings; @@ -315,8 +326,8 @@ Vector<String> OS_LinuxBSD::get_video_adapter_driver_info() const { Vector<String> class_display_device_drivers = OS_LinuxBSD::lspci_get_device_value(class_display_device_candidates, kernel_lit, dummys); Vector<String> class_3d_device_drivers = OS_LinuxBSD::lspci_get_device_value(class_3d_device_candidates, kernel_lit, dummys); - static String driver_name; - static String driver_version; + String driver_name; + String driver_version; // Use first valid value: for (const String &driver : class_3d_device_drivers) { @@ -336,7 +347,6 @@ Vector<String> OS_LinuxBSD::get_video_adapter_driver_info() const { } } - Vector<String> info; info.push_back(driver_name); String modinfo; @@ -486,10 +496,23 @@ bool OS_LinuxBSD::_check_internal_feature_support(const String &p_feature) { return font_config_initialized; } #endif + +#ifndef __linux__ + // `bsd` includes **all** BSD, not only "other BSD" (see `get_name()`). + if (p_feature == "bsd") { + return true; + } +#endif + if (p_feature == "pc") { return true; } + // Match against the specific OS (`linux`, `freebsd`, `netbsd`, `openbsd`). + if (p_feature == get_name().to_lower()) { + return true; + } + return false; } @@ -583,15 +606,9 @@ Vector<String> OS_LinuxBSD::get_system_fonts() const { if (!font_config_initialized) { ERR_FAIL_V_MSG(Vector<String>(), "Unable to load fontconfig, system font support is disabled."); } + HashSet<String> font_names; Vector<String> ret; - - FcConfig *config = FcInitLoadConfigAndFonts(); - ERR_FAIL_COND_V(!config, ret); - - FcObjectSet *object_set = FcObjectSetBuild(FC_FAMILY, nullptr); - ERR_FAIL_COND_V(!object_set, ret); - static const char *allowed_formats[] = { "TrueType", "CFF" }; for (size_t i = 0; i < sizeof(allowed_formats) / sizeof(const char *); i++) { FcPattern *pattern = FcPatternCreate(); @@ -614,8 +631,6 @@ Vector<String> OS_LinuxBSD::get_system_fonts() const { } FcPatternDestroy(pattern); } - FcObjectSetDestroy(object_set); - FcConfigDestroy(config); for (const String &E : font_names) { ret.push_back(E); @@ -626,48 +641,163 @@ Vector<String> OS_LinuxBSD::get_system_fonts() const { #endif } -String OS_LinuxBSD::get_system_font_path(const String &p_font_name, bool p_bold, bool p_italic) const { +#ifdef FONTCONFIG_ENABLED +int OS_LinuxBSD::_weight_to_fc(int p_weight) const { + if (p_weight < 150) { + return FC_WEIGHT_THIN; + } else if (p_weight < 250) { + return FC_WEIGHT_EXTRALIGHT; + } else if (p_weight < 325) { + return FC_WEIGHT_LIGHT; + } else if (p_weight < 375) { + return FC_WEIGHT_DEMILIGHT; + } else if (p_weight < 390) { + return FC_WEIGHT_BOOK; + } else if (p_weight < 450) { + return FC_WEIGHT_REGULAR; + } else if (p_weight < 550) { + return FC_WEIGHT_MEDIUM; + } else if (p_weight < 650) { + return FC_WEIGHT_DEMIBOLD; + } else if (p_weight < 750) { + return FC_WEIGHT_BOLD; + } else if (p_weight < 850) { + return FC_WEIGHT_EXTRABOLD; + } else if (p_weight < 925) { + return FC_WEIGHT_BLACK; + } else { + return FC_WEIGHT_EXTRABLACK; + } +} + +int OS_LinuxBSD::_stretch_to_fc(int p_stretch) const { + if (p_stretch < 56) { + return FC_WIDTH_ULTRACONDENSED; + } else if (p_stretch < 69) { + return FC_WIDTH_EXTRACONDENSED; + } else if (p_stretch < 81) { + return FC_WIDTH_CONDENSED; + } else if (p_stretch < 93) { + return FC_WIDTH_SEMICONDENSED; + } else if (p_stretch < 106) { + return FC_WIDTH_NORMAL; + } else if (p_stretch < 137) { + return FC_WIDTH_SEMIEXPANDED; + } else if (p_stretch < 144) { + return FC_WIDTH_EXPANDED; + } else if (p_stretch < 162) { + return FC_WIDTH_EXTRAEXPANDED; + } else { + return FC_WIDTH_ULTRAEXPANDED; + } +} +#endif // FONTCONFIG_ENABLED + +Vector<String> OS_LinuxBSD::get_system_font_path_for_text(const String &p_font_name, const String &p_text, const String &p_locale, const String &p_script, int p_weight, int p_stretch, bool p_italic) const { #ifdef FONTCONFIG_ENABLED if (!font_config_initialized) { - ERR_FAIL_V_MSG(String(), "Unable to load fontconfig, system font support is disabled."); + ERR_FAIL_V_MSG(Vector<String>(), "Unable to load fontconfig, system font support is disabled."); } - String ret; + Vector<String> ret; + static const char *allowed_formats[] = { "TrueType", "CFF" }; + for (size_t i = 0; i < sizeof(allowed_formats) / sizeof(const char *); i++) { + FcPattern *pattern = FcPatternCreate(); + if (pattern) { + FcPatternAddBool(pattern, FC_SCALABLE, FcTrue); + FcPatternAddString(pattern, FC_FONTFORMAT, reinterpret_cast<const FcChar8 *>(allowed_formats[i])); + FcPatternAddString(pattern, FC_FAMILY, reinterpret_cast<const FcChar8 *>(p_font_name.utf8().get_data())); + FcPatternAddInteger(pattern, FC_WEIGHT, _weight_to_fc(p_weight)); + FcPatternAddInteger(pattern, FC_WIDTH, _stretch_to_fc(p_stretch)); + FcPatternAddInteger(pattern, FC_SLANT, p_italic ? FC_SLANT_ITALIC : FC_SLANT_ROMAN); + + FcCharSet *char_set = FcCharSetCreate(); + for (int j = 0; j < p_text.size(); j++) { + FcCharSetAddChar(char_set, p_text[j]); + } + FcPatternAddCharSet(pattern, FC_CHARSET, char_set); + + FcLangSet *lang_set = FcLangSetCreate(); + FcLangSetAdd(lang_set, reinterpret_cast<const FcChar8 *>(p_locale.utf8().get_data())); + FcPatternAddLangSet(pattern, FC_LANG, lang_set); + + FcConfigSubstitute(0, pattern, FcMatchPattern); + FcDefaultSubstitute(pattern); + + FcResult result; + FcPattern *match = FcFontMatch(0, pattern, &result); + if (match) { + char *file_name = nullptr; + if (FcPatternGetString(match, FC_FILE, 0, reinterpret_cast<FcChar8 **>(&file_name)) == FcResultMatch) { + if (file_name) { + ret.push_back(String::utf8(file_name)); + } + } + FcPatternDestroy(match); + } + FcPatternDestroy(pattern); + FcCharSetDestroy(char_set); + FcLangSetDestroy(lang_set); + } + } - FcConfig *config = FcInitLoadConfigAndFonts(); - ERR_FAIL_COND_V(!config, ret); + return ret; +#else + ERR_FAIL_V_MSG(Vector<String>(), "Godot was compiled without fontconfig, system font support is disabled."); +#endif +} - FcObjectSet *object_set = FcObjectSetBuild(FC_FAMILY, FC_FILE, nullptr); - ERR_FAIL_COND_V(!object_set, ret); +String OS_LinuxBSD::get_system_font_path(const String &p_font_name, int p_weight, int p_stretch, bool p_italic) const { +#ifdef FONTCONFIG_ENABLED + if (!font_config_initialized) { + ERR_FAIL_V_MSG(String(), "Unable to load fontconfig, system font support is disabled."); + } - FcPattern *pattern = FcPatternCreate(); - if (pattern) { - FcPatternAddBool(pattern, FC_SCALABLE, FcTrue); - FcPatternAddString(pattern, FC_FAMILY, reinterpret_cast<const FcChar8 *>(p_font_name.utf8().get_data())); - FcPatternAddInteger(pattern, FC_WEIGHT, p_bold ? FC_WEIGHT_BOLD : FC_WEIGHT_NORMAL); - FcPatternAddInteger(pattern, FC_SLANT, p_italic ? FC_SLANT_ITALIC : FC_SLANT_ROMAN); - - FcConfigSubstitute(0, pattern, FcMatchPattern); - FcDefaultSubstitute(pattern); - - FcResult result; - FcPattern *match = FcFontMatch(0, pattern, &result); - if (match) { - char *file_name = nullptr; - if (FcPatternGetString(match, FC_FILE, 0, reinterpret_cast<FcChar8 **>(&file_name)) == FcResultMatch) { - if (file_name) { - ret = String::utf8(file_name); + static const char *allowed_formats[] = { "TrueType", "CFF" }; + for (size_t i = 0; i < sizeof(allowed_formats) / sizeof(const char *); i++) { + FcPattern *pattern = FcPatternCreate(); + if (pattern) { + bool allow_substitutes = (p_font_name.to_lower() == "sans-serif") || (p_font_name.to_lower() == "serif") || (p_font_name.to_lower() == "monospace") || (p_font_name.to_lower() == "cursive") || (p_font_name.to_lower() == "fantasy"); + + FcPatternAddBool(pattern, FC_SCALABLE, FcTrue); + FcPatternAddString(pattern, FC_FONTFORMAT, reinterpret_cast<const FcChar8 *>(allowed_formats[i])); + FcPatternAddString(pattern, FC_FAMILY, reinterpret_cast<const FcChar8 *>(p_font_name.utf8().get_data())); + FcPatternAddInteger(pattern, FC_WEIGHT, _weight_to_fc(p_weight)); + FcPatternAddInteger(pattern, FC_WIDTH, _stretch_to_fc(p_stretch)); + FcPatternAddInteger(pattern, FC_SLANT, p_italic ? FC_SLANT_ITALIC : FC_SLANT_ROMAN); + + FcConfigSubstitute(0, pattern, FcMatchPattern); + FcDefaultSubstitute(pattern); + + FcResult result; + FcPattern *match = FcFontMatch(0, pattern, &result); + if (match) { + if (!allow_substitutes) { + char *family_name = nullptr; + if (FcPatternGetString(match, FC_FAMILY, 0, reinterpret_cast<FcChar8 **>(&family_name)) == FcResultMatch) { + if (family_name && String::utf8(family_name).to_lower() != p_font_name.to_lower()) { + FcPatternDestroy(match); + FcPatternDestroy(pattern); + continue; + } + } } + char *file_name = nullptr; + if (FcPatternGetString(match, FC_FILE, 0, reinterpret_cast<FcChar8 **>(&file_name)) == FcResultMatch) { + if (file_name) { + String ret = String::utf8(file_name); + FcPatternDestroy(match); + FcPatternDestroy(pattern); + return ret; + } + } + FcPatternDestroy(match); } - - FcPatternDestroy(match); + FcPatternDestroy(pattern); } - FcPatternDestroy(pattern); } - FcObjectSetDestroy(object_set); - FcConfigDestroy(config); - return ret; + return String(); #else ERR_FAIL_V_MSG(String(), "Godot was compiled without fontconfig, system font support is disabled."); #endif @@ -719,6 +849,10 @@ String OS_LinuxBSD::get_cache_path() const { } String OS_LinuxBSD::get_system_dir(SystemDir p_dir, bool p_shared_storage) const { + if (p_dir == SYSTEM_DIR_DESKTOP && !system_dir_desktop_cache.is_empty()) { + return system_dir_desktop_cache; + } + String xdgparam; switch (p_dir) { @@ -727,31 +861,24 @@ String OS_LinuxBSD::get_system_dir(SystemDir p_dir, bool p_shared_storage) const } break; case SYSTEM_DIR_DCIM: { xdgparam = "PICTURES"; - } break; case SYSTEM_DIR_DOCUMENTS: { xdgparam = "DOCUMENTS"; - } break; case SYSTEM_DIR_DOWNLOADS: { xdgparam = "DOWNLOAD"; - } break; case SYSTEM_DIR_MOVIES: { xdgparam = "VIDEOS"; - } break; case SYSTEM_DIR_MUSIC: { xdgparam = "MUSIC"; - } break; case SYSTEM_DIR_PICTURES: { xdgparam = "PICTURES"; - } break; case SYSTEM_DIR_RINGTONES: { xdgparam = "MUSIC"; - } break; } @@ -972,6 +1099,40 @@ Error OS_LinuxBSD::move_to_trash(const String &p_path) { return OK; } +String OS_LinuxBSD::get_system_ca_certificates() { + String certfile; + Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + + // Compile time preferred certificates path. + if (!String(_SYSTEM_CERTS_PATH).is_empty() && da->file_exists(_SYSTEM_CERTS_PATH)) { + certfile = _SYSTEM_CERTS_PATH; + } else if (da->file_exists("/etc/ssl/certs/ca-certificates.crt")) { + // Debian/Ubuntu + certfile = "/etc/ssl/certs/ca-certificates.crt"; + } else if (da->file_exists("/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem")) { + // Fedora + certfile = "/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem"; + } else if (da->file_exists("/etc/ca-certificates/extracted/tls-ca-bundle.pem")) { + // Arch Linux + certfile = "/etc/ca-certificates/extracted/tls-ca-bundle.pem"; + } else if (da->file_exists("/var/lib/ca-certificates/ca-bundle.pem")) { + // openSUSE + certfile = "/var/lib/ca-certificates/ca-bundle.pem"; + } else if (da->file_exists("/etc/ssl/cert.pem")) { + // FreeBSD/OpenBSD + certfile = "/etc/ssl/cert.pem"; + } + + if (certfile.is_empty()) { + return ""; + } + + Ref<FileAccess> f = FileAccess::open(certfile, FileAccess::READ); + ERR_FAIL_COND_V_MSG(f.is_null(), "", vformat("Failed to open system CA certificates file: '%s'", certfile)); + + return f->get_as_text(); +} + OS_LinuxBSD::OS_LinuxBSD() { main_loop = nullptr; @@ -988,11 +1149,46 @@ OS_LinuxBSD::OS_LinuxBSD() { #endif #ifdef FONTCONFIG_ENABLED +#ifdef SOWRAP_ENABLED #ifdef DEBUG_ENABLED int dylibloader_verbose = 1; #else int dylibloader_verbose = 0; #endif font_config_initialized = (initialize_fontconfig(dylibloader_verbose) == 0); +#else + font_config_initialized = true; +#endif + if (font_config_initialized) { + bool ver_ok = false; + int version = FcGetVersion(); + ver_ok = ((version / 100 / 100) == 2 && (version / 100 % 100) >= 11) || ((version / 100 / 100) > 2); // 2.11.0 + print_verbose(vformat("FontConfig %d.%d.%d detected.", version / 100 / 100, version / 100 % 100, version % 100)); + if (!ver_ok) { + font_config_initialized = false; + } + } + + if (font_config_initialized) { + config = FcInitLoadConfigAndFonts(); + if (!config) { + font_config_initialized = false; + } + object_set = FcObjectSetBuild(FC_FAMILY, FC_FILE, nullptr); + if (!object_set) { + font_config_initialized = false; + } + } +#endif // FONTCONFIG_ENABLED +} + +OS_LinuxBSD::~OS_LinuxBSD() { +#ifdef FONTCONFIG_ENABLED + if (object_set) { + FcObjectSetDestroy(object_set); + } + if (config) { + FcConfigDestroy(config); + } #endif // FONTCONFIG_ENABLED } diff --git a/platform/linuxbsd/os_linuxbsd.h b/platform/linuxbsd/os_linuxbsd.h index aea04c1363..007b90b82b 100644 --- a/platform/linuxbsd/os_linuxbsd.h +++ b/platform/linuxbsd/os_linuxbsd.h @@ -1,50 +1,64 @@ -/*************************************************************************/ -/* os_linuxbsd.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* os_linuxbsd.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 OS_LINUXBSD_H #define OS_LINUXBSD_H -#include "core/input/input.h" #include "crash_handler_linuxbsd.h" +#include "joypad_linux.h" + +#include "core/input/input.h" #include "drivers/alsa/audio_driver_alsa.h" #include "drivers/alsamidi/midi_driver_alsamidi.h" #include "drivers/pulseaudio/audio_driver_pulseaudio.h" #include "drivers/unix/os_unix.h" -#include "joypad_linux.h" #include "servers/audio_server.h" +#ifdef FONTCONFIG_ENABLED +#ifdef SOWRAP_ENABLED +#include "fontconfig-so_wrap.h" +#else +#include <fontconfig/fontconfig.h> +#endif +#endif + class OS_LinuxBSD : public OS_Unix { virtual void delete_main_loop() override; #ifdef FONTCONFIG_ENABLED bool font_config_initialized = false; + FcConfig *config = nullptr; + FcObjectSet *object_set = nullptr; + + int _weight_to_fc(int p_weight) const; + int _stretch_to_fc(int p_stretch) const; #endif #ifdef JOYDEV_ENABLED @@ -72,6 +86,8 @@ class OS_LinuxBSD : public OS_Unix { Vector<String> lspci_device_filter(Vector<String> vendor_device_id_mapping, String class_suffix, String check_column, String whitelist) const; Vector<String> lspci_get_device_value(Vector<String> vendor_device_id_mapping, String check_column, String blacklist) const; + String system_dir_desktop_cache; + protected: virtual void initialize() override; virtual void finalize() override; @@ -81,6 +97,7 @@ protected: virtual void set_main_loop(MainLoop *p_main_loop) override; public: + virtual String get_identifier() const override; virtual String get_name() const override; virtual String get_distribution_name() const override; virtual String get_version() const override; @@ -92,7 +109,8 @@ public: virtual uint64_t get_embedded_pck_offset() const override; virtual Vector<String> get_system_fonts() const override; - virtual String get_system_font_path(const String &p_font_name, bool p_bold = false, bool p_italic = false) const override; + virtual String get_system_font_path(const String &p_font_name, int p_weight = 400, int p_stretch = 100, bool p_italic = false) const override; + virtual Vector<String> get_system_font_path_for_text(const String &p_font_name, const String &p_text, const String &p_locale = String(), const String &p_script = String(), int p_weight = 400, int p_stretch = 100, bool p_italic = false) const override; virtual String get_config_path() const override; virtual String get_data_path() const override; @@ -116,7 +134,10 @@ public: virtual Error move_to_trash(const String &p_path) override; + virtual String get_system_ca_certificates() override; + OS_LinuxBSD(); + ~OS_LinuxBSD(); }; #endif // OS_LINUXBSD_H diff --git a/platform/linuxbsd/platform_config.h b/platform/linuxbsd/platform_config.h index 3c05c67444..82c9c54879 100644 --- a/platform/linuxbsd/platform_config.h +++ b/platform/linuxbsd/platform_config.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* platform_config.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* platform_config.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ #ifdef __linux__ #include <alloca.h> @@ -44,4 +44,4 @@ #endif #endif -#define OPENGL_INCLUDE_H "thirdparty/glad/glad/glad.h" +#define OPENGL_INCLUDE_H "thirdparty/glad/glad/gl.h" diff --git a/platform/linuxbsd/run_icon.svg b/platform/linuxbsd/run_icon.svg new file mode 100644 index 0000000000..56465a0df3 --- /dev/null +++ b/platform/linuxbsd/run_icon.svg @@ -0,0 +1 @@ +<svg height="16" width="16" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><path d="M7.941 13.966a3.62 3.62 0 0 1-.096.444 2.129 2.129 0 0 1-.31.668c.15.01.305.01.464.003.16.008.314.007.465-.003a2.129 2.129 0 0 1-.31-.668 3.62 3.62 0 0 1-.097-.444l-.058.001-.058-.001z" fill="#333" style="stroke-width:.472092;fill:#e0e0e0;fill-opacity:1"/><path d="M10.688 10.793c-.297.005-.441.299-.707.33-.328.038-.533-.34-.996-.058-.463.283-.862 3.528.212 3.97 1.074.442 3.072-2.146 2.942-2.673-.13-.527-.542-.403-.747-.66-.206-.258 0-.666-.47-.86a.588.588 0 0 0-.234-.05zm-5.411 0a.62.62 0 0 0-.199.05c-.47.193-.264.601-.47.859-.205.257-.618.133-.748.66s1.867 3.115 2.942 2.673c1.074-.442.674-3.687.211-3.97-.463-.283-.668.096-.995.058-.277-.032-.42-.349-.741-.33z" fill="#f4bb37" style="stroke-width:.472092;fill:#e0e0e0;fill-opacity:1"/><path d="M8 .914c-1.386 0-2.2.845-2.353 1.985-.153 1.14.094 1.348-.29 2.515s-2.103 3.168-2.063 5.013c.012.575.078 1.072.194 1.507a1.25 1.25 0 0 1 .503-.47 4.37 4.37 0 0 1 .204-.09c.004-.03.019-.098.046-.23.038-.182.183-.467.43-.654a4.773 4.773 0 0 1-.006-.172c-.029-1.431 1.45-2.982 1.723-3.888.272-.905.154-.998.199-1.223.045-.225.218-.487.468-.696a.11.11 0 0 1 .07-.028c.228-.003.456.826.897.827.44 0 .67-1.01.923-.799.25.21.423.471.468.696.045.225-.073.318.199 1.223.272.906 1.75 2.457 1.722 3.888-.001.058-.004.114-.007.17a1.2 1.2 0 0 1 .432.656c.027.132.042.2.046.23.027.01.085.037.204.092.153.07.36.236.502.47.115-.435.183-.933.195-1.509.04-1.845-1.681-3.846-2.065-5.013-.383-1.167-.135-1.376-.288-2.515C10.2 1.759 9.385.914 7.999.914Z" fill="#333" style="stroke-width:.472092;fill:#e0e0e0;fill-opacity:1"/></svg> diff --git a/platform/linuxbsd/speechd-so_wrap.c b/platform/linuxbsd/speechd-so_wrap.c index 749474e181..1dc5f08c10 100644 --- a/platform/linuxbsd/speechd-so_wrap.c +++ b/platform/linuxbsd/speechd-so_wrap.c @@ -1,7 +1,7 @@ // This file is generated. Do not edit! // see https://github.com/hpvb/dynload-wrapper for details -// generated by ./dynload-wrapper/generate-wrapper.py 0.3 on 2022-04-28 14:34:21 -// flags: ./dynload-wrapper/generate-wrapper.py --sys-include <libspeechd.h> --include /usr/include/speech-dispatcher/libspeechd.h --soname libspeechd.so.2 --init-name speechd --omit-prefix spd_get_client_list --output-header speechd-so_wrap.h --output-implementation speechd-so_wrap.c +// generated by generate-wrapper.py 0.3 on 2023-01-12 10:07:46 +// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/speechd/libspeechd.h --sys-include "thirdparty/linuxbsd_headers/speechd/libspeechd.h" --soname libspeechd.so.2 --init-name speechd --omit-prefix spd_get_client_list --output-header ./platform/linuxbsd/speechd-so_wrap.h --output-implementation ./platform/linuxbsd/speechd-so_wrap.c // #include <stdint.h> @@ -47,9 +47,6 @@ #define spd_set_voice_pitch_all spd_set_voice_pitch_all_dylibloader_orig_speechd #define spd_set_voice_pitch_uid spd_set_voice_pitch_uid_dylibloader_orig_speechd #define spd_get_voice_pitch spd_get_voice_pitch_dylibloader_orig_speechd -#define spd_set_voice_pitch_range spd_set_voice_pitch_range_dylibloader_orig_speechd -#define spd_set_voice_pitch_range_all spd_set_voice_pitch_range_all_dylibloader_orig_speechd -#define spd_set_voice_pitch_range_uid spd_set_voice_pitch_range_uid_dylibloader_orig_speechd #define spd_set_volume spd_set_volume_dylibloader_orig_speechd #define spd_set_volume_all spd_set_volume_all_dylibloader_orig_speechd #define spd_set_volume_uid spd_set_volume_uid_dylibloader_orig_speechd @@ -83,7 +80,7 @@ #define spd_execute_command_wo_mutex spd_execute_command_wo_mutex_dylibloader_orig_speechd #define spd_send_data spd_send_data_dylibloader_orig_speechd #define spd_send_data_wo_mutex spd_send_data_wo_mutex_dylibloader_orig_speechd -#include <libspeechd.h> +#include "thirdparty/linuxbsd_headers/speechd/libspeechd.h" #undef SPDConnectionAddress__free #undef spd_get_default_address #undef spd_open @@ -126,9 +123,6 @@ #undef spd_set_voice_pitch_all #undef spd_set_voice_pitch_uid #undef spd_get_voice_pitch -#undef spd_set_voice_pitch_range -#undef spd_set_voice_pitch_range_all -#undef spd_set_voice_pitch_range_uid #undef spd_set_volume #undef spd_set_volume_all #undef spd_set_volume_uid @@ -206,9 +200,6 @@ int (*spd_set_voice_pitch_dylibloader_wrapper_speechd)( SPDConnection*, signed i int (*spd_set_voice_pitch_all_dylibloader_wrapper_speechd)( SPDConnection*, signed int); int (*spd_set_voice_pitch_uid_dylibloader_wrapper_speechd)( SPDConnection*, signed int, unsigned int); int (*spd_get_voice_pitch_dylibloader_wrapper_speechd)( SPDConnection*); -int (*spd_set_voice_pitch_range_dylibloader_wrapper_speechd)( SPDConnection*, signed int); -int (*spd_set_voice_pitch_range_all_dylibloader_wrapper_speechd)( SPDConnection*, signed int); -int (*spd_set_voice_pitch_range_uid_dylibloader_wrapper_speechd)( SPDConnection*, signed int, unsigned int); int (*spd_set_volume_dylibloader_wrapper_speechd)( SPDConnection*, signed int); int (*spd_set_volume_all_dylibloader_wrapper_speechd)( SPDConnection*, signed int); int (*spd_set_volume_uid_dylibloader_wrapper_speechd)( SPDConnection*, signed int, unsigned int); @@ -589,30 +580,6 @@ int initialize_speechd(int verbose) { fprintf(stderr, "%s\n", error); } } -// spd_set_voice_pitch_range - *(void **) (&spd_set_voice_pitch_range_dylibloader_wrapper_speechd) = dlsym(handle, "spd_set_voice_pitch_range"); - if (verbose) { - error = dlerror(); - if (error != NULL) { - fprintf(stderr, "%s\n", error); - } - } -// spd_set_voice_pitch_range_all - *(void **) (&spd_set_voice_pitch_range_all_dylibloader_wrapper_speechd) = dlsym(handle, "spd_set_voice_pitch_range_all"); - if (verbose) { - error = dlerror(); - if (error != NULL) { - fprintf(stderr, "%s\n", error); - } - } -// spd_set_voice_pitch_range_uid - *(void **) (&spd_set_voice_pitch_range_uid_dylibloader_wrapper_speechd) = dlsym(handle, "spd_set_voice_pitch_range_uid"); - if (verbose) { - error = dlerror(); - if (error != NULL) { - fprintf(stderr, "%s\n", error); - } - } // spd_set_volume *(void **) (&spd_set_volume_dylibloader_wrapper_speechd) = dlsym(handle, "spd_set_volume"); if (verbose) { diff --git a/platform/linuxbsd/speechd-so_wrap.h b/platform/linuxbsd/speechd-so_wrap.h index 8e1c053348..2967cfa929 100644 --- a/platform/linuxbsd/speechd-so_wrap.h +++ b/platform/linuxbsd/speechd-so_wrap.h @@ -2,8 +2,8 @@ #define DYLIBLOAD_WRAPPER_SPEECHD // This file is generated. Do not edit! // see https://github.com/hpvb/dynload-wrapper for details -// generated by ./dynload-wrapper/generate-wrapper.py 0.3 on 2022-04-28 14:34:21 -// flags: ./dynload-wrapper/generate-wrapper.py --sys-include <libspeechd.h> --include /usr/include/speech-dispatcher/libspeechd.h --soname libspeechd.so.2 --init-name speechd --omit-prefix spd_get_client_list --output-header speechd-so_wrap.h --output-implementation speechd-so_wrap.c +// generated by generate-wrapper.py 0.3 on 2023-01-12 10:07:46 +// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/speechd/libspeechd.h --sys-include "thirdparty/linuxbsd_headers/speechd/libspeechd.h" --soname libspeechd.so.2 --init-name speechd --omit-prefix spd_get_client_list --output-header ./platform/linuxbsd/speechd-so_wrap.h --output-implementation ./platform/linuxbsd/speechd-so_wrap.c // #include <stdint.h> @@ -49,9 +49,6 @@ #define spd_set_voice_pitch_all spd_set_voice_pitch_all_dylibloader_orig_speechd #define spd_set_voice_pitch_uid spd_set_voice_pitch_uid_dylibloader_orig_speechd #define spd_get_voice_pitch spd_get_voice_pitch_dylibloader_orig_speechd -#define spd_set_voice_pitch_range spd_set_voice_pitch_range_dylibloader_orig_speechd -#define spd_set_voice_pitch_range_all spd_set_voice_pitch_range_all_dylibloader_orig_speechd -#define spd_set_voice_pitch_range_uid spd_set_voice_pitch_range_uid_dylibloader_orig_speechd #define spd_set_volume spd_set_volume_dylibloader_orig_speechd #define spd_set_volume_all spd_set_volume_all_dylibloader_orig_speechd #define spd_set_volume_uid spd_set_volume_uid_dylibloader_orig_speechd @@ -85,7 +82,7 @@ #define spd_execute_command_wo_mutex spd_execute_command_wo_mutex_dylibloader_orig_speechd #define spd_send_data spd_send_data_dylibloader_orig_speechd #define spd_send_data_wo_mutex spd_send_data_wo_mutex_dylibloader_orig_speechd -#include <libspeechd.h> +#include "thirdparty/linuxbsd_headers/speechd/libspeechd.h" #undef SPDConnectionAddress__free #undef spd_get_default_address #undef spd_open @@ -128,9 +125,6 @@ #undef spd_set_voice_pitch_all #undef spd_set_voice_pitch_uid #undef spd_get_voice_pitch -#undef spd_set_voice_pitch_range -#undef spd_set_voice_pitch_range_all -#undef spd_set_voice_pitch_range_uid #undef spd_set_volume #undef spd_set_volume_all #undef spd_set_volume_uid @@ -209,9 +203,6 @@ extern "C" { #define spd_set_voice_pitch_all spd_set_voice_pitch_all_dylibloader_wrapper_speechd #define spd_set_voice_pitch_uid spd_set_voice_pitch_uid_dylibloader_wrapper_speechd #define spd_get_voice_pitch spd_get_voice_pitch_dylibloader_wrapper_speechd -#define spd_set_voice_pitch_range spd_set_voice_pitch_range_dylibloader_wrapper_speechd -#define spd_set_voice_pitch_range_all spd_set_voice_pitch_range_all_dylibloader_wrapper_speechd -#define spd_set_voice_pitch_range_uid spd_set_voice_pitch_range_uid_dylibloader_wrapper_speechd #define spd_set_volume spd_set_volume_dylibloader_wrapper_speechd #define spd_set_volume_all spd_set_volume_all_dylibloader_wrapper_speechd #define spd_set_volume_uid spd_set_volume_uid_dylibloader_wrapper_speechd @@ -287,9 +278,6 @@ extern int (*spd_set_voice_pitch_dylibloader_wrapper_speechd)( SPDConnection*, s extern int (*spd_set_voice_pitch_all_dylibloader_wrapper_speechd)( SPDConnection*, signed int); extern int (*spd_set_voice_pitch_uid_dylibloader_wrapper_speechd)( SPDConnection*, signed int, unsigned int); extern int (*spd_get_voice_pitch_dylibloader_wrapper_speechd)( SPDConnection*); -extern int (*spd_set_voice_pitch_range_dylibloader_wrapper_speechd)( SPDConnection*, signed int); -extern int (*spd_set_voice_pitch_range_all_dylibloader_wrapper_speechd)( SPDConnection*, signed int); -extern int (*spd_set_voice_pitch_range_uid_dylibloader_wrapper_speechd)( SPDConnection*, signed int, unsigned int); extern int (*spd_set_volume_dylibloader_wrapper_speechd)( SPDConnection*, signed int); extern int (*spd_set_volume_all_dylibloader_wrapper_speechd)( SPDConnection*, signed int); extern int (*spd_set_volume_uid_dylibloader_wrapper_speechd)( SPDConnection*, signed int, unsigned int); diff --git a/platform/linuxbsd/tts_linux.cpp b/platform/linuxbsd/tts_linux.cpp index aea1183d3d..8bc83f5b9c 100644 --- a/platform/linuxbsd/tts_linux.cpp +++ b/platform/linuxbsd/tts_linux.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* tts_linux.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* tts_linux.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "tts_linux.h" @@ -39,12 +39,23 @@ void TTS_Linux::speech_init_thread_func(void *p_userdata) { TTS_Linux *tts = (TTS_Linux *)p_userdata; if (tts) { MutexLock thread_safe_method(tts->_thread_safe_); +#ifdef SOWRAP_ENABLED #ifdef DEBUG_ENABLED int dylibloader_verbose = 1; #else int dylibloader_verbose = 0; #endif - if (initialize_speechd(dylibloader_verbose) == 0) { + if (initialize_speechd(dylibloader_verbose) != 0) { + print_verbose("Text-to-Speech: Cannot load Speech Dispatcher library!"); + } else { + if (!spd_open || !spd_set_notification_on || !spd_list_synthesis_voices || !free_spd_voices || !spd_set_synthesis_voice || !spd_set_volume || !spd_set_voice_pitch || !spd_set_voice_rate || !spd_set_data_mode || !spd_say || !spd_pause || !spd_resume || !spd_cancel) { + // There's no API to check version, check if functions are available instead. + print_verbose("Text-to-Speech: Unsupported Speech Dispatcher library version!"); + return; + } +#else + { +#endif CharString class_str; String config_name = GLOBAL_GET("application/config/name"); if (config_name.length() == 0) { @@ -64,85 +75,103 @@ void TTS_Linux::speech_init_thread_func(void *p_userdata) { } else { print_verbose("Text-to-Speech: Cannot initialize Speech Dispatcher synthesizer!"); } - } else { - print_verbose("Text-to-Speech: Cannot load Speech Dispatcher library!"); } } } void TTS_Linux::speech_event_index_mark(size_t p_msg_id, size_t p_client_id, SPDNotificationType p_type, char *p_index_mark) { TTS_Linux *tts = TTS_Linux::get_singleton(); - if (tts && tts->ids.has(p_msg_id)) { - MutexLock thread_safe_method(tts->_thread_safe_); - // Get word offset from the index mark injected to the text stream. - String mark = String::utf8(p_index_mark); - DisplayServer::get_singleton()->tts_post_utterance_event(DisplayServer::TTS_UTTERANCE_BOUNDARY, tts->ids[p_msg_id], mark.to_int()); + if (tts) { + callable_mp(tts, &TTS_Linux::_speech_index_mark).call_deferred(p_msg_id, p_client_id, (int)p_type, String::utf8(p_index_mark)); + } +} + +void TTS_Linux::_speech_index_mark(size_t p_msg_id, size_t p_client_id, int p_type, const String &p_index_mark) { + _THREAD_SAFE_METHOD_ + + if (ids.has(p_msg_id)) { + DisplayServer::get_singleton()->tts_post_utterance_event(DisplayServer::TTS_UTTERANCE_BOUNDARY, ids[p_msg_id], p_index_mark.to_int()); } } void TTS_Linux::speech_event_callback(size_t p_msg_id, size_t p_client_id, SPDNotificationType p_type) { TTS_Linux *tts = TTS_Linux::get_singleton(); if (tts) { - MutexLock thread_safe_method(tts->_thread_safe_); - List<DisplayServer::TTSUtterance> &queue = tts->queue; - if (!tts->paused && tts->ids.has(p_msg_id)) { - if (p_type == SPD_EVENT_END) { - DisplayServer::get_singleton()->tts_post_utterance_event(DisplayServer::TTS_UTTERANCE_ENDED, tts->ids[p_msg_id]); - tts->ids.erase(p_msg_id); - tts->last_msg_id = -1; - tts->speaking = false; - } else if (p_type == SPD_EVENT_CANCEL) { - DisplayServer::get_singleton()->tts_post_utterance_event(DisplayServer::TTS_UTTERANCE_CANCELED, tts->ids[p_msg_id]); - tts->ids.erase(p_msg_id); - tts->last_msg_id = -1; - tts->speaking = false; + callable_mp(tts, &TTS_Linux::_speech_event).call_deferred(p_msg_id, p_client_id, (int)p_type); + } +} + +void TTS_Linux::_load_voices() { + if (!voices_loaded) { + SPDVoice **spd_voices = spd_list_synthesis_voices(synth); + if (spd_voices != nullptr) { + SPDVoice **voices_ptr = spd_voices; + while (*voices_ptr != nullptr) { + VoiceInfo vi; + vi.language = String::utf8((*voices_ptr)->language); + vi.variant = String::utf8((*voices_ptr)->variant); + voices[String::utf8((*voices_ptr)->name)] = vi; + voices_ptr++; } + free_spd_voices(spd_voices); } - if (!tts->speaking && queue.size() > 0) { - DisplayServer::TTSUtterance &message = queue.front()->get(); - - // Inject index mark after each word. - String text; - String language; - SPDVoice **voices = spd_list_synthesis_voices(tts->synth); - if (voices != nullptr) { - SPDVoice **voices_ptr = voices; - while (*voices_ptr != nullptr) { - if (String::utf8((*voices_ptr)->name) == message.voice) { - language = String::utf8((*voices_ptr)->language); - break; - } - voices_ptr++; - } - free_spd_voices(voices); - } - PackedInt32Array breaks = TS->string_get_word_breaks(message.text, language); - int prev = 0; - for (int i = 0; i < breaks.size(); i++) { - text += message.text.substr(prev, breaks[i] - prev); - text += "<mark name=\"" + String::num_int64(breaks[i], 10) + "\"/>"; - prev = breaks[i]; - } - text += message.text.substr(prev, -1); - - spd_set_synthesis_voice(tts->synth, message.voice.utf8().get_data()); - spd_set_volume(tts->synth, message.volume * 2 - 100); - spd_set_voice_pitch(tts->synth, (message.pitch - 1) * 100); - float rate = 0; - if (message.rate > 1.f) { - rate = log10(MIN(message.rate, 2.5f)) / log10(2.5f) * 100; - } else if (message.rate < 1.f) { - rate = log10(MAX(message.rate, 0.5f)) / log10(0.5f) * -100; - } - spd_set_voice_rate(tts->synth, rate); - spd_set_data_mode(tts->synth, SPD_DATA_SSML); - tts->last_msg_id = spd_say(tts->synth, SPD_TEXT, text.utf8().get_data()); - tts->ids[tts->last_msg_id] = message.id; - DisplayServer::get_singleton()->tts_post_utterance_event(DisplayServer::TTS_UTTERANCE_STARTED, message.id); - - queue.pop_front(); - tts->speaking = true; + voices_loaded = true; + } +} + +void TTS_Linux::_speech_event(size_t p_msg_id, size_t p_client_id, int p_type) { + _THREAD_SAFE_METHOD_ + + if (!paused && ids.has(p_msg_id)) { + if ((SPDNotificationType)p_type == SPD_EVENT_END) { + DisplayServer::get_singleton()->tts_post_utterance_event(DisplayServer::TTS_UTTERANCE_ENDED, ids[p_msg_id]); + ids.erase(p_msg_id); + last_msg_id = -1; + speaking = false; + } else if ((SPDNotificationType)p_type == SPD_EVENT_CANCEL) { + DisplayServer::get_singleton()->tts_post_utterance_event(DisplayServer::TTS_UTTERANCE_CANCELED, ids[p_msg_id]); + ids.erase(p_msg_id); + last_msg_id = -1; + speaking = false; + } + } + if (!speaking && queue.size() > 0) { + DisplayServer::TTSUtterance &message = queue.front()->get(); + + // Inject index mark after each word. + String text; + String language; + + _load_voices(); + const VoiceInfo *voice = voices.getptr(message.voice); + if (voice) { + language = voice->language; + } + + PackedInt32Array breaks = TS->string_get_word_breaks(message.text, language); + for (int i = 0; i < breaks.size(); i += 2) { + const int start = breaks[i]; + const int end = breaks[i + 1]; + text += message.text.substr(start, end - start + 1); + text += "<mark name=\"" + String::num_int64(end, 10) + "\"/>"; + } + spd_set_synthesis_voice(synth, message.voice.utf8().get_data()); + spd_set_volume(synth, message.volume * 2 - 100); + spd_set_voice_pitch(synth, (message.pitch - 1) * 100); + float rate = 0; + if (message.rate > 1.f) { + rate = log10(MIN(message.rate, 2.5f)) / log10(2.5f) * 100; + } else if (message.rate < 1.f) { + rate = log10(MAX(message.rate, 0.5f)) / log10(0.5f) * -100; } + spd_set_voice_rate(synth, rate); + spd_set_data_mode(synth, SPD_DATA_SSML); + last_msg_id = spd_say(synth, SPD_TEXT, text.utf8().get_data()); + ids[last_msg_id] = message.id; + DisplayServer::get_singleton()->tts_post_utterance_event(DisplayServer::TTS_UTTERANCE_STARTED, message.id); + + queue.pop_front(); + speaking = true; } } @@ -158,21 +187,17 @@ Array TTS_Linux::get_voices() const { _THREAD_SAFE_METHOD_ ERR_FAIL_COND_V(!synth, Array()); + const_cast<TTS_Linux *>(this)->_load_voices(); + Array list; - SPDVoice **voices = spd_list_synthesis_voices(synth); - if (voices != nullptr) { - SPDVoice **voices_ptr = voices; - while (*voices_ptr != nullptr) { - Dictionary voice_d; - voice_d["name"] = String::utf8((*voices_ptr)->name); - voice_d["id"] = String::utf8((*voices_ptr)->name); - voice_d["language"] = String::utf8((*voices_ptr)->language) + "_" + String::utf8((*voices_ptr)->variant); - list.push_back(voice_d); - - voices_ptr++; - } - free_spd_voices(voices); + for (const KeyValue<String, VoiceInfo> &E : voices) { + Dictionary voice_d; + voice_d["name"] = E.key; + voice_d["id"] = E.key; + voice_d["language"] = E.value.language + "_" + E.value.variant; + list.push_back(voice_d); } + return list; } @@ -201,7 +226,7 @@ void TTS_Linux::speak(const String &p_text, const String &p_voice, int p_volume, if (is_paused()) { resume(); } else { - speech_event_callback(0, 0, SPD_EVENT_BEGIN); + _speech_event(0, 0, (int)SPD_EVENT_BEGIN); } } diff --git a/platform/linuxbsd/tts_linux.h b/platform/linuxbsd/tts_linux.h index 4e3f348ae4..ec68219689 100644 --- a/platform/linuxbsd/tts_linux.h +++ b/platform/linuxbsd/tts_linux.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* tts_linux.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* tts_linux.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 TTS_LINUX_H #define TTS_LINUX_H @@ -34,14 +34,18 @@ #include "core/os/thread.h" #include "core/os/thread_safe.h" #include "core/string/ustring.h" +#include "core/templates/hash_map.h" #include "core/templates/list.h" -#include "core/templates/rb_map.h" #include "core/variant/array.h" #include "servers/display_server.h" +#ifdef SOWRAP_ENABLED #include "speechd-so_wrap.h" +#else +#include <libspeechd.h> +#endif -class TTS_Linux { +class TTS_Linux : public Object { _THREAD_SAFE_CLASS_ List<DisplayServer::TTSUtterance> queue; @@ -51,6 +55,13 @@ class TTS_Linux { int last_msg_id = -1; HashMap<int, int> ids; + struct VoiceInfo { + String language; + String variant; + }; + bool voices_loaded = false; + HashMap<String, VoiceInfo> voices; + Thread init_thread; static void speech_init_thread_func(void *p_userdata); @@ -59,6 +70,11 @@ class TTS_Linux { static TTS_Linux *singleton; +protected: + void _load_voices(); + void _speech_event(size_t p_msg_id, size_t p_client_id, int p_type); + void _speech_index_mark(size_t p_msg_id, size_t p_client_id, int p_type, const String &p_index_mark); + public: static TTS_Linux *get_singleton(); diff --git a/platform/linuxbsd/x11/SCsub b/platform/linuxbsd/x11/SCsub index 974ad98fb9..a4890391ce 100644 --- a/platform/linuxbsd/x11/SCsub +++ b/platform/linuxbsd/x11/SCsub @@ -7,11 +7,25 @@ source_files = [ "key_mapping_x11.cpp", ] +if env["use_sowrap"]: + source_files.append( + [ + "dynwrappers/xlib-so_wrap.c", + "dynwrappers/xcursor-so_wrap.c", + "dynwrappers/xinerama-so_wrap.c", + "dynwrappers/xinput2-so_wrap.c", + "dynwrappers/xrandr-so_wrap.c", + "dynwrappers/xrender-so_wrap.c", + "dynwrappers/xext-so_wrap.c", + ] + ) + if env["vulkan"]: source_files.append("vulkan_context_x11.cpp") if env["opengl3"]: - source_files.append(["gl_manager_x11.cpp", "detect_prime_x11.cpp"]) + env.Append(CPPDEFINES=["GLAD_GLX_NO_X11"]) + source_files.append(["gl_manager_x11.cpp", "detect_prime_x11.cpp", "#thirdparty/glad/glx.c"]) objects = [] diff --git a/platform/linuxbsd/x11/detect_prime_x11.cpp b/platform/linuxbsd/x11/detect_prime_x11.cpp index fb833ab5e6..2b5776ce54 100644 --- a/platform/linuxbsd/x11/detect_prime_x11.cpp +++ b/platform/linuxbsd/x11/detect_prime_x11.cpp @@ -1,50 +1,53 @@ -/*************************************************************************/ -/* detect_prime_x11.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. */ -/*************************************************************************/ - -#ifdef X11_ENABLED -#if defined(GLES3_ENABLED) +/**************************************************************************/ +/* detect_prime_x11.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ + +#if defined(X11_ENABLED) && defined(GLES3_ENABLED) #include "detect_prime_x11.h" #include "core/string/print_string.h" #include "core/string/ustring.h" -#include <stdlib.h> +#include "thirdparty/glad/glad/gl.h" +#include "thirdparty/glad/glad/glx.h" -#include <GL/gl.h> -#include <GL/glx.h> +#ifdef SOWRAP_ENABLED +#include "x11/dynwrappers/xlib-so_wrap.h" +#else +#include <X11/XKBlib.h> #include <X11/Xlib.h> #include <X11/Xutil.h> +#endif -#include <cstring> - +#include <stdlib.h> +#include <string.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> @@ -54,6 +57,9 @@ typedef GLXContext (*GLXCREATECONTEXTATTRIBSARBPROC)(Display *, GLXFBConfig, GLXContext, Bool, const int *); +// To prevent shadowing warnings +#undef glGetString + struct vendor { const char *glxvendor = nullptr; int priority = 0; @@ -77,8 +83,6 @@ void create_context() { Window x11_window; GLXContext glx_context; - GLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = (GLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddress((const GLubyte *)"glXCreateContextAttribsARB"); - static int visual_attribs[] = { GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, @@ -90,6 +94,10 @@ void create_context() { None }; + if (gladLoaderLoadGLX(x11_display, XScreenNumberOfScreen(XDefaultScreenOfDisplay(x11_display))) == 0) { + print_verbose("Unable to load GLX, GPU detection skipped."); + quick_exit(1); + } int fbcount; GLXFBConfig fbconfig = nullptr; XVisualInfo *vi = nullptr; @@ -101,7 +109,7 @@ void create_context() { GLXFBConfig *fbc = glXChooseFBConfig(x11_display, DefaultScreen(x11_display), visual_attribs, &fbcount); if (!fbc) { - exit(1); + quick_exit(1); } vi = glXGetVisualFromFBConfig(x11_display, fbc[0]); @@ -122,7 +130,7 @@ void create_context() { x11_window = XCreateWindow(x11_display, RootWindow(x11_display, vi->screen), 0, 0, 10, 10, 0, vi->depth, InputOutput, vi->visual, valuemask, &swa); if (!x11_window) { - exit(1); + quick_exit(1); } glXMakeCurrent(x11_display, x11_window, glx_context); @@ -189,8 +197,15 @@ int detect_prime() { if (i) { setenv("DRI_PRIME", "1", 1); } + create_context(); + PFNGLGETSTRINGPROC glGetString = (PFNGLGETSTRINGPROC)glXGetProcAddressARB((GLubyte *)"glGetString"); + if (!glGetString) { + print_verbose("Unable to get glGetString, GPU detection skipped."); + quick_exit(1); + } + const char *vendor = (const char *)glGetString(GL_VENDOR); const char *renderer = (const char *)glGetString(GL_RENDERER); @@ -208,7 +223,10 @@ int detect_prime() { print_verbose("Couldn't write vendor/renderer string."); } close(fdset[1]); - exit(0); + + // The function quick_exit() is used because exit() will call destructors on static objects copied by fork(). + // These objects will be freed anyway when the process finishes execution. + quick_exit(0); } } @@ -244,5 +262,4 @@ int detect_prime() { return preferred; } -#endif -#endif +#endif // X11_ENABLED && GLES3_ENABLED diff --git a/platform/linuxbsd/x11/detect_prime_x11.h b/platform/linuxbsd/x11/detect_prime_x11.h index 7eb7064cc5..62fe426026 100644 --- a/platform/linuxbsd/x11/detect_prime_x11.h +++ b/platform/linuxbsd/x11/detect_prime_x11.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* detect_prime_x11.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* detect_prime_x11.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 DETECT_PRIME_X11_H #define DETECT_PRIME_X11_H diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp index 88c6500e10..a607e26ac5 100644 --- a/platform/linuxbsd/x11/display_server_x11.cpp +++ b/platform/linuxbsd/x11/display_server_x11.cpp @@ -1,43 +1,44 @@ -/*************************************************************************/ -/* display_server_x11.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* display_server_x11.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "display_server_x11.h" #ifdef X11_ENABLED +#include "x11/detect_prime_x11.h" +#include "x11/key_mapping_x11.h" + #include "core/config/project_settings.h" #include "core/math/math_funcs.h" #include "core/string/print_string.h" #include "core/string/ustring.h" -#include "detect_prime_x11.h" -#include "key_mapping_x11.h" #include "main/main.h" #include "scene/resources/texture.h" @@ -58,10 +59,8 @@ #include <sys/types.h> #include <unistd.h> -#include <X11/Xatom.h> -#include <X11/Xutil.h> -#include <X11/extensions/Xinerama.h> -#include <X11/extensions/shape.h> +#undef CursorShape +#include <X11/XKBlib.h> // ICCCM #define WM_NormalState 1L // window normal state @@ -70,9 +69,6 @@ #define _NET_WM_STATE_REMOVE 0L // remove/unset property #define _NET_WM_STATE_ADD 1L // add/set property -#undef CursorShape -#include <X11/XKBlib.h> - // 2.2 is the first release with multitouch #define XINPUT_CLIENT_VERSION_MAJOR 2 #define XINPUT_CLIENT_VERSION_MINOR 2 @@ -133,6 +129,7 @@ bool DisplayServerX11::has_feature(Feature p_feature) const { #endif case FEATURE_CLIPBOARD_PRIMARY: case FEATURE_TEXT_TO_SPEECH: + case FEATURE_SCREEN_CAPTURE: return true; default: { } @@ -190,6 +187,7 @@ bool DisplayServerX11::_refresh_device_info() { xi.absolute_devices.clear(); xi.touch_devices.clear(); xi.pen_inverted_devices.clear(); + xi.last_relative_time = 0; int dev_count; XIDeviceInfo *info = XIQueryDevice(x11_display, XIAllDevices, &dev_count); @@ -306,37 +304,37 @@ void DisplayServerX11::_flush_mouse_motion() { #ifdef SPEECHD_ENABLED bool DisplayServerX11::tts_is_speaking() const { - ERR_FAIL_COND_V(!tts, false); + ERR_FAIL_COND_V_MSG(!tts, false, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); return tts->is_speaking(); } bool DisplayServerX11::tts_is_paused() const { - ERR_FAIL_COND_V(!tts, false); + ERR_FAIL_COND_V_MSG(!tts, false, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); return tts->is_paused(); } TypedArray<Dictionary> DisplayServerX11::tts_get_voices() const { - ERR_FAIL_COND_V(!tts, TypedArray<Dictionary>()); + ERR_FAIL_COND_V_MSG(!tts, TypedArray<Dictionary>(), "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); return tts->get_voices(); } void DisplayServerX11::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); + ERR_FAIL_COND_MSG(!tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); tts->speak(p_text, p_voice, p_volume, p_pitch, p_rate, p_utterance_id, p_interrupt); } void DisplayServerX11::tts_pause() { - ERR_FAIL_COND(!tts); + ERR_FAIL_COND_MSG(!tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); tts->pause(); } void DisplayServerX11::tts_resume() { - ERR_FAIL_COND(!tts); + ERR_FAIL_COND_MSG(!tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); tts->resume(); } void DisplayServerX11::tts_stop() { - ERR_FAIL_COND(!tts); + ERR_FAIL_COND_MSG(!tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); tts->stop(); } @@ -376,10 +374,18 @@ void DisplayServerX11::mouse_set_mode(MouseMode p_mode) { } // The only modes that show a cursor are VISIBLE and CONFINED - bool showCursor = (p_mode == MOUSE_MODE_VISIBLE || p_mode == MOUSE_MODE_CONFINED); + bool show_cursor = (p_mode == MOUSE_MODE_VISIBLE || p_mode == MOUSE_MODE_CONFINED); + bool previously_shown = (mouse_mode == MOUSE_MODE_VISIBLE || mouse_mode == MOUSE_MODE_CONFINED); + + if (show_cursor && !previously_shown) { + WindowID window_id = get_window_at_screen_position(mouse_get_position()); + if (window_id != INVALID_WINDOW_ID) { + _send_window_event(windows[window_id], WINDOW_EVENT_MOUSE_ENTER); + } + } for (const KeyValue<WindowID, WindowData> &E : windows) { - if (showCursor) { + if (show_cursor) { XDefineCursor(x11_display, E.value.x11_window, cursors[current_cursor]); // show cursor } else { XDefineCursor(x11_display, E.value.x11_window, null_cursor); // hide cursor @@ -455,7 +461,7 @@ Point2i DisplayServerX11::mouse_get_position() const { return Vector2i(); } -MouseButton DisplayServerX11::mouse_get_button_state() const { +BitField<MouseButtonMask> DisplayServerX11::mouse_get_button_state() const { return last_button_state; } @@ -601,7 +607,7 @@ String DisplayServerX11::_clipboard_get_impl(Atom p_source, Window x11_window, A success = true; } } else { - printf("Failed to get selection data chunk.\n"); + print_verbose("Failed to get selection data chunk."); done = true; } @@ -628,7 +634,7 @@ String DisplayServerX11::_clipboard_get_impl(Atom p_source, Window x11_window, A if (result == Success) { ret.parse_utf8((const char *)data); } else { - printf("Failed to get selection data.\n"); + print_verbose("Failed to get selection data."); } if (data) { @@ -748,13 +754,57 @@ int DisplayServerX11::get_screen_count() const { return count; } -Rect2i DisplayServerX11::_screen_get_rect(int p_screen) const { - Rect2i rect(0, 0, 0, 0); +int DisplayServerX11::get_primary_screen() const { + int event_base, error_base; + if (XineramaQueryExtension(x11_display, &event_base, &error_base)) { + return 0; + } else { + return XDefaultScreen(x11_display); + } +} + +int DisplayServerX11::get_keyboard_focus_screen() const { + int count = get_screen_count(); + if (count < 2) { + // Early exit with single monitor. + return 0; + } + + Window focus = 0; + int revert_to = 0; + + XGetInputFocus(x11_display, &focus, &revert_to); + if (focus) { + Window focus_child = 0; + int x = 0, y = 0; + XTranslateCoordinates(x11_display, focus, DefaultRootWindow(x11_display), 0, 0, &x, &y, &focus_child); - if (p_screen == SCREEN_OF_MAIN_WINDOW) { - p_screen = window_get_current_screen(); + XWindowAttributes xwa; + XGetWindowAttributes(x11_display, focus, &xwa); + Rect2i window_rect = Rect2i(x, y, xwa.width, xwa.height); + + // Find which monitor has the largest overlap with the given window. + int screen_index = 0; + int max_area = 0; + for (int i = 0; i < count; i++) { + Rect2i screen_rect = _screen_get_rect(i); + Rect2i intersection = screen_rect.intersection(window_rect); + int area = intersection.get_area(); + if (area > max_area) { + max_area = area; + screen_index = i; + } + } + return screen_index; } + return get_primary_screen(); +} + +Rect2i DisplayServerX11::_screen_get_rect(int p_screen) const { + Rect2i rect(0, 0, 0, 0); + + p_screen = _get_screen_index(p_screen); ERR_FAIL_COND_V(p_screen < 0, rect); // Using Xinerama Extension. @@ -806,12 +856,30 @@ Size2i DisplayServerX11::screen_get_size(int p_screen) const { return _screen_get_rect(p_screen).size; } +// A Handler to avoid crashing on non-fatal X errors by default. +// +// The original X11 error formatter `_XPrintDefaultError` is defined here: +// https://gitlab.freedesktop.org/xorg/lib/libx11/-/blob/e45ca7b41dcd3ace7681d6897505f85d374640f2/src/XlibInt.c#L1322 +// It is not exposed through the API, accesses X11 internals, +// and is much more complex, so this is a less complete simplified error X11 printer. +int default_window_error_handler(Display *display, XErrorEvent *error) { + static char message[1024]; + XGetErrorText(display, error->error_code, message, sizeof(message)); + + ERR_PRINT(vformat("Unhandled XServer error: %s" + "\n Major opcode of failed request: %d" + "\n Serial number of failed request: %d" + "\n Current serial number in output stream: %d", + String::utf8(message), (uint64_t)error->request_code, (uint64_t)error->minor_code, (uint64_t)error->serial)); + return 0; +} + bool g_bad_window = false; int bad_window_error_handler(Display *display, XErrorEvent *error) { if (error->error_code == BadWindow) { g_bad_window = true; } else { - ERR_PRINT("Unhandled XServer error code: " + itos(error->error_code)); + return default_window_error_handler(display, error); } return 0; } @@ -819,10 +887,7 @@ int bad_window_error_handler(Display *display, XErrorEvent *error) { Rect2i DisplayServerX11::screen_get_usable_rect(int p_screen) const { _THREAD_SAFE_METHOD_ - if (p_screen == SCREEN_OF_MAIN_WINDOW) { - p_screen = window_get_current_screen(); - } - + p_screen = _get_screen_index(p_screen); int screen_count = get_screen_count(); // Check if screen is valid. @@ -1099,11 +1164,7 @@ Rect2i DisplayServerX11::screen_get_usable_rect(int p_screen) const { int DisplayServerX11::screen_get_dpi(int p_screen) const { _THREAD_SAFE_METHOD_ - if (p_screen == SCREEN_OF_MAIN_WINDOW) { - p_screen = window_get_current_screen(); - } - - //invalid screen? + p_screen = _get_screen_index(p_screen); ERR_FAIL_INDEX_V(p_screen, get_screen_count(), 0); //Get physical monitor Dimensions through XRandR and calculate dpi @@ -1141,14 +1202,132 @@ int DisplayServerX11::screen_get_dpi(int p_screen) const { return 96; } -float DisplayServerX11::screen_get_refresh_rate(int p_screen) const { - _THREAD_SAFE_METHOD_ +Color DisplayServerX11::screen_get_pixel(const Point2i &p_position) const { + Point2i pos = p_position; + + int number_of_screens = XScreenCount(x11_display); + for (int i = 0; i < number_of_screens; i++) { + Window root = XRootWindow(x11_display, i); + XWindowAttributes root_attrs; + XGetWindowAttributes(x11_display, root, &root_attrs); + if ((pos.x >= root_attrs.x) && (pos.x <= root_attrs.x + root_attrs.width) && (pos.y >= root_attrs.y) && (pos.y <= root_attrs.y + root_attrs.height)) { + XImage *image = XGetImage(x11_display, root, pos.x, pos.y, 1, 1, AllPlanes, XYPixmap); + if (image) { + XColor c; + c.pixel = XGetPixel(image, 0, 0); + XFree(image); + XQueryColor(x11_display, XDefaultColormap(x11_display, i), &c); + return Color(float(c.red) / 65535.0, float(c.green) / 65535.0, float(c.blue) / 65535.0, 1.0); + } + } + } + + return Color(); +} + +Ref<Image> DisplayServerX11::screen_get_image(int p_screen) const { + ERR_FAIL_INDEX_V(p_screen, get_screen_count(), Ref<Image>()); + + switch (p_screen) { + case SCREEN_PRIMARY: { + p_screen = get_primary_screen(); + } break; + case SCREEN_OF_MAIN_WINDOW: { + p_screen = window_get_current_screen(MAIN_WINDOW_ID); + } break; + default: + break; + } - if (p_screen == SCREEN_OF_MAIN_WINDOW) { - p_screen = window_get_current_screen(); + ERR_FAIL_COND_V(p_screen < 0, Ref<Image>()); + + XImage *image = nullptr; + + int event_base, error_base; + if (XineramaQueryExtension(x11_display, &event_base, &error_base)) { + int xin_count; + XineramaScreenInfo *xsi = XineramaQueryScreens(x11_display, &xin_count); + if (p_screen < xin_count) { + int x_count = XScreenCount(x11_display); + for (int i = 0; i < x_count; i++) { + Window root = XRootWindow(x11_display, i); + XWindowAttributes root_attrs; + XGetWindowAttributes(x11_display, root, &root_attrs); + if ((xsi[p_screen].x_org >= root_attrs.x) && (xsi[p_screen].x_org <= root_attrs.x + root_attrs.width) && (xsi[p_screen].y_org >= root_attrs.y) && (xsi[p_screen].y_org <= root_attrs.y + root_attrs.height)) { + image = XGetImage(x11_display, root, xsi[p_screen].x_org, xsi[p_screen].y_org, xsi[p_screen].width, xsi[p_screen].height, AllPlanes, ZPixmap); + break; + } + } + } else { + ERR_FAIL_V_MSG(Ref<Image>(), "Invalid screen index: " + itos(p_screen) + "(count: " + itos(xin_count) + ")."); + } + } else { + int x_count = XScreenCount(x11_display); + if (p_screen < x_count) { + Window root = XRootWindow(x11_display, p_screen); + + XWindowAttributes root_attrs; + XGetWindowAttributes(x11_display, root, &root_attrs); + + image = XGetImage(x11_display, root, root_attrs.x, root_attrs.y, root_attrs.width, root_attrs.height, AllPlanes, ZPixmap); + } else { + ERR_FAIL_V_MSG(Ref<Image>(), "Invalid screen index: " + itos(p_screen) + "(count: " + itos(x_count) + ")."); + } + } + + Ref<Image> img; + if (image) { + int width = image->width; + int height = image->height; + + Vector<uint8_t> img_data; + img_data.resize(height * width * 4); + + uint8_t *sr = (uint8_t *)image->data; + uint8_t *wr = (uint8_t *)img_data.ptrw(); + + if (image->bits_per_pixel == 24 && image->red_mask == 0xff0000 && image->green_mask == 0x00ff00 && image->blue_mask == 0x0000ff) { + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + wr[(y * width + x) * 4 + 0] = sr[(y * width + x) * 3 + 2]; + wr[(y * width + x) * 4 + 1] = sr[(y * width + x) * 3 + 1]; + wr[(y * width + x) * 4 + 2] = sr[(y * width + x) * 3 + 0]; + wr[(y * width + x) * 4 + 3] = 255; + } + } + } else if (image->bits_per_pixel == 24 && image->red_mask == 0x0000ff && image->green_mask == 0x00ff00 && image->blue_mask == 0xff0000) { + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + wr[(y * width + x) * 4 + 0] = sr[(y * width + x) * 3 + 2]; + wr[(y * width + x) * 4 + 1] = sr[(y * width + x) * 3 + 1]; + wr[(y * width + x) * 4 + 2] = sr[(y * width + x) * 3 + 0]; + wr[(y * width + x) * 4 + 3] = 255; + } + } + } else if (image->bits_per_pixel == 32 && image->red_mask == 0xff0000 && image->green_mask == 0x00ff00 && image->blue_mask == 0x0000ff) { + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + wr[(y * width + x) * 4 + 0] = sr[(y * width + x) * 4 + 2]; + wr[(y * width + x) * 4 + 1] = sr[(y * width + x) * 4 + 1]; + wr[(y * width + x) * 4 + 2] = sr[(y * width + x) * 4 + 0]; + wr[(y * width + x) * 4 + 3] = 255; + } + } + } else { + XFree(image); + ERR_FAIL_V_MSG(Ref<Image>(), vformat("XImage with RGB mask %x %x %x and depth %d is not supported.", (uint64_t)image->red_mask, (uint64_t)image->green_mask, (uint64_t)image->blue_mask, (int64_t)image->bits_per_pixel)); + } + img = Image::create_from_data(width, height, false, Image::FORMAT_RGBA8, img_data); + XFree(image); } - //invalid screen? + return img; +} + +float DisplayServerX11::screen_get_refresh_rate(int p_screen) const { + _THREAD_SAFE_METHOD_ + + p_screen = _get_screen_index(p_screen); ERR_FAIL_INDEX_V(p_screen, get_screen_count(), SCREEN_REFRESH_RATE_FALLBACK); //Use xrandr to get screen refresh rate. @@ -1254,6 +1433,8 @@ void DisplayServerX11::show_window(WindowID p_id) { DEBUG_LOG_X11("show_window: %lu (%u) \n", wd.x11_window, p_id); XMapWindow(x11_display, wd.x11_window); + XSync(x11_display, False); + _validate_mode_on_map(p_id); } void DisplayServerX11::delete_sub_window(WindowID p_id) { @@ -1287,12 +1468,22 @@ void DisplayServerX11::delete_sub_window(WindowID p_id) { } #endif - XUnmapWindow(x11_display, wd.x11_window); - XDestroyWindow(x11_display, wd.x11_window); if (wd.xic) { XDestroyIC(wd.xic); wd.xic = nullptr; } + XDestroyWindow(x11_display, wd.x11_xim_window); +#ifdef XKB_ENABLED + if (xkb_loaded_v05p) { + if (wd.xkb_state) { + xkb_compose_state_unref(wd.xkb_state); + wd.xkb_state = nullptr; + } + } +#endif + + XUnmapWindow(x11_display, wd.x11_window); + XDestroyWindow(x11_display, wd.x11_window); windows.erase(p_id); } @@ -1309,6 +1500,14 @@ int64_t DisplayServerX11::window_get_native_handle(HandleType p_handle_type, Win case WINDOW_VIEW: { return 0; // Not supported. } +#ifdef GLES3_ENABLED + case OPENGL_CONTEXT: { + if (gl_manager) { + return (int64_t)gl_manager->get_glx_context(p_window); + } + return 0; + } +#endif default: { return 0; } @@ -1375,31 +1574,35 @@ void DisplayServerX11::window_set_mouse_passthrough(const Vector<Vector2> &p_reg _THREAD_SAFE_METHOD_ ERR_FAIL_COND(!windows.has(p_window)); - const WindowData &wd = windows[p_window]; + windows[p_window].mpath = p_region; + _update_window_mouse_passthrough(p_window); +} + +void DisplayServerX11::_update_window_mouse_passthrough(WindowID p_window) { + ERR_FAIL_COND(!windows.has(p_window)); + + const Vector<Vector2> region_path = windows[p_window].mpath; int event_base, error_base; const Bool ext_okay = XShapeQueryExtension(x11_display, &event_base, &error_base); if (ext_okay) { - Region region; - if (p_region.size() == 0) { - region = XCreateRegion(); - XRectangle rect; - rect.x = 0; - rect.y = 0; - rect.width = window_get_real_size(p_window).x; - rect.height = window_get_real_size(p_window).y; - XUnionRectWithRegion(&rect, region, region); + if (windows[p_window].mpass) { + Region region = XCreateRegion(); + XShapeCombineRegion(x11_display, windows[p_window].x11_window, ShapeInput, 0, 0, region, ShapeSet); + XDestroyRegion(region); + } else if (region_path.size() == 0) { + XShapeCombineMask(x11_display, windows[p_window].x11_window, ShapeInput, 0, 0, None, ShapeSet); } else { - XPoint *points = (XPoint *)memalloc(sizeof(XPoint) * p_region.size()); - for (int i = 0; i < p_region.size(); i++) { - points[i].x = p_region[i].x; - points[i].y = p_region[i].y; + XPoint *points = (XPoint *)memalloc(sizeof(XPoint) * region_path.size()); + for (int i = 0; i < region_path.size(); i++) { + points[i].x = region_path[i].x; + points[i].y = region_path[i].y; } - region = XPolygonRegion(points, p_region.size(), EvenOddRule); + Region region = XPolygonRegion(points, region_path.size(), EvenOddRule); memfree(points); + XShapeCombineRegion(x11_display, windows[p_window].x11_window, ShapeInput, 0, 0, region, ShapeSet); + XDestroyRegion(region); } - XShapeCombineRegion(x11_display, wd.x11_window, ShapeInput, 0, 0, region, ShapeSet); - XDestroyRegion(region); } } @@ -1487,23 +1690,28 @@ void DisplayServerX11::window_set_current_screen(int p_screen, WindowID p_window ERR_FAIL_COND(!windows.has(p_window)); WindowData &wd = windows[p_window]; - if (p_screen == SCREEN_OF_MAIN_WINDOW) { - p_screen = window_get_current_screen(); - } - - // Check if screen is valid + p_screen = _get_screen_index(p_screen); ERR_FAIL_INDEX(p_screen, get_screen_count()); + if (window_get_current_screen(p_window) == p_screen) { + return; + } + if (window_get_mode(p_window) == WINDOW_MODE_FULLSCREEN) { Point2i position = screen_get_position(p_screen); Size2i size = screen_get_size(p_screen); XMoveResizeWindow(x11_display, wd.x11_window, position.x, position.y, size.x, size.y); } else { - if (p_screen != window_get_current_screen(p_window)) { - 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); + Rect2i srect = screen_get_usable_rect(p_screen); + Point2i wpos = window_get_position(p_window) - screen_get_position(window_get_current_screen(p_window)); + Size2i wsize = window_get_size(p_window); + wpos += srect.position; + if (srect != Rect2i()) { + wpos.x = CLAMP(wpos.x, srect.position.x, srect.position.x + srect.size.width - wsize.width / 3); + wpos.y = CLAMP(wpos.y, srect.position.y, srect.position.y + srect.size.height - wsize.height / 3); } + window_set_position(wpos, p_window); } } @@ -1571,7 +1779,7 @@ void DisplayServerX11::_update_size_hints(WindowID p_window) { xsh->width = wd.size.width; xsh->height = wd.size.height; - if (window_mode == WINDOW_MODE_FULLSCREEN) { + if (window_mode == WINDOW_MODE_FULLSCREEN || window_mode == WINDOW_MODE_EXCLUSIVE_FULLSCREEN) { // Do not set any other hints to prevent the window manager from ignoring the fullscreen flags } else if (window_get_flag(WINDOW_FLAG_RESIZE_DISABLED, p_window)) { // If resizing is disabled, use the forced size @@ -1607,6 +1815,40 @@ Point2i DisplayServerX11::window_get_position(WindowID p_window) const { return wd.position; } +Point2i DisplayServerX11::window_get_position_with_decorations(WindowID p_window) const { + _THREAD_SAFE_METHOD_ + + ERR_FAIL_COND_V(!windows.has(p_window), Size2i()); + const WindowData &wd = windows[p_window]; + + if (wd.fullscreen) { + return wd.position; + } + + XWindowAttributes xwa; + XSync(x11_display, False); + XGetWindowAttributes(x11_display, wd.x11_window, &xwa); + int x = wd.position.x; + int y = wd.position.y; + Atom prop = XInternAtom(x11_display, "_NET_FRAME_EXTENTS", True); + if (prop != None) { + Atom type; + int format; + unsigned long len; + unsigned long remaining; + unsigned char *data = nullptr; + if (XGetWindowProperty(x11_display, wd.x11_window, prop, 0, 4, False, AnyPropertyType, &type, &format, &len, &remaining, &data) == Success) { + if (format == 32 && len == 4 && data) { + long *extents = (long *)data; + x -= extents[0]; // left + y -= extents[2]; // top + } + XFree(data); + } + } + return Size2i(x, y); +} + void DisplayServerX11::window_set_position(const Point2i &p_position, WindowID p_window) { _THREAD_SAFE_METHOD_ @@ -1751,12 +1993,16 @@ Size2i DisplayServerX11::window_get_size(WindowID p_window) const { return wd.size; } -Size2i DisplayServerX11::window_get_real_size(WindowID p_window) const { +Size2i DisplayServerX11::window_get_size_with_decorations(WindowID p_window) const { _THREAD_SAFE_METHOD_ ERR_FAIL_COND_V(!windows.has(p_window), Size2i()); const WindowData &wd = windows[p_window]; + if (wd.fullscreen) { + return wd.size; + } + XWindowAttributes xwa; XSync(x11_display, False); XGetWindowAttributes(x11_display, wd.x11_window, &xwa); @@ -1938,12 +2184,28 @@ void DisplayServerX11::_validate_mode_on_map(WindowID p_window) { // Check if we applied any window modes that didn't take effect while unmapped const WindowData &wd = windows[p_window]; if (wd.fullscreen && !_window_fullscreen_check(p_window)) { - _set_wm_fullscreen(p_window, true); + _set_wm_fullscreen(p_window, true, wd.exclusive_fullscreen); } else if (wd.maximized && !_window_maximize_check(p_window, "_NET_WM_STATE")) { _set_wm_maximized(p_window, true); } else if (wd.minimized && !_window_minimize_check(p_window)) { _set_wm_minimized(p_window, true); } + + if (wd.on_top) { + Atom wm_state = XInternAtom(x11_display, "_NET_WM_STATE", False); + Atom wm_above = XInternAtom(x11_display, "_NET_WM_STATE_ABOVE", False); + + XClientMessageEvent xev; + memset(&xev, 0, sizeof(xev)); + xev.type = ClientMessage; + xev.window = wd.x11_window; + xev.message_type = wm_state; + xev.format = 32; + xev.data.l[0] = _NET_WM_STATE_ADD; + xev.data.l[1] = wm_above; + xev.data.l[3] = 1; + XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureRedirectMask | SubstructureNotifyMask, (XEvent *)&xev); + } } bool DisplayServerX11::window_is_maximize_allowed(WindowID p_window) const { @@ -2013,7 +2275,7 @@ void DisplayServerX11::_set_wm_minimized(WindowID p_window, bool p_enabled) { wd.minimized = p_enabled; } -void DisplayServerX11::_set_wm_fullscreen(WindowID p_window, bool p_enabled) { +void DisplayServerX11::_set_wm_fullscreen(WindowID p_window, bool p_enabled, bool p_exclusive) { ERR_FAIL_COND(!windows.has(p_window)); WindowData &wd = windows[p_window]; @@ -2052,7 +2314,14 @@ void DisplayServerX11::_set_wm_fullscreen(WindowID p_window, bool p_enabled) { // set bypass compositor hint Atom bypass_compositor = XInternAtom(x11_display, "_NET_WM_BYPASS_COMPOSITOR", False); - unsigned long compositing_disable_on = p_enabled ? 1 : 0; + unsigned long compositing_disable_on = 0; // Use default. + if (p_enabled) { + if (p_exclusive) { + compositing_disable_on = 1; // Force composition OFF to reduce overhead. + } else { + compositing_disable_on = 2; // Force composition ON to allow popup windows. + } + } if (bypass_compositor != None) { XChangeProperty(x11_display, wd.x11_window, bypass_compositor, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&compositing_disable_on, 1); } @@ -2098,8 +2367,9 @@ void DisplayServerX11::window_set_mode(WindowMode p_mode, WindowID p_window) { case WINDOW_MODE_FULLSCREEN: { //Remove full-screen wd.fullscreen = false; + wd.exclusive_fullscreen = false; - _set_wm_fullscreen(p_window, false); + _set_wm_fullscreen(p_window, false, false); //un-maximize required for always on top bool on_top = window_get_flag(WINDOW_FLAG_ALWAYS_ON_TOP, p_window); @@ -2132,7 +2402,13 @@ void DisplayServerX11::window_set_mode(WindowMode p_mode, WindowID p_window) { } wd.fullscreen = true; - _set_wm_fullscreen(p_window, true); + if (p_mode == WINDOW_MODE_EXCLUSIVE_FULLSCREEN) { + wd.exclusive_fullscreen = true; + _set_wm_fullscreen(p_window, true, true); + } else { + wd.exclusive_fullscreen = false; + _set_wm_fullscreen(p_window, true, false); + } } break; case WINDOW_MODE_MAXIMIZED: { _set_wm_maximized(p_window, true); @@ -2147,7 +2423,11 @@ DisplayServer::WindowMode DisplayServerX11::window_get_mode(WindowID p_window) c const WindowData &wd = windows[p_window]; if (wd.fullscreen) { //if fullscreen, it's not in another mode - return WINDOW_MODE_FULLSCREEN; + if (wd.exclusive_fullscreen) { + return WINDOW_MODE_EXCLUSIVE_FULLSCREEN; + } else { + return WINDOW_MODE_FULLSCREEN; + } } // Test maximized. @@ -2195,6 +2475,7 @@ void DisplayServerX11::window_set_flag(WindowFlags p_flag, bool p_enabled, Windo window_set_size(window_get_size(p_window), p_window); wd.borderless = p_enabled; + _update_window_mouse_passthrough(p_window); } break; case WINDOW_FLAG_ALWAYS_ON_TOP: { ERR_FAIL_COND_MSG(wd.transient_parent != INVALID_WINDOW_ID, "Can't make a window transient if the 'on top' flag is active."); @@ -2228,6 +2509,10 @@ void DisplayServerX11::window_set_flag(WindowFlags p_flag, bool p_enabled, Windo case WINDOW_FLAG_NO_FOCUS: { wd.no_focus = p_enabled; } break; + case WINDOW_FLAG_MOUSE_PASSTHROUGH: { + wd.mpass = p_enabled; + _update_window_mouse_passthrough(p_window); + } break; case WINDOW_FLAG_POPUP: { XWindowAttributes xwa; XSync(x11_display, False); @@ -2281,6 +2566,9 @@ bool DisplayServerX11::window_get_flag(WindowFlags p_flag, WindowID p_window) co case WINDOW_FLAG_NO_FOCUS: { return wd.no_focus; } break; + case WINDOW_FLAG_MOUSE_PASSTHROUGH: { + return wd.mpass; + } break; case WINDOW_FLAG_POPUP: { return wd.is_popup; } break; @@ -2338,6 +2626,15 @@ void DisplayServerX11::window_move_to_foreground(WindowID p_window) { XFlush(x11_display); } +bool DisplayServerX11::window_is_focused(WindowID p_window) const { + _THREAD_SAFE_METHOD_ + + ERR_FAIL_COND_V(!windows.has(p_window), false); + const WindowData &wd = windows[p_window]; + + return wd.focused; +} + bool DisplayServerX11::window_can_draw(WindowID p_window) const { //this seems to be all that is provided by X11 return window_get_mode(p_window) != WINDOW_MODE_MINIMIZED; @@ -2361,23 +2658,40 @@ void DisplayServerX11::window_set_ime_active(const bool p_active, WindowID p_win ERR_FAIL_COND(!windows.has(p_window)); WindowData &wd = windows[p_window]; - wd.im_active = p_active; - if (!wd.xic) { return; } + if (!wd.focused) { + wd.ime_active = false; + im_text = String(); + im_selection = Vector2i(); + return; + } // Block events polling while changing input focus // because it triggers some event polling internally. if (p_active) { - { - MutexLock mutex_lock(events_mutex); - XSetICFocus(wd.xic); + MutexLock mutex_lock(events_mutex); + + wd.ime_active = true; + + XMapWindow(x11_display, wd.x11_xim_window); + + XWindowAttributes xwa; + XSync(x11_display, False); + XGetWindowAttributes(x11_display, wd.x11_xim_window, &xwa); + if (xwa.map_state == IsViewable) { + XSetInputFocus(x11_display, wd.x11_xim_window, RevertToParent, CurrentTime); } - window_set_ime_position(wd.im_position, p_window); + XSetICFocus(wd.xic); } else { MutexLock mutex_lock(events_mutex); XUnsetICFocus(wd.xic); + XUnmapWindow(x11_display, wd.x11_xim_window); + wd.ime_active = false; + + im_text = String(); + im_selection = Vector2i(); } } @@ -2387,25 +2701,29 @@ void DisplayServerX11::window_set_ime_position(const Point2i &p_pos, WindowID p_ ERR_FAIL_COND(!windows.has(p_window)); WindowData &wd = windows[p_window]; - wd.im_position = p_pos; - if (!wd.xic) { return; } + if (!wd.focused) { + return; + } - ::XPoint spot; - spot.x = short(p_pos.x); - spot.y = short(p_pos.y); - XVaNestedList preedit_attr = XVaCreateNestedList(0, XNSpotLocation, &spot, nullptr); - - { - // Block events polling during this call - // because it triggers some event polling internally. - MutexLock mutex_lock(events_mutex); - XSetICValues(wd.xic, XNPreeditAttributes, preedit_attr, nullptr); + if (wd.ime_active) { + XWindowAttributes xwa; + XSync(x11_display, False); + XGetWindowAttributes(x11_display, wd.x11_xim_window, &xwa); + if (xwa.map_state == IsViewable) { + XMoveWindow(x11_display, wd.x11_xim_window, p_pos.x, p_pos.y); + } } +} + +Point2i DisplayServerX11::ime_get_selection() const { + return im_selection; +} - XFree(preedit_attr); +String DisplayServerX11::ime_get_text() const { + return im_text; } void DisplayServerX11::cursor_set_shape(CursorShape p_shape) { @@ -2439,6 +2757,8 @@ DisplayServerX11::CursorShape DisplayServerX11::cursor_get_shape() const { void DisplayServerX11::cursor_set_custom_image(const Ref<Resource> &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { _THREAD_SAFE_METHOD_ + ERR_FAIL_INDEX(p_shape, CURSOR_MAX); + if (p_cursor.is_valid()) { HashMap<CursorShape, Vector<Variant>>::Iterator cursor_c = cursors_cache.find(p_shape); @@ -2452,16 +2772,12 @@ void DisplayServerX11::cursor_set_custom_image(const Ref<Resource> &p_cursor, Cu } Ref<Texture2D> texture = p_cursor; + ERR_FAIL_COND(!texture.is_valid()); Ref<AtlasTexture> atlas_texture = p_cursor; - Ref<Image> image; Size2i texture_size; Rect2i atlas_rect; - if (texture.is_valid()) { - image = texture->get_image(); - } - - if (!image.is_valid() && atlas_texture.is_valid()) { + if (atlas_texture.is_valid()) { texture = atlas_texture->get_atlas(); atlas_rect.size.width = texture->get_width(); @@ -2471,19 +2787,23 @@ void DisplayServerX11::cursor_set_custom_image(const Ref<Resource> &p_cursor, Cu texture_size.width = atlas_texture->get_region().size.x; texture_size.height = atlas_texture->get_region().size.y; - } else if (image.is_valid()) { + } else { texture_size.width = texture->get_width(); texture_size.height = texture->get_height(); } - ERR_FAIL_COND(!texture.is_valid()); ERR_FAIL_COND(p_hotspot.x < 0 || p_hotspot.y < 0); ERR_FAIL_COND(texture_size.width > 256 || texture_size.height > 256); ERR_FAIL_COND(p_hotspot.x > texture_size.width || p_hotspot.y > texture_size.height); - image = texture->get_image(); + Ref<Image> image = texture->get_image(); ERR_FAIL_COND(!image.is_valid()); + if (image->is_compressed()) { + image = image->duplicate(true); + Error err = image->decompress(); + ERR_FAIL_COND_MSG(err != OK, "Couldn't decompress VRAM-compressed custom mouse cursor image. Switch to a lossless compression mode in the Import dock."); + } // Create the cursor structure XcursorImage *cursor_image = XcursorImageCreate(texture_size.width, texture_size.height); @@ -2532,8 +2852,8 @@ void DisplayServerX11::cursor_set_custom_image(const Ref<Resource> &p_cursor, Cu XcursorImageDestroy(cursor_image); } else { // Reset to default system cursor - if (img[p_shape]) { - cursors[p_shape] = XcursorImageLoadCursor(x11_display, img[p_shape]); + if (cursor_img[p_shape]) { + cursors[p_shape] = XcursorImageLoadCursor(x11_display, cursor_img[p_shape]); } CursorShape c = current_cursor; @@ -2646,7 +2966,7 @@ Key DisplayServerX11::keyboard_get_keycode_from_physical(Key p_keycode) const { Key modifiers = p_keycode & KeyModifierMask::MODIFIER_MASK; Key keycode_no_mod = p_keycode & KeyModifierMask::CODE_MASK; unsigned int xkeycode = KeyMappingX11::get_xlibcode(keycode_no_mod); - KeySym xkeysym = XkbKeycodeToKeysym(x11_display, xkeycode, 0, 0); + KeySym xkeysym = XkbKeycodeToKeysym(x11_display, xkeycode, keyboard_get_current_layout(), 0); if (is_ascii_lower_case(xkeysym)) { xkeysym -= ('a' - 'A'); } @@ -2726,23 +3046,33 @@ void DisplayServerX11::_get_key_modifier_state(unsigned int p_x11_state, Ref<Inp state->set_meta_pressed((p_x11_state & Mod4Mask)); } -MouseButton DisplayServerX11::_get_mouse_button_state(MouseButton p_x11_button, int p_x11_type) { - MouseButton mask = mouse_button_to_mask(p_x11_button); +BitField<MouseButtonMask> DisplayServerX11::_get_mouse_button_state(MouseButton p_x11_button, int p_x11_type) { + MouseButtonMask mask = mouse_button_to_mask(p_x11_button); if (p_x11_type == ButtonPress) { - last_button_state |= mask; + last_button_state.set_flag(mask); } else { - last_button_state &= ~mask; + last_button_state.clear_flag(mask); } return last_button_state; } void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event, LocalVector<XEvent> &p_events, uint32_t &p_event_index, bool p_echo) { - WindowData wd = windows[p_window]; + WindowData &wd = windows[p_window]; // X11 functions don't know what const is XKeyEvent *xkeyevent = p_event; + if (wd.ime_in_progress) { + return; + } + if (wd.ime_suppress_next_keyup) { + wd.ime_suppress_next_keyup = false; + if (xkeyevent->type != KeyPress) { + return; + } + } + // This code was pretty difficult to write. // The docs stink and every toolkit seems to // do it in a different way. @@ -2766,13 +3096,22 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event, KeySym keysym_unicode = 0; // keysym used to find unicode // XLookupString returns keysyms usable as nice keycodes. - char str[256 + 1]; + char str[256] = {}; XKeyEvent xkeyevent_no_mod = *xkeyevent; xkeyevent_no_mod.state &= ~ShiftMask; xkeyevent_no_mod.state &= ~ControlMask; - XLookupString(xkeyevent, str, 256, &keysym_unicode, nullptr); + XLookupString(xkeyevent, str, 255, &keysym_unicode, nullptr); XLookupString(&xkeyevent_no_mod, nullptr, 0, &keysym_keycode, nullptr); + String keysym; +#ifdef XKB_ENABLED + if (xkb_loaded_v08p) { + KeySym keysym_unicode_nm = 0; // keysym used to find unicode + XLookupString(&xkeyevent_no_mod, nullptr, 0, &keysym_unicode_nm, nullptr); + keysym = String::chr(xkb_keysym_to_utf32(xkb_keysym_to_upper(keysym_unicode_nm))); + } +#endif + // Meanwhile, XLookupString returns keysyms useful for unicode. if (!xmbstring) { @@ -2821,13 +3160,18 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event, _get_key_modifier_state(xkeyevent->state, k); k->set_window_id(p_window); - k->set_unicode(tmp[i]); - k->set_pressed(keypress); k->set_keycode(keycode); - - k->set_physical_keycode((Key)physical_keycode); + k->set_physical_keycode(physical_keycode); + if (!keysym.is_empty()) { + k->set_key_label(fix_key_label(keysym[0], keycode)); + } else { + k->set_key_label(keycode); + } + if (keypress) { + k->set_unicode(fix_unicode(tmp[i])); + } k->set_echo(false); @@ -2855,6 +3199,66 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event, } } while (status == XBufferOverflow); #endif +#ifdef XKB_ENABLED + } else if (xkeyevent->type == KeyPress && wd.xkb_state && xkb_loaded_v05p) { + xkb_compose_feed_result res = xkb_compose_state_feed(wd.xkb_state, keysym_unicode); + if (res == XKB_COMPOSE_FEED_ACCEPTED) { + if (xkb_compose_state_get_status(wd.xkb_state) == XKB_COMPOSE_COMPOSED) { + bool keypress = xkeyevent->type == KeyPress; + Key keycode = KeyMappingX11::get_keycode(keysym_keycode); + Key physical_keycode = KeyMappingX11::get_scancode(xkeyevent->keycode); + + if (keycode >= Key::A + 32 && keycode <= Key::Z + 32) { + keycode -= 'a' - 'A'; + } + + char str_xkb[256] = {}; + int str_xkb_size = xkb_compose_state_get_utf8(wd.xkb_state, str_xkb, 255); + + String tmp; + tmp.parse_utf8(str_xkb, str_xkb_size); + for (int i = 0; i < tmp.length(); i++) { + Ref<InputEventKey> k; + k.instantiate(); + if (physical_keycode == Key::NONE && keycode == Key::NONE && tmp[i] == 0) { + continue; + } + + if (keycode == Key::NONE) { + keycode = (Key)physical_keycode; + } + + _get_key_modifier_state(xkeyevent->state, k); + + k->set_window_id(p_window); + k->set_pressed(keypress); + + k->set_keycode(keycode); + k->set_physical_keycode(physical_keycode); + if (!keysym.is_empty()) { + k->set_key_label(fix_key_label(keysym[0], keycode)); + } else { + k->set_key_label(keycode); + } + if (keypress) { + k->set_unicode(fix_unicode(tmp[i])); + } + + k->set_echo(false); + + if (k->get_keycode() == Key::BACKTAB) { + //make it consistent across platforms. + k->set_keycode(Key::TAB); + k->set_physical_keycode(Key::TAB); + k->set_shift_pressed(true); + } + + Input::get_singleton()->parse_input_event(k); + } + return; + } + } +#endif } /* Phase 2, obtain a Godot keycode from the keysym */ @@ -2870,7 +3274,7 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event, // KeyMappingX11 also translates keysym to unicode. // It does a binary search on a table to translate // most properly. - unsigned int unicode = keysym_unicode > 0 ? KeyMappingX11::get_unicode_from_keysym(keysym_unicode) : 0; + char32_t unicode = keysym_unicode > 0 ? KeyMappingX11::get_unicode_from_keysym(keysym_unicode) : 0; /* Phase 4, determine if event must be filtered */ @@ -2956,7 +3360,14 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event, k->set_keycode(keycode); k->set_physical_keycode((Key)physical_keycode); - k->set_unicode(unicode); + if (!keysym.is_empty()) { + k->set_key_label(fix_key_label(keysym[0], keycode)); + } else { + k->set_key_label(keycode); + } + if (keypress) { + k->set_unicode(fix_unicode(unicode)); + } k->set_echo(p_echo); if (k->get_keycode() == Key::BACKTAB) { @@ -3050,7 +3461,7 @@ Atom DisplayServerX11::_process_selection_request_target(Atom p_target, Window p return p_property; } else { char *target_name = XGetAtomName(x11_display, p_target); - printf("Target '%s' not supported.\n", target_name); + print_verbose(vformat("Target '%s' not supported.", target_name)); if (target_name) { XFree(target_name); } @@ -3108,6 +3519,81 @@ void DisplayServerX11::_handle_selection_request_event(XSelectionRequestEvent *p XFlush(x11_display); } +int DisplayServerX11::_xim_preedit_start_callback(::XIM xim, ::XPointer client_data, + ::XPointer call_data) { + DisplayServerX11 *ds = reinterpret_cast<DisplayServerX11 *>(client_data); + WindowID window_id = ds->_get_focused_window_or_popup(); + WindowData &wd = ds->windows[window_id]; + if (wd.ime_active) { + wd.ime_in_progress = true; + } + + return -1; // Allow preedit strings of any length (no limit). +} + +void DisplayServerX11::_xim_preedit_done_callback(::XIM xim, ::XPointer client_data, + ::XPointer call_data) { + DisplayServerX11 *ds = reinterpret_cast<DisplayServerX11 *>(client_data); + WindowID window_id = ds->_get_focused_window_or_popup(); + WindowData &wd = ds->windows[window_id]; + if (wd.ime_active) { + wd.ime_in_progress = false; + wd.ime_suppress_next_keyup = true; + } +} + +void DisplayServerX11::_xim_preedit_draw_callback(::XIM xim, ::XPointer client_data, + ::XIMPreeditDrawCallbackStruct *call_data) { + DisplayServerX11 *ds = reinterpret_cast<DisplayServerX11 *>(client_data); + WindowID window_id = ds->_get_focused_window_or_popup(); + WindowData &wd = ds->windows[window_id]; + + XIMText *xim_text = call_data->text; + if (wd.ime_active) { + if (xim_text != nullptr) { + String changed_text; + if (xim_text->encoding_is_wchar) { + changed_text = String(xim_text->string.wide_char); + } else { + changed_text.parse_utf8(xim_text->string.multi_byte); + } + + if (call_data->chg_length < 0) { + ds->im_text = ds->im_text.substr(0, call_data->chg_first) + changed_text; + } else { + ds->im_text = ds->im_text.substr(0, call_data->chg_first) + changed_text + ds->im_text.substr(call_data->chg_length); + } + + // Find the start and end of the selection. + int start = 0, count = 0; + for (int i = 0; i < xim_text->length; i++) { + if (xim_text->feedback[i] & XIMReverse) { + if (count == 0) { + start = i; + count = 1; + } else { + count++; + } + } + } + if (count > 0) { + ds->im_selection = Point2i(start + call_data->chg_first, count); + } else { + ds->im_selection = Point2i(call_data->caret, 0); + } + } else { + ds->im_text = String(); + ds->im_selection = Point2i(); + } + + OS_Unix::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_OS_IME_UPDATE); + } +} + +void DisplayServerX11::_xim_preedit_caret_callback(::XIM xim, ::XPointer client_data, + ::XIMPreeditCaretCallbackStruct *call_data) { +} + void DisplayServerX11::_xim_destroy_callback(::XIM im, ::XPointer client_data, ::XPointer call_data) { WARN_PRINT("Input method stopped"); @@ -3139,8 +3625,17 @@ void DisplayServerX11::_window_changed(XEvent *event) { // Query display server about a possible new window state. wd.fullscreen = _window_fullscreen_check(window_id); - wd.minimized = _window_minimize_check(window_id); - wd.maximized = _window_maximize_check(window_id, "_NET_WM_STATE"); + wd.maximized = _window_maximize_check(window_id, "_NET_WM_STATE") && !wd.fullscreen; + wd.minimized = _window_minimize_check(window_id) && !wd.fullscreen && !wd.maximized; + + // Readjusting the window position if the window is being reparented by the window manager for decoration + Window root, parent, *children; + unsigned int nchildren; + if (XQueryTree(x11_display, wd.x11_window, &root, &parent, &children, &nchildren) && wd.parent != parent) { + wd.parent = parent; + window_set_position(wd.position, window_id); + } + XFree(children); { //the position in xconfigure is not useful here, obtain it manually @@ -3157,10 +3652,6 @@ void DisplayServerX11::_window_changed(XEvent *event) { if (new_rect == Rect2i(wd.position, wd.size)) { return; } - if (wd.xic) { - // Not portable. - window_set_ime_position(Point2(0, 1)); - } wd.position = new_rect.position; wd.size = new_rect.size; @@ -3356,8 +3847,23 @@ Rect2i DisplayServerX11::window_get_popup_safe_rect(WindowID p_window) const { void DisplayServerX11::popup_open(WindowID p_window) { _THREAD_SAFE_METHOD_ + bool has_popup_ancestor = false; + WindowID transient_root = p_window; + while (true) { + WindowID parent = windows[transient_root].transient_parent; + if (parent == INVALID_WINDOW_ID) { + break; + } else { + transient_root = parent; + if (windows[parent].is_popup) { + has_popup_ancestor = true; + break; + } + } + } + WindowData &wd = windows[p_window]; - if (wd.is_popup) { + if (wd.is_popup || has_popup_ancestor) { // Find current popup parent, or root popup if new window is not transient. List<WindowID>::Element *C = nullptr; List<WindowID>::Element *E = popup_list.back(); @@ -3414,7 +3920,7 @@ bool DisplayServerX11::mouse_process_popups() { XWindowAttributes root_attrs; XGetWindowAttributes(x11_display, root, &root_attrs); Vector2i pos = Vector2i(root_attrs.x + root_x, root_attrs.y + root_y); - if ((pos != last_mouse_monitor_pos) || (mask != last_mouse_monitor_mask)) { + if (mask != last_mouse_monitor_mask) { if (((mask & Button1Mask) || (mask & Button2Mask) || (mask & Button3Mask) || (mask & Button4Mask) || (mask & Button5Mask))) { List<WindowID>::Element *C = nullptr; List<WindowID>::Element *E = popup_list.back(); @@ -3440,7 +3946,6 @@ bool DisplayServerX11::mouse_process_popups() { } } last_mouse_monitor_mask = mask; - last_mouse_monitor_pos = pos; } } return closed; @@ -3504,11 +4009,8 @@ void DisplayServerX11::process_events() { for (uint32_t event_index = 0; event_index < events.size(); ++event_index) { XEvent &event = events[event_index]; - if (ignore_events) { - XFreeEventData(x11_display, &event.xcookie); - continue; - } + bool ime_window_event = false; WindowID window_id = MAIN_WINDOW_ID; // Assign the event to the relevant window @@ -3517,6 +4019,11 @@ void DisplayServerX11::process_events() { window_id = E.key; break; } + if (event.xany.window == E.value.x11_xim_window) { + window_id = E.key; + ime_window_event = true; + break; + } } if (XGetEventData(x11_display, &event.xcookie)) { @@ -3531,6 +4038,9 @@ void DisplayServerX11::process_events() { _refresh_device_info(); } break; case XI_RawMotion: { + if (ime_window_event || ignore_events) { + break; + } XIRawEvent *raw_event = (XIRawEvent *)event_data; int device_id = raw_event->sourceid; @@ -3633,6 +4143,9 @@ void DisplayServerX11::process_events() { #ifdef TOUCH_ENABLED case XI_TouchBegin: case XI_TouchEnd: { + if (ime_window_event || ignore_events) { + break; + } bool is_begin = event_data->evtype == XI_TouchBegin; Ref<InputEventScreenTouch> st; @@ -3663,6 +4176,9 @@ void DisplayServerX11::process_events() { } break; case XI_TouchUpdate: { + if (ime_window_event || ignore_events) { + break; + } HashMap<int, Vector2>::Iterator curr_pos_elem = xi.state.find(index); if (!curr_pos_elem) { // Defensive break; @@ -3689,6 +4205,9 @@ void DisplayServerX11::process_events() { switch (event.type) { case MapNotify: { DEBUG_LOG_X11("[%u] MapNotify window=%lu (%u) \n", frame, event.xmap.window, window_id); + if (ime_window_event) { + break; + } const WindowData &wd = windows[window_id]; @@ -3709,6 +4228,9 @@ 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); + if (ime_window_event) { + break; + } windows[window_id].fullscreen = _window_fullscreen_check(window_id); @@ -3717,18 +4239,27 @@ void DisplayServerX11::process_events() { case NoExpose: { DEBUG_LOG_X11("[%u] NoExpose drawable=%lu (%u) \n", frame, event.xnoexpose.drawable, window_id); + if (ime_window_event) { + break; + } windows[window_id].minimized = true; } break; case VisibilityNotify: { DEBUG_LOG_X11("[%u] VisibilityNotify window=%lu (%u), state=%u \n", frame, event.xvisibility.window, window_id, event.xvisibility.state); + if (ime_window_event) { + break; + } windows[window_id].minimized = _window_minimize_check(window_id); } break; case LeaveNotify: { DEBUG_LOG_X11("[%u] LeaveNotify window=%lu (%u), mode='%u' \n", frame, event.xcrossing.window, window_id, event.xcrossing.mode); + if (ime_window_event) { + break; + } if (!mouse_mode_grab) { _send_window_event(windows[window_id], WINDOW_EVENT_MOUSE_EXIT); @@ -3738,6 +4269,9 @@ void DisplayServerX11::process_events() { case EnterNotify: { DEBUG_LOG_X11("[%u] EnterNotify window=%lu (%u), mode='%u' \n", frame, event.xcrossing.window, window_id, event.xcrossing.mode); + if (ime_window_event) { + break; + } if (!mouse_mode_grab) { _send_window_event(windows[window_id], WINDOW_EVENT_MOUSE_ENTER); @@ -3746,18 +4280,14 @@ void DisplayServerX11::process_events() { case FocusIn: { DEBUG_LOG_X11("[%u] FocusIn window=%lu (%u), mode='%u' \n", frame, event.xfocus.window, window_id, event.xfocus.mode); + if (ime_window_event || (event.xfocus.detail == NotifyInferior)) { + break; + } WindowData &wd = windows[window_id]; last_focused_window = window_id; wd.focused = true; - if (wd.xic) { - // Block events polling while changing input focus - // because it triggers some event polling internally. - MutexLock mutex_lock(events_mutex); - XSetICFocus(wd.xic); - } - // Keep track of focus order for overlapping windows. static unsigned int focus_order = 0; wd.focus_order = ++focus_order; @@ -3797,17 +4327,20 @@ void DisplayServerX11::process_events() { case FocusOut: { DEBUG_LOG_X11("[%u] FocusOut window=%lu (%u), mode='%u' \n", frame, event.xfocus.window, window_id, event.xfocus.mode); - WindowData &wd = windows[window_id]; - - wd.focused = false; - - if (wd.xic) { - // Block events polling while changing input focus - // because it triggers some event polling internally. + if (ime_window_event || (event.xfocus.detail == NotifyInferior)) { + break; + } + if (wd.ime_active) { MutexLock mutex_lock(events_mutex); XUnsetICFocus(wd.xic); + XUnmapWindow(x11_display, wd.x11_xim_window); + wd.ime_active = false; + im_text = String(); + im_selection = Vector2i(); + OS_Unix::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_OS_IME_UPDATE); } + wd.focused = false; Input::get_singleton()->release_pressed_events(); _send_window_event(wd, WINDOW_EVENT_FOCUS_OUT); @@ -3843,6 +4376,9 @@ void DisplayServerX11::process_events() { case ConfigureNotify: { DEBUG_LOG_X11("[%u] ConfigureNotify window=%lu (%u), event=%lu, above=%lu, override_redirect=%u \n", frame, event.xconfigure.window, window_id, event.xconfigure.event, event.xconfigure.above, event.xconfigure.override_redirect); + if (event.xconfigure.window == windows[window_id].x11_xim_window) { + break; + } const WindowData &wd = windows[window_id]; @@ -3862,6 +4398,9 @@ void DisplayServerX11::process_events() { case ButtonPress: case ButtonRelease: { + if (ime_window_event || ignore_events) { + break; + } /* exit in case of a mouse button press */ last_timestamp = event.xbutton.time; if (mouse_mode == MOUSE_MODE_CAPTURED) { @@ -3919,36 +4458,50 @@ void DisplayServerX11::process_events() { } else { DEBUG_LOG_X11("[%u] ButtonRelease window=%lu (%u), button_index=%u \n", frame, event.xbutton.window, window_id, mb->get_button_index()); - if (!wd.focused) { + WindowID window_id_other = INVALID_WINDOW_ID; + Window wd_other_x11_window; + if (wd.focused) { + // Handle cases where an unfocused popup is open that needs to receive button-up events. + WindowID popup_id = _get_focused_window_or_popup(); + if (popup_id != INVALID_WINDOW_ID && popup_id != window_id) { + window_id_other = popup_id; + wd_other_x11_window = windows[popup_id].x11_window; + } + } else { // Propagate the event to the focused window, // because it's received only on the topmost window. // Note: This is needed for drag & drop to work between windows, // because the engine expects events to keep being processed // on the same window dragging started. for (const KeyValue<WindowID, WindowData> &E : windows) { - const WindowData &wd_other = E.value; - WindowID window_id_other = E.key; - if (wd_other.focused) { - if (window_id_other != window_id) { - int x, y; - Window child; - XTranslateCoordinates(x11_display, wd.x11_window, wd_other.x11_window, event.xbutton.x, event.xbutton.y, &x, &y, &child); - - mb->set_window_id(window_id_other); - mb->set_position(Vector2(x, y)); - mb->set_global_position(mb->get_position()); - Input::get_singleton()->parse_input_event(mb); + if (E.value.focused) { + if (E.key != window_id) { + window_id_other = E.key; + wd_other_x11_window = E.value.x11_window; } break; } } } + + if (window_id_other != INVALID_WINDOW_ID) { + int x, y; + Window child; + XTranslateCoordinates(x11_display, wd.x11_window, wd_other_x11_window, event.xbutton.x, event.xbutton.y, &x, &y, &child); + + mb->set_window_id(window_id_other); + mb->set_position(Vector2(x, y)); + mb->set_global_position(mb->get_position()); + } } Input::get_singleton()->parse_input_event(mb); } break; case MotionNotify: { + if (ime_window_event || ignore_events) { + break; + } // The X11 API requires filtering one-by-one through the motion // notify events, in order to figure out which event is the one // generated by warping the mouse pointer. @@ -4044,13 +4597,13 @@ void DisplayServerX11::process_events() { if (xi.pressure_supported) { mm->set_pressure(xi.pressure); } else { - mm->set_pressure(bool(mouse_get_button_state() & MouseButton::MASK_LEFT) ? 1.0f : 0.0f); + mm->set_pressure(bool(mouse_get_button_state().has_flag(MouseButtonMask::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()); + mm->set_button_mask(mouse_get_button_state()); mm->set_position(pos); mm->set_global_position(pos); mm->set_velocity(Input::get_singleton()->get_last_mouse_velocity()); @@ -4094,6 +4647,9 @@ void DisplayServerX11::process_events() { } break; case KeyPress: case KeyRelease: { + if (ignore_events) { + break; + } #ifdef DISPLAY_SERVER_X11_DEBUG_LOGS_ENABLED if (event.type == KeyPress) { DEBUG_LOG_X11("[%u] KeyPress window=%lu (%u), keycode=%u, time=%lu \n", frame, event.xkey.window, window_id, event.xkey.keycode, event.xkey.time); @@ -4109,14 +4665,16 @@ void DisplayServerX11::process_events() { } break; case SelectionNotify: - + if (ime_window_event) { + break; + } if (event.xselection.target == requested) { Property p = _read_property(x11_display, windows[window_id].x11_window, XInternAtom(x11_display, "PRIMARY", 0)); - Vector<String> files = String((char *)p.data).split("\n", false); + Vector<String> files = String((char *)p.data).split("\r\n", false); XFree(p.data); for (int i = 0; i < files.size(); i++) { - files.write[i] = files[i].replace("file://", "").uri_decode().strip_edges(); + files.write[i] = files[i].replace("file://", "").uri_decode(); } if (!windows[window_id].drop_files_callback.is_null()) { @@ -4144,7 +4702,9 @@ void DisplayServerX11::process_events() { break; case ClientMessage: - + if (ime_window_event) { + break; + } if ((unsigned int)event.xclient.data.l[0] == (unsigned int)wm_delete) { _send_window_event(windows[window_id], WINDOW_EVENT_CLOSE_REQUEST); } @@ -4399,7 +4959,7 @@ void DisplayServerX11::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mo #if defined(GLES3_ENABLED) if (gl_manager) { - gl_manager->set_use_vsync(p_vsync_mode == DisplayServer::VSYNC_ENABLED); + gl_manager->set_use_vsync(p_vsync_mode != DisplayServer::VSYNC_DISABLED); } #endif } @@ -4432,23 +4992,25 @@ Vector<String> DisplayServerX11::get_rendering_drivers_func() { return drivers; } -DisplayServer *DisplayServerX11::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error) { - DisplayServer *ds = memnew(DisplayServerX11(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, r_error)); +DisplayServer *DisplayServerX11::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error) { + DisplayServer *ds = memnew(DisplayServerX11(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, p_screen, r_error)); if (r_error != OK) { if (p_rendering_driver == "vulkan") { String executable_name = OS::get_singleton()->get_executable_path().get_file(); - OS::get_singleton()->alert("Your video card driver does not support the selected Vulkan version.\n" - "Please try updating your GPU driver or try using the OpenGL 3 driver.\n" - "You can enable the OpenGL 3 driver by starting the engine from the\n" - "command line with the command:\n'./" + - executable_name + " --rendering-driver opengl3'.\n " - "If you have updated your graphics drivers recently, try rebooting.", - "Unable to initialize Video driver"); + OS::get_singleton()->alert( + vformat("Your video card drivers seem not to support the required Vulkan version.\n\n" + "If possible, consider updating your video card drivers or using the OpenGL 3 driver.\n\n" + "You can enable the OpenGL 3 driver by starting the engine from the\n" + "command line with the command:\n\n \"%s\" --rendering-driver opengl3\n\n" + "If you recently updated your video card drivers, try rebooting.", + executable_name), + "Unable to initialize Vulkan video driver"); } else { - OS::get_singleton()->alert("Your video card driver does not support the selected OpenGL version.\n" - "Please try updating your GPU driver.\n" - "If you have updated your graphics drivers recently, try rebooting.", - "Unable to initialize Video driver"); + OS::get_singleton()->alert( + "Your video card drivers seem not to support the required OpenGL 3.3 version.\n\n" + "If possible, consider updating your video card drivers.\n\n" + "If you recently updated your video card drivers, try rebooting.", + "Unable to initialize OpenGL video driver"); } } return ds; @@ -4462,7 +5024,9 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, V #ifdef GLES3_ENABLED if (gl_manager) { - visualInfo = gl_manager->get_vi(x11_display); + Error err; + visualInfo = gl_manager->get_vi(x11_display, err); + ERR_FAIL_COND_V_MSG(err != OK, INVALID_WINDOW_ID, "Can't acquire visual info from display."); vi_selected = true; } #endif @@ -4524,15 +5088,49 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, V // handling decorations and placement. // On the other hand, focus changes need to be handled manually when this is set. // - save_under is a hint for the WM to keep the content of windows behind to avoid repaint. - if (wd.is_popup || wd.no_focus) { + if (wd.no_focus) { windowAttributes.override_redirect = True; windowAttributes.save_under = True; valuemask |= CWOverrideRedirect | CWSaveUnder; } + int rq_screen = get_screen_from_rect(p_rect); + if (rq_screen < 0) { + rq_screen = get_primary_screen(); // Requested window rect is outside any screen bounds. + } + + Rect2i win_rect = p_rect; + if (p_mode == WINDOW_MODE_FULLSCREEN || p_mode == WINDOW_MODE_EXCLUSIVE_FULLSCREEN) { + Rect2i screen_rect = Rect2i(screen_get_position(rq_screen), screen_get_size(rq_screen)); + + win_rect = screen_rect; + } else { + Rect2i srect = screen_get_usable_rect(rq_screen); + Point2i wpos = p_rect.position; + wpos.x = CLAMP(wpos.x, srect.position.x, srect.position.x + srect.size.width - p_rect.size.width / 3); + wpos.y = CLAMP(wpos.y, srect.position.y, srect.position.y + srect.size.height - p_rect.size.height / 3); + + win_rect.position = wpos; + } + + // Position and size hints are set from these values before they are updated to the actual + // window size, so we need to initialize them here. + wd.position = win_rect.position; + wd.size = win_rect.size; + { - wd.x11_window = XCreateWindow(x11_display, RootWindow(x11_display, visualInfo.screen), p_rect.position.x, p_rect.position.y, p_rect.size.width > 0 ? p_rect.size.width : 1, p_rect.size.height > 0 ? p_rect.size.height : 1, 0, visualInfo.depth, InputOutput, visualInfo.visual, valuemask, &windowAttributes); + wd.x11_window = XCreateWindow(x11_display, RootWindow(x11_display, visualInfo.screen), win_rect.position.x, win_rect.position.y, win_rect.size.width > 0 ? win_rect.size.width : 1, win_rect.size.height > 0 ? win_rect.size.height : 1, 0, visualInfo.depth, InputOutput, visualInfo.visual, valuemask, &windowAttributes); + wd.parent = RootWindow(x11_display, visualInfo.screen); + XSetWindowAttributes window_attributes_ime = {}; + window_attributes_ime.event_mask = KeyPressMask | KeyReleaseMask | StructureNotifyMask | ExposureMask; + + wd.x11_xim_window = XCreateWindow(x11_display, wd.x11_window, 0, 0, 1, 1, 0, CopyFromParent, InputOnly, CopyFromParent, CWEventMask, &window_attributes_ime); +#ifdef XKB_ENABLED + if (dead_tbl && xkb_loaded_v05p) { + wd.xkb_state = xkb_compose_state_new(dead_tbl, XKB_COMPOSE_STATE_NO_FLAGS); + } +#endif // Enable receiving notification when the window is initialized (MapNotify) // so the focus can be set at the right time. if (!wd.no_focus && !wd.is_popup) { @@ -4603,7 +5201,50 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, V // because it triggers some event polling internally. MutexLock mutex_lock(events_mutex); - wd.xic = XCreateIC(xim, XNInputStyle, xim_style, XNClientWindow, wd.x11_window, XNFocusWindow, wd.x11_window, (char *)nullptr); + // Force on-the-spot for the over-the-spot style. + if ((xim_style & XIMPreeditPosition) != 0) { + xim_style &= ~XIMPreeditPosition; + xim_style |= XIMPreeditCallbacks; + } + if ((xim_style & XIMPreeditCallbacks) != 0) { + ::XIMCallback preedit_start_callback; + preedit_start_callback.client_data = (::XPointer)(this); + preedit_start_callback.callback = (::XIMProc)(void *)(_xim_preedit_start_callback); + + ::XIMCallback preedit_done_callback; + preedit_done_callback.client_data = (::XPointer)(this); + preedit_done_callback.callback = (::XIMProc)(_xim_preedit_done_callback); + + ::XIMCallback preedit_draw_callback; + preedit_draw_callback.client_data = (::XPointer)(this); + preedit_draw_callback.callback = (::XIMProc)(_xim_preedit_draw_callback); + + ::XIMCallback preedit_caret_callback; + preedit_caret_callback.client_data = (::XPointer)(this); + preedit_caret_callback.callback = (::XIMProc)(_xim_preedit_caret_callback); + + ::XVaNestedList preedit_attributes = XVaCreateNestedList(0, + XNPreeditStartCallback, &preedit_start_callback, + XNPreeditDoneCallback, &preedit_done_callback, + XNPreeditDrawCallback, &preedit_draw_callback, + XNPreeditCaretCallback, &preedit_caret_callback, + (char *)nullptr); + + wd.xic = XCreateIC(xim, + XNInputStyle, xim_style, + XNClientWindow, wd.x11_xim_window, + XNFocusWindow, wd.x11_xim_window, + XNPreeditAttributes, preedit_attributes, + (char *)nullptr); + XFree(preedit_attributes); + } else { + wd.xic = XCreateIC(xim, + XNInputStyle, xim_style, + XNClientWindow, wd.x11_xim_window, + XNFocusWindow, wd.x11_xim_window, + (char *)nullptr); + } + if (XGetICValues(wd.xic, XNFilterEvents, &im_event_mask, nullptr) != nullptr) { WARN_PRINT("XGetICValues couldn't obtain XNFilterEvents value"); XDestroyIC(wd.xic); @@ -4652,14 +5293,15 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, V #if defined(VULKAN_ENABLED) if (context_vulkan) { - Error err = context_vulkan->window_create(id, p_vsync_mode, wd.x11_window, x11_display, p_rect.size.width, p_rect.size.height); + Error err = context_vulkan->window_create(id, p_vsync_mode, wd.x11_window, x11_display, win_rect.size.width, win_rect.size.height); ERR_FAIL_COND_V_MSG(err != OK, INVALID_WINDOW_ID, "Can't create a Vulkan window"); } #endif #ifdef GLES3_ENABLED if (gl_manager) { - Error err = gl_manager->window_create(id, wd.x11_window, x11_display, p_rect.size.width, p_rect.size.height); + Error err = gl_manager->window_create(id, wd.x11_window, x11_display, win_rect.size.width, win_rect.size.height); ERR_FAIL_COND_V_MSG(err != OK, INVALID_WINDOW_ID, "Can't create an OpenGL window"); + window_set_vsync_mode(p_vsync_mode, id); } #endif @@ -4693,14 +5335,159 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, V return id; } -DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error) { +static bool _is_xim_style_supported(const ::XIMStyle &p_style) { + const ::XIMStyle supported_preedit = XIMPreeditCallbacks | XIMPreeditPosition | XIMPreeditNothing | XIMPreeditNone; + const ::XIMStyle supported_status = XIMStatusNothing | XIMStatusNone; + + // Check preedit style is supported + if ((p_style & supported_preedit) == 0) { + return false; + } + + // Check status style is supported + if ((p_style & supported_status) == 0) { + return false; + } + + return true; +} + +static ::XIMStyle _get_best_xim_style(const ::XIMStyle &p_style_a, const ::XIMStyle &p_style_b) { + if (p_style_a == 0) { + return p_style_b; + } + if (p_style_b == 0) { + return p_style_a; + } + + const ::XIMStyle preedit = XIMPreeditArea | XIMPreeditCallbacks | XIMPreeditPosition | XIMPreeditNothing | XIMPreeditNone; + const ::XIMStyle status = XIMStatusArea | XIMStatusCallbacks | XIMStatusNothing | XIMStatusNone; + + ::XIMStyle a = p_style_a & preedit; + ::XIMStyle b = p_style_b & preedit; + if (a != b) { + // Compare preedit styles. + if ((a | b) & XIMPreeditCallbacks) { + return a == XIMPreeditCallbacks ? p_style_a : p_style_b; + } else if ((a | b) & XIMPreeditPosition) { + return a == XIMPreeditPosition ? p_style_a : p_style_b; + } else if ((a | b) & XIMPreeditArea) { + return a == XIMPreeditArea ? p_style_a : p_style_b; + } else if ((a | b) & XIMPreeditNothing) { + return a == XIMPreeditNothing ? p_style_a : p_style_b; + } + } else { + // Preedit styles are the same, compare status styles. + a = p_style_a & status; + b = p_style_b & status; + + if ((a | b) & XIMStatusCallbacks) { + return a == XIMStatusCallbacks ? p_style_a : p_style_b; + } else if ((a | b) & XIMStatusArea) { + return a == XIMStatusArea ? p_style_a : p_style_b; + } else if ((a | b) & XIMStatusNothing) { + return a == XIMStatusNothing ? p_style_a : p_style_b; + } + } + return p_style_a; +} + +DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error) { + KeyMappingX11::initialize(); + +#ifdef SOWRAP_ENABLED +#ifdef DEBUG_ENABLED + int dylibloader_verbose = 1; +#else + int dylibloader_verbose = 0; +#endif + if (initialize_xlib(dylibloader_verbose) != 0) { + r_error = ERR_UNAVAILABLE; + ERR_FAIL_MSG("Can't load Xlib dynamically."); + } + + if (initialize_xcursor(dylibloader_verbose) != 0) { + r_error = ERR_UNAVAILABLE; + ERR_FAIL_MSG("Can't load XCursor dynamically."); + } +#ifdef XKB_ENABLED + bool xkb_loaded = (initialize_xkbcommon(dylibloader_verbose) == 0); + xkb_loaded_v05p = xkb_loaded; + if (!xkb_context_new || !xkb_compose_table_new_from_locale || !xkb_compose_table_unref || !xkb_context_unref || !xkb_compose_state_feed || !xkb_compose_state_unref || !xkb_compose_state_new || !xkb_compose_state_get_status || !xkb_compose_state_get_utf8) { + xkb_loaded_v05p = false; + print_verbose("Detected XKBcommon library version older than 0.5, dead key composition and Unicode key labels disabled."); + } + xkb_loaded_v08p = xkb_loaded; + if (!xkb_keysym_to_utf32 || !xkb_keysym_to_upper) { + xkb_loaded_v08p = false; + print_verbose("Detected XKBcommon library version older than 0.8, Unicode key labels disabled."); + } +#endif + if (initialize_xext(dylibloader_verbose) != 0) { + r_error = ERR_UNAVAILABLE; + ERR_FAIL_MSG("Can't load Xext dynamically."); + } + + if (initialize_xinerama(dylibloader_verbose) != 0) { + r_error = ERR_UNAVAILABLE; + ERR_FAIL_MSG("Can't load Xinerama dynamically."); + } + + if (initialize_xrandr(dylibloader_verbose) != 0) { + r_error = ERR_UNAVAILABLE; + ERR_FAIL_MSG("Can't load Xrandr dynamically."); + } + + if (initialize_xrender(dylibloader_verbose) != 0) { + r_error = ERR_UNAVAILABLE; + ERR_FAIL_MSG("Can't load Xrender dynamically."); + } + + if (initialize_xinput2(dylibloader_verbose) != 0) { + r_error = ERR_UNAVAILABLE; + ERR_FAIL_MSG("Can't load Xinput2 dynamically."); + } +#else +#ifdef XKB_ENABLED + xkb_loaded = true; +#endif +#endif + +#ifdef XKB_ENABLED + if (xkb_loaded) { + xkb_ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS); + if (xkb_ctx) { + const char *locale = getenv("LC_ALL"); + if (!locale || !*locale) { + locale = getenv("LC_CTYPE"); + } + if (!locale || !*locale) { + locale = getenv("LANG"); + } + if (!locale || !*locale) { + locale = "C"; + } + dead_tbl = xkb_compose_table_new_from_locale(xkb_ctx, locale, XKB_COMPOSE_COMPILE_NO_FLAGS); + } + } +#endif + Input::get_singleton()->set_event_dispatch_function(_dispatch_input_events); r_error = OK; + { + if (!XcursorImageCreate || !XcursorImageLoadCursor || !XcursorImageDestroy || !XcursorGetDefaultSize || !XcursorGetTheme || !XcursorLibraryLoadImage) { + // There's no API to check version, check if functions are available instead. + ERR_PRINT("Unsupported Xcursor library version."); + r_error = ERR_UNAVAILABLE; + return; + } + } + for (int i = 0; i < CURSOR_MAX; i++) { cursors[i] = None; - img[i] = nullptr; + cursor_img[i] = nullptr; } XInitThreads(); //always use threads @@ -4714,6 +5501,71 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode return; } + { + int version_major = 0; + int version_minor = 0; + int rc = XShapeQueryVersion(x11_display, &version_major, &version_minor); + print_verbose(vformat("Xshape %d.%d detected.", version_major, version_minor)); + if (rc != 1 || version_major < 1) { + ERR_PRINT("Unsupported Xshape library version."); + r_error = ERR_UNAVAILABLE; + XCloseDisplay(x11_display); + return; + } + } + + { + int version_major = 0; + int version_minor = 0; + int rc = XineramaQueryVersion(x11_display, &version_major, &version_minor); + print_verbose(vformat("Xinerama %d.%d detected.", version_major, version_minor)); + if (rc != 1 || version_major < 1) { + ERR_PRINT("Unsupported Xinerama library version."); + r_error = ERR_UNAVAILABLE; + XCloseDisplay(x11_display); + return; + } + } + + { + int version_major = 0; + int version_minor = 0; + int rc = XRRQueryVersion(x11_display, &version_major, &version_minor); + print_verbose(vformat("Xrandr %d.%d detected.", version_major, version_minor)); + if (rc != 1 || (version_major == 1 && version_minor < 3) || (version_major < 1)) { + ERR_PRINT("Unsupported Xrandr library version."); + r_error = ERR_UNAVAILABLE; + XCloseDisplay(x11_display); + return; + } + } + + { + int version_major = 0; + int version_minor = 0; + int rc = XRenderQueryVersion(x11_display, &version_major, &version_minor); + print_verbose(vformat("Xrender %d.%d detected.", version_major, version_minor)); + if (rc != 1 || (version_major == 0 && version_minor < 11)) { + ERR_PRINT("Unsupported Xrender library version."); + r_error = ERR_UNAVAILABLE; + XCloseDisplay(x11_display); + return; + } + } + + { + int version_major = 2; // Report 2.2 as supported by engine, but should work with 2.1 or 2.0 library as well. + int version_minor = 2; + int rc = XIQueryVersion(x11_display, &version_major, &version_minor); + print_verbose(vformat("Xinput %d.%d detected.", version_major, version_minor)); + if (rc != Success || (version_major < 2)) { + ERR_PRINT("Unsupported Xinput2 library version."); + r_error = ERR_UNAVAILABLE; + XCloseDisplay(x11_display); + return; + } + } + char *modifiers = nullptr; Bool xkb_dar = False; XAutoRepeatOn(x11_display); @@ -4800,11 +5652,13 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode if (xim_styles) { xim_style = 0L; for (int i = 0; i < xim_styles->count_styles; i++) { - if (xim_styles->supported_styles[i] == - (XIMPreeditNothing | XIMStatusNothing)) { - xim_style = xim_styles->supported_styles[i]; - break; + const ::XIMStyle &style = xim_styles->supported_styles[i]; + + if (!_is_xim_style_supported(style)) { + continue; } + + xim_style = _get_best_xim_style(xim_style, style); } XFree(xim_styles); @@ -4826,7 +5680,10 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode #ifdef SPEECHD_ENABLED // Init TTS - tts = memnew(TTS_Linux); + bool tts_enabled = GLOBAL_GET("audio/general/text_to_speech"); + if (tts_enabled) { + tts = memnew(TTS_Linux); + } #endif //!!!!!!!!!!!!!!!!!!!!!!!!!! @@ -4894,7 +5751,7 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode gl_manager = memnew(GLManager_X11(p_resolution, opengl_api_type)); - if (gl_manager->initialize() != OK) { + if (gl_manager->initialize(x11_display) != OK) { memdelete(gl_manager); gl_manager = nullptr; r_error = ERR_UNAVAILABLE; @@ -4917,12 +5774,14 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode ERR_FAIL_MSG("Video driver not found"); } - Point2i window_position( - (screen_get_size(0).width - p_resolution.width) / 2, - (screen_get_size(0).height - p_resolution.height) / 2); - + Point2i window_position; if (p_position != nullptr) { window_position = *p_position; + } else { + if (p_screen == SCREEN_OF_MAIN_WINDOW) { + p_screen = SCREEN_PRIMARY; + } + window_position = screen_get_position(p_screen) + (screen_get_size(p_screen) - p_resolution) / 2; } WindowID main_window = _create_window(p_mode, p_vsync_mode, p_flags, Rect2i(window_position, p_resolution)); @@ -4936,8 +5795,6 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode } } show_window(main_window); - XSync(x11_display, False); - _validate_mode_on_map(main_window); #if defined(VULKAN_ENABLED) if (rendering_driver == "vulkan") { @@ -4990,8 +5847,8 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode "question_arrow" }; - img[i] = XcursorLibraryLoadImage(cursor_file[i], cursor_theme, cursor_size); - if (!img[i]) { + cursor_img[i] = XcursorLibraryLoadImage(cursor_file[i], cursor_theme, cursor_size); + if (!cursor_img[i]) { const char *fallback = nullptr; switch (i) { @@ -5029,7 +5886,7 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode fallback = "bd_double_arrow"; break; case CURSOR_MOVE: - img[i] = img[CURSOR_DRAG]; + cursor_img[i] = cursor_img[CURSOR_DRAG]; break; case CURSOR_VSPLIT: fallback = "sb_v_double_arrow"; @@ -5042,11 +5899,11 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode break; } if (fallback != nullptr) { - img[i] = XcursorLibraryLoadImage(fallback, cursor_theme, cursor_size); + cursor_img[i] = XcursorLibraryLoadImage(fallback, cursor_theme, cursor_size); } } - if (img[i]) { - cursors[i] = XcursorImageLoadCursor(x11_display, img[i]); + if (cursor_img[i]) { + cursors[i] = XcursorImageLoadCursor(x11_display, cursor_img[i]); } else { print_verbose("Failed loading custom cursor: " + String(cursor_file[i])); } @@ -5101,6 +5958,7 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode portal_desktop = memnew(FreeDesktopPortalDesktop); #endif + XSetErrorHandler(&default_window_error_handler); r_error = OK; } @@ -5132,10 +5990,30 @@ DisplayServerX11::~DisplayServerX11() { XDestroyIC(wd.xic); wd.xic = nullptr; } + XDestroyWindow(x11_display, wd.x11_xim_window); +#ifdef XKB_ENABLED + if (xkb_loaded_v05p) { + if (wd.xkb_state) { + xkb_compose_state_unref(wd.xkb_state); + wd.xkb_state = nullptr; + } + } +#endif XUnmapWindow(x11_display, wd.x11_window); XDestroyWindow(x11_display, wd.x11_window); } +#ifdef XKB_ENABLED + if (xkb_loaded_v05p) { + if (dead_tbl) { + xkb_compose_table_unref(dead_tbl); + } + if (xkb_ctx) { + xkb_context_unref(xkb_ctx); + } + } +#endif + //destroy drivers #if defined(VULKAN_ENABLED) if (rendering_device_vulkan) { @@ -5165,8 +6043,8 @@ DisplayServerX11::~DisplayServerX11() { if (cursors[i] != None) { XFreeCursor(x11_display, cursors[i]); } - if (img[i] != nullptr) { - XcursorImageDestroy(img[i]); + if (cursor_img[i] != nullptr) { + XcursorImageDestroy(cursor_img[i]); } } @@ -5180,7 +6058,9 @@ DisplayServerX11::~DisplayServerX11() { } #ifdef SPEECHD_ENABLED - memdelete(tts); + if (tts) { + memdelete(tts); + } #endif #ifdef DBUS_ENABLED diff --git a/platform/linuxbsd/x11/display_server_x11.h b/platform/linuxbsd/x11/display_server_x11.h index 861eced88b..180362923b 100644 --- a/platform/linuxbsd/x11/display_server_x11.h +++ b/platform/linuxbsd/x11/display_server_x11.h @@ -1,74 +1,107 @@ -/*************************************************************************/ -/* display_server_x11.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* display_server_x11.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 DISPLAY_SERVER_X11_H #define DISPLAY_SERVER_X11_H #ifdef X11_ENABLED -#include "servers/display_server.h" +#include "joypad_linux.h" #include "core/input/input.h" +#include "core/os/mutex.h" +#include "core/os/thread.h" #include "core/templates/local_vector.h" #include "drivers/alsa/audio_driver_alsa.h" #include "drivers/alsamidi/midi_driver_alsamidi.h" #include "drivers/pulseaudio/audio_driver_pulseaudio.h" #include "drivers/unix/os_unix.h" -#include "joypad_linux.h" #include "servers/audio_server.h" +#include "servers/display_server.h" #include "servers/rendering/renderer_compositor.h" #include "servers/rendering_server.h" #if defined(SPEECHD_ENABLED) -#include "../tts_linux.h" +#include "tts_linux.h" #endif #if defined(GLES3_ENABLED) -#include "gl_manager_x11.h" +#include "x11/gl_manager_x11.h" #endif #if defined(VULKAN_ENABLED) +#include "x11/vulkan_context_x11.h" + #include "drivers/vulkan/rendering_device_vulkan.h" -#include "vulkan_context_x11.h" #endif #if defined(DBUS_ENABLED) -#include "../freedesktop_portal_desktop.h" -#include "../freedesktop_screensaver.h" +#include "freedesktop_portal_desktop.h" +#include "freedesktop_screensaver.h" #endif -#include <X11/Xcursor/Xcursor.h> +#include <X11/Xatom.h> #include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <X11/keysym.h> + +#ifdef SOWRAP_ENABLED +#include "x11/dynwrappers/xlib-so_wrap.h" + +#include "x11/dynwrappers/xcursor-so_wrap.h" +#include "x11/dynwrappers/xext-so_wrap.h" +#include "x11/dynwrappers/xinerama-so_wrap.h" +#include "x11/dynwrappers/xinput2-so_wrap.h" +#include "x11/dynwrappers/xrandr-so_wrap.h" +#include "x11/dynwrappers/xrender-so_wrap.h" + +#include "xkbcommon-so_wrap.h" +#else +#include <X11/XKBlib.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> + +#include <X11/Xcursor/Xcursor.h> #include <X11/extensions/XInput2.h> +#include <X11/extensions/Xext.h> +#include <X11/extensions/Xinerama.h> #include <X11/extensions/Xrandr.h> -#include <X11/keysym.h> +#include <X11/extensions/Xrender.h> +#include <X11/extensions/shape.h> + +#ifdef XKB_ENABLED +#include <xkbcommon/xkbcommon-compose.h> +#include <xkbcommon/xkbcommon-keysyms.h> +#include <xkbcommon/xkbcommon.h> +#endif +#endif typedef struct _xrr_monitor_info { Atom name; @@ -87,8 +120,7 @@ typedef struct _xrr_monitor_info { #undef CursorShape class DisplayServerX11 : public DisplayServer { - //No need to register, it's platform-specific and nothing is added - //GDCLASS(DisplayServerX11, DisplayServer) + // No need to register with GDCLASS, it's platform-specific and nothing is added. _THREAD_SAFE_CLASS_ @@ -127,20 +159,28 @@ class DisplayServerX11 : public DisplayServer { struct WindowData { Window x11_window; + Window x11_xim_window; + Window parent; ::XIC xic; + bool ime_active = false; + bool ime_in_progress = false; + bool ime_suppress_next_keyup = false; +#ifdef XKB_ENABLED + xkb_compose_state *xkb_state = nullptr; +#endif Size2i min_size; Size2i max_size; Point2i position; Size2i size; - Point2i im_position; - bool im_active = false; Callable rect_changed_callback; Callable event_callback; Callable input_event_callback; Callable input_text_callback; Callable drop_files_callback; + Vector<Vector2> mpath; + WindowID transient_parent = INVALID_WINDOW_ID; HashSet<WindowID> transient_children; @@ -151,6 +191,7 @@ class DisplayServerX11 : public DisplayServer { //better to guess on the fly, given WM can change it //WindowMode mode; bool fullscreen = false; //OS can't exit from this mode + bool exclusive_fullscreen = false; bool on_top = false; bool borderless = false; bool resize_disabled = false; @@ -160,16 +201,26 @@ class DisplayServerX11 : public DisplayServer { bool maximized = false; bool is_popup = false; bool layered_window = false; + bool mpass = false; Rect2i parent_safe_rect; unsigned int focus_order = 0; }; + Point2i im_selection; + String im_text; + +#ifdef XKB_ENABLED + bool xkb_loaded_v05p = false; + bool xkb_loaded_v08p = false; + xkb_context *xkb_ctx = nullptr; + xkb_compose_table *dead_tbl = nullptr; +#endif + HashMap<WindowID, WindowData> windows; unsigned int last_mouse_monitor_mask = 0; - Vector2i last_mouse_monitor_pos; uint64_t time_since_popup = 0; List<WindowID> popup_list; @@ -189,6 +240,15 @@ class DisplayServerX11 : public DisplayServer { ::Time last_keyrelease_time = 0; ::XIM xim; ::XIMStyle xim_style; + + static int _xim_preedit_start_callback(::XIM xim, ::XPointer client_data, + ::XPointer call_data); + static void _xim_preedit_done_callback(::XIM xim, ::XPointer client_data, + ::XPointer call_data); + static void _xim_preedit_draw_callback(::XIM xim, ::XPointer client_data, + ::XIMPreeditDrawCallbackStruct *call_data); + static void _xim_preedit_caret_callback(::XIM xim, ::XPointer client_data, + ::XIMPreeditCaretCallbackStruct *call_data); static void _xim_destroy_callback(::XIM im, ::XPointer client_data, ::XPointer call_data); @@ -197,7 +257,7 @@ class DisplayServerX11 : public DisplayServer { Point2i last_click_pos = Point2i(-100, -100); uint64_t last_click_ms = 0; MouseButton last_click_button_index = MouseButton::NONE; - MouseButton last_button_state = MouseButton::NONE; + BitField<MouseButtonMask> last_button_state; bool app_focused = false; uint64_t time_since_no_focus = 0; @@ -226,7 +286,7 @@ class DisplayServerX11 : public DisplayServer { Rect2i _screen_get_rect(int p_screen) const; - MouseButton _get_mouse_button_state(MouseButton p_x11_button, int p_x11_type); + BitField<MouseButtonMask> _get_mouse_button_state(MouseButton p_x11_button, int p_x11_type); void _get_key_modifier_state(unsigned int p_x11_state, Ref<InputEventWithModifiers> state); void _flush_mouse_motion(); @@ -237,6 +297,7 @@ class DisplayServerX11 : public DisplayServer { Atom _process_selection_request_target(Atom p_target, Window p_requestor, Atom p_property, Atom p_selection) const; void _handle_selection_request_event(XSelectionRequestEvent *p_event) const; + void _update_window_mouse_passthrough(WindowID p_window); String _clipboard_get_impl(Atom p_source, Window x11_window, Atom target) const; String _clipboard_get(Atom p_source, Window x11_window) const; @@ -246,7 +307,7 @@ class DisplayServerX11 : public DisplayServer { const char *cursor_theme = nullptr; int cursor_size = 0; - XcursorImage *img[CURSOR_MAX]; + XcursorImage *cursor_img[CURSOR_MAX]; Cursor cursors[CURSOR_MAX]; Cursor null_cursor; CursorShape current_cursor = CURSOR_ARROW; @@ -276,7 +337,7 @@ class DisplayServerX11 : public DisplayServer { bool _window_minimize_check(WindowID p_window) const; void _validate_mode_on_map(WindowID p_window); void _update_size_hints(WindowID p_window); - void _set_wm_fullscreen(WindowID p_window, bool p_enabled); + void _set_wm_fullscreen(WindowID p_window, bool p_enabled, bool p_exclusive); void _set_wm_maximized(WindowID p_window, bool p_enabled); void _set_wm_minimized(WindowID p_window, bool p_enabled); @@ -336,7 +397,7 @@ public: virtual void warp_mouse(const Point2i &p_position) override; virtual Point2i mouse_get_position() const override; - virtual MouseButton mouse_get_button_state() const override; + virtual BitField<MouseButtonMask> mouse_get_button_state() const override; virtual void clipboard_set(const String &p_text) override; virtual String clipboard_get() const override; @@ -344,11 +405,15 @@ public: virtual String clipboard_get_primary() const override; virtual int get_screen_count() const override; + virtual int get_primary_screen() const override; + virtual int get_keyboard_focus_screen() const override; virtual Point2i screen_get_position(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; virtual Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; virtual Rect2i screen_get_usable_rect(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; virtual int screen_get_dpi(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; virtual float screen_get_refresh_rate(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; + virtual Color screen_get_pixel(const Point2i &p_position) const override; + virtual Ref<Image> screen_get_image(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; #if defined(DBUS_ENABLED) virtual void screen_set_keep_on(bool p_enable) override; @@ -385,6 +450,7 @@ public: virtual void window_set_current_screen(int p_screen, WindowID p_window = MAIN_WINDOW_ID) override; virtual Point2i window_get_position(WindowID p_window = MAIN_WINDOW_ID) const override; + virtual Point2i window_get_position_with_decorations(WindowID p_window = MAIN_WINDOW_ID) const override; virtual void window_set_position(const Point2i &p_position, WindowID p_window = MAIN_WINDOW_ID) override; virtual void window_set_max_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID) override; @@ -398,7 +464,7 @@ public: virtual void window_set_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID) override; virtual Size2i window_get_size(WindowID p_window = MAIN_WINDOW_ID) const override; - virtual Size2i window_get_real_size(WindowID p_window = MAIN_WINDOW_ID) const override; + virtual Size2i window_get_size_with_decorations(WindowID p_window = MAIN_WINDOW_ID) const override; virtual void window_set_mode(WindowMode p_mode, WindowID p_window = MAIN_WINDOW_ID) override; virtual WindowMode window_get_mode(WindowID p_window = MAIN_WINDOW_ID) const override; @@ -411,6 +477,7 @@ public: virtual void window_request_attention(WindowID p_window = MAIN_WINDOW_ID) override; virtual void window_move_to_foreground(WindowID p_window = MAIN_WINDOW_ID) override; + virtual bool window_is_focused(WindowID p_window = MAIN_WINDOW_ID) const override; virtual bool window_can_draw(WindowID p_window = MAIN_WINDOW_ID) const override; @@ -419,6 +486,9 @@ public: virtual void window_set_ime_active(const bool p_active, WindowID p_window = MAIN_WINDOW_ID) override; virtual void window_set_ime_position(const Point2i &p_pos, WindowID p_window = MAIN_WINDOW_ID) override; + virtual Point2i ime_get_selection() const override; + virtual String ime_get_text() const override; + virtual void window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window = MAIN_WINDOW_ID) override; virtual DisplayServer::VSyncMode window_get_vsync_mode(WindowID p_vsync_mode) const override; @@ -444,15 +514,15 @@ public: virtual void set_native_icon(const String &p_filename) override; virtual void set_icon(const Ref<Image> &p_icon) override; - static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error); + static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error); static Vector<String> get_rendering_drivers_func(); static void register_x11_driver(); - DisplayServerX11(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error); + DisplayServerX11(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error); ~DisplayServerX11(); }; -#endif // X11 enabled +#endif // X11_ENABLED #endif // DISPLAY_SERVER_X11_H diff --git a/platform/linuxbsd/x11/dynwrappers/xcursor-so_wrap.c b/platform/linuxbsd/x11/dynwrappers/xcursor-so_wrap.c new file mode 100644 index 0000000000..bba21b9cb7 --- /dev/null +++ b/platform/linuxbsd/x11/dynwrappers/xcursor-so_wrap.c @@ -0,0 +1,676 @@ +// This file is generated. Do not edit! +// see https://github.com/hpvb/dynload-wrapper for details +// generated by generate-wrapper.py 0.3 on 2023-01-23 15:09:53 +// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/Xcursor/Xcursor.h --sys-include "thirdparty/linuxbsd_headers/X11/Xcursor/Xcursor.h" --soname libXcursor.so.1 --init-name xcursor --output-header ./platform/linuxbsd/x11/dynwrappers/xcursor-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xcursor-so_wrap.c +// +// NOTE: Generated from Xcursor 1.2.0. +// This has been handpatched to workaround some issues with the generator that +// will be eventually fixed. In this case, non-existent symbols inherited from +// libX11, but absent in libXcursor.so.1, were removed. +#include <stdint.h> + +#define XcursorImageCreate XcursorImageCreate_dylibloader_orig_xcursor +#define XcursorImageDestroy XcursorImageDestroy_dylibloader_orig_xcursor +#define XcursorImagesCreate XcursorImagesCreate_dylibloader_orig_xcursor +#define XcursorImagesDestroy XcursorImagesDestroy_dylibloader_orig_xcursor +#define XcursorImagesSetName XcursorImagesSetName_dylibloader_orig_xcursor +#define XcursorCursorsCreate XcursorCursorsCreate_dylibloader_orig_xcursor +#define XcursorCursorsDestroy XcursorCursorsDestroy_dylibloader_orig_xcursor +#define XcursorAnimateCreate XcursorAnimateCreate_dylibloader_orig_xcursor +#define XcursorAnimateDestroy XcursorAnimateDestroy_dylibloader_orig_xcursor +#define XcursorAnimateNext XcursorAnimateNext_dylibloader_orig_xcursor +#define XcursorCommentCreate XcursorCommentCreate_dylibloader_orig_xcursor +#define XcursorCommentDestroy XcursorCommentDestroy_dylibloader_orig_xcursor +#define XcursorCommentsCreate XcursorCommentsCreate_dylibloader_orig_xcursor +#define XcursorCommentsDestroy XcursorCommentsDestroy_dylibloader_orig_xcursor +#define XcursorXcFileLoadImage XcursorXcFileLoadImage_dylibloader_orig_xcursor +#define XcursorXcFileLoadImages XcursorXcFileLoadImages_dylibloader_orig_xcursor +#define XcursorXcFileLoadAllImages XcursorXcFileLoadAllImages_dylibloader_orig_xcursor +#define XcursorXcFileLoad XcursorXcFileLoad_dylibloader_orig_xcursor +#define XcursorXcFileSave XcursorXcFileSave_dylibloader_orig_xcursor +#define XcursorFileLoadImage XcursorFileLoadImage_dylibloader_orig_xcursor +#define XcursorFileLoadImages XcursorFileLoadImages_dylibloader_orig_xcursor +#define XcursorFileLoadAllImages XcursorFileLoadAllImages_dylibloader_orig_xcursor +#define XcursorFileLoad XcursorFileLoad_dylibloader_orig_xcursor +#define XcursorFileSaveImages XcursorFileSaveImages_dylibloader_orig_xcursor +#define XcursorFileSave XcursorFileSave_dylibloader_orig_xcursor +#define XcursorFilenameLoadImage XcursorFilenameLoadImage_dylibloader_orig_xcursor +#define XcursorFilenameLoadImages XcursorFilenameLoadImages_dylibloader_orig_xcursor +#define XcursorFilenameLoadAllImages XcursorFilenameLoadAllImages_dylibloader_orig_xcursor +#define XcursorFilenameLoad XcursorFilenameLoad_dylibloader_orig_xcursor +#define XcursorFilenameSaveImages XcursorFilenameSaveImages_dylibloader_orig_xcursor +#define XcursorFilenameSave XcursorFilenameSave_dylibloader_orig_xcursor +#define XcursorLibraryLoadImage XcursorLibraryLoadImage_dylibloader_orig_xcursor +#define XcursorLibraryLoadImages XcursorLibraryLoadImages_dylibloader_orig_xcursor +#define XcursorLibraryPath XcursorLibraryPath_dylibloader_orig_xcursor +#define XcursorLibraryShape XcursorLibraryShape_dylibloader_orig_xcursor +#define XcursorImageLoadCursor XcursorImageLoadCursor_dylibloader_orig_xcursor +#define XcursorImagesLoadCursors XcursorImagesLoadCursors_dylibloader_orig_xcursor +#define XcursorImagesLoadCursor XcursorImagesLoadCursor_dylibloader_orig_xcursor +#define XcursorFilenameLoadCursor XcursorFilenameLoadCursor_dylibloader_orig_xcursor +#define XcursorFilenameLoadCursors XcursorFilenameLoadCursors_dylibloader_orig_xcursor +#define XcursorLibraryLoadCursor XcursorLibraryLoadCursor_dylibloader_orig_xcursor +#define XcursorLibraryLoadCursors XcursorLibraryLoadCursors_dylibloader_orig_xcursor +#define XcursorShapeLoadImage XcursorShapeLoadImage_dylibloader_orig_xcursor +#define XcursorShapeLoadImages XcursorShapeLoadImages_dylibloader_orig_xcursor +#define XcursorShapeLoadCursor XcursorShapeLoadCursor_dylibloader_orig_xcursor +#define XcursorShapeLoadCursors XcursorShapeLoadCursors_dylibloader_orig_xcursor +#define XcursorTryShapeCursor XcursorTryShapeCursor_dylibloader_orig_xcursor +#define XcursorNoticeCreateBitmap XcursorNoticeCreateBitmap_dylibloader_orig_xcursor +#define XcursorNoticePutBitmap XcursorNoticePutBitmap_dylibloader_orig_xcursor +#define XcursorTryShapeBitmapCursor XcursorTryShapeBitmapCursor_dylibloader_orig_xcursor +#define XcursorImageHash XcursorImageHash_dylibloader_orig_xcursor +#define XcursorSupportsARGB XcursorSupportsARGB_dylibloader_orig_xcursor +#define XcursorSupportsAnim XcursorSupportsAnim_dylibloader_orig_xcursor +#define XcursorSetDefaultSize XcursorSetDefaultSize_dylibloader_orig_xcursor +#define XcursorGetDefaultSize XcursorGetDefaultSize_dylibloader_orig_xcursor +#define XcursorSetTheme XcursorSetTheme_dylibloader_orig_xcursor +#define XcursorGetTheme XcursorGetTheme_dylibloader_orig_xcursor +#define XcursorGetThemeCore XcursorGetThemeCore_dylibloader_orig_xcursor +#define XcursorSetThemeCore XcursorSetThemeCore_dylibloader_orig_xcursor +#include "thirdparty/linuxbsd_headers/X11/Xcursor/Xcursor.h" +#undef XcursorImageCreate +#undef XcursorImageDestroy +#undef XcursorImagesCreate +#undef XcursorImagesDestroy +#undef XcursorImagesSetName +#undef XcursorCursorsCreate +#undef XcursorCursorsDestroy +#undef XcursorAnimateCreate +#undef XcursorAnimateDestroy +#undef XcursorAnimateNext +#undef XcursorCommentCreate +#undef XcursorCommentDestroy +#undef XcursorCommentsCreate +#undef XcursorCommentsDestroy +#undef XcursorXcFileLoadImage +#undef XcursorXcFileLoadImages +#undef XcursorXcFileLoadAllImages +#undef XcursorXcFileLoad +#undef XcursorXcFileSave +#undef XcursorFileLoadImage +#undef XcursorFileLoadImages +#undef XcursorFileLoadAllImages +#undef XcursorFileLoad +#undef XcursorFileSaveImages +#undef XcursorFileSave +#undef XcursorFilenameLoadImage +#undef XcursorFilenameLoadImages +#undef XcursorFilenameLoadAllImages +#undef XcursorFilenameLoad +#undef XcursorFilenameSaveImages +#undef XcursorFilenameSave +#undef XcursorLibraryLoadImage +#undef XcursorLibraryLoadImages +#undef XcursorLibraryPath +#undef XcursorLibraryShape +#undef XcursorImageLoadCursor +#undef XcursorImagesLoadCursors +#undef XcursorImagesLoadCursor +#undef XcursorFilenameLoadCursor +#undef XcursorFilenameLoadCursors +#undef XcursorLibraryLoadCursor +#undef XcursorLibraryLoadCursors +#undef XcursorShapeLoadImage +#undef XcursorShapeLoadImages +#undef XcursorShapeLoadCursor +#undef XcursorShapeLoadCursors +#undef XcursorTryShapeCursor +#undef XcursorNoticeCreateBitmap +#undef XcursorNoticePutBitmap +#undef XcursorTryShapeBitmapCursor +#undef XcursorImageHash +#undef XcursorSupportsARGB +#undef XcursorSupportsAnim +#undef XcursorSetDefaultSize +#undef XcursorGetDefaultSize +#undef XcursorSetTheme +#undef XcursorGetTheme +#undef XcursorGetThemeCore +#undef XcursorSetThemeCore +#include <dlfcn.h> +#include <stdio.h> +XcursorImage* (*XcursorImageCreate_dylibloader_wrapper_xcursor)( int, int); +void (*XcursorImageDestroy_dylibloader_wrapper_xcursor)( XcursorImage*); +XcursorImages* (*XcursorImagesCreate_dylibloader_wrapper_xcursor)( int); +void (*XcursorImagesDestroy_dylibloader_wrapper_xcursor)( XcursorImages*); +void (*XcursorImagesSetName_dylibloader_wrapper_xcursor)( XcursorImages*,const char*); +XcursorCursors* (*XcursorCursorsCreate_dylibloader_wrapper_xcursor)( Display*, int); +void (*XcursorCursorsDestroy_dylibloader_wrapper_xcursor)( XcursorCursors*); +XcursorAnimate* (*XcursorAnimateCreate_dylibloader_wrapper_xcursor)( XcursorCursors*); +void (*XcursorAnimateDestroy_dylibloader_wrapper_xcursor)( XcursorAnimate*); +Cursor (*XcursorAnimateNext_dylibloader_wrapper_xcursor)( XcursorAnimate*); +XcursorComment* (*XcursorCommentCreate_dylibloader_wrapper_xcursor)( XcursorUInt, int); +void (*XcursorCommentDestroy_dylibloader_wrapper_xcursor)( XcursorComment*); +XcursorComments* (*XcursorCommentsCreate_dylibloader_wrapper_xcursor)( int); +void (*XcursorCommentsDestroy_dylibloader_wrapper_xcursor)( XcursorComments*); +XcursorImage* (*XcursorXcFileLoadImage_dylibloader_wrapper_xcursor)( XcursorFile*, int); +XcursorImages* (*XcursorXcFileLoadImages_dylibloader_wrapper_xcursor)( XcursorFile*, int); +XcursorImages* (*XcursorXcFileLoadAllImages_dylibloader_wrapper_xcursor)( XcursorFile*); +XcursorBool (*XcursorXcFileLoad_dylibloader_wrapper_xcursor)( XcursorFile*, XcursorComments**, XcursorImages**); +XcursorBool (*XcursorXcFileSave_dylibloader_wrapper_xcursor)( XcursorFile*,const XcursorComments*,const XcursorImages*); +XcursorImage* (*XcursorFileLoadImage_dylibloader_wrapper_xcursor)( FILE*, int); +XcursorImages* (*XcursorFileLoadImages_dylibloader_wrapper_xcursor)( FILE*, int); +XcursorImages* (*XcursorFileLoadAllImages_dylibloader_wrapper_xcursor)( FILE*); +XcursorBool (*XcursorFileLoad_dylibloader_wrapper_xcursor)( FILE*, XcursorComments**, XcursorImages**); +XcursorBool (*XcursorFileSaveImages_dylibloader_wrapper_xcursor)( FILE*,const XcursorImages*); +XcursorBool (*XcursorFileSave_dylibloader_wrapper_xcursor)( FILE*,const XcursorComments*,const XcursorImages*); +XcursorImage* (*XcursorFilenameLoadImage_dylibloader_wrapper_xcursor)(const char*, int); +XcursorImages* (*XcursorFilenameLoadImages_dylibloader_wrapper_xcursor)(const char*, int); +XcursorImages* (*XcursorFilenameLoadAllImages_dylibloader_wrapper_xcursor)(const char*); +XcursorBool (*XcursorFilenameLoad_dylibloader_wrapper_xcursor)(const char*, XcursorComments**, XcursorImages**); +XcursorBool (*XcursorFilenameSaveImages_dylibloader_wrapper_xcursor)(const char*,const XcursorImages*); +XcursorBool (*XcursorFilenameSave_dylibloader_wrapper_xcursor)(const char*,const XcursorComments*,const XcursorImages*); +XcursorImage* (*XcursorLibraryLoadImage_dylibloader_wrapper_xcursor)(const char*,const char*, int); +XcursorImages* (*XcursorLibraryLoadImages_dylibloader_wrapper_xcursor)(const char*,const char*, int); +const char* (*XcursorLibraryPath_dylibloader_wrapper_xcursor)( void); +int (*XcursorLibraryShape_dylibloader_wrapper_xcursor)(const char*); +Cursor (*XcursorImageLoadCursor_dylibloader_wrapper_xcursor)( Display*,const XcursorImage*); +XcursorCursors* (*XcursorImagesLoadCursors_dylibloader_wrapper_xcursor)( Display*,const XcursorImages*); +Cursor (*XcursorImagesLoadCursor_dylibloader_wrapper_xcursor)( Display*,const XcursorImages*); +Cursor (*XcursorFilenameLoadCursor_dylibloader_wrapper_xcursor)( Display*,const char*); +XcursorCursors* (*XcursorFilenameLoadCursors_dylibloader_wrapper_xcursor)( Display*,const char*); +Cursor (*XcursorLibraryLoadCursor_dylibloader_wrapper_xcursor)( Display*,const char*); +XcursorCursors* (*XcursorLibraryLoadCursors_dylibloader_wrapper_xcursor)( Display*,const char*); +XcursorImage* (*XcursorShapeLoadImage_dylibloader_wrapper_xcursor)( unsigned int,const char*, int); +XcursorImages* (*XcursorShapeLoadImages_dylibloader_wrapper_xcursor)( unsigned int,const char*, int); +Cursor (*XcursorShapeLoadCursor_dylibloader_wrapper_xcursor)( Display*, unsigned int); +XcursorCursors* (*XcursorShapeLoadCursors_dylibloader_wrapper_xcursor)( Display*, unsigned int); +Cursor (*XcursorTryShapeCursor_dylibloader_wrapper_xcursor)( Display*, Font, Font, unsigned int, unsigned int,const XColor*,const XColor*); +void (*XcursorNoticeCreateBitmap_dylibloader_wrapper_xcursor)( Display*, Pixmap, unsigned int, unsigned int); +void (*XcursorNoticePutBitmap_dylibloader_wrapper_xcursor)( Display*, Drawable, XImage*); +Cursor (*XcursorTryShapeBitmapCursor_dylibloader_wrapper_xcursor)( Display*, Pixmap, Pixmap, XColor*, XColor*, unsigned int, unsigned int); +void (*XcursorImageHash_dylibloader_wrapper_xcursor)( XImage*, unsigned char [16]); +XcursorBool (*XcursorSupportsARGB_dylibloader_wrapper_xcursor)( Display*); +XcursorBool (*XcursorSupportsAnim_dylibloader_wrapper_xcursor)( Display*); +XcursorBool (*XcursorSetDefaultSize_dylibloader_wrapper_xcursor)( Display*, int); +int (*XcursorGetDefaultSize_dylibloader_wrapper_xcursor)( Display*); +XcursorBool (*XcursorSetTheme_dylibloader_wrapper_xcursor)( Display*,const char*); +char* (*XcursorGetTheme_dylibloader_wrapper_xcursor)( Display*); +XcursorBool (*XcursorGetThemeCore_dylibloader_wrapper_xcursor)( Display*); +XcursorBool (*XcursorSetThemeCore_dylibloader_wrapper_xcursor)( Display*, XcursorBool); +int initialize_xcursor(int verbose) { + void *handle; + char *error; + handle = dlopen("libXcursor.so.1", RTLD_LAZY); + if (!handle) { + if (verbose) { + fprintf(stderr, "%s\n", dlerror()); + } + return(1); + } + dlerror(); +// XcursorImageCreate + *(void **) (&XcursorImageCreate_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorImageCreate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorImageDestroy + *(void **) (&XcursorImageDestroy_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorImageDestroy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorImagesCreate + *(void **) (&XcursorImagesCreate_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorImagesCreate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorImagesDestroy + *(void **) (&XcursorImagesDestroy_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorImagesDestroy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorImagesSetName + *(void **) (&XcursorImagesSetName_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorImagesSetName"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorCursorsCreate + *(void **) (&XcursorCursorsCreate_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorCursorsCreate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorCursorsDestroy + *(void **) (&XcursorCursorsDestroy_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorCursorsDestroy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorAnimateCreate + *(void **) (&XcursorAnimateCreate_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorAnimateCreate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorAnimateDestroy + *(void **) (&XcursorAnimateDestroy_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorAnimateDestroy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorAnimateNext + *(void **) (&XcursorAnimateNext_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorAnimateNext"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorCommentCreate + *(void **) (&XcursorCommentCreate_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorCommentCreate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorCommentDestroy + *(void **) (&XcursorCommentDestroy_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorCommentDestroy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorCommentsCreate + *(void **) (&XcursorCommentsCreate_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorCommentsCreate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorCommentsDestroy + *(void **) (&XcursorCommentsDestroy_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorCommentsDestroy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorXcFileLoadImage + *(void **) (&XcursorXcFileLoadImage_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorXcFileLoadImage"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorXcFileLoadImages + *(void **) (&XcursorXcFileLoadImages_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorXcFileLoadImages"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorXcFileLoadAllImages + *(void **) (&XcursorXcFileLoadAllImages_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorXcFileLoadAllImages"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorXcFileLoad + *(void **) (&XcursorXcFileLoad_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorXcFileLoad"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorXcFileSave + *(void **) (&XcursorXcFileSave_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorXcFileSave"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorFileLoadImage + *(void **) (&XcursorFileLoadImage_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorFileLoadImage"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorFileLoadImages + *(void **) (&XcursorFileLoadImages_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorFileLoadImages"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorFileLoadAllImages + *(void **) (&XcursorFileLoadAllImages_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorFileLoadAllImages"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorFileLoad + *(void **) (&XcursorFileLoad_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorFileLoad"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorFileSaveImages + *(void **) (&XcursorFileSaveImages_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorFileSaveImages"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorFileSave + *(void **) (&XcursorFileSave_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorFileSave"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorFilenameLoadImage + *(void **) (&XcursorFilenameLoadImage_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorFilenameLoadImage"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorFilenameLoadImages + *(void **) (&XcursorFilenameLoadImages_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorFilenameLoadImages"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorFilenameLoadAllImages + *(void **) (&XcursorFilenameLoadAllImages_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorFilenameLoadAllImages"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorFilenameLoad + *(void **) (&XcursorFilenameLoad_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorFilenameLoad"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorFilenameSaveImages + *(void **) (&XcursorFilenameSaveImages_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorFilenameSaveImages"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorFilenameSave + *(void **) (&XcursorFilenameSave_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorFilenameSave"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorLibraryLoadImage + *(void **) (&XcursorLibraryLoadImage_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorLibraryLoadImage"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorLibraryLoadImages + *(void **) (&XcursorLibraryLoadImages_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorLibraryLoadImages"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorLibraryPath + *(void **) (&XcursorLibraryPath_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorLibraryPath"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorLibraryShape + *(void **) (&XcursorLibraryShape_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorLibraryShape"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorImageLoadCursor + *(void **) (&XcursorImageLoadCursor_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorImageLoadCursor"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorImagesLoadCursors + *(void **) (&XcursorImagesLoadCursors_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorImagesLoadCursors"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorImagesLoadCursor + *(void **) (&XcursorImagesLoadCursor_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorImagesLoadCursor"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorFilenameLoadCursor + *(void **) (&XcursorFilenameLoadCursor_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorFilenameLoadCursor"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorFilenameLoadCursors + *(void **) (&XcursorFilenameLoadCursors_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorFilenameLoadCursors"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorLibraryLoadCursor + *(void **) (&XcursorLibraryLoadCursor_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorLibraryLoadCursor"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorLibraryLoadCursors + *(void **) (&XcursorLibraryLoadCursors_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorLibraryLoadCursors"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorShapeLoadImage + *(void **) (&XcursorShapeLoadImage_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorShapeLoadImage"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorShapeLoadImages + *(void **) (&XcursorShapeLoadImages_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorShapeLoadImages"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorShapeLoadCursor + *(void **) (&XcursorShapeLoadCursor_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorShapeLoadCursor"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorShapeLoadCursors + *(void **) (&XcursorShapeLoadCursors_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorShapeLoadCursors"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorTryShapeCursor + *(void **) (&XcursorTryShapeCursor_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorTryShapeCursor"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorNoticeCreateBitmap + *(void **) (&XcursorNoticeCreateBitmap_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorNoticeCreateBitmap"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorNoticePutBitmap + *(void **) (&XcursorNoticePutBitmap_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorNoticePutBitmap"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorTryShapeBitmapCursor + *(void **) (&XcursorTryShapeBitmapCursor_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorTryShapeBitmapCursor"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorImageHash + *(void **) (&XcursorImageHash_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorImageHash"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorSupportsARGB + *(void **) (&XcursorSupportsARGB_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorSupportsARGB"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorSupportsAnim + *(void **) (&XcursorSupportsAnim_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorSupportsAnim"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorSetDefaultSize + *(void **) (&XcursorSetDefaultSize_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorSetDefaultSize"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorGetDefaultSize + *(void **) (&XcursorGetDefaultSize_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorGetDefaultSize"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorSetTheme + *(void **) (&XcursorSetTheme_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorSetTheme"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorGetTheme + *(void **) (&XcursorGetTheme_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorGetTheme"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorGetThemeCore + *(void **) (&XcursorGetThemeCore_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorGetThemeCore"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XcursorSetThemeCore + *(void **) (&XcursorSetThemeCore_dylibloader_wrapper_xcursor) = dlsym(handle, "XcursorSetThemeCore"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +return 0; +} diff --git a/platform/linuxbsd/x11/dynwrappers/xcursor-so_wrap.h b/platform/linuxbsd/x11/dynwrappers/xcursor-so_wrap.h new file mode 100644 index 0000000000..9f8d8bbca2 --- /dev/null +++ b/platform/linuxbsd/x11/dynwrappers/xcursor-so_wrap.h @@ -0,0 +1,258 @@ +#ifndef DYLIBLOAD_WRAPPER_XCURSOR +#define DYLIBLOAD_WRAPPER_XCURSOR +// This file is generated. Do not edit! +// see https://github.com/hpvb/dynload-wrapper for details +// generated by generate-wrapper.py 0.3 on 2023-01-23 15:09:53 +// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/Xcursor/Xcursor.h --sys-include "thirdparty/linuxbsd_headers/X11/Xcursor/Xcursor.h" --soname libXcursor.so.1 --init-name xcursor --output-header ./platform/linuxbsd/x11/dynwrappers/xcursor-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xcursor-so_wrap.c +// +// NOTE: Generated from Xcursor 1.2.0. +// This has been handpatched to workaround some issues with the generator that +// will be eventually fixed. In this case, non-existent symbols inherited from +// libX11, but absent in libXcursor.so.1, were removed. +#include <stdint.h> + +#define XcursorImageCreate XcursorImageCreate_dylibloader_orig_xcursor +#define XcursorImageDestroy XcursorImageDestroy_dylibloader_orig_xcursor +#define XcursorImagesCreate XcursorImagesCreate_dylibloader_orig_xcursor +#define XcursorImagesDestroy XcursorImagesDestroy_dylibloader_orig_xcursor +#define XcursorImagesSetName XcursorImagesSetName_dylibloader_orig_xcursor +#define XcursorCursorsCreate XcursorCursorsCreate_dylibloader_orig_xcursor +#define XcursorCursorsDestroy XcursorCursorsDestroy_dylibloader_orig_xcursor +#define XcursorAnimateCreate XcursorAnimateCreate_dylibloader_orig_xcursor +#define XcursorAnimateDestroy XcursorAnimateDestroy_dylibloader_orig_xcursor +#define XcursorAnimateNext XcursorAnimateNext_dylibloader_orig_xcursor +#define XcursorCommentCreate XcursorCommentCreate_dylibloader_orig_xcursor +#define XcursorCommentDestroy XcursorCommentDestroy_dylibloader_orig_xcursor +#define XcursorCommentsCreate XcursorCommentsCreate_dylibloader_orig_xcursor +#define XcursorCommentsDestroy XcursorCommentsDestroy_dylibloader_orig_xcursor +#define XcursorXcFileLoadImage XcursorXcFileLoadImage_dylibloader_orig_xcursor +#define XcursorXcFileLoadImages XcursorXcFileLoadImages_dylibloader_orig_xcursor +#define XcursorXcFileLoadAllImages XcursorXcFileLoadAllImages_dylibloader_orig_xcursor +#define XcursorXcFileLoad XcursorXcFileLoad_dylibloader_orig_xcursor +#define XcursorXcFileSave XcursorXcFileSave_dylibloader_orig_xcursor +#define XcursorFileLoadImage XcursorFileLoadImage_dylibloader_orig_xcursor +#define XcursorFileLoadImages XcursorFileLoadImages_dylibloader_orig_xcursor +#define XcursorFileLoadAllImages XcursorFileLoadAllImages_dylibloader_orig_xcursor +#define XcursorFileLoad XcursorFileLoad_dylibloader_orig_xcursor +#define XcursorFileSaveImages XcursorFileSaveImages_dylibloader_orig_xcursor +#define XcursorFileSave XcursorFileSave_dylibloader_orig_xcursor +#define XcursorFilenameLoadImage XcursorFilenameLoadImage_dylibloader_orig_xcursor +#define XcursorFilenameLoadImages XcursorFilenameLoadImages_dylibloader_orig_xcursor +#define XcursorFilenameLoadAllImages XcursorFilenameLoadAllImages_dylibloader_orig_xcursor +#define XcursorFilenameLoad XcursorFilenameLoad_dylibloader_orig_xcursor +#define XcursorFilenameSaveImages XcursorFilenameSaveImages_dylibloader_orig_xcursor +#define XcursorFilenameSave XcursorFilenameSave_dylibloader_orig_xcursor +#define XcursorLibraryLoadImage XcursorLibraryLoadImage_dylibloader_orig_xcursor +#define XcursorLibraryLoadImages XcursorLibraryLoadImages_dylibloader_orig_xcursor +#define XcursorLibraryPath XcursorLibraryPath_dylibloader_orig_xcursor +#define XcursorLibraryShape XcursorLibraryShape_dylibloader_orig_xcursor +#define XcursorImageLoadCursor XcursorImageLoadCursor_dylibloader_orig_xcursor +#define XcursorImagesLoadCursors XcursorImagesLoadCursors_dylibloader_orig_xcursor +#define XcursorImagesLoadCursor XcursorImagesLoadCursor_dylibloader_orig_xcursor +#define XcursorFilenameLoadCursor XcursorFilenameLoadCursor_dylibloader_orig_xcursor +#define XcursorFilenameLoadCursors XcursorFilenameLoadCursors_dylibloader_orig_xcursor +#define XcursorLibraryLoadCursor XcursorLibraryLoadCursor_dylibloader_orig_xcursor +#define XcursorLibraryLoadCursors XcursorLibraryLoadCursors_dylibloader_orig_xcursor +#define XcursorShapeLoadImage XcursorShapeLoadImage_dylibloader_orig_xcursor +#define XcursorShapeLoadImages XcursorShapeLoadImages_dylibloader_orig_xcursor +#define XcursorShapeLoadCursor XcursorShapeLoadCursor_dylibloader_orig_xcursor +#define XcursorShapeLoadCursors XcursorShapeLoadCursors_dylibloader_orig_xcursor +#define XcursorTryShapeCursor XcursorTryShapeCursor_dylibloader_orig_xcursor +#define XcursorNoticeCreateBitmap XcursorNoticeCreateBitmap_dylibloader_orig_xcursor +#define XcursorNoticePutBitmap XcursorNoticePutBitmap_dylibloader_orig_xcursor +#define XcursorTryShapeBitmapCursor XcursorTryShapeBitmapCursor_dylibloader_orig_xcursor +#define XcursorImageHash XcursorImageHash_dylibloader_orig_xcursor +#define XcursorSupportsARGB XcursorSupportsARGB_dylibloader_orig_xcursor +#define XcursorSupportsAnim XcursorSupportsAnim_dylibloader_orig_xcursor +#define XcursorSetDefaultSize XcursorSetDefaultSize_dylibloader_orig_xcursor +#define XcursorGetDefaultSize XcursorGetDefaultSize_dylibloader_orig_xcursor +#define XcursorSetTheme XcursorSetTheme_dylibloader_orig_xcursor +#define XcursorGetTheme XcursorGetTheme_dylibloader_orig_xcursor +#define XcursorGetThemeCore XcursorGetThemeCore_dylibloader_orig_xcursor +#define XcursorSetThemeCore XcursorSetThemeCore_dylibloader_orig_xcursor +#include "thirdparty/linuxbsd_headers/X11/Xcursor/Xcursor.h" +#undef XcursorImageCreate +#undef XcursorImageDestroy +#undef XcursorImagesCreate +#undef XcursorImagesDestroy +#undef XcursorImagesSetName +#undef XcursorCursorsCreate +#undef XcursorCursorsDestroy +#undef XcursorAnimateCreate +#undef XcursorAnimateDestroy +#undef XcursorAnimateNext +#undef XcursorCommentCreate +#undef XcursorCommentDestroy +#undef XcursorCommentsCreate +#undef XcursorCommentsDestroy +#undef XcursorXcFileLoadImage +#undef XcursorXcFileLoadImages +#undef XcursorXcFileLoadAllImages +#undef XcursorXcFileLoad +#undef XcursorXcFileSave +#undef XcursorFileLoadImage +#undef XcursorFileLoadImages +#undef XcursorFileLoadAllImages +#undef XcursorFileLoad +#undef XcursorFileSaveImages +#undef XcursorFileSave +#undef XcursorFilenameLoadImage +#undef XcursorFilenameLoadImages +#undef XcursorFilenameLoadAllImages +#undef XcursorFilenameLoad +#undef XcursorFilenameSaveImages +#undef XcursorFilenameSave +#undef XcursorLibraryLoadImage +#undef XcursorLibraryLoadImages +#undef XcursorLibraryPath +#undef XcursorLibraryShape +#undef XcursorImageLoadCursor +#undef XcursorImagesLoadCursors +#undef XcursorImagesLoadCursor +#undef XcursorFilenameLoadCursor +#undef XcursorFilenameLoadCursors +#undef XcursorLibraryLoadCursor +#undef XcursorLibraryLoadCursors +#undef XcursorShapeLoadImage +#undef XcursorShapeLoadImages +#undef XcursorShapeLoadCursor +#undef XcursorShapeLoadCursors +#undef XcursorTryShapeCursor +#undef XcursorNoticeCreateBitmap +#undef XcursorNoticePutBitmap +#undef XcursorTryShapeBitmapCursor +#undef XcursorImageHash +#undef XcursorSupportsARGB +#undef XcursorSupportsAnim +#undef XcursorSetDefaultSize +#undef XcursorGetDefaultSize +#undef XcursorSetTheme +#undef XcursorGetTheme +#undef XcursorGetThemeCore +#undef XcursorSetThemeCore +#ifdef __cplusplus +extern "C" { +#endif +#define XcursorImageCreate XcursorImageCreate_dylibloader_wrapper_xcursor +#define XcursorImageDestroy XcursorImageDestroy_dylibloader_wrapper_xcursor +#define XcursorImagesCreate XcursorImagesCreate_dylibloader_wrapper_xcursor +#define XcursorImagesDestroy XcursorImagesDestroy_dylibloader_wrapper_xcursor +#define XcursorImagesSetName XcursorImagesSetName_dylibloader_wrapper_xcursor +#define XcursorCursorsCreate XcursorCursorsCreate_dylibloader_wrapper_xcursor +#define XcursorCursorsDestroy XcursorCursorsDestroy_dylibloader_wrapper_xcursor +#define XcursorAnimateCreate XcursorAnimateCreate_dylibloader_wrapper_xcursor +#define XcursorAnimateDestroy XcursorAnimateDestroy_dylibloader_wrapper_xcursor +#define XcursorAnimateNext XcursorAnimateNext_dylibloader_wrapper_xcursor +#define XcursorCommentCreate XcursorCommentCreate_dylibloader_wrapper_xcursor +#define XcursorCommentDestroy XcursorCommentDestroy_dylibloader_wrapper_xcursor +#define XcursorCommentsCreate XcursorCommentsCreate_dylibloader_wrapper_xcursor +#define XcursorCommentsDestroy XcursorCommentsDestroy_dylibloader_wrapper_xcursor +#define XcursorXcFileLoadImage XcursorXcFileLoadImage_dylibloader_wrapper_xcursor +#define XcursorXcFileLoadImages XcursorXcFileLoadImages_dylibloader_wrapper_xcursor +#define XcursorXcFileLoadAllImages XcursorXcFileLoadAllImages_dylibloader_wrapper_xcursor +#define XcursorXcFileLoad XcursorXcFileLoad_dylibloader_wrapper_xcursor +#define XcursorXcFileSave XcursorXcFileSave_dylibloader_wrapper_xcursor +#define XcursorFileLoadImage XcursorFileLoadImage_dylibloader_wrapper_xcursor +#define XcursorFileLoadImages XcursorFileLoadImages_dylibloader_wrapper_xcursor +#define XcursorFileLoadAllImages XcursorFileLoadAllImages_dylibloader_wrapper_xcursor +#define XcursorFileLoad XcursorFileLoad_dylibloader_wrapper_xcursor +#define XcursorFileSaveImages XcursorFileSaveImages_dylibloader_wrapper_xcursor +#define XcursorFileSave XcursorFileSave_dylibloader_wrapper_xcursor +#define XcursorFilenameLoadImage XcursorFilenameLoadImage_dylibloader_wrapper_xcursor +#define XcursorFilenameLoadImages XcursorFilenameLoadImages_dylibloader_wrapper_xcursor +#define XcursorFilenameLoadAllImages XcursorFilenameLoadAllImages_dylibloader_wrapper_xcursor +#define XcursorFilenameLoad XcursorFilenameLoad_dylibloader_wrapper_xcursor +#define XcursorFilenameSaveImages XcursorFilenameSaveImages_dylibloader_wrapper_xcursor +#define XcursorFilenameSave XcursorFilenameSave_dylibloader_wrapper_xcursor +#define XcursorLibraryLoadImage XcursorLibraryLoadImage_dylibloader_wrapper_xcursor +#define XcursorLibraryLoadImages XcursorLibraryLoadImages_dylibloader_wrapper_xcursor +#define XcursorLibraryPath XcursorLibraryPath_dylibloader_wrapper_xcursor +#define XcursorLibraryShape XcursorLibraryShape_dylibloader_wrapper_xcursor +#define XcursorImageLoadCursor XcursorImageLoadCursor_dylibloader_wrapper_xcursor +#define XcursorImagesLoadCursors XcursorImagesLoadCursors_dylibloader_wrapper_xcursor +#define XcursorImagesLoadCursor XcursorImagesLoadCursor_dylibloader_wrapper_xcursor +#define XcursorFilenameLoadCursor XcursorFilenameLoadCursor_dylibloader_wrapper_xcursor +#define XcursorFilenameLoadCursors XcursorFilenameLoadCursors_dylibloader_wrapper_xcursor +#define XcursorLibraryLoadCursor XcursorLibraryLoadCursor_dylibloader_wrapper_xcursor +#define XcursorLibraryLoadCursors XcursorLibraryLoadCursors_dylibloader_wrapper_xcursor +#define XcursorShapeLoadImage XcursorShapeLoadImage_dylibloader_wrapper_xcursor +#define XcursorShapeLoadImages XcursorShapeLoadImages_dylibloader_wrapper_xcursor +#define XcursorShapeLoadCursor XcursorShapeLoadCursor_dylibloader_wrapper_xcursor +#define XcursorShapeLoadCursors XcursorShapeLoadCursors_dylibloader_wrapper_xcursor +#define XcursorTryShapeCursor XcursorTryShapeCursor_dylibloader_wrapper_xcursor +#define XcursorNoticeCreateBitmap XcursorNoticeCreateBitmap_dylibloader_wrapper_xcursor +#define XcursorNoticePutBitmap XcursorNoticePutBitmap_dylibloader_wrapper_xcursor +#define XcursorTryShapeBitmapCursor XcursorTryShapeBitmapCursor_dylibloader_wrapper_xcursor +#define XcursorImageHash XcursorImageHash_dylibloader_wrapper_xcursor +#define XcursorSupportsARGB XcursorSupportsARGB_dylibloader_wrapper_xcursor +#define XcursorSupportsAnim XcursorSupportsAnim_dylibloader_wrapper_xcursor +#define XcursorSetDefaultSize XcursorSetDefaultSize_dylibloader_wrapper_xcursor +#define XcursorGetDefaultSize XcursorGetDefaultSize_dylibloader_wrapper_xcursor +#define XcursorSetTheme XcursorSetTheme_dylibloader_wrapper_xcursor +#define XcursorGetTheme XcursorGetTheme_dylibloader_wrapper_xcursor +#define XcursorGetThemeCore XcursorGetThemeCore_dylibloader_wrapper_xcursor +#define XcursorSetThemeCore XcursorSetThemeCore_dylibloader_wrapper_xcursor +extern XcursorImage* (*XcursorImageCreate_dylibloader_wrapper_xcursor)( int, int); +extern void (*XcursorImageDestroy_dylibloader_wrapper_xcursor)( XcursorImage*); +extern XcursorImages* (*XcursorImagesCreate_dylibloader_wrapper_xcursor)( int); +extern void (*XcursorImagesDestroy_dylibloader_wrapper_xcursor)( XcursorImages*); +extern void (*XcursorImagesSetName_dylibloader_wrapper_xcursor)( XcursorImages*,const char*); +extern XcursorCursors* (*XcursorCursorsCreate_dylibloader_wrapper_xcursor)( Display*, int); +extern void (*XcursorCursorsDestroy_dylibloader_wrapper_xcursor)( XcursorCursors*); +extern XcursorAnimate* (*XcursorAnimateCreate_dylibloader_wrapper_xcursor)( XcursorCursors*); +extern void (*XcursorAnimateDestroy_dylibloader_wrapper_xcursor)( XcursorAnimate*); +extern Cursor (*XcursorAnimateNext_dylibloader_wrapper_xcursor)( XcursorAnimate*); +extern XcursorComment* (*XcursorCommentCreate_dylibloader_wrapper_xcursor)( XcursorUInt, int); +extern void (*XcursorCommentDestroy_dylibloader_wrapper_xcursor)( XcursorComment*); +extern XcursorComments* (*XcursorCommentsCreate_dylibloader_wrapper_xcursor)( int); +extern void (*XcursorCommentsDestroy_dylibloader_wrapper_xcursor)( XcursorComments*); +extern XcursorImage* (*XcursorXcFileLoadImage_dylibloader_wrapper_xcursor)( XcursorFile*, int); +extern XcursorImages* (*XcursorXcFileLoadImages_dylibloader_wrapper_xcursor)( XcursorFile*, int); +extern XcursorImages* (*XcursorXcFileLoadAllImages_dylibloader_wrapper_xcursor)( XcursorFile*); +extern XcursorBool (*XcursorXcFileLoad_dylibloader_wrapper_xcursor)( XcursorFile*, XcursorComments**, XcursorImages**); +extern XcursorBool (*XcursorXcFileSave_dylibloader_wrapper_xcursor)( XcursorFile*,const XcursorComments*,const XcursorImages*); +extern XcursorImage* (*XcursorFileLoadImage_dylibloader_wrapper_xcursor)( FILE*, int); +extern XcursorImages* (*XcursorFileLoadImages_dylibloader_wrapper_xcursor)( FILE*, int); +extern XcursorImages* (*XcursorFileLoadAllImages_dylibloader_wrapper_xcursor)( FILE*); +extern XcursorBool (*XcursorFileLoad_dylibloader_wrapper_xcursor)( FILE*, XcursorComments**, XcursorImages**); +extern XcursorBool (*XcursorFileSaveImages_dylibloader_wrapper_xcursor)( FILE*,const XcursorImages*); +extern XcursorBool (*XcursorFileSave_dylibloader_wrapper_xcursor)( FILE*,const XcursorComments*,const XcursorImages*); +extern XcursorImage* (*XcursorFilenameLoadImage_dylibloader_wrapper_xcursor)(const char*, int); +extern XcursorImages* (*XcursorFilenameLoadImages_dylibloader_wrapper_xcursor)(const char*, int); +extern XcursorImages* (*XcursorFilenameLoadAllImages_dylibloader_wrapper_xcursor)(const char*); +extern XcursorBool (*XcursorFilenameLoad_dylibloader_wrapper_xcursor)(const char*, XcursorComments**, XcursorImages**); +extern XcursorBool (*XcursorFilenameSaveImages_dylibloader_wrapper_xcursor)(const char*,const XcursorImages*); +extern XcursorBool (*XcursorFilenameSave_dylibloader_wrapper_xcursor)(const char*,const XcursorComments*,const XcursorImages*); +extern XcursorImage* (*XcursorLibraryLoadImage_dylibloader_wrapper_xcursor)(const char*,const char*, int); +extern XcursorImages* (*XcursorLibraryLoadImages_dylibloader_wrapper_xcursor)(const char*,const char*, int); +extern const char* (*XcursorLibraryPath_dylibloader_wrapper_xcursor)( void); +extern int (*XcursorLibraryShape_dylibloader_wrapper_xcursor)(const char*); +extern Cursor (*XcursorImageLoadCursor_dylibloader_wrapper_xcursor)( Display*,const XcursorImage*); +extern XcursorCursors* (*XcursorImagesLoadCursors_dylibloader_wrapper_xcursor)( Display*,const XcursorImages*); +extern Cursor (*XcursorImagesLoadCursor_dylibloader_wrapper_xcursor)( Display*,const XcursorImages*); +extern Cursor (*XcursorFilenameLoadCursor_dylibloader_wrapper_xcursor)( Display*,const char*); +extern XcursorCursors* (*XcursorFilenameLoadCursors_dylibloader_wrapper_xcursor)( Display*,const char*); +extern Cursor (*XcursorLibraryLoadCursor_dylibloader_wrapper_xcursor)( Display*,const char*); +extern XcursorCursors* (*XcursorLibraryLoadCursors_dylibloader_wrapper_xcursor)( Display*,const char*); +extern XcursorImage* (*XcursorShapeLoadImage_dylibloader_wrapper_xcursor)( unsigned int,const char*, int); +extern XcursorImages* (*XcursorShapeLoadImages_dylibloader_wrapper_xcursor)( unsigned int,const char*, int); +extern Cursor (*XcursorShapeLoadCursor_dylibloader_wrapper_xcursor)( Display*, unsigned int); +extern XcursorCursors* (*XcursorShapeLoadCursors_dylibloader_wrapper_xcursor)( Display*, unsigned int); +extern Cursor (*XcursorTryShapeCursor_dylibloader_wrapper_xcursor)( Display*, Font, Font, unsigned int, unsigned int,const XColor*,const XColor*); +extern void (*XcursorNoticeCreateBitmap_dylibloader_wrapper_xcursor)( Display*, Pixmap, unsigned int, unsigned int); +extern void (*XcursorNoticePutBitmap_dylibloader_wrapper_xcursor)( Display*, Drawable, XImage*); +extern Cursor (*XcursorTryShapeBitmapCursor_dylibloader_wrapper_xcursor)( Display*, Pixmap, Pixmap, XColor*, XColor*, unsigned int, unsigned int); +extern void (*XcursorImageHash_dylibloader_wrapper_xcursor)( XImage*, unsigned char [16]); +extern XcursorBool (*XcursorSupportsARGB_dylibloader_wrapper_xcursor)( Display*); +extern XcursorBool (*XcursorSupportsAnim_dylibloader_wrapper_xcursor)( Display*); +extern XcursorBool (*XcursorSetDefaultSize_dylibloader_wrapper_xcursor)( Display*, int); +extern int (*XcursorGetDefaultSize_dylibloader_wrapper_xcursor)( Display*); +extern XcursorBool (*XcursorSetTheme_dylibloader_wrapper_xcursor)( Display*,const char*); +extern char* (*XcursorGetTheme_dylibloader_wrapper_xcursor)( Display*); +extern XcursorBool (*XcursorGetThemeCore_dylibloader_wrapper_xcursor)( Display*); +extern XcursorBool (*XcursorSetThemeCore_dylibloader_wrapper_xcursor)( Display*, XcursorBool); +int initialize_xcursor(int verbose); +#ifdef __cplusplus +} +#endif +#endif diff --git a/platform/linuxbsd/x11/dynwrappers/xext-so_wrap.c b/platform/linuxbsd/x11/dynwrappers/xext-so_wrap.c new file mode 100644 index 0000000000..4e3349c574 --- /dev/null +++ b/platform/linuxbsd/x11/dynwrappers/xext-so_wrap.c @@ -0,0 +1,154 @@ +// This file is generated. Do not edit! +// see https://github.com/hpvb/dynload-wrapper for details +// generated by generate-wrapper.py 0.3 on 2023-01-23 15:11:29 +// flags: generate-wrapper.py --sys-include "thirdparty/linuxbsd_headers/X11/extensions/Xext.h" --include ./thirdparty/linuxbsd_headers/X11/extensions/shape.h --sys-include "thirdparty/linuxbsd_headers/X11/extensions/shape.h" --soname libXext.so.6 --init-name xext --output-header ./platform/linuxbsd/x11/dynwrappers/xext-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xext-so_wrap.c +// +// NOTE: Generated from Xext 1.3.5. +// This has been handpatched to workaround some issues with the generator that +// will be eventually fixed. In this case, non-existent symbols inherited from +// libX11, but absent in libXext.so.6, were removed and an include needed for +// proper parsing was added (this had also to be temporarily added to the +// original header, as dynload-wrapper would complain otherwise) +#include <stdint.h> + +// HANDPATCH: Needed for a successful compilation. +#include "thirdparty/linuxbsd_headers/X11/Xlib.h" + +#define XShapeQueryExtension XShapeQueryExtension_dylibloader_orig_xext +#define XShapeQueryVersion XShapeQueryVersion_dylibloader_orig_xext +#define XShapeCombineRegion XShapeCombineRegion_dylibloader_orig_xext +#define XShapeCombineRectangles XShapeCombineRectangles_dylibloader_orig_xext +#define XShapeCombineMask XShapeCombineMask_dylibloader_orig_xext +#define XShapeCombineShape XShapeCombineShape_dylibloader_orig_xext +#define XShapeOffsetShape XShapeOffsetShape_dylibloader_orig_xext +#define XShapeQueryExtents XShapeQueryExtents_dylibloader_orig_xext +#define XShapeSelectInput XShapeSelectInput_dylibloader_orig_xext +#define XShapeInputSelected XShapeInputSelected_dylibloader_orig_xext +#define XShapeGetRectangles XShapeGetRectangles_dylibloader_orig_xext +#include "thirdparty/linuxbsd_headers/X11/extensions/Xext.h" +#include "thirdparty/linuxbsd_headers/X11/extensions/shape.h" +#undef XShapeQueryExtension +#undef XShapeQueryVersion +#undef XShapeCombineRegion +#undef XShapeCombineRectangles +#undef XShapeCombineMask +#undef XShapeCombineShape +#undef XShapeOffsetShape +#undef XShapeQueryExtents +#undef XShapeSelectInput +#undef XShapeInputSelected +#undef XShapeGetRectangles +#include <dlfcn.h> +#include <stdio.h> +int (*XShapeQueryExtension_dylibloader_wrapper_xext)( Display*, int*, int*); +int (*XShapeQueryVersion_dylibloader_wrapper_xext)( Display*, int*, int*); +void (*XShapeCombineRegion_dylibloader_wrapper_xext)( Display*, Window, int, int, int, Region, int); +void (*XShapeCombineRectangles_dylibloader_wrapper_xext)( Display*, Window, int, int, int, XRectangle*, int, int, int); +void (*XShapeCombineMask_dylibloader_wrapper_xext)( Display*, Window, int, int, int, Pixmap, int); +void (*XShapeCombineShape_dylibloader_wrapper_xext)( Display*, Window, int, int, int, Window, int, int); +void (*XShapeOffsetShape_dylibloader_wrapper_xext)( Display*, Window, int, int, int); +int (*XShapeQueryExtents_dylibloader_wrapper_xext)( Display*, Window, int*, int*, int*, unsigned int*, unsigned int*, int*, int*, int*, unsigned int*, unsigned int*); +void (*XShapeSelectInput_dylibloader_wrapper_xext)( Display*, Window, unsigned long); +unsigned long (*XShapeInputSelected_dylibloader_wrapper_xext)( Display*, Window); +XRectangle* (*XShapeGetRectangles_dylibloader_wrapper_xext)( Display*, Window, int, int*, int*); +int initialize_xext(int verbose) { + void *handle; + char *error; + handle = dlopen("libXext.so.6", RTLD_LAZY); + if (!handle) { + if (verbose) { + fprintf(stderr, "%s\n", dlerror()); + } + return(1); + } + dlerror(); +// XShapeQueryExtension + *(void **) (&XShapeQueryExtension_dylibloader_wrapper_xext) = dlsym(handle, "XShapeQueryExtension"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XShapeQueryVersion + *(void **) (&XShapeQueryVersion_dylibloader_wrapper_xext) = dlsym(handle, "XShapeQueryVersion"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XShapeCombineRegion + *(void **) (&XShapeCombineRegion_dylibloader_wrapper_xext) = dlsym(handle, "XShapeCombineRegion"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XShapeCombineRectangles + *(void **) (&XShapeCombineRectangles_dylibloader_wrapper_xext) = dlsym(handle, "XShapeCombineRectangles"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XShapeCombineMask + *(void **) (&XShapeCombineMask_dylibloader_wrapper_xext) = dlsym(handle, "XShapeCombineMask"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XShapeCombineShape + *(void **) (&XShapeCombineShape_dylibloader_wrapper_xext) = dlsym(handle, "XShapeCombineShape"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XShapeOffsetShape + *(void **) (&XShapeOffsetShape_dylibloader_wrapper_xext) = dlsym(handle, "XShapeOffsetShape"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XShapeQueryExtents + *(void **) (&XShapeQueryExtents_dylibloader_wrapper_xext) = dlsym(handle, "XShapeQueryExtents"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XShapeSelectInput + *(void **) (&XShapeSelectInput_dylibloader_wrapper_xext) = dlsym(handle, "XShapeSelectInput"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XShapeInputSelected + *(void **) (&XShapeInputSelected_dylibloader_wrapper_xext) = dlsym(handle, "XShapeInputSelected"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XShapeGetRectangles + *(void **) (&XShapeGetRectangles_dylibloader_wrapper_xext) = dlsym(handle, "XShapeGetRectangles"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +return 0; +} diff --git a/platform/linuxbsd/x11/dynwrappers/xext-so_wrap.h b/platform/linuxbsd/x11/dynwrappers/xext-so_wrap.h new file mode 100644 index 0000000000..e535756d82 --- /dev/null +++ b/platform/linuxbsd/x11/dynwrappers/xext-so_wrap.h @@ -0,0 +1,72 @@ +#ifndef DYLIBLOAD_WRAPPER_XEXT +#define DYLIBLOAD_WRAPPER_XEXT +// This file is generated. Do not edit! +// see https://github.com/hpvb/dynload-wrapper for details +// generated by generate-wrapper.py 0.3 on 2023-01-23 15:11:29 +// flags: generate-wrapper.py --sys-include "thirdparty/linuxbsd_headers/X11/extensions/Xext.h" --include ./thirdparty/linuxbsd_headers/X11/extensions/shape.h --sys-include "thirdparty/linuxbsd_headers/X11/extensions/shape.h" --soname libXext.so.6 --init-name xext --output-header ./platform/linuxbsd/x11/dynwrappers/xext-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xext-so_wrap.c +// +// NOTE: Generated from Xext 1.3.5. +// This has been handpatched to workaround some issues with the generator that +// will be eventually fixed. In this case, non-existent symbols inherited from +// libX11, but absent in libXext.so.6, were removed and an include needed for +// proper parsing was added (this had also to be temporarily added to the +// original header, as dynload-wrapper would complain otherwise) +#include <stdint.h> + +// HANDPATCH: Needed for a successful compilation. +#include "thirdparty/linuxbsd_headers/X11/Xlib.h" + +#define XShapeQueryExtension XShapeQueryExtension_dylibloader_orig_xext +#define XShapeQueryVersion XShapeQueryVersion_dylibloader_orig_xext +#define XShapeCombineRegion XShapeCombineRegion_dylibloader_orig_xext +#define XShapeCombineRectangles XShapeCombineRectangles_dylibloader_orig_xext +#define XShapeCombineMask XShapeCombineMask_dylibloader_orig_xext +#define XShapeCombineShape XShapeCombineShape_dylibloader_orig_xext +#define XShapeOffsetShape XShapeOffsetShape_dylibloader_orig_xext +#define XShapeQueryExtents XShapeQueryExtents_dylibloader_orig_xext +#define XShapeSelectInput XShapeSelectInput_dylibloader_orig_xext +#define XShapeInputSelected XShapeInputSelected_dylibloader_orig_xext +#define XShapeGetRectangles XShapeGetRectangles_dylibloader_orig_xext +#include "thirdparty/linuxbsd_headers/X11/extensions/Xext.h" +#include "thirdparty/linuxbsd_headers/X11/extensions/shape.h" +#undef XShapeQueryExtension +#undef XShapeQueryVersion +#undef XShapeCombineRegion +#undef XShapeCombineRectangles +#undef XShapeCombineMask +#undef XShapeCombineShape +#undef XShapeOffsetShape +#undef XShapeQueryExtents +#undef XShapeSelectInput +#undef XShapeInputSelected +#undef XShapeGetRectangles +#ifdef __cplusplus +extern "C" { +#endif +#define XShapeQueryExtension XShapeQueryExtension_dylibloader_wrapper_xext +#define XShapeQueryVersion XShapeQueryVersion_dylibloader_wrapper_xext +#define XShapeCombineRegion XShapeCombineRegion_dylibloader_wrapper_xext +#define XShapeCombineRectangles XShapeCombineRectangles_dylibloader_wrapper_xext +#define XShapeCombineMask XShapeCombineMask_dylibloader_wrapper_xext +#define XShapeCombineShape XShapeCombineShape_dylibloader_wrapper_xext +#define XShapeOffsetShape XShapeOffsetShape_dylibloader_wrapper_xext +#define XShapeQueryExtents XShapeQueryExtents_dylibloader_wrapper_xext +#define XShapeSelectInput XShapeSelectInput_dylibloader_wrapper_xext +#define XShapeInputSelected XShapeInputSelected_dylibloader_wrapper_xext +#define XShapeGetRectangles XShapeGetRectangles_dylibloader_wrapper_xext +extern int (*XShapeQueryExtension_dylibloader_wrapper_xext)( Display*, int*, int*); +extern int (*XShapeQueryVersion_dylibloader_wrapper_xext)( Display*, int*, int*); +extern void (*XShapeCombineRegion_dylibloader_wrapper_xext)( Display*, Window, int, int, int, Region, int); +extern void (*XShapeCombineRectangles_dylibloader_wrapper_xext)( Display*, Window, int, int, int, XRectangle*, int, int, int); +extern void (*XShapeCombineMask_dylibloader_wrapper_xext)( Display*, Window, int, int, int, Pixmap, int); +extern void (*XShapeCombineShape_dylibloader_wrapper_xext)( Display*, Window, int, int, int, Window, int, int); +extern void (*XShapeOffsetShape_dylibloader_wrapper_xext)( Display*, Window, int, int, int); +extern int (*XShapeQueryExtents_dylibloader_wrapper_xext)( Display*, Window, int*, int*, int*, unsigned int*, unsigned int*, int*, int*, int*, unsigned int*, unsigned int*); +extern void (*XShapeSelectInput_dylibloader_wrapper_xext)( Display*, Window, unsigned long); +extern unsigned long (*XShapeInputSelected_dylibloader_wrapper_xext)( Display*, Window); +extern XRectangle* (*XShapeGetRectangles_dylibloader_wrapper_xext)( Display*, Window, int, int*, int*); +int initialize_xext(int verbose); +#ifdef __cplusplus +} +#endif +#endif diff --git a/platform/linuxbsd/x11/dynwrappers/xinerama-so_wrap.c b/platform/linuxbsd/x11/dynwrappers/xinerama-so_wrap.c new file mode 100644 index 0000000000..850ed1fc6b --- /dev/null +++ b/platform/linuxbsd/x11/dynwrappers/xinerama-so_wrap.c @@ -0,0 +1,71 @@ +// This file is generated. Do not edit! +// see https://github.com/hpvb/dynload-wrapper for details +// generated by generate-wrapper.py 0.3 on 2023-01-23 15:11:35 +// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/extensions/Xinerama.h --sys-include "thirdparty/linuxbsd_headers/X11/extensions/Xinerama.h" --soname libXinerama.so.1 --init-name xinerama --output-header ./platform/linuxbsd/x11/dynwrappers/xinerama-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xinerama-so_wrap.c +// +// NOTE: Generated from Xinerama 1.1.4. +// This has been handpatched to workaround some issues with the generator that +// will be eventually fixed. In this case, non-existent symbols inherited from +// libX11, but absent in libXinerama.so.1, were removed. +#include <stdint.h> + +#define XineramaQueryExtension XineramaQueryExtension_dylibloader_orig_xinerama +#define XineramaQueryVersion XineramaQueryVersion_dylibloader_orig_xinerama +#define XineramaIsActive XineramaIsActive_dylibloader_orig_xinerama +#define XineramaQueryScreens XineramaQueryScreens_dylibloader_orig_xinerama +#include "thirdparty/linuxbsd_headers/X11/extensions/Xinerama.h" +#undef XineramaQueryExtension +#undef XineramaQueryVersion +#undef XineramaIsActive +#undef XineramaQueryScreens +#include <dlfcn.h> +#include <stdio.h> +int (*XineramaQueryExtension_dylibloader_wrapper_xinerama)( Display*, int*, int*); +int (*XineramaQueryVersion_dylibloader_wrapper_xinerama)( Display*, int*, int*); +int (*XineramaIsActive_dylibloader_wrapper_xinerama)( Display*); +XineramaScreenInfo* (*XineramaQueryScreens_dylibloader_wrapper_xinerama)( Display*, int*); +int initialize_xinerama(int verbose) { + void *handle; + char *error; + handle = dlopen("libXinerama.so.1", RTLD_LAZY); + if (!handle) { + if (verbose) { + fprintf(stderr, "%s\n", dlerror()); + } + return(1); + } + dlerror(); +// XineramaQueryExtension + *(void **) (&XineramaQueryExtension_dylibloader_wrapper_xinerama) = dlsym(handle, "XineramaQueryExtension"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XineramaQueryVersion + *(void **) (&XineramaQueryVersion_dylibloader_wrapper_xinerama) = dlsym(handle, "XineramaQueryVersion"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XineramaIsActive + *(void **) (&XineramaIsActive_dylibloader_wrapper_xinerama) = dlsym(handle, "XineramaIsActive"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XineramaQueryScreens + *(void **) (&XineramaQueryScreens_dylibloader_wrapper_xinerama) = dlsym(handle, "XineramaQueryScreens"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +return 0; +} diff --git a/platform/linuxbsd/x11/dynwrappers/xinerama-so_wrap.h b/platform/linuxbsd/x11/dynwrappers/xinerama-so_wrap.h new file mode 100644 index 0000000000..e3cedfc8ad --- /dev/null +++ b/platform/linuxbsd/x11/dynwrappers/xinerama-so_wrap.h @@ -0,0 +1,38 @@ +#ifndef DYLIBLOAD_WRAPPER_XINERAMA +#define DYLIBLOAD_WRAPPER_XINERAMA +// This file is generated. Do not edit! +// see https://github.com/hpvb/dynload-wrapper for details +// generated by generate-wrapper.py 0.3 on 2023-01-23 15:11:35 +// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/extensions/Xinerama.h --sys-include "thirdparty/linuxbsd_headers/X11/extensions/Xinerama.h" --soname libXinerama.so.1 --init-name xinerama --output-header ./platform/linuxbsd/x11/dynwrappers/xinerama-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xinerama-so_wrap.c +// +// NOTE: Generated from Xinerama 1.1.4. +// This has been handpatched to workaround some issues with the generator that +// will be eventually fixed. In this case, non-existent symbols inherited from +// libX11, but absent in libXinerama.so.1, were removed. +#include <stdint.h> + +#define XineramaQueryExtension XineramaQueryExtension_dylibloader_orig_xinerama +#define XineramaQueryVersion XineramaQueryVersion_dylibloader_orig_xinerama +#define XineramaIsActive XineramaIsActive_dylibloader_orig_xinerama +#define XineramaQueryScreens XineramaQueryScreens_dylibloader_orig_xinerama +#include "thirdparty/linuxbsd_headers/X11/extensions/Xinerama.h" +#undef XineramaQueryExtension +#undef XineramaQueryVersion +#undef XineramaIsActive +#undef XineramaQueryScreens +#ifdef __cplusplus +extern "C" { +#endif +#define XineramaQueryExtension XineramaQueryExtension_dylibloader_wrapper_xinerama +#define XineramaQueryVersion XineramaQueryVersion_dylibloader_wrapper_xinerama +#define XineramaIsActive XineramaIsActive_dylibloader_wrapper_xinerama +#define XineramaQueryScreens XineramaQueryScreens_dylibloader_wrapper_xinerama +extern int (*XineramaQueryExtension_dylibloader_wrapper_xinerama)( Display*, int*, int*); +extern int (*XineramaQueryVersion_dylibloader_wrapper_xinerama)( Display*, int*, int*); +extern int (*XineramaIsActive_dylibloader_wrapper_xinerama)( Display*); +extern XineramaScreenInfo* (*XineramaQueryScreens_dylibloader_wrapper_xinerama)( Display*, int*); +int initialize_xinerama(int verbose); +#ifdef __cplusplus +} +#endif +#endif diff --git a/platform/linuxbsd/x11/dynwrappers/xinput2-so_wrap.c b/platform/linuxbsd/x11/dynwrappers/xinput2-so_wrap.c new file mode 100644 index 0000000000..fc08b97e3c --- /dev/null +++ b/platform/linuxbsd/x11/dynwrappers/xinput2-so_wrap.c @@ -0,0 +1,401 @@ +// This file is generated. Do not edit! +// see https://github.com/hpvb/dynload-wrapper for details +// generated by generate-wrapper.py 0.3 on 2023-01-23 15:12:16 +// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/extensions/XInput2.h --sys-include "thirdparty/linuxbsd_headers/X11/extensions/XInput2.h" --soname libXi.so.6 --init-name xinput2 --output-header ./platform/linuxbsd/x11/dynwrappers/xinput2-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xinput2-so_wrap.c +// +// NOTE: Generated from Xi 1.7.10. +// This has been handpatched to workaround some issues with the generator that +// will be eventually fixed. In this case, non-existent symbols inherited from +// libX11, liXext and libXfixes, but absent in libXi.so.6, were removed. +#include <stdint.h> + +#define XIQueryPointer XIQueryPointer_dylibloader_orig_xinput2 +#define XIWarpPointer XIWarpPointer_dylibloader_orig_xinput2 +#define XIDefineCursor XIDefineCursor_dylibloader_orig_xinput2 +#define XIUndefineCursor XIUndefineCursor_dylibloader_orig_xinput2 +#define XIChangeHierarchy XIChangeHierarchy_dylibloader_orig_xinput2 +#define XISetClientPointer XISetClientPointer_dylibloader_orig_xinput2 +#define XIGetClientPointer XIGetClientPointer_dylibloader_orig_xinput2 +#define XISelectEvents XISelectEvents_dylibloader_orig_xinput2 +#define XIGetSelectedEvents XIGetSelectedEvents_dylibloader_orig_xinput2 +#define XIQueryVersion XIQueryVersion_dylibloader_orig_xinput2 +#define XIQueryDevice XIQueryDevice_dylibloader_orig_xinput2 +#define XISetFocus XISetFocus_dylibloader_orig_xinput2 +#define XIGetFocus XIGetFocus_dylibloader_orig_xinput2 +#define XIGrabDevice XIGrabDevice_dylibloader_orig_xinput2 +#define XIUngrabDevice XIUngrabDevice_dylibloader_orig_xinput2 +#define XIAllowEvents XIAllowEvents_dylibloader_orig_xinput2 +#define XIAllowTouchEvents XIAllowTouchEvents_dylibloader_orig_xinput2 +#define XIGrabButton XIGrabButton_dylibloader_orig_xinput2 +#define XIGrabKeycode XIGrabKeycode_dylibloader_orig_xinput2 +#define XIGrabEnter XIGrabEnter_dylibloader_orig_xinput2 +#define XIGrabFocusIn XIGrabFocusIn_dylibloader_orig_xinput2 +#define XIGrabTouchBegin XIGrabTouchBegin_dylibloader_orig_xinput2 +#define XIUngrabButton XIUngrabButton_dylibloader_orig_xinput2 +#define XIUngrabKeycode XIUngrabKeycode_dylibloader_orig_xinput2 +#define XIUngrabEnter XIUngrabEnter_dylibloader_orig_xinput2 +#define XIUngrabFocusIn XIUngrabFocusIn_dylibloader_orig_xinput2 +#define XIUngrabTouchBegin XIUngrabTouchBegin_dylibloader_orig_xinput2 +#define XIListProperties XIListProperties_dylibloader_orig_xinput2 +#define XIChangeProperty XIChangeProperty_dylibloader_orig_xinput2 +#define XIDeleteProperty XIDeleteProperty_dylibloader_orig_xinput2 +#define XIGetProperty XIGetProperty_dylibloader_orig_xinput2 +#define XIBarrierReleasePointers XIBarrierReleasePointers_dylibloader_orig_xinput2 +#define XIBarrierReleasePointer XIBarrierReleasePointer_dylibloader_orig_xinput2 +#define XIFreeDeviceInfo XIFreeDeviceInfo_dylibloader_orig_xinput2 +#include "thirdparty/linuxbsd_headers/X11/extensions/XInput2.h" +#undef XIQueryPointer +#undef XIWarpPointer +#undef XIDefineCursor +#undef XIUndefineCursor +#undef XIChangeHierarchy +#undef XISetClientPointer +#undef XIGetClientPointer +#undef XISelectEvents +#undef XIGetSelectedEvents +#undef XIQueryVersion +#undef XIQueryDevice +#undef XISetFocus +#undef XIGetFocus +#undef XIGrabDevice +#undef XIUngrabDevice +#undef XIAllowEvents +#undef XIAllowTouchEvents +#undef XIGrabButton +#undef XIGrabKeycode +#undef XIGrabEnter +#undef XIGrabFocusIn +#undef XIGrabTouchBegin +#undef XIUngrabButton +#undef XIUngrabKeycode +#undef XIUngrabEnter +#undef XIUngrabFocusIn +#undef XIUngrabTouchBegin +#undef XIListProperties +#undef XIChangeProperty +#undef XIDeleteProperty +#undef XIGetProperty +#undef XIBarrierReleasePointers +#undef XIBarrierReleasePointer +#undef XIFreeDeviceInfo +#include <dlfcn.h> +#include <stdio.h> +int (*XIQueryPointer_dylibloader_wrapper_xinput2)( Display*, int, Window, Window*, Window*, double*, double*, double*, double*, XIButtonState*, XIModifierState*, XIGroupState*); +int (*XIWarpPointer_dylibloader_wrapper_xinput2)( Display*, int, Window, Window, double, double, unsigned int, unsigned int, double, double); +int (*XIDefineCursor_dylibloader_wrapper_xinput2)( Display*, int, Window, Cursor); +int (*XIUndefineCursor_dylibloader_wrapper_xinput2)( Display*, int, Window); +int (*XIChangeHierarchy_dylibloader_wrapper_xinput2)( Display*, XIAnyHierarchyChangeInfo*, int); +int (*XISetClientPointer_dylibloader_wrapper_xinput2)( Display*, Window, int); +int (*XIGetClientPointer_dylibloader_wrapper_xinput2)( Display*, Window, int*); +int (*XISelectEvents_dylibloader_wrapper_xinput2)( Display*, Window, XIEventMask*, int); +XIEventMask* (*XIGetSelectedEvents_dylibloader_wrapper_xinput2)( Display*, Window, int*); +int (*XIQueryVersion_dylibloader_wrapper_xinput2)( Display*, int*, int*); +XIDeviceInfo* (*XIQueryDevice_dylibloader_wrapper_xinput2)( Display*, int, int*); +int (*XISetFocus_dylibloader_wrapper_xinput2)( Display*, int, Window, Time); +int (*XIGetFocus_dylibloader_wrapper_xinput2)( Display*, int, Window*); +int (*XIGrabDevice_dylibloader_wrapper_xinput2)( Display*, int, Window, Time, Cursor, int, int, int, XIEventMask*); +int (*XIUngrabDevice_dylibloader_wrapper_xinput2)( Display*, int, Time); +int (*XIAllowEvents_dylibloader_wrapper_xinput2)( Display*, int, int, Time); +int (*XIAllowTouchEvents_dylibloader_wrapper_xinput2)( Display*, int, unsigned int, Window, int); +int (*XIGrabButton_dylibloader_wrapper_xinput2)( Display*, int, int, Window, Cursor, int, int, int, XIEventMask*, int, XIGrabModifiers*); +int (*XIGrabKeycode_dylibloader_wrapper_xinput2)( Display*, int, int, Window, int, int, int, XIEventMask*, int, XIGrabModifiers*); +int (*XIGrabEnter_dylibloader_wrapper_xinput2)( Display*, int, Window, Cursor, int, int, int, XIEventMask*, int, XIGrabModifiers*); +int (*XIGrabFocusIn_dylibloader_wrapper_xinput2)( Display*, int, Window, int, int, int, XIEventMask*, int, XIGrabModifiers*); +int (*XIGrabTouchBegin_dylibloader_wrapper_xinput2)( Display*, int, Window, int, XIEventMask*, int, XIGrabModifiers*); +int (*XIUngrabButton_dylibloader_wrapper_xinput2)( Display*, int, int, Window, int, XIGrabModifiers*); +int (*XIUngrabKeycode_dylibloader_wrapper_xinput2)( Display*, int, int, Window, int, XIGrabModifiers*); +int (*XIUngrabEnter_dylibloader_wrapper_xinput2)( Display*, int, Window, int, XIGrabModifiers*); +int (*XIUngrabFocusIn_dylibloader_wrapper_xinput2)( Display*, int, Window, int, XIGrabModifiers*); +int (*XIUngrabTouchBegin_dylibloader_wrapper_xinput2)( Display*, int, Window, int, XIGrabModifiers*); +Atom* (*XIListProperties_dylibloader_wrapper_xinput2)( Display*, int, int*); +void (*XIChangeProperty_dylibloader_wrapper_xinput2)( Display*, int, Atom, Atom, int, int, unsigned char*, int); +void (*XIDeleteProperty_dylibloader_wrapper_xinput2)( Display*, int, Atom); +int (*XIGetProperty_dylibloader_wrapper_xinput2)( Display*, int, Atom, long, long, int, Atom, Atom*, int*, unsigned long*, unsigned long*, unsigned char**); +void (*XIBarrierReleasePointers_dylibloader_wrapper_xinput2)( Display*, XIBarrierReleasePointerInfo*, int); +void (*XIBarrierReleasePointer_dylibloader_wrapper_xinput2)( Display*, int, PointerBarrier, BarrierEventID); +void (*XIFreeDeviceInfo_dylibloader_wrapper_xinput2)( XIDeviceInfo*); +int initialize_xinput2(int verbose) { + void *handle; + char *error; + handle = dlopen("libXi.so.6", RTLD_LAZY); + if (!handle) { + if (verbose) { + fprintf(stderr, "%s\n", dlerror()); + } + return(1); + } + dlerror(); +// XIQueryPointer + *(void **) (&XIQueryPointer_dylibloader_wrapper_xinput2) = dlsym(handle, "XIQueryPointer"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XIWarpPointer + *(void **) (&XIWarpPointer_dylibloader_wrapper_xinput2) = dlsym(handle, "XIWarpPointer"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XIDefineCursor + *(void **) (&XIDefineCursor_dylibloader_wrapper_xinput2) = dlsym(handle, "XIDefineCursor"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XIUndefineCursor + *(void **) (&XIUndefineCursor_dylibloader_wrapper_xinput2) = dlsym(handle, "XIUndefineCursor"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XIChangeHierarchy + *(void **) (&XIChangeHierarchy_dylibloader_wrapper_xinput2) = dlsym(handle, "XIChangeHierarchy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XISetClientPointer + *(void **) (&XISetClientPointer_dylibloader_wrapper_xinput2) = dlsym(handle, "XISetClientPointer"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XIGetClientPointer + *(void **) (&XIGetClientPointer_dylibloader_wrapper_xinput2) = dlsym(handle, "XIGetClientPointer"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XISelectEvents + *(void **) (&XISelectEvents_dylibloader_wrapper_xinput2) = dlsym(handle, "XISelectEvents"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XIGetSelectedEvents + *(void **) (&XIGetSelectedEvents_dylibloader_wrapper_xinput2) = dlsym(handle, "XIGetSelectedEvents"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XIQueryVersion + *(void **) (&XIQueryVersion_dylibloader_wrapper_xinput2) = dlsym(handle, "XIQueryVersion"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XIQueryDevice + *(void **) (&XIQueryDevice_dylibloader_wrapper_xinput2) = dlsym(handle, "XIQueryDevice"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XISetFocus + *(void **) (&XISetFocus_dylibloader_wrapper_xinput2) = dlsym(handle, "XISetFocus"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XIGetFocus + *(void **) (&XIGetFocus_dylibloader_wrapper_xinput2) = dlsym(handle, "XIGetFocus"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XIGrabDevice + *(void **) (&XIGrabDevice_dylibloader_wrapper_xinput2) = dlsym(handle, "XIGrabDevice"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XIUngrabDevice + *(void **) (&XIUngrabDevice_dylibloader_wrapper_xinput2) = dlsym(handle, "XIUngrabDevice"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XIAllowEvents + *(void **) (&XIAllowEvents_dylibloader_wrapper_xinput2) = dlsym(handle, "XIAllowEvents"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XIAllowTouchEvents + *(void **) (&XIAllowTouchEvents_dylibloader_wrapper_xinput2) = dlsym(handle, "XIAllowTouchEvents"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XIGrabButton + *(void **) (&XIGrabButton_dylibloader_wrapper_xinput2) = dlsym(handle, "XIGrabButton"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XIGrabKeycode + *(void **) (&XIGrabKeycode_dylibloader_wrapper_xinput2) = dlsym(handle, "XIGrabKeycode"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XIGrabEnter + *(void **) (&XIGrabEnter_dylibloader_wrapper_xinput2) = dlsym(handle, "XIGrabEnter"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XIGrabFocusIn + *(void **) (&XIGrabFocusIn_dylibloader_wrapper_xinput2) = dlsym(handle, "XIGrabFocusIn"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XIGrabTouchBegin + *(void **) (&XIGrabTouchBegin_dylibloader_wrapper_xinput2) = dlsym(handle, "XIGrabTouchBegin"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XIUngrabButton + *(void **) (&XIUngrabButton_dylibloader_wrapper_xinput2) = dlsym(handle, "XIUngrabButton"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XIUngrabKeycode + *(void **) (&XIUngrabKeycode_dylibloader_wrapper_xinput2) = dlsym(handle, "XIUngrabKeycode"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XIUngrabEnter + *(void **) (&XIUngrabEnter_dylibloader_wrapper_xinput2) = dlsym(handle, "XIUngrabEnter"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XIUngrabFocusIn + *(void **) (&XIUngrabFocusIn_dylibloader_wrapper_xinput2) = dlsym(handle, "XIUngrabFocusIn"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XIUngrabTouchBegin + *(void **) (&XIUngrabTouchBegin_dylibloader_wrapper_xinput2) = dlsym(handle, "XIUngrabTouchBegin"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XIListProperties + *(void **) (&XIListProperties_dylibloader_wrapper_xinput2) = dlsym(handle, "XIListProperties"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XIChangeProperty + *(void **) (&XIChangeProperty_dylibloader_wrapper_xinput2) = dlsym(handle, "XIChangeProperty"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XIDeleteProperty + *(void **) (&XIDeleteProperty_dylibloader_wrapper_xinput2) = dlsym(handle, "XIDeleteProperty"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XIGetProperty + *(void **) (&XIGetProperty_dylibloader_wrapper_xinput2) = dlsym(handle, "XIGetProperty"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XIBarrierReleasePointers + *(void **) (&XIBarrierReleasePointers_dylibloader_wrapper_xinput2) = dlsym(handle, "XIBarrierReleasePointers"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XIBarrierReleasePointer + *(void **) (&XIBarrierReleasePointer_dylibloader_wrapper_xinput2) = dlsym(handle, "XIBarrierReleasePointer"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XIFreeDeviceInfo + *(void **) (&XIFreeDeviceInfo_dylibloader_wrapper_xinput2) = dlsym(handle, "XIFreeDeviceInfo"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +return 0; +} diff --git a/platform/linuxbsd/x11/dynwrappers/xinput2-so_wrap.h b/platform/linuxbsd/x11/dynwrappers/xinput2-so_wrap.h new file mode 100644 index 0000000000..571072c3cd --- /dev/null +++ b/platform/linuxbsd/x11/dynwrappers/xinput2-so_wrap.h @@ -0,0 +1,158 @@ +#ifndef DYLIBLOAD_WRAPPER_XINPUT2 +#define DYLIBLOAD_WRAPPER_XINPUT2 +// This file is generated. Do not edit! +// see https://github.com/hpvb/dynload-wrapper for details +// generated by generate-wrapper.py 0.3 on 2023-01-23 15:12:16 +// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/extensions/XInput2.h --sys-include "thirdparty/linuxbsd_headers/X11/extensions/XInput2.h" --soname libXi.so.6 --init-name xinput2 --output-header ./platform/linuxbsd/x11/dynwrappers/xinput2-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xinput2-so_wrap.c +// +// NOTE: Generated from Xi 1.7.10. +// This has been handpatched to workaround some issues with the generator that +// will be eventually fixed. In this case, non-existent symbols inherited from +// libX11, liXext and libXfixes, but absent in libXi.so.6, were removed. +#include <stdint.h> + +#define XIQueryPointer XIQueryPointer_dylibloader_orig_xinput2 +#define XIWarpPointer XIWarpPointer_dylibloader_orig_xinput2 +#define XIDefineCursor XIDefineCursor_dylibloader_orig_xinput2 +#define XIUndefineCursor XIUndefineCursor_dylibloader_orig_xinput2 +#define XIChangeHierarchy XIChangeHierarchy_dylibloader_orig_xinput2 +#define XISetClientPointer XISetClientPointer_dylibloader_orig_xinput2 +#define XIGetClientPointer XIGetClientPointer_dylibloader_orig_xinput2 +#define XISelectEvents XISelectEvents_dylibloader_orig_xinput2 +#define XIGetSelectedEvents XIGetSelectedEvents_dylibloader_orig_xinput2 +#define XIQueryVersion XIQueryVersion_dylibloader_orig_xinput2 +#define XIQueryDevice XIQueryDevice_dylibloader_orig_xinput2 +#define XISetFocus XISetFocus_dylibloader_orig_xinput2 +#define XIGetFocus XIGetFocus_dylibloader_orig_xinput2 +#define XIGrabDevice XIGrabDevice_dylibloader_orig_xinput2 +#define XIUngrabDevice XIUngrabDevice_dylibloader_orig_xinput2 +#define XIAllowEvents XIAllowEvents_dylibloader_orig_xinput2 +#define XIAllowTouchEvents XIAllowTouchEvents_dylibloader_orig_xinput2 +#define XIGrabButton XIGrabButton_dylibloader_orig_xinput2 +#define XIGrabKeycode XIGrabKeycode_dylibloader_orig_xinput2 +#define XIGrabEnter XIGrabEnter_dylibloader_orig_xinput2 +#define XIGrabFocusIn XIGrabFocusIn_dylibloader_orig_xinput2 +#define XIGrabTouchBegin XIGrabTouchBegin_dylibloader_orig_xinput2 +#define XIUngrabButton XIUngrabButton_dylibloader_orig_xinput2 +#define XIUngrabKeycode XIUngrabKeycode_dylibloader_orig_xinput2 +#define XIUngrabEnter XIUngrabEnter_dylibloader_orig_xinput2 +#define XIUngrabFocusIn XIUngrabFocusIn_dylibloader_orig_xinput2 +#define XIUngrabTouchBegin XIUngrabTouchBegin_dylibloader_orig_xinput2 +#define XIListProperties XIListProperties_dylibloader_orig_xinput2 +#define XIChangeProperty XIChangeProperty_dylibloader_orig_xinput2 +#define XIDeleteProperty XIDeleteProperty_dylibloader_orig_xinput2 +#define XIGetProperty XIGetProperty_dylibloader_orig_xinput2 +#define XIBarrierReleasePointers XIBarrierReleasePointers_dylibloader_orig_xinput2 +#define XIBarrierReleasePointer XIBarrierReleasePointer_dylibloader_orig_xinput2 +#define XIFreeDeviceInfo XIFreeDeviceInfo_dylibloader_orig_xinput2 +#include "thirdparty/linuxbsd_headers/X11/extensions/XInput2.h" +#undef XIQueryPointer +#undef XIWarpPointer +#undef XIDefineCursor +#undef XIUndefineCursor +#undef XIChangeHierarchy +#undef XISetClientPointer +#undef XIGetClientPointer +#undef XISelectEvents +#undef XIGetSelectedEvents +#undef XIQueryVersion +#undef XIQueryDevice +#undef XISetFocus +#undef XIGetFocus +#undef XIGrabDevice +#undef XIUngrabDevice +#undef XIAllowEvents +#undef XIAllowTouchEvents +#undef XIGrabButton +#undef XIGrabKeycode +#undef XIGrabEnter +#undef XIGrabFocusIn +#undef XIGrabTouchBegin +#undef XIUngrabButton +#undef XIUngrabKeycode +#undef XIUngrabEnter +#undef XIUngrabFocusIn +#undef XIUngrabTouchBegin +#undef XIListProperties +#undef XIChangeProperty +#undef XIDeleteProperty +#undef XIGetProperty +#undef XIBarrierReleasePointers +#undef XIBarrierReleasePointer +#undef XIFreeDeviceInfo +#ifdef __cplusplus +extern "C" { +#endif +#define XIQueryPointer XIQueryPointer_dylibloader_wrapper_xinput2 +#define XIWarpPointer XIWarpPointer_dylibloader_wrapper_xinput2 +#define XIDefineCursor XIDefineCursor_dylibloader_wrapper_xinput2 +#define XIUndefineCursor XIUndefineCursor_dylibloader_wrapper_xinput2 +#define XIChangeHierarchy XIChangeHierarchy_dylibloader_wrapper_xinput2 +#define XISetClientPointer XISetClientPointer_dylibloader_wrapper_xinput2 +#define XIGetClientPointer XIGetClientPointer_dylibloader_wrapper_xinput2 +#define XISelectEvents XISelectEvents_dylibloader_wrapper_xinput2 +#define XIGetSelectedEvents XIGetSelectedEvents_dylibloader_wrapper_xinput2 +#define XIQueryVersion XIQueryVersion_dylibloader_wrapper_xinput2 +#define XIQueryDevice XIQueryDevice_dylibloader_wrapper_xinput2 +#define XISetFocus XISetFocus_dylibloader_wrapper_xinput2 +#define XIGetFocus XIGetFocus_dylibloader_wrapper_xinput2 +#define XIGrabDevice XIGrabDevice_dylibloader_wrapper_xinput2 +#define XIUngrabDevice XIUngrabDevice_dylibloader_wrapper_xinput2 +#define XIAllowEvents XIAllowEvents_dylibloader_wrapper_xinput2 +#define XIAllowTouchEvents XIAllowTouchEvents_dylibloader_wrapper_xinput2 +#define XIGrabButton XIGrabButton_dylibloader_wrapper_xinput2 +#define XIGrabKeycode XIGrabKeycode_dylibloader_wrapper_xinput2 +#define XIGrabEnter XIGrabEnter_dylibloader_wrapper_xinput2 +#define XIGrabFocusIn XIGrabFocusIn_dylibloader_wrapper_xinput2 +#define XIGrabTouchBegin XIGrabTouchBegin_dylibloader_wrapper_xinput2 +#define XIUngrabButton XIUngrabButton_dylibloader_wrapper_xinput2 +#define XIUngrabKeycode XIUngrabKeycode_dylibloader_wrapper_xinput2 +#define XIUngrabEnter XIUngrabEnter_dylibloader_wrapper_xinput2 +#define XIUngrabFocusIn XIUngrabFocusIn_dylibloader_wrapper_xinput2 +#define XIUngrabTouchBegin XIUngrabTouchBegin_dylibloader_wrapper_xinput2 +#define XIListProperties XIListProperties_dylibloader_wrapper_xinput2 +#define XIChangeProperty XIChangeProperty_dylibloader_wrapper_xinput2 +#define XIDeleteProperty XIDeleteProperty_dylibloader_wrapper_xinput2 +#define XIGetProperty XIGetProperty_dylibloader_wrapper_xinput2 +#define XIBarrierReleasePointers XIBarrierReleasePointers_dylibloader_wrapper_xinput2 +#define XIBarrierReleasePointer XIBarrierReleasePointer_dylibloader_wrapper_xinput2 +#define XIFreeDeviceInfo XIFreeDeviceInfo_dylibloader_wrapper_xinput2 +extern int (*XIQueryPointer_dylibloader_wrapper_xinput2)( Display*, int, Window, Window*, Window*, double*, double*, double*, double*, XIButtonState*, XIModifierState*, XIGroupState*); +extern int (*XIWarpPointer_dylibloader_wrapper_xinput2)( Display*, int, Window, Window, double, double, unsigned int, unsigned int, double, double); +extern int (*XIDefineCursor_dylibloader_wrapper_xinput2)( Display*, int, Window, Cursor); +extern int (*XIUndefineCursor_dylibloader_wrapper_xinput2)( Display*, int, Window); +extern int (*XIChangeHierarchy_dylibloader_wrapper_xinput2)( Display*, XIAnyHierarchyChangeInfo*, int); +extern int (*XISetClientPointer_dylibloader_wrapper_xinput2)( Display*, Window, int); +extern int (*XIGetClientPointer_dylibloader_wrapper_xinput2)( Display*, Window, int*); +extern int (*XISelectEvents_dylibloader_wrapper_xinput2)( Display*, Window, XIEventMask*, int); +extern XIEventMask* (*XIGetSelectedEvents_dylibloader_wrapper_xinput2)( Display*, Window, int*); +extern int (*XIQueryVersion_dylibloader_wrapper_xinput2)( Display*, int*, int*); +extern XIDeviceInfo* (*XIQueryDevice_dylibloader_wrapper_xinput2)( Display*, int, int*); +extern int (*XISetFocus_dylibloader_wrapper_xinput2)( Display*, int, Window, Time); +extern int (*XIGetFocus_dylibloader_wrapper_xinput2)( Display*, int, Window*); +extern int (*XIGrabDevice_dylibloader_wrapper_xinput2)( Display*, int, Window, Time, Cursor, int, int, int, XIEventMask*); +extern int (*XIUngrabDevice_dylibloader_wrapper_xinput2)( Display*, int, Time); +extern int (*XIAllowEvents_dylibloader_wrapper_xinput2)( Display*, int, int, Time); +extern int (*XIAllowTouchEvents_dylibloader_wrapper_xinput2)( Display*, int, unsigned int, Window, int); +extern int (*XIGrabButton_dylibloader_wrapper_xinput2)( Display*, int, int, Window, Cursor, int, int, int, XIEventMask*, int, XIGrabModifiers*); +extern int (*XIGrabKeycode_dylibloader_wrapper_xinput2)( Display*, int, int, Window, int, int, int, XIEventMask*, int, XIGrabModifiers*); +extern int (*XIGrabEnter_dylibloader_wrapper_xinput2)( Display*, int, Window, Cursor, int, int, int, XIEventMask*, int, XIGrabModifiers*); +extern int (*XIGrabFocusIn_dylibloader_wrapper_xinput2)( Display*, int, Window, int, int, int, XIEventMask*, int, XIGrabModifiers*); +extern int (*XIGrabTouchBegin_dylibloader_wrapper_xinput2)( Display*, int, Window, int, XIEventMask*, int, XIGrabModifiers*); +extern int (*XIUngrabButton_dylibloader_wrapper_xinput2)( Display*, int, int, Window, int, XIGrabModifiers*); +extern int (*XIUngrabKeycode_dylibloader_wrapper_xinput2)( Display*, int, int, Window, int, XIGrabModifiers*); +extern int (*XIUngrabEnter_dylibloader_wrapper_xinput2)( Display*, int, Window, int, XIGrabModifiers*); +extern int (*XIUngrabFocusIn_dylibloader_wrapper_xinput2)( Display*, int, Window, int, XIGrabModifiers*); +extern int (*XIUngrabTouchBegin_dylibloader_wrapper_xinput2)( Display*, int, Window, int, XIGrabModifiers*); +extern Atom* (*XIListProperties_dylibloader_wrapper_xinput2)( Display*, int, int*); +extern void (*XIChangeProperty_dylibloader_wrapper_xinput2)( Display*, int, Atom, Atom, int, int, unsigned char*, int); +extern void (*XIDeleteProperty_dylibloader_wrapper_xinput2)( Display*, int, Atom); +extern int (*XIGetProperty_dylibloader_wrapper_xinput2)( Display*, int, Atom, long, long, int, Atom, Atom*, int*, unsigned long*, unsigned long*, unsigned char**); +extern void (*XIBarrierReleasePointers_dylibloader_wrapper_xinput2)( Display*, XIBarrierReleasePointerInfo*, int); +extern void (*XIBarrierReleasePointer_dylibloader_wrapper_xinput2)( Display*, int, PointerBarrier, BarrierEventID); +extern void (*XIFreeDeviceInfo_dylibloader_wrapper_xinput2)( XIDeviceInfo*); +int initialize_xinput2(int verbose); +#ifdef __cplusplus +} +#endif +#endif diff --git a/platform/linuxbsd/x11/dynwrappers/xlib-so_wrap.c b/platform/linuxbsd/x11/dynwrappers/xlib-so_wrap.c new file mode 100644 index 0000000000..d2838569b0 --- /dev/null +++ b/platform/linuxbsd/x11/dynwrappers/xlib-so_wrap.c @@ -0,0 +1,6664 @@ +// This file is generated. Do not edit! +// see https://github.com/hpvb/dynload-wrapper for details +// generated by generate-wrapper.py 0.3 on 2023-01-23 15:13:26 +// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/Xlib.h --include ./thirdparty/linuxbsd_headers/X11/Xutil.h --include ./thirdparty/linuxbsd_headers/X11/XKBlib.h --sys-include "thirdparty/linuxbsd_headers/X11/Xlib.h" --sys-include "thirdparty/linuxbsd_headers/X11/Xutil.h" --sys-include "thirdparty/linuxbsd_headers/X11/XKBlib.h" --soname libX11.so.6 --init-name xlib --omit-prefix XkbGetDeviceIndicatorState --omit-prefix XkbAddSymInterpret --output-header ./platform/linuxbsd/x11/dynwrappers/xlib-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xlib-so_wrap.c~ +// +// NOTE: Generated from Xlib 1.6.9. +// This has been handpatched to workaround some issues with the generator that +// will be eventually fixed. In this case, the type of the third argument of +// XIfEvent, XPeekIfEvent and XCheckIfEvent had to be fixed as it wasn't parsed +// fully (it's a Bool function pointer, but it was just being parsed as an int +// pointer). +#include <stdint.h> + +#define _Xmblen _Xmblen_dylibloader_orig_xlib +#define XLoadQueryFont XLoadQueryFont_dylibloader_orig_xlib +#define XQueryFont XQueryFont_dylibloader_orig_xlib +#define XGetMotionEvents XGetMotionEvents_dylibloader_orig_xlib +#define XDeleteModifiermapEntry XDeleteModifiermapEntry_dylibloader_orig_xlib +#define XGetModifierMapping XGetModifierMapping_dylibloader_orig_xlib +#define XInsertModifiermapEntry XInsertModifiermapEntry_dylibloader_orig_xlib +#define XNewModifiermap XNewModifiermap_dylibloader_orig_xlib +#define XCreateImage XCreateImage_dylibloader_orig_xlib +#define XInitImage XInitImage_dylibloader_orig_xlib +#define XGetImage XGetImage_dylibloader_orig_xlib +#define XGetSubImage XGetSubImage_dylibloader_orig_xlib +#define XOpenDisplay XOpenDisplay_dylibloader_orig_xlib +#define XrmInitialize XrmInitialize_dylibloader_orig_xlib +#define XFetchBytes XFetchBytes_dylibloader_orig_xlib +#define XFetchBuffer XFetchBuffer_dylibloader_orig_xlib +#define XGetAtomName XGetAtomName_dylibloader_orig_xlib +#define XGetAtomNames XGetAtomNames_dylibloader_orig_xlib +#define XGetDefault XGetDefault_dylibloader_orig_xlib +#define XDisplayName XDisplayName_dylibloader_orig_xlib +#define XKeysymToString XKeysymToString_dylibloader_orig_xlib +#define XSynchronize XSynchronize_dylibloader_orig_xlib +#define XSetAfterFunction XSetAfterFunction_dylibloader_orig_xlib +#define XInternAtom XInternAtom_dylibloader_orig_xlib +#define XInternAtoms XInternAtoms_dylibloader_orig_xlib +#define XCopyColormapAndFree XCopyColormapAndFree_dylibloader_orig_xlib +#define XCreateColormap XCreateColormap_dylibloader_orig_xlib +#define XCreatePixmapCursor XCreatePixmapCursor_dylibloader_orig_xlib +#define XCreateGlyphCursor XCreateGlyphCursor_dylibloader_orig_xlib +#define XCreateFontCursor XCreateFontCursor_dylibloader_orig_xlib +#define XLoadFont XLoadFont_dylibloader_orig_xlib +#define XCreateGC XCreateGC_dylibloader_orig_xlib +#define XGContextFromGC XGContextFromGC_dylibloader_orig_xlib +#define XFlushGC XFlushGC_dylibloader_orig_xlib +#define XCreatePixmap XCreatePixmap_dylibloader_orig_xlib +#define XCreateBitmapFromData XCreateBitmapFromData_dylibloader_orig_xlib +#define XCreatePixmapFromBitmapData XCreatePixmapFromBitmapData_dylibloader_orig_xlib +#define XCreateSimpleWindow XCreateSimpleWindow_dylibloader_orig_xlib +#define XGetSelectionOwner XGetSelectionOwner_dylibloader_orig_xlib +#define XCreateWindow XCreateWindow_dylibloader_orig_xlib +#define XListInstalledColormaps XListInstalledColormaps_dylibloader_orig_xlib +#define XListFonts XListFonts_dylibloader_orig_xlib +#define XListFontsWithInfo XListFontsWithInfo_dylibloader_orig_xlib +#define XGetFontPath XGetFontPath_dylibloader_orig_xlib +#define XListExtensions XListExtensions_dylibloader_orig_xlib +#define XListProperties XListProperties_dylibloader_orig_xlib +#define XListHosts XListHosts_dylibloader_orig_xlib +#define XKeycodeToKeysym XKeycodeToKeysym_dylibloader_orig_xlib +#define XLookupKeysym XLookupKeysym_dylibloader_orig_xlib +#define XGetKeyboardMapping XGetKeyboardMapping_dylibloader_orig_xlib +#define XStringToKeysym XStringToKeysym_dylibloader_orig_xlib +#define XMaxRequestSize XMaxRequestSize_dylibloader_orig_xlib +#define XExtendedMaxRequestSize XExtendedMaxRequestSize_dylibloader_orig_xlib +#define XResourceManagerString XResourceManagerString_dylibloader_orig_xlib +#define XScreenResourceString XScreenResourceString_dylibloader_orig_xlib +#define XDisplayMotionBufferSize XDisplayMotionBufferSize_dylibloader_orig_xlib +#define XVisualIDFromVisual XVisualIDFromVisual_dylibloader_orig_xlib +#define XInitThreads XInitThreads_dylibloader_orig_xlib +#define XLockDisplay XLockDisplay_dylibloader_orig_xlib +#define XUnlockDisplay XUnlockDisplay_dylibloader_orig_xlib +#define XInitExtension XInitExtension_dylibloader_orig_xlib +#define XAddExtension XAddExtension_dylibloader_orig_xlib +#define XFindOnExtensionList XFindOnExtensionList_dylibloader_orig_xlib +#define XEHeadOfExtensionList XEHeadOfExtensionList_dylibloader_orig_xlib +#define XRootWindow XRootWindow_dylibloader_orig_xlib +#define XDefaultRootWindow XDefaultRootWindow_dylibloader_orig_xlib +#define XRootWindowOfScreen XRootWindowOfScreen_dylibloader_orig_xlib +#define XDefaultVisual XDefaultVisual_dylibloader_orig_xlib +#define XDefaultVisualOfScreen XDefaultVisualOfScreen_dylibloader_orig_xlib +#define XDefaultGC XDefaultGC_dylibloader_orig_xlib +#define XDefaultGCOfScreen XDefaultGCOfScreen_dylibloader_orig_xlib +#define XBlackPixel XBlackPixel_dylibloader_orig_xlib +#define XWhitePixel XWhitePixel_dylibloader_orig_xlib +#define XAllPlanes XAllPlanes_dylibloader_orig_xlib +#define XBlackPixelOfScreen XBlackPixelOfScreen_dylibloader_orig_xlib +#define XWhitePixelOfScreen XWhitePixelOfScreen_dylibloader_orig_xlib +#define XNextRequest XNextRequest_dylibloader_orig_xlib +#define XLastKnownRequestProcessed XLastKnownRequestProcessed_dylibloader_orig_xlib +#define XServerVendor XServerVendor_dylibloader_orig_xlib +#define XDisplayString XDisplayString_dylibloader_orig_xlib +#define XDefaultColormap XDefaultColormap_dylibloader_orig_xlib +#define XDefaultColormapOfScreen XDefaultColormapOfScreen_dylibloader_orig_xlib +#define XDisplayOfScreen XDisplayOfScreen_dylibloader_orig_xlib +#define XScreenOfDisplay XScreenOfDisplay_dylibloader_orig_xlib +#define XDefaultScreenOfDisplay XDefaultScreenOfDisplay_dylibloader_orig_xlib +#define XEventMaskOfScreen XEventMaskOfScreen_dylibloader_orig_xlib +#define XScreenNumberOfScreen XScreenNumberOfScreen_dylibloader_orig_xlib +#define XSetErrorHandler XSetErrorHandler_dylibloader_orig_xlib +#define XSetIOErrorHandler XSetIOErrorHandler_dylibloader_orig_xlib +#define XListPixmapFormats XListPixmapFormats_dylibloader_orig_xlib +#define XListDepths XListDepths_dylibloader_orig_xlib +#define XReconfigureWMWindow XReconfigureWMWindow_dylibloader_orig_xlib +#define XGetWMProtocols XGetWMProtocols_dylibloader_orig_xlib +#define XSetWMProtocols XSetWMProtocols_dylibloader_orig_xlib +#define XIconifyWindow XIconifyWindow_dylibloader_orig_xlib +#define XWithdrawWindow XWithdrawWindow_dylibloader_orig_xlib +#define XGetCommand XGetCommand_dylibloader_orig_xlib +#define XGetWMColormapWindows XGetWMColormapWindows_dylibloader_orig_xlib +#define XSetWMColormapWindows XSetWMColormapWindows_dylibloader_orig_xlib +#define XFreeStringList XFreeStringList_dylibloader_orig_xlib +#define XSetTransientForHint XSetTransientForHint_dylibloader_orig_xlib +#define XActivateScreenSaver XActivateScreenSaver_dylibloader_orig_xlib +#define XAddHost XAddHost_dylibloader_orig_xlib +#define XAddHosts XAddHosts_dylibloader_orig_xlib +#define XAddToExtensionList XAddToExtensionList_dylibloader_orig_xlib +#define XAddToSaveSet XAddToSaveSet_dylibloader_orig_xlib +#define XAllocColor XAllocColor_dylibloader_orig_xlib +#define XAllocColorCells XAllocColorCells_dylibloader_orig_xlib +#define XAllocColorPlanes XAllocColorPlanes_dylibloader_orig_xlib +#define XAllocNamedColor XAllocNamedColor_dylibloader_orig_xlib +#define XAllowEvents XAllowEvents_dylibloader_orig_xlib +#define XAutoRepeatOff XAutoRepeatOff_dylibloader_orig_xlib +#define XAutoRepeatOn XAutoRepeatOn_dylibloader_orig_xlib +#define XBell XBell_dylibloader_orig_xlib +#define XBitmapBitOrder XBitmapBitOrder_dylibloader_orig_xlib +#define XBitmapPad XBitmapPad_dylibloader_orig_xlib +#define XBitmapUnit XBitmapUnit_dylibloader_orig_xlib +#define XCellsOfScreen XCellsOfScreen_dylibloader_orig_xlib +#define XChangeActivePointerGrab XChangeActivePointerGrab_dylibloader_orig_xlib +#define XChangeGC XChangeGC_dylibloader_orig_xlib +#define XChangeKeyboardControl XChangeKeyboardControl_dylibloader_orig_xlib +#define XChangeKeyboardMapping XChangeKeyboardMapping_dylibloader_orig_xlib +#define XChangePointerControl XChangePointerControl_dylibloader_orig_xlib +#define XChangeProperty XChangeProperty_dylibloader_orig_xlib +#define XChangeSaveSet XChangeSaveSet_dylibloader_orig_xlib +#define XChangeWindowAttributes XChangeWindowAttributes_dylibloader_orig_xlib +#define XCheckIfEvent XCheckIfEvent_dylibloader_orig_xlib +#define XCheckMaskEvent XCheckMaskEvent_dylibloader_orig_xlib +#define XCheckTypedEvent XCheckTypedEvent_dylibloader_orig_xlib +#define XCheckTypedWindowEvent XCheckTypedWindowEvent_dylibloader_orig_xlib +#define XCheckWindowEvent XCheckWindowEvent_dylibloader_orig_xlib +#define XCirculateSubwindows XCirculateSubwindows_dylibloader_orig_xlib +#define XCirculateSubwindowsDown XCirculateSubwindowsDown_dylibloader_orig_xlib +#define XCirculateSubwindowsUp XCirculateSubwindowsUp_dylibloader_orig_xlib +#define XClearArea XClearArea_dylibloader_orig_xlib +#define XClearWindow XClearWindow_dylibloader_orig_xlib +#define XCloseDisplay XCloseDisplay_dylibloader_orig_xlib +#define XConfigureWindow XConfigureWindow_dylibloader_orig_xlib +#define XConnectionNumber XConnectionNumber_dylibloader_orig_xlib +#define XConvertSelection XConvertSelection_dylibloader_orig_xlib +#define XCopyArea XCopyArea_dylibloader_orig_xlib +#define XCopyGC XCopyGC_dylibloader_orig_xlib +#define XCopyPlane XCopyPlane_dylibloader_orig_xlib +#define XDefaultDepth XDefaultDepth_dylibloader_orig_xlib +#define XDefaultDepthOfScreen XDefaultDepthOfScreen_dylibloader_orig_xlib +#define XDefaultScreen XDefaultScreen_dylibloader_orig_xlib +#define XDefineCursor XDefineCursor_dylibloader_orig_xlib +#define XDeleteProperty XDeleteProperty_dylibloader_orig_xlib +#define XDestroyWindow XDestroyWindow_dylibloader_orig_xlib +#define XDestroySubwindows XDestroySubwindows_dylibloader_orig_xlib +#define XDoesBackingStore XDoesBackingStore_dylibloader_orig_xlib +#define XDoesSaveUnders XDoesSaveUnders_dylibloader_orig_xlib +#define XDisableAccessControl XDisableAccessControl_dylibloader_orig_xlib +#define XDisplayCells XDisplayCells_dylibloader_orig_xlib +#define XDisplayHeight XDisplayHeight_dylibloader_orig_xlib +#define XDisplayHeightMM XDisplayHeightMM_dylibloader_orig_xlib +#define XDisplayKeycodes XDisplayKeycodes_dylibloader_orig_xlib +#define XDisplayPlanes XDisplayPlanes_dylibloader_orig_xlib +#define XDisplayWidth XDisplayWidth_dylibloader_orig_xlib +#define XDisplayWidthMM XDisplayWidthMM_dylibloader_orig_xlib +#define XDrawArc XDrawArc_dylibloader_orig_xlib +#define XDrawArcs XDrawArcs_dylibloader_orig_xlib +#define XDrawImageString XDrawImageString_dylibloader_orig_xlib +#define XDrawImageString16 XDrawImageString16_dylibloader_orig_xlib +#define XDrawLine XDrawLine_dylibloader_orig_xlib +#define XDrawLines XDrawLines_dylibloader_orig_xlib +#define XDrawPoint XDrawPoint_dylibloader_orig_xlib +#define XDrawPoints XDrawPoints_dylibloader_orig_xlib +#define XDrawRectangle XDrawRectangle_dylibloader_orig_xlib +#define XDrawRectangles XDrawRectangles_dylibloader_orig_xlib +#define XDrawSegments XDrawSegments_dylibloader_orig_xlib +#define XDrawString XDrawString_dylibloader_orig_xlib +#define XDrawString16 XDrawString16_dylibloader_orig_xlib +#define XDrawText XDrawText_dylibloader_orig_xlib +#define XDrawText16 XDrawText16_dylibloader_orig_xlib +#define XEnableAccessControl XEnableAccessControl_dylibloader_orig_xlib +#define XEventsQueued XEventsQueued_dylibloader_orig_xlib +#define XFetchName XFetchName_dylibloader_orig_xlib +#define XFillArc XFillArc_dylibloader_orig_xlib +#define XFillArcs XFillArcs_dylibloader_orig_xlib +#define XFillPolygon XFillPolygon_dylibloader_orig_xlib +#define XFillRectangle XFillRectangle_dylibloader_orig_xlib +#define XFillRectangles XFillRectangles_dylibloader_orig_xlib +#define XFlush XFlush_dylibloader_orig_xlib +#define XForceScreenSaver XForceScreenSaver_dylibloader_orig_xlib +#define XFree XFree_dylibloader_orig_xlib +#define XFreeColormap XFreeColormap_dylibloader_orig_xlib +#define XFreeColors XFreeColors_dylibloader_orig_xlib +#define XFreeCursor XFreeCursor_dylibloader_orig_xlib +#define XFreeExtensionList XFreeExtensionList_dylibloader_orig_xlib +#define XFreeFont XFreeFont_dylibloader_orig_xlib +#define XFreeFontInfo XFreeFontInfo_dylibloader_orig_xlib +#define XFreeFontNames XFreeFontNames_dylibloader_orig_xlib +#define XFreeFontPath XFreeFontPath_dylibloader_orig_xlib +#define XFreeGC XFreeGC_dylibloader_orig_xlib +#define XFreeModifiermap XFreeModifiermap_dylibloader_orig_xlib +#define XFreePixmap XFreePixmap_dylibloader_orig_xlib +#define XGeometry XGeometry_dylibloader_orig_xlib +#define XGetErrorDatabaseText XGetErrorDatabaseText_dylibloader_orig_xlib +#define XGetErrorText XGetErrorText_dylibloader_orig_xlib +#define XGetFontProperty XGetFontProperty_dylibloader_orig_xlib +#define XGetGCValues XGetGCValues_dylibloader_orig_xlib +#define XGetGeometry XGetGeometry_dylibloader_orig_xlib +#define XGetIconName XGetIconName_dylibloader_orig_xlib +#define XGetInputFocus XGetInputFocus_dylibloader_orig_xlib +#define XGetKeyboardControl XGetKeyboardControl_dylibloader_orig_xlib +#define XGetPointerControl XGetPointerControl_dylibloader_orig_xlib +#define XGetPointerMapping XGetPointerMapping_dylibloader_orig_xlib +#define XGetScreenSaver XGetScreenSaver_dylibloader_orig_xlib +#define XGetTransientForHint XGetTransientForHint_dylibloader_orig_xlib +#define XGetWindowProperty XGetWindowProperty_dylibloader_orig_xlib +#define XGetWindowAttributes XGetWindowAttributes_dylibloader_orig_xlib +#define XGrabButton XGrabButton_dylibloader_orig_xlib +#define XGrabKey XGrabKey_dylibloader_orig_xlib +#define XGrabKeyboard XGrabKeyboard_dylibloader_orig_xlib +#define XGrabPointer XGrabPointer_dylibloader_orig_xlib +#define XGrabServer XGrabServer_dylibloader_orig_xlib +#define XHeightMMOfScreen XHeightMMOfScreen_dylibloader_orig_xlib +#define XHeightOfScreen XHeightOfScreen_dylibloader_orig_xlib +#define XIfEvent XIfEvent_dylibloader_orig_xlib +#define XImageByteOrder XImageByteOrder_dylibloader_orig_xlib +#define XInstallColormap XInstallColormap_dylibloader_orig_xlib +#define XKeysymToKeycode XKeysymToKeycode_dylibloader_orig_xlib +#define XKillClient XKillClient_dylibloader_orig_xlib +#define XLookupColor XLookupColor_dylibloader_orig_xlib +#define XLowerWindow XLowerWindow_dylibloader_orig_xlib +#define XMapRaised XMapRaised_dylibloader_orig_xlib +#define XMapSubwindows XMapSubwindows_dylibloader_orig_xlib +#define XMapWindow XMapWindow_dylibloader_orig_xlib +#define XMaskEvent XMaskEvent_dylibloader_orig_xlib +#define XMaxCmapsOfScreen XMaxCmapsOfScreen_dylibloader_orig_xlib +#define XMinCmapsOfScreen XMinCmapsOfScreen_dylibloader_orig_xlib +#define XMoveResizeWindow XMoveResizeWindow_dylibloader_orig_xlib +#define XMoveWindow XMoveWindow_dylibloader_orig_xlib +#define XNextEvent XNextEvent_dylibloader_orig_xlib +#define XNoOp XNoOp_dylibloader_orig_xlib +#define XParseColor XParseColor_dylibloader_orig_xlib +#define XParseGeometry XParseGeometry_dylibloader_orig_xlib +#define XPeekEvent XPeekEvent_dylibloader_orig_xlib +#define XPeekIfEvent XPeekIfEvent_dylibloader_orig_xlib +#define XPending XPending_dylibloader_orig_xlib +#define XPlanesOfScreen XPlanesOfScreen_dylibloader_orig_xlib +#define XProtocolRevision XProtocolRevision_dylibloader_orig_xlib +#define XProtocolVersion XProtocolVersion_dylibloader_orig_xlib +#define XPutBackEvent XPutBackEvent_dylibloader_orig_xlib +#define XPutImage XPutImage_dylibloader_orig_xlib +#define XQLength XQLength_dylibloader_orig_xlib +#define XQueryBestCursor XQueryBestCursor_dylibloader_orig_xlib +#define XQueryBestSize XQueryBestSize_dylibloader_orig_xlib +#define XQueryBestStipple XQueryBestStipple_dylibloader_orig_xlib +#define XQueryBestTile XQueryBestTile_dylibloader_orig_xlib +#define XQueryColor XQueryColor_dylibloader_orig_xlib +#define XQueryColors XQueryColors_dylibloader_orig_xlib +#define XQueryExtension XQueryExtension_dylibloader_orig_xlib +#define XQueryKeymap XQueryKeymap_dylibloader_orig_xlib +#define XQueryPointer XQueryPointer_dylibloader_orig_xlib +#define XQueryTextExtents XQueryTextExtents_dylibloader_orig_xlib +#define XQueryTextExtents16 XQueryTextExtents16_dylibloader_orig_xlib +#define XQueryTree XQueryTree_dylibloader_orig_xlib +#define XRaiseWindow XRaiseWindow_dylibloader_orig_xlib +#define XReadBitmapFile XReadBitmapFile_dylibloader_orig_xlib +#define XReadBitmapFileData XReadBitmapFileData_dylibloader_orig_xlib +#define XRebindKeysym XRebindKeysym_dylibloader_orig_xlib +#define XRecolorCursor XRecolorCursor_dylibloader_orig_xlib +#define XRefreshKeyboardMapping XRefreshKeyboardMapping_dylibloader_orig_xlib +#define XRemoveFromSaveSet XRemoveFromSaveSet_dylibloader_orig_xlib +#define XRemoveHost XRemoveHost_dylibloader_orig_xlib +#define XRemoveHosts XRemoveHosts_dylibloader_orig_xlib +#define XReparentWindow XReparentWindow_dylibloader_orig_xlib +#define XResetScreenSaver XResetScreenSaver_dylibloader_orig_xlib +#define XResizeWindow XResizeWindow_dylibloader_orig_xlib +#define XRestackWindows XRestackWindows_dylibloader_orig_xlib +#define XRotateBuffers XRotateBuffers_dylibloader_orig_xlib +#define XRotateWindowProperties XRotateWindowProperties_dylibloader_orig_xlib +#define XScreenCount XScreenCount_dylibloader_orig_xlib +#define XSelectInput XSelectInput_dylibloader_orig_xlib +#define XSendEvent XSendEvent_dylibloader_orig_xlib +#define XSetAccessControl XSetAccessControl_dylibloader_orig_xlib +#define XSetArcMode XSetArcMode_dylibloader_orig_xlib +#define XSetBackground XSetBackground_dylibloader_orig_xlib +#define XSetClipMask XSetClipMask_dylibloader_orig_xlib +#define XSetClipOrigin XSetClipOrigin_dylibloader_orig_xlib +#define XSetClipRectangles XSetClipRectangles_dylibloader_orig_xlib +#define XSetCloseDownMode XSetCloseDownMode_dylibloader_orig_xlib +#define XSetCommand XSetCommand_dylibloader_orig_xlib +#define XSetDashes XSetDashes_dylibloader_orig_xlib +#define XSetFillRule XSetFillRule_dylibloader_orig_xlib +#define XSetFillStyle XSetFillStyle_dylibloader_orig_xlib +#define XSetFont XSetFont_dylibloader_orig_xlib +#define XSetFontPath XSetFontPath_dylibloader_orig_xlib +#define XSetForeground XSetForeground_dylibloader_orig_xlib +#define XSetFunction XSetFunction_dylibloader_orig_xlib +#define XSetGraphicsExposures XSetGraphicsExposures_dylibloader_orig_xlib +#define XSetIconName XSetIconName_dylibloader_orig_xlib +#define XSetInputFocus XSetInputFocus_dylibloader_orig_xlib +#define XSetLineAttributes XSetLineAttributes_dylibloader_orig_xlib +#define XSetModifierMapping XSetModifierMapping_dylibloader_orig_xlib +#define XSetPlaneMask XSetPlaneMask_dylibloader_orig_xlib +#define XSetPointerMapping XSetPointerMapping_dylibloader_orig_xlib +#define XSetScreenSaver XSetScreenSaver_dylibloader_orig_xlib +#define XSetSelectionOwner XSetSelectionOwner_dylibloader_orig_xlib +#define XSetState XSetState_dylibloader_orig_xlib +#define XSetStipple XSetStipple_dylibloader_orig_xlib +#define XSetSubwindowMode XSetSubwindowMode_dylibloader_orig_xlib +#define XSetTSOrigin XSetTSOrigin_dylibloader_orig_xlib +#define XSetTile XSetTile_dylibloader_orig_xlib +#define XSetWindowBackground XSetWindowBackground_dylibloader_orig_xlib +#define XSetWindowBackgroundPixmap XSetWindowBackgroundPixmap_dylibloader_orig_xlib +#define XSetWindowBorder XSetWindowBorder_dylibloader_orig_xlib +#define XSetWindowBorderPixmap XSetWindowBorderPixmap_dylibloader_orig_xlib +#define XSetWindowBorderWidth XSetWindowBorderWidth_dylibloader_orig_xlib +#define XSetWindowColormap XSetWindowColormap_dylibloader_orig_xlib +#define XStoreBuffer XStoreBuffer_dylibloader_orig_xlib +#define XStoreBytes XStoreBytes_dylibloader_orig_xlib +#define XStoreColor XStoreColor_dylibloader_orig_xlib +#define XStoreColors XStoreColors_dylibloader_orig_xlib +#define XStoreName XStoreName_dylibloader_orig_xlib +#define XStoreNamedColor XStoreNamedColor_dylibloader_orig_xlib +#define XSync XSync_dylibloader_orig_xlib +#define XTextExtents XTextExtents_dylibloader_orig_xlib +#define XTextExtents16 XTextExtents16_dylibloader_orig_xlib +#define XTextWidth XTextWidth_dylibloader_orig_xlib +#define XTextWidth16 XTextWidth16_dylibloader_orig_xlib +#define XTranslateCoordinates XTranslateCoordinates_dylibloader_orig_xlib +#define XUndefineCursor XUndefineCursor_dylibloader_orig_xlib +#define XUngrabButton XUngrabButton_dylibloader_orig_xlib +#define XUngrabKey XUngrabKey_dylibloader_orig_xlib +#define XUngrabKeyboard XUngrabKeyboard_dylibloader_orig_xlib +#define XUngrabPointer XUngrabPointer_dylibloader_orig_xlib +#define XUngrabServer XUngrabServer_dylibloader_orig_xlib +#define XUninstallColormap XUninstallColormap_dylibloader_orig_xlib +#define XUnloadFont XUnloadFont_dylibloader_orig_xlib +#define XUnmapSubwindows XUnmapSubwindows_dylibloader_orig_xlib +#define XUnmapWindow XUnmapWindow_dylibloader_orig_xlib +#define XVendorRelease XVendorRelease_dylibloader_orig_xlib +#define XWarpPointer XWarpPointer_dylibloader_orig_xlib +#define XWidthMMOfScreen XWidthMMOfScreen_dylibloader_orig_xlib +#define XWidthOfScreen XWidthOfScreen_dylibloader_orig_xlib +#define XWindowEvent XWindowEvent_dylibloader_orig_xlib +#define XWriteBitmapFile XWriteBitmapFile_dylibloader_orig_xlib +#define XSupportsLocale XSupportsLocale_dylibloader_orig_xlib +#define XSetLocaleModifiers XSetLocaleModifiers_dylibloader_orig_xlib +#define XOpenOM XOpenOM_dylibloader_orig_xlib +#define XCloseOM XCloseOM_dylibloader_orig_xlib +#define XSetOMValues XSetOMValues_dylibloader_orig_xlib +#define XGetOMValues XGetOMValues_dylibloader_orig_xlib +#define XDisplayOfOM XDisplayOfOM_dylibloader_orig_xlib +#define XLocaleOfOM XLocaleOfOM_dylibloader_orig_xlib +#define XCreateOC XCreateOC_dylibloader_orig_xlib +#define XDestroyOC XDestroyOC_dylibloader_orig_xlib +#define XOMOfOC XOMOfOC_dylibloader_orig_xlib +#define XSetOCValues XSetOCValues_dylibloader_orig_xlib +#define XGetOCValues XGetOCValues_dylibloader_orig_xlib +#define XCreateFontSet XCreateFontSet_dylibloader_orig_xlib +#define XFreeFontSet XFreeFontSet_dylibloader_orig_xlib +#define XFontsOfFontSet XFontsOfFontSet_dylibloader_orig_xlib +#define XBaseFontNameListOfFontSet XBaseFontNameListOfFontSet_dylibloader_orig_xlib +#define XLocaleOfFontSet XLocaleOfFontSet_dylibloader_orig_xlib +#define XContextDependentDrawing XContextDependentDrawing_dylibloader_orig_xlib +#define XDirectionalDependentDrawing XDirectionalDependentDrawing_dylibloader_orig_xlib +#define XContextualDrawing XContextualDrawing_dylibloader_orig_xlib +#define XExtentsOfFontSet XExtentsOfFontSet_dylibloader_orig_xlib +#define XmbTextEscapement XmbTextEscapement_dylibloader_orig_xlib +#define XwcTextEscapement XwcTextEscapement_dylibloader_orig_xlib +#define Xutf8TextEscapement Xutf8TextEscapement_dylibloader_orig_xlib +#define XmbTextExtents XmbTextExtents_dylibloader_orig_xlib +#define XwcTextExtents XwcTextExtents_dylibloader_orig_xlib +#define Xutf8TextExtents Xutf8TextExtents_dylibloader_orig_xlib +#define XmbTextPerCharExtents XmbTextPerCharExtents_dylibloader_orig_xlib +#define XwcTextPerCharExtents XwcTextPerCharExtents_dylibloader_orig_xlib +#define Xutf8TextPerCharExtents Xutf8TextPerCharExtents_dylibloader_orig_xlib +#define XmbDrawText XmbDrawText_dylibloader_orig_xlib +#define XwcDrawText XwcDrawText_dylibloader_orig_xlib +#define Xutf8DrawText Xutf8DrawText_dylibloader_orig_xlib +#define XmbDrawString XmbDrawString_dylibloader_orig_xlib +#define XwcDrawString XwcDrawString_dylibloader_orig_xlib +#define Xutf8DrawString Xutf8DrawString_dylibloader_orig_xlib +#define XmbDrawImageString XmbDrawImageString_dylibloader_orig_xlib +#define XwcDrawImageString XwcDrawImageString_dylibloader_orig_xlib +#define Xutf8DrawImageString Xutf8DrawImageString_dylibloader_orig_xlib +#define XOpenIM XOpenIM_dylibloader_orig_xlib +#define XCloseIM XCloseIM_dylibloader_orig_xlib +#define XGetIMValues XGetIMValues_dylibloader_orig_xlib +#define XSetIMValues XSetIMValues_dylibloader_orig_xlib +#define XDisplayOfIM XDisplayOfIM_dylibloader_orig_xlib +#define XLocaleOfIM XLocaleOfIM_dylibloader_orig_xlib +#define XCreateIC XCreateIC_dylibloader_orig_xlib +#define XDestroyIC XDestroyIC_dylibloader_orig_xlib +#define XSetICFocus XSetICFocus_dylibloader_orig_xlib +#define XUnsetICFocus XUnsetICFocus_dylibloader_orig_xlib +#define XwcResetIC XwcResetIC_dylibloader_orig_xlib +#define XmbResetIC XmbResetIC_dylibloader_orig_xlib +#define Xutf8ResetIC Xutf8ResetIC_dylibloader_orig_xlib +#define XSetICValues XSetICValues_dylibloader_orig_xlib +#define XGetICValues XGetICValues_dylibloader_orig_xlib +#define XIMOfIC XIMOfIC_dylibloader_orig_xlib +#define XFilterEvent XFilterEvent_dylibloader_orig_xlib +#define XmbLookupString XmbLookupString_dylibloader_orig_xlib +#define XwcLookupString XwcLookupString_dylibloader_orig_xlib +#define Xutf8LookupString Xutf8LookupString_dylibloader_orig_xlib +#define XVaCreateNestedList XVaCreateNestedList_dylibloader_orig_xlib +#define XRegisterIMInstantiateCallback XRegisterIMInstantiateCallback_dylibloader_orig_xlib +#define XUnregisterIMInstantiateCallback XUnregisterIMInstantiateCallback_dylibloader_orig_xlib +#define XInternalConnectionNumbers XInternalConnectionNumbers_dylibloader_orig_xlib +#define XProcessInternalConnection XProcessInternalConnection_dylibloader_orig_xlib +#define XAddConnectionWatch XAddConnectionWatch_dylibloader_orig_xlib +#define XRemoveConnectionWatch XRemoveConnectionWatch_dylibloader_orig_xlib +#define XSetAuthorization XSetAuthorization_dylibloader_orig_xlib +#define _Xmbtowc _Xmbtowc_dylibloader_orig_xlib +#define _Xwctomb _Xwctomb_dylibloader_orig_xlib +#define XGetEventData XGetEventData_dylibloader_orig_xlib +#define XFreeEventData XFreeEventData_dylibloader_orig_xlib +#define XAllocClassHint XAllocClassHint_dylibloader_orig_xlib +#define XAllocIconSize XAllocIconSize_dylibloader_orig_xlib +#define XAllocSizeHints XAllocSizeHints_dylibloader_orig_xlib +#define XAllocStandardColormap XAllocStandardColormap_dylibloader_orig_xlib +#define XAllocWMHints XAllocWMHints_dylibloader_orig_xlib +#define XClipBox XClipBox_dylibloader_orig_xlib +#define XCreateRegion XCreateRegion_dylibloader_orig_xlib +#define XDefaultString XDefaultString_dylibloader_orig_xlib +#define XDeleteContext XDeleteContext_dylibloader_orig_xlib +#define XDestroyRegion XDestroyRegion_dylibloader_orig_xlib +#define XEmptyRegion XEmptyRegion_dylibloader_orig_xlib +#define XEqualRegion XEqualRegion_dylibloader_orig_xlib +#define XFindContext XFindContext_dylibloader_orig_xlib +#define XGetClassHint XGetClassHint_dylibloader_orig_xlib +#define XGetIconSizes XGetIconSizes_dylibloader_orig_xlib +#define XGetNormalHints XGetNormalHints_dylibloader_orig_xlib +#define XGetRGBColormaps XGetRGBColormaps_dylibloader_orig_xlib +#define XGetSizeHints XGetSizeHints_dylibloader_orig_xlib +#define XGetStandardColormap XGetStandardColormap_dylibloader_orig_xlib +#define XGetTextProperty XGetTextProperty_dylibloader_orig_xlib +#define XGetVisualInfo XGetVisualInfo_dylibloader_orig_xlib +#define XGetWMClientMachine XGetWMClientMachine_dylibloader_orig_xlib +#define XGetWMHints XGetWMHints_dylibloader_orig_xlib +#define XGetWMIconName XGetWMIconName_dylibloader_orig_xlib +#define XGetWMName XGetWMName_dylibloader_orig_xlib +#define XGetWMNormalHints XGetWMNormalHints_dylibloader_orig_xlib +#define XGetWMSizeHints XGetWMSizeHints_dylibloader_orig_xlib +#define XGetZoomHints XGetZoomHints_dylibloader_orig_xlib +#define XIntersectRegion XIntersectRegion_dylibloader_orig_xlib +#define XConvertCase XConvertCase_dylibloader_orig_xlib +#define XLookupString XLookupString_dylibloader_orig_xlib +#define XMatchVisualInfo XMatchVisualInfo_dylibloader_orig_xlib +#define XOffsetRegion XOffsetRegion_dylibloader_orig_xlib +#define XPointInRegion XPointInRegion_dylibloader_orig_xlib +#define XPolygonRegion XPolygonRegion_dylibloader_orig_xlib +#define XRectInRegion XRectInRegion_dylibloader_orig_xlib +#define XSaveContext XSaveContext_dylibloader_orig_xlib +#define XSetClassHint XSetClassHint_dylibloader_orig_xlib +#define XSetIconSizes XSetIconSizes_dylibloader_orig_xlib +#define XSetNormalHints XSetNormalHints_dylibloader_orig_xlib +#define XSetRGBColormaps XSetRGBColormaps_dylibloader_orig_xlib +#define XSetSizeHints XSetSizeHints_dylibloader_orig_xlib +#define XSetStandardProperties XSetStandardProperties_dylibloader_orig_xlib +#define XSetTextProperty XSetTextProperty_dylibloader_orig_xlib +#define XSetWMClientMachine XSetWMClientMachine_dylibloader_orig_xlib +#define XSetWMHints XSetWMHints_dylibloader_orig_xlib +#define XSetWMIconName XSetWMIconName_dylibloader_orig_xlib +#define XSetWMName XSetWMName_dylibloader_orig_xlib +#define XSetWMNormalHints XSetWMNormalHints_dylibloader_orig_xlib +#define XSetWMProperties XSetWMProperties_dylibloader_orig_xlib +#define XmbSetWMProperties XmbSetWMProperties_dylibloader_orig_xlib +#define Xutf8SetWMProperties Xutf8SetWMProperties_dylibloader_orig_xlib +#define XSetWMSizeHints XSetWMSizeHints_dylibloader_orig_xlib +#define XSetRegion XSetRegion_dylibloader_orig_xlib +#define XSetStandardColormap XSetStandardColormap_dylibloader_orig_xlib +#define XSetZoomHints XSetZoomHints_dylibloader_orig_xlib +#define XShrinkRegion XShrinkRegion_dylibloader_orig_xlib +#define XStringListToTextProperty XStringListToTextProperty_dylibloader_orig_xlib +#define XSubtractRegion XSubtractRegion_dylibloader_orig_xlib +#define XmbTextListToTextProperty XmbTextListToTextProperty_dylibloader_orig_xlib +#define XwcTextListToTextProperty XwcTextListToTextProperty_dylibloader_orig_xlib +#define Xutf8TextListToTextProperty Xutf8TextListToTextProperty_dylibloader_orig_xlib +#define XwcFreeStringList XwcFreeStringList_dylibloader_orig_xlib +#define XTextPropertyToStringList XTextPropertyToStringList_dylibloader_orig_xlib +#define XmbTextPropertyToTextList XmbTextPropertyToTextList_dylibloader_orig_xlib +#define XwcTextPropertyToTextList XwcTextPropertyToTextList_dylibloader_orig_xlib +#define Xutf8TextPropertyToTextList Xutf8TextPropertyToTextList_dylibloader_orig_xlib +#define XUnionRectWithRegion XUnionRectWithRegion_dylibloader_orig_xlib +#define XUnionRegion XUnionRegion_dylibloader_orig_xlib +#define XWMGeometry XWMGeometry_dylibloader_orig_xlib +#define XXorRegion XXorRegion_dylibloader_orig_xlib +#define XkbIgnoreExtension XkbIgnoreExtension_dylibloader_orig_xlib +#define XkbOpenDisplay XkbOpenDisplay_dylibloader_orig_xlib +#define XkbQueryExtension XkbQueryExtension_dylibloader_orig_xlib +#define XkbUseExtension XkbUseExtension_dylibloader_orig_xlib +#define XkbLibraryVersion XkbLibraryVersion_dylibloader_orig_xlib +#define XkbSetXlibControls XkbSetXlibControls_dylibloader_orig_xlib +#define XkbGetXlibControls XkbGetXlibControls_dylibloader_orig_xlib +#define XkbXlibControlsImplemented XkbXlibControlsImplemented_dylibloader_orig_xlib +#define XkbSetAtomFuncs XkbSetAtomFuncs_dylibloader_orig_xlib +#define XkbKeycodeToKeysym XkbKeycodeToKeysym_dylibloader_orig_xlib +#define XkbKeysymToModifiers XkbKeysymToModifiers_dylibloader_orig_xlib +#define XkbLookupKeySym XkbLookupKeySym_dylibloader_orig_xlib +#define XkbLookupKeyBinding XkbLookupKeyBinding_dylibloader_orig_xlib +#define XkbTranslateKeyCode XkbTranslateKeyCode_dylibloader_orig_xlib +#define XkbTranslateKeySym XkbTranslateKeySym_dylibloader_orig_xlib +#define XkbSetAutoRepeatRate XkbSetAutoRepeatRate_dylibloader_orig_xlib +#define XkbGetAutoRepeatRate XkbGetAutoRepeatRate_dylibloader_orig_xlib +#define XkbChangeEnabledControls XkbChangeEnabledControls_dylibloader_orig_xlib +#define XkbDeviceBell XkbDeviceBell_dylibloader_orig_xlib +#define XkbForceDeviceBell XkbForceDeviceBell_dylibloader_orig_xlib +#define XkbDeviceBellEvent XkbDeviceBellEvent_dylibloader_orig_xlib +#define XkbBell XkbBell_dylibloader_orig_xlib +#define XkbForceBell XkbForceBell_dylibloader_orig_xlib +#define XkbBellEvent XkbBellEvent_dylibloader_orig_xlib +#define XkbSelectEvents XkbSelectEvents_dylibloader_orig_xlib +#define XkbSelectEventDetails XkbSelectEventDetails_dylibloader_orig_xlib +#define XkbNoteMapChanges XkbNoteMapChanges_dylibloader_orig_xlib +#define XkbNoteNameChanges XkbNoteNameChanges_dylibloader_orig_xlib +#define XkbGetIndicatorState XkbGetIndicatorState_dylibloader_orig_xlib +#define XkbGetIndicatorMap XkbGetIndicatorMap_dylibloader_orig_xlib +#define XkbSetIndicatorMap XkbSetIndicatorMap_dylibloader_orig_xlib +#define XkbGetNamedIndicator XkbGetNamedIndicator_dylibloader_orig_xlib +#define XkbGetNamedDeviceIndicator XkbGetNamedDeviceIndicator_dylibloader_orig_xlib +#define XkbSetNamedIndicator XkbSetNamedIndicator_dylibloader_orig_xlib +#define XkbSetNamedDeviceIndicator XkbSetNamedDeviceIndicator_dylibloader_orig_xlib +#define XkbLockModifiers XkbLockModifiers_dylibloader_orig_xlib +#define XkbLatchModifiers XkbLatchModifiers_dylibloader_orig_xlib +#define XkbLockGroup XkbLockGroup_dylibloader_orig_xlib +#define XkbLatchGroup XkbLatchGroup_dylibloader_orig_xlib +#define XkbSetServerInternalMods XkbSetServerInternalMods_dylibloader_orig_xlib +#define XkbSetIgnoreLockMods XkbSetIgnoreLockMods_dylibloader_orig_xlib +#define XkbVirtualModsToReal XkbVirtualModsToReal_dylibloader_orig_xlib +#define XkbComputeEffectiveMap XkbComputeEffectiveMap_dylibloader_orig_xlib +#define XkbInitCanonicalKeyTypes XkbInitCanonicalKeyTypes_dylibloader_orig_xlib +#define XkbAllocKeyboard XkbAllocKeyboard_dylibloader_orig_xlib +#define XkbFreeKeyboard XkbFreeKeyboard_dylibloader_orig_xlib +#define XkbAllocClientMap XkbAllocClientMap_dylibloader_orig_xlib +#define XkbAllocServerMap XkbAllocServerMap_dylibloader_orig_xlib +#define XkbFreeClientMap XkbFreeClientMap_dylibloader_orig_xlib +#define XkbFreeServerMap XkbFreeServerMap_dylibloader_orig_xlib +#define XkbAddKeyType XkbAddKeyType_dylibloader_orig_xlib +#define XkbAllocIndicatorMaps XkbAllocIndicatorMaps_dylibloader_orig_xlib +#define XkbFreeIndicatorMaps XkbFreeIndicatorMaps_dylibloader_orig_xlib +#define XkbGetMap XkbGetMap_dylibloader_orig_xlib +#define XkbGetUpdatedMap XkbGetUpdatedMap_dylibloader_orig_xlib +#define XkbGetMapChanges XkbGetMapChanges_dylibloader_orig_xlib +#define XkbRefreshKeyboardMapping XkbRefreshKeyboardMapping_dylibloader_orig_xlib +#define XkbGetKeyTypes XkbGetKeyTypes_dylibloader_orig_xlib +#define XkbGetKeySyms XkbGetKeySyms_dylibloader_orig_xlib +#define XkbGetKeyActions XkbGetKeyActions_dylibloader_orig_xlib +#define XkbGetKeyBehaviors XkbGetKeyBehaviors_dylibloader_orig_xlib +#define XkbGetVirtualMods XkbGetVirtualMods_dylibloader_orig_xlib +#define XkbGetKeyExplicitComponents XkbGetKeyExplicitComponents_dylibloader_orig_xlib +#define XkbGetKeyModifierMap XkbGetKeyModifierMap_dylibloader_orig_xlib +#define XkbGetKeyVirtualModMap XkbGetKeyVirtualModMap_dylibloader_orig_xlib +#define XkbAllocControls XkbAllocControls_dylibloader_orig_xlib +#define XkbFreeControls XkbFreeControls_dylibloader_orig_xlib +#define XkbGetControls XkbGetControls_dylibloader_orig_xlib +#define XkbSetControls XkbSetControls_dylibloader_orig_xlib +#define XkbNoteControlsChanges XkbNoteControlsChanges_dylibloader_orig_xlib +#define XkbAllocCompatMap XkbAllocCompatMap_dylibloader_orig_xlib +#define XkbFreeCompatMap XkbFreeCompatMap_dylibloader_orig_xlib +#define XkbGetCompatMap XkbGetCompatMap_dylibloader_orig_xlib +#define XkbSetCompatMap XkbSetCompatMap_dylibloader_orig_xlib +#define XkbAllocNames XkbAllocNames_dylibloader_orig_xlib +#define XkbGetNames XkbGetNames_dylibloader_orig_xlib +#define XkbSetNames XkbSetNames_dylibloader_orig_xlib +#define XkbChangeNames XkbChangeNames_dylibloader_orig_xlib +#define XkbFreeNames XkbFreeNames_dylibloader_orig_xlib +#define XkbGetState XkbGetState_dylibloader_orig_xlib +#define XkbSetMap XkbSetMap_dylibloader_orig_xlib +#define XkbChangeMap XkbChangeMap_dylibloader_orig_xlib +#define XkbSetDetectableAutoRepeat XkbSetDetectableAutoRepeat_dylibloader_orig_xlib +#define XkbGetDetectableAutoRepeat XkbGetDetectableAutoRepeat_dylibloader_orig_xlib +#define XkbSetAutoResetControls XkbSetAutoResetControls_dylibloader_orig_xlib +#define XkbGetAutoResetControls XkbGetAutoResetControls_dylibloader_orig_xlib +#define XkbSetPerClientControls XkbSetPerClientControls_dylibloader_orig_xlib +#define XkbGetPerClientControls XkbGetPerClientControls_dylibloader_orig_xlib +#define XkbCopyKeyType XkbCopyKeyType_dylibloader_orig_xlib +#define XkbCopyKeyTypes XkbCopyKeyTypes_dylibloader_orig_xlib +#define XkbResizeKeyType XkbResizeKeyType_dylibloader_orig_xlib +#define XkbResizeKeySyms XkbResizeKeySyms_dylibloader_orig_xlib +#define XkbResizeKeyActions XkbResizeKeyActions_dylibloader_orig_xlib +#define XkbChangeTypesOfKey XkbChangeTypesOfKey_dylibloader_orig_xlib +#define XkbChangeKeycodeRange XkbChangeKeycodeRange_dylibloader_orig_xlib +#define XkbListComponents XkbListComponents_dylibloader_orig_xlib +#define XkbFreeComponentList XkbFreeComponentList_dylibloader_orig_xlib +#define XkbGetKeyboard XkbGetKeyboard_dylibloader_orig_xlib +#define XkbGetKeyboardByName XkbGetKeyboardByName_dylibloader_orig_xlib +#define XkbKeyTypesForCoreSymbols XkbKeyTypesForCoreSymbols_dylibloader_orig_xlib +#define XkbApplyCompatMapToKey XkbApplyCompatMapToKey_dylibloader_orig_xlib +#define XkbUpdateMapFromCore XkbUpdateMapFromCore_dylibloader_orig_xlib +#define XkbAddDeviceLedInfo XkbAddDeviceLedInfo_dylibloader_orig_xlib +#define XkbResizeDeviceButtonActions XkbResizeDeviceButtonActions_dylibloader_orig_xlib +#define XkbAllocDeviceInfo XkbAllocDeviceInfo_dylibloader_orig_xlib +#define XkbFreeDeviceInfo XkbFreeDeviceInfo_dylibloader_orig_xlib +#define XkbNoteDeviceChanges XkbNoteDeviceChanges_dylibloader_orig_xlib +#define XkbGetDeviceInfo XkbGetDeviceInfo_dylibloader_orig_xlib +#define XkbGetDeviceInfoChanges XkbGetDeviceInfoChanges_dylibloader_orig_xlib +#define XkbGetDeviceButtonActions XkbGetDeviceButtonActions_dylibloader_orig_xlib +#define XkbGetDeviceLedInfo XkbGetDeviceLedInfo_dylibloader_orig_xlib +#define XkbSetDeviceInfo XkbSetDeviceInfo_dylibloader_orig_xlib +#define XkbChangeDeviceInfo XkbChangeDeviceInfo_dylibloader_orig_xlib +#define XkbSetDeviceLedInfo XkbSetDeviceLedInfo_dylibloader_orig_xlib +#define XkbSetDeviceButtonActions XkbSetDeviceButtonActions_dylibloader_orig_xlib +#define XkbToControl XkbToControl_dylibloader_orig_xlib +#define XkbSetDebuggingFlags XkbSetDebuggingFlags_dylibloader_orig_xlib +#define XkbApplyVirtualModChanges XkbApplyVirtualModChanges_dylibloader_orig_xlib +#define XkbUpdateActionVirtualMods XkbUpdateActionVirtualMods_dylibloader_orig_xlib +#define XkbUpdateKeyTypeVirtualMods XkbUpdateKeyTypeVirtualMods_dylibloader_orig_xlib +#include "thirdparty/linuxbsd_headers/X11/Xlib.h" +#include "thirdparty/linuxbsd_headers/X11/Xutil.h" +#include "thirdparty/linuxbsd_headers/X11/XKBlib.h" +#undef _Xmblen +#undef XLoadQueryFont +#undef XQueryFont +#undef XGetMotionEvents +#undef XDeleteModifiermapEntry +#undef XGetModifierMapping +#undef XInsertModifiermapEntry +#undef XNewModifiermap +#undef XCreateImage +#undef XInitImage +#undef XGetImage +#undef XGetSubImage +#undef XOpenDisplay +#undef XrmInitialize +#undef XFetchBytes +#undef XFetchBuffer +#undef XGetAtomName +#undef XGetAtomNames +#undef XGetDefault +#undef XDisplayName +#undef XKeysymToString +#undef XSynchronize +#undef XSetAfterFunction +#undef XInternAtom +#undef XInternAtoms +#undef XCopyColormapAndFree +#undef XCreateColormap +#undef XCreatePixmapCursor +#undef XCreateGlyphCursor +#undef XCreateFontCursor +#undef XLoadFont +#undef XCreateGC +#undef XGContextFromGC +#undef XFlushGC +#undef XCreatePixmap +#undef XCreateBitmapFromData +#undef XCreatePixmapFromBitmapData +#undef XCreateSimpleWindow +#undef XGetSelectionOwner +#undef XCreateWindow +#undef XListInstalledColormaps +#undef XListFonts +#undef XListFontsWithInfo +#undef XGetFontPath +#undef XListExtensions +#undef XListProperties +#undef XListHosts +#undef XKeycodeToKeysym +#undef XLookupKeysym +#undef XGetKeyboardMapping +#undef XStringToKeysym +#undef XMaxRequestSize +#undef XExtendedMaxRequestSize +#undef XResourceManagerString +#undef XScreenResourceString +#undef XDisplayMotionBufferSize +#undef XVisualIDFromVisual +#undef XInitThreads +#undef XLockDisplay +#undef XUnlockDisplay +#undef XInitExtension +#undef XAddExtension +#undef XFindOnExtensionList +#undef XEHeadOfExtensionList +#undef XRootWindow +#undef XDefaultRootWindow +#undef XRootWindowOfScreen +#undef XDefaultVisual +#undef XDefaultVisualOfScreen +#undef XDefaultGC +#undef XDefaultGCOfScreen +#undef XBlackPixel +#undef XWhitePixel +#undef XAllPlanes +#undef XBlackPixelOfScreen +#undef XWhitePixelOfScreen +#undef XNextRequest +#undef XLastKnownRequestProcessed +#undef XServerVendor +#undef XDisplayString +#undef XDefaultColormap +#undef XDefaultColormapOfScreen +#undef XDisplayOfScreen +#undef XScreenOfDisplay +#undef XDefaultScreenOfDisplay +#undef XEventMaskOfScreen +#undef XScreenNumberOfScreen +#undef XSetErrorHandler +#undef XSetIOErrorHandler +#undef XListPixmapFormats +#undef XListDepths +#undef XReconfigureWMWindow +#undef XGetWMProtocols +#undef XSetWMProtocols +#undef XIconifyWindow +#undef XWithdrawWindow +#undef XGetCommand +#undef XGetWMColormapWindows +#undef XSetWMColormapWindows +#undef XFreeStringList +#undef XSetTransientForHint +#undef XActivateScreenSaver +#undef XAddHost +#undef XAddHosts +#undef XAddToExtensionList +#undef XAddToSaveSet +#undef XAllocColor +#undef XAllocColorCells +#undef XAllocColorPlanes +#undef XAllocNamedColor +#undef XAllowEvents +#undef XAutoRepeatOff +#undef XAutoRepeatOn +#undef XBell +#undef XBitmapBitOrder +#undef XBitmapPad +#undef XBitmapUnit +#undef XCellsOfScreen +#undef XChangeActivePointerGrab +#undef XChangeGC +#undef XChangeKeyboardControl +#undef XChangeKeyboardMapping +#undef XChangePointerControl +#undef XChangeProperty +#undef XChangeSaveSet +#undef XChangeWindowAttributes +#undef XCheckIfEvent +#undef XCheckMaskEvent +#undef XCheckTypedEvent +#undef XCheckTypedWindowEvent +#undef XCheckWindowEvent +#undef XCirculateSubwindows +#undef XCirculateSubwindowsDown +#undef XCirculateSubwindowsUp +#undef XClearArea +#undef XClearWindow +#undef XCloseDisplay +#undef XConfigureWindow +#undef XConnectionNumber +#undef XConvertSelection +#undef XCopyArea +#undef XCopyGC +#undef XCopyPlane +#undef XDefaultDepth +#undef XDefaultDepthOfScreen +#undef XDefaultScreen +#undef XDefineCursor +#undef XDeleteProperty +#undef XDestroyWindow +#undef XDestroySubwindows +#undef XDoesBackingStore +#undef XDoesSaveUnders +#undef XDisableAccessControl +#undef XDisplayCells +#undef XDisplayHeight +#undef XDisplayHeightMM +#undef XDisplayKeycodes +#undef XDisplayPlanes +#undef XDisplayWidth +#undef XDisplayWidthMM +#undef XDrawArc +#undef XDrawArcs +#undef XDrawImageString +#undef XDrawImageString16 +#undef XDrawLine +#undef XDrawLines +#undef XDrawPoint +#undef XDrawPoints +#undef XDrawRectangle +#undef XDrawRectangles +#undef XDrawSegments +#undef XDrawString +#undef XDrawString16 +#undef XDrawText +#undef XDrawText16 +#undef XEnableAccessControl +#undef XEventsQueued +#undef XFetchName +#undef XFillArc +#undef XFillArcs +#undef XFillPolygon +#undef XFillRectangle +#undef XFillRectangles +#undef XFlush +#undef XForceScreenSaver +#undef XFree +#undef XFreeColormap +#undef XFreeColors +#undef XFreeCursor +#undef XFreeExtensionList +#undef XFreeFont +#undef XFreeFontInfo +#undef XFreeFontNames +#undef XFreeFontPath +#undef XFreeGC +#undef XFreeModifiermap +#undef XFreePixmap +#undef XGeometry +#undef XGetErrorDatabaseText +#undef XGetErrorText +#undef XGetFontProperty +#undef XGetGCValues +#undef XGetGeometry +#undef XGetIconName +#undef XGetInputFocus +#undef XGetKeyboardControl +#undef XGetPointerControl +#undef XGetPointerMapping +#undef XGetScreenSaver +#undef XGetTransientForHint +#undef XGetWindowProperty +#undef XGetWindowAttributes +#undef XGrabButton +#undef XGrabKey +#undef XGrabKeyboard +#undef XGrabPointer +#undef XGrabServer +#undef XHeightMMOfScreen +#undef XHeightOfScreen +#undef XIfEvent +#undef XImageByteOrder +#undef XInstallColormap +#undef XKeysymToKeycode +#undef XKillClient +#undef XLookupColor +#undef XLowerWindow +#undef XMapRaised +#undef XMapSubwindows +#undef XMapWindow +#undef XMaskEvent +#undef XMaxCmapsOfScreen +#undef XMinCmapsOfScreen +#undef XMoveResizeWindow +#undef XMoveWindow +#undef XNextEvent +#undef XNoOp +#undef XParseColor +#undef XParseGeometry +#undef XPeekEvent +#undef XPeekIfEvent +#undef XPending +#undef XPlanesOfScreen +#undef XProtocolRevision +#undef XProtocolVersion +#undef XPutBackEvent +#undef XPutImage +#undef XQLength +#undef XQueryBestCursor +#undef XQueryBestSize +#undef XQueryBestStipple +#undef XQueryBestTile +#undef XQueryColor +#undef XQueryColors +#undef XQueryExtension +#undef XQueryKeymap +#undef XQueryPointer +#undef XQueryTextExtents +#undef XQueryTextExtents16 +#undef XQueryTree +#undef XRaiseWindow +#undef XReadBitmapFile +#undef XReadBitmapFileData +#undef XRebindKeysym +#undef XRecolorCursor +#undef XRefreshKeyboardMapping +#undef XRemoveFromSaveSet +#undef XRemoveHost +#undef XRemoveHosts +#undef XReparentWindow +#undef XResetScreenSaver +#undef XResizeWindow +#undef XRestackWindows +#undef XRotateBuffers +#undef XRotateWindowProperties +#undef XScreenCount +#undef XSelectInput +#undef XSendEvent +#undef XSetAccessControl +#undef XSetArcMode +#undef XSetBackground +#undef XSetClipMask +#undef XSetClipOrigin +#undef XSetClipRectangles +#undef XSetCloseDownMode +#undef XSetCommand +#undef XSetDashes +#undef XSetFillRule +#undef XSetFillStyle +#undef XSetFont +#undef XSetFontPath +#undef XSetForeground +#undef XSetFunction +#undef XSetGraphicsExposures +#undef XSetIconName +#undef XSetInputFocus +#undef XSetLineAttributes +#undef XSetModifierMapping +#undef XSetPlaneMask +#undef XSetPointerMapping +#undef XSetScreenSaver +#undef XSetSelectionOwner +#undef XSetState +#undef XSetStipple +#undef XSetSubwindowMode +#undef XSetTSOrigin +#undef XSetTile +#undef XSetWindowBackground +#undef XSetWindowBackgroundPixmap +#undef XSetWindowBorder +#undef XSetWindowBorderPixmap +#undef XSetWindowBorderWidth +#undef XSetWindowColormap +#undef XStoreBuffer +#undef XStoreBytes +#undef XStoreColor +#undef XStoreColors +#undef XStoreName +#undef XStoreNamedColor +#undef XSync +#undef XTextExtents +#undef XTextExtents16 +#undef XTextWidth +#undef XTextWidth16 +#undef XTranslateCoordinates +#undef XUndefineCursor +#undef XUngrabButton +#undef XUngrabKey +#undef XUngrabKeyboard +#undef XUngrabPointer +#undef XUngrabServer +#undef XUninstallColormap +#undef XUnloadFont +#undef XUnmapSubwindows +#undef XUnmapWindow +#undef XVendorRelease +#undef XWarpPointer +#undef XWidthMMOfScreen +#undef XWidthOfScreen +#undef XWindowEvent +#undef XWriteBitmapFile +#undef XSupportsLocale +#undef XSetLocaleModifiers +#undef XOpenOM +#undef XCloseOM +#undef XSetOMValues +#undef XGetOMValues +#undef XDisplayOfOM +#undef XLocaleOfOM +#undef XCreateOC +#undef XDestroyOC +#undef XOMOfOC +#undef XSetOCValues +#undef XGetOCValues +#undef XCreateFontSet +#undef XFreeFontSet +#undef XFontsOfFontSet +#undef XBaseFontNameListOfFontSet +#undef XLocaleOfFontSet +#undef XContextDependentDrawing +#undef XDirectionalDependentDrawing +#undef XContextualDrawing +#undef XExtentsOfFontSet +#undef XmbTextEscapement +#undef XwcTextEscapement +#undef Xutf8TextEscapement +#undef XmbTextExtents +#undef XwcTextExtents +#undef Xutf8TextExtents +#undef XmbTextPerCharExtents +#undef XwcTextPerCharExtents +#undef Xutf8TextPerCharExtents +#undef XmbDrawText +#undef XwcDrawText +#undef Xutf8DrawText +#undef XmbDrawString +#undef XwcDrawString +#undef Xutf8DrawString +#undef XmbDrawImageString +#undef XwcDrawImageString +#undef Xutf8DrawImageString +#undef XOpenIM +#undef XCloseIM +#undef XGetIMValues +#undef XSetIMValues +#undef XDisplayOfIM +#undef XLocaleOfIM +#undef XCreateIC +#undef XDestroyIC +#undef XSetICFocus +#undef XUnsetICFocus +#undef XwcResetIC +#undef XmbResetIC +#undef Xutf8ResetIC +#undef XSetICValues +#undef XGetICValues +#undef XIMOfIC +#undef XFilterEvent +#undef XmbLookupString +#undef XwcLookupString +#undef Xutf8LookupString +#undef XVaCreateNestedList +#undef XRegisterIMInstantiateCallback +#undef XUnregisterIMInstantiateCallback +#undef XInternalConnectionNumbers +#undef XProcessInternalConnection +#undef XAddConnectionWatch +#undef XRemoveConnectionWatch +#undef XSetAuthorization +#undef _Xmbtowc +#undef _Xwctomb +#undef XGetEventData +#undef XFreeEventData +#undef XAllocClassHint +#undef XAllocIconSize +#undef XAllocSizeHints +#undef XAllocStandardColormap +#undef XAllocWMHints +#undef XClipBox +#undef XCreateRegion +#undef XDefaultString +#undef XDeleteContext +#undef XDestroyRegion +#undef XEmptyRegion +#undef XEqualRegion +#undef XFindContext +#undef XGetClassHint +#undef XGetIconSizes +#undef XGetNormalHints +#undef XGetRGBColormaps +#undef XGetSizeHints +#undef XGetStandardColormap +#undef XGetTextProperty +#undef XGetVisualInfo +#undef XGetWMClientMachine +#undef XGetWMHints +#undef XGetWMIconName +#undef XGetWMName +#undef XGetWMNormalHints +#undef XGetWMSizeHints +#undef XGetZoomHints +#undef XIntersectRegion +#undef XConvertCase +#undef XLookupString +#undef XMatchVisualInfo +#undef XOffsetRegion +#undef XPointInRegion +#undef XPolygonRegion +#undef XRectInRegion +#undef XSaveContext +#undef XSetClassHint +#undef XSetIconSizes +#undef XSetNormalHints +#undef XSetRGBColormaps +#undef XSetSizeHints +#undef XSetStandardProperties +#undef XSetTextProperty +#undef XSetWMClientMachine +#undef XSetWMHints +#undef XSetWMIconName +#undef XSetWMName +#undef XSetWMNormalHints +#undef XSetWMProperties +#undef XmbSetWMProperties +#undef Xutf8SetWMProperties +#undef XSetWMSizeHints +#undef XSetRegion +#undef XSetStandardColormap +#undef XSetZoomHints +#undef XShrinkRegion +#undef XStringListToTextProperty +#undef XSubtractRegion +#undef XmbTextListToTextProperty +#undef XwcTextListToTextProperty +#undef Xutf8TextListToTextProperty +#undef XwcFreeStringList +#undef XTextPropertyToStringList +#undef XmbTextPropertyToTextList +#undef XwcTextPropertyToTextList +#undef Xutf8TextPropertyToTextList +#undef XUnionRectWithRegion +#undef XUnionRegion +#undef XWMGeometry +#undef XXorRegion +#undef XkbIgnoreExtension +#undef XkbOpenDisplay +#undef XkbQueryExtension +#undef XkbUseExtension +#undef XkbLibraryVersion +#undef XkbSetXlibControls +#undef XkbGetXlibControls +#undef XkbXlibControlsImplemented +#undef XkbSetAtomFuncs +#undef XkbKeycodeToKeysym +#undef XkbKeysymToModifiers +#undef XkbLookupKeySym +#undef XkbLookupKeyBinding +#undef XkbTranslateKeyCode +#undef XkbTranslateKeySym +#undef XkbSetAutoRepeatRate +#undef XkbGetAutoRepeatRate +#undef XkbChangeEnabledControls +#undef XkbDeviceBell +#undef XkbForceDeviceBell +#undef XkbDeviceBellEvent +#undef XkbBell +#undef XkbForceBell +#undef XkbBellEvent +#undef XkbSelectEvents +#undef XkbSelectEventDetails +#undef XkbNoteMapChanges +#undef XkbNoteNameChanges +#undef XkbGetIndicatorState +#undef XkbGetIndicatorMap +#undef XkbSetIndicatorMap +#undef XkbGetNamedIndicator +#undef XkbGetNamedDeviceIndicator +#undef XkbSetNamedIndicator +#undef XkbSetNamedDeviceIndicator +#undef XkbLockModifiers +#undef XkbLatchModifiers +#undef XkbLockGroup +#undef XkbLatchGroup +#undef XkbSetServerInternalMods +#undef XkbSetIgnoreLockMods +#undef XkbVirtualModsToReal +#undef XkbComputeEffectiveMap +#undef XkbInitCanonicalKeyTypes +#undef XkbAllocKeyboard +#undef XkbFreeKeyboard +#undef XkbAllocClientMap +#undef XkbAllocServerMap +#undef XkbFreeClientMap +#undef XkbFreeServerMap +#undef XkbAddKeyType +#undef XkbAllocIndicatorMaps +#undef XkbFreeIndicatorMaps +#undef XkbGetMap +#undef XkbGetUpdatedMap +#undef XkbGetMapChanges +#undef XkbRefreshKeyboardMapping +#undef XkbGetKeyTypes +#undef XkbGetKeySyms +#undef XkbGetKeyActions +#undef XkbGetKeyBehaviors +#undef XkbGetVirtualMods +#undef XkbGetKeyExplicitComponents +#undef XkbGetKeyModifierMap +#undef XkbGetKeyVirtualModMap +#undef XkbAllocControls +#undef XkbFreeControls +#undef XkbGetControls +#undef XkbSetControls +#undef XkbNoteControlsChanges +#undef XkbAllocCompatMap +#undef XkbFreeCompatMap +#undef XkbGetCompatMap +#undef XkbSetCompatMap +#undef XkbAllocNames +#undef XkbGetNames +#undef XkbSetNames +#undef XkbChangeNames +#undef XkbFreeNames +#undef XkbGetState +#undef XkbSetMap +#undef XkbChangeMap +#undef XkbSetDetectableAutoRepeat +#undef XkbGetDetectableAutoRepeat +#undef XkbSetAutoResetControls +#undef XkbGetAutoResetControls +#undef XkbSetPerClientControls +#undef XkbGetPerClientControls +#undef XkbCopyKeyType +#undef XkbCopyKeyTypes +#undef XkbResizeKeyType +#undef XkbResizeKeySyms +#undef XkbResizeKeyActions +#undef XkbChangeTypesOfKey +#undef XkbChangeKeycodeRange +#undef XkbListComponents +#undef XkbFreeComponentList +#undef XkbGetKeyboard +#undef XkbGetKeyboardByName +#undef XkbKeyTypesForCoreSymbols +#undef XkbApplyCompatMapToKey +#undef XkbUpdateMapFromCore +#undef XkbAddDeviceLedInfo +#undef XkbResizeDeviceButtonActions +#undef XkbAllocDeviceInfo +#undef XkbFreeDeviceInfo +#undef XkbNoteDeviceChanges +#undef XkbGetDeviceInfo +#undef XkbGetDeviceInfoChanges +#undef XkbGetDeviceButtonActions +#undef XkbGetDeviceLedInfo +#undef XkbSetDeviceInfo +#undef XkbChangeDeviceInfo +#undef XkbSetDeviceLedInfo +#undef XkbSetDeviceButtonActions +#undef XkbToControl +#undef XkbSetDebuggingFlags +#undef XkbApplyVirtualModChanges +#undef XkbUpdateActionVirtualMods +#undef XkbUpdateKeyTypeVirtualMods +#include <dlfcn.h> +#include <stdio.h> +int (*_Xmblen_dylibloader_wrapper_xlib)( char*, int); +XFontStruct* (*XLoadQueryFont_dylibloader_wrapper_xlib)( Display*,const char*); +XFontStruct* (*XQueryFont_dylibloader_wrapper_xlib)( Display*, XID); +XTimeCoord* (*XGetMotionEvents_dylibloader_wrapper_xlib)( Display*, Window, Time, Time, int*); +XModifierKeymap* (*XDeleteModifiermapEntry_dylibloader_wrapper_xlib)( XModifierKeymap*, KeyCode, int); +XModifierKeymap* (*XGetModifierMapping_dylibloader_wrapper_xlib)( Display*); +XModifierKeymap* (*XInsertModifiermapEntry_dylibloader_wrapper_xlib)( XModifierKeymap*, KeyCode, int); +XModifierKeymap* (*XNewModifiermap_dylibloader_wrapper_xlib)( int); +XImage* (*XCreateImage_dylibloader_wrapper_xlib)( Display*, Visual*, unsigned int, int, int, char*, unsigned int, unsigned int, int, int); +int (*XInitImage_dylibloader_wrapper_xlib)( XImage*); +XImage* (*XGetImage_dylibloader_wrapper_xlib)( Display*, Drawable, int, int, unsigned int, unsigned int, unsigned long, int); +XImage* (*XGetSubImage_dylibloader_wrapper_xlib)( Display*, Drawable, int, int, unsigned int, unsigned int, unsigned long, int, XImage*, int, int); +Display* (*XOpenDisplay_dylibloader_wrapper_xlib)(const char*); +void (*XrmInitialize_dylibloader_wrapper_xlib)( void); +char* (*XFetchBytes_dylibloader_wrapper_xlib)( Display*, int*); +char* (*XFetchBuffer_dylibloader_wrapper_xlib)( Display*, int*, int); +char* (*XGetAtomName_dylibloader_wrapper_xlib)( Display*, Atom); +int (*XGetAtomNames_dylibloader_wrapper_xlib)( Display*, Atom*, int, char**); +char* (*XGetDefault_dylibloader_wrapper_xlib)( Display*,const char*,const char*); +char* (*XDisplayName_dylibloader_wrapper_xlib)(const char*); +char* (*XKeysymToString_dylibloader_wrapper_xlib)( KeySym); +int* (*XSynchronize_dylibloader_wrapper_xlib)( Display*, int); +int* (*XSetAfterFunction_dylibloader_wrapper_xlib)( Display*, int*); +Atom (*XInternAtom_dylibloader_wrapper_xlib)( Display*,const char*, int); +int (*XInternAtoms_dylibloader_wrapper_xlib)( Display*, char**, int, int, Atom*); +Colormap (*XCopyColormapAndFree_dylibloader_wrapper_xlib)( Display*, Colormap); +Colormap (*XCreateColormap_dylibloader_wrapper_xlib)( Display*, Window, Visual*, int); +Cursor (*XCreatePixmapCursor_dylibloader_wrapper_xlib)( Display*, Pixmap, Pixmap, XColor*, XColor*, unsigned int, unsigned int); +Cursor (*XCreateGlyphCursor_dylibloader_wrapper_xlib)( Display*, Font, Font, unsigned int, unsigned int,const XColor*,const XColor*); +Cursor (*XCreateFontCursor_dylibloader_wrapper_xlib)( Display*, unsigned int); +Font (*XLoadFont_dylibloader_wrapper_xlib)( Display*,const char*); +GC (*XCreateGC_dylibloader_wrapper_xlib)( Display*, Drawable, unsigned long, XGCValues*); +GContext (*XGContextFromGC_dylibloader_wrapper_xlib)( GC); +void (*XFlushGC_dylibloader_wrapper_xlib)( Display*, GC); +Pixmap (*XCreatePixmap_dylibloader_wrapper_xlib)( Display*, Drawable, unsigned int, unsigned int, unsigned int); +Pixmap (*XCreateBitmapFromData_dylibloader_wrapper_xlib)( Display*, Drawable,const char*, unsigned int, unsigned int); +Pixmap (*XCreatePixmapFromBitmapData_dylibloader_wrapper_xlib)( Display*, Drawable, char*, unsigned int, unsigned int, unsigned long, unsigned long, unsigned int); +Window (*XCreateSimpleWindow_dylibloader_wrapper_xlib)( Display*, Window, int, int, unsigned int, unsigned int, unsigned int, unsigned long, unsigned long); +Window (*XGetSelectionOwner_dylibloader_wrapper_xlib)( Display*, Atom); +Window (*XCreateWindow_dylibloader_wrapper_xlib)( Display*, Window, int, int, unsigned int, unsigned int, unsigned int, int, unsigned int, Visual*, unsigned long, XSetWindowAttributes*); +Colormap* (*XListInstalledColormaps_dylibloader_wrapper_xlib)( Display*, Window, int*); +char** (*XListFonts_dylibloader_wrapper_xlib)( Display*,const char*, int, int*); +char** (*XListFontsWithInfo_dylibloader_wrapper_xlib)( Display*,const char*, int, int*, XFontStruct**); +char** (*XGetFontPath_dylibloader_wrapper_xlib)( Display*, int*); +char** (*XListExtensions_dylibloader_wrapper_xlib)( Display*, int*); +Atom* (*XListProperties_dylibloader_wrapper_xlib)( Display*, Window, int*); +XHostAddress* (*XListHosts_dylibloader_wrapper_xlib)( Display*, int*, int*); +KeySym (*XKeycodeToKeysym_dylibloader_wrapper_xlib)( Display*, KeyCode, int); +KeySym (*XLookupKeysym_dylibloader_wrapper_xlib)( XKeyEvent*, int); +KeySym* (*XGetKeyboardMapping_dylibloader_wrapper_xlib)( Display*, KeyCode, int, int*); +KeySym (*XStringToKeysym_dylibloader_wrapper_xlib)(const char*); +long (*XMaxRequestSize_dylibloader_wrapper_xlib)( Display*); +long (*XExtendedMaxRequestSize_dylibloader_wrapper_xlib)( Display*); +char* (*XResourceManagerString_dylibloader_wrapper_xlib)( Display*); +char* (*XScreenResourceString_dylibloader_wrapper_xlib)( Screen*); +unsigned long (*XDisplayMotionBufferSize_dylibloader_wrapper_xlib)( Display*); +VisualID (*XVisualIDFromVisual_dylibloader_wrapper_xlib)( Visual*); +int (*XInitThreads_dylibloader_wrapper_xlib)( void); +void (*XLockDisplay_dylibloader_wrapper_xlib)( Display*); +void (*XUnlockDisplay_dylibloader_wrapper_xlib)( Display*); +XExtCodes* (*XInitExtension_dylibloader_wrapper_xlib)( Display*,const char*); +XExtCodes* (*XAddExtension_dylibloader_wrapper_xlib)( Display*); +XExtData* (*XFindOnExtensionList_dylibloader_wrapper_xlib)( XExtData**, int); +XExtData** (*XEHeadOfExtensionList_dylibloader_wrapper_xlib)( XEDataObject); +Window (*XRootWindow_dylibloader_wrapper_xlib)( Display*, int); +Window (*XDefaultRootWindow_dylibloader_wrapper_xlib)( Display*); +Window (*XRootWindowOfScreen_dylibloader_wrapper_xlib)( Screen*); +Visual* (*XDefaultVisual_dylibloader_wrapper_xlib)( Display*, int); +Visual* (*XDefaultVisualOfScreen_dylibloader_wrapper_xlib)( Screen*); +GC (*XDefaultGC_dylibloader_wrapper_xlib)( Display*, int); +GC (*XDefaultGCOfScreen_dylibloader_wrapper_xlib)( Screen*); +unsigned long (*XBlackPixel_dylibloader_wrapper_xlib)( Display*, int); +unsigned long (*XWhitePixel_dylibloader_wrapper_xlib)( Display*, int); +unsigned long (*XAllPlanes_dylibloader_wrapper_xlib)( void); +unsigned long (*XBlackPixelOfScreen_dylibloader_wrapper_xlib)( Screen*); +unsigned long (*XWhitePixelOfScreen_dylibloader_wrapper_xlib)( Screen*); +unsigned long (*XNextRequest_dylibloader_wrapper_xlib)( Display*); +unsigned long (*XLastKnownRequestProcessed_dylibloader_wrapper_xlib)( Display*); +char* (*XServerVendor_dylibloader_wrapper_xlib)( Display*); +char* (*XDisplayString_dylibloader_wrapper_xlib)( Display*); +Colormap (*XDefaultColormap_dylibloader_wrapper_xlib)( Display*, int); +Colormap (*XDefaultColormapOfScreen_dylibloader_wrapper_xlib)( Screen*); +Display* (*XDisplayOfScreen_dylibloader_wrapper_xlib)( Screen*); +Screen* (*XScreenOfDisplay_dylibloader_wrapper_xlib)( Display*, int); +Screen* (*XDefaultScreenOfDisplay_dylibloader_wrapper_xlib)( Display*); +long (*XEventMaskOfScreen_dylibloader_wrapper_xlib)( Screen*); +int (*XScreenNumberOfScreen_dylibloader_wrapper_xlib)( Screen*); +XErrorHandler (*XSetErrorHandler_dylibloader_wrapper_xlib)( XErrorHandler); +XIOErrorHandler (*XSetIOErrorHandler_dylibloader_wrapper_xlib)( XIOErrorHandler); +XPixmapFormatValues* (*XListPixmapFormats_dylibloader_wrapper_xlib)( Display*, int*); +int* (*XListDepths_dylibloader_wrapper_xlib)( Display*, int, int*); +int (*XReconfigureWMWindow_dylibloader_wrapper_xlib)( Display*, Window, int, unsigned int, XWindowChanges*); +int (*XGetWMProtocols_dylibloader_wrapper_xlib)( Display*, Window, Atom**, int*); +int (*XSetWMProtocols_dylibloader_wrapper_xlib)( Display*, Window, Atom*, int); +int (*XIconifyWindow_dylibloader_wrapper_xlib)( Display*, Window, int); +int (*XWithdrawWindow_dylibloader_wrapper_xlib)( Display*, Window, int); +int (*XGetCommand_dylibloader_wrapper_xlib)( Display*, Window, char***, int*); +int (*XGetWMColormapWindows_dylibloader_wrapper_xlib)( Display*, Window, Window**, int*); +int (*XSetWMColormapWindows_dylibloader_wrapper_xlib)( Display*, Window, Window*, int); +void (*XFreeStringList_dylibloader_wrapper_xlib)( char**); +int (*XSetTransientForHint_dylibloader_wrapper_xlib)( Display*, Window, Window); +int (*XActivateScreenSaver_dylibloader_wrapper_xlib)( Display*); +int (*XAddHost_dylibloader_wrapper_xlib)( Display*, XHostAddress*); +int (*XAddHosts_dylibloader_wrapper_xlib)( Display*, XHostAddress*, int); +int (*XAddToExtensionList_dylibloader_wrapper_xlib)(struct _XExtData**, XExtData*); +int (*XAddToSaveSet_dylibloader_wrapper_xlib)( Display*, Window); +int (*XAllocColor_dylibloader_wrapper_xlib)( Display*, Colormap, XColor*); +int (*XAllocColorCells_dylibloader_wrapper_xlib)( Display*, Colormap, int, unsigned long*, unsigned int, unsigned long*, unsigned int); +int (*XAllocColorPlanes_dylibloader_wrapper_xlib)( Display*, Colormap, int, unsigned long*, int, int, int, int, unsigned long*, unsigned long*, unsigned long*); +int (*XAllocNamedColor_dylibloader_wrapper_xlib)( Display*, Colormap,const char*, XColor*, XColor*); +int (*XAllowEvents_dylibloader_wrapper_xlib)( Display*, int, Time); +int (*XAutoRepeatOff_dylibloader_wrapper_xlib)( Display*); +int (*XAutoRepeatOn_dylibloader_wrapper_xlib)( Display*); +int (*XBell_dylibloader_wrapper_xlib)( Display*, int); +int (*XBitmapBitOrder_dylibloader_wrapper_xlib)( Display*); +int (*XBitmapPad_dylibloader_wrapper_xlib)( Display*); +int (*XBitmapUnit_dylibloader_wrapper_xlib)( Display*); +int (*XCellsOfScreen_dylibloader_wrapper_xlib)( Screen*); +int (*XChangeActivePointerGrab_dylibloader_wrapper_xlib)( Display*, unsigned int, Cursor, Time); +int (*XChangeGC_dylibloader_wrapper_xlib)( Display*, GC, unsigned long, XGCValues*); +int (*XChangeKeyboardControl_dylibloader_wrapper_xlib)( Display*, unsigned long, XKeyboardControl*); +int (*XChangeKeyboardMapping_dylibloader_wrapper_xlib)( Display*, int, int, KeySym*, int); +int (*XChangePointerControl_dylibloader_wrapper_xlib)( Display*, int, int, int, int, int); +int (*XChangeProperty_dylibloader_wrapper_xlib)( Display*, Window, Atom, Atom, int, int,const unsigned char*, int); +int (*XChangeSaveSet_dylibloader_wrapper_xlib)( Display*, Window, int); +int (*XChangeWindowAttributes_dylibloader_wrapper_xlib)( Display*, Window, unsigned long, XSetWindowAttributes*); +int (*XCheckIfEvent_dylibloader_wrapper_xlib)( Display*, XEvent*, Bool (*) (Display*, XEvent*, XPointer), XPointer); +int (*XCheckMaskEvent_dylibloader_wrapper_xlib)( Display*, long, XEvent*); +int (*XCheckTypedEvent_dylibloader_wrapper_xlib)( Display*, int, XEvent*); +int (*XCheckTypedWindowEvent_dylibloader_wrapper_xlib)( Display*, Window, int, XEvent*); +int (*XCheckWindowEvent_dylibloader_wrapper_xlib)( Display*, Window, long, XEvent*); +int (*XCirculateSubwindows_dylibloader_wrapper_xlib)( Display*, Window, int); +int (*XCirculateSubwindowsDown_dylibloader_wrapper_xlib)( Display*, Window); +int (*XCirculateSubwindowsUp_dylibloader_wrapper_xlib)( Display*, Window); +int (*XClearArea_dylibloader_wrapper_xlib)( Display*, Window, int, int, unsigned int, unsigned int, int); +int (*XClearWindow_dylibloader_wrapper_xlib)( Display*, Window); +int (*XCloseDisplay_dylibloader_wrapper_xlib)( Display*); +int (*XConfigureWindow_dylibloader_wrapper_xlib)( Display*, Window, unsigned int, XWindowChanges*); +int (*XConnectionNumber_dylibloader_wrapper_xlib)( Display*); +int (*XConvertSelection_dylibloader_wrapper_xlib)( Display*, Atom, Atom, Atom, Window, Time); +int (*XCopyArea_dylibloader_wrapper_xlib)( Display*, Drawable, Drawable, GC, int, int, unsigned int, unsigned int, int, int); +int (*XCopyGC_dylibloader_wrapper_xlib)( Display*, GC, unsigned long, GC); +int (*XCopyPlane_dylibloader_wrapper_xlib)( Display*, Drawable, Drawable, GC, int, int, unsigned int, unsigned int, int, int, unsigned long); +int (*XDefaultDepth_dylibloader_wrapper_xlib)( Display*, int); +int (*XDefaultDepthOfScreen_dylibloader_wrapper_xlib)( Screen*); +int (*XDefaultScreen_dylibloader_wrapper_xlib)( Display*); +int (*XDefineCursor_dylibloader_wrapper_xlib)( Display*, Window, Cursor); +int (*XDeleteProperty_dylibloader_wrapper_xlib)( Display*, Window, Atom); +int (*XDestroyWindow_dylibloader_wrapper_xlib)( Display*, Window); +int (*XDestroySubwindows_dylibloader_wrapper_xlib)( Display*, Window); +int (*XDoesBackingStore_dylibloader_wrapper_xlib)( Screen*); +int (*XDoesSaveUnders_dylibloader_wrapper_xlib)( Screen*); +int (*XDisableAccessControl_dylibloader_wrapper_xlib)( Display*); +int (*XDisplayCells_dylibloader_wrapper_xlib)( Display*, int); +int (*XDisplayHeight_dylibloader_wrapper_xlib)( Display*, int); +int (*XDisplayHeightMM_dylibloader_wrapper_xlib)( Display*, int); +int (*XDisplayKeycodes_dylibloader_wrapper_xlib)( Display*, int*, int*); +int (*XDisplayPlanes_dylibloader_wrapper_xlib)( Display*, int); +int (*XDisplayWidth_dylibloader_wrapper_xlib)( Display*, int); +int (*XDisplayWidthMM_dylibloader_wrapper_xlib)( Display*, int); +int (*XDrawArc_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int, unsigned int, unsigned int, int, int); +int (*XDrawArcs_dylibloader_wrapper_xlib)( Display*, Drawable, GC, XArc*, int); +int (*XDrawImageString_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int,const char*, int); +int (*XDrawImageString16_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int,const XChar2b*, int); +int (*XDrawLine_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int, int, int); +int (*XDrawLines_dylibloader_wrapper_xlib)( Display*, Drawable, GC, XPoint*, int, int); +int (*XDrawPoint_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int); +int (*XDrawPoints_dylibloader_wrapper_xlib)( Display*, Drawable, GC, XPoint*, int, int); +int (*XDrawRectangle_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int, unsigned int, unsigned int); +int (*XDrawRectangles_dylibloader_wrapper_xlib)( Display*, Drawable, GC, XRectangle*, int); +int (*XDrawSegments_dylibloader_wrapper_xlib)( Display*, Drawable, GC, XSegment*, int); +int (*XDrawString_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int,const char*, int); +int (*XDrawString16_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int,const XChar2b*, int); +int (*XDrawText_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int, XTextItem*, int); +int (*XDrawText16_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int, XTextItem16*, int); +int (*XEnableAccessControl_dylibloader_wrapper_xlib)( Display*); +int (*XEventsQueued_dylibloader_wrapper_xlib)( Display*, int); +int (*XFetchName_dylibloader_wrapper_xlib)( Display*, Window, char**); +int (*XFillArc_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int, unsigned int, unsigned int, int, int); +int (*XFillArcs_dylibloader_wrapper_xlib)( Display*, Drawable, GC, XArc*, int); +int (*XFillPolygon_dylibloader_wrapper_xlib)( Display*, Drawable, GC, XPoint*, int, int, int); +int (*XFillRectangle_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int, unsigned int, unsigned int); +int (*XFillRectangles_dylibloader_wrapper_xlib)( Display*, Drawable, GC, XRectangle*, int); +int (*XFlush_dylibloader_wrapper_xlib)( Display*); +int (*XForceScreenSaver_dylibloader_wrapper_xlib)( Display*, int); +int (*XFree_dylibloader_wrapper_xlib)( void*); +int (*XFreeColormap_dylibloader_wrapper_xlib)( Display*, Colormap); +int (*XFreeColors_dylibloader_wrapper_xlib)( Display*, Colormap, unsigned long*, int, unsigned long); +int (*XFreeCursor_dylibloader_wrapper_xlib)( Display*, Cursor); +int (*XFreeExtensionList_dylibloader_wrapper_xlib)( char**); +int (*XFreeFont_dylibloader_wrapper_xlib)( Display*, XFontStruct*); +int (*XFreeFontInfo_dylibloader_wrapper_xlib)( char**, XFontStruct*, int); +int (*XFreeFontNames_dylibloader_wrapper_xlib)( char**); +int (*XFreeFontPath_dylibloader_wrapper_xlib)( char**); +int (*XFreeGC_dylibloader_wrapper_xlib)( Display*, GC); +int (*XFreeModifiermap_dylibloader_wrapper_xlib)( XModifierKeymap*); +int (*XFreePixmap_dylibloader_wrapper_xlib)( Display*, Pixmap); +int (*XGeometry_dylibloader_wrapper_xlib)( Display*, int,const char*,const char*, unsigned int, unsigned int, unsigned int, int, int, int*, int*, int*, int*); +int (*XGetErrorDatabaseText_dylibloader_wrapper_xlib)( Display*,const char*,const char*,const char*, char*, int); +int (*XGetErrorText_dylibloader_wrapper_xlib)( Display*, int, char*, int); +int (*XGetFontProperty_dylibloader_wrapper_xlib)( XFontStruct*, Atom, unsigned long*); +int (*XGetGCValues_dylibloader_wrapper_xlib)( Display*, GC, unsigned long, XGCValues*); +int (*XGetGeometry_dylibloader_wrapper_xlib)( Display*, Drawable, Window*, int*, int*, unsigned int*, unsigned int*, unsigned int*, unsigned int*); +int (*XGetIconName_dylibloader_wrapper_xlib)( Display*, Window, char**); +int (*XGetInputFocus_dylibloader_wrapper_xlib)( Display*, Window*, int*); +int (*XGetKeyboardControl_dylibloader_wrapper_xlib)( Display*, XKeyboardState*); +int (*XGetPointerControl_dylibloader_wrapper_xlib)( Display*, int*, int*, int*); +int (*XGetPointerMapping_dylibloader_wrapper_xlib)( Display*, unsigned char*, int); +int (*XGetScreenSaver_dylibloader_wrapper_xlib)( Display*, int*, int*, int*, int*); +int (*XGetTransientForHint_dylibloader_wrapper_xlib)( Display*, Window, Window*); +int (*XGetWindowProperty_dylibloader_wrapper_xlib)( Display*, Window, Atom, long, long, int, Atom, Atom*, int*, unsigned long*, unsigned long*, unsigned char**); +int (*XGetWindowAttributes_dylibloader_wrapper_xlib)( Display*, Window, XWindowAttributes*); +int (*XGrabButton_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, Window, int, unsigned int, int, int, Window, Cursor); +int (*XGrabKey_dylibloader_wrapper_xlib)( Display*, int, unsigned int, Window, int, int, int); +int (*XGrabKeyboard_dylibloader_wrapper_xlib)( Display*, Window, int, int, int, Time); +int (*XGrabPointer_dylibloader_wrapper_xlib)( Display*, Window, int, unsigned int, int, int, Window, Cursor, Time); +int (*XGrabServer_dylibloader_wrapper_xlib)( Display*); +int (*XHeightMMOfScreen_dylibloader_wrapper_xlib)( Screen*); +int (*XHeightOfScreen_dylibloader_wrapper_xlib)( Screen*); +int (*XIfEvent_dylibloader_wrapper_xlib)( Display*, XEvent*, Bool (*) (Display*, XEvent*, XPointer), XPointer); +int (*XImageByteOrder_dylibloader_wrapper_xlib)( Display*); +int (*XInstallColormap_dylibloader_wrapper_xlib)( Display*, Colormap); +KeyCode (*XKeysymToKeycode_dylibloader_wrapper_xlib)( Display*, KeySym); +int (*XKillClient_dylibloader_wrapper_xlib)( Display*, XID); +int (*XLookupColor_dylibloader_wrapper_xlib)( Display*, Colormap,const char*, XColor*, XColor*); +int (*XLowerWindow_dylibloader_wrapper_xlib)( Display*, Window); +int (*XMapRaised_dylibloader_wrapper_xlib)( Display*, Window); +int (*XMapSubwindows_dylibloader_wrapper_xlib)( Display*, Window); +int (*XMapWindow_dylibloader_wrapper_xlib)( Display*, Window); +int (*XMaskEvent_dylibloader_wrapper_xlib)( Display*, long, XEvent*); +int (*XMaxCmapsOfScreen_dylibloader_wrapper_xlib)( Screen*); +int (*XMinCmapsOfScreen_dylibloader_wrapper_xlib)( Screen*); +int (*XMoveResizeWindow_dylibloader_wrapper_xlib)( Display*, Window, int, int, unsigned int, unsigned int); +int (*XMoveWindow_dylibloader_wrapper_xlib)( Display*, Window, int, int); +int (*XNextEvent_dylibloader_wrapper_xlib)( Display*, XEvent*); +int (*XNoOp_dylibloader_wrapper_xlib)( Display*); +int (*XParseColor_dylibloader_wrapper_xlib)( Display*, Colormap,const char*, XColor*); +int (*XParseGeometry_dylibloader_wrapper_xlib)(const char*, int*, int*, unsigned int*, unsigned int*); +int (*XPeekEvent_dylibloader_wrapper_xlib)( Display*, XEvent*); +int (*XPeekIfEvent_dylibloader_wrapper_xlib)( Display*, XEvent*, Bool (*) (Display*, XEvent*, XPointer), XPointer); +int (*XPending_dylibloader_wrapper_xlib)( Display*); +int (*XPlanesOfScreen_dylibloader_wrapper_xlib)( Screen*); +int (*XProtocolRevision_dylibloader_wrapper_xlib)( Display*); +int (*XProtocolVersion_dylibloader_wrapper_xlib)( Display*); +int (*XPutBackEvent_dylibloader_wrapper_xlib)( Display*, XEvent*); +int (*XPutImage_dylibloader_wrapper_xlib)( Display*, Drawable, GC, XImage*, int, int, int, int, unsigned int, unsigned int); +int (*XQLength_dylibloader_wrapper_xlib)( Display*); +int (*XQueryBestCursor_dylibloader_wrapper_xlib)( Display*, Drawable, unsigned int, unsigned int, unsigned int*, unsigned int*); +int (*XQueryBestSize_dylibloader_wrapper_xlib)( Display*, int, Drawable, unsigned int, unsigned int, unsigned int*, unsigned int*); +int (*XQueryBestStipple_dylibloader_wrapper_xlib)( Display*, Drawable, unsigned int, unsigned int, unsigned int*, unsigned int*); +int (*XQueryBestTile_dylibloader_wrapper_xlib)( Display*, Drawable, unsigned int, unsigned int, unsigned int*, unsigned int*); +int (*XQueryColor_dylibloader_wrapper_xlib)( Display*, Colormap, XColor*); +int (*XQueryColors_dylibloader_wrapper_xlib)( Display*, Colormap, XColor*, int); +int (*XQueryExtension_dylibloader_wrapper_xlib)( Display*,const char*, int*, int*, int*); +int (*XQueryKeymap_dylibloader_wrapper_xlib)( Display*, char [32]); +int (*XQueryPointer_dylibloader_wrapper_xlib)( Display*, Window, Window*, Window*, int*, int*, int*, int*, unsigned int*); +int (*XQueryTextExtents_dylibloader_wrapper_xlib)( Display*, XID,const char*, int, int*, int*, int*, XCharStruct*); +int (*XQueryTextExtents16_dylibloader_wrapper_xlib)( Display*, XID,const XChar2b*, int, int*, int*, int*, XCharStruct*); +int (*XQueryTree_dylibloader_wrapper_xlib)( Display*, Window, Window*, Window*, Window**, unsigned int*); +int (*XRaiseWindow_dylibloader_wrapper_xlib)( Display*, Window); +int (*XReadBitmapFile_dylibloader_wrapper_xlib)( Display*, Drawable,const char*, unsigned int*, unsigned int*, Pixmap*, int*, int*); +int (*XReadBitmapFileData_dylibloader_wrapper_xlib)(const char*, unsigned int*, unsigned int*, unsigned char**, int*, int*); +int (*XRebindKeysym_dylibloader_wrapper_xlib)( Display*, KeySym, KeySym*, int,const unsigned char*, int); +int (*XRecolorCursor_dylibloader_wrapper_xlib)( Display*, Cursor, XColor*, XColor*); +int (*XRefreshKeyboardMapping_dylibloader_wrapper_xlib)( XMappingEvent*); +int (*XRemoveFromSaveSet_dylibloader_wrapper_xlib)( Display*, Window); +int (*XRemoveHost_dylibloader_wrapper_xlib)( Display*, XHostAddress*); +int (*XRemoveHosts_dylibloader_wrapper_xlib)( Display*, XHostAddress*, int); +int (*XReparentWindow_dylibloader_wrapper_xlib)( Display*, Window, Window, int, int); +int (*XResetScreenSaver_dylibloader_wrapper_xlib)( Display*); +int (*XResizeWindow_dylibloader_wrapper_xlib)( Display*, Window, unsigned int, unsigned int); +int (*XRestackWindows_dylibloader_wrapper_xlib)( Display*, Window*, int); +int (*XRotateBuffers_dylibloader_wrapper_xlib)( Display*, int); +int (*XRotateWindowProperties_dylibloader_wrapper_xlib)( Display*, Window, Atom*, int, int); +int (*XScreenCount_dylibloader_wrapper_xlib)( Display*); +int (*XSelectInput_dylibloader_wrapper_xlib)( Display*, Window, long); +int (*XSendEvent_dylibloader_wrapper_xlib)( Display*, Window, int, long, XEvent*); +int (*XSetAccessControl_dylibloader_wrapper_xlib)( Display*, int); +int (*XSetArcMode_dylibloader_wrapper_xlib)( Display*, GC, int); +int (*XSetBackground_dylibloader_wrapper_xlib)( Display*, GC, unsigned long); +int (*XSetClipMask_dylibloader_wrapper_xlib)( Display*, GC, Pixmap); +int (*XSetClipOrigin_dylibloader_wrapper_xlib)( Display*, GC, int, int); +int (*XSetClipRectangles_dylibloader_wrapper_xlib)( Display*, GC, int, int, XRectangle*, int, int); +int (*XSetCloseDownMode_dylibloader_wrapper_xlib)( Display*, int); +int (*XSetCommand_dylibloader_wrapper_xlib)( Display*, Window, char**, int); +int (*XSetDashes_dylibloader_wrapper_xlib)( Display*, GC, int,const char*, int); +int (*XSetFillRule_dylibloader_wrapper_xlib)( Display*, GC, int); +int (*XSetFillStyle_dylibloader_wrapper_xlib)( Display*, GC, int); +int (*XSetFont_dylibloader_wrapper_xlib)( Display*, GC, Font); +int (*XSetFontPath_dylibloader_wrapper_xlib)( Display*, char**, int); +int (*XSetForeground_dylibloader_wrapper_xlib)( Display*, GC, unsigned long); +int (*XSetFunction_dylibloader_wrapper_xlib)( Display*, GC, int); +int (*XSetGraphicsExposures_dylibloader_wrapper_xlib)( Display*, GC, int); +int (*XSetIconName_dylibloader_wrapper_xlib)( Display*, Window,const char*); +int (*XSetInputFocus_dylibloader_wrapper_xlib)( Display*, Window, int, Time); +int (*XSetLineAttributes_dylibloader_wrapper_xlib)( Display*, GC, unsigned int, int, int, int); +int (*XSetModifierMapping_dylibloader_wrapper_xlib)( Display*, XModifierKeymap*); +int (*XSetPlaneMask_dylibloader_wrapper_xlib)( Display*, GC, unsigned long); +int (*XSetPointerMapping_dylibloader_wrapper_xlib)( Display*,const unsigned char*, int); +int (*XSetScreenSaver_dylibloader_wrapper_xlib)( Display*, int, int, int, int); +int (*XSetSelectionOwner_dylibloader_wrapper_xlib)( Display*, Atom, Window, Time); +int (*XSetState_dylibloader_wrapper_xlib)( Display*, GC, unsigned long, unsigned long, int, unsigned long); +int (*XSetStipple_dylibloader_wrapper_xlib)( Display*, GC, Pixmap); +int (*XSetSubwindowMode_dylibloader_wrapper_xlib)( Display*, GC, int); +int (*XSetTSOrigin_dylibloader_wrapper_xlib)( Display*, GC, int, int); +int (*XSetTile_dylibloader_wrapper_xlib)( Display*, GC, Pixmap); +int (*XSetWindowBackground_dylibloader_wrapper_xlib)( Display*, Window, unsigned long); +int (*XSetWindowBackgroundPixmap_dylibloader_wrapper_xlib)( Display*, Window, Pixmap); +int (*XSetWindowBorder_dylibloader_wrapper_xlib)( Display*, Window, unsigned long); +int (*XSetWindowBorderPixmap_dylibloader_wrapper_xlib)( Display*, Window, Pixmap); +int (*XSetWindowBorderWidth_dylibloader_wrapper_xlib)( Display*, Window, unsigned int); +int (*XSetWindowColormap_dylibloader_wrapper_xlib)( Display*, Window, Colormap); +int (*XStoreBuffer_dylibloader_wrapper_xlib)( Display*,const char*, int, int); +int (*XStoreBytes_dylibloader_wrapper_xlib)( Display*,const char*, int); +int (*XStoreColor_dylibloader_wrapper_xlib)( Display*, Colormap, XColor*); +int (*XStoreColors_dylibloader_wrapper_xlib)( Display*, Colormap, XColor*, int); +int (*XStoreName_dylibloader_wrapper_xlib)( Display*, Window,const char*); +int (*XStoreNamedColor_dylibloader_wrapper_xlib)( Display*, Colormap,const char*, unsigned long, int); +int (*XSync_dylibloader_wrapper_xlib)( Display*, int); +int (*XTextExtents_dylibloader_wrapper_xlib)( XFontStruct*,const char*, int, int*, int*, int*, XCharStruct*); +int (*XTextExtents16_dylibloader_wrapper_xlib)( XFontStruct*,const XChar2b*, int, int*, int*, int*, XCharStruct*); +int (*XTextWidth_dylibloader_wrapper_xlib)( XFontStruct*,const char*, int); +int (*XTextWidth16_dylibloader_wrapper_xlib)( XFontStruct*,const XChar2b*, int); +int (*XTranslateCoordinates_dylibloader_wrapper_xlib)( Display*, Window, Window, int, int, int*, int*, Window*); +int (*XUndefineCursor_dylibloader_wrapper_xlib)( Display*, Window); +int (*XUngrabButton_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, Window); +int (*XUngrabKey_dylibloader_wrapper_xlib)( Display*, int, unsigned int, Window); +int (*XUngrabKeyboard_dylibloader_wrapper_xlib)( Display*, Time); +int (*XUngrabPointer_dylibloader_wrapper_xlib)( Display*, Time); +int (*XUngrabServer_dylibloader_wrapper_xlib)( Display*); +int (*XUninstallColormap_dylibloader_wrapper_xlib)( Display*, Colormap); +int (*XUnloadFont_dylibloader_wrapper_xlib)( Display*, Font); +int (*XUnmapSubwindows_dylibloader_wrapper_xlib)( Display*, Window); +int (*XUnmapWindow_dylibloader_wrapper_xlib)( Display*, Window); +int (*XVendorRelease_dylibloader_wrapper_xlib)( Display*); +int (*XWarpPointer_dylibloader_wrapper_xlib)( Display*, Window, Window, int, int, unsigned int, unsigned int, int, int); +int (*XWidthMMOfScreen_dylibloader_wrapper_xlib)( Screen*); +int (*XWidthOfScreen_dylibloader_wrapper_xlib)( Screen*); +int (*XWindowEvent_dylibloader_wrapper_xlib)( Display*, Window, long, XEvent*); +int (*XWriteBitmapFile_dylibloader_wrapper_xlib)( Display*,const char*, Pixmap, unsigned int, unsigned int, int, int); +int (*XSupportsLocale_dylibloader_wrapper_xlib)( void); +char* (*XSetLocaleModifiers_dylibloader_wrapper_xlib)(const char*); +XOM (*XOpenOM_dylibloader_wrapper_xlib)( Display*,struct _XrmHashBucketRec*,const char*,const char*); +int (*XCloseOM_dylibloader_wrapper_xlib)( XOM); +char* (*XSetOMValues_dylibloader_wrapper_xlib)( XOM,...); +char* (*XGetOMValues_dylibloader_wrapper_xlib)( XOM,...); +Display* (*XDisplayOfOM_dylibloader_wrapper_xlib)( XOM); +char* (*XLocaleOfOM_dylibloader_wrapper_xlib)( XOM); +XOC (*XCreateOC_dylibloader_wrapper_xlib)( XOM,...); +void (*XDestroyOC_dylibloader_wrapper_xlib)( XOC); +XOM (*XOMOfOC_dylibloader_wrapper_xlib)( XOC); +char* (*XSetOCValues_dylibloader_wrapper_xlib)( XOC,...); +char* (*XGetOCValues_dylibloader_wrapper_xlib)( XOC,...); +XFontSet (*XCreateFontSet_dylibloader_wrapper_xlib)( Display*,const char*, char***, int*, char**); +void (*XFreeFontSet_dylibloader_wrapper_xlib)( Display*, XFontSet); +int (*XFontsOfFontSet_dylibloader_wrapper_xlib)( XFontSet, XFontStruct***, char***); +char* (*XBaseFontNameListOfFontSet_dylibloader_wrapper_xlib)( XFontSet); +char* (*XLocaleOfFontSet_dylibloader_wrapper_xlib)( XFontSet); +int (*XContextDependentDrawing_dylibloader_wrapper_xlib)( XFontSet); +int (*XDirectionalDependentDrawing_dylibloader_wrapper_xlib)( XFontSet); +int (*XContextualDrawing_dylibloader_wrapper_xlib)( XFontSet); +XFontSetExtents* (*XExtentsOfFontSet_dylibloader_wrapper_xlib)( XFontSet); +int (*XmbTextEscapement_dylibloader_wrapper_xlib)( XFontSet,const char*, int); +int (*XwcTextEscapement_dylibloader_wrapper_xlib)( XFontSet,const wchar_t*, int); +int (*Xutf8TextEscapement_dylibloader_wrapper_xlib)( XFontSet,const char*, int); +int (*XmbTextExtents_dylibloader_wrapper_xlib)( XFontSet,const char*, int, XRectangle*, XRectangle*); +int (*XwcTextExtents_dylibloader_wrapper_xlib)( XFontSet,const wchar_t*, int, XRectangle*, XRectangle*); +int (*Xutf8TextExtents_dylibloader_wrapper_xlib)( XFontSet,const char*, int, XRectangle*, XRectangle*); +int (*XmbTextPerCharExtents_dylibloader_wrapper_xlib)( XFontSet,const char*, int, XRectangle*, XRectangle*, int, int*, XRectangle*, XRectangle*); +int (*XwcTextPerCharExtents_dylibloader_wrapper_xlib)( XFontSet,const wchar_t*, int, XRectangle*, XRectangle*, int, int*, XRectangle*, XRectangle*); +int (*Xutf8TextPerCharExtents_dylibloader_wrapper_xlib)( XFontSet,const char*, int, XRectangle*, XRectangle*, int, int*, XRectangle*, XRectangle*); +void (*XmbDrawText_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int, XmbTextItem*, int); +void (*XwcDrawText_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int, XwcTextItem*, int); +void (*Xutf8DrawText_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int, XmbTextItem*, int); +void (*XmbDrawString_dylibloader_wrapper_xlib)( Display*, Drawable, XFontSet, GC, int, int,const char*, int); +void (*XwcDrawString_dylibloader_wrapper_xlib)( Display*, Drawable, XFontSet, GC, int, int,const wchar_t*, int); +void (*Xutf8DrawString_dylibloader_wrapper_xlib)( Display*, Drawable, XFontSet, GC, int, int,const char*, int); +void (*XmbDrawImageString_dylibloader_wrapper_xlib)( Display*, Drawable, XFontSet, GC, int, int,const char*, int); +void (*XwcDrawImageString_dylibloader_wrapper_xlib)( Display*, Drawable, XFontSet, GC, int, int,const wchar_t*, int); +void (*Xutf8DrawImageString_dylibloader_wrapper_xlib)( Display*, Drawable, XFontSet, GC, int, int,const char*, int); +XIM (*XOpenIM_dylibloader_wrapper_xlib)( Display*,struct _XrmHashBucketRec*, char*, char*); +int (*XCloseIM_dylibloader_wrapper_xlib)( XIM); +char* (*XGetIMValues_dylibloader_wrapper_xlib)( XIM,...); +char* (*XSetIMValues_dylibloader_wrapper_xlib)( XIM,...); +Display* (*XDisplayOfIM_dylibloader_wrapper_xlib)( XIM); +char* (*XLocaleOfIM_dylibloader_wrapper_xlib)( XIM); +XIC (*XCreateIC_dylibloader_wrapper_xlib)( XIM,...); +void (*XDestroyIC_dylibloader_wrapper_xlib)( XIC); +void (*XSetICFocus_dylibloader_wrapper_xlib)( XIC); +void (*XUnsetICFocus_dylibloader_wrapper_xlib)( XIC); +wchar_t* (*XwcResetIC_dylibloader_wrapper_xlib)( XIC); +char* (*XmbResetIC_dylibloader_wrapper_xlib)( XIC); +char* (*Xutf8ResetIC_dylibloader_wrapper_xlib)( XIC); +char* (*XSetICValues_dylibloader_wrapper_xlib)( XIC,...); +char* (*XGetICValues_dylibloader_wrapper_xlib)( XIC,...); +XIM (*XIMOfIC_dylibloader_wrapper_xlib)( XIC); +int (*XFilterEvent_dylibloader_wrapper_xlib)( XEvent*, Window); +int (*XmbLookupString_dylibloader_wrapper_xlib)( XIC, XKeyPressedEvent*, char*, int, KeySym*, int*); +int (*XwcLookupString_dylibloader_wrapper_xlib)( XIC, XKeyPressedEvent*, wchar_t*, int, KeySym*, int*); +int (*Xutf8LookupString_dylibloader_wrapper_xlib)( XIC, XKeyPressedEvent*, char*, int, KeySym*, int*); +XVaNestedList (*XVaCreateNestedList_dylibloader_wrapper_xlib)( int,...); +int (*XRegisterIMInstantiateCallback_dylibloader_wrapper_xlib)( Display*,struct _XrmHashBucketRec*, char*, char*, XIDProc, XPointer); +int (*XUnregisterIMInstantiateCallback_dylibloader_wrapper_xlib)( Display*,struct _XrmHashBucketRec*, char*, char*, XIDProc, XPointer); +int (*XInternalConnectionNumbers_dylibloader_wrapper_xlib)( Display*, int**, int*); +void (*XProcessInternalConnection_dylibloader_wrapper_xlib)( Display*, int); +int (*XAddConnectionWatch_dylibloader_wrapper_xlib)( Display*, XConnectionWatchProc, XPointer); +void (*XRemoveConnectionWatch_dylibloader_wrapper_xlib)( Display*, XConnectionWatchProc, XPointer); +void (*XSetAuthorization_dylibloader_wrapper_xlib)( char*, int, char*, int); +int (*_Xmbtowc_dylibloader_wrapper_xlib)( wchar_t*, char*, int); +int (*_Xwctomb_dylibloader_wrapper_xlib)( char*, wchar_t); +int (*XGetEventData_dylibloader_wrapper_xlib)( Display*, XGenericEventCookie*); +void (*XFreeEventData_dylibloader_wrapper_xlib)( Display*, XGenericEventCookie*); +XClassHint* (*XAllocClassHint_dylibloader_wrapper_xlib)( void); +XIconSize* (*XAllocIconSize_dylibloader_wrapper_xlib)( void); +XSizeHints* (*XAllocSizeHints_dylibloader_wrapper_xlib)( void); +XStandardColormap* (*XAllocStandardColormap_dylibloader_wrapper_xlib)( void); +XWMHints* (*XAllocWMHints_dylibloader_wrapper_xlib)( void); +int (*XClipBox_dylibloader_wrapper_xlib)( Region, XRectangle*); +Region (*XCreateRegion_dylibloader_wrapper_xlib)( void); +const char* (*XDefaultString_dylibloader_wrapper_xlib)( void); +int (*XDeleteContext_dylibloader_wrapper_xlib)( Display*, XID, XContext); +int (*XDestroyRegion_dylibloader_wrapper_xlib)( Region); +int (*XEmptyRegion_dylibloader_wrapper_xlib)( Region); +int (*XEqualRegion_dylibloader_wrapper_xlib)( Region, Region); +int (*XFindContext_dylibloader_wrapper_xlib)( Display*, XID, XContext, XPointer*); +int (*XGetClassHint_dylibloader_wrapper_xlib)( Display*, Window, XClassHint*); +int (*XGetIconSizes_dylibloader_wrapper_xlib)( Display*, Window, XIconSize**, int*); +int (*XGetNormalHints_dylibloader_wrapper_xlib)( Display*, Window, XSizeHints*); +int (*XGetRGBColormaps_dylibloader_wrapper_xlib)( Display*, Window, XStandardColormap**, int*, Atom); +int (*XGetSizeHints_dylibloader_wrapper_xlib)( Display*, Window, XSizeHints*, Atom); +int (*XGetStandardColormap_dylibloader_wrapper_xlib)( Display*, Window, XStandardColormap*, Atom); +int (*XGetTextProperty_dylibloader_wrapper_xlib)( Display*, Window, XTextProperty*, Atom); +XVisualInfo* (*XGetVisualInfo_dylibloader_wrapper_xlib)( Display*, long, XVisualInfo*, int*); +int (*XGetWMClientMachine_dylibloader_wrapper_xlib)( Display*, Window, XTextProperty*); +XWMHints* (*XGetWMHints_dylibloader_wrapper_xlib)( Display*, Window); +int (*XGetWMIconName_dylibloader_wrapper_xlib)( Display*, Window, XTextProperty*); +int (*XGetWMName_dylibloader_wrapper_xlib)( Display*, Window, XTextProperty*); +int (*XGetWMNormalHints_dylibloader_wrapper_xlib)( Display*, Window, XSizeHints*, long*); +int (*XGetWMSizeHints_dylibloader_wrapper_xlib)( Display*, Window, XSizeHints*, long*, Atom); +int (*XGetZoomHints_dylibloader_wrapper_xlib)( Display*, Window, XSizeHints*); +int (*XIntersectRegion_dylibloader_wrapper_xlib)( Region, Region, Region); +void (*XConvertCase_dylibloader_wrapper_xlib)( KeySym, KeySym*, KeySym*); +int (*XLookupString_dylibloader_wrapper_xlib)( XKeyEvent*, char*, int, KeySym*, XComposeStatus*); +int (*XMatchVisualInfo_dylibloader_wrapper_xlib)( Display*, int, int, int, XVisualInfo*); +int (*XOffsetRegion_dylibloader_wrapper_xlib)( Region, int, int); +int (*XPointInRegion_dylibloader_wrapper_xlib)( Region, int, int); +Region (*XPolygonRegion_dylibloader_wrapper_xlib)( XPoint*, int, int); +int (*XRectInRegion_dylibloader_wrapper_xlib)( Region, int, int, unsigned int, unsigned int); +int (*XSaveContext_dylibloader_wrapper_xlib)( Display*, XID, XContext,const char*); +int (*XSetClassHint_dylibloader_wrapper_xlib)( Display*, Window, XClassHint*); +int (*XSetIconSizes_dylibloader_wrapper_xlib)( Display*, Window, XIconSize*, int); +int (*XSetNormalHints_dylibloader_wrapper_xlib)( Display*, Window, XSizeHints*); +void (*XSetRGBColormaps_dylibloader_wrapper_xlib)( Display*, Window, XStandardColormap*, int, Atom); +int (*XSetSizeHints_dylibloader_wrapper_xlib)( Display*, Window, XSizeHints*, Atom); +int (*XSetStandardProperties_dylibloader_wrapper_xlib)( Display*, Window,const char*,const char*, Pixmap, char**, int, XSizeHints*); +void (*XSetTextProperty_dylibloader_wrapper_xlib)( Display*, Window, XTextProperty*, Atom); +void (*XSetWMClientMachine_dylibloader_wrapper_xlib)( Display*, Window, XTextProperty*); +int (*XSetWMHints_dylibloader_wrapper_xlib)( Display*, Window, XWMHints*); +void (*XSetWMIconName_dylibloader_wrapper_xlib)( Display*, Window, XTextProperty*); +void (*XSetWMName_dylibloader_wrapper_xlib)( Display*, Window, XTextProperty*); +void (*XSetWMNormalHints_dylibloader_wrapper_xlib)( Display*, Window, XSizeHints*); +void (*XSetWMProperties_dylibloader_wrapper_xlib)( Display*, Window, XTextProperty*, XTextProperty*, char**, int, XSizeHints*, XWMHints*, XClassHint*); +void (*XmbSetWMProperties_dylibloader_wrapper_xlib)( Display*, Window,const char*,const char*, char**, int, XSizeHints*, XWMHints*, XClassHint*); +void (*Xutf8SetWMProperties_dylibloader_wrapper_xlib)( Display*, Window,const char*,const char*, char**, int, XSizeHints*, XWMHints*, XClassHint*); +void (*XSetWMSizeHints_dylibloader_wrapper_xlib)( Display*, Window, XSizeHints*, Atom); +int (*XSetRegion_dylibloader_wrapper_xlib)( Display*, GC, Region); +void (*XSetStandardColormap_dylibloader_wrapper_xlib)( Display*, Window, XStandardColormap*, Atom); +int (*XSetZoomHints_dylibloader_wrapper_xlib)( Display*, Window, XSizeHints*); +int (*XShrinkRegion_dylibloader_wrapper_xlib)( Region, int, int); +int (*XStringListToTextProperty_dylibloader_wrapper_xlib)( char**, int, XTextProperty*); +int (*XSubtractRegion_dylibloader_wrapper_xlib)( Region, Region, Region); +int (*XmbTextListToTextProperty_dylibloader_wrapper_xlib)( Display*, char**, int, XICCEncodingStyle, XTextProperty*); +int (*XwcTextListToTextProperty_dylibloader_wrapper_xlib)( Display*, wchar_t**, int, XICCEncodingStyle, XTextProperty*); +int (*Xutf8TextListToTextProperty_dylibloader_wrapper_xlib)( Display*, char**, int, XICCEncodingStyle, XTextProperty*); +void (*XwcFreeStringList_dylibloader_wrapper_xlib)( wchar_t**); +int (*XTextPropertyToStringList_dylibloader_wrapper_xlib)( XTextProperty*, char***, int*); +int (*XmbTextPropertyToTextList_dylibloader_wrapper_xlib)( Display*,const XTextProperty*, char***, int*); +int (*XwcTextPropertyToTextList_dylibloader_wrapper_xlib)( Display*,const XTextProperty*, wchar_t***, int*); +int (*Xutf8TextPropertyToTextList_dylibloader_wrapper_xlib)( Display*,const XTextProperty*, char***, int*); +int (*XUnionRectWithRegion_dylibloader_wrapper_xlib)( XRectangle*, Region, Region); +int (*XUnionRegion_dylibloader_wrapper_xlib)( Region, Region, Region); +int (*XWMGeometry_dylibloader_wrapper_xlib)( Display*, int,const char*,const char*, unsigned int, XSizeHints*, int*, int*, int*, int*, int*); +int (*XXorRegion_dylibloader_wrapper_xlib)( Region, Region, Region); +int (*XkbIgnoreExtension_dylibloader_wrapper_xlib)( int); +Display* (*XkbOpenDisplay_dylibloader_wrapper_xlib)( char*, int*, int*, int*, int*, int*); +int (*XkbQueryExtension_dylibloader_wrapper_xlib)( Display*, int*, int*, int*, int*, int*); +int (*XkbUseExtension_dylibloader_wrapper_xlib)( Display*, int*, int*); +int (*XkbLibraryVersion_dylibloader_wrapper_xlib)( int*, int*); +unsigned int (*XkbSetXlibControls_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int); +unsigned int (*XkbGetXlibControls_dylibloader_wrapper_xlib)( Display*); +unsigned int (*XkbXlibControlsImplemented_dylibloader_wrapper_xlib)( void); +void (*XkbSetAtomFuncs_dylibloader_wrapper_xlib)( XkbInternAtomFunc, XkbGetAtomNameFunc); +KeySym (*XkbKeycodeToKeysym_dylibloader_wrapper_xlib)( Display*, KeyCode, int, int); +unsigned int (*XkbKeysymToModifiers_dylibloader_wrapper_xlib)( Display*, KeySym); +int (*XkbLookupKeySym_dylibloader_wrapper_xlib)( Display*, KeyCode, unsigned int, unsigned int*, KeySym*); +int (*XkbLookupKeyBinding_dylibloader_wrapper_xlib)( Display*, KeySym, unsigned int, char*, int, int*); +int (*XkbTranslateKeyCode_dylibloader_wrapper_xlib)( XkbDescPtr, KeyCode, unsigned int, unsigned int*, KeySym*); +int (*XkbTranslateKeySym_dylibloader_wrapper_xlib)( Display*, KeySym*, unsigned int, char*, int, int*); +int (*XkbSetAutoRepeatRate_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned int); +int (*XkbGetAutoRepeatRate_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int*, unsigned int*); +int (*XkbChangeEnabledControls_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned int); +int (*XkbDeviceBell_dylibloader_wrapper_xlib)( Display*, Window, int, int, int, int, Atom); +int (*XkbForceDeviceBell_dylibloader_wrapper_xlib)( Display*, int, int, int, int); +int (*XkbDeviceBellEvent_dylibloader_wrapper_xlib)( Display*, Window, int, int, int, int, Atom); +int (*XkbBell_dylibloader_wrapper_xlib)( Display*, Window, int, Atom); +int (*XkbForceBell_dylibloader_wrapper_xlib)( Display*, int); +int (*XkbBellEvent_dylibloader_wrapper_xlib)( Display*, Window, int, Atom); +int (*XkbSelectEvents_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned int); +int (*XkbSelectEventDetails_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned long, unsigned long); +void (*XkbNoteMapChanges_dylibloader_wrapper_xlib)( XkbMapChangesPtr, XkbMapNotifyEvent*, unsigned int); +void (*XkbNoteNameChanges_dylibloader_wrapper_xlib)( XkbNameChangesPtr, XkbNamesNotifyEvent*, unsigned int); +int (*XkbGetIndicatorState_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int*); +int (*XkbGetIndicatorMap_dylibloader_wrapper_xlib)( Display*, unsigned long, XkbDescPtr); +int (*XkbSetIndicatorMap_dylibloader_wrapper_xlib)( Display*, unsigned long, XkbDescPtr); +int (*XkbGetNamedIndicator_dylibloader_wrapper_xlib)( Display*, Atom, int*, int*, XkbIndicatorMapPtr, int*); +int (*XkbGetNamedDeviceIndicator_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned int, Atom, int*, int*, XkbIndicatorMapPtr, int*); +int (*XkbSetNamedIndicator_dylibloader_wrapper_xlib)( Display*, Atom, int, int, int, XkbIndicatorMapPtr); +int (*XkbSetNamedDeviceIndicator_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned int, Atom, int, int, int, XkbIndicatorMapPtr); +int (*XkbLockModifiers_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned int); +int (*XkbLatchModifiers_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned int); +int (*XkbLockGroup_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int); +int (*XkbLatchGroup_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int); +int (*XkbSetServerInternalMods_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int); +int (*XkbSetIgnoreLockMods_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int); +int (*XkbVirtualModsToReal_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, unsigned int*); +int (*XkbComputeEffectiveMap_dylibloader_wrapper_xlib)( XkbDescPtr, XkbKeyTypePtr, unsigned char*); +int (*XkbInitCanonicalKeyTypes_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, int); +XkbDescPtr (*XkbAllocKeyboard_dylibloader_wrapper_xlib)( void); +void (*XkbFreeKeyboard_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, int); +int (*XkbAllocClientMap_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, unsigned int); +int (*XkbAllocServerMap_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, unsigned int); +void (*XkbFreeClientMap_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, int); +void (*XkbFreeServerMap_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, int); +XkbKeyTypePtr (*XkbAddKeyType_dylibloader_wrapper_xlib)( XkbDescPtr, Atom, int, int, int); +int (*XkbAllocIndicatorMaps_dylibloader_wrapper_xlib)( XkbDescPtr); +void (*XkbFreeIndicatorMaps_dylibloader_wrapper_xlib)( XkbDescPtr); +XkbDescPtr (*XkbGetMap_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int); +int (*XkbGetUpdatedMap_dylibloader_wrapper_xlib)( Display*, unsigned int, XkbDescPtr); +int (*XkbGetMapChanges_dylibloader_wrapper_xlib)( Display*, XkbDescPtr, XkbMapChangesPtr); +int (*XkbRefreshKeyboardMapping_dylibloader_wrapper_xlib)( XkbMapNotifyEvent*); +int (*XkbGetKeyTypes_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, XkbDescPtr); +int (*XkbGetKeySyms_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, XkbDescPtr); +int (*XkbGetKeyActions_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, XkbDescPtr); +int (*XkbGetKeyBehaviors_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, XkbDescPtr); +int (*XkbGetVirtualMods_dylibloader_wrapper_xlib)( Display*, unsigned int, XkbDescPtr); +int (*XkbGetKeyExplicitComponents_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, XkbDescPtr); +int (*XkbGetKeyModifierMap_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, XkbDescPtr); +int (*XkbGetKeyVirtualModMap_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, XkbDescPtr); +int (*XkbAllocControls_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int); +void (*XkbFreeControls_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, int); +int (*XkbGetControls_dylibloader_wrapper_xlib)( Display*, unsigned long, XkbDescPtr); +int (*XkbSetControls_dylibloader_wrapper_xlib)( Display*, unsigned long, XkbDescPtr); +void (*XkbNoteControlsChanges_dylibloader_wrapper_xlib)( XkbControlsChangesPtr, XkbControlsNotifyEvent*, unsigned int); +int (*XkbAllocCompatMap_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, unsigned int); +void (*XkbFreeCompatMap_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, int); +int (*XkbGetCompatMap_dylibloader_wrapper_xlib)( Display*, unsigned int, XkbDescPtr); +int (*XkbSetCompatMap_dylibloader_wrapper_xlib)( Display*, unsigned int, XkbDescPtr, int); +int (*XkbAllocNames_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, int, int); +int (*XkbGetNames_dylibloader_wrapper_xlib)( Display*, unsigned int, XkbDescPtr); +int (*XkbSetNames_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned int, XkbDescPtr); +int (*XkbChangeNames_dylibloader_wrapper_xlib)( Display*, XkbDescPtr, XkbNameChangesPtr); +void (*XkbFreeNames_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, int); +int (*XkbGetState_dylibloader_wrapper_xlib)( Display*, unsigned int, XkbStatePtr); +int (*XkbSetMap_dylibloader_wrapper_xlib)( Display*, unsigned int, XkbDescPtr); +int (*XkbChangeMap_dylibloader_wrapper_xlib)( Display*, XkbDescPtr, XkbMapChangesPtr); +int (*XkbSetDetectableAutoRepeat_dylibloader_wrapper_xlib)( Display*, int, int*); +int (*XkbGetDetectableAutoRepeat_dylibloader_wrapper_xlib)( Display*, int*); +int (*XkbSetAutoResetControls_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int*, unsigned int*); +int (*XkbGetAutoResetControls_dylibloader_wrapper_xlib)( Display*, unsigned int*, unsigned int*); +int (*XkbSetPerClientControls_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int*); +int (*XkbGetPerClientControls_dylibloader_wrapper_xlib)( Display*, unsigned int*); +int (*XkbCopyKeyType_dylibloader_wrapper_xlib)( XkbKeyTypePtr, XkbKeyTypePtr); +int (*XkbCopyKeyTypes_dylibloader_wrapper_xlib)( XkbKeyTypePtr, XkbKeyTypePtr, int); +int (*XkbResizeKeyType_dylibloader_wrapper_xlib)( XkbDescPtr, int, int, int, int); +KeySym* (*XkbResizeKeySyms_dylibloader_wrapper_xlib)( XkbDescPtr, int, int); +XkbAction* (*XkbResizeKeyActions_dylibloader_wrapper_xlib)( XkbDescPtr, int, int); +int (*XkbChangeTypesOfKey_dylibloader_wrapper_xlib)( XkbDescPtr, int, int, unsigned int, int*, XkbMapChangesPtr); +int (*XkbChangeKeycodeRange_dylibloader_wrapper_xlib)( XkbDescPtr, int, int, XkbChangesPtr); +XkbComponentListPtr (*XkbListComponents_dylibloader_wrapper_xlib)( Display*, unsigned int, XkbComponentNamesPtr, int*); +void (*XkbFreeComponentList_dylibloader_wrapper_xlib)( XkbComponentListPtr); +XkbDescPtr (*XkbGetKeyboard_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int); +XkbDescPtr (*XkbGetKeyboardByName_dylibloader_wrapper_xlib)( Display*, unsigned int, XkbComponentNamesPtr, unsigned int, unsigned int, int); +int (*XkbKeyTypesForCoreSymbols_dylibloader_wrapper_xlib)( XkbDescPtr, int, KeySym*, unsigned int, int*, KeySym*); +int (*XkbApplyCompatMapToKey_dylibloader_wrapper_xlib)( XkbDescPtr, KeyCode, XkbChangesPtr); +int (*XkbUpdateMapFromCore_dylibloader_wrapper_xlib)( XkbDescPtr, KeyCode, int, int, KeySym*, XkbChangesPtr); +XkbDeviceLedInfoPtr (*XkbAddDeviceLedInfo_dylibloader_wrapper_xlib)( XkbDeviceInfoPtr, unsigned int, unsigned int); +int (*XkbResizeDeviceButtonActions_dylibloader_wrapper_xlib)( XkbDeviceInfoPtr, unsigned int); +XkbDeviceInfoPtr (*XkbAllocDeviceInfo_dylibloader_wrapper_xlib)( unsigned int, unsigned int, unsigned int); +void (*XkbFreeDeviceInfo_dylibloader_wrapper_xlib)( XkbDeviceInfoPtr, unsigned int, int); +void (*XkbNoteDeviceChanges_dylibloader_wrapper_xlib)( XkbDeviceChangesPtr, XkbExtensionDeviceNotifyEvent*, unsigned int); +XkbDeviceInfoPtr (*XkbGetDeviceInfo_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned int, unsigned int); +int (*XkbGetDeviceInfoChanges_dylibloader_wrapper_xlib)( Display*, XkbDeviceInfoPtr, XkbDeviceChangesPtr); +int (*XkbGetDeviceButtonActions_dylibloader_wrapper_xlib)( Display*, XkbDeviceInfoPtr, int, unsigned int, unsigned int); +int (*XkbGetDeviceLedInfo_dylibloader_wrapper_xlib)( Display*, XkbDeviceInfoPtr, unsigned int, unsigned int, unsigned int); +int (*XkbSetDeviceInfo_dylibloader_wrapper_xlib)( Display*, unsigned int, XkbDeviceInfoPtr); +int (*XkbChangeDeviceInfo_dylibloader_wrapper_xlib)( Display*, XkbDeviceInfoPtr, XkbDeviceChangesPtr); +int (*XkbSetDeviceLedInfo_dylibloader_wrapper_xlib)( Display*, XkbDeviceInfoPtr, unsigned int, unsigned int, unsigned int); +int (*XkbSetDeviceButtonActions_dylibloader_wrapper_xlib)( Display*, XkbDeviceInfoPtr, unsigned int, unsigned int); +char (*XkbToControl_dylibloader_wrapper_xlib)( char); +int (*XkbSetDebuggingFlags_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, char*, unsigned int, unsigned int, unsigned int*, unsigned int*); +int (*XkbApplyVirtualModChanges_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, XkbChangesPtr); +int (*XkbUpdateActionVirtualMods_dylibloader_wrapper_xlib)( XkbDescPtr, XkbAction*, unsigned int); +void (*XkbUpdateKeyTypeVirtualMods_dylibloader_wrapper_xlib)( XkbDescPtr, XkbKeyTypePtr, unsigned int, XkbChangesPtr); +int initialize_xlib(int verbose) { + void *handle; + char *error; + handle = dlopen("libX11.so.6", RTLD_LAZY); + if (!handle) { + if (verbose) { + fprintf(stderr, "%s\n", dlerror()); + } + return(1); + } + dlerror(); +// _Xmblen + *(void **) (&_Xmblen_dylibloader_wrapper_xlib) = dlsym(handle, "_Xmblen"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XLoadQueryFont + *(void **) (&XLoadQueryFont_dylibloader_wrapper_xlib) = dlsym(handle, "XLoadQueryFont"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XQueryFont + *(void **) (&XQueryFont_dylibloader_wrapper_xlib) = dlsym(handle, "XQueryFont"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetMotionEvents + *(void **) (&XGetMotionEvents_dylibloader_wrapper_xlib) = dlsym(handle, "XGetMotionEvents"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDeleteModifiermapEntry + *(void **) (&XDeleteModifiermapEntry_dylibloader_wrapper_xlib) = dlsym(handle, "XDeleteModifiermapEntry"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetModifierMapping + *(void **) (&XGetModifierMapping_dylibloader_wrapper_xlib) = dlsym(handle, "XGetModifierMapping"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XInsertModifiermapEntry + *(void **) (&XInsertModifiermapEntry_dylibloader_wrapper_xlib) = dlsym(handle, "XInsertModifiermapEntry"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XNewModifiermap + *(void **) (&XNewModifiermap_dylibloader_wrapper_xlib) = dlsym(handle, "XNewModifiermap"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XCreateImage + *(void **) (&XCreateImage_dylibloader_wrapper_xlib) = dlsym(handle, "XCreateImage"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XInitImage + *(void **) (&XInitImage_dylibloader_wrapper_xlib) = dlsym(handle, "XInitImage"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetImage + *(void **) (&XGetImage_dylibloader_wrapper_xlib) = dlsym(handle, "XGetImage"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetSubImage + *(void **) (&XGetSubImage_dylibloader_wrapper_xlib) = dlsym(handle, "XGetSubImage"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XOpenDisplay + *(void **) (&XOpenDisplay_dylibloader_wrapper_xlib) = dlsym(handle, "XOpenDisplay"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XrmInitialize + *(void **) (&XrmInitialize_dylibloader_wrapper_xlib) = dlsym(handle, "XrmInitialize"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XFetchBytes + *(void **) (&XFetchBytes_dylibloader_wrapper_xlib) = dlsym(handle, "XFetchBytes"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XFetchBuffer + *(void **) (&XFetchBuffer_dylibloader_wrapper_xlib) = dlsym(handle, "XFetchBuffer"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetAtomName + *(void **) (&XGetAtomName_dylibloader_wrapper_xlib) = dlsym(handle, "XGetAtomName"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetAtomNames + *(void **) (&XGetAtomNames_dylibloader_wrapper_xlib) = dlsym(handle, "XGetAtomNames"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetDefault + *(void **) (&XGetDefault_dylibloader_wrapper_xlib) = dlsym(handle, "XGetDefault"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDisplayName + *(void **) (&XDisplayName_dylibloader_wrapper_xlib) = dlsym(handle, "XDisplayName"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XKeysymToString + *(void **) (&XKeysymToString_dylibloader_wrapper_xlib) = dlsym(handle, "XKeysymToString"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSynchronize + *(void **) (&XSynchronize_dylibloader_wrapper_xlib) = dlsym(handle, "XSynchronize"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetAfterFunction + *(void **) (&XSetAfterFunction_dylibloader_wrapper_xlib) = dlsym(handle, "XSetAfterFunction"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XInternAtom + *(void **) (&XInternAtom_dylibloader_wrapper_xlib) = dlsym(handle, "XInternAtom"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XInternAtoms + *(void **) (&XInternAtoms_dylibloader_wrapper_xlib) = dlsym(handle, "XInternAtoms"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XCopyColormapAndFree + *(void **) (&XCopyColormapAndFree_dylibloader_wrapper_xlib) = dlsym(handle, "XCopyColormapAndFree"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XCreateColormap + *(void **) (&XCreateColormap_dylibloader_wrapper_xlib) = dlsym(handle, "XCreateColormap"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XCreatePixmapCursor + *(void **) (&XCreatePixmapCursor_dylibloader_wrapper_xlib) = dlsym(handle, "XCreatePixmapCursor"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XCreateGlyphCursor + *(void **) (&XCreateGlyphCursor_dylibloader_wrapper_xlib) = dlsym(handle, "XCreateGlyphCursor"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XCreateFontCursor + *(void **) (&XCreateFontCursor_dylibloader_wrapper_xlib) = dlsym(handle, "XCreateFontCursor"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XLoadFont + *(void **) (&XLoadFont_dylibloader_wrapper_xlib) = dlsym(handle, "XLoadFont"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XCreateGC + *(void **) (&XCreateGC_dylibloader_wrapper_xlib) = dlsym(handle, "XCreateGC"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGContextFromGC + *(void **) (&XGContextFromGC_dylibloader_wrapper_xlib) = dlsym(handle, "XGContextFromGC"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XFlushGC + *(void **) (&XFlushGC_dylibloader_wrapper_xlib) = dlsym(handle, "XFlushGC"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XCreatePixmap + *(void **) (&XCreatePixmap_dylibloader_wrapper_xlib) = dlsym(handle, "XCreatePixmap"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XCreateBitmapFromData + *(void **) (&XCreateBitmapFromData_dylibloader_wrapper_xlib) = dlsym(handle, "XCreateBitmapFromData"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XCreatePixmapFromBitmapData + *(void **) (&XCreatePixmapFromBitmapData_dylibloader_wrapper_xlib) = dlsym(handle, "XCreatePixmapFromBitmapData"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XCreateSimpleWindow + *(void **) (&XCreateSimpleWindow_dylibloader_wrapper_xlib) = dlsym(handle, "XCreateSimpleWindow"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetSelectionOwner + *(void **) (&XGetSelectionOwner_dylibloader_wrapper_xlib) = dlsym(handle, "XGetSelectionOwner"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XCreateWindow + *(void **) (&XCreateWindow_dylibloader_wrapper_xlib) = dlsym(handle, "XCreateWindow"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XListInstalledColormaps + *(void **) (&XListInstalledColormaps_dylibloader_wrapper_xlib) = dlsym(handle, "XListInstalledColormaps"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XListFonts + *(void **) (&XListFonts_dylibloader_wrapper_xlib) = dlsym(handle, "XListFonts"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XListFontsWithInfo + *(void **) (&XListFontsWithInfo_dylibloader_wrapper_xlib) = dlsym(handle, "XListFontsWithInfo"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetFontPath + *(void **) (&XGetFontPath_dylibloader_wrapper_xlib) = dlsym(handle, "XGetFontPath"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XListExtensions + *(void **) (&XListExtensions_dylibloader_wrapper_xlib) = dlsym(handle, "XListExtensions"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XListProperties + *(void **) (&XListProperties_dylibloader_wrapper_xlib) = dlsym(handle, "XListProperties"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XListHosts + *(void **) (&XListHosts_dylibloader_wrapper_xlib) = dlsym(handle, "XListHosts"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XKeycodeToKeysym + *(void **) (&XKeycodeToKeysym_dylibloader_wrapper_xlib) = dlsym(handle, "XKeycodeToKeysym"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XLookupKeysym + *(void **) (&XLookupKeysym_dylibloader_wrapper_xlib) = dlsym(handle, "XLookupKeysym"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetKeyboardMapping + *(void **) (&XGetKeyboardMapping_dylibloader_wrapper_xlib) = dlsym(handle, "XGetKeyboardMapping"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XStringToKeysym + *(void **) (&XStringToKeysym_dylibloader_wrapper_xlib) = dlsym(handle, "XStringToKeysym"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XMaxRequestSize + *(void **) (&XMaxRequestSize_dylibloader_wrapper_xlib) = dlsym(handle, "XMaxRequestSize"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XExtendedMaxRequestSize + *(void **) (&XExtendedMaxRequestSize_dylibloader_wrapper_xlib) = dlsym(handle, "XExtendedMaxRequestSize"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XResourceManagerString + *(void **) (&XResourceManagerString_dylibloader_wrapper_xlib) = dlsym(handle, "XResourceManagerString"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XScreenResourceString + *(void **) (&XScreenResourceString_dylibloader_wrapper_xlib) = dlsym(handle, "XScreenResourceString"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDisplayMotionBufferSize + *(void **) (&XDisplayMotionBufferSize_dylibloader_wrapper_xlib) = dlsym(handle, "XDisplayMotionBufferSize"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XVisualIDFromVisual + *(void **) (&XVisualIDFromVisual_dylibloader_wrapper_xlib) = dlsym(handle, "XVisualIDFromVisual"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XInitThreads + *(void **) (&XInitThreads_dylibloader_wrapper_xlib) = dlsym(handle, "XInitThreads"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XLockDisplay + *(void **) (&XLockDisplay_dylibloader_wrapper_xlib) = dlsym(handle, "XLockDisplay"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XUnlockDisplay + *(void **) (&XUnlockDisplay_dylibloader_wrapper_xlib) = dlsym(handle, "XUnlockDisplay"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XInitExtension + *(void **) (&XInitExtension_dylibloader_wrapper_xlib) = dlsym(handle, "XInitExtension"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XAddExtension + *(void **) (&XAddExtension_dylibloader_wrapper_xlib) = dlsym(handle, "XAddExtension"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XFindOnExtensionList + *(void **) (&XFindOnExtensionList_dylibloader_wrapper_xlib) = dlsym(handle, "XFindOnExtensionList"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XEHeadOfExtensionList + *(void **) (&XEHeadOfExtensionList_dylibloader_wrapper_xlib) = dlsym(handle, "XEHeadOfExtensionList"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRootWindow + *(void **) (&XRootWindow_dylibloader_wrapper_xlib) = dlsym(handle, "XRootWindow"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDefaultRootWindow + *(void **) (&XDefaultRootWindow_dylibloader_wrapper_xlib) = dlsym(handle, "XDefaultRootWindow"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRootWindowOfScreen + *(void **) (&XRootWindowOfScreen_dylibloader_wrapper_xlib) = dlsym(handle, "XRootWindowOfScreen"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDefaultVisual + *(void **) (&XDefaultVisual_dylibloader_wrapper_xlib) = dlsym(handle, "XDefaultVisual"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDefaultVisualOfScreen + *(void **) (&XDefaultVisualOfScreen_dylibloader_wrapper_xlib) = dlsym(handle, "XDefaultVisualOfScreen"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDefaultGC + *(void **) (&XDefaultGC_dylibloader_wrapper_xlib) = dlsym(handle, "XDefaultGC"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDefaultGCOfScreen + *(void **) (&XDefaultGCOfScreen_dylibloader_wrapper_xlib) = dlsym(handle, "XDefaultGCOfScreen"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XBlackPixel + *(void **) (&XBlackPixel_dylibloader_wrapper_xlib) = dlsym(handle, "XBlackPixel"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XWhitePixel + *(void **) (&XWhitePixel_dylibloader_wrapper_xlib) = dlsym(handle, "XWhitePixel"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XAllPlanes + *(void **) (&XAllPlanes_dylibloader_wrapper_xlib) = dlsym(handle, "XAllPlanes"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XBlackPixelOfScreen + *(void **) (&XBlackPixelOfScreen_dylibloader_wrapper_xlib) = dlsym(handle, "XBlackPixelOfScreen"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XWhitePixelOfScreen + *(void **) (&XWhitePixelOfScreen_dylibloader_wrapper_xlib) = dlsym(handle, "XWhitePixelOfScreen"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XNextRequest + *(void **) (&XNextRequest_dylibloader_wrapper_xlib) = dlsym(handle, "XNextRequest"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XLastKnownRequestProcessed + *(void **) (&XLastKnownRequestProcessed_dylibloader_wrapper_xlib) = dlsym(handle, "XLastKnownRequestProcessed"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XServerVendor + *(void **) (&XServerVendor_dylibloader_wrapper_xlib) = dlsym(handle, "XServerVendor"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDisplayString + *(void **) (&XDisplayString_dylibloader_wrapper_xlib) = dlsym(handle, "XDisplayString"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDefaultColormap + *(void **) (&XDefaultColormap_dylibloader_wrapper_xlib) = dlsym(handle, "XDefaultColormap"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDefaultColormapOfScreen + *(void **) (&XDefaultColormapOfScreen_dylibloader_wrapper_xlib) = dlsym(handle, "XDefaultColormapOfScreen"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDisplayOfScreen + *(void **) (&XDisplayOfScreen_dylibloader_wrapper_xlib) = dlsym(handle, "XDisplayOfScreen"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XScreenOfDisplay + *(void **) (&XScreenOfDisplay_dylibloader_wrapper_xlib) = dlsym(handle, "XScreenOfDisplay"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDefaultScreenOfDisplay + *(void **) (&XDefaultScreenOfDisplay_dylibloader_wrapper_xlib) = dlsym(handle, "XDefaultScreenOfDisplay"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XEventMaskOfScreen + *(void **) (&XEventMaskOfScreen_dylibloader_wrapper_xlib) = dlsym(handle, "XEventMaskOfScreen"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XScreenNumberOfScreen + *(void **) (&XScreenNumberOfScreen_dylibloader_wrapper_xlib) = dlsym(handle, "XScreenNumberOfScreen"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetErrorHandler + *(void **) (&XSetErrorHandler_dylibloader_wrapper_xlib) = dlsym(handle, "XSetErrorHandler"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetIOErrorHandler + *(void **) (&XSetIOErrorHandler_dylibloader_wrapper_xlib) = dlsym(handle, "XSetIOErrorHandler"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XListPixmapFormats + *(void **) (&XListPixmapFormats_dylibloader_wrapper_xlib) = dlsym(handle, "XListPixmapFormats"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XListDepths + *(void **) (&XListDepths_dylibloader_wrapper_xlib) = dlsym(handle, "XListDepths"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XReconfigureWMWindow + *(void **) (&XReconfigureWMWindow_dylibloader_wrapper_xlib) = dlsym(handle, "XReconfigureWMWindow"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetWMProtocols + *(void **) (&XGetWMProtocols_dylibloader_wrapper_xlib) = dlsym(handle, "XGetWMProtocols"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetWMProtocols + *(void **) (&XSetWMProtocols_dylibloader_wrapper_xlib) = dlsym(handle, "XSetWMProtocols"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XIconifyWindow + *(void **) (&XIconifyWindow_dylibloader_wrapper_xlib) = dlsym(handle, "XIconifyWindow"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XWithdrawWindow + *(void **) (&XWithdrawWindow_dylibloader_wrapper_xlib) = dlsym(handle, "XWithdrawWindow"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetCommand + *(void **) (&XGetCommand_dylibloader_wrapper_xlib) = dlsym(handle, "XGetCommand"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetWMColormapWindows + *(void **) (&XGetWMColormapWindows_dylibloader_wrapper_xlib) = dlsym(handle, "XGetWMColormapWindows"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetWMColormapWindows + *(void **) (&XSetWMColormapWindows_dylibloader_wrapper_xlib) = dlsym(handle, "XSetWMColormapWindows"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XFreeStringList + *(void **) (&XFreeStringList_dylibloader_wrapper_xlib) = dlsym(handle, "XFreeStringList"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetTransientForHint + *(void **) (&XSetTransientForHint_dylibloader_wrapper_xlib) = dlsym(handle, "XSetTransientForHint"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XActivateScreenSaver + *(void **) (&XActivateScreenSaver_dylibloader_wrapper_xlib) = dlsym(handle, "XActivateScreenSaver"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XAddHost + *(void **) (&XAddHost_dylibloader_wrapper_xlib) = dlsym(handle, "XAddHost"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XAddHosts + *(void **) (&XAddHosts_dylibloader_wrapper_xlib) = dlsym(handle, "XAddHosts"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XAddToExtensionList + *(void **) (&XAddToExtensionList_dylibloader_wrapper_xlib) = dlsym(handle, "XAddToExtensionList"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XAddToSaveSet + *(void **) (&XAddToSaveSet_dylibloader_wrapper_xlib) = dlsym(handle, "XAddToSaveSet"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XAllocColor + *(void **) (&XAllocColor_dylibloader_wrapper_xlib) = dlsym(handle, "XAllocColor"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XAllocColorCells + *(void **) (&XAllocColorCells_dylibloader_wrapper_xlib) = dlsym(handle, "XAllocColorCells"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XAllocColorPlanes + *(void **) (&XAllocColorPlanes_dylibloader_wrapper_xlib) = dlsym(handle, "XAllocColorPlanes"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XAllocNamedColor + *(void **) (&XAllocNamedColor_dylibloader_wrapper_xlib) = dlsym(handle, "XAllocNamedColor"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XAllowEvents + *(void **) (&XAllowEvents_dylibloader_wrapper_xlib) = dlsym(handle, "XAllowEvents"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XAutoRepeatOff + *(void **) (&XAutoRepeatOff_dylibloader_wrapper_xlib) = dlsym(handle, "XAutoRepeatOff"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XAutoRepeatOn + *(void **) (&XAutoRepeatOn_dylibloader_wrapper_xlib) = dlsym(handle, "XAutoRepeatOn"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XBell + *(void **) (&XBell_dylibloader_wrapper_xlib) = dlsym(handle, "XBell"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XBitmapBitOrder + *(void **) (&XBitmapBitOrder_dylibloader_wrapper_xlib) = dlsym(handle, "XBitmapBitOrder"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XBitmapPad + *(void **) (&XBitmapPad_dylibloader_wrapper_xlib) = dlsym(handle, "XBitmapPad"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XBitmapUnit + *(void **) (&XBitmapUnit_dylibloader_wrapper_xlib) = dlsym(handle, "XBitmapUnit"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XCellsOfScreen + *(void **) (&XCellsOfScreen_dylibloader_wrapper_xlib) = dlsym(handle, "XCellsOfScreen"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XChangeActivePointerGrab + *(void **) (&XChangeActivePointerGrab_dylibloader_wrapper_xlib) = dlsym(handle, "XChangeActivePointerGrab"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XChangeGC + *(void **) (&XChangeGC_dylibloader_wrapper_xlib) = dlsym(handle, "XChangeGC"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XChangeKeyboardControl + *(void **) (&XChangeKeyboardControl_dylibloader_wrapper_xlib) = dlsym(handle, "XChangeKeyboardControl"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XChangeKeyboardMapping + *(void **) (&XChangeKeyboardMapping_dylibloader_wrapper_xlib) = dlsym(handle, "XChangeKeyboardMapping"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XChangePointerControl + *(void **) (&XChangePointerControl_dylibloader_wrapper_xlib) = dlsym(handle, "XChangePointerControl"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XChangeProperty + *(void **) (&XChangeProperty_dylibloader_wrapper_xlib) = dlsym(handle, "XChangeProperty"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XChangeSaveSet + *(void **) (&XChangeSaveSet_dylibloader_wrapper_xlib) = dlsym(handle, "XChangeSaveSet"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XChangeWindowAttributes + *(void **) (&XChangeWindowAttributes_dylibloader_wrapper_xlib) = dlsym(handle, "XChangeWindowAttributes"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XCheckIfEvent + *(void **) (&XCheckIfEvent_dylibloader_wrapper_xlib) = dlsym(handle, "XCheckIfEvent"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XCheckMaskEvent + *(void **) (&XCheckMaskEvent_dylibloader_wrapper_xlib) = dlsym(handle, "XCheckMaskEvent"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XCheckTypedEvent + *(void **) (&XCheckTypedEvent_dylibloader_wrapper_xlib) = dlsym(handle, "XCheckTypedEvent"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XCheckTypedWindowEvent + *(void **) (&XCheckTypedWindowEvent_dylibloader_wrapper_xlib) = dlsym(handle, "XCheckTypedWindowEvent"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XCheckWindowEvent + *(void **) (&XCheckWindowEvent_dylibloader_wrapper_xlib) = dlsym(handle, "XCheckWindowEvent"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XCirculateSubwindows + *(void **) (&XCirculateSubwindows_dylibloader_wrapper_xlib) = dlsym(handle, "XCirculateSubwindows"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XCirculateSubwindowsDown + *(void **) (&XCirculateSubwindowsDown_dylibloader_wrapper_xlib) = dlsym(handle, "XCirculateSubwindowsDown"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XCirculateSubwindowsUp + *(void **) (&XCirculateSubwindowsUp_dylibloader_wrapper_xlib) = dlsym(handle, "XCirculateSubwindowsUp"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XClearArea + *(void **) (&XClearArea_dylibloader_wrapper_xlib) = dlsym(handle, "XClearArea"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XClearWindow + *(void **) (&XClearWindow_dylibloader_wrapper_xlib) = dlsym(handle, "XClearWindow"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XCloseDisplay + *(void **) (&XCloseDisplay_dylibloader_wrapper_xlib) = dlsym(handle, "XCloseDisplay"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XConfigureWindow + *(void **) (&XConfigureWindow_dylibloader_wrapper_xlib) = dlsym(handle, "XConfigureWindow"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XConnectionNumber + *(void **) (&XConnectionNumber_dylibloader_wrapper_xlib) = dlsym(handle, "XConnectionNumber"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XConvertSelection + *(void **) (&XConvertSelection_dylibloader_wrapper_xlib) = dlsym(handle, "XConvertSelection"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XCopyArea + *(void **) (&XCopyArea_dylibloader_wrapper_xlib) = dlsym(handle, "XCopyArea"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XCopyGC + *(void **) (&XCopyGC_dylibloader_wrapper_xlib) = dlsym(handle, "XCopyGC"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XCopyPlane + *(void **) (&XCopyPlane_dylibloader_wrapper_xlib) = dlsym(handle, "XCopyPlane"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDefaultDepth + *(void **) (&XDefaultDepth_dylibloader_wrapper_xlib) = dlsym(handle, "XDefaultDepth"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDefaultDepthOfScreen + *(void **) (&XDefaultDepthOfScreen_dylibloader_wrapper_xlib) = dlsym(handle, "XDefaultDepthOfScreen"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDefaultScreen + *(void **) (&XDefaultScreen_dylibloader_wrapper_xlib) = dlsym(handle, "XDefaultScreen"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDefineCursor + *(void **) (&XDefineCursor_dylibloader_wrapper_xlib) = dlsym(handle, "XDefineCursor"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDeleteProperty + *(void **) (&XDeleteProperty_dylibloader_wrapper_xlib) = dlsym(handle, "XDeleteProperty"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDestroyWindow + *(void **) (&XDestroyWindow_dylibloader_wrapper_xlib) = dlsym(handle, "XDestroyWindow"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDestroySubwindows + *(void **) (&XDestroySubwindows_dylibloader_wrapper_xlib) = dlsym(handle, "XDestroySubwindows"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDoesBackingStore + *(void **) (&XDoesBackingStore_dylibloader_wrapper_xlib) = dlsym(handle, "XDoesBackingStore"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDoesSaveUnders + *(void **) (&XDoesSaveUnders_dylibloader_wrapper_xlib) = dlsym(handle, "XDoesSaveUnders"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDisableAccessControl + *(void **) (&XDisableAccessControl_dylibloader_wrapper_xlib) = dlsym(handle, "XDisableAccessControl"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDisplayCells + *(void **) (&XDisplayCells_dylibloader_wrapper_xlib) = dlsym(handle, "XDisplayCells"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDisplayHeight + *(void **) (&XDisplayHeight_dylibloader_wrapper_xlib) = dlsym(handle, "XDisplayHeight"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDisplayHeightMM + *(void **) (&XDisplayHeightMM_dylibloader_wrapper_xlib) = dlsym(handle, "XDisplayHeightMM"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDisplayKeycodes + *(void **) (&XDisplayKeycodes_dylibloader_wrapper_xlib) = dlsym(handle, "XDisplayKeycodes"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDisplayPlanes + *(void **) (&XDisplayPlanes_dylibloader_wrapper_xlib) = dlsym(handle, "XDisplayPlanes"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDisplayWidth + *(void **) (&XDisplayWidth_dylibloader_wrapper_xlib) = dlsym(handle, "XDisplayWidth"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDisplayWidthMM + *(void **) (&XDisplayWidthMM_dylibloader_wrapper_xlib) = dlsym(handle, "XDisplayWidthMM"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDrawArc + *(void **) (&XDrawArc_dylibloader_wrapper_xlib) = dlsym(handle, "XDrawArc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDrawArcs + *(void **) (&XDrawArcs_dylibloader_wrapper_xlib) = dlsym(handle, "XDrawArcs"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDrawImageString + *(void **) (&XDrawImageString_dylibloader_wrapper_xlib) = dlsym(handle, "XDrawImageString"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDrawImageString16 + *(void **) (&XDrawImageString16_dylibloader_wrapper_xlib) = dlsym(handle, "XDrawImageString16"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDrawLine + *(void **) (&XDrawLine_dylibloader_wrapper_xlib) = dlsym(handle, "XDrawLine"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDrawLines + *(void **) (&XDrawLines_dylibloader_wrapper_xlib) = dlsym(handle, "XDrawLines"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDrawPoint + *(void **) (&XDrawPoint_dylibloader_wrapper_xlib) = dlsym(handle, "XDrawPoint"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDrawPoints + *(void **) (&XDrawPoints_dylibloader_wrapper_xlib) = dlsym(handle, "XDrawPoints"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDrawRectangle + *(void **) (&XDrawRectangle_dylibloader_wrapper_xlib) = dlsym(handle, "XDrawRectangle"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDrawRectangles + *(void **) (&XDrawRectangles_dylibloader_wrapper_xlib) = dlsym(handle, "XDrawRectangles"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDrawSegments + *(void **) (&XDrawSegments_dylibloader_wrapper_xlib) = dlsym(handle, "XDrawSegments"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDrawString + *(void **) (&XDrawString_dylibloader_wrapper_xlib) = dlsym(handle, "XDrawString"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDrawString16 + *(void **) (&XDrawString16_dylibloader_wrapper_xlib) = dlsym(handle, "XDrawString16"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDrawText + *(void **) (&XDrawText_dylibloader_wrapper_xlib) = dlsym(handle, "XDrawText"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDrawText16 + *(void **) (&XDrawText16_dylibloader_wrapper_xlib) = dlsym(handle, "XDrawText16"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XEnableAccessControl + *(void **) (&XEnableAccessControl_dylibloader_wrapper_xlib) = dlsym(handle, "XEnableAccessControl"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XEventsQueued + *(void **) (&XEventsQueued_dylibloader_wrapper_xlib) = dlsym(handle, "XEventsQueued"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XFetchName + *(void **) (&XFetchName_dylibloader_wrapper_xlib) = dlsym(handle, "XFetchName"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XFillArc + *(void **) (&XFillArc_dylibloader_wrapper_xlib) = dlsym(handle, "XFillArc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XFillArcs + *(void **) (&XFillArcs_dylibloader_wrapper_xlib) = dlsym(handle, "XFillArcs"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XFillPolygon + *(void **) (&XFillPolygon_dylibloader_wrapper_xlib) = dlsym(handle, "XFillPolygon"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XFillRectangle + *(void **) (&XFillRectangle_dylibloader_wrapper_xlib) = dlsym(handle, "XFillRectangle"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XFillRectangles + *(void **) (&XFillRectangles_dylibloader_wrapper_xlib) = dlsym(handle, "XFillRectangles"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XFlush + *(void **) (&XFlush_dylibloader_wrapper_xlib) = dlsym(handle, "XFlush"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XForceScreenSaver + *(void **) (&XForceScreenSaver_dylibloader_wrapper_xlib) = dlsym(handle, "XForceScreenSaver"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XFree + *(void **) (&XFree_dylibloader_wrapper_xlib) = dlsym(handle, "XFree"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XFreeColormap + *(void **) (&XFreeColormap_dylibloader_wrapper_xlib) = dlsym(handle, "XFreeColormap"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XFreeColors + *(void **) (&XFreeColors_dylibloader_wrapper_xlib) = dlsym(handle, "XFreeColors"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XFreeCursor + *(void **) (&XFreeCursor_dylibloader_wrapper_xlib) = dlsym(handle, "XFreeCursor"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XFreeExtensionList + *(void **) (&XFreeExtensionList_dylibloader_wrapper_xlib) = dlsym(handle, "XFreeExtensionList"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XFreeFont + *(void **) (&XFreeFont_dylibloader_wrapper_xlib) = dlsym(handle, "XFreeFont"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XFreeFontInfo + *(void **) (&XFreeFontInfo_dylibloader_wrapper_xlib) = dlsym(handle, "XFreeFontInfo"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XFreeFontNames + *(void **) (&XFreeFontNames_dylibloader_wrapper_xlib) = dlsym(handle, "XFreeFontNames"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XFreeFontPath + *(void **) (&XFreeFontPath_dylibloader_wrapper_xlib) = dlsym(handle, "XFreeFontPath"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XFreeGC + *(void **) (&XFreeGC_dylibloader_wrapper_xlib) = dlsym(handle, "XFreeGC"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XFreeModifiermap + *(void **) (&XFreeModifiermap_dylibloader_wrapper_xlib) = dlsym(handle, "XFreeModifiermap"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XFreePixmap + *(void **) (&XFreePixmap_dylibloader_wrapper_xlib) = dlsym(handle, "XFreePixmap"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGeometry + *(void **) (&XGeometry_dylibloader_wrapper_xlib) = dlsym(handle, "XGeometry"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetErrorDatabaseText + *(void **) (&XGetErrorDatabaseText_dylibloader_wrapper_xlib) = dlsym(handle, "XGetErrorDatabaseText"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetErrorText + *(void **) (&XGetErrorText_dylibloader_wrapper_xlib) = dlsym(handle, "XGetErrorText"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetFontProperty + *(void **) (&XGetFontProperty_dylibloader_wrapper_xlib) = dlsym(handle, "XGetFontProperty"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetGCValues + *(void **) (&XGetGCValues_dylibloader_wrapper_xlib) = dlsym(handle, "XGetGCValues"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetGeometry + *(void **) (&XGetGeometry_dylibloader_wrapper_xlib) = dlsym(handle, "XGetGeometry"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetIconName + *(void **) (&XGetIconName_dylibloader_wrapper_xlib) = dlsym(handle, "XGetIconName"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetInputFocus + *(void **) (&XGetInputFocus_dylibloader_wrapper_xlib) = dlsym(handle, "XGetInputFocus"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetKeyboardControl + *(void **) (&XGetKeyboardControl_dylibloader_wrapper_xlib) = dlsym(handle, "XGetKeyboardControl"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetPointerControl + *(void **) (&XGetPointerControl_dylibloader_wrapper_xlib) = dlsym(handle, "XGetPointerControl"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetPointerMapping + *(void **) (&XGetPointerMapping_dylibloader_wrapper_xlib) = dlsym(handle, "XGetPointerMapping"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetScreenSaver + *(void **) (&XGetScreenSaver_dylibloader_wrapper_xlib) = dlsym(handle, "XGetScreenSaver"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetTransientForHint + *(void **) (&XGetTransientForHint_dylibloader_wrapper_xlib) = dlsym(handle, "XGetTransientForHint"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetWindowProperty + *(void **) (&XGetWindowProperty_dylibloader_wrapper_xlib) = dlsym(handle, "XGetWindowProperty"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetWindowAttributes + *(void **) (&XGetWindowAttributes_dylibloader_wrapper_xlib) = dlsym(handle, "XGetWindowAttributes"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGrabButton + *(void **) (&XGrabButton_dylibloader_wrapper_xlib) = dlsym(handle, "XGrabButton"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGrabKey + *(void **) (&XGrabKey_dylibloader_wrapper_xlib) = dlsym(handle, "XGrabKey"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGrabKeyboard + *(void **) (&XGrabKeyboard_dylibloader_wrapper_xlib) = dlsym(handle, "XGrabKeyboard"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGrabPointer + *(void **) (&XGrabPointer_dylibloader_wrapper_xlib) = dlsym(handle, "XGrabPointer"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGrabServer + *(void **) (&XGrabServer_dylibloader_wrapper_xlib) = dlsym(handle, "XGrabServer"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XHeightMMOfScreen + *(void **) (&XHeightMMOfScreen_dylibloader_wrapper_xlib) = dlsym(handle, "XHeightMMOfScreen"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XHeightOfScreen + *(void **) (&XHeightOfScreen_dylibloader_wrapper_xlib) = dlsym(handle, "XHeightOfScreen"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XIfEvent + *(void **) (&XIfEvent_dylibloader_wrapper_xlib) = dlsym(handle, "XIfEvent"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XImageByteOrder + *(void **) (&XImageByteOrder_dylibloader_wrapper_xlib) = dlsym(handle, "XImageByteOrder"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XInstallColormap + *(void **) (&XInstallColormap_dylibloader_wrapper_xlib) = dlsym(handle, "XInstallColormap"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XKeysymToKeycode + *(void **) (&XKeysymToKeycode_dylibloader_wrapper_xlib) = dlsym(handle, "XKeysymToKeycode"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XKillClient + *(void **) (&XKillClient_dylibloader_wrapper_xlib) = dlsym(handle, "XKillClient"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XLookupColor + *(void **) (&XLookupColor_dylibloader_wrapper_xlib) = dlsym(handle, "XLookupColor"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XLowerWindow + *(void **) (&XLowerWindow_dylibloader_wrapper_xlib) = dlsym(handle, "XLowerWindow"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XMapRaised + *(void **) (&XMapRaised_dylibloader_wrapper_xlib) = dlsym(handle, "XMapRaised"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XMapSubwindows + *(void **) (&XMapSubwindows_dylibloader_wrapper_xlib) = dlsym(handle, "XMapSubwindows"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XMapWindow + *(void **) (&XMapWindow_dylibloader_wrapper_xlib) = dlsym(handle, "XMapWindow"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XMaskEvent + *(void **) (&XMaskEvent_dylibloader_wrapper_xlib) = dlsym(handle, "XMaskEvent"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XMaxCmapsOfScreen + *(void **) (&XMaxCmapsOfScreen_dylibloader_wrapper_xlib) = dlsym(handle, "XMaxCmapsOfScreen"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XMinCmapsOfScreen + *(void **) (&XMinCmapsOfScreen_dylibloader_wrapper_xlib) = dlsym(handle, "XMinCmapsOfScreen"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XMoveResizeWindow + *(void **) (&XMoveResizeWindow_dylibloader_wrapper_xlib) = dlsym(handle, "XMoveResizeWindow"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XMoveWindow + *(void **) (&XMoveWindow_dylibloader_wrapper_xlib) = dlsym(handle, "XMoveWindow"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XNextEvent + *(void **) (&XNextEvent_dylibloader_wrapper_xlib) = dlsym(handle, "XNextEvent"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XNoOp + *(void **) (&XNoOp_dylibloader_wrapper_xlib) = dlsym(handle, "XNoOp"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XParseColor + *(void **) (&XParseColor_dylibloader_wrapper_xlib) = dlsym(handle, "XParseColor"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XParseGeometry + *(void **) (&XParseGeometry_dylibloader_wrapper_xlib) = dlsym(handle, "XParseGeometry"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XPeekEvent + *(void **) (&XPeekEvent_dylibloader_wrapper_xlib) = dlsym(handle, "XPeekEvent"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XPeekIfEvent + *(void **) (&XPeekIfEvent_dylibloader_wrapper_xlib) = dlsym(handle, "XPeekIfEvent"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XPending + *(void **) (&XPending_dylibloader_wrapper_xlib) = dlsym(handle, "XPending"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XPlanesOfScreen + *(void **) (&XPlanesOfScreen_dylibloader_wrapper_xlib) = dlsym(handle, "XPlanesOfScreen"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XProtocolRevision + *(void **) (&XProtocolRevision_dylibloader_wrapper_xlib) = dlsym(handle, "XProtocolRevision"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XProtocolVersion + *(void **) (&XProtocolVersion_dylibloader_wrapper_xlib) = dlsym(handle, "XProtocolVersion"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XPutBackEvent + *(void **) (&XPutBackEvent_dylibloader_wrapper_xlib) = dlsym(handle, "XPutBackEvent"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XPutImage + *(void **) (&XPutImage_dylibloader_wrapper_xlib) = dlsym(handle, "XPutImage"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XQLength + *(void **) (&XQLength_dylibloader_wrapper_xlib) = dlsym(handle, "XQLength"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XQueryBestCursor + *(void **) (&XQueryBestCursor_dylibloader_wrapper_xlib) = dlsym(handle, "XQueryBestCursor"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XQueryBestSize + *(void **) (&XQueryBestSize_dylibloader_wrapper_xlib) = dlsym(handle, "XQueryBestSize"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XQueryBestStipple + *(void **) (&XQueryBestStipple_dylibloader_wrapper_xlib) = dlsym(handle, "XQueryBestStipple"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XQueryBestTile + *(void **) (&XQueryBestTile_dylibloader_wrapper_xlib) = dlsym(handle, "XQueryBestTile"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XQueryColor + *(void **) (&XQueryColor_dylibloader_wrapper_xlib) = dlsym(handle, "XQueryColor"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XQueryColors + *(void **) (&XQueryColors_dylibloader_wrapper_xlib) = dlsym(handle, "XQueryColors"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XQueryExtension + *(void **) (&XQueryExtension_dylibloader_wrapper_xlib) = dlsym(handle, "XQueryExtension"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XQueryKeymap + *(void **) (&XQueryKeymap_dylibloader_wrapper_xlib) = dlsym(handle, "XQueryKeymap"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XQueryPointer + *(void **) (&XQueryPointer_dylibloader_wrapper_xlib) = dlsym(handle, "XQueryPointer"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XQueryTextExtents + *(void **) (&XQueryTextExtents_dylibloader_wrapper_xlib) = dlsym(handle, "XQueryTextExtents"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XQueryTextExtents16 + *(void **) (&XQueryTextExtents16_dylibloader_wrapper_xlib) = dlsym(handle, "XQueryTextExtents16"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XQueryTree + *(void **) (&XQueryTree_dylibloader_wrapper_xlib) = dlsym(handle, "XQueryTree"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRaiseWindow + *(void **) (&XRaiseWindow_dylibloader_wrapper_xlib) = dlsym(handle, "XRaiseWindow"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XReadBitmapFile + *(void **) (&XReadBitmapFile_dylibloader_wrapper_xlib) = dlsym(handle, "XReadBitmapFile"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XReadBitmapFileData + *(void **) (&XReadBitmapFileData_dylibloader_wrapper_xlib) = dlsym(handle, "XReadBitmapFileData"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRebindKeysym + *(void **) (&XRebindKeysym_dylibloader_wrapper_xlib) = dlsym(handle, "XRebindKeysym"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRecolorCursor + *(void **) (&XRecolorCursor_dylibloader_wrapper_xlib) = dlsym(handle, "XRecolorCursor"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRefreshKeyboardMapping + *(void **) (&XRefreshKeyboardMapping_dylibloader_wrapper_xlib) = dlsym(handle, "XRefreshKeyboardMapping"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRemoveFromSaveSet + *(void **) (&XRemoveFromSaveSet_dylibloader_wrapper_xlib) = dlsym(handle, "XRemoveFromSaveSet"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRemoveHost + *(void **) (&XRemoveHost_dylibloader_wrapper_xlib) = dlsym(handle, "XRemoveHost"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRemoveHosts + *(void **) (&XRemoveHosts_dylibloader_wrapper_xlib) = dlsym(handle, "XRemoveHosts"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XReparentWindow + *(void **) (&XReparentWindow_dylibloader_wrapper_xlib) = dlsym(handle, "XReparentWindow"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XResetScreenSaver + *(void **) (&XResetScreenSaver_dylibloader_wrapper_xlib) = dlsym(handle, "XResetScreenSaver"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XResizeWindow + *(void **) (&XResizeWindow_dylibloader_wrapper_xlib) = dlsym(handle, "XResizeWindow"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRestackWindows + *(void **) (&XRestackWindows_dylibloader_wrapper_xlib) = dlsym(handle, "XRestackWindows"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRotateBuffers + *(void **) (&XRotateBuffers_dylibloader_wrapper_xlib) = dlsym(handle, "XRotateBuffers"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRotateWindowProperties + *(void **) (&XRotateWindowProperties_dylibloader_wrapper_xlib) = dlsym(handle, "XRotateWindowProperties"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XScreenCount + *(void **) (&XScreenCount_dylibloader_wrapper_xlib) = dlsym(handle, "XScreenCount"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSelectInput + *(void **) (&XSelectInput_dylibloader_wrapper_xlib) = dlsym(handle, "XSelectInput"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSendEvent + *(void **) (&XSendEvent_dylibloader_wrapper_xlib) = dlsym(handle, "XSendEvent"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetAccessControl + *(void **) (&XSetAccessControl_dylibloader_wrapper_xlib) = dlsym(handle, "XSetAccessControl"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetArcMode + *(void **) (&XSetArcMode_dylibloader_wrapper_xlib) = dlsym(handle, "XSetArcMode"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetBackground + *(void **) (&XSetBackground_dylibloader_wrapper_xlib) = dlsym(handle, "XSetBackground"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetClipMask + *(void **) (&XSetClipMask_dylibloader_wrapper_xlib) = dlsym(handle, "XSetClipMask"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetClipOrigin + *(void **) (&XSetClipOrigin_dylibloader_wrapper_xlib) = dlsym(handle, "XSetClipOrigin"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetClipRectangles + *(void **) (&XSetClipRectangles_dylibloader_wrapper_xlib) = dlsym(handle, "XSetClipRectangles"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetCloseDownMode + *(void **) (&XSetCloseDownMode_dylibloader_wrapper_xlib) = dlsym(handle, "XSetCloseDownMode"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetCommand + *(void **) (&XSetCommand_dylibloader_wrapper_xlib) = dlsym(handle, "XSetCommand"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetDashes + *(void **) (&XSetDashes_dylibloader_wrapper_xlib) = dlsym(handle, "XSetDashes"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetFillRule + *(void **) (&XSetFillRule_dylibloader_wrapper_xlib) = dlsym(handle, "XSetFillRule"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetFillStyle + *(void **) (&XSetFillStyle_dylibloader_wrapper_xlib) = dlsym(handle, "XSetFillStyle"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetFont + *(void **) (&XSetFont_dylibloader_wrapper_xlib) = dlsym(handle, "XSetFont"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetFontPath + *(void **) (&XSetFontPath_dylibloader_wrapper_xlib) = dlsym(handle, "XSetFontPath"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetForeground + *(void **) (&XSetForeground_dylibloader_wrapper_xlib) = dlsym(handle, "XSetForeground"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetFunction + *(void **) (&XSetFunction_dylibloader_wrapper_xlib) = dlsym(handle, "XSetFunction"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetGraphicsExposures + *(void **) (&XSetGraphicsExposures_dylibloader_wrapper_xlib) = dlsym(handle, "XSetGraphicsExposures"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetIconName + *(void **) (&XSetIconName_dylibloader_wrapper_xlib) = dlsym(handle, "XSetIconName"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetInputFocus + *(void **) (&XSetInputFocus_dylibloader_wrapper_xlib) = dlsym(handle, "XSetInputFocus"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetLineAttributes + *(void **) (&XSetLineAttributes_dylibloader_wrapper_xlib) = dlsym(handle, "XSetLineAttributes"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetModifierMapping + *(void **) (&XSetModifierMapping_dylibloader_wrapper_xlib) = dlsym(handle, "XSetModifierMapping"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetPlaneMask + *(void **) (&XSetPlaneMask_dylibloader_wrapper_xlib) = dlsym(handle, "XSetPlaneMask"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetPointerMapping + *(void **) (&XSetPointerMapping_dylibloader_wrapper_xlib) = dlsym(handle, "XSetPointerMapping"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetScreenSaver + *(void **) (&XSetScreenSaver_dylibloader_wrapper_xlib) = dlsym(handle, "XSetScreenSaver"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetSelectionOwner + *(void **) (&XSetSelectionOwner_dylibloader_wrapper_xlib) = dlsym(handle, "XSetSelectionOwner"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetState + *(void **) (&XSetState_dylibloader_wrapper_xlib) = dlsym(handle, "XSetState"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetStipple + *(void **) (&XSetStipple_dylibloader_wrapper_xlib) = dlsym(handle, "XSetStipple"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetSubwindowMode + *(void **) (&XSetSubwindowMode_dylibloader_wrapper_xlib) = dlsym(handle, "XSetSubwindowMode"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetTSOrigin + *(void **) (&XSetTSOrigin_dylibloader_wrapper_xlib) = dlsym(handle, "XSetTSOrigin"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetTile + *(void **) (&XSetTile_dylibloader_wrapper_xlib) = dlsym(handle, "XSetTile"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetWindowBackground + *(void **) (&XSetWindowBackground_dylibloader_wrapper_xlib) = dlsym(handle, "XSetWindowBackground"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetWindowBackgroundPixmap + *(void **) (&XSetWindowBackgroundPixmap_dylibloader_wrapper_xlib) = dlsym(handle, "XSetWindowBackgroundPixmap"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetWindowBorder + *(void **) (&XSetWindowBorder_dylibloader_wrapper_xlib) = dlsym(handle, "XSetWindowBorder"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetWindowBorderPixmap + *(void **) (&XSetWindowBorderPixmap_dylibloader_wrapper_xlib) = dlsym(handle, "XSetWindowBorderPixmap"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetWindowBorderWidth + *(void **) (&XSetWindowBorderWidth_dylibloader_wrapper_xlib) = dlsym(handle, "XSetWindowBorderWidth"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetWindowColormap + *(void **) (&XSetWindowColormap_dylibloader_wrapper_xlib) = dlsym(handle, "XSetWindowColormap"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XStoreBuffer + *(void **) (&XStoreBuffer_dylibloader_wrapper_xlib) = dlsym(handle, "XStoreBuffer"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XStoreBytes + *(void **) (&XStoreBytes_dylibloader_wrapper_xlib) = dlsym(handle, "XStoreBytes"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XStoreColor + *(void **) (&XStoreColor_dylibloader_wrapper_xlib) = dlsym(handle, "XStoreColor"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XStoreColors + *(void **) (&XStoreColors_dylibloader_wrapper_xlib) = dlsym(handle, "XStoreColors"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XStoreName + *(void **) (&XStoreName_dylibloader_wrapper_xlib) = dlsym(handle, "XStoreName"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XStoreNamedColor + *(void **) (&XStoreNamedColor_dylibloader_wrapper_xlib) = dlsym(handle, "XStoreNamedColor"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSync + *(void **) (&XSync_dylibloader_wrapper_xlib) = dlsym(handle, "XSync"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XTextExtents + *(void **) (&XTextExtents_dylibloader_wrapper_xlib) = dlsym(handle, "XTextExtents"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XTextExtents16 + *(void **) (&XTextExtents16_dylibloader_wrapper_xlib) = dlsym(handle, "XTextExtents16"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XTextWidth + *(void **) (&XTextWidth_dylibloader_wrapper_xlib) = dlsym(handle, "XTextWidth"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XTextWidth16 + *(void **) (&XTextWidth16_dylibloader_wrapper_xlib) = dlsym(handle, "XTextWidth16"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XTranslateCoordinates + *(void **) (&XTranslateCoordinates_dylibloader_wrapper_xlib) = dlsym(handle, "XTranslateCoordinates"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XUndefineCursor + *(void **) (&XUndefineCursor_dylibloader_wrapper_xlib) = dlsym(handle, "XUndefineCursor"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XUngrabButton + *(void **) (&XUngrabButton_dylibloader_wrapper_xlib) = dlsym(handle, "XUngrabButton"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XUngrabKey + *(void **) (&XUngrabKey_dylibloader_wrapper_xlib) = dlsym(handle, "XUngrabKey"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XUngrabKeyboard + *(void **) (&XUngrabKeyboard_dylibloader_wrapper_xlib) = dlsym(handle, "XUngrabKeyboard"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XUngrabPointer + *(void **) (&XUngrabPointer_dylibloader_wrapper_xlib) = dlsym(handle, "XUngrabPointer"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XUngrabServer + *(void **) (&XUngrabServer_dylibloader_wrapper_xlib) = dlsym(handle, "XUngrabServer"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XUninstallColormap + *(void **) (&XUninstallColormap_dylibloader_wrapper_xlib) = dlsym(handle, "XUninstallColormap"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XUnloadFont + *(void **) (&XUnloadFont_dylibloader_wrapper_xlib) = dlsym(handle, "XUnloadFont"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XUnmapSubwindows + *(void **) (&XUnmapSubwindows_dylibloader_wrapper_xlib) = dlsym(handle, "XUnmapSubwindows"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XUnmapWindow + *(void **) (&XUnmapWindow_dylibloader_wrapper_xlib) = dlsym(handle, "XUnmapWindow"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XVendorRelease + *(void **) (&XVendorRelease_dylibloader_wrapper_xlib) = dlsym(handle, "XVendorRelease"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XWarpPointer + *(void **) (&XWarpPointer_dylibloader_wrapper_xlib) = dlsym(handle, "XWarpPointer"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XWidthMMOfScreen + *(void **) (&XWidthMMOfScreen_dylibloader_wrapper_xlib) = dlsym(handle, "XWidthMMOfScreen"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XWidthOfScreen + *(void **) (&XWidthOfScreen_dylibloader_wrapper_xlib) = dlsym(handle, "XWidthOfScreen"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XWindowEvent + *(void **) (&XWindowEvent_dylibloader_wrapper_xlib) = dlsym(handle, "XWindowEvent"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XWriteBitmapFile + *(void **) (&XWriteBitmapFile_dylibloader_wrapper_xlib) = dlsym(handle, "XWriteBitmapFile"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSupportsLocale + *(void **) (&XSupportsLocale_dylibloader_wrapper_xlib) = dlsym(handle, "XSupportsLocale"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetLocaleModifiers + *(void **) (&XSetLocaleModifiers_dylibloader_wrapper_xlib) = dlsym(handle, "XSetLocaleModifiers"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XOpenOM + *(void **) (&XOpenOM_dylibloader_wrapper_xlib) = dlsym(handle, "XOpenOM"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XCloseOM + *(void **) (&XCloseOM_dylibloader_wrapper_xlib) = dlsym(handle, "XCloseOM"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetOMValues + *(void **) (&XSetOMValues_dylibloader_wrapper_xlib) = dlsym(handle, "XSetOMValues"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetOMValues + *(void **) (&XGetOMValues_dylibloader_wrapper_xlib) = dlsym(handle, "XGetOMValues"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDisplayOfOM + *(void **) (&XDisplayOfOM_dylibloader_wrapper_xlib) = dlsym(handle, "XDisplayOfOM"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XLocaleOfOM + *(void **) (&XLocaleOfOM_dylibloader_wrapper_xlib) = dlsym(handle, "XLocaleOfOM"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XCreateOC + *(void **) (&XCreateOC_dylibloader_wrapper_xlib) = dlsym(handle, "XCreateOC"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDestroyOC + *(void **) (&XDestroyOC_dylibloader_wrapper_xlib) = dlsym(handle, "XDestroyOC"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XOMOfOC + *(void **) (&XOMOfOC_dylibloader_wrapper_xlib) = dlsym(handle, "XOMOfOC"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetOCValues + *(void **) (&XSetOCValues_dylibloader_wrapper_xlib) = dlsym(handle, "XSetOCValues"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetOCValues + *(void **) (&XGetOCValues_dylibloader_wrapper_xlib) = dlsym(handle, "XGetOCValues"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XCreateFontSet + *(void **) (&XCreateFontSet_dylibloader_wrapper_xlib) = dlsym(handle, "XCreateFontSet"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XFreeFontSet + *(void **) (&XFreeFontSet_dylibloader_wrapper_xlib) = dlsym(handle, "XFreeFontSet"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XFontsOfFontSet + *(void **) (&XFontsOfFontSet_dylibloader_wrapper_xlib) = dlsym(handle, "XFontsOfFontSet"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XBaseFontNameListOfFontSet + *(void **) (&XBaseFontNameListOfFontSet_dylibloader_wrapper_xlib) = dlsym(handle, "XBaseFontNameListOfFontSet"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XLocaleOfFontSet + *(void **) (&XLocaleOfFontSet_dylibloader_wrapper_xlib) = dlsym(handle, "XLocaleOfFontSet"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XContextDependentDrawing + *(void **) (&XContextDependentDrawing_dylibloader_wrapper_xlib) = dlsym(handle, "XContextDependentDrawing"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDirectionalDependentDrawing + *(void **) (&XDirectionalDependentDrawing_dylibloader_wrapper_xlib) = dlsym(handle, "XDirectionalDependentDrawing"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XContextualDrawing + *(void **) (&XContextualDrawing_dylibloader_wrapper_xlib) = dlsym(handle, "XContextualDrawing"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XExtentsOfFontSet + *(void **) (&XExtentsOfFontSet_dylibloader_wrapper_xlib) = dlsym(handle, "XExtentsOfFontSet"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XmbTextEscapement + *(void **) (&XmbTextEscapement_dylibloader_wrapper_xlib) = dlsym(handle, "XmbTextEscapement"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XwcTextEscapement + *(void **) (&XwcTextEscapement_dylibloader_wrapper_xlib) = dlsym(handle, "XwcTextEscapement"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// Xutf8TextEscapement + *(void **) (&Xutf8TextEscapement_dylibloader_wrapper_xlib) = dlsym(handle, "Xutf8TextEscapement"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XmbTextExtents + *(void **) (&XmbTextExtents_dylibloader_wrapper_xlib) = dlsym(handle, "XmbTextExtents"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XwcTextExtents + *(void **) (&XwcTextExtents_dylibloader_wrapper_xlib) = dlsym(handle, "XwcTextExtents"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// Xutf8TextExtents + *(void **) (&Xutf8TextExtents_dylibloader_wrapper_xlib) = dlsym(handle, "Xutf8TextExtents"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XmbTextPerCharExtents + *(void **) (&XmbTextPerCharExtents_dylibloader_wrapper_xlib) = dlsym(handle, "XmbTextPerCharExtents"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XwcTextPerCharExtents + *(void **) (&XwcTextPerCharExtents_dylibloader_wrapper_xlib) = dlsym(handle, "XwcTextPerCharExtents"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// Xutf8TextPerCharExtents + *(void **) (&Xutf8TextPerCharExtents_dylibloader_wrapper_xlib) = dlsym(handle, "Xutf8TextPerCharExtents"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XmbDrawText + *(void **) (&XmbDrawText_dylibloader_wrapper_xlib) = dlsym(handle, "XmbDrawText"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XwcDrawText + *(void **) (&XwcDrawText_dylibloader_wrapper_xlib) = dlsym(handle, "XwcDrawText"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// Xutf8DrawText + *(void **) (&Xutf8DrawText_dylibloader_wrapper_xlib) = dlsym(handle, "Xutf8DrawText"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XmbDrawString + *(void **) (&XmbDrawString_dylibloader_wrapper_xlib) = dlsym(handle, "XmbDrawString"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XwcDrawString + *(void **) (&XwcDrawString_dylibloader_wrapper_xlib) = dlsym(handle, "XwcDrawString"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// Xutf8DrawString + *(void **) (&Xutf8DrawString_dylibloader_wrapper_xlib) = dlsym(handle, "Xutf8DrawString"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XmbDrawImageString + *(void **) (&XmbDrawImageString_dylibloader_wrapper_xlib) = dlsym(handle, "XmbDrawImageString"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XwcDrawImageString + *(void **) (&XwcDrawImageString_dylibloader_wrapper_xlib) = dlsym(handle, "XwcDrawImageString"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// Xutf8DrawImageString + *(void **) (&Xutf8DrawImageString_dylibloader_wrapper_xlib) = dlsym(handle, "Xutf8DrawImageString"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XOpenIM + *(void **) (&XOpenIM_dylibloader_wrapper_xlib) = dlsym(handle, "XOpenIM"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XCloseIM + *(void **) (&XCloseIM_dylibloader_wrapper_xlib) = dlsym(handle, "XCloseIM"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetIMValues + *(void **) (&XGetIMValues_dylibloader_wrapper_xlib) = dlsym(handle, "XGetIMValues"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetIMValues + *(void **) (&XSetIMValues_dylibloader_wrapper_xlib) = dlsym(handle, "XSetIMValues"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDisplayOfIM + *(void **) (&XDisplayOfIM_dylibloader_wrapper_xlib) = dlsym(handle, "XDisplayOfIM"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XLocaleOfIM + *(void **) (&XLocaleOfIM_dylibloader_wrapper_xlib) = dlsym(handle, "XLocaleOfIM"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XCreateIC + *(void **) (&XCreateIC_dylibloader_wrapper_xlib) = dlsym(handle, "XCreateIC"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDestroyIC + *(void **) (&XDestroyIC_dylibloader_wrapper_xlib) = dlsym(handle, "XDestroyIC"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetICFocus + *(void **) (&XSetICFocus_dylibloader_wrapper_xlib) = dlsym(handle, "XSetICFocus"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XUnsetICFocus + *(void **) (&XUnsetICFocus_dylibloader_wrapper_xlib) = dlsym(handle, "XUnsetICFocus"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XwcResetIC + *(void **) (&XwcResetIC_dylibloader_wrapper_xlib) = dlsym(handle, "XwcResetIC"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XmbResetIC + *(void **) (&XmbResetIC_dylibloader_wrapper_xlib) = dlsym(handle, "XmbResetIC"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// Xutf8ResetIC + *(void **) (&Xutf8ResetIC_dylibloader_wrapper_xlib) = dlsym(handle, "Xutf8ResetIC"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetICValues + *(void **) (&XSetICValues_dylibloader_wrapper_xlib) = dlsym(handle, "XSetICValues"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetICValues + *(void **) (&XGetICValues_dylibloader_wrapper_xlib) = dlsym(handle, "XGetICValues"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XIMOfIC + *(void **) (&XIMOfIC_dylibloader_wrapper_xlib) = dlsym(handle, "XIMOfIC"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XFilterEvent + *(void **) (&XFilterEvent_dylibloader_wrapper_xlib) = dlsym(handle, "XFilterEvent"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XmbLookupString + *(void **) (&XmbLookupString_dylibloader_wrapper_xlib) = dlsym(handle, "XmbLookupString"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XwcLookupString + *(void **) (&XwcLookupString_dylibloader_wrapper_xlib) = dlsym(handle, "XwcLookupString"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// Xutf8LookupString + *(void **) (&Xutf8LookupString_dylibloader_wrapper_xlib) = dlsym(handle, "Xutf8LookupString"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XVaCreateNestedList + *(void **) (&XVaCreateNestedList_dylibloader_wrapper_xlib) = dlsym(handle, "XVaCreateNestedList"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRegisterIMInstantiateCallback + *(void **) (&XRegisterIMInstantiateCallback_dylibloader_wrapper_xlib) = dlsym(handle, "XRegisterIMInstantiateCallback"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XUnregisterIMInstantiateCallback + *(void **) (&XUnregisterIMInstantiateCallback_dylibloader_wrapper_xlib) = dlsym(handle, "XUnregisterIMInstantiateCallback"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XInternalConnectionNumbers + *(void **) (&XInternalConnectionNumbers_dylibloader_wrapper_xlib) = dlsym(handle, "XInternalConnectionNumbers"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XProcessInternalConnection + *(void **) (&XProcessInternalConnection_dylibloader_wrapper_xlib) = dlsym(handle, "XProcessInternalConnection"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XAddConnectionWatch + *(void **) (&XAddConnectionWatch_dylibloader_wrapper_xlib) = dlsym(handle, "XAddConnectionWatch"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRemoveConnectionWatch + *(void **) (&XRemoveConnectionWatch_dylibloader_wrapper_xlib) = dlsym(handle, "XRemoveConnectionWatch"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetAuthorization + *(void **) (&XSetAuthorization_dylibloader_wrapper_xlib) = dlsym(handle, "XSetAuthorization"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// _Xmbtowc + *(void **) (&_Xmbtowc_dylibloader_wrapper_xlib) = dlsym(handle, "_Xmbtowc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// _Xwctomb + *(void **) (&_Xwctomb_dylibloader_wrapper_xlib) = dlsym(handle, "_Xwctomb"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetEventData + *(void **) (&XGetEventData_dylibloader_wrapper_xlib) = dlsym(handle, "XGetEventData"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XFreeEventData + *(void **) (&XFreeEventData_dylibloader_wrapper_xlib) = dlsym(handle, "XFreeEventData"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XAllocClassHint + *(void **) (&XAllocClassHint_dylibloader_wrapper_xlib) = dlsym(handle, "XAllocClassHint"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XAllocIconSize + *(void **) (&XAllocIconSize_dylibloader_wrapper_xlib) = dlsym(handle, "XAllocIconSize"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XAllocSizeHints + *(void **) (&XAllocSizeHints_dylibloader_wrapper_xlib) = dlsym(handle, "XAllocSizeHints"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XAllocStandardColormap + *(void **) (&XAllocStandardColormap_dylibloader_wrapper_xlib) = dlsym(handle, "XAllocStandardColormap"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XAllocWMHints + *(void **) (&XAllocWMHints_dylibloader_wrapper_xlib) = dlsym(handle, "XAllocWMHints"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XClipBox + *(void **) (&XClipBox_dylibloader_wrapper_xlib) = dlsym(handle, "XClipBox"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XCreateRegion + *(void **) (&XCreateRegion_dylibloader_wrapper_xlib) = dlsym(handle, "XCreateRegion"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDefaultString + *(void **) (&XDefaultString_dylibloader_wrapper_xlib) = dlsym(handle, "XDefaultString"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDeleteContext + *(void **) (&XDeleteContext_dylibloader_wrapper_xlib) = dlsym(handle, "XDeleteContext"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XDestroyRegion + *(void **) (&XDestroyRegion_dylibloader_wrapper_xlib) = dlsym(handle, "XDestroyRegion"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XEmptyRegion + *(void **) (&XEmptyRegion_dylibloader_wrapper_xlib) = dlsym(handle, "XEmptyRegion"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XEqualRegion + *(void **) (&XEqualRegion_dylibloader_wrapper_xlib) = dlsym(handle, "XEqualRegion"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XFindContext + *(void **) (&XFindContext_dylibloader_wrapper_xlib) = dlsym(handle, "XFindContext"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetClassHint + *(void **) (&XGetClassHint_dylibloader_wrapper_xlib) = dlsym(handle, "XGetClassHint"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetIconSizes + *(void **) (&XGetIconSizes_dylibloader_wrapper_xlib) = dlsym(handle, "XGetIconSizes"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetNormalHints + *(void **) (&XGetNormalHints_dylibloader_wrapper_xlib) = dlsym(handle, "XGetNormalHints"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetRGBColormaps + *(void **) (&XGetRGBColormaps_dylibloader_wrapper_xlib) = dlsym(handle, "XGetRGBColormaps"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetSizeHints + *(void **) (&XGetSizeHints_dylibloader_wrapper_xlib) = dlsym(handle, "XGetSizeHints"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetStandardColormap + *(void **) (&XGetStandardColormap_dylibloader_wrapper_xlib) = dlsym(handle, "XGetStandardColormap"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetTextProperty + *(void **) (&XGetTextProperty_dylibloader_wrapper_xlib) = dlsym(handle, "XGetTextProperty"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetVisualInfo + *(void **) (&XGetVisualInfo_dylibloader_wrapper_xlib) = dlsym(handle, "XGetVisualInfo"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetWMClientMachine + *(void **) (&XGetWMClientMachine_dylibloader_wrapper_xlib) = dlsym(handle, "XGetWMClientMachine"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetWMHints + *(void **) (&XGetWMHints_dylibloader_wrapper_xlib) = dlsym(handle, "XGetWMHints"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetWMIconName + *(void **) (&XGetWMIconName_dylibloader_wrapper_xlib) = dlsym(handle, "XGetWMIconName"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetWMName + *(void **) (&XGetWMName_dylibloader_wrapper_xlib) = dlsym(handle, "XGetWMName"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetWMNormalHints + *(void **) (&XGetWMNormalHints_dylibloader_wrapper_xlib) = dlsym(handle, "XGetWMNormalHints"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetWMSizeHints + *(void **) (&XGetWMSizeHints_dylibloader_wrapper_xlib) = dlsym(handle, "XGetWMSizeHints"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XGetZoomHints + *(void **) (&XGetZoomHints_dylibloader_wrapper_xlib) = dlsym(handle, "XGetZoomHints"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XIntersectRegion + *(void **) (&XIntersectRegion_dylibloader_wrapper_xlib) = dlsym(handle, "XIntersectRegion"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XConvertCase + *(void **) (&XConvertCase_dylibloader_wrapper_xlib) = dlsym(handle, "XConvertCase"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XLookupString + *(void **) (&XLookupString_dylibloader_wrapper_xlib) = dlsym(handle, "XLookupString"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XMatchVisualInfo + *(void **) (&XMatchVisualInfo_dylibloader_wrapper_xlib) = dlsym(handle, "XMatchVisualInfo"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XOffsetRegion + *(void **) (&XOffsetRegion_dylibloader_wrapper_xlib) = dlsym(handle, "XOffsetRegion"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XPointInRegion + *(void **) (&XPointInRegion_dylibloader_wrapper_xlib) = dlsym(handle, "XPointInRegion"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XPolygonRegion + *(void **) (&XPolygonRegion_dylibloader_wrapper_xlib) = dlsym(handle, "XPolygonRegion"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRectInRegion + *(void **) (&XRectInRegion_dylibloader_wrapper_xlib) = dlsym(handle, "XRectInRegion"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSaveContext + *(void **) (&XSaveContext_dylibloader_wrapper_xlib) = dlsym(handle, "XSaveContext"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetClassHint + *(void **) (&XSetClassHint_dylibloader_wrapper_xlib) = dlsym(handle, "XSetClassHint"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetIconSizes + *(void **) (&XSetIconSizes_dylibloader_wrapper_xlib) = dlsym(handle, "XSetIconSizes"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetNormalHints + *(void **) (&XSetNormalHints_dylibloader_wrapper_xlib) = dlsym(handle, "XSetNormalHints"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetRGBColormaps + *(void **) (&XSetRGBColormaps_dylibloader_wrapper_xlib) = dlsym(handle, "XSetRGBColormaps"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetSizeHints + *(void **) (&XSetSizeHints_dylibloader_wrapper_xlib) = dlsym(handle, "XSetSizeHints"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetStandardProperties + *(void **) (&XSetStandardProperties_dylibloader_wrapper_xlib) = dlsym(handle, "XSetStandardProperties"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetTextProperty + *(void **) (&XSetTextProperty_dylibloader_wrapper_xlib) = dlsym(handle, "XSetTextProperty"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetWMClientMachine + *(void **) (&XSetWMClientMachine_dylibloader_wrapper_xlib) = dlsym(handle, "XSetWMClientMachine"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetWMHints + *(void **) (&XSetWMHints_dylibloader_wrapper_xlib) = dlsym(handle, "XSetWMHints"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetWMIconName + *(void **) (&XSetWMIconName_dylibloader_wrapper_xlib) = dlsym(handle, "XSetWMIconName"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetWMName + *(void **) (&XSetWMName_dylibloader_wrapper_xlib) = dlsym(handle, "XSetWMName"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetWMNormalHints + *(void **) (&XSetWMNormalHints_dylibloader_wrapper_xlib) = dlsym(handle, "XSetWMNormalHints"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetWMProperties + *(void **) (&XSetWMProperties_dylibloader_wrapper_xlib) = dlsym(handle, "XSetWMProperties"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XmbSetWMProperties + *(void **) (&XmbSetWMProperties_dylibloader_wrapper_xlib) = dlsym(handle, "XmbSetWMProperties"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// Xutf8SetWMProperties + *(void **) (&Xutf8SetWMProperties_dylibloader_wrapper_xlib) = dlsym(handle, "Xutf8SetWMProperties"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetWMSizeHints + *(void **) (&XSetWMSizeHints_dylibloader_wrapper_xlib) = dlsym(handle, "XSetWMSizeHints"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetRegion + *(void **) (&XSetRegion_dylibloader_wrapper_xlib) = dlsym(handle, "XSetRegion"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetStandardColormap + *(void **) (&XSetStandardColormap_dylibloader_wrapper_xlib) = dlsym(handle, "XSetStandardColormap"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSetZoomHints + *(void **) (&XSetZoomHints_dylibloader_wrapper_xlib) = dlsym(handle, "XSetZoomHints"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XShrinkRegion + *(void **) (&XShrinkRegion_dylibloader_wrapper_xlib) = dlsym(handle, "XShrinkRegion"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XStringListToTextProperty + *(void **) (&XStringListToTextProperty_dylibloader_wrapper_xlib) = dlsym(handle, "XStringListToTextProperty"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XSubtractRegion + *(void **) (&XSubtractRegion_dylibloader_wrapper_xlib) = dlsym(handle, "XSubtractRegion"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XmbTextListToTextProperty + *(void **) (&XmbTextListToTextProperty_dylibloader_wrapper_xlib) = dlsym(handle, "XmbTextListToTextProperty"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XwcTextListToTextProperty + *(void **) (&XwcTextListToTextProperty_dylibloader_wrapper_xlib) = dlsym(handle, "XwcTextListToTextProperty"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// Xutf8TextListToTextProperty + *(void **) (&Xutf8TextListToTextProperty_dylibloader_wrapper_xlib) = dlsym(handle, "Xutf8TextListToTextProperty"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XwcFreeStringList + *(void **) (&XwcFreeStringList_dylibloader_wrapper_xlib) = dlsym(handle, "XwcFreeStringList"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XTextPropertyToStringList + *(void **) (&XTextPropertyToStringList_dylibloader_wrapper_xlib) = dlsym(handle, "XTextPropertyToStringList"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XmbTextPropertyToTextList + *(void **) (&XmbTextPropertyToTextList_dylibloader_wrapper_xlib) = dlsym(handle, "XmbTextPropertyToTextList"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XwcTextPropertyToTextList + *(void **) (&XwcTextPropertyToTextList_dylibloader_wrapper_xlib) = dlsym(handle, "XwcTextPropertyToTextList"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// Xutf8TextPropertyToTextList + *(void **) (&Xutf8TextPropertyToTextList_dylibloader_wrapper_xlib) = dlsym(handle, "Xutf8TextPropertyToTextList"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XUnionRectWithRegion + *(void **) (&XUnionRectWithRegion_dylibloader_wrapper_xlib) = dlsym(handle, "XUnionRectWithRegion"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XUnionRegion + *(void **) (&XUnionRegion_dylibloader_wrapper_xlib) = dlsym(handle, "XUnionRegion"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XWMGeometry + *(void **) (&XWMGeometry_dylibloader_wrapper_xlib) = dlsym(handle, "XWMGeometry"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XXorRegion + *(void **) (&XXorRegion_dylibloader_wrapper_xlib) = dlsym(handle, "XXorRegion"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbIgnoreExtension + *(void **) (&XkbIgnoreExtension_dylibloader_wrapper_xlib) = dlsym(handle, "XkbIgnoreExtension"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbOpenDisplay + *(void **) (&XkbOpenDisplay_dylibloader_wrapper_xlib) = dlsym(handle, "XkbOpenDisplay"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbQueryExtension + *(void **) (&XkbQueryExtension_dylibloader_wrapper_xlib) = dlsym(handle, "XkbQueryExtension"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbUseExtension + *(void **) (&XkbUseExtension_dylibloader_wrapper_xlib) = dlsym(handle, "XkbUseExtension"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbLibraryVersion + *(void **) (&XkbLibraryVersion_dylibloader_wrapper_xlib) = dlsym(handle, "XkbLibraryVersion"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbSetXlibControls + *(void **) (&XkbSetXlibControls_dylibloader_wrapper_xlib) = dlsym(handle, "XkbSetXlibControls"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbGetXlibControls + *(void **) (&XkbGetXlibControls_dylibloader_wrapper_xlib) = dlsym(handle, "XkbGetXlibControls"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbXlibControlsImplemented + *(void **) (&XkbXlibControlsImplemented_dylibloader_wrapper_xlib) = dlsym(handle, "XkbXlibControlsImplemented"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbSetAtomFuncs + *(void **) (&XkbSetAtomFuncs_dylibloader_wrapper_xlib) = dlsym(handle, "XkbSetAtomFuncs"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbKeycodeToKeysym + *(void **) (&XkbKeycodeToKeysym_dylibloader_wrapper_xlib) = dlsym(handle, "XkbKeycodeToKeysym"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbKeysymToModifiers + *(void **) (&XkbKeysymToModifiers_dylibloader_wrapper_xlib) = dlsym(handle, "XkbKeysymToModifiers"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbLookupKeySym + *(void **) (&XkbLookupKeySym_dylibloader_wrapper_xlib) = dlsym(handle, "XkbLookupKeySym"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbLookupKeyBinding + *(void **) (&XkbLookupKeyBinding_dylibloader_wrapper_xlib) = dlsym(handle, "XkbLookupKeyBinding"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbTranslateKeyCode + *(void **) (&XkbTranslateKeyCode_dylibloader_wrapper_xlib) = dlsym(handle, "XkbTranslateKeyCode"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbTranslateKeySym + *(void **) (&XkbTranslateKeySym_dylibloader_wrapper_xlib) = dlsym(handle, "XkbTranslateKeySym"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbSetAutoRepeatRate + *(void **) (&XkbSetAutoRepeatRate_dylibloader_wrapper_xlib) = dlsym(handle, "XkbSetAutoRepeatRate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbGetAutoRepeatRate + *(void **) (&XkbGetAutoRepeatRate_dylibloader_wrapper_xlib) = dlsym(handle, "XkbGetAutoRepeatRate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbChangeEnabledControls + *(void **) (&XkbChangeEnabledControls_dylibloader_wrapper_xlib) = dlsym(handle, "XkbChangeEnabledControls"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbDeviceBell + *(void **) (&XkbDeviceBell_dylibloader_wrapper_xlib) = dlsym(handle, "XkbDeviceBell"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbForceDeviceBell + *(void **) (&XkbForceDeviceBell_dylibloader_wrapper_xlib) = dlsym(handle, "XkbForceDeviceBell"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbDeviceBellEvent + *(void **) (&XkbDeviceBellEvent_dylibloader_wrapper_xlib) = dlsym(handle, "XkbDeviceBellEvent"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbBell + *(void **) (&XkbBell_dylibloader_wrapper_xlib) = dlsym(handle, "XkbBell"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbForceBell + *(void **) (&XkbForceBell_dylibloader_wrapper_xlib) = dlsym(handle, "XkbForceBell"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbBellEvent + *(void **) (&XkbBellEvent_dylibloader_wrapper_xlib) = dlsym(handle, "XkbBellEvent"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbSelectEvents + *(void **) (&XkbSelectEvents_dylibloader_wrapper_xlib) = dlsym(handle, "XkbSelectEvents"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbSelectEventDetails + *(void **) (&XkbSelectEventDetails_dylibloader_wrapper_xlib) = dlsym(handle, "XkbSelectEventDetails"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbNoteMapChanges + *(void **) (&XkbNoteMapChanges_dylibloader_wrapper_xlib) = dlsym(handle, "XkbNoteMapChanges"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbNoteNameChanges + *(void **) (&XkbNoteNameChanges_dylibloader_wrapper_xlib) = dlsym(handle, "XkbNoteNameChanges"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbGetIndicatorState + *(void **) (&XkbGetIndicatorState_dylibloader_wrapper_xlib) = dlsym(handle, "XkbGetIndicatorState"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbGetIndicatorMap + *(void **) (&XkbGetIndicatorMap_dylibloader_wrapper_xlib) = dlsym(handle, "XkbGetIndicatorMap"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbSetIndicatorMap + *(void **) (&XkbSetIndicatorMap_dylibloader_wrapper_xlib) = dlsym(handle, "XkbSetIndicatorMap"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbGetNamedIndicator + *(void **) (&XkbGetNamedIndicator_dylibloader_wrapper_xlib) = dlsym(handle, "XkbGetNamedIndicator"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbGetNamedDeviceIndicator + *(void **) (&XkbGetNamedDeviceIndicator_dylibloader_wrapper_xlib) = dlsym(handle, "XkbGetNamedDeviceIndicator"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbSetNamedIndicator + *(void **) (&XkbSetNamedIndicator_dylibloader_wrapper_xlib) = dlsym(handle, "XkbSetNamedIndicator"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbSetNamedDeviceIndicator + *(void **) (&XkbSetNamedDeviceIndicator_dylibloader_wrapper_xlib) = dlsym(handle, "XkbSetNamedDeviceIndicator"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbLockModifiers + *(void **) (&XkbLockModifiers_dylibloader_wrapper_xlib) = dlsym(handle, "XkbLockModifiers"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbLatchModifiers + *(void **) (&XkbLatchModifiers_dylibloader_wrapper_xlib) = dlsym(handle, "XkbLatchModifiers"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbLockGroup + *(void **) (&XkbLockGroup_dylibloader_wrapper_xlib) = dlsym(handle, "XkbLockGroup"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbLatchGroup + *(void **) (&XkbLatchGroup_dylibloader_wrapper_xlib) = dlsym(handle, "XkbLatchGroup"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbSetServerInternalMods + *(void **) (&XkbSetServerInternalMods_dylibloader_wrapper_xlib) = dlsym(handle, "XkbSetServerInternalMods"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbSetIgnoreLockMods + *(void **) (&XkbSetIgnoreLockMods_dylibloader_wrapper_xlib) = dlsym(handle, "XkbSetIgnoreLockMods"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbVirtualModsToReal + *(void **) (&XkbVirtualModsToReal_dylibloader_wrapper_xlib) = dlsym(handle, "XkbVirtualModsToReal"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbComputeEffectiveMap + *(void **) (&XkbComputeEffectiveMap_dylibloader_wrapper_xlib) = dlsym(handle, "XkbComputeEffectiveMap"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbInitCanonicalKeyTypes + *(void **) (&XkbInitCanonicalKeyTypes_dylibloader_wrapper_xlib) = dlsym(handle, "XkbInitCanonicalKeyTypes"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbAllocKeyboard + *(void **) (&XkbAllocKeyboard_dylibloader_wrapper_xlib) = dlsym(handle, "XkbAllocKeyboard"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbFreeKeyboard + *(void **) (&XkbFreeKeyboard_dylibloader_wrapper_xlib) = dlsym(handle, "XkbFreeKeyboard"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbAllocClientMap + *(void **) (&XkbAllocClientMap_dylibloader_wrapper_xlib) = dlsym(handle, "XkbAllocClientMap"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbAllocServerMap + *(void **) (&XkbAllocServerMap_dylibloader_wrapper_xlib) = dlsym(handle, "XkbAllocServerMap"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbFreeClientMap + *(void **) (&XkbFreeClientMap_dylibloader_wrapper_xlib) = dlsym(handle, "XkbFreeClientMap"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbFreeServerMap + *(void **) (&XkbFreeServerMap_dylibloader_wrapper_xlib) = dlsym(handle, "XkbFreeServerMap"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbAddKeyType + *(void **) (&XkbAddKeyType_dylibloader_wrapper_xlib) = dlsym(handle, "XkbAddKeyType"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbAllocIndicatorMaps + *(void **) (&XkbAllocIndicatorMaps_dylibloader_wrapper_xlib) = dlsym(handle, "XkbAllocIndicatorMaps"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbFreeIndicatorMaps + *(void **) (&XkbFreeIndicatorMaps_dylibloader_wrapper_xlib) = dlsym(handle, "XkbFreeIndicatorMaps"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbGetMap + *(void **) (&XkbGetMap_dylibloader_wrapper_xlib) = dlsym(handle, "XkbGetMap"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbGetUpdatedMap + *(void **) (&XkbGetUpdatedMap_dylibloader_wrapper_xlib) = dlsym(handle, "XkbGetUpdatedMap"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbGetMapChanges + *(void **) (&XkbGetMapChanges_dylibloader_wrapper_xlib) = dlsym(handle, "XkbGetMapChanges"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbRefreshKeyboardMapping + *(void **) (&XkbRefreshKeyboardMapping_dylibloader_wrapper_xlib) = dlsym(handle, "XkbRefreshKeyboardMapping"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbGetKeyTypes + *(void **) (&XkbGetKeyTypes_dylibloader_wrapper_xlib) = dlsym(handle, "XkbGetKeyTypes"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbGetKeySyms + *(void **) (&XkbGetKeySyms_dylibloader_wrapper_xlib) = dlsym(handle, "XkbGetKeySyms"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbGetKeyActions + *(void **) (&XkbGetKeyActions_dylibloader_wrapper_xlib) = dlsym(handle, "XkbGetKeyActions"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbGetKeyBehaviors + *(void **) (&XkbGetKeyBehaviors_dylibloader_wrapper_xlib) = dlsym(handle, "XkbGetKeyBehaviors"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbGetVirtualMods + *(void **) (&XkbGetVirtualMods_dylibloader_wrapper_xlib) = dlsym(handle, "XkbGetVirtualMods"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbGetKeyExplicitComponents + *(void **) (&XkbGetKeyExplicitComponents_dylibloader_wrapper_xlib) = dlsym(handle, "XkbGetKeyExplicitComponents"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbGetKeyModifierMap + *(void **) (&XkbGetKeyModifierMap_dylibloader_wrapper_xlib) = dlsym(handle, "XkbGetKeyModifierMap"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbGetKeyVirtualModMap + *(void **) (&XkbGetKeyVirtualModMap_dylibloader_wrapper_xlib) = dlsym(handle, "XkbGetKeyVirtualModMap"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbAllocControls + *(void **) (&XkbAllocControls_dylibloader_wrapper_xlib) = dlsym(handle, "XkbAllocControls"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbFreeControls + *(void **) (&XkbFreeControls_dylibloader_wrapper_xlib) = dlsym(handle, "XkbFreeControls"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbGetControls + *(void **) (&XkbGetControls_dylibloader_wrapper_xlib) = dlsym(handle, "XkbGetControls"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbSetControls + *(void **) (&XkbSetControls_dylibloader_wrapper_xlib) = dlsym(handle, "XkbSetControls"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbNoteControlsChanges + *(void **) (&XkbNoteControlsChanges_dylibloader_wrapper_xlib) = dlsym(handle, "XkbNoteControlsChanges"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbAllocCompatMap + *(void **) (&XkbAllocCompatMap_dylibloader_wrapper_xlib) = dlsym(handle, "XkbAllocCompatMap"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbFreeCompatMap + *(void **) (&XkbFreeCompatMap_dylibloader_wrapper_xlib) = dlsym(handle, "XkbFreeCompatMap"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbGetCompatMap + *(void **) (&XkbGetCompatMap_dylibloader_wrapper_xlib) = dlsym(handle, "XkbGetCompatMap"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbSetCompatMap + *(void **) (&XkbSetCompatMap_dylibloader_wrapper_xlib) = dlsym(handle, "XkbSetCompatMap"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbAllocNames + *(void **) (&XkbAllocNames_dylibloader_wrapper_xlib) = dlsym(handle, "XkbAllocNames"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbGetNames + *(void **) (&XkbGetNames_dylibloader_wrapper_xlib) = dlsym(handle, "XkbGetNames"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbSetNames + *(void **) (&XkbSetNames_dylibloader_wrapper_xlib) = dlsym(handle, "XkbSetNames"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbChangeNames + *(void **) (&XkbChangeNames_dylibloader_wrapper_xlib) = dlsym(handle, "XkbChangeNames"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbFreeNames + *(void **) (&XkbFreeNames_dylibloader_wrapper_xlib) = dlsym(handle, "XkbFreeNames"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbGetState + *(void **) (&XkbGetState_dylibloader_wrapper_xlib) = dlsym(handle, "XkbGetState"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbSetMap + *(void **) (&XkbSetMap_dylibloader_wrapper_xlib) = dlsym(handle, "XkbSetMap"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbChangeMap + *(void **) (&XkbChangeMap_dylibloader_wrapper_xlib) = dlsym(handle, "XkbChangeMap"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbSetDetectableAutoRepeat + *(void **) (&XkbSetDetectableAutoRepeat_dylibloader_wrapper_xlib) = dlsym(handle, "XkbSetDetectableAutoRepeat"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbGetDetectableAutoRepeat + *(void **) (&XkbGetDetectableAutoRepeat_dylibloader_wrapper_xlib) = dlsym(handle, "XkbGetDetectableAutoRepeat"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbSetAutoResetControls + *(void **) (&XkbSetAutoResetControls_dylibloader_wrapper_xlib) = dlsym(handle, "XkbSetAutoResetControls"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbGetAutoResetControls + *(void **) (&XkbGetAutoResetControls_dylibloader_wrapper_xlib) = dlsym(handle, "XkbGetAutoResetControls"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbSetPerClientControls + *(void **) (&XkbSetPerClientControls_dylibloader_wrapper_xlib) = dlsym(handle, "XkbSetPerClientControls"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbGetPerClientControls + *(void **) (&XkbGetPerClientControls_dylibloader_wrapper_xlib) = dlsym(handle, "XkbGetPerClientControls"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbCopyKeyType + *(void **) (&XkbCopyKeyType_dylibloader_wrapper_xlib) = dlsym(handle, "XkbCopyKeyType"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbCopyKeyTypes + *(void **) (&XkbCopyKeyTypes_dylibloader_wrapper_xlib) = dlsym(handle, "XkbCopyKeyTypes"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbResizeKeyType + *(void **) (&XkbResizeKeyType_dylibloader_wrapper_xlib) = dlsym(handle, "XkbResizeKeyType"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbResizeKeySyms + *(void **) (&XkbResizeKeySyms_dylibloader_wrapper_xlib) = dlsym(handle, "XkbResizeKeySyms"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbResizeKeyActions + *(void **) (&XkbResizeKeyActions_dylibloader_wrapper_xlib) = dlsym(handle, "XkbResizeKeyActions"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbChangeTypesOfKey + *(void **) (&XkbChangeTypesOfKey_dylibloader_wrapper_xlib) = dlsym(handle, "XkbChangeTypesOfKey"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbChangeKeycodeRange + *(void **) (&XkbChangeKeycodeRange_dylibloader_wrapper_xlib) = dlsym(handle, "XkbChangeKeycodeRange"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbListComponents + *(void **) (&XkbListComponents_dylibloader_wrapper_xlib) = dlsym(handle, "XkbListComponents"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbFreeComponentList + *(void **) (&XkbFreeComponentList_dylibloader_wrapper_xlib) = dlsym(handle, "XkbFreeComponentList"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbGetKeyboard + *(void **) (&XkbGetKeyboard_dylibloader_wrapper_xlib) = dlsym(handle, "XkbGetKeyboard"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbGetKeyboardByName + *(void **) (&XkbGetKeyboardByName_dylibloader_wrapper_xlib) = dlsym(handle, "XkbGetKeyboardByName"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbKeyTypesForCoreSymbols + *(void **) (&XkbKeyTypesForCoreSymbols_dylibloader_wrapper_xlib) = dlsym(handle, "XkbKeyTypesForCoreSymbols"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbApplyCompatMapToKey + *(void **) (&XkbApplyCompatMapToKey_dylibloader_wrapper_xlib) = dlsym(handle, "XkbApplyCompatMapToKey"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbUpdateMapFromCore + *(void **) (&XkbUpdateMapFromCore_dylibloader_wrapper_xlib) = dlsym(handle, "XkbUpdateMapFromCore"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbAddDeviceLedInfo + *(void **) (&XkbAddDeviceLedInfo_dylibloader_wrapper_xlib) = dlsym(handle, "XkbAddDeviceLedInfo"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbResizeDeviceButtonActions + *(void **) (&XkbResizeDeviceButtonActions_dylibloader_wrapper_xlib) = dlsym(handle, "XkbResizeDeviceButtonActions"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbAllocDeviceInfo + *(void **) (&XkbAllocDeviceInfo_dylibloader_wrapper_xlib) = dlsym(handle, "XkbAllocDeviceInfo"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbFreeDeviceInfo + *(void **) (&XkbFreeDeviceInfo_dylibloader_wrapper_xlib) = dlsym(handle, "XkbFreeDeviceInfo"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbNoteDeviceChanges + *(void **) (&XkbNoteDeviceChanges_dylibloader_wrapper_xlib) = dlsym(handle, "XkbNoteDeviceChanges"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbGetDeviceInfo + *(void **) (&XkbGetDeviceInfo_dylibloader_wrapper_xlib) = dlsym(handle, "XkbGetDeviceInfo"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbGetDeviceInfoChanges + *(void **) (&XkbGetDeviceInfoChanges_dylibloader_wrapper_xlib) = dlsym(handle, "XkbGetDeviceInfoChanges"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbGetDeviceButtonActions + *(void **) (&XkbGetDeviceButtonActions_dylibloader_wrapper_xlib) = dlsym(handle, "XkbGetDeviceButtonActions"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbGetDeviceLedInfo + *(void **) (&XkbGetDeviceLedInfo_dylibloader_wrapper_xlib) = dlsym(handle, "XkbGetDeviceLedInfo"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbSetDeviceInfo + *(void **) (&XkbSetDeviceInfo_dylibloader_wrapper_xlib) = dlsym(handle, "XkbSetDeviceInfo"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbChangeDeviceInfo + *(void **) (&XkbChangeDeviceInfo_dylibloader_wrapper_xlib) = dlsym(handle, "XkbChangeDeviceInfo"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbSetDeviceLedInfo + *(void **) (&XkbSetDeviceLedInfo_dylibloader_wrapper_xlib) = dlsym(handle, "XkbSetDeviceLedInfo"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbSetDeviceButtonActions + *(void **) (&XkbSetDeviceButtonActions_dylibloader_wrapper_xlib) = dlsym(handle, "XkbSetDeviceButtonActions"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbToControl + *(void **) (&XkbToControl_dylibloader_wrapper_xlib) = dlsym(handle, "XkbToControl"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbSetDebuggingFlags + *(void **) (&XkbSetDebuggingFlags_dylibloader_wrapper_xlib) = dlsym(handle, "XkbSetDebuggingFlags"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbApplyVirtualModChanges + *(void **) (&XkbApplyVirtualModChanges_dylibloader_wrapper_xlib) = dlsym(handle, "XkbApplyVirtualModChanges"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbUpdateActionVirtualMods + *(void **) (&XkbUpdateActionVirtualMods_dylibloader_wrapper_xlib) = dlsym(handle, "XkbUpdateActionVirtualMods"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XkbUpdateKeyTypeVirtualMods + *(void **) (&XkbUpdateKeyTypeVirtualMods_dylibloader_wrapper_xlib) = dlsym(handle, "XkbUpdateKeyTypeVirtualMods"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +return 0; +} diff --git a/platform/linuxbsd/x11/dynwrappers/xlib-so_wrap.h b/platform/linuxbsd/x11/dynwrappers/xlib-so_wrap.h new file mode 100644 index 0000000000..5bad21002d --- /dev/null +++ b/platform/linuxbsd/x11/dynwrappers/xlib-so_wrap.h @@ -0,0 +1,2439 @@ +#ifndef DYLIBLOAD_WRAPPER_XLIB +#define DYLIBLOAD_WRAPPER_XLIB +// This file is generated. Do not edit! +// see https://github.com/hpvb/dynload-wrapper for details +// generated by generate-wrapper.py 0.3 on 2023-01-23 15:13:26 +// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/Xlib.h --include ./thirdparty/linuxbsd_headers/X11/Xutil.h --include ./thirdparty/linuxbsd_headers/X11/XKBlib.h --sys-include "thirdparty/linuxbsd_headers/X11/Xlib.h" --sys-include "thirdparty/linuxbsd_headers/X11/Xutil.h" --sys-include "thirdparty/linuxbsd_headers/X11/XKBlib.h" --soname libX11.so.6 --init-name xlib --omit-prefix XkbGetDeviceIndicatorState --omit-prefix XkbAddSymInterpret --output-header ./platform/linuxbsd/x11/dynwrappers/xlib-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xlib-so_wrap.c~ +// +// NOTE: Generated from Xlib 1.6.9. +// This has been handpatched to workaround some issues with the generator that +// will be eventually fixed. In this case, the type of the third argument of +// XIfEvent, XPeekIfEvent and XCheckIfEvent had to be fixed as it wasn't parsed +// fully (it's a Bool function pointer, but it was just being parsed as an int +// pointer). + +#include <stdint.h> + +#define _Xmblen _Xmblen_dylibloader_orig_xlib +#define XLoadQueryFont XLoadQueryFont_dylibloader_orig_xlib +#define XQueryFont XQueryFont_dylibloader_orig_xlib +#define XGetMotionEvents XGetMotionEvents_dylibloader_orig_xlib +#define XDeleteModifiermapEntry XDeleteModifiermapEntry_dylibloader_orig_xlib +#define XGetModifierMapping XGetModifierMapping_dylibloader_orig_xlib +#define XInsertModifiermapEntry XInsertModifiermapEntry_dylibloader_orig_xlib +#define XNewModifiermap XNewModifiermap_dylibloader_orig_xlib +#define XCreateImage XCreateImage_dylibloader_orig_xlib +#define XInitImage XInitImage_dylibloader_orig_xlib +#define XGetImage XGetImage_dylibloader_orig_xlib +#define XGetSubImage XGetSubImage_dylibloader_orig_xlib +#define XOpenDisplay XOpenDisplay_dylibloader_orig_xlib +#define XrmInitialize XrmInitialize_dylibloader_orig_xlib +#define XFetchBytes XFetchBytes_dylibloader_orig_xlib +#define XFetchBuffer XFetchBuffer_dylibloader_orig_xlib +#define XGetAtomName XGetAtomName_dylibloader_orig_xlib +#define XGetAtomNames XGetAtomNames_dylibloader_orig_xlib +#define XGetDefault XGetDefault_dylibloader_orig_xlib +#define XDisplayName XDisplayName_dylibloader_orig_xlib +#define XKeysymToString XKeysymToString_dylibloader_orig_xlib +#define XSynchronize XSynchronize_dylibloader_orig_xlib +#define XSetAfterFunction XSetAfterFunction_dylibloader_orig_xlib +#define XInternAtom XInternAtom_dylibloader_orig_xlib +#define XInternAtoms XInternAtoms_dylibloader_orig_xlib +#define XCopyColormapAndFree XCopyColormapAndFree_dylibloader_orig_xlib +#define XCreateColormap XCreateColormap_dylibloader_orig_xlib +#define XCreatePixmapCursor XCreatePixmapCursor_dylibloader_orig_xlib +#define XCreateGlyphCursor XCreateGlyphCursor_dylibloader_orig_xlib +#define XCreateFontCursor XCreateFontCursor_dylibloader_orig_xlib +#define XLoadFont XLoadFont_dylibloader_orig_xlib +#define XCreateGC XCreateGC_dylibloader_orig_xlib +#define XGContextFromGC XGContextFromGC_dylibloader_orig_xlib +#define XFlushGC XFlushGC_dylibloader_orig_xlib +#define XCreatePixmap XCreatePixmap_dylibloader_orig_xlib +#define XCreateBitmapFromData XCreateBitmapFromData_dylibloader_orig_xlib +#define XCreatePixmapFromBitmapData XCreatePixmapFromBitmapData_dylibloader_orig_xlib +#define XCreateSimpleWindow XCreateSimpleWindow_dylibloader_orig_xlib +#define XGetSelectionOwner XGetSelectionOwner_dylibloader_orig_xlib +#define XCreateWindow XCreateWindow_dylibloader_orig_xlib +#define XListInstalledColormaps XListInstalledColormaps_dylibloader_orig_xlib +#define XListFonts XListFonts_dylibloader_orig_xlib +#define XListFontsWithInfo XListFontsWithInfo_dylibloader_orig_xlib +#define XGetFontPath XGetFontPath_dylibloader_orig_xlib +#define XListExtensions XListExtensions_dylibloader_orig_xlib +#define XListProperties XListProperties_dylibloader_orig_xlib +#define XListHosts XListHosts_dylibloader_orig_xlib +#define XKeycodeToKeysym XKeycodeToKeysym_dylibloader_orig_xlib +#define XLookupKeysym XLookupKeysym_dylibloader_orig_xlib +#define XGetKeyboardMapping XGetKeyboardMapping_dylibloader_orig_xlib +#define XStringToKeysym XStringToKeysym_dylibloader_orig_xlib +#define XMaxRequestSize XMaxRequestSize_dylibloader_orig_xlib +#define XExtendedMaxRequestSize XExtendedMaxRequestSize_dylibloader_orig_xlib +#define XResourceManagerString XResourceManagerString_dylibloader_orig_xlib +#define XScreenResourceString XScreenResourceString_dylibloader_orig_xlib +#define XDisplayMotionBufferSize XDisplayMotionBufferSize_dylibloader_orig_xlib +#define XVisualIDFromVisual XVisualIDFromVisual_dylibloader_orig_xlib +#define XInitThreads XInitThreads_dylibloader_orig_xlib +#define XLockDisplay XLockDisplay_dylibloader_orig_xlib +#define XUnlockDisplay XUnlockDisplay_dylibloader_orig_xlib +#define XInitExtension XInitExtension_dylibloader_orig_xlib +#define XAddExtension XAddExtension_dylibloader_orig_xlib +#define XFindOnExtensionList XFindOnExtensionList_dylibloader_orig_xlib +#define XEHeadOfExtensionList XEHeadOfExtensionList_dylibloader_orig_xlib +#define XRootWindow XRootWindow_dylibloader_orig_xlib +#define XDefaultRootWindow XDefaultRootWindow_dylibloader_orig_xlib +#define XRootWindowOfScreen XRootWindowOfScreen_dylibloader_orig_xlib +#define XDefaultVisual XDefaultVisual_dylibloader_orig_xlib +#define XDefaultVisualOfScreen XDefaultVisualOfScreen_dylibloader_orig_xlib +#define XDefaultGC XDefaultGC_dylibloader_orig_xlib +#define XDefaultGCOfScreen XDefaultGCOfScreen_dylibloader_orig_xlib +#define XBlackPixel XBlackPixel_dylibloader_orig_xlib +#define XWhitePixel XWhitePixel_dylibloader_orig_xlib +#define XAllPlanes XAllPlanes_dylibloader_orig_xlib +#define XBlackPixelOfScreen XBlackPixelOfScreen_dylibloader_orig_xlib +#define XWhitePixelOfScreen XWhitePixelOfScreen_dylibloader_orig_xlib +#define XNextRequest XNextRequest_dylibloader_orig_xlib +#define XLastKnownRequestProcessed XLastKnownRequestProcessed_dylibloader_orig_xlib +#define XServerVendor XServerVendor_dylibloader_orig_xlib +#define XDisplayString XDisplayString_dylibloader_orig_xlib +#define XDefaultColormap XDefaultColormap_dylibloader_orig_xlib +#define XDefaultColormapOfScreen XDefaultColormapOfScreen_dylibloader_orig_xlib +#define XDisplayOfScreen XDisplayOfScreen_dylibloader_orig_xlib +#define XScreenOfDisplay XScreenOfDisplay_dylibloader_orig_xlib +#define XDefaultScreenOfDisplay XDefaultScreenOfDisplay_dylibloader_orig_xlib +#define XEventMaskOfScreen XEventMaskOfScreen_dylibloader_orig_xlib +#define XScreenNumberOfScreen XScreenNumberOfScreen_dylibloader_orig_xlib +#define XSetErrorHandler XSetErrorHandler_dylibloader_orig_xlib +#define XSetIOErrorHandler XSetIOErrorHandler_dylibloader_orig_xlib +#define XListPixmapFormats XListPixmapFormats_dylibloader_orig_xlib +#define XListDepths XListDepths_dylibloader_orig_xlib +#define XReconfigureWMWindow XReconfigureWMWindow_dylibloader_orig_xlib +#define XGetWMProtocols XGetWMProtocols_dylibloader_orig_xlib +#define XSetWMProtocols XSetWMProtocols_dylibloader_orig_xlib +#define XIconifyWindow XIconifyWindow_dylibloader_orig_xlib +#define XWithdrawWindow XWithdrawWindow_dylibloader_orig_xlib +#define XGetCommand XGetCommand_dylibloader_orig_xlib +#define XGetWMColormapWindows XGetWMColormapWindows_dylibloader_orig_xlib +#define XSetWMColormapWindows XSetWMColormapWindows_dylibloader_orig_xlib +#define XFreeStringList XFreeStringList_dylibloader_orig_xlib +#define XSetTransientForHint XSetTransientForHint_dylibloader_orig_xlib +#define XActivateScreenSaver XActivateScreenSaver_dylibloader_orig_xlib +#define XAddHost XAddHost_dylibloader_orig_xlib +#define XAddHosts XAddHosts_dylibloader_orig_xlib +#define XAddToExtensionList XAddToExtensionList_dylibloader_orig_xlib +#define XAddToSaveSet XAddToSaveSet_dylibloader_orig_xlib +#define XAllocColor XAllocColor_dylibloader_orig_xlib +#define XAllocColorCells XAllocColorCells_dylibloader_orig_xlib +#define XAllocColorPlanes XAllocColorPlanes_dylibloader_orig_xlib +#define XAllocNamedColor XAllocNamedColor_dylibloader_orig_xlib +#define XAllowEvents XAllowEvents_dylibloader_orig_xlib +#define XAutoRepeatOff XAutoRepeatOff_dylibloader_orig_xlib +#define XAutoRepeatOn XAutoRepeatOn_dylibloader_orig_xlib +#define XBell XBell_dylibloader_orig_xlib +#define XBitmapBitOrder XBitmapBitOrder_dylibloader_orig_xlib +#define XBitmapPad XBitmapPad_dylibloader_orig_xlib +#define XBitmapUnit XBitmapUnit_dylibloader_orig_xlib +#define XCellsOfScreen XCellsOfScreen_dylibloader_orig_xlib +#define XChangeActivePointerGrab XChangeActivePointerGrab_dylibloader_orig_xlib +#define XChangeGC XChangeGC_dylibloader_orig_xlib +#define XChangeKeyboardControl XChangeKeyboardControl_dylibloader_orig_xlib +#define XChangeKeyboardMapping XChangeKeyboardMapping_dylibloader_orig_xlib +#define XChangePointerControl XChangePointerControl_dylibloader_orig_xlib +#define XChangeProperty XChangeProperty_dylibloader_orig_xlib +#define XChangeSaveSet XChangeSaveSet_dylibloader_orig_xlib +#define XChangeWindowAttributes XChangeWindowAttributes_dylibloader_orig_xlib +#define XCheckIfEvent XCheckIfEvent_dylibloader_orig_xlib +#define XCheckMaskEvent XCheckMaskEvent_dylibloader_orig_xlib +#define XCheckTypedEvent XCheckTypedEvent_dylibloader_orig_xlib +#define XCheckTypedWindowEvent XCheckTypedWindowEvent_dylibloader_orig_xlib +#define XCheckWindowEvent XCheckWindowEvent_dylibloader_orig_xlib +#define XCirculateSubwindows XCirculateSubwindows_dylibloader_orig_xlib +#define XCirculateSubwindowsDown XCirculateSubwindowsDown_dylibloader_orig_xlib +#define XCirculateSubwindowsUp XCirculateSubwindowsUp_dylibloader_orig_xlib +#define XClearArea XClearArea_dylibloader_orig_xlib +#define XClearWindow XClearWindow_dylibloader_orig_xlib +#define XCloseDisplay XCloseDisplay_dylibloader_orig_xlib +#define XConfigureWindow XConfigureWindow_dylibloader_orig_xlib +#define XConnectionNumber XConnectionNumber_dylibloader_orig_xlib +#define XConvertSelection XConvertSelection_dylibloader_orig_xlib +#define XCopyArea XCopyArea_dylibloader_orig_xlib +#define XCopyGC XCopyGC_dylibloader_orig_xlib +#define XCopyPlane XCopyPlane_dylibloader_orig_xlib +#define XDefaultDepth XDefaultDepth_dylibloader_orig_xlib +#define XDefaultDepthOfScreen XDefaultDepthOfScreen_dylibloader_orig_xlib +#define XDefaultScreen XDefaultScreen_dylibloader_orig_xlib +#define XDefineCursor XDefineCursor_dylibloader_orig_xlib +#define XDeleteProperty XDeleteProperty_dylibloader_orig_xlib +#define XDestroyWindow XDestroyWindow_dylibloader_orig_xlib +#define XDestroySubwindows XDestroySubwindows_dylibloader_orig_xlib +#define XDoesBackingStore XDoesBackingStore_dylibloader_orig_xlib +#define XDoesSaveUnders XDoesSaveUnders_dylibloader_orig_xlib +#define XDisableAccessControl XDisableAccessControl_dylibloader_orig_xlib +#define XDisplayCells XDisplayCells_dylibloader_orig_xlib +#define XDisplayHeight XDisplayHeight_dylibloader_orig_xlib +#define XDisplayHeightMM XDisplayHeightMM_dylibloader_orig_xlib +#define XDisplayKeycodes XDisplayKeycodes_dylibloader_orig_xlib +#define XDisplayPlanes XDisplayPlanes_dylibloader_orig_xlib +#define XDisplayWidth XDisplayWidth_dylibloader_orig_xlib +#define XDisplayWidthMM XDisplayWidthMM_dylibloader_orig_xlib +#define XDrawArc XDrawArc_dylibloader_orig_xlib +#define XDrawArcs XDrawArcs_dylibloader_orig_xlib +#define XDrawImageString XDrawImageString_dylibloader_orig_xlib +#define XDrawImageString16 XDrawImageString16_dylibloader_orig_xlib +#define XDrawLine XDrawLine_dylibloader_orig_xlib +#define XDrawLines XDrawLines_dylibloader_orig_xlib +#define XDrawPoint XDrawPoint_dylibloader_orig_xlib +#define XDrawPoints XDrawPoints_dylibloader_orig_xlib +#define XDrawRectangle XDrawRectangle_dylibloader_orig_xlib +#define XDrawRectangles XDrawRectangles_dylibloader_orig_xlib +#define XDrawSegments XDrawSegments_dylibloader_orig_xlib +#define XDrawString XDrawString_dylibloader_orig_xlib +#define XDrawString16 XDrawString16_dylibloader_orig_xlib +#define XDrawText XDrawText_dylibloader_orig_xlib +#define XDrawText16 XDrawText16_dylibloader_orig_xlib +#define XEnableAccessControl XEnableAccessControl_dylibloader_orig_xlib +#define XEventsQueued XEventsQueued_dylibloader_orig_xlib +#define XFetchName XFetchName_dylibloader_orig_xlib +#define XFillArc XFillArc_dylibloader_orig_xlib +#define XFillArcs XFillArcs_dylibloader_orig_xlib +#define XFillPolygon XFillPolygon_dylibloader_orig_xlib +#define XFillRectangle XFillRectangle_dylibloader_orig_xlib +#define XFillRectangles XFillRectangles_dylibloader_orig_xlib +#define XFlush XFlush_dylibloader_orig_xlib +#define XForceScreenSaver XForceScreenSaver_dylibloader_orig_xlib +#define XFree XFree_dylibloader_orig_xlib +#define XFreeColormap XFreeColormap_dylibloader_orig_xlib +#define XFreeColors XFreeColors_dylibloader_orig_xlib +#define XFreeCursor XFreeCursor_dylibloader_orig_xlib +#define XFreeExtensionList XFreeExtensionList_dylibloader_orig_xlib +#define XFreeFont XFreeFont_dylibloader_orig_xlib +#define XFreeFontInfo XFreeFontInfo_dylibloader_orig_xlib +#define XFreeFontNames XFreeFontNames_dylibloader_orig_xlib +#define XFreeFontPath XFreeFontPath_dylibloader_orig_xlib +#define XFreeGC XFreeGC_dylibloader_orig_xlib +#define XFreeModifiermap XFreeModifiermap_dylibloader_orig_xlib +#define XFreePixmap XFreePixmap_dylibloader_orig_xlib +#define XGeometry XGeometry_dylibloader_orig_xlib +#define XGetErrorDatabaseText XGetErrorDatabaseText_dylibloader_orig_xlib +#define XGetErrorText XGetErrorText_dylibloader_orig_xlib +#define XGetFontProperty XGetFontProperty_dylibloader_orig_xlib +#define XGetGCValues XGetGCValues_dylibloader_orig_xlib +#define XGetGeometry XGetGeometry_dylibloader_orig_xlib +#define XGetIconName XGetIconName_dylibloader_orig_xlib +#define XGetInputFocus XGetInputFocus_dylibloader_orig_xlib +#define XGetKeyboardControl XGetKeyboardControl_dylibloader_orig_xlib +#define XGetPointerControl XGetPointerControl_dylibloader_orig_xlib +#define XGetPointerMapping XGetPointerMapping_dylibloader_orig_xlib +#define XGetScreenSaver XGetScreenSaver_dylibloader_orig_xlib +#define XGetTransientForHint XGetTransientForHint_dylibloader_orig_xlib +#define XGetWindowProperty XGetWindowProperty_dylibloader_orig_xlib +#define XGetWindowAttributes XGetWindowAttributes_dylibloader_orig_xlib +#define XGrabButton XGrabButton_dylibloader_orig_xlib +#define XGrabKey XGrabKey_dylibloader_orig_xlib +#define XGrabKeyboard XGrabKeyboard_dylibloader_orig_xlib +#define XGrabPointer XGrabPointer_dylibloader_orig_xlib +#define XGrabServer XGrabServer_dylibloader_orig_xlib +#define XHeightMMOfScreen XHeightMMOfScreen_dylibloader_orig_xlib +#define XHeightOfScreen XHeightOfScreen_dylibloader_orig_xlib +#define XIfEvent XIfEvent_dylibloader_orig_xlib +#define XImageByteOrder XImageByteOrder_dylibloader_orig_xlib +#define XInstallColormap XInstallColormap_dylibloader_orig_xlib +#define XKeysymToKeycode XKeysymToKeycode_dylibloader_orig_xlib +#define XKillClient XKillClient_dylibloader_orig_xlib +#define XLookupColor XLookupColor_dylibloader_orig_xlib +#define XLowerWindow XLowerWindow_dylibloader_orig_xlib +#define XMapRaised XMapRaised_dylibloader_orig_xlib +#define XMapSubwindows XMapSubwindows_dylibloader_orig_xlib +#define XMapWindow XMapWindow_dylibloader_orig_xlib +#define XMaskEvent XMaskEvent_dylibloader_orig_xlib +#define XMaxCmapsOfScreen XMaxCmapsOfScreen_dylibloader_orig_xlib +#define XMinCmapsOfScreen XMinCmapsOfScreen_dylibloader_orig_xlib +#define XMoveResizeWindow XMoveResizeWindow_dylibloader_orig_xlib +#define XMoveWindow XMoveWindow_dylibloader_orig_xlib +#define XNextEvent XNextEvent_dylibloader_orig_xlib +#define XNoOp XNoOp_dylibloader_orig_xlib +#define XParseColor XParseColor_dylibloader_orig_xlib +#define XParseGeometry XParseGeometry_dylibloader_orig_xlib +#define XPeekEvent XPeekEvent_dylibloader_orig_xlib +#define XPeekIfEvent XPeekIfEvent_dylibloader_orig_xlib +#define XPending XPending_dylibloader_orig_xlib +#define XPlanesOfScreen XPlanesOfScreen_dylibloader_orig_xlib +#define XProtocolRevision XProtocolRevision_dylibloader_orig_xlib +#define XProtocolVersion XProtocolVersion_dylibloader_orig_xlib +#define XPutBackEvent XPutBackEvent_dylibloader_orig_xlib +#define XPutImage XPutImage_dylibloader_orig_xlib +#define XQLength XQLength_dylibloader_orig_xlib +#define XQueryBestCursor XQueryBestCursor_dylibloader_orig_xlib +#define XQueryBestSize XQueryBestSize_dylibloader_orig_xlib +#define XQueryBestStipple XQueryBestStipple_dylibloader_orig_xlib +#define XQueryBestTile XQueryBestTile_dylibloader_orig_xlib +#define XQueryColor XQueryColor_dylibloader_orig_xlib +#define XQueryColors XQueryColors_dylibloader_orig_xlib +#define XQueryExtension XQueryExtension_dylibloader_orig_xlib +#define XQueryKeymap XQueryKeymap_dylibloader_orig_xlib +#define XQueryPointer XQueryPointer_dylibloader_orig_xlib +#define XQueryTextExtents XQueryTextExtents_dylibloader_orig_xlib +#define XQueryTextExtents16 XQueryTextExtents16_dylibloader_orig_xlib +#define XQueryTree XQueryTree_dylibloader_orig_xlib +#define XRaiseWindow XRaiseWindow_dylibloader_orig_xlib +#define XReadBitmapFile XReadBitmapFile_dylibloader_orig_xlib +#define XReadBitmapFileData XReadBitmapFileData_dylibloader_orig_xlib +#define XRebindKeysym XRebindKeysym_dylibloader_orig_xlib +#define XRecolorCursor XRecolorCursor_dylibloader_orig_xlib +#define XRefreshKeyboardMapping XRefreshKeyboardMapping_dylibloader_orig_xlib +#define XRemoveFromSaveSet XRemoveFromSaveSet_dylibloader_orig_xlib +#define XRemoveHost XRemoveHost_dylibloader_orig_xlib +#define XRemoveHosts XRemoveHosts_dylibloader_orig_xlib +#define XReparentWindow XReparentWindow_dylibloader_orig_xlib +#define XResetScreenSaver XResetScreenSaver_dylibloader_orig_xlib +#define XResizeWindow XResizeWindow_dylibloader_orig_xlib +#define XRestackWindows XRestackWindows_dylibloader_orig_xlib +#define XRotateBuffers XRotateBuffers_dylibloader_orig_xlib +#define XRotateWindowProperties XRotateWindowProperties_dylibloader_orig_xlib +#define XScreenCount XScreenCount_dylibloader_orig_xlib +#define XSelectInput XSelectInput_dylibloader_orig_xlib +#define XSendEvent XSendEvent_dylibloader_orig_xlib +#define XSetAccessControl XSetAccessControl_dylibloader_orig_xlib +#define XSetArcMode XSetArcMode_dylibloader_orig_xlib +#define XSetBackground XSetBackground_dylibloader_orig_xlib +#define XSetClipMask XSetClipMask_dylibloader_orig_xlib +#define XSetClipOrigin XSetClipOrigin_dylibloader_orig_xlib +#define XSetClipRectangles XSetClipRectangles_dylibloader_orig_xlib +#define XSetCloseDownMode XSetCloseDownMode_dylibloader_orig_xlib +#define XSetCommand XSetCommand_dylibloader_orig_xlib +#define XSetDashes XSetDashes_dylibloader_orig_xlib +#define XSetFillRule XSetFillRule_dylibloader_orig_xlib +#define XSetFillStyle XSetFillStyle_dylibloader_orig_xlib +#define XSetFont XSetFont_dylibloader_orig_xlib +#define XSetFontPath XSetFontPath_dylibloader_orig_xlib +#define XSetForeground XSetForeground_dylibloader_orig_xlib +#define XSetFunction XSetFunction_dylibloader_orig_xlib +#define XSetGraphicsExposures XSetGraphicsExposures_dylibloader_orig_xlib +#define XSetIconName XSetIconName_dylibloader_orig_xlib +#define XSetInputFocus XSetInputFocus_dylibloader_orig_xlib +#define XSetLineAttributes XSetLineAttributes_dylibloader_orig_xlib +#define XSetModifierMapping XSetModifierMapping_dylibloader_orig_xlib +#define XSetPlaneMask XSetPlaneMask_dylibloader_orig_xlib +#define XSetPointerMapping XSetPointerMapping_dylibloader_orig_xlib +#define XSetScreenSaver XSetScreenSaver_dylibloader_orig_xlib +#define XSetSelectionOwner XSetSelectionOwner_dylibloader_orig_xlib +#define XSetState XSetState_dylibloader_orig_xlib +#define XSetStipple XSetStipple_dylibloader_orig_xlib +#define XSetSubwindowMode XSetSubwindowMode_dylibloader_orig_xlib +#define XSetTSOrigin XSetTSOrigin_dylibloader_orig_xlib +#define XSetTile XSetTile_dylibloader_orig_xlib +#define XSetWindowBackground XSetWindowBackground_dylibloader_orig_xlib +#define XSetWindowBackgroundPixmap XSetWindowBackgroundPixmap_dylibloader_orig_xlib +#define XSetWindowBorder XSetWindowBorder_dylibloader_orig_xlib +#define XSetWindowBorderPixmap XSetWindowBorderPixmap_dylibloader_orig_xlib +#define XSetWindowBorderWidth XSetWindowBorderWidth_dylibloader_orig_xlib +#define XSetWindowColormap XSetWindowColormap_dylibloader_orig_xlib +#define XStoreBuffer XStoreBuffer_dylibloader_orig_xlib +#define XStoreBytes XStoreBytes_dylibloader_orig_xlib +#define XStoreColor XStoreColor_dylibloader_orig_xlib +#define XStoreColors XStoreColors_dylibloader_orig_xlib +#define XStoreName XStoreName_dylibloader_orig_xlib +#define XStoreNamedColor XStoreNamedColor_dylibloader_orig_xlib +#define XSync XSync_dylibloader_orig_xlib +#define XTextExtents XTextExtents_dylibloader_orig_xlib +#define XTextExtents16 XTextExtents16_dylibloader_orig_xlib +#define XTextWidth XTextWidth_dylibloader_orig_xlib +#define XTextWidth16 XTextWidth16_dylibloader_orig_xlib +#define XTranslateCoordinates XTranslateCoordinates_dylibloader_orig_xlib +#define XUndefineCursor XUndefineCursor_dylibloader_orig_xlib +#define XUngrabButton XUngrabButton_dylibloader_orig_xlib +#define XUngrabKey XUngrabKey_dylibloader_orig_xlib +#define XUngrabKeyboard XUngrabKeyboard_dylibloader_orig_xlib +#define XUngrabPointer XUngrabPointer_dylibloader_orig_xlib +#define XUngrabServer XUngrabServer_dylibloader_orig_xlib +#define XUninstallColormap XUninstallColormap_dylibloader_orig_xlib +#define XUnloadFont XUnloadFont_dylibloader_orig_xlib +#define XUnmapSubwindows XUnmapSubwindows_dylibloader_orig_xlib +#define XUnmapWindow XUnmapWindow_dylibloader_orig_xlib +#define XVendorRelease XVendorRelease_dylibloader_orig_xlib +#define XWarpPointer XWarpPointer_dylibloader_orig_xlib +#define XWidthMMOfScreen XWidthMMOfScreen_dylibloader_orig_xlib +#define XWidthOfScreen XWidthOfScreen_dylibloader_orig_xlib +#define XWindowEvent XWindowEvent_dylibloader_orig_xlib +#define XWriteBitmapFile XWriteBitmapFile_dylibloader_orig_xlib +#define XSupportsLocale XSupportsLocale_dylibloader_orig_xlib +#define XSetLocaleModifiers XSetLocaleModifiers_dylibloader_orig_xlib +#define XOpenOM XOpenOM_dylibloader_orig_xlib +#define XCloseOM XCloseOM_dylibloader_orig_xlib +#define XSetOMValues XSetOMValues_dylibloader_orig_xlib +#define XGetOMValues XGetOMValues_dylibloader_orig_xlib +#define XDisplayOfOM XDisplayOfOM_dylibloader_orig_xlib +#define XLocaleOfOM XLocaleOfOM_dylibloader_orig_xlib +#define XCreateOC XCreateOC_dylibloader_orig_xlib +#define XDestroyOC XDestroyOC_dylibloader_orig_xlib +#define XOMOfOC XOMOfOC_dylibloader_orig_xlib +#define XSetOCValues XSetOCValues_dylibloader_orig_xlib +#define XGetOCValues XGetOCValues_dylibloader_orig_xlib +#define XCreateFontSet XCreateFontSet_dylibloader_orig_xlib +#define XFreeFontSet XFreeFontSet_dylibloader_orig_xlib +#define XFontsOfFontSet XFontsOfFontSet_dylibloader_orig_xlib +#define XBaseFontNameListOfFontSet XBaseFontNameListOfFontSet_dylibloader_orig_xlib +#define XLocaleOfFontSet XLocaleOfFontSet_dylibloader_orig_xlib +#define XContextDependentDrawing XContextDependentDrawing_dylibloader_orig_xlib +#define XDirectionalDependentDrawing XDirectionalDependentDrawing_dylibloader_orig_xlib +#define XContextualDrawing XContextualDrawing_dylibloader_orig_xlib +#define XExtentsOfFontSet XExtentsOfFontSet_dylibloader_orig_xlib +#define XmbTextEscapement XmbTextEscapement_dylibloader_orig_xlib +#define XwcTextEscapement XwcTextEscapement_dylibloader_orig_xlib +#define Xutf8TextEscapement Xutf8TextEscapement_dylibloader_orig_xlib +#define XmbTextExtents XmbTextExtents_dylibloader_orig_xlib +#define XwcTextExtents XwcTextExtents_dylibloader_orig_xlib +#define Xutf8TextExtents Xutf8TextExtents_dylibloader_orig_xlib +#define XmbTextPerCharExtents XmbTextPerCharExtents_dylibloader_orig_xlib +#define XwcTextPerCharExtents XwcTextPerCharExtents_dylibloader_orig_xlib +#define Xutf8TextPerCharExtents Xutf8TextPerCharExtents_dylibloader_orig_xlib +#define XmbDrawText XmbDrawText_dylibloader_orig_xlib +#define XwcDrawText XwcDrawText_dylibloader_orig_xlib +#define Xutf8DrawText Xutf8DrawText_dylibloader_orig_xlib +#define XmbDrawString XmbDrawString_dylibloader_orig_xlib +#define XwcDrawString XwcDrawString_dylibloader_orig_xlib +#define Xutf8DrawString Xutf8DrawString_dylibloader_orig_xlib +#define XmbDrawImageString XmbDrawImageString_dylibloader_orig_xlib +#define XwcDrawImageString XwcDrawImageString_dylibloader_orig_xlib +#define Xutf8DrawImageString Xutf8DrawImageString_dylibloader_orig_xlib +#define XOpenIM XOpenIM_dylibloader_orig_xlib +#define XCloseIM XCloseIM_dylibloader_orig_xlib +#define XGetIMValues XGetIMValues_dylibloader_orig_xlib +#define XSetIMValues XSetIMValues_dylibloader_orig_xlib +#define XDisplayOfIM XDisplayOfIM_dylibloader_orig_xlib +#define XLocaleOfIM XLocaleOfIM_dylibloader_orig_xlib +#define XCreateIC XCreateIC_dylibloader_orig_xlib +#define XDestroyIC XDestroyIC_dylibloader_orig_xlib +#define XSetICFocus XSetICFocus_dylibloader_orig_xlib +#define XUnsetICFocus XUnsetICFocus_dylibloader_orig_xlib +#define XwcResetIC XwcResetIC_dylibloader_orig_xlib +#define XmbResetIC XmbResetIC_dylibloader_orig_xlib +#define Xutf8ResetIC Xutf8ResetIC_dylibloader_orig_xlib +#define XSetICValues XSetICValues_dylibloader_orig_xlib +#define XGetICValues XGetICValues_dylibloader_orig_xlib +#define XIMOfIC XIMOfIC_dylibloader_orig_xlib +#define XFilterEvent XFilterEvent_dylibloader_orig_xlib +#define XmbLookupString XmbLookupString_dylibloader_orig_xlib +#define XwcLookupString XwcLookupString_dylibloader_orig_xlib +#define Xutf8LookupString Xutf8LookupString_dylibloader_orig_xlib +#define XVaCreateNestedList XVaCreateNestedList_dylibloader_orig_xlib +#define XRegisterIMInstantiateCallback XRegisterIMInstantiateCallback_dylibloader_orig_xlib +#define XUnregisterIMInstantiateCallback XUnregisterIMInstantiateCallback_dylibloader_orig_xlib +#define XInternalConnectionNumbers XInternalConnectionNumbers_dylibloader_orig_xlib +#define XProcessInternalConnection XProcessInternalConnection_dylibloader_orig_xlib +#define XAddConnectionWatch XAddConnectionWatch_dylibloader_orig_xlib +#define XRemoveConnectionWatch XRemoveConnectionWatch_dylibloader_orig_xlib +#define XSetAuthorization XSetAuthorization_dylibloader_orig_xlib +#define _Xmbtowc _Xmbtowc_dylibloader_orig_xlib +#define _Xwctomb _Xwctomb_dylibloader_orig_xlib +#define XGetEventData XGetEventData_dylibloader_orig_xlib +#define XFreeEventData XFreeEventData_dylibloader_orig_xlib +#define XAllocClassHint XAllocClassHint_dylibloader_orig_xlib +#define XAllocIconSize XAllocIconSize_dylibloader_orig_xlib +#define XAllocSizeHints XAllocSizeHints_dylibloader_orig_xlib +#define XAllocStandardColormap XAllocStandardColormap_dylibloader_orig_xlib +#define XAllocWMHints XAllocWMHints_dylibloader_orig_xlib +#define XClipBox XClipBox_dylibloader_orig_xlib +#define XCreateRegion XCreateRegion_dylibloader_orig_xlib +#define XDefaultString XDefaultString_dylibloader_orig_xlib +#define XDeleteContext XDeleteContext_dylibloader_orig_xlib +#define XDestroyRegion XDestroyRegion_dylibloader_orig_xlib +#define XEmptyRegion XEmptyRegion_dylibloader_orig_xlib +#define XEqualRegion XEqualRegion_dylibloader_orig_xlib +#define XFindContext XFindContext_dylibloader_orig_xlib +#define XGetClassHint XGetClassHint_dylibloader_orig_xlib +#define XGetIconSizes XGetIconSizes_dylibloader_orig_xlib +#define XGetNormalHints XGetNormalHints_dylibloader_orig_xlib +#define XGetRGBColormaps XGetRGBColormaps_dylibloader_orig_xlib +#define XGetSizeHints XGetSizeHints_dylibloader_orig_xlib +#define XGetStandardColormap XGetStandardColormap_dylibloader_orig_xlib +#define XGetTextProperty XGetTextProperty_dylibloader_orig_xlib +#define XGetVisualInfo XGetVisualInfo_dylibloader_orig_xlib +#define XGetWMClientMachine XGetWMClientMachine_dylibloader_orig_xlib +#define XGetWMHints XGetWMHints_dylibloader_orig_xlib +#define XGetWMIconName XGetWMIconName_dylibloader_orig_xlib +#define XGetWMName XGetWMName_dylibloader_orig_xlib +#define XGetWMNormalHints XGetWMNormalHints_dylibloader_orig_xlib +#define XGetWMSizeHints XGetWMSizeHints_dylibloader_orig_xlib +#define XGetZoomHints XGetZoomHints_dylibloader_orig_xlib +#define XIntersectRegion XIntersectRegion_dylibloader_orig_xlib +#define XConvertCase XConvertCase_dylibloader_orig_xlib +#define XLookupString XLookupString_dylibloader_orig_xlib +#define XMatchVisualInfo XMatchVisualInfo_dylibloader_orig_xlib +#define XOffsetRegion XOffsetRegion_dylibloader_orig_xlib +#define XPointInRegion XPointInRegion_dylibloader_orig_xlib +#define XPolygonRegion XPolygonRegion_dylibloader_orig_xlib +#define XRectInRegion XRectInRegion_dylibloader_orig_xlib +#define XSaveContext XSaveContext_dylibloader_orig_xlib +#define XSetClassHint XSetClassHint_dylibloader_orig_xlib +#define XSetIconSizes XSetIconSizes_dylibloader_orig_xlib +#define XSetNormalHints XSetNormalHints_dylibloader_orig_xlib +#define XSetRGBColormaps XSetRGBColormaps_dylibloader_orig_xlib +#define XSetSizeHints XSetSizeHints_dylibloader_orig_xlib +#define XSetStandardProperties XSetStandardProperties_dylibloader_orig_xlib +#define XSetTextProperty XSetTextProperty_dylibloader_orig_xlib +#define XSetWMClientMachine XSetWMClientMachine_dylibloader_orig_xlib +#define XSetWMHints XSetWMHints_dylibloader_orig_xlib +#define XSetWMIconName XSetWMIconName_dylibloader_orig_xlib +#define XSetWMName XSetWMName_dylibloader_orig_xlib +#define XSetWMNormalHints XSetWMNormalHints_dylibloader_orig_xlib +#define XSetWMProperties XSetWMProperties_dylibloader_orig_xlib +#define XmbSetWMProperties XmbSetWMProperties_dylibloader_orig_xlib +#define Xutf8SetWMProperties Xutf8SetWMProperties_dylibloader_orig_xlib +#define XSetWMSizeHints XSetWMSizeHints_dylibloader_orig_xlib +#define XSetRegion XSetRegion_dylibloader_orig_xlib +#define XSetStandardColormap XSetStandardColormap_dylibloader_orig_xlib +#define XSetZoomHints XSetZoomHints_dylibloader_orig_xlib +#define XShrinkRegion XShrinkRegion_dylibloader_orig_xlib +#define XStringListToTextProperty XStringListToTextProperty_dylibloader_orig_xlib +#define XSubtractRegion XSubtractRegion_dylibloader_orig_xlib +#define XmbTextListToTextProperty XmbTextListToTextProperty_dylibloader_orig_xlib +#define XwcTextListToTextProperty XwcTextListToTextProperty_dylibloader_orig_xlib +#define Xutf8TextListToTextProperty Xutf8TextListToTextProperty_dylibloader_orig_xlib +#define XwcFreeStringList XwcFreeStringList_dylibloader_orig_xlib +#define XTextPropertyToStringList XTextPropertyToStringList_dylibloader_orig_xlib +#define XmbTextPropertyToTextList XmbTextPropertyToTextList_dylibloader_orig_xlib +#define XwcTextPropertyToTextList XwcTextPropertyToTextList_dylibloader_orig_xlib +#define Xutf8TextPropertyToTextList Xutf8TextPropertyToTextList_dylibloader_orig_xlib +#define XUnionRectWithRegion XUnionRectWithRegion_dylibloader_orig_xlib +#define XUnionRegion XUnionRegion_dylibloader_orig_xlib +#define XWMGeometry XWMGeometry_dylibloader_orig_xlib +#define XXorRegion XXorRegion_dylibloader_orig_xlib +#define XkbIgnoreExtension XkbIgnoreExtension_dylibloader_orig_xlib +#define XkbOpenDisplay XkbOpenDisplay_dylibloader_orig_xlib +#define XkbQueryExtension XkbQueryExtension_dylibloader_orig_xlib +#define XkbUseExtension XkbUseExtension_dylibloader_orig_xlib +#define XkbLibraryVersion XkbLibraryVersion_dylibloader_orig_xlib +#define XkbSetXlibControls XkbSetXlibControls_dylibloader_orig_xlib +#define XkbGetXlibControls XkbGetXlibControls_dylibloader_orig_xlib +#define XkbXlibControlsImplemented XkbXlibControlsImplemented_dylibloader_orig_xlib +#define XkbSetAtomFuncs XkbSetAtomFuncs_dylibloader_orig_xlib +#define XkbKeycodeToKeysym XkbKeycodeToKeysym_dylibloader_orig_xlib +#define XkbKeysymToModifiers XkbKeysymToModifiers_dylibloader_orig_xlib +#define XkbLookupKeySym XkbLookupKeySym_dylibloader_orig_xlib +#define XkbLookupKeyBinding XkbLookupKeyBinding_dylibloader_orig_xlib +#define XkbTranslateKeyCode XkbTranslateKeyCode_dylibloader_orig_xlib +#define XkbTranslateKeySym XkbTranslateKeySym_dylibloader_orig_xlib +#define XkbSetAutoRepeatRate XkbSetAutoRepeatRate_dylibloader_orig_xlib +#define XkbGetAutoRepeatRate XkbGetAutoRepeatRate_dylibloader_orig_xlib +#define XkbChangeEnabledControls XkbChangeEnabledControls_dylibloader_orig_xlib +#define XkbDeviceBell XkbDeviceBell_dylibloader_orig_xlib +#define XkbForceDeviceBell XkbForceDeviceBell_dylibloader_orig_xlib +#define XkbDeviceBellEvent XkbDeviceBellEvent_dylibloader_orig_xlib +#define XkbBell XkbBell_dylibloader_orig_xlib +#define XkbForceBell XkbForceBell_dylibloader_orig_xlib +#define XkbBellEvent XkbBellEvent_dylibloader_orig_xlib +#define XkbSelectEvents XkbSelectEvents_dylibloader_orig_xlib +#define XkbSelectEventDetails XkbSelectEventDetails_dylibloader_orig_xlib +#define XkbNoteMapChanges XkbNoteMapChanges_dylibloader_orig_xlib +#define XkbNoteNameChanges XkbNoteNameChanges_dylibloader_orig_xlib +#define XkbGetIndicatorState XkbGetIndicatorState_dylibloader_orig_xlib +#define XkbGetIndicatorMap XkbGetIndicatorMap_dylibloader_orig_xlib +#define XkbSetIndicatorMap XkbSetIndicatorMap_dylibloader_orig_xlib +#define XkbGetNamedIndicator XkbGetNamedIndicator_dylibloader_orig_xlib +#define XkbGetNamedDeviceIndicator XkbGetNamedDeviceIndicator_dylibloader_orig_xlib +#define XkbSetNamedIndicator XkbSetNamedIndicator_dylibloader_orig_xlib +#define XkbSetNamedDeviceIndicator XkbSetNamedDeviceIndicator_dylibloader_orig_xlib +#define XkbLockModifiers XkbLockModifiers_dylibloader_orig_xlib +#define XkbLatchModifiers XkbLatchModifiers_dylibloader_orig_xlib +#define XkbLockGroup XkbLockGroup_dylibloader_orig_xlib +#define XkbLatchGroup XkbLatchGroup_dylibloader_orig_xlib +#define XkbSetServerInternalMods XkbSetServerInternalMods_dylibloader_orig_xlib +#define XkbSetIgnoreLockMods XkbSetIgnoreLockMods_dylibloader_orig_xlib +#define XkbVirtualModsToReal XkbVirtualModsToReal_dylibloader_orig_xlib +#define XkbComputeEffectiveMap XkbComputeEffectiveMap_dylibloader_orig_xlib +#define XkbInitCanonicalKeyTypes XkbInitCanonicalKeyTypes_dylibloader_orig_xlib +#define XkbAllocKeyboard XkbAllocKeyboard_dylibloader_orig_xlib +#define XkbFreeKeyboard XkbFreeKeyboard_dylibloader_orig_xlib +#define XkbAllocClientMap XkbAllocClientMap_dylibloader_orig_xlib +#define XkbAllocServerMap XkbAllocServerMap_dylibloader_orig_xlib +#define XkbFreeClientMap XkbFreeClientMap_dylibloader_orig_xlib +#define XkbFreeServerMap XkbFreeServerMap_dylibloader_orig_xlib +#define XkbAddKeyType XkbAddKeyType_dylibloader_orig_xlib +#define XkbAllocIndicatorMaps XkbAllocIndicatorMaps_dylibloader_orig_xlib +#define XkbFreeIndicatorMaps XkbFreeIndicatorMaps_dylibloader_orig_xlib +#define XkbGetMap XkbGetMap_dylibloader_orig_xlib +#define XkbGetUpdatedMap XkbGetUpdatedMap_dylibloader_orig_xlib +#define XkbGetMapChanges XkbGetMapChanges_dylibloader_orig_xlib +#define XkbRefreshKeyboardMapping XkbRefreshKeyboardMapping_dylibloader_orig_xlib +#define XkbGetKeyTypes XkbGetKeyTypes_dylibloader_orig_xlib +#define XkbGetKeySyms XkbGetKeySyms_dylibloader_orig_xlib +#define XkbGetKeyActions XkbGetKeyActions_dylibloader_orig_xlib +#define XkbGetKeyBehaviors XkbGetKeyBehaviors_dylibloader_orig_xlib +#define XkbGetVirtualMods XkbGetVirtualMods_dylibloader_orig_xlib +#define XkbGetKeyExplicitComponents XkbGetKeyExplicitComponents_dylibloader_orig_xlib +#define XkbGetKeyModifierMap XkbGetKeyModifierMap_dylibloader_orig_xlib +#define XkbGetKeyVirtualModMap XkbGetKeyVirtualModMap_dylibloader_orig_xlib +#define XkbAllocControls XkbAllocControls_dylibloader_orig_xlib +#define XkbFreeControls XkbFreeControls_dylibloader_orig_xlib +#define XkbGetControls XkbGetControls_dylibloader_orig_xlib +#define XkbSetControls XkbSetControls_dylibloader_orig_xlib +#define XkbNoteControlsChanges XkbNoteControlsChanges_dylibloader_orig_xlib +#define XkbAllocCompatMap XkbAllocCompatMap_dylibloader_orig_xlib +#define XkbFreeCompatMap XkbFreeCompatMap_dylibloader_orig_xlib +#define XkbGetCompatMap XkbGetCompatMap_dylibloader_orig_xlib +#define XkbSetCompatMap XkbSetCompatMap_dylibloader_orig_xlib +#define XkbAllocNames XkbAllocNames_dylibloader_orig_xlib +#define XkbGetNames XkbGetNames_dylibloader_orig_xlib +#define XkbSetNames XkbSetNames_dylibloader_orig_xlib +#define XkbChangeNames XkbChangeNames_dylibloader_orig_xlib +#define XkbFreeNames XkbFreeNames_dylibloader_orig_xlib +#define XkbGetState XkbGetState_dylibloader_orig_xlib +#define XkbSetMap XkbSetMap_dylibloader_orig_xlib +#define XkbChangeMap XkbChangeMap_dylibloader_orig_xlib +#define XkbSetDetectableAutoRepeat XkbSetDetectableAutoRepeat_dylibloader_orig_xlib +#define XkbGetDetectableAutoRepeat XkbGetDetectableAutoRepeat_dylibloader_orig_xlib +#define XkbSetAutoResetControls XkbSetAutoResetControls_dylibloader_orig_xlib +#define XkbGetAutoResetControls XkbGetAutoResetControls_dylibloader_orig_xlib +#define XkbSetPerClientControls XkbSetPerClientControls_dylibloader_orig_xlib +#define XkbGetPerClientControls XkbGetPerClientControls_dylibloader_orig_xlib +#define XkbCopyKeyType XkbCopyKeyType_dylibloader_orig_xlib +#define XkbCopyKeyTypes XkbCopyKeyTypes_dylibloader_orig_xlib +#define XkbResizeKeyType XkbResizeKeyType_dylibloader_orig_xlib +#define XkbResizeKeySyms XkbResizeKeySyms_dylibloader_orig_xlib +#define XkbResizeKeyActions XkbResizeKeyActions_dylibloader_orig_xlib +#define XkbChangeTypesOfKey XkbChangeTypesOfKey_dylibloader_orig_xlib +#define XkbChangeKeycodeRange XkbChangeKeycodeRange_dylibloader_orig_xlib +#define XkbListComponents XkbListComponents_dylibloader_orig_xlib +#define XkbFreeComponentList XkbFreeComponentList_dylibloader_orig_xlib +#define XkbGetKeyboard XkbGetKeyboard_dylibloader_orig_xlib +#define XkbGetKeyboardByName XkbGetKeyboardByName_dylibloader_orig_xlib +#define XkbKeyTypesForCoreSymbols XkbKeyTypesForCoreSymbols_dylibloader_orig_xlib +#define XkbApplyCompatMapToKey XkbApplyCompatMapToKey_dylibloader_orig_xlib +#define XkbUpdateMapFromCore XkbUpdateMapFromCore_dylibloader_orig_xlib +#define XkbAddDeviceLedInfo XkbAddDeviceLedInfo_dylibloader_orig_xlib +#define XkbResizeDeviceButtonActions XkbResizeDeviceButtonActions_dylibloader_orig_xlib +#define XkbAllocDeviceInfo XkbAllocDeviceInfo_dylibloader_orig_xlib +#define XkbFreeDeviceInfo XkbFreeDeviceInfo_dylibloader_orig_xlib +#define XkbNoteDeviceChanges XkbNoteDeviceChanges_dylibloader_orig_xlib +#define XkbGetDeviceInfo XkbGetDeviceInfo_dylibloader_orig_xlib +#define XkbGetDeviceInfoChanges XkbGetDeviceInfoChanges_dylibloader_orig_xlib +#define XkbGetDeviceButtonActions XkbGetDeviceButtonActions_dylibloader_orig_xlib +#define XkbGetDeviceLedInfo XkbGetDeviceLedInfo_dylibloader_orig_xlib +#define XkbSetDeviceInfo XkbSetDeviceInfo_dylibloader_orig_xlib +#define XkbChangeDeviceInfo XkbChangeDeviceInfo_dylibloader_orig_xlib +#define XkbSetDeviceLedInfo XkbSetDeviceLedInfo_dylibloader_orig_xlib +#define XkbSetDeviceButtonActions XkbSetDeviceButtonActions_dylibloader_orig_xlib +#define XkbToControl XkbToControl_dylibloader_orig_xlib +#define XkbSetDebuggingFlags XkbSetDebuggingFlags_dylibloader_orig_xlib +#define XkbApplyVirtualModChanges XkbApplyVirtualModChanges_dylibloader_orig_xlib +#define XkbUpdateActionVirtualMods XkbUpdateActionVirtualMods_dylibloader_orig_xlib +#define XkbUpdateKeyTypeVirtualMods XkbUpdateKeyTypeVirtualMods_dylibloader_orig_xlib +#include "thirdparty/linuxbsd_headers/X11/Xlib.h" +#include "thirdparty/linuxbsd_headers/X11/Xutil.h" +#include "thirdparty/linuxbsd_headers/X11/XKBlib.h" +#undef _Xmblen +#undef XLoadQueryFont +#undef XQueryFont +#undef XGetMotionEvents +#undef XDeleteModifiermapEntry +#undef XGetModifierMapping +#undef XInsertModifiermapEntry +#undef XNewModifiermap +#undef XCreateImage +#undef XInitImage +#undef XGetImage +#undef XGetSubImage +#undef XOpenDisplay +#undef XrmInitialize +#undef XFetchBytes +#undef XFetchBuffer +#undef XGetAtomName +#undef XGetAtomNames +#undef XGetDefault +#undef XDisplayName +#undef XKeysymToString +#undef XSynchronize +#undef XSetAfterFunction +#undef XInternAtom +#undef XInternAtoms +#undef XCopyColormapAndFree +#undef XCreateColormap +#undef XCreatePixmapCursor +#undef XCreateGlyphCursor +#undef XCreateFontCursor +#undef XLoadFont +#undef XCreateGC +#undef XGContextFromGC +#undef XFlushGC +#undef XCreatePixmap +#undef XCreateBitmapFromData +#undef XCreatePixmapFromBitmapData +#undef XCreateSimpleWindow +#undef XGetSelectionOwner +#undef XCreateWindow +#undef XListInstalledColormaps +#undef XListFonts +#undef XListFontsWithInfo +#undef XGetFontPath +#undef XListExtensions +#undef XListProperties +#undef XListHosts +#undef XKeycodeToKeysym +#undef XLookupKeysym +#undef XGetKeyboardMapping +#undef XStringToKeysym +#undef XMaxRequestSize +#undef XExtendedMaxRequestSize +#undef XResourceManagerString +#undef XScreenResourceString +#undef XDisplayMotionBufferSize +#undef XVisualIDFromVisual +#undef XInitThreads +#undef XLockDisplay +#undef XUnlockDisplay +#undef XInitExtension +#undef XAddExtension +#undef XFindOnExtensionList +#undef XEHeadOfExtensionList +#undef XRootWindow +#undef XDefaultRootWindow +#undef XRootWindowOfScreen +#undef XDefaultVisual +#undef XDefaultVisualOfScreen +#undef XDefaultGC +#undef XDefaultGCOfScreen +#undef XBlackPixel +#undef XWhitePixel +#undef XAllPlanes +#undef XBlackPixelOfScreen +#undef XWhitePixelOfScreen +#undef XNextRequest +#undef XLastKnownRequestProcessed +#undef XServerVendor +#undef XDisplayString +#undef XDefaultColormap +#undef XDefaultColormapOfScreen +#undef XDisplayOfScreen +#undef XScreenOfDisplay +#undef XDefaultScreenOfDisplay +#undef XEventMaskOfScreen +#undef XScreenNumberOfScreen +#undef XSetErrorHandler +#undef XSetIOErrorHandler +#undef XListPixmapFormats +#undef XListDepths +#undef XReconfigureWMWindow +#undef XGetWMProtocols +#undef XSetWMProtocols +#undef XIconifyWindow +#undef XWithdrawWindow +#undef XGetCommand +#undef XGetWMColormapWindows +#undef XSetWMColormapWindows +#undef XFreeStringList +#undef XSetTransientForHint +#undef XActivateScreenSaver +#undef XAddHost +#undef XAddHosts +#undef XAddToExtensionList +#undef XAddToSaveSet +#undef XAllocColor +#undef XAllocColorCells +#undef XAllocColorPlanes +#undef XAllocNamedColor +#undef XAllowEvents +#undef XAutoRepeatOff +#undef XAutoRepeatOn +#undef XBell +#undef XBitmapBitOrder +#undef XBitmapPad +#undef XBitmapUnit +#undef XCellsOfScreen +#undef XChangeActivePointerGrab +#undef XChangeGC +#undef XChangeKeyboardControl +#undef XChangeKeyboardMapping +#undef XChangePointerControl +#undef XChangeProperty +#undef XChangeSaveSet +#undef XChangeWindowAttributes +#undef XCheckIfEvent +#undef XCheckMaskEvent +#undef XCheckTypedEvent +#undef XCheckTypedWindowEvent +#undef XCheckWindowEvent +#undef XCirculateSubwindows +#undef XCirculateSubwindowsDown +#undef XCirculateSubwindowsUp +#undef XClearArea +#undef XClearWindow +#undef XCloseDisplay +#undef XConfigureWindow +#undef XConnectionNumber +#undef XConvertSelection +#undef XCopyArea +#undef XCopyGC +#undef XCopyPlane +#undef XDefaultDepth +#undef XDefaultDepthOfScreen +#undef XDefaultScreen +#undef XDefineCursor +#undef XDeleteProperty +#undef XDestroyWindow +#undef XDestroySubwindows +#undef XDoesBackingStore +#undef XDoesSaveUnders +#undef XDisableAccessControl +#undef XDisplayCells +#undef XDisplayHeight +#undef XDisplayHeightMM +#undef XDisplayKeycodes +#undef XDisplayPlanes +#undef XDisplayWidth +#undef XDisplayWidthMM +#undef XDrawArc +#undef XDrawArcs +#undef XDrawImageString +#undef XDrawImageString16 +#undef XDrawLine +#undef XDrawLines +#undef XDrawPoint +#undef XDrawPoints +#undef XDrawRectangle +#undef XDrawRectangles +#undef XDrawSegments +#undef XDrawString +#undef XDrawString16 +#undef XDrawText +#undef XDrawText16 +#undef XEnableAccessControl +#undef XEventsQueued +#undef XFetchName +#undef XFillArc +#undef XFillArcs +#undef XFillPolygon +#undef XFillRectangle +#undef XFillRectangles +#undef XFlush +#undef XForceScreenSaver +#undef XFree +#undef XFreeColormap +#undef XFreeColors +#undef XFreeCursor +#undef XFreeExtensionList +#undef XFreeFont +#undef XFreeFontInfo +#undef XFreeFontNames +#undef XFreeFontPath +#undef XFreeGC +#undef XFreeModifiermap +#undef XFreePixmap +#undef XGeometry +#undef XGetErrorDatabaseText +#undef XGetErrorText +#undef XGetFontProperty +#undef XGetGCValues +#undef XGetGeometry +#undef XGetIconName +#undef XGetInputFocus +#undef XGetKeyboardControl +#undef XGetPointerControl +#undef XGetPointerMapping +#undef XGetScreenSaver +#undef XGetTransientForHint +#undef XGetWindowProperty +#undef XGetWindowAttributes +#undef XGrabButton +#undef XGrabKey +#undef XGrabKeyboard +#undef XGrabPointer +#undef XGrabServer +#undef XHeightMMOfScreen +#undef XHeightOfScreen +#undef XIfEvent +#undef XImageByteOrder +#undef XInstallColormap +#undef XKeysymToKeycode +#undef XKillClient +#undef XLookupColor +#undef XLowerWindow +#undef XMapRaised +#undef XMapSubwindows +#undef XMapWindow +#undef XMaskEvent +#undef XMaxCmapsOfScreen +#undef XMinCmapsOfScreen +#undef XMoveResizeWindow +#undef XMoveWindow +#undef XNextEvent +#undef XNoOp +#undef XParseColor +#undef XParseGeometry +#undef XPeekEvent +#undef XPeekIfEvent +#undef XPending +#undef XPlanesOfScreen +#undef XProtocolRevision +#undef XProtocolVersion +#undef XPutBackEvent +#undef XPutImage +#undef XQLength +#undef XQueryBestCursor +#undef XQueryBestSize +#undef XQueryBestStipple +#undef XQueryBestTile +#undef XQueryColor +#undef XQueryColors +#undef XQueryExtension +#undef XQueryKeymap +#undef XQueryPointer +#undef XQueryTextExtents +#undef XQueryTextExtents16 +#undef XQueryTree +#undef XRaiseWindow +#undef XReadBitmapFile +#undef XReadBitmapFileData +#undef XRebindKeysym +#undef XRecolorCursor +#undef XRefreshKeyboardMapping +#undef XRemoveFromSaveSet +#undef XRemoveHost +#undef XRemoveHosts +#undef XReparentWindow +#undef XResetScreenSaver +#undef XResizeWindow +#undef XRestackWindows +#undef XRotateBuffers +#undef XRotateWindowProperties +#undef XScreenCount +#undef XSelectInput +#undef XSendEvent +#undef XSetAccessControl +#undef XSetArcMode +#undef XSetBackground +#undef XSetClipMask +#undef XSetClipOrigin +#undef XSetClipRectangles +#undef XSetCloseDownMode +#undef XSetCommand +#undef XSetDashes +#undef XSetFillRule +#undef XSetFillStyle +#undef XSetFont +#undef XSetFontPath +#undef XSetForeground +#undef XSetFunction +#undef XSetGraphicsExposures +#undef XSetIconName +#undef XSetInputFocus +#undef XSetLineAttributes +#undef XSetModifierMapping +#undef XSetPlaneMask +#undef XSetPointerMapping +#undef XSetScreenSaver +#undef XSetSelectionOwner +#undef XSetState +#undef XSetStipple +#undef XSetSubwindowMode +#undef XSetTSOrigin +#undef XSetTile +#undef XSetWindowBackground +#undef XSetWindowBackgroundPixmap +#undef XSetWindowBorder +#undef XSetWindowBorderPixmap +#undef XSetWindowBorderWidth +#undef XSetWindowColormap +#undef XStoreBuffer +#undef XStoreBytes +#undef XStoreColor +#undef XStoreColors +#undef XStoreName +#undef XStoreNamedColor +#undef XSync +#undef XTextExtents +#undef XTextExtents16 +#undef XTextWidth +#undef XTextWidth16 +#undef XTranslateCoordinates +#undef XUndefineCursor +#undef XUngrabButton +#undef XUngrabKey +#undef XUngrabKeyboard +#undef XUngrabPointer +#undef XUngrabServer +#undef XUninstallColormap +#undef XUnloadFont +#undef XUnmapSubwindows +#undef XUnmapWindow +#undef XVendorRelease +#undef XWarpPointer +#undef XWidthMMOfScreen +#undef XWidthOfScreen +#undef XWindowEvent +#undef XWriteBitmapFile +#undef XSupportsLocale +#undef XSetLocaleModifiers +#undef XOpenOM +#undef XCloseOM +#undef XSetOMValues +#undef XGetOMValues +#undef XDisplayOfOM +#undef XLocaleOfOM +#undef XCreateOC +#undef XDestroyOC +#undef XOMOfOC +#undef XSetOCValues +#undef XGetOCValues +#undef XCreateFontSet +#undef XFreeFontSet +#undef XFontsOfFontSet +#undef XBaseFontNameListOfFontSet +#undef XLocaleOfFontSet +#undef XContextDependentDrawing +#undef XDirectionalDependentDrawing +#undef XContextualDrawing +#undef XExtentsOfFontSet +#undef XmbTextEscapement +#undef XwcTextEscapement +#undef Xutf8TextEscapement +#undef XmbTextExtents +#undef XwcTextExtents +#undef Xutf8TextExtents +#undef XmbTextPerCharExtents +#undef XwcTextPerCharExtents +#undef Xutf8TextPerCharExtents +#undef XmbDrawText +#undef XwcDrawText +#undef Xutf8DrawText +#undef XmbDrawString +#undef XwcDrawString +#undef Xutf8DrawString +#undef XmbDrawImageString +#undef XwcDrawImageString +#undef Xutf8DrawImageString +#undef XOpenIM +#undef XCloseIM +#undef XGetIMValues +#undef XSetIMValues +#undef XDisplayOfIM +#undef XLocaleOfIM +#undef XCreateIC +#undef XDestroyIC +#undef XSetICFocus +#undef XUnsetICFocus +#undef XwcResetIC +#undef XmbResetIC +#undef Xutf8ResetIC +#undef XSetICValues +#undef XGetICValues +#undef XIMOfIC +#undef XFilterEvent +#undef XmbLookupString +#undef XwcLookupString +#undef Xutf8LookupString +#undef XVaCreateNestedList +#undef XRegisterIMInstantiateCallback +#undef XUnregisterIMInstantiateCallback +#undef XInternalConnectionNumbers +#undef XProcessInternalConnection +#undef XAddConnectionWatch +#undef XRemoveConnectionWatch +#undef XSetAuthorization +#undef _Xmbtowc +#undef _Xwctomb +#undef XGetEventData +#undef XFreeEventData +#undef XAllocClassHint +#undef XAllocIconSize +#undef XAllocSizeHints +#undef XAllocStandardColormap +#undef XAllocWMHints +#undef XClipBox +#undef XCreateRegion +#undef XDefaultString +#undef XDeleteContext +#undef XDestroyRegion +#undef XEmptyRegion +#undef XEqualRegion +#undef XFindContext +#undef XGetClassHint +#undef XGetIconSizes +#undef XGetNormalHints +#undef XGetRGBColormaps +#undef XGetSizeHints +#undef XGetStandardColormap +#undef XGetTextProperty +#undef XGetVisualInfo +#undef XGetWMClientMachine +#undef XGetWMHints +#undef XGetWMIconName +#undef XGetWMName +#undef XGetWMNormalHints +#undef XGetWMSizeHints +#undef XGetZoomHints +#undef XIntersectRegion +#undef XConvertCase +#undef XLookupString +#undef XMatchVisualInfo +#undef XOffsetRegion +#undef XPointInRegion +#undef XPolygonRegion +#undef XRectInRegion +#undef XSaveContext +#undef XSetClassHint +#undef XSetIconSizes +#undef XSetNormalHints +#undef XSetRGBColormaps +#undef XSetSizeHints +#undef XSetStandardProperties +#undef XSetTextProperty +#undef XSetWMClientMachine +#undef XSetWMHints +#undef XSetWMIconName +#undef XSetWMName +#undef XSetWMNormalHints +#undef XSetWMProperties +#undef XmbSetWMProperties +#undef Xutf8SetWMProperties +#undef XSetWMSizeHints +#undef XSetRegion +#undef XSetStandardColormap +#undef XSetZoomHints +#undef XShrinkRegion +#undef XStringListToTextProperty +#undef XSubtractRegion +#undef XmbTextListToTextProperty +#undef XwcTextListToTextProperty +#undef Xutf8TextListToTextProperty +#undef XwcFreeStringList +#undef XTextPropertyToStringList +#undef XmbTextPropertyToTextList +#undef XwcTextPropertyToTextList +#undef Xutf8TextPropertyToTextList +#undef XUnionRectWithRegion +#undef XUnionRegion +#undef XWMGeometry +#undef XXorRegion +#undef XkbIgnoreExtension +#undef XkbOpenDisplay +#undef XkbQueryExtension +#undef XkbUseExtension +#undef XkbLibraryVersion +#undef XkbSetXlibControls +#undef XkbGetXlibControls +#undef XkbXlibControlsImplemented +#undef XkbSetAtomFuncs +#undef XkbKeycodeToKeysym +#undef XkbKeysymToModifiers +#undef XkbLookupKeySym +#undef XkbLookupKeyBinding +#undef XkbTranslateKeyCode +#undef XkbTranslateKeySym +#undef XkbSetAutoRepeatRate +#undef XkbGetAutoRepeatRate +#undef XkbChangeEnabledControls +#undef XkbDeviceBell +#undef XkbForceDeviceBell +#undef XkbDeviceBellEvent +#undef XkbBell +#undef XkbForceBell +#undef XkbBellEvent +#undef XkbSelectEvents +#undef XkbSelectEventDetails +#undef XkbNoteMapChanges +#undef XkbNoteNameChanges +#undef XkbGetIndicatorState +#undef XkbGetIndicatorMap +#undef XkbSetIndicatorMap +#undef XkbGetNamedIndicator +#undef XkbGetNamedDeviceIndicator +#undef XkbSetNamedIndicator +#undef XkbSetNamedDeviceIndicator +#undef XkbLockModifiers +#undef XkbLatchModifiers +#undef XkbLockGroup +#undef XkbLatchGroup +#undef XkbSetServerInternalMods +#undef XkbSetIgnoreLockMods +#undef XkbVirtualModsToReal +#undef XkbComputeEffectiveMap +#undef XkbInitCanonicalKeyTypes +#undef XkbAllocKeyboard +#undef XkbFreeKeyboard +#undef XkbAllocClientMap +#undef XkbAllocServerMap +#undef XkbFreeClientMap +#undef XkbFreeServerMap +#undef XkbAddKeyType +#undef XkbAllocIndicatorMaps +#undef XkbFreeIndicatorMaps +#undef XkbGetMap +#undef XkbGetUpdatedMap +#undef XkbGetMapChanges +#undef XkbRefreshKeyboardMapping +#undef XkbGetKeyTypes +#undef XkbGetKeySyms +#undef XkbGetKeyActions +#undef XkbGetKeyBehaviors +#undef XkbGetVirtualMods +#undef XkbGetKeyExplicitComponents +#undef XkbGetKeyModifierMap +#undef XkbGetKeyVirtualModMap +#undef XkbAllocControls +#undef XkbFreeControls +#undef XkbGetControls +#undef XkbSetControls +#undef XkbNoteControlsChanges +#undef XkbAllocCompatMap +#undef XkbFreeCompatMap +#undef XkbGetCompatMap +#undef XkbSetCompatMap +#undef XkbAllocNames +#undef XkbGetNames +#undef XkbSetNames +#undef XkbChangeNames +#undef XkbFreeNames +#undef XkbGetState +#undef XkbSetMap +#undef XkbChangeMap +#undef XkbSetDetectableAutoRepeat +#undef XkbGetDetectableAutoRepeat +#undef XkbSetAutoResetControls +#undef XkbGetAutoResetControls +#undef XkbSetPerClientControls +#undef XkbGetPerClientControls +#undef XkbCopyKeyType +#undef XkbCopyKeyTypes +#undef XkbResizeKeyType +#undef XkbResizeKeySyms +#undef XkbResizeKeyActions +#undef XkbChangeTypesOfKey +#undef XkbChangeKeycodeRange +#undef XkbListComponents +#undef XkbFreeComponentList +#undef XkbGetKeyboard +#undef XkbGetKeyboardByName +#undef XkbKeyTypesForCoreSymbols +#undef XkbApplyCompatMapToKey +#undef XkbUpdateMapFromCore +#undef XkbAddDeviceLedInfo +#undef XkbResizeDeviceButtonActions +#undef XkbAllocDeviceInfo +#undef XkbFreeDeviceInfo +#undef XkbNoteDeviceChanges +#undef XkbGetDeviceInfo +#undef XkbGetDeviceInfoChanges +#undef XkbGetDeviceButtonActions +#undef XkbGetDeviceLedInfo +#undef XkbSetDeviceInfo +#undef XkbChangeDeviceInfo +#undef XkbSetDeviceLedInfo +#undef XkbSetDeviceButtonActions +#undef XkbToControl +#undef XkbSetDebuggingFlags +#undef XkbApplyVirtualModChanges +#undef XkbUpdateActionVirtualMods +#undef XkbUpdateKeyTypeVirtualMods +#ifdef __cplusplus +extern "C" { +#endif +#define _Xmblen _Xmblen_dylibloader_wrapper_xlib +#define XLoadQueryFont XLoadQueryFont_dylibloader_wrapper_xlib +#define XQueryFont XQueryFont_dylibloader_wrapper_xlib +#define XGetMotionEvents XGetMotionEvents_dylibloader_wrapper_xlib +#define XDeleteModifiermapEntry XDeleteModifiermapEntry_dylibloader_wrapper_xlib +#define XGetModifierMapping XGetModifierMapping_dylibloader_wrapper_xlib +#define XInsertModifiermapEntry XInsertModifiermapEntry_dylibloader_wrapper_xlib +#define XNewModifiermap XNewModifiermap_dylibloader_wrapper_xlib +#define XCreateImage XCreateImage_dylibloader_wrapper_xlib +#define XInitImage XInitImage_dylibloader_wrapper_xlib +#define XGetImage XGetImage_dylibloader_wrapper_xlib +#define XGetSubImage XGetSubImage_dylibloader_wrapper_xlib +#define XOpenDisplay XOpenDisplay_dylibloader_wrapper_xlib +#define XrmInitialize XrmInitialize_dylibloader_wrapper_xlib +#define XFetchBytes XFetchBytes_dylibloader_wrapper_xlib +#define XFetchBuffer XFetchBuffer_dylibloader_wrapper_xlib +#define XGetAtomName XGetAtomName_dylibloader_wrapper_xlib +#define XGetAtomNames XGetAtomNames_dylibloader_wrapper_xlib +#define XGetDefault XGetDefault_dylibloader_wrapper_xlib +#define XDisplayName XDisplayName_dylibloader_wrapper_xlib +#define XKeysymToString XKeysymToString_dylibloader_wrapper_xlib +#define XSynchronize XSynchronize_dylibloader_wrapper_xlib +#define XSetAfterFunction XSetAfterFunction_dylibloader_wrapper_xlib +#define XInternAtom XInternAtom_dylibloader_wrapper_xlib +#define XInternAtoms XInternAtoms_dylibloader_wrapper_xlib +#define XCopyColormapAndFree XCopyColormapAndFree_dylibloader_wrapper_xlib +#define XCreateColormap XCreateColormap_dylibloader_wrapper_xlib +#define XCreatePixmapCursor XCreatePixmapCursor_dylibloader_wrapper_xlib +#define XCreateGlyphCursor XCreateGlyphCursor_dylibloader_wrapper_xlib +#define XCreateFontCursor XCreateFontCursor_dylibloader_wrapper_xlib +#define XLoadFont XLoadFont_dylibloader_wrapper_xlib +#define XCreateGC XCreateGC_dylibloader_wrapper_xlib +#define XGContextFromGC XGContextFromGC_dylibloader_wrapper_xlib +#define XFlushGC XFlushGC_dylibloader_wrapper_xlib +#define XCreatePixmap XCreatePixmap_dylibloader_wrapper_xlib +#define XCreateBitmapFromData XCreateBitmapFromData_dylibloader_wrapper_xlib +#define XCreatePixmapFromBitmapData XCreatePixmapFromBitmapData_dylibloader_wrapper_xlib +#define XCreateSimpleWindow XCreateSimpleWindow_dylibloader_wrapper_xlib +#define XGetSelectionOwner XGetSelectionOwner_dylibloader_wrapper_xlib +#define XCreateWindow XCreateWindow_dylibloader_wrapper_xlib +#define XListInstalledColormaps XListInstalledColormaps_dylibloader_wrapper_xlib +#define XListFonts XListFonts_dylibloader_wrapper_xlib +#define XListFontsWithInfo XListFontsWithInfo_dylibloader_wrapper_xlib +#define XGetFontPath XGetFontPath_dylibloader_wrapper_xlib +#define XListExtensions XListExtensions_dylibloader_wrapper_xlib +#define XListProperties XListProperties_dylibloader_wrapper_xlib +#define XListHosts XListHosts_dylibloader_wrapper_xlib +#define XKeycodeToKeysym XKeycodeToKeysym_dylibloader_wrapper_xlib +#define XLookupKeysym XLookupKeysym_dylibloader_wrapper_xlib +#define XGetKeyboardMapping XGetKeyboardMapping_dylibloader_wrapper_xlib +#define XStringToKeysym XStringToKeysym_dylibloader_wrapper_xlib +#define XMaxRequestSize XMaxRequestSize_dylibloader_wrapper_xlib +#define XExtendedMaxRequestSize XExtendedMaxRequestSize_dylibloader_wrapper_xlib +#define XResourceManagerString XResourceManagerString_dylibloader_wrapper_xlib +#define XScreenResourceString XScreenResourceString_dylibloader_wrapper_xlib +#define XDisplayMotionBufferSize XDisplayMotionBufferSize_dylibloader_wrapper_xlib +#define XVisualIDFromVisual XVisualIDFromVisual_dylibloader_wrapper_xlib +#define XInitThreads XInitThreads_dylibloader_wrapper_xlib +#define XLockDisplay XLockDisplay_dylibloader_wrapper_xlib +#define XUnlockDisplay XUnlockDisplay_dylibloader_wrapper_xlib +#define XInitExtension XInitExtension_dylibloader_wrapper_xlib +#define XAddExtension XAddExtension_dylibloader_wrapper_xlib +#define XFindOnExtensionList XFindOnExtensionList_dylibloader_wrapper_xlib +#define XEHeadOfExtensionList XEHeadOfExtensionList_dylibloader_wrapper_xlib +#define XRootWindow XRootWindow_dylibloader_wrapper_xlib +#define XDefaultRootWindow XDefaultRootWindow_dylibloader_wrapper_xlib +#define XRootWindowOfScreen XRootWindowOfScreen_dylibloader_wrapper_xlib +#define XDefaultVisual XDefaultVisual_dylibloader_wrapper_xlib +#define XDefaultVisualOfScreen XDefaultVisualOfScreen_dylibloader_wrapper_xlib +#define XDefaultGC XDefaultGC_dylibloader_wrapper_xlib +#define XDefaultGCOfScreen XDefaultGCOfScreen_dylibloader_wrapper_xlib +#define XBlackPixel XBlackPixel_dylibloader_wrapper_xlib +#define XWhitePixel XWhitePixel_dylibloader_wrapper_xlib +#define XAllPlanes XAllPlanes_dylibloader_wrapper_xlib +#define XBlackPixelOfScreen XBlackPixelOfScreen_dylibloader_wrapper_xlib +#define XWhitePixelOfScreen XWhitePixelOfScreen_dylibloader_wrapper_xlib +#define XNextRequest XNextRequest_dylibloader_wrapper_xlib +#define XLastKnownRequestProcessed XLastKnownRequestProcessed_dylibloader_wrapper_xlib +#define XServerVendor XServerVendor_dylibloader_wrapper_xlib +#define XDisplayString XDisplayString_dylibloader_wrapper_xlib +#define XDefaultColormap XDefaultColormap_dylibloader_wrapper_xlib +#define XDefaultColormapOfScreen XDefaultColormapOfScreen_dylibloader_wrapper_xlib +#define XDisplayOfScreen XDisplayOfScreen_dylibloader_wrapper_xlib +#define XScreenOfDisplay XScreenOfDisplay_dylibloader_wrapper_xlib +#define XDefaultScreenOfDisplay XDefaultScreenOfDisplay_dylibloader_wrapper_xlib +#define XEventMaskOfScreen XEventMaskOfScreen_dylibloader_wrapper_xlib +#define XScreenNumberOfScreen XScreenNumberOfScreen_dylibloader_wrapper_xlib +#define XSetErrorHandler XSetErrorHandler_dylibloader_wrapper_xlib +#define XSetIOErrorHandler XSetIOErrorHandler_dylibloader_wrapper_xlib +#define XListPixmapFormats XListPixmapFormats_dylibloader_wrapper_xlib +#define XListDepths XListDepths_dylibloader_wrapper_xlib +#define XReconfigureWMWindow XReconfigureWMWindow_dylibloader_wrapper_xlib +#define XGetWMProtocols XGetWMProtocols_dylibloader_wrapper_xlib +#define XSetWMProtocols XSetWMProtocols_dylibloader_wrapper_xlib +#define XIconifyWindow XIconifyWindow_dylibloader_wrapper_xlib +#define XWithdrawWindow XWithdrawWindow_dylibloader_wrapper_xlib +#define XGetCommand XGetCommand_dylibloader_wrapper_xlib +#define XGetWMColormapWindows XGetWMColormapWindows_dylibloader_wrapper_xlib +#define XSetWMColormapWindows XSetWMColormapWindows_dylibloader_wrapper_xlib +#define XFreeStringList XFreeStringList_dylibloader_wrapper_xlib +#define XSetTransientForHint XSetTransientForHint_dylibloader_wrapper_xlib +#define XActivateScreenSaver XActivateScreenSaver_dylibloader_wrapper_xlib +#define XAddHost XAddHost_dylibloader_wrapper_xlib +#define XAddHosts XAddHosts_dylibloader_wrapper_xlib +#define XAddToExtensionList XAddToExtensionList_dylibloader_wrapper_xlib +#define XAddToSaveSet XAddToSaveSet_dylibloader_wrapper_xlib +#define XAllocColor XAllocColor_dylibloader_wrapper_xlib +#define XAllocColorCells XAllocColorCells_dylibloader_wrapper_xlib +#define XAllocColorPlanes XAllocColorPlanes_dylibloader_wrapper_xlib +#define XAllocNamedColor XAllocNamedColor_dylibloader_wrapper_xlib +#define XAllowEvents XAllowEvents_dylibloader_wrapper_xlib +#define XAutoRepeatOff XAutoRepeatOff_dylibloader_wrapper_xlib +#define XAutoRepeatOn XAutoRepeatOn_dylibloader_wrapper_xlib +#define XBell XBell_dylibloader_wrapper_xlib +#define XBitmapBitOrder XBitmapBitOrder_dylibloader_wrapper_xlib +#define XBitmapPad XBitmapPad_dylibloader_wrapper_xlib +#define XBitmapUnit XBitmapUnit_dylibloader_wrapper_xlib +#define XCellsOfScreen XCellsOfScreen_dylibloader_wrapper_xlib +#define XChangeActivePointerGrab XChangeActivePointerGrab_dylibloader_wrapper_xlib +#define XChangeGC XChangeGC_dylibloader_wrapper_xlib +#define XChangeKeyboardControl XChangeKeyboardControl_dylibloader_wrapper_xlib +#define XChangeKeyboardMapping XChangeKeyboardMapping_dylibloader_wrapper_xlib +#define XChangePointerControl XChangePointerControl_dylibloader_wrapper_xlib +#define XChangeProperty XChangeProperty_dylibloader_wrapper_xlib +#define XChangeSaveSet XChangeSaveSet_dylibloader_wrapper_xlib +#define XChangeWindowAttributes XChangeWindowAttributes_dylibloader_wrapper_xlib +#define XCheckIfEvent XCheckIfEvent_dylibloader_wrapper_xlib +#define XCheckMaskEvent XCheckMaskEvent_dylibloader_wrapper_xlib +#define XCheckTypedEvent XCheckTypedEvent_dylibloader_wrapper_xlib +#define XCheckTypedWindowEvent XCheckTypedWindowEvent_dylibloader_wrapper_xlib +#define XCheckWindowEvent XCheckWindowEvent_dylibloader_wrapper_xlib +#define XCirculateSubwindows XCirculateSubwindows_dylibloader_wrapper_xlib +#define XCirculateSubwindowsDown XCirculateSubwindowsDown_dylibloader_wrapper_xlib +#define XCirculateSubwindowsUp XCirculateSubwindowsUp_dylibloader_wrapper_xlib +#define XClearArea XClearArea_dylibloader_wrapper_xlib +#define XClearWindow XClearWindow_dylibloader_wrapper_xlib +#define XCloseDisplay XCloseDisplay_dylibloader_wrapper_xlib +#define XConfigureWindow XConfigureWindow_dylibloader_wrapper_xlib +#define XConnectionNumber XConnectionNumber_dylibloader_wrapper_xlib +#define XConvertSelection XConvertSelection_dylibloader_wrapper_xlib +#define XCopyArea XCopyArea_dylibloader_wrapper_xlib +#define XCopyGC XCopyGC_dylibloader_wrapper_xlib +#define XCopyPlane XCopyPlane_dylibloader_wrapper_xlib +#define XDefaultDepth XDefaultDepth_dylibloader_wrapper_xlib +#define XDefaultDepthOfScreen XDefaultDepthOfScreen_dylibloader_wrapper_xlib +#define XDefaultScreen XDefaultScreen_dylibloader_wrapper_xlib +#define XDefineCursor XDefineCursor_dylibloader_wrapper_xlib +#define XDeleteProperty XDeleteProperty_dylibloader_wrapper_xlib +#define XDestroyWindow XDestroyWindow_dylibloader_wrapper_xlib +#define XDestroySubwindows XDestroySubwindows_dylibloader_wrapper_xlib +#define XDoesBackingStore XDoesBackingStore_dylibloader_wrapper_xlib +#define XDoesSaveUnders XDoesSaveUnders_dylibloader_wrapper_xlib +#define XDisableAccessControl XDisableAccessControl_dylibloader_wrapper_xlib +#define XDisplayCells XDisplayCells_dylibloader_wrapper_xlib +#define XDisplayHeight XDisplayHeight_dylibloader_wrapper_xlib +#define XDisplayHeightMM XDisplayHeightMM_dylibloader_wrapper_xlib +#define XDisplayKeycodes XDisplayKeycodes_dylibloader_wrapper_xlib +#define XDisplayPlanes XDisplayPlanes_dylibloader_wrapper_xlib +#define XDisplayWidth XDisplayWidth_dylibloader_wrapper_xlib +#define XDisplayWidthMM XDisplayWidthMM_dylibloader_wrapper_xlib +#define XDrawArc XDrawArc_dylibloader_wrapper_xlib +#define XDrawArcs XDrawArcs_dylibloader_wrapper_xlib +#define XDrawImageString XDrawImageString_dylibloader_wrapper_xlib +#define XDrawImageString16 XDrawImageString16_dylibloader_wrapper_xlib +#define XDrawLine XDrawLine_dylibloader_wrapper_xlib +#define XDrawLines XDrawLines_dylibloader_wrapper_xlib +#define XDrawPoint XDrawPoint_dylibloader_wrapper_xlib +#define XDrawPoints XDrawPoints_dylibloader_wrapper_xlib +#define XDrawRectangle XDrawRectangle_dylibloader_wrapper_xlib +#define XDrawRectangles XDrawRectangles_dylibloader_wrapper_xlib +#define XDrawSegments XDrawSegments_dylibloader_wrapper_xlib +#define XDrawString XDrawString_dylibloader_wrapper_xlib +#define XDrawString16 XDrawString16_dylibloader_wrapper_xlib +#define XDrawText XDrawText_dylibloader_wrapper_xlib +#define XDrawText16 XDrawText16_dylibloader_wrapper_xlib +#define XEnableAccessControl XEnableAccessControl_dylibloader_wrapper_xlib +#define XEventsQueued XEventsQueued_dylibloader_wrapper_xlib +#define XFetchName XFetchName_dylibloader_wrapper_xlib +#define XFillArc XFillArc_dylibloader_wrapper_xlib +#define XFillArcs XFillArcs_dylibloader_wrapper_xlib +#define XFillPolygon XFillPolygon_dylibloader_wrapper_xlib +#define XFillRectangle XFillRectangle_dylibloader_wrapper_xlib +#define XFillRectangles XFillRectangles_dylibloader_wrapper_xlib +#define XFlush XFlush_dylibloader_wrapper_xlib +#define XForceScreenSaver XForceScreenSaver_dylibloader_wrapper_xlib +#define XFree XFree_dylibloader_wrapper_xlib +#define XFreeColormap XFreeColormap_dylibloader_wrapper_xlib +#define XFreeColors XFreeColors_dylibloader_wrapper_xlib +#define XFreeCursor XFreeCursor_dylibloader_wrapper_xlib +#define XFreeExtensionList XFreeExtensionList_dylibloader_wrapper_xlib +#define XFreeFont XFreeFont_dylibloader_wrapper_xlib +#define XFreeFontInfo XFreeFontInfo_dylibloader_wrapper_xlib +#define XFreeFontNames XFreeFontNames_dylibloader_wrapper_xlib +#define XFreeFontPath XFreeFontPath_dylibloader_wrapper_xlib +#define XFreeGC XFreeGC_dylibloader_wrapper_xlib +#define XFreeModifiermap XFreeModifiermap_dylibloader_wrapper_xlib +#define XFreePixmap XFreePixmap_dylibloader_wrapper_xlib +#define XGeometry XGeometry_dylibloader_wrapper_xlib +#define XGetErrorDatabaseText XGetErrorDatabaseText_dylibloader_wrapper_xlib +#define XGetErrorText XGetErrorText_dylibloader_wrapper_xlib +#define XGetFontProperty XGetFontProperty_dylibloader_wrapper_xlib +#define XGetGCValues XGetGCValues_dylibloader_wrapper_xlib +#define XGetGeometry XGetGeometry_dylibloader_wrapper_xlib +#define XGetIconName XGetIconName_dylibloader_wrapper_xlib +#define XGetInputFocus XGetInputFocus_dylibloader_wrapper_xlib +#define XGetKeyboardControl XGetKeyboardControl_dylibloader_wrapper_xlib +#define XGetPointerControl XGetPointerControl_dylibloader_wrapper_xlib +#define XGetPointerMapping XGetPointerMapping_dylibloader_wrapper_xlib +#define XGetScreenSaver XGetScreenSaver_dylibloader_wrapper_xlib +#define XGetTransientForHint XGetTransientForHint_dylibloader_wrapper_xlib +#define XGetWindowProperty XGetWindowProperty_dylibloader_wrapper_xlib +#define XGetWindowAttributes XGetWindowAttributes_dylibloader_wrapper_xlib +#define XGrabButton XGrabButton_dylibloader_wrapper_xlib +#define XGrabKey XGrabKey_dylibloader_wrapper_xlib +#define XGrabKeyboard XGrabKeyboard_dylibloader_wrapper_xlib +#define XGrabPointer XGrabPointer_dylibloader_wrapper_xlib +#define XGrabServer XGrabServer_dylibloader_wrapper_xlib +#define XHeightMMOfScreen XHeightMMOfScreen_dylibloader_wrapper_xlib +#define XHeightOfScreen XHeightOfScreen_dylibloader_wrapper_xlib +#define XIfEvent XIfEvent_dylibloader_wrapper_xlib +#define XImageByteOrder XImageByteOrder_dylibloader_wrapper_xlib +#define XInstallColormap XInstallColormap_dylibloader_wrapper_xlib +#define XKeysymToKeycode XKeysymToKeycode_dylibloader_wrapper_xlib +#define XKillClient XKillClient_dylibloader_wrapper_xlib +#define XLookupColor XLookupColor_dylibloader_wrapper_xlib +#define XLowerWindow XLowerWindow_dylibloader_wrapper_xlib +#define XMapRaised XMapRaised_dylibloader_wrapper_xlib +#define XMapSubwindows XMapSubwindows_dylibloader_wrapper_xlib +#define XMapWindow XMapWindow_dylibloader_wrapper_xlib +#define XMaskEvent XMaskEvent_dylibloader_wrapper_xlib +#define XMaxCmapsOfScreen XMaxCmapsOfScreen_dylibloader_wrapper_xlib +#define XMinCmapsOfScreen XMinCmapsOfScreen_dylibloader_wrapper_xlib +#define XMoveResizeWindow XMoveResizeWindow_dylibloader_wrapper_xlib +#define XMoveWindow XMoveWindow_dylibloader_wrapper_xlib +#define XNextEvent XNextEvent_dylibloader_wrapper_xlib +#define XNoOp XNoOp_dylibloader_wrapper_xlib +#define XParseColor XParseColor_dylibloader_wrapper_xlib +#define XParseGeometry XParseGeometry_dylibloader_wrapper_xlib +#define XPeekEvent XPeekEvent_dylibloader_wrapper_xlib +#define XPeekIfEvent XPeekIfEvent_dylibloader_wrapper_xlib +#define XPending XPending_dylibloader_wrapper_xlib +#define XPlanesOfScreen XPlanesOfScreen_dylibloader_wrapper_xlib +#define XProtocolRevision XProtocolRevision_dylibloader_wrapper_xlib +#define XProtocolVersion XProtocolVersion_dylibloader_wrapper_xlib +#define XPutBackEvent XPutBackEvent_dylibloader_wrapper_xlib +#define XPutImage XPutImage_dylibloader_wrapper_xlib +#define XQLength XQLength_dylibloader_wrapper_xlib +#define XQueryBestCursor XQueryBestCursor_dylibloader_wrapper_xlib +#define XQueryBestSize XQueryBestSize_dylibloader_wrapper_xlib +#define XQueryBestStipple XQueryBestStipple_dylibloader_wrapper_xlib +#define XQueryBestTile XQueryBestTile_dylibloader_wrapper_xlib +#define XQueryColor XQueryColor_dylibloader_wrapper_xlib +#define XQueryColors XQueryColors_dylibloader_wrapper_xlib +#define XQueryExtension XQueryExtension_dylibloader_wrapper_xlib +#define XQueryKeymap XQueryKeymap_dylibloader_wrapper_xlib +#define XQueryPointer XQueryPointer_dylibloader_wrapper_xlib +#define XQueryTextExtents XQueryTextExtents_dylibloader_wrapper_xlib +#define XQueryTextExtents16 XQueryTextExtents16_dylibloader_wrapper_xlib +#define XQueryTree XQueryTree_dylibloader_wrapper_xlib +#define XRaiseWindow XRaiseWindow_dylibloader_wrapper_xlib +#define XReadBitmapFile XReadBitmapFile_dylibloader_wrapper_xlib +#define XReadBitmapFileData XReadBitmapFileData_dylibloader_wrapper_xlib +#define XRebindKeysym XRebindKeysym_dylibloader_wrapper_xlib +#define XRecolorCursor XRecolorCursor_dylibloader_wrapper_xlib +#define XRefreshKeyboardMapping XRefreshKeyboardMapping_dylibloader_wrapper_xlib +#define XRemoveFromSaveSet XRemoveFromSaveSet_dylibloader_wrapper_xlib +#define XRemoveHost XRemoveHost_dylibloader_wrapper_xlib +#define XRemoveHosts XRemoveHosts_dylibloader_wrapper_xlib +#define XReparentWindow XReparentWindow_dylibloader_wrapper_xlib +#define XResetScreenSaver XResetScreenSaver_dylibloader_wrapper_xlib +#define XResizeWindow XResizeWindow_dylibloader_wrapper_xlib +#define XRestackWindows XRestackWindows_dylibloader_wrapper_xlib +#define XRotateBuffers XRotateBuffers_dylibloader_wrapper_xlib +#define XRotateWindowProperties XRotateWindowProperties_dylibloader_wrapper_xlib +#define XScreenCount XScreenCount_dylibloader_wrapper_xlib +#define XSelectInput XSelectInput_dylibloader_wrapper_xlib +#define XSendEvent XSendEvent_dylibloader_wrapper_xlib +#define XSetAccessControl XSetAccessControl_dylibloader_wrapper_xlib +#define XSetArcMode XSetArcMode_dylibloader_wrapper_xlib +#define XSetBackground XSetBackground_dylibloader_wrapper_xlib +#define XSetClipMask XSetClipMask_dylibloader_wrapper_xlib +#define XSetClipOrigin XSetClipOrigin_dylibloader_wrapper_xlib +#define XSetClipRectangles XSetClipRectangles_dylibloader_wrapper_xlib +#define XSetCloseDownMode XSetCloseDownMode_dylibloader_wrapper_xlib +#define XSetCommand XSetCommand_dylibloader_wrapper_xlib +#define XSetDashes XSetDashes_dylibloader_wrapper_xlib +#define XSetFillRule XSetFillRule_dylibloader_wrapper_xlib +#define XSetFillStyle XSetFillStyle_dylibloader_wrapper_xlib +#define XSetFont XSetFont_dylibloader_wrapper_xlib +#define XSetFontPath XSetFontPath_dylibloader_wrapper_xlib +#define XSetForeground XSetForeground_dylibloader_wrapper_xlib +#define XSetFunction XSetFunction_dylibloader_wrapper_xlib +#define XSetGraphicsExposures XSetGraphicsExposures_dylibloader_wrapper_xlib +#define XSetIconName XSetIconName_dylibloader_wrapper_xlib +#define XSetInputFocus XSetInputFocus_dylibloader_wrapper_xlib +#define XSetLineAttributes XSetLineAttributes_dylibloader_wrapper_xlib +#define XSetModifierMapping XSetModifierMapping_dylibloader_wrapper_xlib +#define XSetPlaneMask XSetPlaneMask_dylibloader_wrapper_xlib +#define XSetPointerMapping XSetPointerMapping_dylibloader_wrapper_xlib +#define XSetScreenSaver XSetScreenSaver_dylibloader_wrapper_xlib +#define XSetSelectionOwner XSetSelectionOwner_dylibloader_wrapper_xlib +#define XSetState XSetState_dylibloader_wrapper_xlib +#define XSetStipple XSetStipple_dylibloader_wrapper_xlib +#define XSetSubwindowMode XSetSubwindowMode_dylibloader_wrapper_xlib +#define XSetTSOrigin XSetTSOrigin_dylibloader_wrapper_xlib +#define XSetTile XSetTile_dylibloader_wrapper_xlib +#define XSetWindowBackground XSetWindowBackground_dylibloader_wrapper_xlib +#define XSetWindowBackgroundPixmap XSetWindowBackgroundPixmap_dylibloader_wrapper_xlib +#define XSetWindowBorder XSetWindowBorder_dylibloader_wrapper_xlib +#define XSetWindowBorderPixmap XSetWindowBorderPixmap_dylibloader_wrapper_xlib +#define XSetWindowBorderWidth XSetWindowBorderWidth_dylibloader_wrapper_xlib +#define XSetWindowColormap XSetWindowColormap_dylibloader_wrapper_xlib +#define XStoreBuffer XStoreBuffer_dylibloader_wrapper_xlib +#define XStoreBytes XStoreBytes_dylibloader_wrapper_xlib +#define XStoreColor XStoreColor_dylibloader_wrapper_xlib +#define XStoreColors XStoreColors_dylibloader_wrapper_xlib +#define XStoreName XStoreName_dylibloader_wrapper_xlib +#define XStoreNamedColor XStoreNamedColor_dylibloader_wrapper_xlib +#define XSync XSync_dylibloader_wrapper_xlib +#define XTextExtents XTextExtents_dylibloader_wrapper_xlib +#define XTextExtents16 XTextExtents16_dylibloader_wrapper_xlib +#define XTextWidth XTextWidth_dylibloader_wrapper_xlib +#define XTextWidth16 XTextWidth16_dylibloader_wrapper_xlib +#define XTranslateCoordinates XTranslateCoordinates_dylibloader_wrapper_xlib +#define XUndefineCursor XUndefineCursor_dylibloader_wrapper_xlib +#define XUngrabButton XUngrabButton_dylibloader_wrapper_xlib +#define XUngrabKey XUngrabKey_dylibloader_wrapper_xlib +#define XUngrabKeyboard XUngrabKeyboard_dylibloader_wrapper_xlib +#define XUngrabPointer XUngrabPointer_dylibloader_wrapper_xlib +#define XUngrabServer XUngrabServer_dylibloader_wrapper_xlib +#define XUninstallColormap XUninstallColormap_dylibloader_wrapper_xlib +#define XUnloadFont XUnloadFont_dylibloader_wrapper_xlib +#define XUnmapSubwindows XUnmapSubwindows_dylibloader_wrapper_xlib +#define XUnmapWindow XUnmapWindow_dylibloader_wrapper_xlib +#define XVendorRelease XVendorRelease_dylibloader_wrapper_xlib +#define XWarpPointer XWarpPointer_dylibloader_wrapper_xlib +#define XWidthMMOfScreen XWidthMMOfScreen_dylibloader_wrapper_xlib +#define XWidthOfScreen XWidthOfScreen_dylibloader_wrapper_xlib +#define XWindowEvent XWindowEvent_dylibloader_wrapper_xlib +#define XWriteBitmapFile XWriteBitmapFile_dylibloader_wrapper_xlib +#define XSupportsLocale XSupportsLocale_dylibloader_wrapper_xlib +#define XSetLocaleModifiers XSetLocaleModifiers_dylibloader_wrapper_xlib +#define XOpenOM XOpenOM_dylibloader_wrapper_xlib +#define XCloseOM XCloseOM_dylibloader_wrapper_xlib +#define XSetOMValues XSetOMValues_dylibloader_wrapper_xlib +#define XGetOMValues XGetOMValues_dylibloader_wrapper_xlib +#define XDisplayOfOM XDisplayOfOM_dylibloader_wrapper_xlib +#define XLocaleOfOM XLocaleOfOM_dylibloader_wrapper_xlib +#define XCreateOC XCreateOC_dylibloader_wrapper_xlib +#define XDestroyOC XDestroyOC_dylibloader_wrapper_xlib +#define XOMOfOC XOMOfOC_dylibloader_wrapper_xlib +#define XSetOCValues XSetOCValues_dylibloader_wrapper_xlib +#define XGetOCValues XGetOCValues_dylibloader_wrapper_xlib +#define XCreateFontSet XCreateFontSet_dylibloader_wrapper_xlib +#define XFreeFontSet XFreeFontSet_dylibloader_wrapper_xlib +#define XFontsOfFontSet XFontsOfFontSet_dylibloader_wrapper_xlib +#define XBaseFontNameListOfFontSet XBaseFontNameListOfFontSet_dylibloader_wrapper_xlib +#define XLocaleOfFontSet XLocaleOfFontSet_dylibloader_wrapper_xlib +#define XContextDependentDrawing XContextDependentDrawing_dylibloader_wrapper_xlib +#define XDirectionalDependentDrawing XDirectionalDependentDrawing_dylibloader_wrapper_xlib +#define XContextualDrawing XContextualDrawing_dylibloader_wrapper_xlib +#define XExtentsOfFontSet XExtentsOfFontSet_dylibloader_wrapper_xlib +#define XmbTextEscapement XmbTextEscapement_dylibloader_wrapper_xlib +#define XwcTextEscapement XwcTextEscapement_dylibloader_wrapper_xlib +#define Xutf8TextEscapement Xutf8TextEscapement_dylibloader_wrapper_xlib +#define XmbTextExtents XmbTextExtents_dylibloader_wrapper_xlib +#define XwcTextExtents XwcTextExtents_dylibloader_wrapper_xlib +#define Xutf8TextExtents Xutf8TextExtents_dylibloader_wrapper_xlib +#define XmbTextPerCharExtents XmbTextPerCharExtents_dylibloader_wrapper_xlib +#define XwcTextPerCharExtents XwcTextPerCharExtents_dylibloader_wrapper_xlib +#define Xutf8TextPerCharExtents Xutf8TextPerCharExtents_dylibloader_wrapper_xlib +#define XmbDrawText XmbDrawText_dylibloader_wrapper_xlib +#define XwcDrawText XwcDrawText_dylibloader_wrapper_xlib +#define Xutf8DrawText Xutf8DrawText_dylibloader_wrapper_xlib +#define XmbDrawString XmbDrawString_dylibloader_wrapper_xlib +#define XwcDrawString XwcDrawString_dylibloader_wrapper_xlib +#define Xutf8DrawString Xutf8DrawString_dylibloader_wrapper_xlib +#define XmbDrawImageString XmbDrawImageString_dylibloader_wrapper_xlib +#define XwcDrawImageString XwcDrawImageString_dylibloader_wrapper_xlib +#define Xutf8DrawImageString Xutf8DrawImageString_dylibloader_wrapper_xlib +#define XOpenIM XOpenIM_dylibloader_wrapper_xlib +#define XCloseIM XCloseIM_dylibloader_wrapper_xlib +#define XGetIMValues XGetIMValues_dylibloader_wrapper_xlib +#define XSetIMValues XSetIMValues_dylibloader_wrapper_xlib +#define XDisplayOfIM XDisplayOfIM_dylibloader_wrapper_xlib +#define XLocaleOfIM XLocaleOfIM_dylibloader_wrapper_xlib +#define XCreateIC XCreateIC_dylibloader_wrapper_xlib +#define XDestroyIC XDestroyIC_dylibloader_wrapper_xlib +#define XSetICFocus XSetICFocus_dylibloader_wrapper_xlib +#define XUnsetICFocus XUnsetICFocus_dylibloader_wrapper_xlib +#define XwcResetIC XwcResetIC_dylibloader_wrapper_xlib +#define XmbResetIC XmbResetIC_dylibloader_wrapper_xlib +#define Xutf8ResetIC Xutf8ResetIC_dylibloader_wrapper_xlib +#define XSetICValues XSetICValues_dylibloader_wrapper_xlib +#define XGetICValues XGetICValues_dylibloader_wrapper_xlib +#define XIMOfIC XIMOfIC_dylibloader_wrapper_xlib +#define XFilterEvent XFilterEvent_dylibloader_wrapper_xlib +#define XmbLookupString XmbLookupString_dylibloader_wrapper_xlib +#define XwcLookupString XwcLookupString_dylibloader_wrapper_xlib +#define Xutf8LookupString Xutf8LookupString_dylibloader_wrapper_xlib +#define XVaCreateNestedList XVaCreateNestedList_dylibloader_wrapper_xlib +#define XRegisterIMInstantiateCallback XRegisterIMInstantiateCallback_dylibloader_wrapper_xlib +#define XUnregisterIMInstantiateCallback XUnregisterIMInstantiateCallback_dylibloader_wrapper_xlib +#define XInternalConnectionNumbers XInternalConnectionNumbers_dylibloader_wrapper_xlib +#define XProcessInternalConnection XProcessInternalConnection_dylibloader_wrapper_xlib +#define XAddConnectionWatch XAddConnectionWatch_dylibloader_wrapper_xlib +#define XRemoveConnectionWatch XRemoveConnectionWatch_dylibloader_wrapper_xlib +#define XSetAuthorization XSetAuthorization_dylibloader_wrapper_xlib +#define _Xmbtowc _Xmbtowc_dylibloader_wrapper_xlib +#define _Xwctomb _Xwctomb_dylibloader_wrapper_xlib +#define XGetEventData XGetEventData_dylibloader_wrapper_xlib +#define XFreeEventData XFreeEventData_dylibloader_wrapper_xlib +#define XAllocClassHint XAllocClassHint_dylibloader_wrapper_xlib +#define XAllocIconSize XAllocIconSize_dylibloader_wrapper_xlib +#define XAllocSizeHints XAllocSizeHints_dylibloader_wrapper_xlib +#define XAllocStandardColormap XAllocStandardColormap_dylibloader_wrapper_xlib +#define XAllocWMHints XAllocWMHints_dylibloader_wrapper_xlib +#define XClipBox XClipBox_dylibloader_wrapper_xlib +#define XCreateRegion XCreateRegion_dylibloader_wrapper_xlib +#define XDefaultString XDefaultString_dylibloader_wrapper_xlib +#define XDeleteContext XDeleteContext_dylibloader_wrapper_xlib +#define XDestroyRegion XDestroyRegion_dylibloader_wrapper_xlib +#define XEmptyRegion XEmptyRegion_dylibloader_wrapper_xlib +#define XEqualRegion XEqualRegion_dylibloader_wrapper_xlib +#define XFindContext XFindContext_dylibloader_wrapper_xlib +#define XGetClassHint XGetClassHint_dylibloader_wrapper_xlib +#define XGetIconSizes XGetIconSizes_dylibloader_wrapper_xlib +#define XGetNormalHints XGetNormalHints_dylibloader_wrapper_xlib +#define XGetRGBColormaps XGetRGBColormaps_dylibloader_wrapper_xlib +#define XGetSizeHints XGetSizeHints_dylibloader_wrapper_xlib +#define XGetStandardColormap XGetStandardColormap_dylibloader_wrapper_xlib +#define XGetTextProperty XGetTextProperty_dylibloader_wrapper_xlib +#define XGetVisualInfo XGetVisualInfo_dylibloader_wrapper_xlib +#define XGetWMClientMachine XGetWMClientMachine_dylibloader_wrapper_xlib +#define XGetWMHints XGetWMHints_dylibloader_wrapper_xlib +#define XGetWMIconName XGetWMIconName_dylibloader_wrapper_xlib +#define XGetWMName XGetWMName_dylibloader_wrapper_xlib +#define XGetWMNormalHints XGetWMNormalHints_dylibloader_wrapper_xlib +#define XGetWMSizeHints XGetWMSizeHints_dylibloader_wrapper_xlib +#define XGetZoomHints XGetZoomHints_dylibloader_wrapper_xlib +#define XIntersectRegion XIntersectRegion_dylibloader_wrapper_xlib +#define XConvertCase XConvertCase_dylibloader_wrapper_xlib +#define XLookupString XLookupString_dylibloader_wrapper_xlib +#define XMatchVisualInfo XMatchVisualInfo_dylibloader_wrapper_xlib +#define XOffsetRegion XOffsetRegion_dylibloader_wrapper_xlib +#define XPointInRegion XPointInRegion_dylibloader_wrapper_xlib +#define XPolygonRegion XPolygonRegion_dylibloader_wrapper_xlib +#define XRectInRegion XRectInRegion_dylibloader_wrapper_xlib +#define XSaveContext XSaveContext_dylibloader_wrapper_xlib +#define XSetClassHint XSetClassHint_dylibloader_wrapper_xlib +#define XSetIconSizes XSetIconSizes_dylibloader_wrapper_xlib +#define XSetNormalHints XSetNormalHints_dylibloader_wrapper_xlib +#define XSetRGBColormaps XSetRGBColormaps_dylibloader_wrapper_xlib +#define XSetSizeHints XSetSizeHints_dylibloader_wrapper_xlib +#define XSetStandardProperties XSetStandardProperties_dylibloader_wrapper_xlib +#define XSetTextProperty XSetTextProperty_dylibloader_wrapper_xlib +#define XSetWMClientMachine XSetWMClientMachine_dylibloader_wrapper_xlib +#define XSetWMHints XSetWMHints_dylibloader_wrapper_xlib +#define XSetWMIconName XSetWMIconName_dylibloader_wrapper_xlib +#define XSetWMName XSetWMName_dylibloader_wrapper_xlib +#define XSetWMNormalHints XSetWMNormalHints_dylibloader_wrapper_xlib +#define XSetWMProperties XSetWMProperties_dylibloader_wrapper_xlib +#define XmbSetWMProperties XmbSetWMProperties_dylibloader_wrapper_xlib +#define Xutf8SetWMProperties Xutf8SetWMProperties_dylibloader_wrapper_xlib +#define XSetWMSizeHints XSetWMSizeHints_dylibloader_wrapper_xlib +#define XSetRegion XSetRegion_dylibloader_wrapper_xlib +#define XSetStandardColormap XSetStandardColormap_dylibloader_wrapper_xlib +#define XSetZoomHints XSetZoomHints_dylibloader_wrapper_xlib +#define XShrinkRegion XShrinkRegion_dylibloader_wrapper_xlib +#define XStringListToTextProperty XStringListToTextProperty_dylibloader_wrapper_xlib +#define XSubtractRegion XSubtractRegion_dylibloader_wrapper_xlib +#define XmbTextListToTextProperty XmbTextListToTextProperty_dylibloader_wrapper_xlib +#define XwcTextListToTextProperty XwcTextListToTextProperty_dylibloader_wrapper_xlib +#define Xutf8TextListToTextProperty Xutf8TextListToTextProperty_dylibloader_wrapper_xlib +#define XwcFreeStringList XwcFreeStringList_dylibloader_wrapper_xlib +#define XTextPropertyToStringList XTextPropertyToStringList_dylibloader_wrapper_xlib +#define XmbTextPropertyToTextList XmbTextPropertyToTextList_dylibloader_wrapper_xlib +#define XwcTextPropertyToTextList XwcTextPropertyToTextList_dylibloader_wrapper_xlib +#define Xutf8TextPropertyToTextList Xutf8TextPropertyToTextList_dylibloader_wrapper_xlib +#define XUnionRectWithRegion XUnionRectWithRegion_dylibloader_wrapper_xlib +#define XUnionRegion XUnionRegion_dylibloader_wrapper_xlib +#define XWMGeometry XWMGeometry_dylibloader_wrapper_xlib +#define XXorRegion XXorRegion_dylibloader_wrapper_xlib +#define XkbIgnoreExtension XkbIgnoreExtension_dylibloader_wrapper_xlib +#define XkbOpenDisplay XkbOpenDisplay_dylibloader_wrapper_xlib +#define XkbQueryExtension XkbQueryExtension_dylibloader_wrapper_xlib +#define XkbUseExtension XkbUseExtension_dylibloader_wrapper_xlib +#define XkbLibraryVersion XkbLibraryVersion_dylibloader_wrapper_xlib +#define XkbSetXlibControls XkbSetXlibControls_dylibloader_wrapper_xlib +#define XkbGetXlibControls XkbGetXlibControls_dylibloader_wrapper_xlib +#define XkbXlibControlsImplemented XkbXlibControlsImplemented_dylibloader_wrapper_xlib +#define XkbSetAtomFuncs XkbSetAtomFuncs_dylibloader_wrapper_xlib +#define XkbKeycodeToKeysym XkbKeycodeToKeysym_dylibloader_wrapper_xlib +#define XkbKeysymToModifiers XkbKeysymToModifiers_dylibloader_wrapper_xlib +#define XkbLookupKeySym XkbLookupKeySym_dylibloader_wrapper_xlib +#define XkbLookupKeyBinding XkbLookupKeyBinding_dylibloader_wrapper_xlib +#define XkbTranslateKeyCode XkbTranslateKeyCode_dylibloader_wrapper_xlib +#define XkbTranslateKeySym XkbTranslateKeySym_dylibloader_wrapper_xlib +#define XkbSetAutoRepeatRate XkbSetAutoRepeatRate_dylibloader_wrapper_xlib +#define XkbGetAutoRepeatRate XkbGetAutoRepeatRate_dylibloader_wrapper_xlib +#define XkbChangeEnabledControls XkbChangeEnabledControls_dylibloader_wrapper_xlib +#define XkbDeviceBell XkbDeviceBell_dylibloader_wrapper_xlib +#define XkbForceDeviceBell XkbForceDeviceBell_dylibloader_wrapper_xlib +#define XkbDeviceBellEvent XkbDeviceBellEvent_dylibloader_wrapper_xlib +#define XkbBell XkbBell_dylibloader_wrapper_xlib +#define XkbForceBell XkbForceBell_dylibloader_wrapper_xlib +#define XkbBellEvent XkbBellEvent_dylibloader_wrapper_xlib +#define XkbSelectEvents XkbSelectEvents_dylibloader_wrapper_xlib +#define XkbSelectEventDetails XkbSelectEventDetails_dylibloader_wrapper_xlib +#define XkbNoteMapChanges XkbNoteMapChanges_dylibloader_wrapper_xlib +#define XkbNoteNameChanges XkbNoteNameChanges_dylibloader_wrapper_xlib +#define XkbGetIndicatorState XkbGetIndicatorState_dylibloader_wrapper_xlib +#define XkbGetIndicatorMap XkbGetIndicatorMap_dylibloader_wrapper_xlib +#define XkbSetIndicatorMap XkbSetIndicatorMap_dylibloader_wrapper_xlib +#define XkbGetNamedIndicator XkbGetNamedIndicator_dylibloader_wrapper_xlib +#define XkbGetNamedDeviceIndicator XkbGetNamedDeviceIndicator_dylibloader_wrapper_xlib +#define XkbSetNamedIndicator XkbSetNamedIndicator_dylibloader_wrapper_xlib +#define XkbSetNamedDeviceIndicator XkbSetNamedDeviceIndicator_dylibloader_wrapper_xlib +#define XkbLockModifiers XkbLockModifiers_dylibloader_wrapper_xlib +#define XkbLatchModifiers XkbLatchModifiers_dylibloader_wrapper_xlib +#define XkbLockGroup XkbLockGroup_dylibloader_wrapper_xlib +#define XkbLatchGroup XkbLatchGroup_dylibloader_wrapper_xlib +#define XkbSetServerInternalMods XkbSetServerInternalMods_dylibloader_wrapper_xlib +#define XkbSetIgnoreLockMods XkbSetIgnoreLockMods_dylibloader_wrapper_xlib +#define XkbVirtualModsToReal XkbVirtualModsToReal_dylibloader_wrapper_xlib +#define XkbComputeEffectiveMap XkbComputeEffectiveMap_dylibloader_wrapper_xlib +#define XkbInitCanonicalKeyTypes XkbInitCanonicalKeyTypes_dylibloader_wrapper_xlib +#define XkbAllocKeyboard XkbAllocKeyboard_dylibloader_wrapper_xlib +#define XkbFreeKeyboard XkbFreeKeyboard_dylibloader_wrapper_xlib +#define XkbAllocClientMap XkbAllocClientMap_dylibloader_wrapper_xlib +#define XkbAllocServerMap XkbAllocServerMap_dylibloader_wrapper_xlib +#define XkbFreeClientMap XkbFreeClientMap_dylibloader_wrapper_xlib +#define XkbFreeServerMap XkbFreeServerMap_dylibloader_wrapper_xlib +#define XkbAddKeyType XkbAddKeyType_dylibloader_wrapper_xlib +#define XkbAllocIndicatorMaps XkbAllocIndicatorMaps_dylibloader_wrapper_xlib +#define XkbFreeIndicatorMaps XkbFreeIndicatorMaps_dylibloader_wrapper_xlib +#define XkbGetMap XkbGetMap_dylibloader_wrapper_xlib +#define XkbGetUpdatedMap XkbGetUpdatedMap_dylibloader_wrapper_xlib +#define XkbGetMapChanges XkbGetMapChanges_dylibloader_wrapper_xlib +#define XkbRefreshKeyboardMapping XkbRefreshKeyboardMapping_dylibloader_wrapper_xlib +#define XkbGetKeyTypes XkbGetKeyTypes_dylibloader_wrapper_xlib +#define XkbGetKeySyms XkbGetKeySyms_dylibloader_wrapper_xlib +#define XkbGetKeyActions XkbGetKeyActions_dylibloader_wrapper_xlib +#define XkbGetKeyBehaviors XkbGetKeyBehaviors_dylibloader_wrapper_xlib +#define XkbGetVirtualMods XkbGetVirtualMods_dylibloader_wrapper_xlib +#define XkbGetKeyExplicitComponents XkbGetKeyExplicitComponents_dylibloader_wrapper_xlib +#define XkbGetKeyModifierMap XkbGetKeyModifierMap_dylibloader_wrapper_xlib +#define XkbGetKeyVirtualModMap XkbGetKeyVirtualModMap_dylibloader_wrapper_xlib +#define XkbAllocControls XkbAllocControls_dylibloader_wrapper_xlib +#define XkbFreeControls XkbFreeControls_dylibloader_wrapper_xlib +#define XkbGetControls XkbGetControls_dylibloader_wrapper_xlib +#define XkbSetControls XkbSetControls_dylibloader_wrapper_xlib +#define XkbNoteControlsChanges XkbNoteControlsChanges_dylibloader_wrapper_xlib +#define XkbAllocCompatMap XkbAllocCompatMap_dylibloader_wrapper_xlib +#define XkbFreeCompatMap XkbFreeCompatMap_dylibloader_wrapper_xlib +#define XkbGetCompatMap XkbGetCompatMap_dylibloader_wrapper_xlib +#define XkbSetCompatMap XkbSetCompatMap_dylibloader_wrapper_xlib +#define XkbAllocNames XkbAllocNames_dylibloader_wrapper_xlib +#define XkbGetNames XkbGetNames_dylibloader_wrapper_xlib +#define XkbSetNames XkbSetNames_dylibloader_wrapper_xlib +#define XkbChangeNames XkbChangeNames_dylibloader_wrapper_xlib +#define XkbFreeNames XkbFreeNames_dylibloader_wrapper_xlib +#define XkbGetState XkbGetState_dylibloader_wrapper_xlib +#define XkbSetMap XkbSetMap_dylibloader_wrapper_xlib +#define XkbChangeMap XkbChangeMap_dylibloader_wrapper_xlib +#define XkbSetDetectableAutoRepeat XkbSetDetectableAutoRepeat_dylibloader_wrapper_xlib +#define XkbGetDetectableAutoRepeat XkbGetDetectableAutoRepeat_dylibloader_wrapper_xlib +#define XkbSetAutoResetControls XkbSetAutoResetControls_dylibloader_wrapper_xlib +#define XkbGetAutoResetControls XkbGetAutoResetControls_dylibloader_wrapper_xlib +#define XkbSetPerClientControls XkbSetPerClientControls_dylibloader_wrapper_xlib +#define XkbGetPerClientControls XkbGetPerClientControls_dylibloader_wrapper_xlib +#define XkbCopyKeyType XkbCopyKeyType_dylibloader_wrapper_xlib +#define XkbCopyKeyTypes XkbCopyKeyTypes_dylibloader_wrapper_xlib +#define XkbResizeKeyType XkbResizeKeyType_dylibloader_wrapper_xlib +#define XkbResizeKeySyms XkbResizeKeySyms_dylibloader_wrapper_xlib +#define XkbResizeKeyActions XkbResizeKeyActions_dylibloader_wrapper_xlib +#define XkbChangeTypesOfKey XkbChangeTypesOfKey_dylibloader_wrapper_xlib +#define XkbChangeKeycodeRange XkbChangeKeycodeRange_dylibloader_wrapper_xlib +#define XkbListComponents XkbListComponents_dylibloader_wrapper_xlib +#define XkbFreeComponentList XkbFreeComponentList_dylibloader_wrapper_xlib +#define XkbGetKeyboard XkbGetKeyboard_dylibloader_wrapper_xlib +#define XkbGetKeyboardByName XkbGetKeyboardByName_dylibloader_wrapper_xlib +#define XkbKeyTypesForCoreSymbols XkbKeyTypesForCoreSymbols_dylibloader_wrapper_xlib +#define XkbApplyCompatMapToKey XkbApplyCompatMapToKey_dylibloader_wrapper_xlib +#define XkbUpdateMapFromCore XkbUpdateMapFromCore_dylibloader_wrapper_xlib +#define XkbAddDeviceLedInfo XkbAddDeviceLedInfo_dylibloader_wrapper_xlib +#define XkbResizeDeviceButtonActions XkbResizeDeviceButtonActions_dylibloader_wrapper_xlib +#define XkbAllocDeviceInfo XkbAllocDeviceInfo_dylibloader_wrapper_xlib +#define XkbFreeDeviceInfo XkbFreeDeviceInfo_dylibloader_wrapper_xlib +#define XkbNoteDeviceChanges XkbNoteDeviceChanges_dylibloader_wrapper_xlib +#define XkbGetDeviceInfo XkbGetDeviceInfo_dylibloader_wrapper_xlib +#define XkbGetDeviceInfoChanges XkbGetDeviceInfoChanges_dylibloader_wrapper_xlib +#define XkbGetDeviceButtonActions XkbGetDeviceButtonActions_dylibloader_wrapper_xlib +#define XkbGetDeviceLedInfo XkbGetDeviceLedInfo_dylibloader_wrapper_xlib +#define XkbSetDeviceInfo XkbSetDeviceInfo_dylibloader_wrapper_xlib +#define XkbChangeDeviceInfo XkbChangeDeviceInfo_dylibloader_wrapper_xlib +#define XkbSetDeviceLedInfo XkbSetDeviceLedInfo_dylibloader_wrapper_xlib +#define XkbSetDeviceButtonActions XkbSetDeviceButtonActions_dylibloader_wrapper_xlib +#define XkbToControl XkbToControl_dylibloader_wrapper_xlib +#define XkbSetDebuggingFlags XkbSetDebuggingFlags_dylibloader_wrapper_xlib +#define XkbApplyVirtualModChanges XkbApplyVirtualModChanges_dylibloader_wrapper_xlib +#define XkbUpdateActionVirtualMods XkbUpdateActionVirtualMods_dylibloader_wrapper_xlib +#define XkbUpdateKeyTypeVirtualMods XkbUpdateKeyTypeVirtualMods_dylibloader_wrapper_xlib +extern int (*_Xmblen_dylibloader_wrapper_xlib)( char*, int); +extern XFontStruct* (*XLoadQueryFont_dylibloader_wrapper_xlib)( Display*,const char*); +extern XFontStruct* (*XQueryFont_dylibloader_wrapper_xlib)( Display*, XID); +extern XTimeCoord* (*XGetMotionEvents_dylibloader_wrapper_xlib)( Display*, Window, Time, Time, int*); +extern XModifierKeymap* (*XDeleteModifiermapEntry_dylibloader_wrapper_xlib)( XModifierKeymap*, KeyCode, int); +extern XModifierKeymap* (*XGetModifierMapping_dylibloader_wrapper_xlib)( Display*); +extern XModifierKeymap* (*XInsertModifiermapEntry_dylibloader_wrapper_xlib)( XModifierKeymap*, KeyCode, int); +extern XModifierKeymap* (*XNewModifiermap_dylibloader_wrapper_xlib)( int); +extern XImage* (*XCreateImage_dylibloader_wrapper_xlib)( Display*, Visual*, unsigned int, int, int, char*, unsigned int, unsigned int, int, int); +extern int (*XInitImage_dylibloader_wrapper_xlib)( XImage*); +extern XImage* (*XGetImage_dylibloader_wrapper_xlib)( Display*, Drawable, int, int, unsigned int, unsigned int, unsigned long, int); +extern XImage* (*XGetSubImage_dylibloader_wrapper_xlib)( Display*, Drawable, int, int, unsigned int, unsigned int, unsigned long, int, XImage*, int, int); +extern Display* (*XOpenDisplay_dylibloader_wrapper_xlib)(const char*); +extern void (*XrmInitialize_dylibloader_wrapper_xlib)( void); +extern char* (*XFetchBytes_dylibloader_wrapper_xlib)( Display*, int*); +extern char* (*XFetchBuffer_dylibloader_wrapper_xlib)( Display*, int*, int); +extern char* (*XGetAtomName_dylibloader_wrapper_xlib)( Display*, Atom); +extern int (*XGetAtomNames_dylibloader_wrapper_xlib)( Display*, Atom*, int, char**); +extern char* (*XGetDefault_dylibloader_wrapper_xlib)( Display*,const char*,const char*); +extern char* (*XDisplayName_dylibloader_wrapper_xlib)(const char*); +extern char* (*XKeysymToString_dylibloader_wrapper_xlib)( KeySym); +extern int* (*XSynchronize_dylibloader_wrapper_xlib)( Display*, int); +extern int* (*XSetAfterFunction_dylibloader_wrapper_xlib)( Display*, int*); +extern Atom (*XInternAtom_dylibloader_wrapper_xlib)( Display*,const char*, int); +extern int (*XInternAtoms_dylibloader_wrapper_xlib)( Display*, char**, int, int, Atom*); +extern Colormap (*XCopyColormapAndFree_dylibloader_wrapper_xlib)( Display*, Colormap); +extern Colormap (*XCreateColormap_dylibloader_wrapper_xlib)( Display*, Window, Visual*, int); +extern Cursor (*XCreatePixmapCursor_dylibloader_wrapper_xlib)( Display*, Pixmap, Pixmap, XColor*, XColor*, unsigned int, unsigned int); +extern Cursor (*XCreateGlyphCursor_dylibloader_wrapper_xlib)( Display*, Font, Font, unsigned int, unsigned int,const XColor*,const XColor*); +extern Cursor (*XCreateFontCursor_dylibloader_wrapper_xlib)( Display*, unsigned int); +extern Font (*XLoadFont_dylibloader_wrapper_xlib)( Display*,const char*); +extern GC (*XCreateGC_dylibloader_wrapper_xlib)( Display*, Drawable, unsigned long, XGCValues*); +extern GContext (*XGContextFromGC_dylibloader_wrapper_xlib)( GC); +extern void (*XFlushGC_dylibloader_wrapper_xlib)( Display*, GC); +extern Pixmap (*XCreatePixmap_dylibloader_wrapper_xlib)( Display*, Drawable, unsigned int, unsigned int, unsigned int); +extern Pixmap (*XCreateBitmapFromData_dylibloader_wrapper_xlib)( Display*, Drawable,const char*, unsigned int, unsigned int); +extern Pixmap (*XCreatePixmapFromBitmapData_dylibloader_wrapper_xlib)( Display*, Drawable, char*, unsigned int, unsigned int, unsigned long, unsigned long, unsigned int); +extern Window (*XCreateSimpleWindow_dylibloader_wrapper_xlib)( Display*, Window, int, int, unsigned int, unsigned int, unsigned int, unsigned long, unsigned long); +extern Window (*XGetSelectionOwner_dylibloader_wrapper_xlib)( Display*, Atom); +extern Window (*XCreateWindow_dylibloader_wrapper_xlib)( Display*, Window, int, int, unsigned int, unsigned int, unsigned int, int, unsigned int, Visual*, unsigned long, XSetWindowAttributes*); +extern Colormap* (*XListInstalledColormaps_dylibloader_wrapper_xlib)( Display*, Window, int*); +extern char** (*XListFonts_dylibloader_wrapper_xlib)( Display*,const char*, int, int*); +extern char** (*XListFontsWithInfo_dylibloader_wrapper_xlib)( Display*,const char*, int, int*, XFontStruct**); +extern char** (*XGetFontPath_dylibloader_wrapper_xlib)( Display*, int*); +extern char** (*XListExtensions_dylibloader_wrapper_xlib)( Display*, int*); +extern Atom* (*XListProperties_dylibloader_wrapper_xlib)( Display*, Window, int*); +extern XHostAddress* (*XListHosts_dylibloader_wrapper_xlib)( Display*, int*, int*); +extern KeySym (*XKeycodeToKeysym_dylibloader_wrapper_xlib)( Display*, KeyCode, int); +extern KeySym (*XLookupKeysym_dylibloader_wrapper_xlib)( XKeyEvent*, int); +extern KeySym* (*XGetKeyboardMapping_dylibloader_wrapper_xlib)( Display*, KeyCode, int, int*); +extern KeySym (*XStringToKeysym_dylibloader_wrapper_xlib)(const char*); +extern long (*XMaxRequestSize_dylibloader_wrapper_xlib)( Display*); +extern long (*XExtendedMaxRequestSize_dylibloader_wrapper_xlib)( Display*); +extern char* (*XResourceManagerString_dylibloader_wrapper_xlib)( Display*); +extern char* (*XScreenResourceString_dylibloader_wrapper_xlib)( Screen*); +extern unsigned long (*XDisplayMotionBufferSize_dylibloader_wrapper_xlib)( Display*); +extern VisualID (*XVisualIDFromVisual_dylibloader_wrapper_xlib)( Visual*); +extern int (*XInitThreads_dylibloader_wrapper_xlib)( void); +extern void (*XLockDisplay_dylibloader_wrapper_xlib)( Display*); +extern void (*XUnlockDisplay_dylibloader_wrapper_xlib)( Display*); +extern XExtCodes* (*XInitExtension_dylibloader_wrapper_xlib)( Display*,const char*); +extern XExtCodes* (*XAddExtension_dylibloader_wrapper_xlib)( Display*); +extern XExtData* (*XFindOnExtensionList_dylibloader_wrapper_xlib)( XExtData**, int); +extern XExtData** (*XEHeadOfExtensionList_dylibloader_wrapper_xlib)( XEDataObject); +extern Window (*XRootWindow_dylibloader_wrapper_xlib)( Display*, int); +extern Window (*XDefaultRootWindow_dylibloader_wrapper_xlib)( Display*); +extern Window (*XRootWindowOfScreen_dylibloader_wrapper_xlib)( Screen*); +extern Visual* (*XDefaultVisual_dylibloader_wrapper_xlib)( Display*, int); +extern Visual* (*XDefaultVisualOfScreen_dylibloader_wrapper_xlib)( Screen*); +extern GC (*XDefaultGC_dylibloader_wrapper_xlib)( Display*, int); +extern GC (*XDefaultGCOfScreen_dylibloader_wrapper_xlib)( Screen*); +extern unsigned long (*XBlackPixel_dylibloader_wrapper_xlib)( Display*, int); +extern unsigned long (*XWhitePixel_dylibloader_wrapper_xlib)( Display*, int); +extern unsigned long (*XAllPlanes_dylibloader_wrapper_xlib)( void); +extern unsigned long (*XBlackPixelOfScreen_dylibloader_wrapper_xlib)( Screen*); +extern unsigned long (*XWhitePixelOfScreen_dylibloader_wrapper_xlib)( Screen*); +extern unsigned long (*XNextRequest_dylibloader_wrapper_xlib)( Display*); +extern unsigned long (*XLastKnownRequestProcessed_dylibloader_wrapper_xlib)( Display*); +extern char* (*XServerVendor_dylibloader_wrapper_xlib)( Display*); +extern char* (*XDisplayString_dylibloader_wrapper_xlib)( Display*); +extern Colormap (*XDefaultColormap_dylibloader_wrapper_xlib)( Display*, int); +extern Colormap (*XDefaultColormapOfScreen_dylibloader_wrapper_xlib)( Screen*); +extern Display* (*XDisplayOfScreen_dylibloader_wrapper_xlib)( Screen*); +extern Screen* (*XScreenOfDisplay_dylibloader_wrapper_xlib)( Display*, int); +extern Screen* (*XDefaultScreenOfDisplay_dylibloader_wrapper_xlib)( Display*); +extern long (*XEventMaskOfScreen_dylibloader_wrapper_xlib)( Screen*); +extern int (*XScreenNumberOfScreen_dylibloader_wrapper_xlib)( Screen*); +extern XErrorHandler (*XSetErrorHandler_dylibloader_wrapper_xlib)( XErrorHandler); +extern XIOErrorHandler (*XSetIOErrorHandler_dylibloader_wrapper_xlib)( XIOErrorHandler); +extern XPixmapFormatValues* (*XListPixmapFormats_dylibloader_wrapper_xlib)( Display*, int*); +extern int* (*XListDepths_dylibloader_wrapper_xlib)( Display*, int, int*); +extern int (*XReconfigureWMWindow_dylibloader_wrapper_xlib)( Display*, Window, int, unsigned int, XWindowChanges*); +extern int (*XGetWMProtocols_dylibloader_wrapper_xlib)( Display*, Window, Atom**, int*); +extern int (*XSetWMProtocols_dylibloader_wrapper_xlib)( Display*, Window, Atom*, int); +extern int (*XIconifyWindow_dylibloader_wrapper_xlib)( Display*, Window, int); +extern int (*XWithdrawWindow_dylibloader_wrapper_xlib)( Display*, Window, int); +extern int (*XGetCommand_dylibloader_wrapper_xlib)( Display*, Window, char***, int*); +extern int (*XGetWMColormapWindows_dylibloader_wrapper_xlib)( Display*, Window, Window**, int*); +extern int (*XSetWMColormapWindows_dylibloader_wrapper_xlib)( Display*, Window, Window*, int); +extern void (*XFreeStringList_dylibloader_wrapper_xlib)( char**); +extern int (*XSetTransientForHint_dylibloader_wrapper_xlib)( Display*, Window, Window); +extern int (*XActivateScreenSaver_dylibloader_wrapper_xlib)( Display*); +extern int (*XAddHost_dylibloader_wrapper_xlib)( Display*, XHostAddress*); +extern int (*XAddHosts_dylibloader_wrapper_xlib)( Display*, XHostAddress*, int); +extern int (*XAddToExtensionList_dylibloader_wrapper_xlib)(struct _XExtData**, XExtData*); +extern int (*XAddToSaveSet_dylibloader_wrapper_xlib)( Display*, Window); +extern int (*XAllocColor_dylibloader_wrapper_xlib)( Display*, Colormap, XColor*); +extern int (*XAllocColorCells_dylibloader_wrapper_xlib)( Display*, Colormap, int, unsigned long*, unsigned int, unsigned long*, unsigned int); +extern int (*XAllocColorPlanes_dylibloader_wrapper_xlib)( Display*, Colormap, int, unsigned long*, int, int, int, int, unsigned long*, unsigned long*, unsigned long*); +extern int (*XAllocNamedColor_dylibloader_wrapper_xlib)( Display*, Colormap,const char*, XColor*, XColor*); +extern int (*XAllowEvents_dylibloader_wrapper_xlib)( Display*, int, Time); +extern int (*XAutoRepeatOff_dylibloader_wrapper_xlib)( Display*); +extern int (*XAutoRepeatOn_dylibloader_wrapper_xlib)( Display*); +extern int (*XBell_dylibloader_wrapper_xlib)( Display*, int); +extern int (*XBitmapBitOrder_dylibloader_wrapper_xlib)( Display*); +extern int (*XBitmapPad_dylibloader_wrapper_xlib)( Display*); +extern int (*XBitmapUnit_dylibloader_wrapper_xlib)( Display*); +extern int (*XCellsOfScreen_dylibloader_wrapper_xlib)( Screen*); +extern int (*XChangeActivePointerGrab_dylibloader_wrapper_xlib)( Display*, unsigned int, Cursor, Time); +extern int (*XChangeGC_dylibloader_wrapper_xlib)( Display*, GC, unsigned long, XGCValues*); +extern int (*XChangeKeyboardControl_dylibloader_wrapper_xlib)( Display*, unsigned long, XKeyboardControl*); +extern int (*XChangeKeyboardMapping_dylibloader_wrapper_xlib)( Display*, int, int, KeySym*, int); +extern int (*XChangePointerControl_dylibloader_wrapper_xlib)( Display*, int, int, int, int, int); +extern int (*XChangeProperty_dylibloader_wrapper_xlib)( Display*, Window, Atom, Atom, int, int,const unsigned char*, int); +extern int (*XChangeSaveSet_dylibloader_wrapper_xlib)( Display*, Window, int); +extern int (*XChangeWindowAttributes_dylibloader_wrapper_xlib)( Display*, Window, unsigned long, XSetWindowAttributes*); +extern int (*XCheckIfEvent_dylibloader_wrapper_xlib)( Display*, XEvent*, Bool (*) (Display*, XEvent*, XPointer), XPointer); +extern int (*XCheckMaskEvent_dylibloader_wrapper_xlib)( Display*, long, XEvent*); +extern int (*XCheckTypedEvent_dylibloader_wrapper_xlib)( Display*, int, XEvent*); +extern int (*XCheckTypedWindowEvent_dylibloader_wrapper_xlib)( Display*, Window, int, XEvent*); +extern int (*XCheckWindowEvent_dylibloader_wrapper_xlib)( Display*, Window, long, XEvent*); +extern int (*XCirculateSubwindows_dylibloader_wrapper_xlib)( Display*, Window, int); +extern int (*XCirculateSubwindowsDown_dylibloader_wrapper_xlib)( Display*, Window); +extern int (*XCirculateSubwindowsUp_dylibloader_wrapper_xlib)( Display*, Window); +extern int (*XClearArea_dylibloader_wrapper_xlib)( Display*, Window, int, int, unsigned int, unsigned int, int); +extern int (*XClearWindow_dylibloader_wrapper_xlib)( Display*, Window); +extern int (*XCloseDisplay_dylibloader_wrapper_xlib)( Display*); +extern int (*XConfigureWindow_dylibloader_wrapper_xlib)( Display*, Window, unsigned int, XWindowChanges*); +extern int (*XConnectionNumber_dylibloader_wrapper_xlib)( Display*); +extern int (*XConvertSelection_dylibloader_wrapper_xlib)( Display*, Atom, Atom, Atom, Window, Time); +extern int (*XCopyArea_dylibloader_wrapper_xlib)( Display*, Drawable, Drawable, GC, int, int, unsigned int, unsigned int, int, int); +extern int (*XCopyGC_dylibloader_wrapper_xlib)( Display*, GC, unsigned long, GC); +extern int (*XCopyPlane_dylibloader_wrapper_xlib)( Display*, Drawable, Drawable, GC, int, int, unsigned int, unsigned int, int, int, unsigned long); +extern int (*XDefaultDepth_dylibloader_wrapper_xlib)( Display*, int); +extern int (*XDefaultDepthOfScreen_dylibloader_wrapper_xlib)( Screen*); +extern int (*XDefaultScreen_dylibloader_wrapper_xlib)( Display*); +extern int (*XDefineCursor_dylibloader_wrapper_xlib)( Display*, Window, Cursor); +extern int (*XDeleteProperty_dylibloader_wrapper_xlib)( Display*, Window, Atom); +extern int (*XDestroyWindow_dylibloader_wrapper_xlib)( Display*, Window); +extern int (*XDestroySubwindows_dylibloader_wrapper_xlib)( Display*, Window); +extern int (*XDoesBackingStore_dylibloader_wrapper_xlib)( Screen*); +extern int (*XDoesSaveUnders_dylibloader_wrapper_xlib)( Screen*); +extern int (*XDisableAccessControl_dylibloader_wrapper_xlib)( Display*); +extern int (*XDisplayCells_dylibloader_wrapper_xlib)( Display*, int); +extern int (*XDisplayHeight_dylibloader_wrapper_xlib)( Display*, int); +extern int (*XDisplayHeightMM_dylibloader_wrapper_xlib)( Display*, int); +extern int (*XDisplayKeycodes_dylibloader_wrapper_xlib)( Display*, int*, int*); +extern int (*XDisplayPlanes_dylibloader_wrapper_xlib)( Display*, int); +extern int (*XDisplayWidth_dylibloader_wrapper_xlib)( Display*, int); +extern int (*XDisplayWidthMM_dylibloader_wrapper_xlib)( Display*, int); +extern int (*XDrawArc_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int, unsigned int, unsigned int, int, int); +extern int (*XDrawArcs_dylibloader_wrapper_xlib)( Display*, Drawable, GC, XArc*, int); +extern int (*XDrawImageString_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int,const char*, int); +extern int (*XDrawImageString16_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int,const XChar2b*, int); +extern int (*XDrawLine_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int, int, int); +extern int (*XDrawLines_dylibloader_wrapper_xlib)( Display*, Drawable, GC, XPoint*, int, int); +extern int (*XDrawPoint_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int); +extern int (*XDrawPoints_dylibloader_wrapper_xlib)( Display*, Drawable, GC, XPoint*, int, int); +extern int (*XDrawRectangle_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int, unsigned int, unsigned int); +extern int (*XDrawRectangles_dylibloader_wrapper_xlib)( Display*, Drawable, GC, XRectangle*, int); +extern int (*XDrawSegments_dylibloader_wrapper_xlib)( Display*, Drawable, GC, XSegment*, int); +extern int (*XDrawString_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int,const char*, int); +extern int (*XDrawString16_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int,const XChar2b*, int); +extern int (*XDrawText_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int, XTextItem*, int); +extern int (*XDrawText16_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int, XTextItem16*, int); +extern int (*XEnableAccessControl_dylibloader_wrapper_xlib)( Display*); +extern int (*XEventsQueued_dylibloader_wrapper_xlib)( Display*, int); +extern int (*XFetchName_dylibloader_wrapper_xlib)( Display*, Window, char**); +extern int (*XFillArc_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int, unsigned int, unsigned int, int, int); +extern int (*XFillArcs_dylibloader_wrapper_xlib)( Display*, Drawable, GC, XArc*, int); +extern int (*XFillPolygon_dylibloader_wrapper_xlib)( Display*, Drawable, GC, XPoint*, int, int, int); +extern int (*XFillRectangle_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int, unsigned int, unsigned int); +extern int (*XFillRectangles_dylibloader_wrapper_xlib)( Display*, Drawable, GC, XRectangle*, int); +extern int (*XFlush_dylibloader_wrapper_xlib)( Display*); +extern int (*XForceScreenSaver_dylibloader_wrapper_xlib)( Display*, int); +extern int (*XFree_dylibloader_wrapper_xlib)( void*); +extern int (*XFreeColormap_dylibloader_wrapper_xlib)( Display*, Colormap); +extern int (*XFreeColors_dylibloader_wrapper_xlib)( Display*, Colormap, unsigned long*, int, unsigned long); +extern int (*XFreeCursor_dylibloader_wrapper_xlib)( Display*, Cursor); +extern int (*XFreeExtensionList_dylibloader_wrapper_xlib)( char**); +extern int (*XFreeFont_dylibloader_wrapper_xlib)( Display*, XFontStruct*); +extern int (*XFreeFontInfo_dylibloader_wrapper_xlib)( char**, XFontStruct*, int); +extern int (*XFreeFontNames_dylibloader_wrapper_xlib)( char**); +extern int (*XFreeFontPath_dylibloader_wrapper_xlib)( char**); +extern int (*XFreeGC_dylibloader_wrapper_xlib)( Display*, GC); +extern int (*XFreeModifiermap_dylibloader_wrapper_xlib)( XModifierKeymap*); +extern int (*XFreePixmap_dylibloader_wrapper_xlib)( Display*, Pixmap); +extern int (*XGeometry_dylibloader_wrapper_xlib)( Display*, int,const char*,const char*, unsigned int, unsigned int, unsigned int, int, int, int*, int*, int*, int*); +extern int (*XGetErrorDatabaseText_dylibloader_wrapper_xlib)( Display*,const char*,const char*,const char*, char*, int); +extern int (*XGetErrorText_dylibloader_wrapper_xlib)( Display*, int, char*, int); +extern int (*XGetFontProperty_dylibloader_wrapper_xlib)( XFontStruct*, Atom, unsigned long*); +extern int (*XGetGCValues_dylibloader_wrapper_xlib)( Display*, GC, unsigned long, XGCValues*); +extern int (*XGetGeometry_dylibloader_wrapper_xlib)( Display*, Drawable, Window*, int*, int*, unsigned int*, unsigned int*, unsigned int*, unsigned int*); +extern int (*XGetIconName_dylibloader_wrapper_xlib)( Display*, Window, char**); +extern int (*XGetInputFocus_dylibloader_wrapper_xlib)( Display*, Window*, int*); +extern int (*XGetKeyboardControl_dylibloader_wrapper_xlib)( Display*, XKeyboardState*); +extern int (*XGetPointerControl_dylibloader_wrapper_xlib)( Display*, int*, int*, int*); +extern int (*XGetPointerMapping_dylibloader_wrapper_xlib)( Display*, unsigned char*, int); +extern int (*XGetScreenSaver_dylibloader_wrapper_xlib)( Display*, int*, int*, int*, int*); +extern int (*XGetTransientForHint_dylibloader_wrapper_xlib)( Display*, Window, Window*); +extern int (*XGetWindowProperty_dylibloader_wrapper_xlib)( Display*, Window, Atom, long, long, int, Atom, Atom*, int*, unsigned long*, unsigned long*, unsigned char**); +extern int (*XGetWindowAttributes_dylibloader_wrapper_xlib)( Display*, Window, XWindowAttributes*); +extern int (*XGrabButton_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, Window, int, unsigned int, int, int, Window, Cursor); +extern int (*XGrabKey_dylibloader_wrapper_xlib)( Display*, int, unsigned int, Window, int, int, int); +extern int (*XGrabKeyboard_dylibloader_wrapper_xlib)( Display*, Window, int, int, int, Time); +extern int (*XGrabPointer_dylibloader_wrapper_xlib)( Display*, Window, int, unsigned int, int, int, Window, Cursor, Time); +extern int (*XGrabServer_dylibloader_wrapper_xlib)( Display*); +extern int (*XHeightMMOfScreen_dylibloader_wrapper_xlib)( Screen*); +extern int (*XHeightOfScreen_dylibloader_wrapper_xlib)( Screen*); +extern int (*XIfEvent_dylibloader_wrapper_xlib)( Display*, XEvent*, Bool (*) (Display*, XEvent*, XPointer), XPointer); +extern int (*XImageByteOrder_dylibloader_wrapper_xlib)( Display*); +extern int (*XInstallColormap_dylibloader_wrapper_xlib)( Display*, Colormap); +extern KeyCode (*XKeysymToKeycode_dylibloader_wrapper_xlib)( Display*, KeySym); +extern int (*XKillClient_dylibloader_wrapper_xlib)( Display*, XID); +extern int (*XLookupColor_dylibloader_wrapper_xlib)( Display*, Colormap,const char*, XColor*, XColor*); +extern int (*XLowerWindow_dylibloader_wrapper_xlib)( Display*, Window); +extern int (*XMapRaised_dylibloader_wrapper_xlib)( Display*, Window); +extern int (*XMapSubwindows_dylibloader_wrapper_xlib)( Display*, Window); +extern int (*XMapWindow_dylibloader_wrapper_xlib)( Display*, Window); +extern int (*XMaskEvent_dylibloader_wrapper_xlib)( Display*, long, XEvent*); +extern int (*XMaxCmapsOfScreen_dylibloader_wrapper_xlib)( Screen*); +extern int (*XMinCmapsOfScreen_dylibloader_wrapper_xlib)( Screen*); +extern int (*XMoveResizeWindow_dylibloader_wrapper_xlib)( Display*, Window, int, int, unsigned int, unsigned int); +extern int (*XMoveWindow_dylibloader_wrapper_xlib)( Display*, Window, int, int); +extern int (*XNextEvent_dylibloader_wrapper_xlib)( Display*, XEvent*); +extern int (*XNoOp_dylibloader_wrapper_xlib)( Display*); +extern int (*XParseColor_dylibloader_wrapper_xlib)( Display*, Colormap,const char*, XColor*); +extern int (*XParseGeometry_dylibloader_wrapper_xlib)(const char*, int*, int*, unsigned int*, unsigned int*); +extern int (*XPeekEvent_dylibloader_wrapper_xlib)( Display*, XEvent*); +extern int (*XPeekIfEvent_dylibloader_wrapper_xlib)( Display*, XEvent*, Bool (*) (Display*, XEvent*, XPointer), XPointer); +extern int (*XPending_dylibloader_wrapper_xlib)( Display*); +extern int (*XPlanesOfScreen_dylibloader_wrapper_xlib)( Screen*); +extern int (*XProtocolRevision_dylibloader_wrapper_xlib)( Display*); +extern int (*XProtocolVersion_dylibloader_wrapper_xlib)( Display*); +extern int (*XPutBackEvent_dylibloader_wrapper_xlib)( Display*, XEvent*); +extern int (*XPutImage_dylibloader_wrapper_xlib)( Display*, Drawable, GC, XImage*, int, int, int, int, unsigned int, unsigned int); +extern int (*XQLength_dylibloader_wrapper_xlib)( Display*); +extern int (*XQueryBestCursor_dylibloader_wrapper_xlib)( Display*, Drawable, unsigned int, unsigned int, unsigned int*, unsigned int*); +extern int (*XQueryBestSize_dylibloader_wrapper_xlib)( Display*, int, Drawable, unsigned int, unsigned int, unsigned int*, unsigned int*); +extern int (*XQueryBestStipple_dylibloader_wrapper_xlib)( Display*, Drawable, unsigned int, unsigned int, unsigned int*, unsigned int*); +extern int (*XQueryBestTile_dylibloader_wrapper_xlib)( Display*, Drawable, unsigned int, unsigned int, unsigned int*, unsigned int*); +extern int (*XQueryColor_dylibloader_wrapper_xlib)( Display*, Colormap, XColor*); +extern int (*XQueryColors_dylibloader_wrapper_xlib)( Display*, Colormap, XColor*, int); +extern int (*XQueryExtension_dylibloader_wrapper_xlib)( Display*,const char*, int*, int*, int*); +extern int (*XQueryKeymap_dylibloader_wrapper_xlib)( Display*, char [32]); +extern int (*XQueryPointer_dylibloader_wrapper_xlib)( Display*, Window, Window*, Window*, int*, int*, int*, int*, unsigned int*); +extern int (*XQueryTextExtents_dylibloader_wrapper_xlib)( Display*, XID,const char*, int, int*, int*, int*, XCharStruct*); +extern int (*XQueryTextExtents16_dylibloader_wrapper_xlib)( Display*, XID,const XChar2b*, int, int*, int*, int*, XCharStruct*); +extern int (*XQueryTree_dylibloader_wrapper_xlib)( Display*, Window, Window*, Window*, Window**, unsigned int*); +extern int (*XRaiseWindow_dylibloader_wrapper_xlib)( Display*, Window); +extern int (*XReadBitmapFile_dylibloader_wrapper_xlib)( Display*, Drawable,const char*, unsigned int*, unsigned int*, Pixmap*, int*, int*); +extern int (*XReadBitmapFileData_dylibloader_wrapper_xlib)(const char*, unsigned int*, unsigned int*, unsigned char**, int*, int*); +extern int (*XRebindKeysym_dylibloader_wrapper_xlib)( Display*, KeySym, KeySym*, int,const unsigned char*, int); +extern int (*XRecolorCursor_dylibloader_wrapper_xlib)( Display*, Cursor, XColor*, XColor*); +extern int (*XRefreshKeyboardMapping_dylibloader_wrapper_xlib)( XMappingEvent*); +extern int (*XRemoveFromSaveSet_dylibloader_wrapper_xlib)( Display*, Window); +extern int (*XRemoveHost_dylibloader_wrapper_xlib)( Display*, XHostAddress*); +extern int (*XRemoveHosts_dylibloader_wrapper_xlib)( Display*, XHostAddress*, int); +extern int (*XReparentWindow_dylibloader_wrapper_xlib)( Display*, Window, Window, int, int); +extern int (*XResetScreenSaver_dylibloader_wrapper_xlib)( Display*); +extern int (*XResizeWindow_dylibloader_wrapper_xlib)( Display*, Window, unsigned int, unsigned int); +extern int (*XRestackWindows_dylibloader_wrapper_xlib)( Display*, Window*, int); +extern int (*XRotateBuffers_dylibloader_wrapper_xlib)( Display*, int); +extern int (*XRotateWindowProperties_dylibloader_wrapper_xlib)( Display*, Window, Atom*, int, int); +extern int (*XScreenCount_dylibloader_wrapper_xlib)( Display*); +extern int (*XSelectInput_dylibloader_wrapper_xlib)( Display*, Window, long); +extern int (*XSendEvent_dylibloader_wrapper_xlib)( Display*, Window, int, long, XEvent*); +extern int (*XSetAccessControl_dylibloader_wrapper_xlib)( Display*, int); +extern int (*XSetArcMode_dylibloader_wrapper_xlib)( Display*, GC, int); +extern int (*XSetBackground_dylibloader_wrapper_xlib)( Display*, GC, unsigned long); +extern int (*XSetClipMask_dylibloader_wrapper_xlib)( Display*, GC, Pixmap); +extern int (*XSetClipOrigin_dylibloader_wrapper_xlib)( Display*, GC, int, int); +extern int (*XSetClipRectangles_dylibloader_wrapper_xlib)( Display*, GC, int, int, XRectangle*, int, int); +extern int (*XSetCloseDownMode_dylibloader_wrapper_xlib)( Display*, int); +extern int (*XSetCommand_dylibloader_wrapper_xlib)( Display*, Window, char**, int); +extern int (*XSetDashes_dylibloader_wrapper_xlib)( Display*, GC, int,const char*, int); +extern int (*XSetFillRule_dylibloader_wrapper_xlib)( Display*, GC, int); +extern int (*XSetFillStyle_dylibloader_wrapper_xlib)( Display*, GC, int); +extern int (*XSetFont_dylibloader_wrapper_xlib)( Display*, GC, Font); +extern int (*XSetFontPath_dylibloader_wrapper_xlib)( Display*, char**, int); +extern int (*XSetForeground_dylibloader_wrapper_xlib)( Display*, GC, unsigned long); +extern int (*XSetFunction_dylibloader_wrapper_xlib)( Display*, GC, int); +extern int (*XSetGraphicsExposures_dylibloader_wrapper_xlib)( Display*, GC, int); +extern int (*XSetIconName_dylibloader_wrapper_xlib)( Display*, Window,const char*); +extern int (*XSetInputFocus_dylibloader_wrapper_xlib)( Display*, Window, int, Time); +extern int (*XSetLineAttributes_dylibloader_wrapper_xlib)( Display*, GC, unsigned int, int, int, int); +extern int (*XSetModifierMapping_dylibloader_wrapper_xlib)( Display*, XModifierKeymap*); +extern int (*XSetPlaneMask_dylibloader_wrapper_xlib)( Display*, GC, unsigned long); +extern int (*XSetPointerMapping_dylibloader_wrapper_xlib)( Display*,const unsigned char*, int); +extern int (*XSetScreenSaver_dylibloader_wrapper_xlib)( Display*, int, int, int, int); +extern int (*XSetSelectionOwner_dylibloader_wrapper_xlib)( Display*, Atom, Window, Time); +extern int (*XSetState_dylibloader_wrapper_xlib)( Display*, GC, unsigned long, unsigned long, int, unsigned long); +extern int (*XSetStipple_dylibloader_wrapper_xlib)( Display*, GC, Pixmap); +extern int (*XSetSubwindowMode_dylibloader_wrapper_xlib)( Display*, GC, int); +extern int (*XSetTSOrigin_dylibloader_wrapper_xlib)( Display*, GC, int, int); +extern int (*XSetTile_dylibloader_wrapper_xlib)( Display*, GC, Pixmap); +extern int (*XSetWindowBackground_dylibloader_wrapper_xlib)( Display*, Window, unsigned long); +extern int (*XSetWindowBackgroundPixmap_dylibloader_wrapper_xlib)( Display*, Window, Pixmap); +extern int (*XSetWindowBorder_dylibloader_wrapper_xlib)( Display*, Window, unsigned long); +extern int (*XSetWindowBorderPixmap_dylibloader_wrapper_xlib)( Display*, Window, Pixmap); +extern int (*XSetWindowBorderWidth_dylibloader_wrapper_xlib)( Display*, Window, unsigned int); +extern int (*XSetWindowColormap_dylibloader_wrapper_xlib)( Display*, Window, Colormap); +extern int (*XStoreBuffer_dylibloader_wrapper_xlib)( Display*,const char*, int, int); +extern int (*XStoreBytes_dylibloader_wrapper_xlib)( Display*,const char*, int); +extern int (*XStoreColor_dylibloader_wrapper_xlib)( Display*, Colormap, XColor*); +extern int (*XStoreColors_dylibloader_wrapper_xlib)( Display*, Colormap, XColor*, int); +extern int (*XStoreName_dylibloader_wrapper_xlib)( Display*, Window,const char*); +extern int (*XStoreNamedColor_dylibloader_wrapper_xlib)( Display*, Colormap,const char*, unsigned long, int); +extern int (*XSync_dylibloader_wrapper_xlib)( Display*, int); +extern int (*XTextExtents_dylibloader_wrapper_xlib)( XFontStruct*,const char*, int, int*, int*, int*, XCharStruct*); +extern int (*XTextExtents16_dylibloader_wrapper_xlib)( XFontStruct*,const XChar2b*, int, int*, int*, int*, XCharStruct*); +extern int (*XTextWidth_dylibloader_wrapper_xlib)( XFontStruct*,const char*, int); +extern int (*XTextWidth16_dylibloader_wrapper_xlib)( XFontStruct*,const XChar2b*, int); +extern int (*XTranslateCoordinates_dylibloader_wrapper_xlib)( Display*, Window, Window, int, int, int*, int*, Window*); +extern int (*XUndefineCursor_dylibloader_wrapper_xlib)( Display*, Window); +extern int (*XUngrabButton_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, Window); +extern int (*XUngrabKey_dylibloader_wrapper_xlib)( Display*, int, unsigned int, Window); +extern int (*XUngrabKeyboard_dylibloader_wrapper_xlib)( Display*, Time); +extern int (*XUngrabPointer_dylibloader_wrapper_xlib)( Display*, Time); +extern int (*XUngrabServer_dylibloader_wrapper_xlib)( Display*); +extern int (*XUninstallColormap_dylibloader_wrapper_xlib)( Display*, Colormap); +extern int (*XUnloadFont_dylibloader_wrapper_xlib)( Display*, Font); +extern int (*XUnmapSubwindows_dylibloader_wrapper_xlib)( Display*, Window); +extern int (*XUnmapWindow_dylibloader_wrapper_xlib)( Display*, Window); +extern int (*XVendorRelease_dylibloader_wrapper_xlib)( Display*); +extern int (*XWarpPointer_dylibloader_wrapper_xlib)( Display*, Window, Window, int, int, unsigned int, unsigned int, int, int); +extern int (*XWidthMMOfScreen_dylibloader_wrapper_xlib)( Screen*); +extern int (*XWidthOfScreen_dylibloader_wrapper_xlib)( Screen*); +extern int (*XWindowEvent_dylibloader_wrapper_xlib)( Display*, Window, long, XEvent*); +extern int (*XWriteBitmapFile_dylibloader_wrapper_xlib)( Display*,const char*, Pixmap, unsigned int, unsigned int, int, int); +extern int (*XSupportsLocale_dylibloader_wrapper_xlib)( void); +extern char* (*XSetLocaleModifiers_dylibloader_wrapper_xlib)(const char*); +extern XOM (*XOpenOM_dylibloader_wrapper_xlib)( Display*,struct _XrmHashBucketRec*,const char*,const char*); +extern int (*XCloseOM_dylibloader_wrapper_xlib)( XOM); +extern char* (*XSetOMValues_dylibloader_wrapper_xlib)( XOM,...); +extern char* (*XGetOMValues_dylibloader_wrapper_xlib)( XOM,...); +extern Display* (*XDisplayOfOM_dylibloader_wrapper_xlib)( XOM); +extern char* (*XLocaleOfOM_dylibloader_wrapper_xlib)( XOM); +extern XOC (*XCreateOC_dylibloader_wrapper_xlib)( XOM,...); +extern void (*XDestroyOC_dylibloader_wrapper_xlib)( XOC); +extern XOM (*XOMOfOC_dylibloader_wrapper_xlib)( XOC); +extern char* (*XSetOCValues_dylibloader_wrapper_xlib)( XOC,...); +extern char* (*XGetOCValues_dylibloader_wrapper_xlib)( XOC,...); +extern XFontSet (*XCreateFontSet_dylibloader_wrapper_xlib)( Display*,const char*, char***, int*, char**); +extern void (*XFreeFontSet_dylibloader_wrapper_xlib)( Display*, XFontSet); +extern int (*XFontsOfFontSet_dylibloader_wrapper_xlib)( XFontSet, XFontStruct***, char***); +extern char* (*XBaseFontNameListOfFontSet_dylibloader_wrapper_xlib)( XFontSet); +extern char* (*XLocaleOfFontSet_dylibloader_wrapper_xlib)( XFontSet); +extern int (*XContextDependentDrawing_dylibloader_wrapper_xlib)( XFontSet); +extern int (*XDirectionalDependentDrawing_dylibloader_wrapper_xlib)( XFontSet); +extern int (*XContextualDrawing_dylibloader_wrapper_xlib)( XFontSet); +extern XFontSetExtents* (*XExtentsOfFontSet_dylibloader_wrapper_xlib)( XFontSet); +extern int (*XmbTextEscapement_dylibloader_wrapper_xlib)( XFontSet,const char*, int); +extern int (*XwcTextEscapement_dylibloader_wrapper_xlib)( XFontSet,const wchar_t*, int); +extern int (*Xutf8TextEscapement_dylibloader_wrapper_xlib)( XFontSet,const char*, int); +extern int (*XmbTextExtents_dylibloader_wrapper_xlib)( XFontSet,const char*, int, XRectangle*, XRectangle*); +extern int (*XwcTextExtents_dylibloader_wrapper_xlib)( XFontSet,const wchar_t*, int, XRectangle*, XRectangle*); +extern int (*Xutf8TextExtents_dylibloader_wrapper_xlib)( XFontSet,const char*, int, XRectangle*, XRectangle*); +extern int (*XmbTextPerCharExtents_dylibloader_wrapper_xlib)( XFontSet,const char*, int, XRectangle*, XRectangle*, int, int*, XRectangle*, XRectangle*); +extern int (*XwcTextPerCharExtents_dylibloader_wrapper_xlib)( XFontSet,const wchar_t*, int, XRectangle*, XRectangle*, int, int*, XRectangle*, XRectangle*); +extern int (*Xutf8TextPerCharExtents_dylibloader_wrapper_xlib)( XFontSet,const char*, int, XRectangle*, XRectangle*, int, int*, XRectangle*, XRectangle*); +extern void (*XmbDrawText_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int, XmbTextItem*, int); +extern void (*XwcDrawText_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int, XwcTextItem*, int); +extern void (*Xutf8DrawText_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int, XmbTextItem*, int); +extern void (*XmbDrawString_dylibloader_wrapper_xlib)( Display*, Drawable, XFontSet, GC, int, int,const char*, int); +extern void (*XwcDrawString_dylibloader_wrapper_xlib)( Display*, Drawable, XFontSet, GC, int, int,const wchar_t*, int); +extern void (*Xutf8DrawString_dylibloader_wrapper_xlib)( Display*, Drawable, XFontSet, GC, int, int,const char*, int); +extern void (*XmbDrawImageString_dylibloader_wrapper_xlib)( Display*, Drawable, XFontSet, GC, int, int,const char*, int); +extern void (*XwcDrawImageString_dylibloader_wrapper_xlib)( Display*, Drawable, XFontSet, GC, int, int,const wchar_t*, int); +extern void (*Xutf8DrawImageString_dylibloader_wrapper_xlib)( Display*, Drawable, XFontSet, GC, int, int,const char*, int); +extern XIM (*XOpenIM_dylibloader_wrapper_xlib)( Display*,struct _XrmHashBucketRec*, char*, char*); +extern int (*XCloseIM_dylibloader_wrapper_xlib)( XIM); +extern char* (*XGetIMValues_dylibloader_wrapper_xlib)( XIM,...); +extern char* (*XSetIMValues_dylibloader_wrapper_xlib)( XIM,...); +extern Display* (*XDisplayOfIM_dylibloader_wrapper_xlib)( XIM); +extern char* (*XLocaleOfIM_dylibloader_wrapper_xlib)( XIM); +extern XIC (*XCreateIC_dylibloader_wrapper_xlib)( XIM,...); +extern void (*XDestroyIC_dylibloader_wrapper_xlib)( XIC); +extern void (*XSetICFocus_dylibloader_wrapper_xlib)( XIC); +extern void (*XUnsetICFocus_dylibloader_wrapper_xlib)( XIC); +extern wchar_t* (*XwcResetIC_dylibloader_wrapper_xlib)( XIC); +extern char* (*XmbResetIC_dylibloader_wrapper_xlib)( XIC); +extern char* (*Xutf8ResetIC_dylibloader_wrapper_xlib)( XIC); +extern char* (*XSetICValues_dylibloader_wrapper_xlib)( XIC,...); +extern char* (*XGetICValues_dylibloader_wrapper_xlib)( XIC,...); +extern XIM (*XIMOfIC_dylibloader_wrapper_xlib)( XIC); +extern int (*XFilterEvent_dylibloader_wrapper_xlib)( XEvent*, Window); +extern int (*XmbLookupString_dylibloader_wrapper_xlib)( XIC, XKeyPressedEvent*, char*, int, KeySym*, int*); +extern int (*XwcLookupString_dylibloader_wrapper_xlib)( XIC, XKeyPressedEvent*, wchar_t*, int, KeySym*, int*); +extern int (*Xutf8LookupString_dylibloader_wrapper_xlib)( XIC, XKeyPressedEvent*, char*, int, KeySym*, int*); +extern XVaNestedList (*XVaCreateNestedList_dylibloader_wrapper_xlib)( int,...); +extern int (*XRegisterIMInstantiateCallback_dylibloader_wrapper_xlib)( Display*,struct _XrmHashBucketRec*, char*, char*, XIDProc, XPointer); +extern int (*XUnregisterIMInstantiateCallback_dylibloader_wrapper_xlib)( Display*,struct _XrmHashBucketRec*, char*, char*, XIDProc, XPointer); +extern int (*XInternalConnectionNumbers_dylibloader_wrapper_xlib)( Display*, int**, int*); +extern void (*XProcessInternalConnection_dylibloader_wrapper_xlib)( Display*, int); +extern int (*XAddConnectionWatch_dylibloader_wrapper_xlib)( Display*, XConnectionWatchProc, XPointer); +extern void (*XRemoveConnectionWatch_dylibloader_wrapper_xlib)( Display*, XConnectionWatchProc, XPointer); +extern void (*XSetAuthorization_dylibloader_wrapper_xlib)( char*, int, char*, int); +extern int (*_Xmbtowc_dylibloader_wrapper_xlib)( wchar_t*, char*, int); +extern int (*_Xwctomb_dylibloader_wrapper_xlib)( char*, wchar_t); +extern int (*XGetEventData_dylibloader_wrapper_xlib)( Display*, XGenericEventCookie*); +extern void (*XFreeEventData_dylibloader_wrapper_xlib)( Display*, XGenericEventCookie*); +extern XClassHint* (*XAllocClassHint_dylibloader_wrapper_xlib)( void); +extern XIconSize* (*XAllocIconSize_dylibloader_wrapper_xlib)( void); +extern XSizeHints* (*XAllocSizeHints_dylibloader_wrapper_xlib)( void); +extern XStandardColormap* (*XAllocStandardColormap_dylibloader_wrapper_xlib)( void); +extern XWMHints* (*XAllocWMHints_dylibloader_wrapper_xlib)( void); +extern int (*XClipBox_dylibloader_wrapper_xlib)( Region, XRectangle*); +extern Region (*XCreateRegion_dylibloader_wrapper_xlib)( void); +extern const char* (*XDefaultString_dylibloader_wrapper_xlib)( void); +extern int (*XDeleteContext_dylibloader_wrapper_xlib)( Display*, XID, XContext); +extern int (*XDestroyRegion_dylibloader_wrapper_xlib)( Region); +extern int (*XEmptyRegion_dylibloader_wrapper_xlib)( Region); +extern int (*XEqualRegion_dylibloader_wrapper_xlib)( Region, Region); +extern int (*XFindContext_dylibloader_wrapper_xlib)( Display*, XID, XContext, XPointer*); +extern int (*XGetClassHint_dylibloader_wrapper_xlib)( Display*, Window, XClassHint*); +extern int (*XGetIconSizes_dylibloader_wrapper_xlib)( Display*, Window, XIconSize**, int*); +extern int (*XGetNormalHints_dylibloader_wrapper_xlib)( Display*, Window, XSizeHints*); +extern int (*XGetRGBColormaps_dylibloader_wrapper_xlib)( Display*, Window, XStandardColormap**, int*, Atom); +extern int (*XGetSizeHints_dylibloader_wrapper_xlib)( Display*, Window, XSizeHints*, Atom); +extern int (*XGetStandardColormap_dylibloader_wrapper_xlib)( Display*, Window, XStandardColormap*, Atom); +extern int (*XGetTextProperty_dylibloader_wrapper_xlib)( Display*, Window, XTextProperty*, Atom); +extern XVisualInfo* (*XGetVisualInfo_dylibloader_wrapper_xlib)( Display*, long, XVisualInfo*, int*); +extern int (*XGetWMClientMachine_dylibloader_wrapper_xlib)( Display*, Window, XTextProperty*); +extern XWMHints* (*XGetWMHints_dylibloader_wrapper_xlib)( Display*, Window); +extern int (*XGetWMIconName_dylibloader_wrapper_xlib)( Display*, Window, XTextProperty*); +extern int (*XGetWMName_dylibloader_wrapper_xlib)( Display*, Window, XTextProperty*); +extern int (*XGetWMNormalHints_dylibloader_wrapper_xlib)( Display*, Window, XSizeHints*, long*); +extern int (*XGetWMSizeHints_dylibloader_wrapper_xlib)( Display*, Window, XSizeHints*, long*, Atom); +extern int (*XGetZoomHints_dylibloader_wrapper_xlib)( Display*, Window, XSizeHints*); +extern int (*XIntersectRegion_dylibloader_wrapper_xlib)( Region, Region, Region); +extern void (*XConvertCase_dylibloader_wrapper_xlib)( KeySym, KeySym*, KeySym*); +extern int (*XLookupString_dylibloader_wrapper_xlib)( XKeyEvent*, char*, int, KeySym*, XComposeStatus*); +extern int (*XMatchVisualInfo_dylibloader_wrapper_xlib)( Display*, int, int, int, XVisualInfo*); +extern int (*XOffsetRegion_dylibloader_wrapper_xlib)( Region, int, int); +extern int (*XPointInRegion_dylibloader_wrapper_xlib)( Region, int, int); +extern Region (*XPolygonRegion_dylibloader_wrapper_xlib)( XPoint*, int, int); +extern int (*XRectInRegion_dylibloader_wrapper_xlib)( Region, int, int, unsigned int, unsigned int); +extern int (*XSaveContext_dylibloader_wrapper_xlib)( Display*, XID, XContext,const char*); +extern int (*XSetClassHint_dylibloader_wrapper_xlib)( Display*, Window, XClassHint*); +extern int (*XSetIconSizes_dylibloader_wrapper_xlib)( Display*, Window, XIconSize*, int); +extern int (*XSetNormalHints_dylibloader_wrapper_xlib)( Display*, Window, XSizeHints*); +extern void (*XSetRGBColormaps_dylibloader_wrapper_xlib)( Display*, Window, XStandardColormap*, int, Atom); +extern int (*XSetSizeHints_dylibloader_wrapper_xlib)( Display*, Window, XSizeHints*, Atom); +extern int (*XSetStandardProperties_dylibloader_wrapper_xlib)( Display*, Window,const char*,const char*, Pixmap, char**, int, XSizeHints*); +extern void (*XSetTextProperty_dylibloader_wrapper_xlib)( Display*, Window, XTextProperty*, Atom); +extern void (*XSetWMClientMachine_dylibloader_wrapper_xlib)( Display*, Window, XTextProperty*); +extern int (*XSetWMHints_dylibloader_wrapper_xlib)( Display*, Window, XWMHints*); +extern void (*XSetWMIconName_dylibloader_wrapper_xlib)( Display*, Window, XTextProperty*); +extern void (*XSetWMName_dylibloader_wrapper_xlib)( Display*, Window, XTextProperty*); +extern void (*XSetWMNormalHints_dylibloader_wrapper_xlib)( Display*, Window, XSizeHints*); +extern void (*XSetWMProperties_dylibloader_wrapper_xlib)( Display*, Window, XTextProperty*, XTextProperty*, char**, int, XSizeHints*, XWMHints*, XClassHint*); +extern void (*XmbSetWMProperties_dylibloader_wrapper_xlib)( Display*, Window,const char*,const char*, char**, int, XSizeHints*, XWMHints*, XClassHint*); +extern void (*Xutf8SetWMProperties_dylibloader_wrapper_xlib)( Display*, Window,const char*,const char*, char**, int, XSizeHints*, XWMHints*, XClassHint*); +extern void (*XSetWMSizeHints_dylibloader_wrapper_xlib)( Display*, Window, XSizeHints*, Atom); +extern int (*XSetRegion_dylibloader_wrapper_xlib)( Display*, GC, Region); +extern void (*XSetStandardColormap_dylibloader_wrapper_xlib)( Display*, Window, XStandardColormap*, Atom); +extern int (*XSetZoomHints_dylibloader_wrapper_xlib)( Display*, Window, XSizeHints*); +extern int (*XShrinkRegion_dylibloader_wrapper_xlib)( Region, int, int); +extern int (*XStringListToTextProperty_dylibloader_wrapper_xlib)( char**, int, XTextProperty*); +extern int (*XSubtractRegion_dylibloader_wrapper_xlib)( Region, Region, Region); +extern int (*XmbTextListToTextProperty_dylibloader_wrapper_xlib)( Display*, char**, int, XICCEncodingStyle, XTextProperty*); +extern int (*XwcTextListToTextProperty_dylibloader_wrapper_xlib)( Display*, wchar_t**, int, XICCEncodingStyle, XTextProperty*); +extern int (*Xutf8TextListToTextProperty_dylibloader_wrapper_xlib)( Display*, char**, int, XICCEncodingStyle, XTextProperty*); +extern void (*XwcFreeStringList_dylibloader_wrapper_xlib)( wchar_t**); +extern int (*XTextPropertyToStringList_dylibloader_wrapper_xlib)( XTextProperty*, char***, int*); +extern int (*XmbTextPropertyToTextList_dylibloader_wrapper_xlib)( Display*,const XTextProperty*, char***, int*); +extern int (*XwcTextPropertyToTextList_dylibloader_wrapper_xlib)( Display*,const XTextProperty*, wchar_t***, int*); +extern int (*Xutf8TextPropertyToTextList_dylibloader_wrapper_xlib)( Display*,const XTextProperty*, char***, int*); +extern int (*XUnionRectWithRegion_dylibloader_wrapper_xlib)( XRectangle*, Region, Region); +extern int (*XUnionRegion_dylibloader_wrapper_xlib)( Region, Region, Region); +extern int (*XWMGeometry_dylibloader_wrapper_xlib)( Display*, int,const char*,const char*, unsigned int, XSizeHints*, int*, int*, int*, int*, int*); +extern int (*XXorRegion_dylibloader_wrapper_xlib)( Region, Region, Region); +extern int (*XkbIgnoreExtension_dylibloader_wrapper_xlib)( int); +extern Display* (*XkbOpenDisplay_dylibloader_wrapper_xlib)( char*, int*, int*, int*, int*, int*); +extern int (*XkbQueryExtension_dylibloader_wrapper_xlib)( Display*, int*, int*, int*, int*, int*); +extern int (*XkbUseExtension_dylibloader_wrapper_xlib)( Display*, int*, int*); +extern int (*XkbLibraryVersion_dylibloader_wrapper_xlib)( int*, int*); +extern unsigned int (*XkbSetXlibControls_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int); +extern unsigned int (*XkbGetXlibControls_dylibloader_wrapper_xlib)( Display*); +extern unsigned int (*XkbXlibControlsImplemented_dylibloader_wrapper_xlib)( void); +extern void (*XkbSetAtomFuncs_dylibloader_wrapper_xlib)( XkbInternAtomFunc, XkbGetAtomNameFunc); +extern KeySym (*XkbKeycodeToKeysym_dylibloader_wrapper_xlib)( Display*, KeyCode, int, int); +extern unsigned int (*XkbKeysymToModifiers_dylibloader_wrapper_xlib)( Display*, KeySym); +extern int (*XkbLookupKeySym_dylibloader_wrapper_xlib)( Display*, KeyCode, unsigned int, unsigned int*, KeySym*); +extern int (*XkbLookupKeyBinding_dylibloader_wrapper_xlib)( Display*, KeySym, unsigned int, char*, int, int*); +extern int (*XkbTranslateKeyCode_dylibloader_wrapper_xlib)( XkbDescPtr, KeyCode, unsigned int, unsigned int*, KeySym*); +extern int (*XkbTranslateKeySym_dylibloader_wrapper_xlib)( Display*, KeySym*, unsigned int, char*, int, int*); +extern int (*XkbSetAutoRepeatRate_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned int); +extern int (*XkbGetAutoRepeatRate_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int*, unsigned int*); +extern int (*XkbChangeEnabledControls_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned int); +extern int (*XkbDeviceBell_dylibloader_wrapper_xlib)( Display*, Window, int, int, int, int, Atom); +extern int (*XkbForceDeviceBell_dylibloader_wrapper_xlib)( Display*, int, int, int, int); +extern int (*XkbDeviceBellEvent_dylibloader_wrapper_xlib)( Display*, Window, int, int, int, int, Atom); +extern int (*XkbBell_dylibloader_wrapper_xlib)( Display*, Window, int, Atom); +extern int (*XkbForceBell_dylibloader_wrapper_xlib)( Display*, int); +extern int (*XkbBellEvent_dylibloader_wrapper_xlib)( Display*, Window, int, Atom); +extern int (*XkbSelectEvents_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned int); +extern int (*XkbSelectEventDetails_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned long, unsigned long); +extern void (*XkbNoteMapChanges_dylibloader_wrapper_xlib)( XkbMapChangesPtr, XkbMapNotifyEvent*, unsigned int); +extern void (*XkbNoteNameChanges_dylibloader_wrapper_xlib)( XkbNameChangesPtr, XkbNamesNotifyEvent*, unsigned int); +extern int (*XkbGetIndicatorState_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int*); +extern int (*XkbGetIndicatorMap_dylibloader_wrapper_xlib)( Display*, unsigned long, XkbDescPtr); +extern int (*XkbSetIndicatorMap_dylibloader_wrapper_xlib)( Display*, unsigned long, XkbDescPtr); +extern int (*XkbGetNamedIndicator_dylibloader_wrapper_xlib)( Display*, Atom, int*, int*, XkbIndicatorMapPtr, int*); +extern int (*XkbGetNamedDeviceIndicator_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned int, Atom, int*, int*, XkbIndicatorMapPtr, int*); +extern int (*XkbSetNamedIndicator_dylibloader_wrapper_xlib)( Display*, Atom, int, int, int, XkbIndicatorMapPtr); +extern int (*XkbSetNamedDeviceIndicator_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned int, Atom, int, int, int, XkbIndicatorMapPtr); +extern int (*XkbLockModifiers_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned int); +extern int (*XkbLatchModifiers_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned int); +extern int (*XkbLockGroup_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int); +extern int (*XkbLatchGroup_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int); +extern int (*XkbSetServerInternalMods_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int); +extern int (*XkbSetIgnoreLockMods_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int); +extern int (*XkbVirtualModsToReal_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, unsigned int*); +extern int (*XkbComputeEffectiveMap_dylibloader_wrapper_xlib)( XkbDescPtr, XkbKeyTypePtr, unsigned char*); +extern int (*XkbInitCanonicalKeyTypes_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, int); +extern XkbDescPtr (*XkbAllocKeyboard_dylibloader_wrapper_xlib)( void); +extern void (*XkbFreeKeyboard_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, int); +extern int (*XkbAllocClientMap_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, unsigned int); +extern int (*XkbAllocServerMap_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, unsigned int); +extern void (*XkbFreeClientMap_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, int); +extern void (*XkbFreeServerMap_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, int); +extern XkbKeyTypePtr (*XkbAddKeyType_dylibloader_wrapper_xlib)( XkbDescPtr, Atom, int, int, int); +extern int (*XkbAllocIndicatorMaps_dylibloader_wrapper_xlib)( XkbDescPtr); +extern void (*XkbFreeIndicatorMaps_dylibloader_wrapper_xlib)( XkbDescPtr); +extern XkbDescPtr (*XkbGetMap_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int); +extern int (*XkbGetUpdatedMap_dylibloader_wrapper_xlib)( Display*, unsigned int, XkbDescPtr); +extern int (*XkbGetMapChanges_dylibloader_wrapper_xlib)( Display*, XkbDescPtr, XkbMapChangesPtr); +extern int (*XkbRefreshKeyboardMapping_dylibloader_wrapper_xlib)( XkbMapNotifyEvent*); +extern int (*XkbGetKeyTypes_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, XkbDescPtr); +extern int (*XkbGetKeySyms_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, XkbDescPtr); +extern int (*XkbGetKeyActions_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, XkbDescPtr); +extern int (*XkbGetKeyBehaviors_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, XkbDescPtr); +extern int (*XkbGetVirtualMods_dylibloader_wrapper_xlib)( Display*, unsigned int, XkbDescPtr); +extern int (*XkbGetKeyExplicitComponents_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, XkbDescPtr); +extern int (*XkbGetKeyModifierMap_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, XkbDescPtr); +extern int (*XkbGetKeyVirtualModMap_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, XkbDescPtr); +extern int (*XkbAllocControls_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int); +extern void (*XkbFreeControls_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, int); +extern int (*XkbGetControls_dylibloader_wrapper_xlib)( Display*, unsigned long, XkbDescPtr); +extern int (*XkbSetControls_dylibloader_wrapper_xlib)( Display*, unsigned long, XkbDescPtr); +extern void (*XkbNoteControlsChanges_dylibloader_wrapper_xlib)( XkbControlsChangesPtr, XkbControlsNotifyEvent*, unsigned int); +extern int (*XkbAllocCompatMap_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, unsigned int); +extern void (*XkbFreeCompatMap_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, int); +extern int (*XkbGetCompatMap_dylibloader_wrapper_xlib)( Display*, unsigned int, XkbDescPtr); +extern int (*XkbSetCompatMap_dylibloader_wrapper_xlib)( Display*, unsigned int, XkbDescPtr, int); +extern int (*XkbAllocNames_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, int, int); +extern int (*XkbGetNames_dylibloader_wrapper_xlib)( Display*, unsigned int, XkbDescPtr); +extern int (*XkbSetNames_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned int, XkbDescPtr); +extern int (*XkbChangeNames_dylibloader_wrapper_xlib)( Display*, XkbDescPtr, XkbNameChangesPtr); +extern void (*XkbFreeNames_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, int); +extern int (*XkbGetState_dylibloader_wrapper_xlib)( Display*, unsigned int, XkbStatePtr); +extern int (*XkbSetMap_dylibloader_wrapper_xlib)( Display*, unsigned int, XkbDescPtr); +extern int (*XkbChangeMap_dylibloader_wrapper_xlib)( Display*, XkbDescPtr, XkbMapChangesPtr); +extern int (*XkbSetDetectableAutoRepeat_dylibloader_wrapper_xlib)( Display*, int, int*); +extern int (*XkbGetDetectableAutoRepeat_dylibloader_wrapper_xlib)( Display*, int*); +extern int (*XkbSetAutoResetControls_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int*, unsigned int*); +extern int (*XkbGetAutoResetControls_dylibloader_wrapper_xlib)( Display*, unsigned int*, unsigned int*); +extern int (*XkbSetPerClientControls_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int*); +extern int (*XkbGetPerClientControls_dylibloader_wrapper_xlib)( Display*, unsigned int*); +extern int (*XkbCopyKeyType_dylibloader_wrapper_xlib)( XkbKeyTypePtr, XkbKeyTypePtr); +extern int (*XkbCopyKeyTypes_dylibloader_wrapper_xlib)( XkbKeyTypePtr, XkbKeyTypePtr, int); +extern int (*XkbResizeKeyType_dylibloader_wrapper_xlib)( XkbDescPtr, int, int, int, int); +extern KeySym* (*XkbResizeKeySyms_dylibloader_wrapper_xlib)( XkbDescPtr, int, int); +extern XkbAction* (*XkbResizeKeyActions_dylibloader_wrapper_xlib)( XkbDescPtr, int, int); +extern int (*XkbChangeTypesOfKey_dylibloader_wrapper_xlib)( XkbDescPtr, int, int, unsigned int, int*, XkbMapChangesPtr); +extern int (*XkbChangeKeycodeRange_dylibloader_wrapper_xlib)( XkbDescPtr, int, int, XkbChangesPtr); +extern XkbComponentListPtr (*XkbListComponents_dylibloader_wrapper_xlib)( Display*, unsigned int, XkbComponentNamesPtr, int*); +extern void (*XkbFreeComponentList_dylibloader_wrapper_xlib)( XkbComponentListPtr); +extern XkbDescPtr (*XkbGetKeyboard_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int); +extern XkbDescPtr (*XkbGetKeyboardByName_dylibloader_wrapper_xlib)( Display*, unsigned int, XkbComponentNamesPtr, unsigned int, unsigned int, int); +extern int (*XkbKeyTypesForCoreSymbols_dylibloader_wrapper_xlib)( XkbDescPtr, int, KeySym*, unsigned int, int*, KeySym*); +extern int (*XkbApplyCompatMapToKey_dylibloader_wrapper_xlib)( XkbDescPtr, KeyCode, XkbChangesPtr); +extern int (*XkbUpdateMapFromCore_dylibloader_wrapper_xlib)( XkbDescPtr, KeyCode, int, int, KeySym*, XkbChangesPtr); +extern XkbDeviceLedInfoPtr (*XkbAddDeviceLedInfo_dylibloader_wrapper_xlib)( XkbDeviceInfoPtr, unsigned int, unsigned int); +extern int (*XkbResizeDeviceButtonActions_dylibloader_wrapper_xlib)( XkbDeviceInfoPtr, unsigned int); +extern XkbDeviceInfoPtr (*XkbAllocDeviceInfo_dylibloader_wrapper_xlib)( unsigned int, unsigned int, unsigned int); +extern void (*XkbFreeDeviceInfo_dylibloader_wrapper_xlib)( XkbDeviceInfoPtr, unsigned int, int); +extern void (*XkbNoteDeviceChanges_dylibloader_wrapper_xlib)( XkbDeviceChangesPtr, XkbExtensionDeviceNotifyEvent*, unsigned int); +extern XkbDeviceInfoPtr (*XkbGetDeviceInfo_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned int, unsigned int); +extern int (*XkbGetDeviceInfoChanges_dylibloader_wrapper_xlib)( Display*, XkbDeviceInfoPtr, XkbDeviceChangesPtr); +extern int (*XkbGetDeviceButtonActions_dylibloader_wrapper_xlib)( Display*, XkbDeviceInfoPtr, int, unsigned int, unsigned int); +extern int (*XkbGetDeviceLedInfo_dylibloader_wrapper_xlib)( Display*, XkbDeviceInfoPtr, unsigned int, unsigned int, unsigned int); +extern int (*XkbSetDeviceInfo_dylibloader_wrapper_xlib)( Display*, unsigned int, XkbDeviceInfoPtr); +extern int (*XkbChangeDeviceInfo_dylibloader_wrapper_xlib)( Display*, XkbDeviceInfoPtr, XkbDeviceChangesPtr); +extern int (*XkbSetDeviceLedInfo_dylibloader_wrapper_xlib)( Display*, XkbDeviceInfoPtr, unsigned int, unsigned int, unsigned int); +extern int (*XkbSetDeviceButtonActions_dylibloader_wrapper_xlib)( Display*, XkbDeviceInfoPtr, unsigned int, unsigned int); +extern char (*XkbToControl_dylibloader_wrapper_xlib)( char); +extern int (*XkbSetDebuggingFlags_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, char*, unsigned int, unsigned int, unsigned int*, unsigned int*); +extern int (*XkbApplyVirtualModChanges_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, XkbChangesPtr); +extern int (*XkbUpdateActionVirtualMods_dylibloader_wrapper_xlib)( XkbDescPtr, XkbAction*, unsigned int); +extern void (*XkbUpdateKeyTypeVirtualMods_dylibloader_wrapper_xlib)( XkbDescPtr, XkbKeyTypePtr, unsigned int, XkbChangesPtr); +int initialize_xlib(int verbose); +#ifdef __cplusplus +} +#endif +#endif diff --git a/platform/linuxbsd/x11/dynwrappers/xrandr-so_wrap.c b/platform/linuxbsd/x11/dynwrappers/xrandr-so_wrap.c new file mode 100644 index 0000000000..05f98d2506 --- /dev/null +++ b/platform/linuxbsd/x11/dynwrappers/xrandr-so_wrap.c @@ -0,0 +1,797 @@ +// This file is generated. Do not edit! +// see https://github.com/hpvb/dynload-wrapper for details +// generated by generate-wrapper.py 0.3 on 2023-01-23 15:13:54 +// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/extensions/Xrandr.h --sys-include "thirdparty/linuxbsd_headers/X11/extensions/Xrandr.h" --soname libXrandr.so.2 --init-name xrandr --output-header ./platform/linuxbsd/x11/dynwrappers/xrandr-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xrandr-so_wrap.c +// +// NOTE: Generated from Xrandr 1.5.2. +// This has been handpatched to workaround some issues with the generator that +// will be eventually fixed. In this case, non-existent symbols inherited from +// libX11 and libXrender, but absent in libXrandr.so.2, were removed. +#include <stdint.h> + +#define XRRQueryExtension XRRQueryExtension_dylibloader_orig_xrandr +#define XRRQueryVersion XRRQueryVersion_dylibloader_orig_xrandr +#define XRRGetScreenInfo XRRGetScreenInfo_dylibloader_orig_xrandr +#define XRRFreeScreenConfigInfo XRRFreeScreenConfigInfo_dylibloader_orig_xrandr +#define XRRSetScreenConfig XRRSetScreenConfig_dylibloader_orig_xrandr +#define XRRSetScreenConfigAndRate XRRSetScreenConfigAndRate_dylibloader_orig_xrandr +#define XRRConfigRotations XRRConfigRotations_dylibloader_orig_xrandr +#define XRRConfigTimes XRRConfigTimes_dylibloader_orig_xrandr +#define XRRConfigSizes XRRConfigSizes_dylibloader_orig_xrandr +#define XRRConfigRates XRRConfigRates_dylibloader_orig_xrandr +#define XRRConfigCurrentConfiguration XRRConfigCurrentConfiguration_dylibloader_orig_xrandr +#define XRRConfigCurrentRate XRRConfigCurrentRate_dylibloader_orig_xrandr +#define XRRRootToScreen XRRRootToScreen_dylibloader_orig_xrandr +#define XRRSelectInput XRRSelectInput_dylibloader_orig_xrandr +#define XRRRotations XRRRotations_dylibloader_orig_xrandr +#define XRRSizes XRRSizes_dylibloader_orig_xrandr +#define XRRRates XRRRates_dylibloader_orig_xrandr +#define XRRTimes XRRTimes_dylibloader_orig_xrandr +#define XRRGetScreenSizeRange XRRGetScreenSizeRange_dylibloader_orig_xrandr +#define XRRSetScreenSize XRRSetScreenSize_dylibloader_orig_xrandr +#define XRRGetScreenResources XRRGetScreenResources_dylibloader_orig_xrandr +#define XRRFreeScreenResources XRRFreeScreenResources_dylibloader_orig_xrandr +#define XRRGetOutputInfo XRRGetOutputInfo_dylibloader_orig_xrandr +#define XRRFreeOutputInfo XRRFreeOutputInfo_dylibloader_orig_xrandr +#define XRRListOutputProperties XRRListOutputProperties_dylibloader_orig_xrandr +#define XRRQueryOutputProperty XRRQueryOutputProperty_dylibloader_orig_xrandr +#define XRRConfigureOutputProperty XRRConfigureOutputProperty_dylibloader_orig_xrandr +#define XRRChangeOutputProperty XRRChangeOutputProperty_dylibloader_orig_xrandr +#define XRRDeleteOutputProperty XRRDeleteOutputProperty_dylibloader_orig_xrandr +#define XRRGetOutputProperty XRRGetOutputProperty_dylibloader_orig_xrandr +#define XRRAllocModeInfo XRRAllocModeInfo_dylibloader_orig_xrandr +#define XRRCreateMode XRRCreateMode_dylibloader_orig_xrandr +#define XRRDestroyMode XRRDestroyMode_dylibloader_orig_xrandr +#define XRRAddOutputMode XRRAddOutputMode_dylibloader_orig_xrandr +#define XRRDeleteOutputMode XRRDeleteOutputMode_dylibloader_orig_xrandr +#define XRRFreeModeInfo XRRFreeModeInfo_dylibloader_orig_xrandr +#define XRRGetCrtcInfo XRRGetCrtcInfo_dylibloader_orig_xrandr +#define XRRFreeCrtcInfo XRRFreeCrtcInfo_dylibloader_orig_xrandr +#define XRRSetCrtcConfig XRRSetCrtcConfig_dylibloader_orig_xrandr +#define XRRGetCrtcGammaSize XRRGetCrtcGammaSize_dylibloader_orig_xrandr +#define XRRGetCrtcGamma XRRGetCrtcGamma_dylibloader_orig_xrandr +#define XRRAllocGamma XRRAllocGamma_dylibloader_orig_xrandr +#define XRRSetCrtcGamma XRRSetCrtcGamma_dylibloader_orig_xrandr +#define XRRFreeGamma XRRFreeGamma_dylibloader_orig_xrandr +#define XRRGetScreenResourcesCurrent XRRGetScreenResourcesCurrent_dylibloader_orig_xrandr +#define XRRSetCrtcTransform XRRSetCrtcTransform_dylibloader_orig_xrandr +#define XRRGetCrtcTransform XRRGetCrtcTransform_dylibloader_orig_xrandr +#define XRRUpdateConfiguration XRRUpdateConfiguration_dylibloader_orig_xrandr +#define XRRGetPanning XRRGetPanning_dylibloader_orig_xrandr +#define XRRFreePanning XRRFreePanning_dylibloader_orig_xrandr +#define XRRSetPanning XRRSetPanning_dylibloader_orig_xrandr +#define XRRSetOutputPrimary XRRSetOutputPrimary_dylibloader_orig_xrandr +#define XRRGetOutputPrimary XRRGetOutputPrimary_dylibloader_orig_xrandr +#define XRRGetProviderResources XRRGetProviderResources_dylibloader_orig_xrandr +#define XRRFreeProviderResources XRRFreeProviderResources_dylibloader_orig_xrandr +#define XRRGetProviderInfo XRRGetProviderInfo_dylibloader_orig_xrandr +#define XRRFreeProviderInfo XRRFreeProviderInfo_dylibloader_orig_xrandr +#define XRRSetProviderOutputSource XRRSetProviderOutputSource_dylibloader_orig_xrandr +#define XRRSetProviderOffloadSink XRRSetProviderOffloadSink_dylibloader_orig_xrandr +#define XRRListProviderProperties XRRListProviderProperties_dylibloader_orig_xrandr +#define XRRQueryProviderProperty XRRQueryProviderProperty_dylibloader_orig_xrandr +#define XRRConfigureProviderProperty XRRConfigureProviderProperty_dylibloader_orig_xrandr +#define XRRChangeProviderProperty XRRChangeProviderProperty_dylibloader_orig_xrandr +#define XRRDeleteProviderProperty XRRDeleteProviderProperty_dylibloader_orig_xrandr +#define XRRGetProviderProperty XRRGetProviderProperty_dylibloader_orig_xrandr +#define XRRAllocateMonitor XRRAllocateMonitor_dylibloader_orig_xrandr +#define XRRGetMonitors XRRGetMonitors_dylibloader_orig_xrandr +#define XRRSetMonitor XRRSetMonitor_dylibloader_orig_xrandr +#define XRRDeleteMonitor XRRDeleteMonitor_dylibloader_orig_xrandr +#define XRRFreeMonitors XRRFreeMonitors_dylibloader_orig_xrandr +#include "thirdparty/linuxbsd_headers/X11/extensions/Xrandr.h" +#undef XRRQueryExtension +#undef XRRQueryVersion +#undef XRRGetScreenInfo +#undef XRRFreeScreenConfigInfo +#undef XRRSetScreenConfig +#undef XRRSetScreenConfigAndRate +#undef XRRConfigRotations +#undef XRRConfigTimes +#undef XRRConfigSizes +#undef XRRConfigRates +#undef XRRConfigCurrentConfiguration +#undef XRRConfigCurrentRate +#undef XRRRootToScreen +#undef XRRSelectInput +#undef XRRRotations +#undef XRRSizes +#undef XRRRates +#undef XRRTimes +#undef XRRGetScreenSizeRange +#undef XRRSetScreenSize +#undef XRRGetScreenResources +#undef XRRFreeScreenResources +#undef XRRGetOutputInfo +#undef XRRFreeOutputInfo +#undef XRRListOutputProperties +#undef XRRQueryOutputProperty +#undef XRRConfigureOutputProperty +#undef XRRChangeOutputProperty +#undef XRRDeleteOutputProperty +#undef XRRGetOutputProperty +#undef XRRAllocModeInfo +#undef XRRCreateMode +#undef XRRDestroyMode +#undef XRRAddOutputMode +#undef XRRDeleteOutputMode +#undef XRRFreeModeInfo +#undef XRRGetCrtcInfo +#undef XRRFreeCrtcInfo +#undef XRRSetCrtcConfig +#undef XRRGetCrtcGammaSize +#undef XRRGetCrtcGamma +#undef XRRAllocGamma +#undef XRRSetCrtcGamma +#undef XRRFreeGamma +#undef XRRGetScreenResourcesCurrent +#undef XRRSetCrtcTransform +#undef XRRGetCrtcTransform +#undef XRRUpdateConfiguration +#undef XRRGetPanning +#undef XRRFreePanning +#undef XRRSetPanning +#undef XRRSetOutputPrimary +#undef XRRGetOutputPrimary +#undef XRRGetProviderResources +#undef XRRFreeProviderResources +#undef XRRGetProviderInfo +#undef XRRFreeProviderInfo +#undef XRRSetProviderOutputSource +#undef XRRSetProviderOffloadSink +#undef XRRListProviderProperties +#undef XRRQueryProviderProperty +#undef XRRConfigureProviderProperty +#undef XRRChangeProviderProperty +#undef XRRDeleteProviderProperty +#undef XRRGetProviderProperty +#undef XRRAllocateMonitor +#undef XRRGetMonitors +#undef XRRSetMonitor +#undef XRRDeleteMonitor +#undef XRRFreeMonitors +#include <dlfcn.h> +#include <stdio.h> +int (*XRRQueryExtension_dylibloader_wrapper_xrandr)( Display*, int*, int*); +int (*XRRQueryVersion_dylibloader_wrapper_xrandr)( Display*, int*, int*); +XRRScreenConfiguration* (*XRRGetScreenInfo_dylibloader_wrapper_xrandr)( Display*, Window); +void (*XRRFreeScreenConfigInfo_dylibloader_wrapper_xrandr)( XRRScreenConfiguration*); +int (*XRRSetScreenConfig_dylibloader_wrapper_xrandr)( Display*, XRRScreenConfiguration*, Drawable, int, Rotation, Time); +int (*XRRSetScreenConfigAndRate_dylibloader_wrapper_xrandr)( Display*, XRRScreenConfiguration*, Drawable, int, Rotation, short, Time); +Rotation (*XRRConfigRotations_dylibloader_wrapper_xrandr)( XRRScreenConfiguration*, Rotation*); +Time (*XRRConfigTimes_dylibloader_wrapper_xrandr)( XRRScreenConfiguration*, Time*); +XRRScreenSize* (*XRRConfigSizes_dylibloader_wrapper_xrandr)( XRRScreenConfiguration*, int*); +short* (*XRRConfigRates_dylibloader_wrapper_xrandr)( XRRScreenConfiguration*, int, int*); +SizeID (*XRRConfigCurrentConfiguration_dylibloader_wrapper_xrandr)( XRRScreenConfiguration*, Rotation*); +short (*XRRConfigCurrentRate_dylibloader_wrapper_xrandr)( XRRScreenConfiguration*); +int (*XRRRootToScreen_dylibloader_wrapper_xrandr)( Display*, Window); +void (*XRRSelectInput_dylibloader_wrapper_xrandr)( Display*, Window, int); +Rotation (*XRRRotations_dylibloader_wrapper_xrandr)( Display*, int, Rotation*); +XRRScreenSize* (*XRRSizes_dylibloader_wrapper_xrandr)( Display*, int, int*); +short* (*XRRRates_dylibloader_wrapper_xrandr)( Display*, int, int, int*); +Time (*XRRTimes_dylibloader_wrapper_xrandr)( Display*, int, Time*); +int (*XRRGetScreenSizeRange_dylibloader_wrapper_xrandr)( Display*, Window, int*, int*, int*, int*); +void (*XRRSetScreenSize_dylibloader_wrapper_xrandr)( Display*, Window, int, int, int, int); +XRRScreenResources* (*XRRGetScreenResources_dylibloader_wrapper_xrandr)( Display*, Window); +void (*XRRFreeScreenResources_dylibloader_wrapper_xrandr)( XRRScreenResources*); +XRROutputInfo* (*XRRGetOutputInfo_dylibloader_wrapper_xrandr)( Display*, XRRScreenResources*, RROutput); +void (*XRRFreeOutputInfo_dylibloader_wrapper_xrandr)( XRROutputInfo*); +Atom* (*XRRListOutputProperties_dylibloader_wrapper_xrandr)( Display*, RROutput, int*); +XRRPropertyInfo* (*XRRQueryOutputProperty_dylibloader_wrapper_xrandr)( Display*, RROutput, Atom); +void (*XRRConfigureOutputProperty_dylibloader_wrapper_xrandr)( Display*, RROutput, Atom, int, int, int, long*); +void (*XRRChangeOutputProperty_dylibloader_wrapper_xrandr)( Display*, RROutput, Atom, Atom, int, int,const unsigned char*, int); +void (*XRRDeleteOutputProperty_dylibloader_wrapper_xrandr)( Display*, RROutput, Atom); +int (*XRRGetOutputProperty_dylibloader_wrapper_xrandr)( Display*, RROutput, Atom, long, long, int, int, Atom, Atom*, int*, unsigned long*, unsigned long*, unsigned char**); +XRRModeInfo* (*XRRAllocModeInfo_dylibloader_wrapper_xrandr)(const char*, int); +RRMode (*XRRCreateMode_dylibloader_wrapper_xrandr)( Display*, Window, XRRModeInfo*); +void (*XRRDestroyMode_dylibloader_wrapper_xrandr)( Display*, RRMode); +void (*XRRAddOutputMode_dylibloader_wrapper_xrandr)( Display*, RROutput, RRMode); +void (*XRRDeleteOutputMode_dylibloader_wrapper_xrandr)( Display*, RROutput, RRMode); +void (*XRRFreeModeInfo_dylibloader_wrapper_xrandr)( XRRModeInfo*); +XRRCrtcInfo* (*XRRGetCrtcInfo_dylibloader_wrapper_xrandr)( Display*, XRRScreenResources*, RRCrtc); +void (*XRRFreeCrtcInfo_dylibloader_wrapper_xrandr)( XRRCrtcInfo*); +int (*XRRSetCrtcConfig_dylibloader_wrapper_xrandr)( Display*, XRRScreenResources*, RRCrtc, Time, int, int, RRMode, Rotation, RROutput*, int); +int (*XRRGetCrtcGammaSize_dylibloader_wrapper_xrandr)( Display*, RRCrtc); +XRRCrtcGamma* (*XRRGetCrtcGamma_dylibloader_wrapper_xrandr)( Display*, RRCrtc); +XRRCrtcGamma* (*XRRAllocGamma_dylibloader_wrapper_xrandr)( int); +void (*XRRSetCrtcGamma_dylibloader_wrapper_xrandr)( Display*, RRCrtc, XRRCrtcGamma*); +void (*XRRFreeGamma_dylibloader_wrapper_xrandr)( XRRCrtcGamma*); +XRRScreenResources* (*XRRGetScreenResourcesCurrent_dylibloader_wrapper_xrandr)( Display*, Window); +void (*XRRSetCrtcTransform_dylibloader_wrapper_xrandr)( Display*, RRCrtc, XTransform*,const char*, XFixed*, int); +int (*XRRGetCrtcTransform_dylibloader_wrapper_xrandr)( Display*, RRCrtc, XRRCrtcTransformAttributes**); +int (*XRRUpdateConfiguration_dylibloader_wrapper_xrandr)( XEvent*); +XRRPanning* (*XRRGetPanning_dylibloader_wrapper_xrandr)( Display*, XRRScreenResources*, RRCrtc); +void (*XRRFreePanning_dylibloader_wrapper_xrandr)( XRRPanning*); +int (*XRRSetPanning_dylibloader_wrapper_xrandr)( Display*, XRRScreenResources*, RRCrtc, XRRPanning*); +void (*XRRSetOutputPrimary_dylibloader_wrapper_xrandr)( Display*, Window, RROutput); +RROutput (*XRRGetOutputPrimary_dylibloader_wrapper_xrandr)( Display*, Window); +XRRProviderResources* (*XRRGetProviderResources_dylibloader_wrapper_xrandr)( Display*, Window); +void (*XRRFreeProviderResources_dylibloader_wrapper_xrandr)( XRRProviderResources*); +XRRProviderInfo* (*XRRGetProviderInfo_dylibloader_wrapper_xrandr)( Display*, XRRScreenResources*, RRProvider); +void (*XRRFreeProviderInfo_dylibloader_wrapper_xrandr)( XRRProviderInfo*); +int (*XRRSetProviderOutputSource_dylibloader_wrapper_xrandr)( Display*, XID, XID); +int (*XRRSetProviderOffloadSink_dylibloader_wrapper_xrandr)( Display*, XID, XID); +Atom* (*XRRListProviderProperties_dylibloader_wrapper_xrandr)( Display*, RRProvider, int*); +XRRPropertyInfo* (*XRRQueryProviderProperty_dylibloader_wrapper_xrandr)( Display*, RRProvider, Atom); +void (*XRRConfigureProviderProperty_dylibloader_wrapper_xrandr)( Display*, RRProvider, Atom, int, int, int, long*); +void (*XRRChangeProviderProperty_dylibloader_wrapper_xrandr)( Display*, RRProvider, Atom, Atom, int, int,const unsigned char*, int); +void (*XRRDeleteProviderProperty_dylibloader_wrapper_xrandr)( Display*, RRProvider, Atom); +int (*XRRGetProviderProperty_dylibloader_wrapper_xrandr)( Display*, RRProvider, Atom, long, long, int, int, Atom, Atom*, int*, unsigned long*, unsigned long*, unsigned char**); +XRRMonitorInfo* (*XRRAllocateMonitor_dylibloader_wrapper_xrandr)( Display*, int); +XRRMonitorInfo* (*XRRGetMonitors_dylibloader_wrapper_xrandr)( Display*, Window, int, int*); +void (*XRRSetMonitor_dylibloader_wrapper_xrandr)( Display*, Window, XRRMonitorInfo*); +void (*XRRDeleteMonitor_dylibloader_wrapper_xrandr)( Display*, Window, Atom); +void (*XRRFreeMonitors_dylibloader_wrapper_xrandr)( XRRMonitorInfo*); +int initialize_xrandr(int verbose) { + void *handle; + char *error; + handle = dlopen("libXrandr.so.2", RTLD_LAZY); + if (!handle) { + if (verbose) { + fprintf(stderr, "%s\n", dlerror()); + } + return(1); + } + dlerror(); +// XRRQueryExtension + *(void **) (&XRRQueryExtension_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRQueryExtension"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRQueryVersion + *(void **) (&XRRQueryVersion_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRQueryVersion"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRGetScreenInfo + *(void **) (&XRRGetScreenInfo_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRGetScreenInfo"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRFreeScreenConfigInfo + *(void **) (&XRRFreeScreenConfigInfo_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRFreeScreenConfigInfo"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRSetScreenConfig + *(void **) (&XRRSetScreenConfig_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRSetScreenConfig"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRSetScreenConfigAndRate + *(void **) (&XRRSetScreenConfigAndRate_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRSetScreenConfigAndRate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRConfigRotations + *(void **) (&XRRConfigRotations_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRConfigRotations"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRConfigTimes + *(void **) (&XRRConfigTimes_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRConfigTimes"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRConfigSizes + *(void **) (&XRRConfigSizes_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRConfigSizes"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRConfigRates + *(void **) (&XRRConfigRates_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRConfigRates"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRConfigCurrentConfiguration + *(void **) (&XRRConfigCurrentConfiguration_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRConfigCurrentConfiguration"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRConfigCurrentRate + *(void **) (&XRRConfigCurrentRate_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRConfigCurrentRate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRRootToScreen + *(void **) (&XRRRootToScreen_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRRootToScreen"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRSelectInput + *(void **) (&XRRSelectInput_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRSelectInput"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRRotations + *(void **) (&XRRRotations_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRRotations"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRSizes + *(void **) (&XRRSizes_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRSizes"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRRates + *(void **) (&XRRRates_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRRates"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRTimes + *(void **) (&XRRTimes_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRTimes"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRGetScreenSizeRange + *(void **) (&XRRGetScreenSizeRange_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRGetScreenSizeRange"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRSetScreenSize + *(void **) (&XRRSetScreenSize_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRSetScreenSize"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRGetScreenResources + *(void **) (&XRRGetScreenResources_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRGetScreenResources"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRFreeScreenResources + *(void **) (&XRRFreeScreenResources_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRFreeScreenResources"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRGetOutputInfo + *(void **) (&XRRGetOutputInfo_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRGetOutputInfo"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRFreeOutputInfo + *(void **) (&XRRFreeOutputInfo_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRFreeOutputInfo"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRListOutputProperties + *(void **) (&XRRListOutputProperties_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRListOutputProperties"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRQueryOutputProperty + *(void **) (&XRRQueryOutputProperty_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRQueryOutputProperty"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRConfigureOutputProperty + *(void **) (&XRRConfigureOutputProperty_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRConfigureOutputProperty"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRChangeOutputProperty + *(void **) (&XRRChangeOutputProperty_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRChangeOutputProperty"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRDeleteOutputProperty + *(void **) (&XRRDeleteOutputProperty_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRDeleteOutputProperty"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRGetOutputProperty + *(void **) (&XRRGetOutputProperty_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRGetOutputProperty"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRAllocModeInfo + *(void **) (&XRRAllocModeInfo_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRAllocModeInfo"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRCreateMode + *(void **) (&XRRCreateMode_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRCreateMode"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRDestroyMode + *(void **) (&XRRDestroyMode_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRDestroyMode"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRAddOutputMode + *(void **) (&XRRAddOutputMode_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRAddOutputMode"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRDeleteOutputMode + *(void **) (&XRRDeleteOutputMode_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRDeleteOutputMode"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRFreeModeInfo + *(void **) (&XRRFreeModeInfo_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRFreeModeInfo"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRGetCrtcInfo + *(void **) (&XRRGetCrtcInfo_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRGetCrtcInfo"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRFreeCrtcInfo + *(void **) (&XRRFreeCrtcInfo_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRFreeCrtcInfo"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRSetCrtcConfig + *(void **) (&XRRSetCrtcConfig_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRSetCrtcConfig"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRGetCrtcGammaSize + *(void **) (&XRRGetCrtcGammaSize_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRGetCrtcGammaSize"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRGetCrtcGamma + *(void **) (&XRRGetCrtcGamma_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRGetCrtcGamma"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRAllocGamma + *(void **) (&XRRAllocGamma_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRAllocGamma"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRSetCrtcGamma + *(void **) (&XRRSetCrtcGamma_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRSetCrtcGamma"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRFreeGamma + *(void **) (&XRRFreeGamma_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRFreeGamma"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRGetScreenResourcesCurrent + *(void **) (&XRRGetScreenResourcesCurrent_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRGetScreenResourcesCurrent"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRSetCrtcTransform + *(void **) (&XRRSetCrtcTransform_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRSetCrtcTransform"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRGetCrtcTransform + *(void **) (&XRRGetCrtcTransform_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRGetCrtcTransform"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRUpdateConfiguration + *(void **) (&XRRUpdateConfiguration_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRUpdateConfiguration"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRGetPanning + *(void **) (&XRRGetPanning_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRGetPanning"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRFreePanning + *(void **) (&XRRFreePanning_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRFreePanning"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRSetPanning + *(void **) (&XRRSetPanning_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRSetPanning"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRSetOutputPrimary + *(void **) (&XRRSetOutputPrimary_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRSetOutputPrimary"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRGetOutputPrimary + *(void **) (&XRRGetOutputPrimary_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRGetOutputPrimary"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRGetProviderResources + *(void **) (&XRRGetProviderResources_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRGetProviderResources"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRFreeProviderResources + *(void **) (&XRRFreeProviderResources_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRFreeProviderResources"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRGetProviderInfo + *(void **) (&XRRGetProviderInfo_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRGetProviderInfo"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRFreeProviderInfo + *(void **) (&XRRFreeProviderInfo_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRFreeProviderInfo"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRSetProviderOutputSource + *(void **) (&XRRSetProviderOutputSource_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRSetProviderOutputSource"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRSetProviderOffloadSink + *(void **) (&XRRSetProviderOffloadSink_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRSetProviderOffloadSink"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRListProviderProperties + *(void **) (&XRRListProviderProperties_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRListProviderProperties"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRQueryProviderProperty + *(void **) (&XRRQueryProviderProperty_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRQueryProviderProperty"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRConfigureProviderProperty + *(void **) (&XRRConfigureProviderProperty_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRConfigureProviderProperty"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRChangeProviderProperty + *(void **) (&XRRChangeProviderProperty_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRChangeProviderProperty"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRDeleteProviderProperty + *(void **) (&XRRDeleteProviderProperty_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRDeleteProviderProperty"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRGetProviderProperty + *(void **) (&XRRGetProviderProperty_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRGetProviderProperty"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRAllocateMonitor + *(void **) (&XRRAllocateMonitor_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRAllocateMonitor"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRGetMonitors + *(void **) (&XRRGetMonitors_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRGetMonitors"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRSetMonitor + *(void **) (&XRRSetMonitor_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRSetMonitor"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRDeleteMonitor + *(void **) (&XRRDeleteMonitor_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRDeleteMonitor"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRRFreeMonitors + *(void **) (&XRRFreeMonitors_dylibloader_wrapper_xrandr) = dlsym(handle, "XRRFreeMonitors"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +return 0; +} diff --git a/platform/linuxbsd/x11/dynwrappers/xrandr-so_wrap.h b/platform/linuxbsd/x11/dynwrappers/xrandr-so_wrap.h new file mode 100644 index 0000000000..db5d44203d --- /dev/null +++ b/platform/linuxbsd/x11/dynwrappers/xrandr-so_wrap.h @@ -0,0 +1,302 @@ +#ifndef DYLIBLOAD_WRAPPER_XRANDR +#define DYLIBLOAD_WRAPPER_XRANDR +// This file is generated. Do not edit! +// see https://github.com/hpvb/dynload-wrapper for details +// generated by generate-wrapper.py 0.3 on 2023-01-23 15:13:54 +// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/extensions/Xrandr.h --sys-include "thirdparty/linuxbsd_headers/X11/extensions/Xrandr.h" --soname libXrandr.so.2 --init-name xrandr --output-header ./platform/linuxbsd/x11/dynwrappers/xrandr-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xrandr-so_wrap.c +// +// NOTE: Generated from Xrandr 1.5.2. +// This has been handpatched to workaround some issues with the generator that +// will be eventually fixed. In this case, non-existent symbols inherited from +// libX11 and libXrender, but absent in libXrandr.so.2, were removed. +#include <stdint.h> + +#define XRRQueryExtension XRRQueryExtension_dylibloader_orig_xrandr +#define XRRQueryVersion XRRQueryVersion_dylibloader_orig_xrandr +#define XRRGetScreenInfo XRRGetScreenInfo_dylibloader_orig_xrandr +#define XRRFreeScreenConfigInfo XRRFreeScreenConfigInfo_dylibloader_orig_xrandr +#define XRRSetScreenConfig XRRSetScreenConfig_dylibloader_orig_xrandr +#define XRRSetScreenConfigAndRate XRRSetScreenConfigAndRate_dylibloader_orig_xrandr +#define XRRConfigRotations XRRConfigRotations_dylibloader_orig_xrandr +#define XRRConfigTimes XRRConfigTimes_dylibloader_orig_xrandr +#define XRRConfigSizes XRRConfigSizes_dylibloader_orig_xrandr +#define XRRConfigRates XRRConfigRates_dylibloader_orig_xrandr +#define XRRConfigCurrentConfiguration XRRConfigCurrentConfiguration_dylibloader_orig_xrandr +#define XRRConfigCurrentRate XRRConfigCurrentRate_dylibloader_orig_xrandr +#define XRRRootToScreen XRRRootToScreen_dylibloader_orig_xrandr +#define XRRSelectInput XRRSelectInput_dylibloader_orig_xrandr +#define XRRRotations XRRRotations_dylibloader_orig_xrandr +#define XRRSizes XRRSizes_dylibloader_orig_xrandr +#define XRRRates XRRRates_dylibloader_orig_xrandr +#define XRRTimes XRRTimes_dylibloader_orig_xrandr +#define XRRGetScreenSizeRange XRRGetScreenSizeRange_dylibloader_orig_xrandr +#define XRRSetScreenSize XRRSetScreenSize_dylibloader_orig_xrandr +#define XRRGetScreenResources XRRGetScreenResources_dylibloader_orig_xrandr +#define XRRFreeScreenResources XRRFreeScreenResources_dylibloader_orig_xrandr +#define XRRGetOutputInfo XRRGetOutputInfo_dylibloader_orig_xrandr +#define XRRFreeOutputInfo XRRFreeOutputInfo_dylibloader_orig_xrandr +#define XRRListOutputProperties XRRListOutputProperties_dylibloader_orig_xrandr +#define XRRQueryOutputProperty XRRQueryOutputProperty_dylibloader_orig_xrandr +#define XRRConfigureOutputProperty XRRConfigureOutputProperty_dylibloader_orig_xrandr +#define XRRChangeOutputProperty XRRChangeOutputProperty_dylibloader_orig_xrandr +#define XRRDeleteOutputProperty XRRDeleteOutputProperty_dylibloader_orig_xrandr +#define XRRGetOutputProperty XRRGetOutputProperty_dylibloader_orig_xrandr +#define XRRAllocModeInfo XRRAllocModeInfo_dylibloader_orig_xrandr +#define XRRCreateMode XRRCreateMode_dylibloader_orig_xrandr +#define XRRDestroyMode XRRDestroyMode_dylibloader_orig_xrandr +#define XRRAddOutputMode XRRAddOutputMode_dylibloader_orig_xrandr +#define XRRDeleteOutputMode XRRDeleteOutputMode_dylibloader_orig_xrandr +#define XRRFreeModeInfo XRRFreeModeInfo_dylibloader_orig_xrandr +#define XRRGetCrtcInfo XRRGetCrtcInfo_dylibloader_orig_xrandr +#define XRRFreeCrtcInfo XRRFreeCrtcInfo_dylibloader_orig_xrandr +#define XRRSetCrtcConfig XRRSetCrtcConfig_dylibloader_orig_xrandr +#define XRRGetCrtcGammaSize XRRGetCrtcGammaSize_dylibloader_orig_xrandr +#define XRRGetCrtcGamma XRRGetCrtcGamma_dylibloader_orig_xrandr +#define XRRAllocGamma XRRAllocGamma_dylibloader_orig_xrandr +#define XRRSetCrtcGamma XRRSetCrtcGamma_dylibloader_orig_xrandr +#define XRRFreeGamma XRRFreeGamma_dylibloader_orig_xrandr +#define XRRGetScreenResourcesCurrent XRRGetScreenResourcesCurrent_dylibloader_orig_xrandr +#define XRRSetCrtcTransform XRRSetCrtcTransform_dylibloader_orig_xrandr +#define XRRGetCrtcTransform XRRGetCrtcTransform_dylibloader_orig_xrandr +#define XRRUpdateConfiguration XRRUpdateConfiguration_dylibloader_orig_xrandr +#define XRRGetPanning XRRGetPanning_dylibloader_orig_xrandr +#define XRRFreePanning XRRFreePanning_dylibloader_orig_xrandr +#define XRRSetPanning XRRSetPanning_dylibloader_orig_xrandr +#define XRRSetOutputPrimary XRRSetOutputPrimary_dylibloader_orig_xrandr +#define XRRGetOutputPrimary XRRGetOutputPrimary_dylibloader_orig_xrandr +#define XRRGetProviderResources XRRGetProviderResources_dylibloader_orig_xrandr +#define XRRFreeProviderResources XRRFreeProviderResources_dylibloader_orig_xrandr +#define XRRGetProviderInfo XRRGetProviderInfo_dylibloader_orig_xrandr +#define XRRFreeProviderInfo XRRFreeProviderInfo_dylibloader_orig_xrandr +#define XRRSetProviderOutputSource XRRSetProviderOutputSource_dylibloader_orig_xrandr +#define XRRSetProviderOffloadSink XRRSetProviderOffloadSink_dylibloader_orig_xrandr +#define XRRListProviderProperties XRRListProviderProperties_dylibloader_orig_xrandr +#define XRRQueryProviderProperty XRRQueryProviderProperty_dylibloader_orig_xrandr +#define XRRConfigureProviderProperty XRRConfigureProviderProperty_dylibloader_orig_xrandr +#define XRRChangeProviderProperty XRRChangeProviderProperty_dylibloader_orig_xrandr +#define XRRDeleteProviderProperty XRRDeleteProviderProperty_dylibloader_orig_xrandr +#define XRRGetProviderProperty XRRGetProviderProperty_dylibloader_orig_xrandr +#define XRRAllocateMonitor XRRAllocateMonitor_dylibloader_orig_xrandr +#define XRRGetMonitors XRRGetMonitors_dylibloader_orig_xrandr +#define XRRSetMonitor XRRSetMonitor_dylibloader_orig_xrandr +#define XRRDeleteMonitor XRRDeleteMonitor_dylibloader_orig_xrandr +#define XRRFreeMonitors XRRFreeMonitors_dylibloader_orig_xrandr +#include "thirdparty/linuxbsd_headers/X11/extensions/Xrandr.h" +#undef XRRQueryExtension +#undef XRRQueryVersion +#undef XRRGetScreenInfo +#undef XRRFreeScreenConfigInfo +#undef XRRSetScreenConfig +#undef XRRSetScreenConfigAndRate +#undef XRRConfigRotations +#undef XRRConfigTimes +#undef XRRConfigSizes +#undef XRRConfigRates +#undef XRRConfigCurrentConfiguration +#undef XRRConfigCurrentRate +#undef XRRRootToScreen +#undef XRRSelectInput +#undef XRRRotations +#undef XRRSizes +#undef XRRRates +#undef XRRTimes +#undef XRRGetScreenSizeRange +#undef XRRSetScreenSize +#undef XRRGetScreenResources +#undef XRRFreeScreenResources +#undef XRRGetOutputInfo +#undef XRRFreeOutputInfo +#undef XRRListOutputProperties +#undef XRRQueryOutputProperty +#undef XRRConfigureOutputProperty +#undef XRRChangeOutputProperty +#undef XRRDeleteOutputProperty +#undef XRRGetOutputProperty +#undef XRRAllocModeInfo +#undef XRRCreateMode +#undef XRRDestroyMode +#undef XRRAddOutputMode +#undef XRRDeleteOutputMode +#undef XRRFreeModeInfo +#undef XRRGetCrtcInfo +#undef XRRFreeCrtcInfo +#undef XRRSetCrtcConfig +#undef XRRGetCrtcGammaSize +#undef XRRGetCrtcGamma +#undef XRRAllocGamma +#undef XRRSetCrtcGamma +#undef XRRFreeGamma +#undef XRRGetScreenResourcesCurrent +#undef XRRSetCrtcTransform +#undef XRRGetCrtcTransform +#undef XRRUpdateConfiguration +#undef XRRGetPanning +#undef XRRFreePanning +#undef XRRSetPanning +#undef XRRSetOutputPrimary +#undef XRRGetOutputPrimary +#undef XRRGetProviderResources +#undef XRRFreeProviderResources +#undef XRRGetProviderInfo +#undef XRRFreeProviderInfo +#undef XRRSetProviderOutputSource +#undef XRRSetProviderOffloadSink +#undef XRRListProviderProperties +#undef XRRQueryProviderProperty +#undef XRRConfigureProviderProperty +#undef XRRChangeProviderProperty +#undef XRRDeleteProviderProperty +#undef XRRGetProviderProperty +#undef XRRAllocateMonitor +#undef XRRGetMonitors +#undef XRRSetMonitor +#undef XRRDeleteMonitor +#undef XRRFreeMonitors +#ifdef __cplusplus +extern "C" { +#endif +#define XRRQueryExtension XRRQueryExtension_dylibloader_wrapper_xrandr +#define XRRQueryVersion XRRQueryVersion_dylibloader_wrapper_xrandr +#define XRRGetScreenInfo XRRGetScreenInfo_dylibloader_wrapper_xrandr +#define XRRFreeScreenConfigInfo XRRFreeScreenConfigInfo_dylibloader_wrapper_xrandr +#define XRRSetScreenConfig XRRSetScreenConfig_dylibloader_wrapper_xrandr +#define XRRSetScreenConfigAndRate XRRSetScreenConfigAndRate_dylibloader_wrapper_xrandr +#define XRRConfigRotations XRRConfigRotations_dylibloader_wrapper_xrandr +#define XRRConfigTimes XRRConfigTimes_dylibloader_wrapper_xrandr +#define XRRConfigSizes XRRConfigSizes_dylibloader_wrapper_xrandr +#define XRRConfigRates XRRConfigRates_dylibloader_wrapper_xrandr +#define XRRConfigCurrentConfiguration XRRConfigCurrentConfiguration_dylibloader_wrapper_xrandr +#define XRRConfigCurrentRate XRRConfigCurrentRate_dylibloader_wrapper_xrandr +#define XRRRootToScreen XRRRootToScreen_dylibloader_wrapper_xrandr +#define XRRSelectInput XRRSelectInput_dylibloader_wrapper_xrandr +#define XRRRotations XRRRotations_dylibloader_wrapper_xrandr +#define XRRSizes XRRSizes_dylibloader_wrapper_xrandr +#define XRRRates XRRRates_dylibloader_wrapper_xrandr +#define XRRTimes XRRTimes_dylibloader_wrapper_xrandr +#define XRRGetScreenSizeRange XRRGetScreenSizeRange_dylibloader_wrapper_xrandr +#define XRRSetScreenSize XRRSetScreenSize_dylibloader_wrapper_xrandr +#define XRRGetScreenResources XRRGetScreenResources_dylibloader_wrapper_xrandr +#define XRRFreeScreenResources XRRFreeScreenResources_dylibloader_wrapper_xrandr +#define XRRGetOutputInfo XRRGetOutputInfo_dylibloader_wrapper_xrandr +#define XRRFreeOutputInfo XRRFreeOutputInfo_dylibloader_wrapper_xrandr +#define XRRListOutputProperties XRRListOutputProperties_dylibloader_wrapper_xrandr +#define XRRQueryOutputProperty XRRQueryOutputProperty_dylibloader_wrapper_xrandr +#define XRRConfigureOutputProperty XRRConfigureOutputProperty_dylibloader_wrapper_xrandr +#define XRRChangeOutputProperty XRRChangeOutputProperty_dylibloader_wrapper_xrandr +#define XRRDeleteOutputProperty XRRDeleteOutputProperty_dylibloader_wrapper_xrandr +#define XRRGetOutputProperty XRRGetOutputProperty_dylibloader_wrapper_xrandr +#define XRRAllocModeInfo XRRAllocModeInfo_dylibloader_wrapper_xrandr +#define XRRCreateMode XRRCreateMode_dylibloader_wrapper_xrandr +#define XRRDestroyMode XRRDestroyMode_dylibloader_wrapper_xrandr +#define XRRAddOutputMode XRRAddOutputMode_dylibloader_wrapper_xrandr +#define XRRDeleteOutputMode XRRDeleteOutputMode_dylibloader_wrapper_xrandr +#define XRRFreeModeInfo XRRFreeModeInfo_dylibloader_wrapper_xrandr +#define XRRGetCrtcInfo XRRGetCrtcInfo_dylibloader_wrapper_xrandr +#define XRRFreeCrtcInfo XRRFreeCrtcInfo_dylibloader_wrapper_xrandr +#define XRRSetCrtcConfig XRRSetCrtcConfig_dylibloader_wrapper_xrandr +#define XRRGetCrtcGammaSize XRRGetCrtcGammaSize_dylibloader_wrapper_xrandr +#define XRRGetCrtcGamma XRRGetCrtcGamma_dylibloader_wrapper_xrandr +#define XRRAllocGamma XRRAllocGamma_dylibloader_wrapper_xrandr +#define XRRSetCrtcGamma XRRSetCrtcGamma_dylibloader_wrapper_xrandr +#define XRRFreeGamma XRRFreeGamma_dylibloader_wrapper_xrandr +#define XRRGetScreenResourcesCurrent XRRGetScreenResourcesCurrent_dylibloader_wrapper_xrandr +#define XRRSetCrtcTransform XRRSetCrtcTransform_dylibloader_wrapper_xrandr +#define XRRGetCrtcTransform XRRGetCrtcTransform_dylibloader_wrapper_xrandr +#define XRRUpdateConfiguration XRRUpdateConfiguration_dylibloader_wrapper_xrandr +#define XRRGetPanning XRRGetPanning_dylibloader_wrapper_xrandr +#define XRRFreePanning XRRFreePanning_dylibloader_wrapper_xrandr +#define XRRSetPanning XRRSetPanning_dylibloader_wrapper_xrandr +#define XRRSetOutputPrimary XRRSetOutputPrimary_dylibloader_wrapper_xrandr +#define XRRGetOutputPrimary XRRGetOutputPrimary_dylibloader_wrapper_xrandr +#define XRRGetProviderResources XRRGetProviderResources_dylibloader_wrapper_xrandr +#define XRRFreeProviderResources XRRFreeProviderResources_dylibloader_wrapper_xrandr +#define XRRGetProviderInfo XRRGetProviderInfo_dylibloader_wrapper_xrandr +#define XRRFreeProviderInfo XRRFreeProviderInfo_dylibloader_wrapper_xrandr +#define XRRSetProviderOutputSource XRRSetProviderOutputSource_dylibloader_wrapper_xrandr +#define XRRSetProviderOffloadSink XRRSetProviderOffloadSink_dylibloader_wrapper_xrandr +#define XRRListProviderProperties XRRListProviderProperties_dylibloader_wrapper_xrandr +#define XRRQueryProviderProperty XRRQueryProviderProperty_dylibloader_wrapper_xrandr +#define XRRConfigureProviderProperty XRRConfigureProviderProperty_dylibloader_wrapper_xrandr +#define XRRChangeProviderProperty XRRChangeProviderProperty_dylibloader_wrapper_xrandr +#define XRRDeleteProviderProperty XRRDeleteProviderProperty_dylibloader_wrapper_xrandr +#define XRRGetProviderProperty XRRGetProviderProperty_dylibloader_wrapper_xrandr +#define XRRAllocateMonitor XRRAllocateMonitor_dylibloader_wrapper_xrandr +#define XRRGetMonitors XRRGetMonitors_dylibloader_wrapper_xrandr +#define XRRSetMonitor XRRSetMonitor_dylibloader_wrapper_xrandr +#define XRRDeleteMonitor XRRDeleteMonitor_dylibloader_wrapper_xrandr +#define XRRFreeMonitors XRRFreeMonitors_dylibloader_wrapper_xrandr +extern int (*XRRQueryExtension_dylibloader_wrapper_xrandr)( Display*, int*, int*); +extern int (*XRRQueryVersion_dylibloader_wrapper_xrandr)( Display*, int*, int*); +extern XRRScreenConfiguration* (*XRRGetScreenInfo_dylibloader_wrapper_xrandr)( Display*, Window); +extern void (*XRRFreeScreenConfigInfo_dylibloader_wrapper_xrandr)( XRRScreenConfiguration*); +extern int (*XRRSetScreenConfig_dylibloader_wrapper_xrandr)( Display*, XRRScreenConfiguration*, Drawable, int, Rotation, Time); +extern int (*XRRSetScreenConfigAndRate_dylibloader_wrapper_xrandr)( Display*, XRRScreenConfiguration*, Drawable, int, Rotation, short, Time); +extern Rotation (*XRRConfigRotations_dylibloader_wrapper_xrandr)( XRRScreenConfiguration*, Rotation*); +extern Time (*XRRConfigTimes_dylibloader_wrapper_xrandr)( XRRScreenConfiguration*, Time*); +extern XRRScreenSize* (*XRRConfigSizes_dylibloader_wrapper_xrandr)( XRRScreenConfiguration*, int*); +extern short* (*XRRConfigRates_dylibloader_wrapper_xrandr)( XRRScreenConfiguration*, int, int*); +extern SizeID (*XRRConfigCurrentConfiguration_dylibloader_wrapper_xrandr)( XRRScreenConfiguration*, Rotation*); +extern short (*XRRConfigCurrentRate_dylibloader_wrapper_xrandr)( XRRScreenConfiguration*); +extern int (*XRRRootToScreen_dylibloader_wrapper_xrandr)( Display*, Window); +extern void (*XRRSelectInput_dylibloader_wrapper_xrandr)( Display*, Window, int); +extern Rotation (*XRRRotations_dylibloader_wrapper_xrandr)( Display*, int, Rotation*); +extern XRRScreenSize* (*XRRSizes_dylibloader_wrapper_xrandr)( Display*, int, int*); +extern short* (*XRRRates_dylibloader_wrapper_xrandr)( Display*, int, int, int*); +extern Time (*XRRTimes_dylibloader_wrapper_xrandr)( Display*, int, Time*); +extern int (*XRRGetScreenSizeRange_dylibloader_wrapper_xrandr)( Display*, Window, int*, int*, int*, int*); +extern void (*XRRSetScreenSize_dylibloader_wrapper_xrandr)( Display*, Window, int, int, int, int); +extern XRRScreenResources* (*XRRGetScreenResources_dylibloader_wrapper_xrandr)( Display*, Window); +extern void (*XRRFreeScreenResources_dylibloader_wrapper_xrandr)( XRRScreenResources*); +extern XRROutputInfo* (*XRRGetOutputInfo_dylibloader_wrapper_xrandr)( Display*, XRRScreenResources*, RROutput); +extern void (*XRRFreeOutputInfo_dylibloader_wrapper_xrandr)( XRROutputInfo*); +extern Atom* (*XRRListOutputProperties_dylibloader_wrapper_xrandr)( Display*, RROutput, int*); +extern XRRPropertyInfo* (*XRRQueryOutputProperty_dylibloader_wrapper_xrandr)( Display*, RROutput, Atom); +extern void (*XRRConfigureOutputProperty_dylibloader_wrapper_xrandr)( Display*, RROutput, Atom, int, int, int, long*); +extern void (*XRRChangeOutputProperty_dylibloader_wrapper_xrandr)( Display*, RROutput, Atom, Atom, int, int,const unsigned char*, int); +extern void (*XRRDeleteOutputProperty_dylibloader_wrapper_xrandr)( Display*, RROutput, Atom); +extern int (*XRRGetOutputProperty_dylibloader_wrapper_xrandr)( Display*, RROutput, Atom, long, long, int, int, Atom, Atom*, int*, unsigned long*, unsigned long*, unsigned char**); +extern XRRModeInfo* (*XRRAllocModeInfo_dylibloader_wrapper_xrandr)(const char*, int); +extern RRMode (*XRRCreateMode_dylibloader_wrapper_xrandr)( Display*, Window, XRRModeInfo*); +extern void (*XRRDestroyMode_dylibloader_wrapper_xrandr)( Display*, RRMode); +extern void (*XRRAddOutputMode_dylibloader_wrapper_xrandr)( Display*, RROutput, RRMode); +extern void (*XRRDeleteOutputMode_dylibloader_wrapper_xrandr)( Display*, RROutput, RRMode); +extern void (*XRRFreeModeInfo_dylibloader_wrapper_xrandr)( XRRModeInfo*); +extern XRRCrtcInfo* (*XRRGetCrtcInfo_dylibloader_wrapper_xrandr)( Display*, XRRScreenResources*, RRCrtc); +extern void (*XRRFreeCrtcInfo_dylibloader_wrapper_xrandr)( XRRCrtcInfo*); +extern int (*XRRSetCrtcConfig_dylibloader_wrapper_xrandr)( Display*, XRRScreenResources*, RRCrtc, Time, int, int, RRMode, Rotation, RROutput*, int); +extern int (*XRRGetCrtcGammaSize_dylibloader_wrapper_xrandr)( Display*, RRCrtc); +extern XRRCrtcGamma* (*XRRGetCrtcGamma_dylibloader_wrapper_xrandr)( Display*, RRCrtc); +extern XRRCrtcGamma* (*XRRAllocGamma_dylibloader_wrapper_xrandr)( int); +extern void (*XRRSetCrtcGamma_dylibloader_wrapper_xrandr)( Display*, RRCrtc, XRRCrtcGamma*); +extern void (*XRRFreeGamma_dylibloader_wrapper_xrandr)( XRRCrtcGamma*); +extern XRRScreenResources* (*XRRGetScreenResourcesCurrent_dylibloader_wrapper_xrandr)( Display*, Window); +extern void (*XRRSetCrtcTransform_dylibloader_wrapper_xrandr)( Display*, RRCrtc, XTransform*,const char*, XFixed*, int); +extern int (*XRRGetCrtcTransform_dylibloader_wrapper_xrandr)( Display*, RRCrtc, XRRCrtcTransformAttributes**); +extern int (*XRRUpdateConfiguration_dylibloader_wrapper_xrandr)( XEvent*); +extern XRRPanning* (*XRRGetPanning_dylibloader_wrapper_xrandr)( Display*, XRRScreenResources*, RRCrtc); +extern void (*XRRFreePanning_dylibloader_wrapper_xrandr)( XRRPanning*); +extern int (*XRRSetPanning_dylibloader_wrapper_xrandr)( Display*, XRRScreenResources*, RRCrtc, XRRPanning*); +extern void (*XRRSetOutputPrimary_dylibloader_wrapper_xrandr)( Display*, Window, RROutput); +extern RROutput (*XRRGetOutputPrimary_dylibloader_wrapper_xrandr)( Display*, Window); +extern XRRProviderResources* (*XRRGetProviderResources_dylibloader_wrapper_xrandr)( Display*, Window); +extern void (*XRRFreeProviderResources_dylibloader_wrapper_xrandr)( XRRProviderResources*); +extern XRRProviderInfo* (*XRRGetProviderInfo_dylibloader_wrapper_xrandr)( Display*, XRRScreenResources*, RRProvider); +extern void (*XRRFreeProviderInfo_dylibloader_wrapper_xrandr)( XRRProviderInfo*); +extern int (*XRRSetProviderOutputSource_dylibloader_wrapper_xrandr)( Display*, XID, XID); +extern int (*XRRSetProviderOffloadSink_dylibloader_wrapper_xrandr)( Display*, XID, XID); +extern Atom* (*XRRListProviderProperties_dylibloader_wrapper_xrandr)( Display*, RRProvider, int*); +extern XRRPropertyInfo* (*XRRQueryProviderProperty_dylibloader_wrapper_xrandr)( Display*, RRProvider, Atom); +extern void (*XRRConfigureProviderProperty_dylibloader_wrapper_xrandr)( Display*, RRProvider, Atom, int, int, int, long*); +extern void (*XRRChangeProviderProperty_dylibloader_wrapper_xrandr)( Display*, RRProvider, Atom, Atom, int, int,const unsigned char*, int); +extern void (*XRRDeleteProviderProperty_dylibloader_wrapper_xrandr)( Display*, RRProvider, Atom); +extern int (*XRRGetProviderProperty_dylibloader_wrapper_xrandr)( Display*, RRProvider, Atom, long, long, int, int, Atom, Atom*, int*, unsigned long*, unsigned long*, unsigned char**); +extern XRRMonitorInfo* (*XRRAllocateMonitor_dylibloader_wrapper_xrandr)( Display*, int); +extern XRRMonitorInfo* (*XRRGetMonitors_dylibloader_wrapper_xrandr)( Display*, Window, int, int*); +extern void (*XRRSetMonitor_dylibloader_wrapper_xrandr)( Display*, Window, XRRMonitorInfo*); +extern void (*XRRDeleteMonitor_dylibloader_wrapper_xrandr)( Display*, Window, Atom); +extern void (*XRRFreeMonitors_dylibloader_wrapper_xrandr)( XRRMonitorInfo*); +int initialize_xrandr(int verbose); +#ifdef __cplusplus +} +#endif +#endif diff --git a/platform/linuxbsd/x11/dynwrappers/xrender-so_wrap.c b/platform/linuxbsd/x11/dynwrappers/xrender-so_wrap.c new file mode 100644 index 0000000000..7421f94601 --- /dev/null +++ b/platform/linuxbsd/x11/dynwrappers/xrender-so_wrap.c @@ -0,0 +1,511 @@ +// This file is generated. Do not edit! +// see https://github.com/hpvb/dynload-wrapper for details +// generated by generate-wrapper.py 0.3 on 2023-01-23 15:14:14 +// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/extensions/Xrender.h --sys-include "thirdparty/linuxbsd_headers/X11/extensions/Xrender.h" --soname libXrender.so.1 --init-name xrender --output-header ./platform/linuxbsd/x11/dynwrappers/xrender-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xrender-so_wrap.c~ +// +// NOTE: Generated from Xrender 0.9.10. +// This has been handpatched to workaround some issues with the generator that +// will be eventually fixed. In this case, non-existent symbols inherited from +// libX11, but absent in libXrender.so.1, were removed. +#include <stdint.h> + +#define XRenderQueryExtension XRenderQueryExtension_dylibloader_orig_xrender +#define XRenderQueryVersion XRenderQueryVersion_dylibloader_orig_xrender +#define XRenderQueryFormats XRenderQueryFormats_dylibloader_orig_xrender +#define XRenderQuerySubpixelOrder XRenderQuerySubpixelOrder_dylibloader_orig_xrender +#define XRenderSetSubpixelOrder XRenderSetSubpixelOrder_dylibloader_orig_xrender +#define XRenderFindVisualFormat XRenderFindVisualFormat_dylibloader_orig_xrender +#define XRenderFindFormat XRenderFindFormat_dylibloader_orig_xrender +#define XRenderFindStandardFormat XRenderFindStandardFormat_dylibloader_orig_xrender +#define XRenderQueryPictIndexValues XRenderQueryPictIndexValues_dylibloader_orig_xrender +#define XRenderCreatePicture XRenderCreatePicture_dylibloader_orig_xrender +#define XRenderChangePicture XRenderChangePicture_dylibloader_orig_xrender +#define XRenderSetPictureClipRectangles XRenderSetPictureClipRectangles_dylibloader_orig_xrender +#define XRenderSetPictureClipRegion XRenderSetPictureClipRegion_dylibloader_orig_xrender +#define XRenderSetPictureTransform XRenderSetPictureTransform_dylibloader_orig_xrender +#define XRenderFreePicture XRenderFreePicture_dylibloader_orig_xrender +#define XRenderComposite XRenderComposite_dylibloader_orig_xrender +#define XRenderCreateGlyphSet XRenderCreateGlyphSet_dylibloader_orig_xrender +#define XRenderReferenceGlyphSet XRenderReferenceGlyphSet_dylibloader_orig_xrender +#define XRenderFreeGlyphSet XRenderFreeGlyphSet_dylibloader_orig_xrender +#define XRenderAddGlyphs XRenderAddGlyphs_dylibloader_orig_xrender +#define XRenderFreeGlyphs XRenderFreeGlyphs_dylibloader_orig_xrender +#define XRenderCompositeString8 XRenderCompositeString8_dylibloader_orig_xrender +#define XRenderCompositeString16 XRenderCompositeString16_dylibloader_orig_xrender +#define XRenderCompositeString32 XRenderCompositeString32_dylibloader_orig_xrender +#define XRenderCompositeText8 XRenderCompositeText8_dylibloader_orig_xrender +#define XRenderCompositeText16 XRenderCompositeText16_dylibloader_orig_xrender +#define XRenderCompositeText32 XRenderCompositeText32_dylibloader_orig_xrender +#define XRenderFillRectangle XRenderFillRectangle_dylibloader_orig_xrender +#define XRenderFillRectangles XRenderFillRectangles_dylibloader_orig_xrender +#define XRenderCompositeTrapezoids XRenderCompositeTrapezoids_dylibloader_orig_xrender +#define XRenderCompositeTriangles XRenderCompositeTriangles_dylibloader_orig_xrender +#define XRenderCompositeTriStrip XRenderCompositeTriStrip_dylibloader_orig_xrender +#define XRenderCompositeTriFan XRenderCompositeTriFan_dylibloader_orig_xrender +#define XRenderCompositeDoublePoly XRenderCompositeDoublePoly_dylibloader_orig_xrender +#define XRenderParseColor XRenderParseColor_dylibloader_orig_xrender +#define XRenderCreateCursor XRenderCreateCursor_dylibloader_orig_xrender +#define XRenderQueryFilters XRenderQueryFilters_dylibloader_orig_xrender +#define XRenderSetPictureFilter XRenderSetPictureFilter_dylibloader_orig_xrender +#define XRenderCreateAnimCursor XRenderCreateAnimCursor_dylibloader_orig_xrender +#define XRenderAddTraps XRenderAddTraps_dylibloader_orig_xrender +#define XRenderCreateSolidFill XRenderCreateSolidFill_dylibloader_orig_xrender +#define XRenderCreateLinearGradient XRenderCreateLinearGradient_dylibloader_orig_xrender +#define XRenderCreateRadialGradient XRenderCreateRadialGradient_dylibloader_orig_xrender +#define XRenderCreateConicalGradient XRenderCreateConicalGradient_dylibloader_orig_xrender +#include "thirdparty/linuxbsd_headers/X11/extensions/Xrender.h" +#undef XRenderQueryExtension +#undef XRenderQueryVersion +#undef XRenderQueryFormats +#undef XRenderQuerySubpixelOrder +#undef XRenderSetSubpixelOrder +#undef XRenderFindVisualFormat +#undef XRenderFindFormat +#undef XRenderFindStandardFormat +#undef XRenderQueryPictIndexValues +#undef XRenderCreatePicture +#undef XRenderChangePicture +#undef XRenderSetPictureClipRectangles +#undef XRenderSetPictureClipRegion +#undef XRenderSetPictureTransform +#undef XRenderFreePicture +#undef XRenderComposite +#undef XRenderCreateGlyphSet +#undef XRenderReferenceGlyphSet +#undef XRenderFreeGlyphSet +#undef XRenderAddGlyphs +#undef XRenderFreeGlyphs +#undef XRenderCompositeString8 +#undef XRenderCompositeString16 +#undef XRenderCompositeString32 +#undef XRenderCompositeText8 +#undef XRenderCompositeText16 +#undef XRenderCompositeText32 +#undef XRenderFillRectangle +#undef XRenderFillRectangles +#undef XRenderCompositeTrapezoids +#undef XRenderCompositeTriangles +#undef XRenderCompositeTriStrip +#undef XRenderCompositeTriFan +#undef XRenderCompositeDoublePoly +#undef XRenderParseColor +#undef XRenderCreateCursor +#undef XRenderQueryFilters +#undef XRenderSetPictureFilter +#undef XRenderCreateAnimCursor +#undef XRenderAddTraps +#undef XRenderCreateSolidFill +#undef XRenderCreateLinearGradient +#undef XRenderCreateRadialGradient +#undef XRenderCreateConicalGradient +#include <dlfcn.h> +#include <stdio.h> +int (*XRenderQueryExtension_dylibloader_wrapper_xrender)( Display*, int*, int*); +int (*XRenderQueryVersion_dylibloader_wrapper_xrender)( Display*, int*, int*); +int (*XRenderQueryFormats_dylibloader_wrapper_xrender)( Display*); +int (*XRenderQuerySubpixelOrder_dylibloader_wrapper_xrender)( Display*, int); +int (*XRenderSetSubpixelOrder_dylibloader_wrapper_xrender)( Display*, int, int); +XRenderPictFormat* (*XRenderFindVisualFormat_dylibloader_wrapper_xrender)( Display*,const Visual*); +XRenderPictFormat* (*XRenderFindFormat_dylibloader_wrapper_xrender)( Display*, unsigned long,const XRenderPictFormat*, int); +XRenderPictFormat* (*XRenderFindStandardFormat_dylibloader_wrapper_xrender)( Display*, int); +XIndexValue* (*XRenderQueryPictIndexValues_dylibloader_wrapper_xrender)( Display*,const XRenderPictFormat*, int*); +Picture (*XRenderCreatePicture_dylibloader_wrapper_xrender)( Display*, Drawable,const XRenderPictFormat*, unsigned long,const XRenderPictureAttributes*); +void (*XRenderChangePicture_dylibloader_wrapper_xrender)( Display*, Picture, unsigned long,const XRenderPictureAttributes*); +void (*XRenderSetPictureClipRectangles_dylibloader_wrapper_xrender)( Display*, Picture, int, int,const XRectangle*, int); +void (*XRenderSetPictureClipRegion_dylibloader_wrapper_xrender)( Display*, Picture, Region); +void (*XRenderSetPictureTransform_dylibloader_wrapper_xrender)( Display*, Picture, XTransform*); +void (*XRenderFreePicture_dylibloader_wrapper_xrender)( Display*, Picture); +void (*XRenderComposite_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture, Picture, int, int, int, int, int, int, unsigned int, unsigned int); +GlyphSet (*XRenderCreateGlyphSet_dylibloader_wrapper_xrender)( Display*,const XRenderPictFormat*); +GlyphSet (*XRenderReferenceGlyphSet_dylibloader_wrapper_xrender)( Display*, GlyphSet); +void (*XRenderFreeGlyphSet_dylibloader_wrapper_xrender)( Display*, GlyphSet); +void (*XRenderAddGlyphs_dylibloader_wrapper_xrender)( Display*, GlyphSet,const Glyph*,const XGlyphInfo*, int,const char*, int); +void (*XRenderFreeGlyphs_dylibloader_wrapper_xrender)( Display*, GlyphSet,const Glyph*, int); +void (*XRenderCompositeString8_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture,const XRenderPictFormat*, GlyphSet, int, int, int, int,const char*, int); +void (*XRenderCompositeString16_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture,const XRenderPictFormat*, GlyphSet, int, int, int, int,const unsigned short*, int); +void (*XRenderCompositeString32_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture,const XRenderPictFormat*, GlyphSet, int, int, int, int,const unsigned int*, int); +void (*XRenderCompositeText8_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture,const XRenderPictFormat*, int, int, int, int,const XGlyphElt8*, int); +void (*XRenderCompositeText16_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture,const XRenderPictFormat*, int, int, int, int,const XGlyphElt16*, int); +void (*XRenderCompositeText32_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture,const XRenderPictFormat*, int, int, int, int,const XGlyphElt32*, int); +void (*XRenderFillRectangle_dylibloader_wrapper_xrender)( Display*, int, Picture,const XRenderColor*, int, int, unsigned int, unsigned int); +void (*XRenderFillRectangles_dylibloader_wrapper_xrender)( Display*, int, Picture,const XRenderColor*,const XRectangle*, int); +void (*XRenderCompositeTrapezoids_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture,const XRenderPictFormat*, int, int,const XTrapezoid*, int); +void (*XRenderCompositeTriangles_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture,const XRenderPictFormat*, int, int,const XTriangle*, int); +void (*XRenderCompositeTriStrip_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture,const XRenderPictFormat*, int, int,const XPointFixed*, int); +void (*XRenderCompositeTriFan_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture,const XRenderPictFormat*, int, int,const XPointFixed*, int); +void (*XRenderCompositeDoublePoly_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture,const XRenderPictFormat*, int, int, int, int,const XPointDouble*, int, int); +int (*XRenderParseColor_dylibloader_wrapper_xrender)( Display*, char*, XRenderColor*); +Cursor (*XRenderCreateCursor_dylibloader_wrapper_xrender)( Display*, Picture, unsigned int, unsigned int); +XFilters* (*XRenderQueryFilters_dylibloader_wrapper_xrender)( Display*, Drawable); +void (*XRenderSetPictureFilter_dylibloader_wrapper_xrender)( Display*, Picture,const char*, XFixed*, int); +Cursor (*XRenderCreateAnimCursor_dylibloader_wrapper_xrender)( Display*, int, XAnimCursor*); +void (*XRenderAddTraps_dylibloader_wrapper_xrender)( Display*, Picture, int, int,const XTrap*, int); +Picture (*XRenderCreateSolidFill_dylibloader_wrapper_xrender)( Display*,const XRenderColor*); +Picture (*XRenderCreateLinearGradient_dylibloader_wrapper_xrender)( Display*,const XLinearGradient*,const XFixed*,const XRenderColor*, int); +Picture (*XRenderCreateRadialGradient_dylibloader_wrapper_xrender)( Display*,const XRadialGradient*,const XFixed*,const XRenderColor*, int); +Picture (*XRenderCreateConicalGradient_dylibloader_wrapper_xrender)( Display*,const XConicalGradient*,const XFixed*,const XRenderColor*, int); +int initialize_xrender(int verbose) { + void *handle; + char *error; + handle = dlopen("libXrender.so.1", RTLD_LAZY); + if (!handle) { + if (verbose) { + fprintf(stderr, "%s\n", dlerror()); + } + return(1); + } + dlerror(); +// XRenderQueryExtension + *(void **) (&XRenderQueryExtension_dylibloader_wrapper_xrender) = dlsym(handle, "XRenderQueryExtension"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRenderQueryVersion + *(void **) (&XRenderQueryVersion_dylibloader_wrapper_xrender) = dlsym(handle, "XRenderQueryVersion"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRenderQueryFormats + *(void **) (&XRenderQueryFormats_dylibloader_wrapper_xrender) = dlsym(handle, "XRenderQueryFormats"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRenderQuerySubpixelOrder + *(void **) (&XRenderQuerySubpixelOrder_dylibloader_wrapper_xrender) = dlsym(handle, "XRenderQuerySubpixelOrder"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRenderSetSubpixelOrder + *(void **) (&XRenderSetSubpixelOrder_dylibloader_wrapper_xrender) = dlsym(handle, "XRenderSetSubpixelOrder"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRenderFindVisualFormat + *(void **) (&XRenderFindVisualFormat_dylibloader_wrapper_xrender) = dlsym(handle, "XRenderFindVisualFormat"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRenderFindFormat + *(void **) (&XRenderFindFormat_dylibloader_wrapper_xrender) = dlsym(handle, "XRenderFindFormat"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRenderFindStandardFormat + *(void **) (&XRenderFindStandardFormat_dylibloader_wrapper_xrender) = dlsym(handle, "XRenderFindStandardFormat"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRenderQueryPictIndexValues + *(void **) (&XRenderQueryPictIndexValues_dylibloader_wrapper_xrender) = dlsym(handle, "XRenderQueryPictIndexValues"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRenderCreatePicture + *(void **) (&XRenderCreatePicture_dylibloader_wrapper_xrender) = dlsym(handle, "XRenderCreatePicture"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRenderChangePicture + *(void **) (&XRenderChangePicture_dylibloader_wrapper_xrender) = dlsym(handle, "XRenderChangePicture"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRenderSetPictureClipRectangles + *(void **) (&XRenderSetPictureClipRectangles_dylibloader_wrapper_xrender) = dlsym(handle, "XRenderSetPictureClipRectangles"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRenderSetPictureClipRegion + *(void **) (&XRenderSetPictureClipRegion_dylibloader_wrapper_xrender) = dlsym(handle, "XRenderSetPictureClipRegion"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRenderSetPictureTransform + *(void **) (&XRenderSetPictureTransform_dylibloader_wrapper_xrender) = dlsym(handle, "XRenderSetPictureTransform"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRenderFreePicture + *(void **) (&XRenderFreePicture_dylibloader_wrapper_xrender) = dlsym(handle, "XRenderFreePicture"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRenderComposite + *(void **) (&XRenderComposite_dylibloader_wrapper_xrender) = dlsym(handle, "XRenderComposite"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRenderCreateGlyphSet + *(void **) (&XRenderCreateGlyphSet_dylibloader_wrapper_xrender) = dlsym(handle, "XRenderCreateGlyphSet"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRenderReferenceGlyphSet + *(void **) (&XRenderReferenceGlyphSet_dylibloader_wrapper_xrender) = dlsym(handle, "XRenderReferenceGlyphSet"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRenderFreeGlyphSet + *(void **) (&XRenderFreeGlyphSet_dylibloader_wrapper_xrender) = dlsym(handle, "XRenderFreeGlyphSet"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRenderAddGlyphs + *(void **) (&XRenderAddGlyphs_dylibloader_wrapper_xrender) = dlsym(handle, "XRenderAddGlyphs"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRenderFreeGlyphs + *(void **) (&XRenderFreeGlyphs_dylibloader_wrapper_xrender) = dlsym(handle, "XRenderFreeGlyphs"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRenderCompositeString8 + *(void **) (&XRenderCompositeString8_dylibloader_wrapper_xrender) = dlsym(handle, "XRenderCompositeString8"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRenderCompositeString16 + *(void **) (&XRenderCompositeString16_dylibloader_wrapper_xrender) = dlsym(handle, "XRenderCompositeString16"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRenderCompositeString32 + *(void **) (&XRenderCompositeString32_dylibloader_wrapper_xrender) = dlsym(handle, "XRenderCompositeString32"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRenderCompositeText8 + *(void **) (&XRenderCompositeText8_dylibloader_wrapper_xrender) = dlsym(handle, "XRenderCompositeText8"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRenderCompositeText16 + *(void **) (&XRenderCompositeText16_dylibloader_wrapper_xrender) = dlsym(handle, "XRenderCompositeText16"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRenderCompositeText32 + *(void **) (&XRenderCompositeText32_dylibloader_wrapper_xrender) = dlsym(handle, "XRenderCompositeText32"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRenderFillRectangle + *(void **) (&XRenderFillRectangle_dylibloader_wrapper_xrender) = dlsym(handle, "XRenderFillRectangle"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRenderFillRectangles + *(void **) (&XRenderFillRectangles_dylibloader_wrapper_xrender) = dlsym(handle, "XRenderFillRectangles"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRenderCompositeTrapezoids + *(void **) (&XRenderCompositeTrapezoids_dylibloader_wrapper_xrender) = dlsym(handle, "XRenderCompositeTrapezoids"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRenderCompositeTriangles + *(void **) (&XRenderCompositeTriangles_dylibloader_wrapper_xrender) = dlsym(handle, "XRenderCompositeTriangles"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRenderCompositeTriStrip + *(void **) (&XRenderCompositeTriStrip_dylibloader_wrapper_xrender) = dlsym(handle, "XRenderCompositeTriStrip"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRenderCompositeTriFan + *(void **) (&XRenderCompositeTriFan_dylibloader_wrapper_xrender) = dlsym(handle, "XRenderCompositeTriFan"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRenderCompositeDoublePoly + *(void **) (&XRenderCompositeDoublePoly_dylibloader_wrapper_xrender) = dlsym(handle, "XRenderCompositeDoublePoly"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRenderParseColor + *(void **) (&XRenderParseColor_dylibloader_wrapper_xrender) = dlsym(handle, "XRenderParseColor"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRenderCreateCursor + *(void **) (&XRenderCreateCursor_dylibloader_wrapper_xrender) = dlsym(handle, "XRenderCreateCursor"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRenderQueryFilters + *(void **) (&XRenderQueryFilters_dylibloader_wrapper_xrender) = dlsym(handle, "XRenderQueryFilters"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRenderSetPictureFilter + *(void **) (&XRenderSetPictureFilter_dylibloader_wrapper_xrender) = dlsym(handle, "XRenderSetPictureFilter"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRenderCreateAnimCursor + *(void **) (&XRenderCreateAnimCursor_dylibloader_wrapper_xrender) = dlsym(handle, "XRenderCreateAnimCursor"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRenderAddTraps + *(void **) (&XRenderAddTraps_dylibloader_wrapper_xrender) = dlsym(handle, "XRenderAddTraps"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRenderCreateSolidFill + *(void **) (&XRenderCreateSolidFill_dylibloader_wrapper_xrender) = dlsym(handle, "XRenderCreateSolidFill"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRenderCreateLinearGradient + *(void **) (&XRenderCreateLinearGradient_dylibloader_wrapper_xrender) = dlsym(handle, "XRenderCreateLinearGradient"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRenderCreateRadialGradient + *(void **) (&XRenderCreateRadialGradient_dylibloader_wrapper_xrender) = dlsym(handle, "XRenderCreateRadialGradient"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// XRenderCreateConicalGradient + *(void **) (&XRenderCreateConicalGradient_dylibloader_wrapper_xrender) = dlsym(handle, "XRenderCreateConicalGradient"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +return 0; +} diff --git a/platform/linuxbsd/x11/dynwrappers/xrender-so_wrap.h b/platform/linuxbsd/x11/dynwrappers/xrender-so_wrap.h new file mode 100644 index 0000000000..5d3f695959 --- /dev/null +++ b/platform/linuxbsd/x11/dynwrappers/xrender-so_wrap.h @@ -0,0 +1,198 @@ +#ifndef DYLIBLOAD_WRAPPER_XRENDER +#define DYLIBLOAD_WRAPPER_XRENDER +// This file is generated. Do not edit! +// see https://github.com/hpvb/dynload-wrapper for details +// generated by generate-wrapper.py 0.3 on 2023-01-23 15:14:14 +// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/extensions/Xrender.h --sys-include "thirdparty/linuxbsd_headers/X11/extensions/Xrender.h" --soname libXrender.so.1 --init-name xrender --output-header ./platform/linuxbsd/x11/dynwrappers/xrender-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xrender-so_wrap.c~ +// +// NOTE: Generated from Xrender 0.9.10. +// This has been handpatched to workaround some issues with the generator that +// will be eventually fixed. In this case, non-existent symbols inherited from +// libX11, but absent in libXrender.so.1, were removed. +#include <stdint.h> + +#define XRenderQueryExtension XRenderQueryExtension_dylibloader_orig_xrender +#define XRenderQueryVersion XRenderQueryVersion_dylibloader_orig_xrender +#define XRenderQueryFormats XRenderQueryFormats_dylibloader_orig_xrender +#define XRenderQuerySubpixelOrder XRenderQuerySubpixelOrder_dylibloader_orig_xrender +#define XRenderSetSubpixelOrder XRenderSetSubpixelOrder_dylibloader_orig_xrender +#define XRenderFindVisualFormat XRenderFindVisualFormat_dylibloader_orig_xrender +#define XRenderFindFormat XRenderFindFormat_dylibloader_orig_xrender +#define XRenderFindStandardFormat XRenderFindStandardFormat_dylibloader_orig_xrender +#define XRenderQueryPictIndexValues XRenderQueryPictIndexValues_dylibloader_orig_xrender +#define XRenderCreatePicture XRenderCreatePicture_dylibloader_orig_xrender +#define XRenderChangePicture XRenderChangePicture_dylibloader_orig_xrender +#define XRenderSetPictureClipRectangles XRenderSetPictureClipRectangles_dylibloader_orig_xrender +#define XRenderSetPictureClipRegion XRenderSetPictureClipRegion_dylibloader_orig_xrender +#define XRenderSetPictureTransform XRenderSetPictureTransform_dylibloader_orig_xrender +#define XRenderFreePicture XRenderFreePicture_dylibloader_orig_xrender +#define XRenderComposite XRenderComposite_dylibloader_orig_xrender +#define XRenderCreateGlyphSet XRenderCreateGlyphSet_dylibloader_orig_xrender +#define XRenderReferenceGlyphSet XRenderReferenceGlyphSet_dylibloader_orig_xrender +#define XRenderFreeGlyphSet XRenderFreeGlyphSet_dylibloader_orig_xrender +#define XRenderAddGlyphs XRenderAddGlyphs_dylibloader_orig_xrender +#define XRenderFreeGlyphs XRenderFreeGlyphs_dylibloader_orig_xrender +#define XRenderCompositeString8 XRenderCompositeString8_dylibloader_orig_xrender +#define XRenderCompositeString16 XRenderCompositeString16_dylibloader_orig_xrender +#define XRenderCompositeString32 XRenderCompositeString32_dylibloader_orig_xrender +#define XRenderCompositeText8 XRenderCompositeText8_dylibloader_orig_xrender +#define XRenderCompositeText16 XRenderCompositeText16_dylibloader_orig_xrender +#define XRenderCompositeText32 XRenderCompositeText32_dylibloader_orig_xrender +#define XRenderFillRectangle XRenderFillRectangle_dylibloader_orig_xrender +#define XRenderFillRectangles XRenderFillRectangles_dylibloader_orig_xrender +#define XRenderCompositeTrapezoids XRenderCompositeTrapezoids_dylibloader_orig_xrender +#define XRenderCompositeTriangles XRenderCompositeTriangles_dylibloader_orig_xrender +#define XRenderCompositeTriStrip XRenderCompositeTriStrip_dylibloader_orig_xrender +#define XRenderCompositeTriFan XRenderCompositeTriFan_dylibloader_orig_xrender +#define XRenderCompositeDoublePoly XRenderCompositeDoublePoly_dylibloader_orig_xrender +#define XRenderParseColor XRenderParseColor_dylibloader_orig_xrender +#define XRenderCreateCursor XRenderCreateCursor_dylibloader_orig_xrender +#define XRenderQueryFilters XRenderQueryFilters_dylibloader_orig_xrender +#define XRenderSetPictureFilter XRenderSetPictureFilter_dylibloader_orig_xrender +#define XRenderCreateAnimCursor XRenderCreateAnimCursor_dylibloader_orig_xrender +#define XRenderAddTraps XRenderAddTraps_dylibloader_orig_xrender +#define XRenderCreateSolidFill XRenderCreateSolidFill_dylibloader_orig_xrender +#define XRenderCreateLinearGradient XRenderCreateLinearGradient_dylibloader_orig_xrender +#define XRenderCreateRadialGradient XRenderCreateRadialGradient_dylibloader_orig_xrender +#define XRenderCreateConicalGradient XRenderCreateConicalGradient_dylibloader_orig_xrender +#include "thirdparty/linuxbsd_headers/X11/extensions/Xrender.h" +#undef XRenderQueryExtension +#undef XRenderQueryVersion +#undef XRenderQueryFormats +#undef XRenderQuerySubpixelOrder +#undef XRenderSetSubpixelOrder +#undef XRenderFindVisualFormat +#undef XRenderFindFormat +#undef XRenderFindStandardFormat +#undef XRenderQueryPictIndexValues +#undef XRenderCreatePicture +#undef XRenderChangePicture +#undef XRenderSetPictureClipRectangles +#undef XRenderSetPictureClipRegion +#undef XRenderSetPictureTransform +#undef XRenderFreePicture +#undef XRenderComposite +#undef XRenderCreateGlyphSet +#undef XRenderReferenceGlyphSet +#undef XRenderFreeGlyphSet +#undef XRenderAddGlyphs +#undef XRenderFreeGlyphs +#undef XRenderCompositeString8 +#undef XRenderCompositeString16 +#undef XRenderCompositeString32 +#undef XRenderCompositeText8 +#undef XRenderCompositeText16 +#undef XRenderCompositeText32 +#undef XRenderFillRectangle +#undef XRenderFillRectangles +#undef XRenderCompositeTrapezoids +#undef XRenderCompositeTriangles +#undef XRenderCompositeTriStrip +#undef XRenderCompositeTriFan +#undef XRenderCompositeDoublePoly +#undef XRenderParseColor +#undef XRenderCreateCursor +#undef XRenderQueryFilters +#undef XRenderSetPictureFilter +#undef XRenderCreateAnimCursor +#undef XRenderAddTraps +#undef XRenderCreateSolidFill +#undef XRenderCreateLinearGradient +#undef XRenderCreateRadialGradient +#undef XRenderCreateConicalGradient +#ifdef __cplusplus +extern "C" { +#endif +#define XRenderQueryExtension XRenderQueryExtension_dylibloader_wrapper_xrender +#define XRenderQueryVersion XRenderQueryVersion_dylibloader_wrapper_xrender +#define XRenderQueryFormats XRenderQueryFormats_dylibloader_wrapper_xrender +#define XRenderQuerySubpixelOrder XRenderQuerySubpixelOrder_dylibloader_wrapper_xrender +#define XRenderSetSubpixelOrder XRenderSetSubpixelOrder_dylibloader_wrapper_xrender +#define XRenderFindVisualFormat XRenderFindVisualFormat_dylibloader_wrapper_xrender +#define XRenderFindFormat XRenderFindFormat_dylibloader_wrapper_xrender +#define XRenderFindStandardFormat XRenderFindStandardFormat_dylibloader_wrapper_xrender +#define XRenderQueryPictIndexValues XRenderQueryPictIndexValues_dylibloader_wrapper_xrender +#define XRenderCreatePicture XRenderCreatePicture_dylibloader_wrapper_xrender +#define XRenderChangePicture XRenderChangePicture_dylibloader_wrapper_xrender +#define XRenderSetPictureClipRectangles XRenderSetPictureClipRectangles_dylibloader_wrapper_xrender +#define XRenderSetPictureClipRegion XRenderSetPictureClipRegion_dylibloader_wrapper_xrender +#define XRenderSetPictureTransform XRenderSetPictureTransform_dylibloader_wrapper_xrender +#define XRenderFreePicture XRenderFreePicture_dylibloader_wrapper_xrender +#define XRenderComposite XRenderComposite_dylibloader_wrapper_xrender +#define XRenderCreateGlyphSet XRenderCreateGlyphSet_dylibloader_wrapper_xrender +#define XRenderReferenceGlyphSet XRenderReferenceGlyphSet_dylibloader_wrapper_xrender +#define XRenderFreeGlyphSet XRenderFreeGlyphSet_dylibloader_wrapper_xrender +#define XRenderAddGlyphs XRenderAddGlyphs_dylibloader_wrapper_xrender +#define XRenderFreeGlyphs XRenderFreeGlyphs_dylibloader_wrapper_xrender +#define XRenderCompositeString8 XRenderCompositeString8_dylibloader_wrapper_xrender +#define XRenderCompositeString16 XRenderCompositeString16_dylibloader_wrapper_xrender +#define XRenderCompositeString32 XRenderCompositeString32_dylibloader_wrapper_xrender +#define XRenderCompositeText8 XRenderCompositeText8_dylibloader_wrapper_xrender +#define XRenderCompositeText16 XRenderCompositeText16_dylibloader_wrapper_xrender +#define XRenderCompositeText32 XRenderCompositeText32_dylibloader_wrapper_xrender +#define XRenderFillRectangle XRenderFillRectangle_dylibloader_wrapper_xrender +#define XRenderFillRectangles XRenderFillRectangles_dylibloader_wrapper_xrender +#define XRenderCompositeTrapezoids XRenderCompositeTrapezoids_dylibloader_wrapper_xrender +#define XRenderCompositeTriangles XRenderCompositeTriangles_dylibloader_wrapper_xrender +#define XRenderCompositeTriStrip XRenderCompositeTriStrip_dylibloader_wrapper_xrender +#define XRenderCompositeTriFan XRenderCompositeTriFan_dylibloader_wrapper_xrender +#define XRenderCompositeDoublePoly XRenderCompositeDoublePoly_dylibloader_wrapper_xrender +#define XRenderParseColor XRenderParseColor_dylibloader_wrapper_xrender +#define XRenderCreateCursor XRenderCreateCursor_dylibloader_wrapper_xrender +#define XRenderQueryFilters XRenderQueryFilters_dylibloader_wrapper_xrender +#define XRenderSetPictureFilter XRenderSetPictureFilter_dylibloader_wrapper_xrender +#define XRenderCreateAnimCursor XRenderCreateAnimCursor_dylibloader_wrapper_xrender +#define XRenderAddTraps XRenderAddTraps_dylibloader_wrapper_xrender +#define XRenderCreateSolidFill XRenderCreateSolidFill_dylibloader_wrapper_xrender +#define XRenderCreateLinearGradient XRenderCreateLinearGradient_dylibloader_wrapper_xrender +#define XRenderCreateRadialGradient XRenderCreateRadialGradient_dylibloader_wrapper_xrender +#define XRenderCreateConicalGradient XRenderCreateConicalGradient_dylibloader_wrapper_xrender +extern int (*XRenderQueryExtension_dylibloader_wrapper_xrender)( Display*, int*, int*); +extern int (*XRenderQueryVersion_dylibloader_wrapper_xrender)( Display*, int*, int*); +extern int (*XRenderQueryFormats_dylibloader_wrapper_xrender)( Display*); +extern int (*XRenderQuerySubpixelOrder_dylibloader_wrapper_xrender)( Display*, int); +extern int (*XRenderSetSubpixelOrder_dylibloader_wrapper_xrender)( Display*, int, int); +extern XRenderPictFormat* (*XRenderFindVisualFormat_dylibloader_wrapper_xrender)( Display*,const Visual*); +extern XRenderPictFormat* (*XRenderFindFormat_dylibloader_wrapper_xrender)( Display*, unsigned long,const XRenderPictFormat*, int); +extern XRenderPictFormat* (*XRenderFindStandardFormat_dylibloader_wrapper_xrender)( Display*, int); +extern XIndexValue* (*XRenderQueryPictIndexValues_dylibloader_wrapper_xrender)( Display*,const XRenderPictFormat*, int*); +extern Picture (*XRenderCreatePicture_dylibloader_wrapper_xrender)( Display*, Drawable,const XRenderPictFormat*, unsigned long,const XRenderPictureAttributes*); +extern void (*XRenderChangePicture_dylibloader_wrapper_xrender)( Display*, Picture, unsigned long,const XRenderPictureAttributes*); +extern void (*XRenderSetPictureClipRectangles_dylibloader_wrapper_xrender)( Display*, Picture, int, int,const XRectangle*, int); +extern void (*XRenderSetPictureClipRegion_dylibloader_wrapper_xrender)( Display*, Picture, Region); +extern void (*XRenderSetPictureTransform_dylibloader_wrapper_xrender)( Display*, Picture, XTransform*); +extern void (*XRenderFreePicture_dylibloader_wrapper_xrender)( Display*, Picture); +extern void (*XRenderComposite_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture, Picture, int, int, int, int, int, int, unsigned int, unsigned int); +extern GlyphSet (*XRenderCreateGlyphSet_dylibloader_wrapper_xrender)( Display*,const XRenderPictFormat*); +extern GlyphSet (*XRenderReferenceGlyphSet_dylibloader_wrapper_xrender)( Display*, GlyphSet); +extern void (*XRenderFreeGlyphSet_dylibloader_wrapper_xrender)( Display*, GlyphSet); +extern void (*XRenderAddGlyphs_dylibloader_wrapper_xrender)( Display*, GlyphSet,const Glyph*,const XGlyphInfo*, int,const char*, int); +extern void (*XRenderFreeGlyphs_dylibloader_wrapper_xrender)( Display*, GlyphSet,const Glyph*, int); +extern void (*XRenderCompositeString8_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture,const XRenderPictFormat*, GlyphSet, int, int, int, int,const char*, int); +extern void (*XRenderCompositeString16_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture,const XRenderPictFormat*, GlyphSet, int, int, int, int,const unsigned short*, int); +extern void (*XRenderCompositeString32_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture,const XRenderPictFormat*, GlyphSet, int, int, int, int,const unsigned int*, int); +extern void (*XRenderCompositeText8_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture,const XRenderPictFormat*, int, int, int, int,const XGlyphElt8*, int); +extern void (*XRenderCompositeText16_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture,const XRenderPictFormat*, int, int, int, int,const XGlyphElt16*, int); +extern void (*XRenderCompositeText32_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture,const XRenderPictFormat*, int, int, int, int,const XGlyphElt32*, int); +extern void (*XRenderFillRectangle_dylibloader_wrapper_xrender)( Display*, int, Picture,const XRenderColor*, int, int, unsigned int, unsigned int); +extern void (*XRenderFillRectangles_dylibloader_wrapper_xrender)( Display*, int, Picture,const XRenderColor*,const XRectangle*, int); +extern void (*XRenderCompositeTrapezoids_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture,const XRenderPictFormat*, int, int,const XTrapezoid*, int); +extern void (*XRenderCompositeTriangles_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture,const XRenderPictFormat*, int, int,const XTriangle*, int); +extern void (*XRenderCompositeTriStrip_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture,const XRenderPictFormat*, int, int,const XPointFixed*, int); +extern void (*XRenderCompositeTriFan_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture,const XRenderPictFormat*, int, int,const XPointFixed*, int); +extern void (*XRenderCompositeDoublePoly_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture,const XRenderPictFormat*, int, int, int, int,const XPointDouble*, int, int); +extern int (*XRenderParseColor_dylibloader_wrapper_xrender)( Display*, char*, XRenderColor*); +extern Cursor (*XRenderCreateCursor_dylibloader_wrapper_xrender)( Display*, Picture, unsigned int, unsigned int); +extern XFilters* (*XRenderQueryFilters_dylibloader_wrapper_xrender)( Display*, Drawable); +extern void (*XRenderSetPictureFilter_dylibloader_wrapper_xrender)( Display*, Picture,const char*, XFixed*, int); +extern Cursor (*XRenderCreateAnimCursor_dylibloader_wrapper_xrender)( Display*, int, XAnimCursor*); +extern void (*XRenderAddTraps_dylibloader_wrapper_xrender)( Display*, Picture, int, int,const XTrap*, int); +extern Picture (*XRenderCreateSolidFill_dylibloader_wrapper_xrender)( Display*,const XRenderColor*); +extern Picture (*XRenderCreateLinearGradient_dylibloader_wrapper_xrender)( Display*,const XLinearGradient*,const XFixed*,const XRenderColor*, int); +extern Picture (*XRenderCreateRadialGradient_dylibloader_wrapper_xrender)( Display*,const XRadialGradient*,const XFixed*,const XRenderColor*, int); +extern Picture (*XRenderCreateConicalGradient_dylibloader_wrapper_xrender)( Display*,const XConicalGradient*,const XFixed*,const XRenderColor*, int); +int initialize_xrender(int verbose); +#ifdef __cplusplus +} +#endif +#endif diff --git a/platform/linuxbsd/x11/gl_manager_x11.cpp b/platform/linuxbsd/x11/gl_manager_x11.cpp index f586c57dda..f24bac5e19 100644 --- a/platform/linuxbsd/x11/gl_manager_x11.cpp +++ b/platform/linuxbsd/x11/gl_manager_x11.cpp @@ -1,51 +1,51 @@ -/*************************************************************************/ -/* gl_manager_x11.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* gl_manager_x11.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "gl_manager_x11.h" -#ifdef X11_ENABLED -#if defined(GLES3_ENABLED) +#if defined(X11_ENABLED) && defined(GLES3_ENABLED) + +#include "thirdparty/glad/glad/glx.h" #include <stdio.h> #include <stdlib.h> #include <unistd.h> -#define GLX_GLXEXT_PROTOTYPES -#include <GL/glx.h> -#include <GL/glxext.h> - #define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 #define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 typedef GLXContext (*GLXCREATECONTEXTATTRIBSARBPROC)(Display *, GLXFBConfig, GLXContext, Bool, const int *); +// To prevent shadowing warnings +#undef glXCreateContextAttribsARB + struct GLManager_X11_Private { ::GLXContext glx_context; }; @@ -85,8 +85,13 @@ int GLManager_X11::_find_or_create_display(Display *p_x11_display) { d.context = memnew(GLManager_X11_Private); d.context->glx_context = nullptr; - //Error err = _create_context(d); - _create_context(d); + Error err = _create_context(d); + + if (err != OK) { + _displays.remove_at(new_display_id); + return -1; + } + return new_display_id; } @@ -193,8 +198,14 @@ Error GLManager_X11::_create_context(GLDisplay &gl_display) { return OK; } -XVisualInfo GLManager_X11::get_vi(Display *p_display) { - return _displays[_find_or_create_display(p_display)].x_vi; +XVisualInfo GLManager_X11::get_vi(Display *p_display, Error &r_error) { + int display_id = _find_or_create_display(p_display); + if (display_id < 0) { + r_error = FAILED; + return XVisualInfo(); + } + r_error = OK; + return _displays[display_id].x_vi; } Error GLManager_X11::window_create(DisplayServer::WindowID p_window_id, ::Window p_window, Display *p_display, int p_width, int p_height) { @@ -213,6 +224,10 @@ Error GLManager_X11::window_create(DisplayServer::WindowID p_window_id, ::Window win.x11_window = p_window; win.gldisplay_id = _find_or_create_display(p_display); + if (win.gldisplay_id == -1) { + return FAILED; + } + // the display could be invalid .. check NYI GLDisplay &gl_display = _displays[win.gldisplay_id]; ::Display *x11_display = gl_display.x11_display; @@ -323,16 +338,15 @@ void GLManager_X11::swap_buffers() { glXSwapBuffers(_x_windisp.x11_display, _x_windisp.x11_window); } -Error GLManager_X11::initialize() { +Error GLManager_X11::initialize(Display *p_display) { + if (!gladLoaderLoadGLX(p_display, XScreenNumberOfScreen(XDefaultScreenOfDisplay(p_display)))) { + return ERR_CANT_CREATE; + } + return OK; } void GLManager_X11::set_use_vsync(bool p_use) { - static bool setup = false; - static PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT = nullptr; - static PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalMESA = nullptr; - static PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalSGI = nullptr; - // force vsync in the editor for now, as a safety measure bool is_editor = Engine::get_singleton()->is_editor_hint(); if (is_editor) { @@ -345,25 +359,12 @@ void GLManager_X11::set_use_vsync(bool p_use) { } const GLDisplay &disp = get_current_display(); - if (!setup) { - setup = true; - String extensions = glXQueryExtensionsString(disp.x11_display, DefaultScreen(disp.x11_display)); - if (extensions.find("GLX_EXT_swap_control") != -1) { - glXSwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC)glXGetProcAddressARB((const GLubyte *)"glXSwapIntervalEXT"); - } - if (extensions.find("GLX_MESA_swap_control") != -1) { - glXSwapIntervalMESA = (PFNGLXSWAPINTERVALSGIPROC)glXGetProcAddressARB((const GLubyte *)"glXSwapIntervalMESA"); - } - if (extensions.find("GLX_SGI_swap_control") != -1) { - glXSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)glXGetProcAddressARB((const GLubyte *)"glXSwapIntervalSGI"); - } - } int val = p_use ? 1 : 0; - if (glXSwapIntervalMESA) { + if (GLAD_GLX_MESA_swap_control) { glXSwapIntervalMESA(val); - } else if (glXSwapIntervalSGI) { + } else if (GLAD_GLX_SGI_swap_control) { glXSwapIntervalSGI(val); - } else if (glXSwapIntervalEXT) { + } else if (GLAD_GLX_EXT_swap_control) { GLXDrawable drawable = glXGetCurrentDrawable(); glXSwapIntervalEXT(disp.x11_display, drawable, val); } else { @@ -376,6 +377,17 @@ bool GLManager_X11::is_using_vsync() const { return use_vsync; } +void *GLManager_X11::get_glx_context(DisplayServer::WindowID p_window_id) { + if (p_window_id == -1) { + return nullptr; + } + + const GLWindow &win = _windows[p_window_id]; + const GLDisplay &disp = get_display(win.gldisplay_id); + + return (void *)disp.context->glx_context; +} + GLManager_X11::GLManager_X11(const Vector2i &p_size, ContextType p_context_type) { context_type = p_context_type; @@ -390,5 +402,4 @@ GLManager_X11::~GLManager_X11() { release_current(); } -#endif -#endif +#endif // X11_ENABLED && GLES3_ENABLED diff --git a/platform/linuxbsd/x11/gl_manager_x11.h b/platform/linuxbsd/x11/gl_manager_x11.h index 4f78c45c88..59e20fec45 100644 --- a/platform/linuxbsd/x11/gl_manager_x11.h +++ b/platform/linuxbsd/x11/gl_manager_x11.h @@ -1,45 +1,56 @@ -/*************************************************************************/ -/* gl_manager_x11.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* gl_manager_x11.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 GL_MANAGER_X11_H #define GL_MANAGER_X11_H -#ifdef X11_ENABLED - -#ifdef GLES3_ENABLED +#if defined(X11_ENABLED) && defined(GLES3_ENABLED) #include "core/os/os.h" #include "core/templates/local_vector.h" #include "servers/display_server.h" + +#ifdef SOWRAP_ENABLED +#include "dynwrappers/xlib-so_wrap.h" + +#include "dynwrappers/xext-so_wrap.h" +#include "dynwrappers/xrender-so_wrap.h" +#else +#include <X11/XKBlib.h> #include <X11/Xlib.h> +#include <X11/Xutil.h> + +#include <X11/extensions/Xext.h> #include <X11/extensions/Xrender.h> +#include <X11/extensions/shape.h> +#endif struct GLManager_X11_Private; @@ -100,7 +111,7 @@ private: Error _create_context(GLDisplay &gl_display); public: - XVisualInfo get_vi(Display *p_display); + XVisualInfo get_vi(Display *p_display, Error &r_error); Error window_create(DisplayServer::WindowID p_window_id, ::Window p_window, Display *p_display, int p_width, int p_height); void window_destroy(DisplayServer::WindowID p_window_id); void window_resize(DisplayServer::WindowID p_window_id, int p_width, int p_height); @@ -111,16 +122,17 @@ public: void window_make_current(DisplayServer::WindowID p_window_id); - Error initialize(); + Error initialize(Display *p_display); void set_use_vsync(bool p_use); bool is_using_vsync() const; + void *get_glx_context(DisplayServer::WindowID p_window_id); + GLManager_X11(const Vector2i &p_size, ContextType p_context_type); ~GLManager_X11(); }; -#endif // GLES3_ENABLED -#endif // X11_ENABLED +#endif // X11_ENABLED && GLES3_ENABLED #endif // GL_MANAGER_X11_H diff --git a/platform/linuxbsd/x11/key_mapping_x11.cpp b/platform/linuxbsd/x11/key_mapping_x11.cpp index f774c99d99..0f709872cb 100644 --- a/platform/linuxbsd/x11/key_mapping_x11.cpp +++ b/platform/linuxbsd/x11/key_mapping_x11.cpp @@ -1,2001 +1,1175 @@ -/*************************************************************************/ -/* key_mapping_x11.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* key_mapping_x11.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "key_mapping_x11.h" -/***** SCAN CODE CONVERSION ******/ +void KeyMappingX11::initialize() { + // X11 Keysym to Godot Key map. -struct _XTranslatePair { - KeySym keysym; - Key keycode; -}; + xkeysym_map[XK_Escape] = Key::ESCAPE; + xkeysym_map[XK_Tab] = Key::TAB; + xkeysym_map[XK_ISO_Left_Tab] = Key::BACKTAB; + xkeysym_map[XK_BackSpace] = Key::BACKSPACE; + xkeysym_map[XK_Return] = Key::ENTER; + xkeysym_map[XK_Insert] = Key::INSERT; + xkeysym_map[XK_Delete] = Key::KEY_DELETE; + xkeysym_map[XK_Clear] = Key::KEY_DELETE; + xkeysym_map[XK_Pause] = Key::PAUSE; + xkeysym_map[XK_Print] = Key::PRINT; + xkeysym_map[XK_Home] = Key::HOME; + xkeysym_map[XK_End] = Key::END; + xkeysym_map[XK_Left] = Key::LEFT; + xkeysym_map[XK_Up] = Key::UP; + xkeysym_map[XK_Right] = Key::RIGHT; + xkeysym_map[XK_Down] = Key::DOWN; + xkeysym_map[XK_Prior] = Key::PAGEUP; + xkeysym_map[XK_Next] = Key::PAGEDOWN; + xkeysym_map[XK_Shift_L] = Key::SHIFT; + xkeysym_map[XK_Shift_R] = Key::SHIFT; + xkeysym_map[XK_Shift_Lock] = Key::SHIFT; + xkeysym_map[XK_Control_L] = Key::CTRL; + xkeysym_map[XK_Control_R] = Key::CTRL; + xkeysym_map[XK_Meta_L] = Key::META; + xkeysym_map[XK_Meta_R] = Key::META; + xkeysym_map[XK_Alt_L] = Key::ALT; + xkeysym_map[XK_Alt_R] = Key::ALT; + xkeysym_map[XK_Caps_Lock] = Key::CAPSLOCK; + xkeysym_map[XK_Num_Lock] = Key::NUMLOCK; + xkeysym_map[XK_Scroll_Lock] = Key::SCROLLLOCK; + xkeysym_map[XK_less] = Key::QUOTELEFT; + xkeysym_map[XK_grave] = Key::SECTION; + xkeysym_map[XK_Super_L] = Key::META; + xkeysym_map[XK_Super_R] = Key::META; + xkeysym_map[XK_Menu] = Key::MENU; + xkeysym_map[XK_Hyper_L] = Key::HYPER; + xkeysym_map[XK_Hyper_R] = Key::HYPER; + xkeysym_map[XK_Help] = Key::HELP; + xkeysym_map[XK_KP_Space] = Key::SPACE; + xkeysym_map[XK_KP_Tab] = Key::TAB; + xkeysym_map[XK_KP_Enter] = Key::KP_ENTER; + xkeysym_map[XK_Home] = Key::HOME; + xkeysym_map[XK_Left] = Key::LEFT; + xkeysym_map[XK_Up] = Key::UP; + xkeysym_map[XK_Right] = Key::RIGHT; + xkeysym_map[XK_Down] = Key::DOWN; + xkeysym_map[XK_Prior] = Key::PAGEUP; + xkeysym_map[XK_Next] = Key::PAGEDOWN; + xkeysym_map[XK_End] = Key::END; + xkeysym_map[XK_Begin] = Key::CLEAR; + xkeysym_map[XK_Insert] = Key::INSERT; + xkeysym_map[XK_Delete] = Key::KEY_DELETE; + xkeysym_map[XK_KP_Equal] = Key::EQUAL; + xkeysym_map[XK_KP_Separator] = Key::COMMA; + xkeysym_map[XK_KP_Decimal] = Key::KP_PERIOD; + xkeysym_map[XK_KP_Delete] = Key::KP_PERIOD; + xkeysym_map[XK_KP_Multiply] = Key::KP_MULTIPLY; + xkeysym_map[XK_KP_Divide] = Key::KP_DIVIDE; + xkeysym_map[XK_KP_Subtract] = Key::KP_SUBTRACT; + xkeysym_map[XK_KP_Add] = Key::KP_ADD; + xkeysym_map[XK_KP_0] = Key::KP_0; + xkeysym_map[XK_KP_1] = Key::KP_1; + xkeysym_map[XK_KP_2] = Key::KP_2; + xkeysym_map[XK_KP_3] = Key::KP_3; + xkeysym_map[XK_KP_4] = Key::KP_4; + xkeysym_map[XK_KP_5] = Key::KP_5; + xkeysym_map[XK_KP_6] = Key::KP_6; + xkeysym_map[XK_KP_7] = Key::KP_7; + xkeysym_map[XK_KP_8] = Key::KP_8; + xkeysym_map[XK_KP_9] = Key::KP_9; + // Same keys but with numlock off. + xkeysym_map[XK_KP_Insert] = Key::INSERT; + xkeysym_map[XK_KP_End] = Key::END; + xkeysym_map[XK_KP_Down] = Key::DOWN; + xkeysym_map[XK_KP_Page_Down] = Key::PAGEDOWN; + xkeysym_map[XK_KP_Left] = Key::LEFT; + // X11 documents this (numpad 5) as "begin of line" but no toolkit seems to interpret it this way. + // On Windows this is emitting Key::Clear so for consistency it will be mapped to Key::Clear + xkeysym_map[XK_KP_Begin] = Key::CLEAR; + xkeysym_map[XK_KP_Right] = Key::RIGHT; + xkeysym_map[XK_KP_Home] = Key::HOME; + xkeysym_map[XK_KP_Up] = Key::UP; + xkeysym_map[XK_KP_Page_Up] = Key::PAGEUP; + xkeysym_map[XK_F1] = Key::F1; + xkeysym_map[XK_F2] = Key::F2; + xkeysym_map[XK_F3] = Key::F3; + xkeysym_map[XK_F4] = Key::F4; + xkeysym_map[XK_F5] = Key::F5; + xkeysym_map[XK_F6] = Key::F6; + xkeysym_map[XK_F7] = Key::F7; + xkeysym_map[XK_F8] = Key::F8; + xkeysym_map[XK_F9] = Key::F9; + xkeysym_map[XK_F10] = Key::F10; + xkeysym_map[XK_F11] = Key::F11; + xkeysym_map[XK_F12] = Key::F12; + xkeysym_map[XK_F13] = Key::F13; + xkeysym_map[XK_F14] = Key::F14; + xkeysym_map[XK_F15] = Key::F15; + xkeysym_map[XK_F16] = Key::F16; + xkeysym_map[XK_F17] = Key::F17; + xkeysym_map[XK_F18] = Key::F18; + xkeysym_map[XK_F19] = Key::F19; + xkeysym_map[XK_F20] = Key::F20; + xkeysym_map[XK_F21] = Key::F21; + xkeysym_map[XK_F22] = Key::F22; + xkeysym_map[XK_F23] = Key::F23; + xkeysym_map[XK_F24] = Key::F24; + xkeysym_map[XK_F25] = Key::F25; + xkeysym_map[XK_F26] = Key::F26; + xkeysym_map[XK_F27] = Key::F27; + xkeysym_map[XK_F28] = Key::F28; + xkeysym_map[XK_F29] = Key::F29; + xkeysym_map[XK_F30] = Key::F30; + xkeysym_map[XK_F31] = Key::F31; + xkeysym_map[XK_F32] = Key::F32; + xkeysym_map[XK_F33] = Key::F33; + xkeysym_map[XK_F34] = Key::F34; + xkeysym_map[XK_F35] = Key::F35; + xkeysym_map[XK_yen] = Key::YEN; + xkeysym_map[XK_section] = Key::SECTION; + // Media keys. + xkeysym_map[XF86XK_Back] = Key::BACK; + xkeysym_map[XF86XK_Forward] = Key::FORWARD; + xkeysym_map[XF86XK_Stop] = Key::STOP; + xkeysym_map[XF86XK_Refresh] = Key::REFRESH; + xkeysym_map[XF86XK_Favorites] = Key::FAVORITES; + xkeysym_map[XF86XK_OpenURL] = Key::OPENURL; + xkeysym_map[XF86XK_HomePage] = Key::HOMEPAGE; + xkeysym_map[XF86XK_Search] = Key::SEARCH; + xkeysym_map[XF86XK_AudioLowerVolume] = Key::VOLUMEDOWN; + xkeysym_map[XF86XK_AudioMute] = Key::VOLUMEMUTE; + xkeysym_map[XF86XK_AudioRaiseVolume] = Key::VOLUMEUP; + xkeysym_map[XF86XK_AudioPlay] = Key::MEDIAPLAY; + xkeysym_map[XF86XK_AudioStop] = Key::MEDIASTOP; + xkeysym_map[XF86XK_AudioPrev] = Key::MEDIAPREVIOUS; + xkeysym_map[XF86XK_AudioNext] = Key::MEDIANEXT; + xkeysym_map[XF86XK_AudioRecord] = Key::MEDIARECORD; + xkeysym_map[XF86XK_Standby] = Key::STANDBY; + // Launch keys. + xkeysym_map[XF86XK_Mail] = Key::LAUNCHMAIL; + xkeysym_map[XF86XK_AudioMedia] = Key::LAUNCHMEDIA; + xkeysym_map[XF86XK_MyComputer] = Key::LAUNCH0; + xkeysym_map[XF86XK_Calculator] = Key::LAUNCH1; + xkeysym_map[XF86XK_Launch0] = Key::LAUNCH2; + xkeysym_map[XF86XK_Launch1] = Key::LAUNCH3; + xkeysym_map[XF86XK_Launch2] = Key::LAUNCH4; + xkeysym_map[XF86XK_Launch3] = Key::LAUNCH5; + xkeysym_map[XF86XK_Launch4] = Key::LAUNCH6; + xkeysym_map[XF86XK_Launch5] = Key::LAUNCH7; + xkeysym_map[XF86XK_Launch6] = Key::LAUNCH8; + xkeysym_map[XF86XK_Launch7] = Key::LAUNCH9; + xkeysym_map[XF86XK_Launch8] = Key::LAUNCHA; + xkeysym_map[XF86XK_Launch9] = Key::LAUNCHB; + xkeysym_map[XF86XK_LaunchA] = Key::LAUNCHC; + xkeysym_map[XF86XK_LaunchB] = Key::LAUNCHD; + xkeysym_map[XF86XK_LaunchC] = Key::LAUNCHE; + xkeysym_map[XF86XK_LaunchD] = Key::LAUNCHF; -static _XTranslatePair _xkeysym_to_keycode[] = { - // misc keys + // Scancode to Godot Key map. + scancode_map[0x09] = Key::ESCAPE; + scancode_map[0x0A] = Key::KEY_1; + scancode_map[0x0B] = Key::KEY_2; + scancode_map[0x0C] = Key::KEY_3; + scancode_map[0x0D] = Key::KEY_4; + scancode_map[0x0E] = Key::KEY_5; + scancode_map[0x0F] = Key::KEY_6; + scancode_map[0x10] = Key::KEY_7; + scancode_map[0x11] = Key::KEY_8; + scancode_map[0x12] = Key::KEY_9; + scancode_map[0x13] = Key::KEY_0; + scancode_map[0x14] = Key::MINUS; + scancode_map[0x15] = Key::EQUAL; + scancode_map[0x16] = Key::BACKSPACE; + scancode_map[0x17] = Key::TAB; + scancode_map[0x18] = Key::Q; + scancode_map[0x19] = Key::W; + scancode_map[0x1A] = Key::E; + scancode_map[0x1B] = Key::R; + scancode_map[0x1C] = Key::T; + scancode_map[0x1D] = Key::Y; + scancode_map[0x1E] = Key::U; + scancode_map[0x1F] = Key::I; + scancode_map[0x20] = Key::O; + scancode_map[0x21] = Key::P; + scancode_map[0x22] = Key::BRACKETLEFT; + scancode_map[0x23] = Key::BRACKETRIGHT; + scancode_map[0x24] = Key::ENTER; + scancode_map[0x25] = Key::CTRL; // Left + scancode_map[0x26] = Key::A; + scancode_map[0x27] = Key::S; + scancode_map[0x28] = Key::D; + scancode_map[0x29] = Key::F; + scancode_map[0x2A] = Key::G; + scancode_map[0x2B] = Key::H; + scancode_map[0x2C] = Key::J; + scancode_map[0x2D] = Key::K; + scancode_map[0x2E] = Key::L; + scancode_map[0x2F] = Key::SEMICOLON; + scancode_map[0x30] = Key::APOSTROPHE; + scancode_map[0x31] = Key::QUOTELEFT; + scancode_map[0x32] = Key::SHIFT; // Left + scancode_map[0x33] = Key::BACKSLASH; + scancode_map[0x34] = Key::Z; + scancode_map[0x35] = Key::X; + scancode_map[0x36] = Key::C; + scancode_map[0x37] = Key::V; + scancode_map[0x38] = Key::B; + scancode_map[0x39] = Key::N; + scancode_map[0x3A] = Key::M; + scancode_map[0x3B] = Key::COMMA; + scancode_map[0x3C] = Key::PERIOD; + scancode_map[0x3D] = Key::SLASH; + scancode_map[0x3E] = Key::SHIFT; // Right + scancode_map[0x3F] = Key::KP_MULTIPLY; + scancode_map[0x40] = Key::ALT; // Left + scancode_map[0x41] = Key::SPACE; + scancode_map[0x42] = Key::CAPSLOCK; + scancode_map[0x43] = Key::F1; + scancode_map[0x44] = Key::F2; + scancode_map[0x45] = Key::F3; + scancode_map[0x46] = Key::F4; + scancode_map[0x47] = Key::F5; + scancode_map[0x48] = Key::F6; + scancode_map[0x49] = Key::F7; + scancode_map[0x4A] = Key::F8; + scancode_map[0x4B] = Key::F9; + scancode_map[0x4C] = Key::F10; + scancode_map[0x4D] = Key::NUMLOCK; + scancode_map[0x4E] = Key::SCROLLLOCK; + scancode_map[0x4F] = Key::KP_7; + scancode_map[0x50] = Key::KP_8; + scancode_map[0x51] = Key::KP_9; + scancode_map[0x52] = Key::KP_SUBTRACT; + scancode_map[0x53] = Key::KP_4; + scancode_map[0x54] = Key::KP_5; + scancode_map[0x55] = Key::KP_6; + scancode_map[0x56] = Key::KP_ADD; + scancode_map[0x57] = Key::KP_1; + scancode_map[0x58] = Key::KP_2; + scancode_map[0x59] = Key::KP_3; + scancode_map[0x5A] = Key::KP_0; + scancode_map[0x5B] = Key::KP_PERIOD; + //scancode_map[0x5C] + //scancode_map[0x5D] // Zenkaku Hankaku + scancode_map[0x5E] = Key::SECTION; + scancode_map[0x5F] = Key::F11; + scancode_map[0x60] = Key::F12; + //scancode_map[0x61] // Romaji + //scancode_map[0x62] // Katakana + //scancode_map[0x63] // Hiragana + //scancode_map[0x64] // Henkan + //scancode_map[0x65] // Hiragana Katakana + //scancode_map[0x66] // Muhenkan + scancode_map[0x67] = Key::COMMA; // KP_Separator + scancode_map[0x68] = Key::KP_ENTER; + scancode_map[0x69] = Key::CTRL; // Right + scancode_map[0x6A] = Key::KP_DIVIDE; + scancode_map[0x6B] = Key::PRINT; + scancode_map[0x6C] = Key::ALT; // Right + scancode_map[0x6D] = Key::ENTER; + scancode_map[0x6E] = Key::HOME; + scancode_map[0x6F] = Key::UP; + scancode_map[0x70] = Key::PAGEUP; + scancode_map[0x71] = Key::LEFT; + scancode_map[0x72] = Key::RIGHT; + scancode_map[0x73] = Key::END; + scancode_map[0x74] = Key::DOWN; + scancode_map[0x75] = Key::PAGEDOWN; + scancode_map[0x76] = Key::INSERT; + scancode_map[0x77] = Key::KEY_DELETE; + //scancode_map[0x78] // Macro + scancode_map[0x79] = Key::VOLUMEMUTE; + scancode_map[0x7A] = Key::VOLUMEDOWN; + scancode_map[0x7B] = Key::VOLUMEUP; + //scancode_map[0x7C] // Power + scancode_map[0x7D] = Key::EQUAL; // KP_Equal + //scancode_map[0x7E] // KP_PlusMinus + scancode_map[0x7F] = Key::PAUSE; + scancode_map[0x80] = Key::LAUNCH0; + scancode_map[0x81] = Key::COMMA; // KP_Comma + //scancode_map[0x82] // Hangul + //scancode_map[0x83] // Hangul_Hanja + scancode_map[0x84] = Key::YEN; + scancode_map[0x85] = Key::META; // Left + scancode_map[0x86] = Key::META; // Right + scancode_map[0x87] = Key::MENU; - { XK_Escape, Key::ESCAPE }, - { XK_Tab, Key::TAB }, - { XK_ISO_Left_Tab, Key::BACKTAB }, - { XK_BackSpace, Key::BACKSPACE }, - { XK_Return, Key::ENTER }, - { XK_Insert, Key::INSERT }, - { XK_Delete, Key::KEY_DELETE }, - { XK_Clear, Key::KEY_DELETE }, - { XK_Pause, Key::PAUSE }, - { XK_Print, Key::PRINT }, - { XK_Home, Key::HOME }, - { XK_End, Key::END }, - { XK_Left, Key::LEFT }, - { XK_Up, Key::UP }, - { XK_Right, Key::RIGHT }, - { XK_Down, Key::DOWN }, - { XK_Prior, Key::PAGEUP }, - { XK_Next, Key::PAGEDOWN }, - { XK_Shift_L, Key::SHIFT }, - { XK_Shift_R, Key::SHIFT }, - { XK_Shift_Lock, Key::SHIFT }, - { XK_Control_L, Key::CTRL }, - { XK_Control_R, Key::CTRL }, - { XK_Meta_L, Key::META }, - { XK_Meta_R, Key::META }, - { XK_Alt_L, Key::ALT }, - { XK_Alt_R, Key::ALT }, - { XK_Caps_Lock, Key::CAPSLOCK }, - { XK_Num_Lock, Key::NUMLOCK }, - { XK_Scroll_Lock, Key::SCROLLLOCK }, - { XK_Super_L, Key::SUPER_L }, - { XK_Super_R, Key::SUPER_R }, - { XK_Menu, Key::MENU }, - { XK_Hyper_L, Key::HYPER_L }, - { XK_Hyper_R, Key::HYPER_R }, - { XK_Help, Key::HELP }, - { XK_KP_Space, Key::SPACE }, - { XK_KP_Tab, Key::TAB }, - { XK_KP_Enter, Key::KP_ENTER }, - { XK_Home, Key::HOME }, - { XK_Left, Key::LEFT }, - { XK_Up, Key::UP }, - { XK_Right, Key::RIGHT }, - { XK_Down, Key::DOWN }, - { XK_Prior, Key::PAGEUP }, - { XK_Next, Key::PAGEDOWN }, - { XK_End, Key::END }, - { XK_Begin, Key::CLEAR }, - { XK_Insert, Key::INSERT }, - { XK_Delete, Key::KEY_DELETE }, - //{ XK_KP_Equal, Key::EQUAL }, - //{ XK_KP_Separator, Key::COMMA }, - { XK_KP_Decimal, Key::KP_PERIOD }, - { XK_KP_Delete, Key::KP_PERIOD }, - { XK_KP_Multiply, Key::KP_MULTIPLY }, - { XK_KP_Divide, Key::KP_DIVIDE }, - { XK_KP_Subtract, Key::KP_SUBTRACT }, - { XK_KP_Add, Key::KP_ADD }, - { XK_KP_0, Key::KP_0 }, - { XK_KP_1, Key::KP_1 }, - { XK_KP_2, Key::KP_2 }, - { XK_KP_3, Key::KP_3 }, - { XK_KP_4, Key::KP_4 }, - { XK_KP_5, Key::KP_5 }, - { XK_KP_6, Key::KP_6 }, - { XK_KP_7, Key::KP_7 }, - { XK_KP_8, Key::KP_8 }, - { XK_KP_9, Key::KP_9 }, - // same keys but with numlock off - { XK_KP_Insert, Key::INSERT }, - { XK_KP_End, Key::END }, - { XK_KP_Down, Key::DOWN }, - { XK_KP_Page_Down, Key::PAGEDOWN }, - { XK_KP_Left, Key::LEFT }, - // X11 documents this (numpad 5) as "begin of line" but no toolkit - // seems to interpret it this way. - // On Windows this is emitting Key::Clear so for consistency it - // will be mapped to Key::Clear - { XK_KP_Begin, Key::CLEAR }, - { XK_KP_Right, Key::RIGHT }, - { XK_KP_Home, Key::HOME }, - { XK_KP_Up, Key::UP }, - { XK_KP_Page_Up, Key::PAGEUP }, - { XK_F1, Key::F1 }, - { XK_F2, Key::F2 }, - { XK_F3, Key::F3 }, - { XK_F4, Key::F4 }, - { XK_F5, Key::F5 }, - { XK_F6, Key::F6 }, - { XK_F7, Key::F7 }, - { XK_F8, Key::F8 }, - { XK_F9, Key::F9 }, - { XK_F10, Key::F10 }, - { XK_F11, Key::F11 }, - { XK_F12, Key::F12 }, - { XK_F13, Key::F13 }, - { XK_F14, Key::F14 }, - { XK_F15, Key::F15 }, - { XK_F16, Key::F16 }, - { XK_F17, Key::F17 }, - { XK_F18, Key::F18 }, - { XK_F19, Key::F19 }, - { XK_F20, Key::F20 }, - { XK_F21, Key::F21 }, - { XK_F22, Key::F22 }, - { XK_F23, Key::F23 }, - { XK_F24, Key::F24 }, - { XK_F25, Key::F25 }, - { XK_F26, Key::F26 }, - { XK_F27, Key::F27 }, - { XK_F28, Key::F28 }, - { XK_F29, Key::F29 }, - { XK_F30, Key::F30 }, - { XK_F31, Key::F31 }, - { XK_F32, Key::F32 }, - { XK_F33, Key::F33 }, - { XK_F34, Key::F34 }, - { XK_F35, Key::F35 }, + scancode_map[0xA6] = Key::BACK; // On Chromebooks + scancode_map[0xA7] = Key::FORWARD; // On Chromebooks - // media keys - { XF86XK_Back, Key::BACK }, - { XF86XK_Forward, Key::FORWARD }, - { XF86XK_Stop, Key::STOP }, - { XF86XK_Refresh, Key::REFRESH }, - { XF86XK_Favorites, Key::FAVORITES }, - { XF86XK_AudioMedia, Key::LAUNCHMEDIA }, - { XF86XK_OpenURL, Key::OPENURL }, - { XF86XK_HomePage, Key::HOMEPAGE }, - { XF86XK_Search, Key::SEARCH }, - { XF86XK_AudioLowerVolume, Key::VOLUMEDOWN }, - { XF86XK_AudioMute, Key::VOLUMEMUTE }, - { XF86XK_AudioRaiseVolume, Key::VOLUMEUP }, - { XF86XK_AudioPlay, Key::MEDIAPLAY }, - { XF86XK_AudioStop, Key::MEDIASTOP }, - { XF86XK_AudioPrev, Key::MEDIAPREVIOUS }, - { XF86XK_AudioNext, Key::MEDIANEXT }, - { XF86XK_AudioRecord, Key::MEDIARECORD }, + scancode_map[0xB5] = Key::REFRESH; // On Chromebooks - // launch keys - { XF86XK_Mail, Key::LAUNCHMAIL }, - { XF86XK_MyComputer, Key::LAUNCH0 }, - { XF86XK_Calculator, Key::LAUNCH1 }, - { XF86XK_Standby, Key::STANDBY }, + scancode_map[0xBF] = Key::F13; + scancode_map[0xC0] = Key::F14; + scancode_map[0xC1] = Key::F15; + scancode_map[0xC2] = Key::F16; + scancode_map[0xC3] = Key::F17; + scancode_map[0xC4] = Key::F18; + scancode_map[0xC5] = Key::F19; + scancode_map[0xC6] = Key::F20; + scancode_map[0xC7] = Key::F21; + scancode_map[0xC8] = Key::F22; + scancode_map[0xC9] = Key::F23; + scancode_map[0xCA] = Key::F24; + scancode_map[0xCB] = Key::F25; + scancode_map[0xCC] = Key::F26; + scancode_map[0xCD] = Key::F27; + scancode_map[0xCE] = Key::F28; + scancode_map[0xCF] = Key::F29; + scancode_map[0xD0] = Key::F30; + scancode_map[0xD1] = Key::F31; + scancode_map[0xD2] = Key::F32; + scancode_map[0xD3] = Key::F33; + scancode_map[0xD4] = Key::F34; + scancode_map[0xD5] = Key::F35; - { XF86XK_Launch0, Key::LAUNCH2 }, - { XF86XK_Launch1, Key::LAUNCH3 }, - { XF86XK_Launch2, Key::LAUNCH4 }, - { XF86XK_Launch3, Key::LAUNCH5 }, - { XF86XK_Launch4, Key::LAUNCH6 }, - { XF86XK_Launch5, Key::LAUNCH7 }, - { XF86XK_Launch6, Key::LAUNCH8 }, - { XF86XK_Launch7, Key::LAUNCH9 }, - { XF86XK_Launch8, Key::LAUNCHA }, - { XF86XK_Launch9, Key::LAUNCHB }, - { XF86XK_LaunchA, Key::LAUNCHC }, - { XF86XK_LaunchB, Key::LAUNCHD }, - { XF86XK_LaunchC, Key::LAUNCHE }, - { XF86XK_LaunchD, Key::LAUNCHF }, - - { 0, Key::NONE } -}; - -struct _TranslatePair { - Key keysym; - unsigned int keycode; -}; - -static _TranslatePair _scancode_to_keycode[] = { - { Key::ESCAPE, 0x09 }, - { Key::KEY_1, 0x0A }, - { Key::KEY_2, 0x0B }, - { Key::KEY_3, 0x0C }, - { Key::KEY_4, 0x0D }, - { Key::KEY_5, 0x0E }, - { Key::KEY_6, 0x0F }, - { Key::KEY_7, 0x10 }, - { Key::KEY_8, 0x11 }, - { Key::KEY_9, 0x12 }, - { Key::KEY_0, 0x13 }, - { Key::MINUS, 0x14 }, - { Key::EQUAL, 0x15 }, - { Key::BACKSPACE, 0x16 }, - { Key::TAB, 0x17 }, - { Key::Q, 0x18 }, - { Key::W, 0x19 }, - { Key::E, 0x1A }, - { Key::R, 0x1B }, - { Key::T, 0x1C }, - { Key::Y, 0x1D }, - { Key::U, 0x1E }, - { Key::I, 0x1F }, - { Key::O, 0x20 }, - { Key::P, 0x21 }, - { Key::BRACELEFT, 0x22 }, - { Key::BRACERIGHT, 0x23 }, - { Key::ENTER, 0x24 }, - { Key::CTRL, 0x25 }, - { Key::A, 0x26 }, - { Key::S, 0x27 }, - { Key::D, 0x28 }, - { Key::F, 0x29 }, - { Key::G, 0x2A }, - { Key::H, 0x2B }, - { Key::J, 0x2C }, - { Key::K, 0x2D }, - { Key::L, 0x2E }, - { Key::SEMICOLON, 0x2F }, - { Key::APOSTROPHE, 0x30 }, - { Key::QUOTELEFT, 0x31 }, - { Key::SHIFT, 0x32 }, - { Key::BACKSLASH, 0x33 }, - { Key::Z, 0x34 }, - { Key::X, 0x35 }, - { Key::C, 0x36 }, - { Key::V, 0x37 }, - { Key::B, 0x38 }, - { Key::N, 0x39 }, - { Key::M, 0x3A }, - { Key::COMMA, 0x3B }, - { Key::PERIOD, 0x3C }, - { Key::SLASH, 0x3D }, - { Key::SHIFT, 0x3E }, - { Key::KP_MULTIPLY, 0x3F }, - { Key::ALT, 0x40 }, - { Key::SPACE, 0x41 }, - { Key::CAPSLOCK, 0x42 }, - { Key::F1, 0x43 }, - { Key::F2, 0x44 }, - { Key::F3, 0x45 }, - { Key::F4, 0x46 }, - { Key::F5, 0x47 }, - { Key::F6, 0x48 }, - { Key::F7, 0x49 }, - { Key::F8, 0x4A }, - { Key::F9, 0x4B }, - { Key::F10, 0x4C }, - { Key::NUMLOCK, 0x4D }, - { Key::SCROLLLOCK, 0x4E }, - { Key::KP_7, 0x4F }, - { Key::KP_8, 0x50 }, - { Key::KP_9, 0x51 }, - { Key::KP_SUBTRACT, 0x52 }, - { Key::KP_4, 0x53 }, - { Key::KP_5, 0x54 }, - { Key::KP_6, 0x55 }, - { Key::KP_ADD, 0x56 }, - { Key::KP_1, 0x57 }, - { Key::KP_2, 0x58 }, - { Key::KP_3, 0x59 }, - { Key::KP_0, 0x5A }, - { Key::KP_PERIOD, 0x5B }, - //{ Key::???, 0x5E }, //NON US BACKSLASH - { Key::F11, 0x5F }, - { Key::F12, 0x60 }, - { Key::KP_ENTER, 0x68 }, - { Key::CTRL, 0x69 }, - { Key::KP_DIVIDE, 0x6A }, - { Key::PRINT, 0x6B }, - { Key::ALT, 0x6C }, - { Key::ENTER, 0x6D }, - { Key::HOME, 0x6E }, - { Key::UP, 0x6F }, - { Key::PAGEUP, 0x70 }, - { Key::LEFT, 0x71 }, - { Key::RIGHT, 0x72 }, - { Key::END, 0x73 }, - { Key::DOWN, 0x74 }, - { Key::PAGEDOWN, 0x75 }, - { Key::INSERT, 0x76 }, - { Key::KEY_DELETE, 0x77 }, - { Key::VOLUMEMUTE, 0x79 }, - { Key::VOLUMEDOWN, 0x7A }, - { Key::VOLUMEUP, 0x7B }, - { Key::PAUSE, 0x7F }, - { Key::SUPER_L, 0x85 }, - { Key::SUPER_R, 0x86 }, - { Key::MENU, 0x87 }, - { Key::F13, 0xBF }, - { Key::F14, 0xC0 }, - { Key::F15, 0xC1 }, - { Key::F16, 0xC2 }, - { Key::F17, 0xC3 }, - { Key::F18, 0xC4 }, - { Key::F19, 0xC5 }, - { Key::F20, 0xC6 }, - { Key::F21, 0xC7 }, - { Key::F22, 0xC8 }, - { Key::F23, 0xC9 }, - { Key::F24, 0xCA }, - { Key::F25, 0xCB }, - { Key::F26, 0xCC }, - { Key::F27, 0xCD }, - { Key::F28, 0xCE }, - { Key::F29, 0xCF }, - { Key::F30, 0xD0 }, - { Key::F31, 0xD1 }, - { Key::F32, 0xD2 }, - { Key::F33, 0xD3 }, - { Key::F34, 0xD4 }, - { Key::F35, 0xD5 }, - { Key::UNKNOWN, 0 } -}; - -Key KeyMappingX11::get_scancode(unsigned int p_code) { - Key keycode = Key::UNKNOWN; - for (int i = 0; _scancode_to_keycode[i].keysym != Key::UNKNOWN; i++) { - if (_scancode_to_keycode[i].keycode == p_code) { - keycode = _scancode_to_keycode[i].keysym; - break; - } + // Godot to scancode map. + for (const KeyValue<unsigned int, Key> &E : scancode_map) { + scancode_map_inv[E.value] = E.key; } - return keycode; + // Keysym to Unicode map, tables taken from FOX toolkit. + xkeysym_unicode_map[0x01A1] = 0x0104; + xkeysym_unicode_map[0x01A2] = 0x02D8; + xkeysym_unicode_map[0x01A3] = 0x0141; + xkeysym_unicode_map[0x01A5] = 0x013D; + xkeysym_unicode_map[0x01A6] = 0x015A; + xkeysym_unicode_map[0x01A9] = 0x0160; + xkeysym_unicode_map[0x01AA] = 0x015E; + xkeysym_unicode_map[0x01AB] = 0x0164; + xkeysym_unicode_map[0x01AC] = 0x0179; + xkeysym_unicode_map[0x01AE] = 0x017D; + xkeysym_unicode_map[0x01AF] = 0x017B; + xkeysym_unicode_map[0x01B1] = 0x0105; + xkeysym_unicode_map[0x01B2] = 0x02DB; + xkeysym_unicode_map[0x01B3] = 0x0142; + xkeysym_unicode_map[0x01B5] = 0x013E; + xkeysym_unicode_map[0x01B6] = 0x015B; + xkeysym_unicode_map[0x01B7] = 0x02C7; + xkeysym_unicode_map[0x01B9] = 0x0161; + xkeysym_unicode_map[0x01BA] = 0x015F; + xkeysym_unicode_map[0x01BB] = 0x0165; + xkeysym_unicode_map[0x01BC] = 0x017A; + xkeysym_unicode_map[0x01BD] = 0x02DD; + xkeysym_unicode_map[0x01BE] = 0x017E; + xkeysym_unicode_map[0x01BF] = 0x017C; + xkeysym_unicode_map[0x01C0] = 0x0154; + xkeysym_unicode_map[0x01C3] = 0x0102; + xkeysym_unicode_map[0x01C5] = 0x0139; + xkeysym_unicode_map[0x01C6] = 0x0106; + xkeysym_unicode_map[0x01C8] = 0x010C; + xkeysym_unicode_map[0x01CA] = 0x0118; + xkeysym_unicode_map[0x01CC] = 0x011A; + xkeysym_unicode_map[0x01CF] = 0x010E; + xkeysym_unicode_map[0x01D0] = 0x0110; + xkeysym_unicode_map[0x01D1] = 0x0143; + xkeysym_unicode_map[0x01D2] = 0x0147; + xkeysym_unicode_map[0x01D5] = 0x0150; + xkeysym_unicode_map[0x01D8] = 0x0158; + xkeysym_unicode_map[0x01D9] = 0x016E; + xkeysym_unicode_map[0x01DB] = 0x0170; + xkeysym_unicode_map[0x01DE] = 0x0162; + xkeysym_unicode_map[0x01E0] = 0x0155; + xkeysym_unicode_map[0x01E3] = 0x0103; + xkeysym_unicode_map[0x01E5] = 0x013A; + xkeysym_unicode_map[0x01E6] = 0x0107; + xkeysym_unicode_map[0x01E8] = 0x010D; + xkeysym_unicode_map[0x01EA] = 0x0119; + xkeysym_unicode_map[0x01EC] = 0x011B; + xkeysym_unicode_map[0x01EF] = 0x010F; + xkeysym_unicode_map[0x01F0] = 0x0111; + xkeysym_unicode_map[0x01F1] = 0x0144; + xkeysym_unicode_map[0x01F2] = 0x0148; + xkeysym_unicode_map[0x01F5] = 0x0151; + xkeysym_unicode_map[0x01F8] = 0x0159; + xkeysym_unicode_map[0x01F9] = 0x016F; + xkeysym_unicode_map[0x01FB] = 0x0171; + xkeysym_unicode_map[0x01FE] = 0x0163; + xkeysym_unicode_map[0x01FF] = 0x02D9; + xkeysym_unicode_map[0x02A1] = 0x0126; + xkeysym_unicode_map[0x02A6] = 0x0124; + xkeysym_unicode_map[0x02A9] = 0x0130; + xkeysym_unicode_map[0x02AB] = 0x011E; + xkeysym_unicode_map[0x02AC] = 0x0134; + xkeysym_unicode_map[0x02B1] = 0x0127; + xkeysym_unicode_map[0x02B6] = 0x0125; + xkeysym_unicode_map[0x02B9] = 0x0131; + xkeysym_unicode_map[0x02BB] = 0x011F; + xkeysym_unicode_map[0x02BC] = 0x0135; + xkeysym_unicode_map[0x02C5] = 0x010A; + xkeysym_unicode_map[0x02C6] = 0x0108; + xkeysym_unicode_map[0x02D5] = 0x0120; + xkeysym_unicode_map[0x02D8] = 0x011C; + xkeysym_unicode_map[0x02DD] = 0x016C; + xkeysym_unicode_map[0x02DE] = 0x015C; + xkeysym_unicode_map[0x02E5] = 0x010B; + xkeysym_unicode_map[0x02E6] = 0x0109; + xkeysym_unicode_map[0x02F5] = 0x0121; + xkeysym_unicode_map[0x02F8] = 0x011D; + xkeysym_unicode_map[0x02FD] = 0x016D; + xkeysym_unicode_map[0x02FE] = 0x015D; + xkeysym_unicode_map[0x03A2] = 0x0138; + xkeysym_unicode_map[0x03A3] = 0x0156; + xkeysym_unicode_map[0x03A5] = 0x0128; + xkeysym_unicode_map[0x03A6] = 0x013B; + xkeysym_unicode_map[0x03AA] = 0x0112; + xkeysym_unicode_map[0x03AB] = 0x0122; + xkeysym_unicode_map[0x03AC] = 0x0166; + xkeysym_unicode_map[0x03B3] = 0x0157; + xkeysym_unicode_map[0x03B5] = 0x0129; + xkeysym_unicode_map[0x03B6] = 0x013C; + xkeysym_unicode_map[0x03BA] = 0x0113; + xkeysym_unicode_map[0x03BB] = 0x0123; + xkeysym_unicode_map[0x03BC] = 0x0167; + xkeysym_unicode_map[0x03BD] = 0x014A; + xkeysym_unicode_map[0x03BF] = 0x014B; + xkeysym_unicode_map[0x03C0] = 0x0100; + xkeysym_unicode_map[0x03C7] = 0x012E; + xkeysym_unicode_map[0x03CC] = 0x0116; + xkeysym_unicode_map[0x03CF] = 0x012A; + xkeysym_unicode_map[0x03D1] = 0x0145; + xkeysym_unicode_map[0x03D2] = 0x014C; + xkeysym_unicode_map[0x03D3] = 0x0136; + xkeysym_unicode_map[0x03D9] = 0x0172; + xkeysym_unicode_map[0x03DD] = 0x0168; + xkeysym_unicode_map[0x03DE] = 0x016A; + xkeysym_unicode_map[0x03E0] = 0x0101; + xkeysym_unicode_map[0x03E7] = 0x012F; + xkeysym_unicode_map[0x03EC] = 0x0117; + xkeysym_unicode_map[0x03EF] = 0x012B; + xkeysym_unicode_map[0x03F1] = 0x0146; + xkeysym_unicode_map[0x03F2] = 0x014D; + xkeysym_unicode_map[0x03F3] = 0x0137; + xkeysym_unicode_map[0x03F9] = 0x0173; + xkeysym_unicode_map[0x03FD] = 0x0169; + xkeysym_unicode_map[0x03FE] = 0x016B; + xkeysym_unicode_map[0x047E] = 0x203E; + xkeysym_unicode_map[0x04A1] = 0x3002; + xkeysym_unicode_map[0x04A2] = 0x300C; + xkeysym_unicode_map[0x04A3] = 0x300D; + xkeysym_unicode_map[0x04A4] = 0x3001; + xkeysym_unicode_map[0x04A5] = 0x30FB; + xkeysym_unicode_map[0x04A6] = 0x30F2; + xkeysym_unicode_map[0x04A7] = 0x30A1; + xkeysym_unicode_map[0x04A8] = 0x30A3; + xkeysym_unicode_map[0x04A9] = 0x30A5; + xkeysym_unicode_map[0x04AA] = 0x30A7; + xkeysym_unicode_map[0x04AB] = 0x30A9; + xkeysym_unicode_map[0x04AC] = 0x30E3; + xkeysym_unicode_map[0x04AD] = 0x30E5; + xkeysym_unicode_map[0x04AE] = 0x30E7; + xkeysym_unicode_map[0x04AF] = 0x30C3; + xkeysym_unicode_map[0x04B0] = 0x30FC; + xkeysym_unicode_map[0x04B1] = 0x30A2; + xkeysym_unicode_map[0x04B2] = 0x30A4; + xkeysym_unicode_map[0x04B3] = 0x30A6; + xkeysym_unicode_map[0x04B4] = 0x30A8; + xkeysym_unicode_map[0x04B5] = 0x30AA; + xkeysym_unicode_map[0x04B6] = 0x30AB; + xkeysym_unicode_map[0x04B7] = 0x30AD; + xkeysym_unicode_map[0x04B8] = 0x30AF; + xkeysym_unicode_map[0x04B9] = 0x30B1; + xkeysym_unicode_map[0x04BA] = 0x30B3; + xkeysym_unicode_map[0x04BB] = 0x30B5; + xkeysym_unicode_map[0x04BC] = 0x30B7; + xkeysym_unicode_map[0x04BD] = 0x30B9; + xkeysym_unicode_map[0x04BE] = 0x30BB; + xkeysym_unicode_map[0x04BF] = 0x30BD; + xkeysym_unicode_map[0x04C0] = 0x30BF; + xkeysym_unicode_map[0x04C1] = 0x30C1; + xkeysym_unicode_map[0x04C2] = 0x30C4; + xkeysym_unicode_map[0x04C3] = 0x30C6; + xkeysym_unicode_map[0x04C4] = 0x30C8; + xkeysym_unicode_map[0x04C5] = 0x30CA; + xkeysym_unicode_map[0x04C6] = 0x30CB; + xkeysym_unicode_map[0x04C7] = 0x30CC; + xkeysym_unicode_map[0x04C8] = 0x30CD; + xkeysym_unicode_map[0x04C9] = 0x30CE; + xkeysym_unicode_map[0x04CA] = 0x30CF; + xkeysym_unicode_map[0x04CB] = 0x30D2; + xkeysym_unicode_map[0x04CC] = 0x30D5; + xkeysym_unicode_map[0x04CD] = 0x30D8; + xkeysym_unicode_map[0x04CE] = 0x30DB; + xkeysym_unicode_map[0x04CF] = 0x30DE; + xkeysym_unicode_map[0x04D0] = 0x30DF; + xkeysym_unicode_map[0x04D1] = 0x30E0; + xkeysym_unicode_map[0x04D2] = 0x30E1; + xkeysym_unicode_map[0x04D3] = 0x30E2; + xkeysym_unicode_map[0x04D4] = 0x30E4; + xkeysym_unicode_map[0x04D5] = 0x30E6; + xkeysym_unicode_map[0x04D6] = 0x30E8; + xkeysym_unicode_map[0x04D7] = 0x30E9; + xkeysym_unicode_map[0x04D8] = 0x30EA; + xkeysym_unicode_map[0x04D9] = 0x30EB; + xkeysym_unicode_map[0x04DA] = 0x30EC; + xkeysym_unicode_map[0x04DB] = 0x30ED; + xkeysym_unicode_map[0x04DC] = 0x30EF; + xkeysym_unicode_map[0x04DD] = 0x30F3; + xkeysym_unicode_map[0x04DE] = 0x309B; + xkeysym_unicode_map[0x04DF] = 0x309C; + xkeysym_unicode_map[0x05AC] = 0x060C; + xkeysym_unicode_map[0x05BB] = 0x061B; + xkeysym_unicode_map[0x05BF] = 0x061F; + xkeysym_unicode_map[0x05C1] = 0x0621; + xkeysym_unicode_map[0x05C2] = 0x0622; + xkeysym_unicode_map[0x05C3] = 0x0623; + xkeysym_unicode_map[0x05C4] = 0x0624; + xkeysym_unicode_map[0x05C5] = 0x0625; + xkeysym_unicode_map[0x05C6] = 0x0626; + xkeysym_unicode_map[0x05C7] = 0x0627; + xkeysym_unicode_map[0x05C8] = 0x0628; + xkeysym_unicode_map[0x05C9] = 0x0629; + xkeysym_unicode_map[0x05CA] = 0x062A; + xkeysym_unicode_map[0x05CB] = 0x062B; + xkeysym_unicode_map[0x05CC] = 0x062C; + xkeysym_unicode_map[0x05CD] = 0x062D; + xkeysym_unicode_map[0x05CE] = 0x062E; + xkeysym_unicode_map[0x05CF] = 0x062F; + xkeysym_unicode_map[0x05D0] = 0x0630; + xkeysym_unicode_map[0x05D1] = 0x0631; + xkeysym_unicode_map[0x05D2] = 0x0632; + xkeysym_unicode_map[0x05D3] = 0x0633; + xkeysym_unicode_map[0x05D4] = 0x0634; + xkeysym_unicode_map[0x05D5] = 0x0635; + xkeysym_unicode_map[0x05D6] = 0x0636; + xkeysym_unicode_map[0x05D7] = 0x0637; + xkeysym_unicode_map[0x05D8] = 0x0638; + xkeysym_unicode_map[0x05D9] = 0x0639; + xkeysym_unicode_map[0x05DA] = 0x063A; + xkeysym_unicode_map[0x05E0] = 0x0640; + xkeysym_unicode_map[0x05E1] = 0x0641; + xkeysym_unicode_map[0x05E2] = 0x0642; + xkeysym_unicode_map[0x05E3] = 0x0643; + xkeysym_unicode_map[0x05E4] = 0x0644; + xkeysym_unicode_map[0x05E5] = 0x0645; + xkeysym_unicode_map[0x05E6] = 0x0646; + xkeysym_unicode_map[0x05E7] = 0x0647; + xkeysym_unicode_map[0x05E8] = 0x0648; + xkeysym_unicode_map[0x05E9] = 0x0649; + xkeysym_unicode_map[0x05EA] = 0x064A; + xkeysym_unicode_map[0x05EB] = 0x064B; + xkeysym_unicode_map[0x05EC] = 0x064C; + xkeysym_unicode_map[0x05ED] = 0x064D; + xkeysym_unicode_map[0x05EE] = 0x064E; + xkeysym_unicode_map[0x05EF] = 0x064F; + xkeysym_unicode_map[0x05F0] = 0x0650; + xkeysym_unicode_map[0x05F1] = 0x0651; + xkeysym_unicode_map[0x05F2] = 0x0652; + xkeysym_unicode_map[0x06A1] = 0x0452; + xkeysym_unicode_map[0x06A2] = 0x0453; + xkeysym_unicode_map[0x06A3] = 0x0451; + xkeysym_unicode_map[0x06A4] = 0x0454; + xkeysym_unicode_map[0x06A5] = 0x0455; + xkeysym_unicode_map[0x06A6] = 0x0456; + xkeysym_unicode_map[0x06A7] = 0x0457; + xkeysym_unicode_map[0x06A8] = 0x0458; + xkeysym_unicode_map[0x06A9] = 0x0459; + xkeysym_unicode_map[0x06AA] = 0x045A; + xkeysym_unicode_map[0x06AB] = 0x045B; + xkeysym_unicode_map[0x06AC] = 0x045C; + xkeysym_unicode_map[0x06AE] = 0x045E; + xkeysym_unicode_map[0x06AF] = 0x045F; + xkeysym_unicode_map[0x06B0] = 0x2116; + xkeysym_unicode_map[0x06B1] = 0x0402; + xkeysym_unicode_map[0x06B2] = 0x0403; + xkeysym_unicode_map[0x06B3] = 0x0401; + xkeysym_unicode_map[0x06B4] = 0x0404; + xkeysym_unicode_map[0x06B5] = 0x0405; + xkeysym_unicode_map[0x06B6] = 0x0406; + xkeysym_unicode_map[0x06B7] = 0x0407; + xkeysym_unicode_map[0x06B8] = 0x0408; + xkeysym_unicode_map[0x06B9] = 0x0409; + xkeysym_unicode_map[0x06BA] = 0x040A; + xkeysym_unicode_map[0x06BB] = 0x040B; + xkeysym_unicode_map[0x06BC] = 0x040C; + xkeysym_unicode_map[0x06BE] = 0x040E; + xkeysym_unicode_map[0x06BF] = 0x040F; + xkeysym_unicode_map[0x06C0] = 0x044E; + xkeysym_unicode_map[0x06C1] = 0x0430; + xkeysym_unicode_map[0x06C2] = 0x0431; + xkeysym_unicode_map[0x06C3] = 0x0446; + xkeysym_unicode_map[0x06C4] = 0x0434; + xkeysym_unicode_map[0x06C5] = 0x0435; + xkeysym_unicode_map[0x06C6] = 0x0444; + xkeysym_unicode_map[0x06C7] = 0x0433; + xkeysym_unicode_map[0x06C8] = 0x0445; + xkeysym_unicode_map[0x06C9] = 0x0438; + xkeysym_unicode_map[0x06CA] = 0x0439; + xkeysym_unicode_map[0x06CB] = 0x043A; + xkeysym_unicode_map[0x06CC] = 0x043B; + xkeysym_unicode_map[0x06CD] = 0x043C; + xkeysym_unicode_map[0x06CE] = 0x043D; + xkeysym_unicode_map[0x06CF] = 0x043E; + xkeysym_unicode_map[0x06D0] = 0x043F; + xkeysym_unicode_map[0x06D1] = 0x044F; + xkeysym_unicode_map[0x06D2] = 0x0440; + xkeysym_unicode_map[0x06D3] = 0x0441; + xkeysym_unicode_map[0x06D4] = 0x0442; + xkeysym_unicode_map[0x06D5] = 0x0443; + xkeysym_unicode_map[0x06D6] = 0x0436; + xkeysym_unicode_map[0x06D7] = 0x0432; + xkeysym_unicode_map[0x06D8] = 0x044C; + xkeysym_unicode_map[0x06D9] = 0x044B; + xkeysym_unicode_map[0x06DA] = 0x0437; + xkeysym_unicode_map[0x06DB] = 0x0448; + xkeysym_unicode_map[0x06DC] = 0x044D; + xkeysym_unicode_map[0x06DD] = 0x0449; + xkeysym_unicode_map[0x06DE] = 0x0447; + xkeysym_unicode_map[0x06DF] = 0x044A; + xkeysym_unicode_map[0x06E0] = 0x042E; + xkeysym_unicode_map[0x06E1] = 0x0410; + xkeysym_unicode_map[0x06E2] = 0x0411; + xkeysym_unicode_map[0x06E3] = 0x0426; + xkeysym_unicode_map[0x06E4] = 0x0414; + xkeysym_unicode_map[0x06E5] = 0x0415; + xkeysym_unicode_map[0x06E6] = 0x0424; + xkeysym_unicode_map[0x06E7] = 0x0413; + xkeysym_unicode_map[0x06E8] = 0x0425; + xkeysym_unicode_map[0x06E9] = 0x0418; + xkeysym_unicode_map[0x06EA] = 0x0419; + xkeysym_unicode_map[0x06EB] = 0x041A; + xkeysym_unicode_map[0x06EC] = 0x041B; + xkeysym_unicode_map[0x06ED] = 0x041C; + xkeysym_unicode_map[0x06EE] = 0x041D; + xkeysym_unicode_map[0x06EF] = 0x041E; + xkeysym_unicode_map[0x06F0] = 0x041F; + xkeysym_unicode_map[0x06F1] = 0x042F; + xkeysym_unicode_map[0x06F2] = 0x0420; + xkeysym_unicode_map[0x06F3] = 0x0421; + xkeysym_unicode_map[0x06F4] = 0x0422; + xkeysym_unicode_map[0x06F5] = 0x0423; + xkeysym_unicode_map[0x06F6] = 0x0416; + xkeysym_unicode_map[0x06F7] = 0x0412; + xkeysym_unicode_map[0x06F8] = 0x042C; + xkeysym_unicode_map[0x06F9] = 0x042B; + xkeysym_unicode_map[0x06FA] = 0x0417; + xkeysym_unicode_map[0x06FB] = 0x0428; + xkeysym_unicode_map[0x06FC] = 0x042D; + xkeysym_unicode_map[0x06FD] = 0x0429; + xkeysym_unicode_map[0x06FE] = 0x0427; + xkeysym_unicode_map[0x06FF] = 0x042A; + xkeysym_unicode_map[0x07A1] = 0x0386; + xkeysym_unicode_map[0x07A2] = 0x0388; + xkeysym_unicode_map[0x07A3] = 0x0389; + xkeysym_unicode_map[0x07A4] = 0x038A; + xkeysym_unicode_map[0x07A5] = 0x03AA; + xkeysym_unicode_map[0x07A7] = 0x038C; + xkeysym_unicode_map[0x07A8] = 0x038E; + xkeysym_unicode_map[0x07A9] = 0x03AB; + xkeysym_unicode_map[0x07AB] = 0x038F; + xkeysym_unicode_map[0x07AE] = 0x0385; + xkeysym_unicode_map[0x07AF] = 0x2015; + xkeysym_unicode_map[0x07B1] = 0x03AC; + xkeysym_unicode_map[0x07B2] = 0x03AD; + xkeysym_unicode_map[0x07B3] = 0x03AE; + xkeysym_unicode_map[0x07B4] = 0x03AF; + xkeysym_unicode_map[0x07B5] = 0x03CA; + xkeysym_unicode_map[0x07B6] = 0x0390; + xkeysym_unicode_map[0x07B7] = 0x03CC; + xkeysym_unicode_map[0x07B8] = 0x03CD; + xkeysym_unicode_map[0x07B9] = 0x03CB; + xkeysym_unicode_map[0x07BA] = 0x03B0; + xkeysym_unicode_map[0x07BB] = 0x03CE; + xkeysym_unicode_map[0x07C1] = 0x0391; + xkeysym_unicode_map[0x07C2] = 0x0392; + xkeysym_unicode_map[0x07C3] = 0x0393; + xkeysym_unicode_map[0x07C4] = 0x0394; + xkeysym_unicode_map[0x07C5] = 0x0395; + xkeysym_unicode_map[0x07C6] = 0x0396; + xkeysym_unicode_map[0x07C7] = 0x0397; + xkeysym_unicode_map[0x07C8] = 0x0398; + xkeysym_unicode_map[0x07C9] = 0x0399; + xkeysym_unicode_map[0x07CA] = 0x039A; + xkeysym_unicode_map[0x07CB] = 0x039B; + xkeysym_unicode_map[0x07CC] = 0x039C; + xkeysym_unicode_map[0x07CD] = 0x039D; + xkeysym_unicode_map[0x07CE] = 0x039E; + xkeysym_unicode_map[0x07CF] = 0x039F; + xkeysym_unicode_map[0x07D0] = 0x03A0; + xkeysym_unicode_map[0x07D1] = 0x03A1; + xkeysym_unicode_map[0x07D2] = 0x03A3; + xkeysym_unicode_map[0x07D4] = 0x03A4; + xkeysym_unicode_map[0x07D5] = 0x03A5; + xkeysym_unicode_map[0x07D6] = 0x03A6; + xkeysym_unicode_map[0x07D7] = 0x03A7; + xkeysym_unicode_map[0x07D8] = 0x03A8; + xkeysym_unicode_map[0x07D9] = 0x03A9; + xkeysym_unicode_map[0x07E1] = 0x03B1; + xkeysym_unicode_map[0x07E2] = 0x03B2; + xkeysym_unicode_map[0x07E3] = 0x03B3; + xkeysym_unicode_map[0x07E4] = 0x03B4; + xkeysym_unicode_map[0x07E5] = 0x03B5; + xkeysym_unicode_map[0x07E6] = 0x03B6; + xkeysym_unicode_map[0x07E7] = 0x03B7; + xkeysym_unicode_map[0x07E8] = 0x03B8; + xkeysym_unicode_map[0x07E9] = 0x03B9; + xkeysym_unicode_map[0x07EA] = 0x03BA; + xkeysym_unicode_map[0x07EB] = 0x03BB; + xkeysym_unicode_map[0x07EC] = 0x03BC; + xkeysym_unicode_map[0x07ED] = 0x03BD; + xkeysym_unicode_map[0x07EE] = 0x03BE; + xkeysym_unicode_map[0x07EF] = 0x03BF; + xkeysym_unicode_map[0x07F0] = 0x03C0; + xkeysym_unicode_map[0x07F1] = 0x03C1; + xkeysym_unicode_map[0x07F2] = 0x03C3; + xkeysym_unicode_map[0x07F3] = 0x03C2; + xkeysym_unicode_map[0x07F4] = 0x03C4; + xkeysym_unicode_map[0x07F5] = 0x03C5; + xkeysym_unicode_map[0x07F6] = 0x03C6; + xkeysym_unicode_map[0x07F7] = 0x03C7; + xkeysym_unicode_map[0x07F8] = 0x03C8; + xkeysym_unicode_map[0x07F9] = 0x03C9; + xkeysym_unicode_map[0x08A1] = 0x23B7; + xkeysym_unicode_map[0x08A2] = 0x250C; + xkeysym_unicode_map[0x08A3] = 0x2500; + xkeysym_unicode_map[0x08A4] = 0x2320; + xkeysym_unicode_map[0x08A5] = 0x2321; + xkeysym_unicode_map[0x08A6] = 0x2502; + xkeysym_unicode_map[0x08A7] = 0x23A1; + xkeysym_unicode_map[0x08A8] = 0x23A3; + xkeysym_unicode_map[0x08A9] = 0x23A4; + xkeysym_unicode_map[0x08AA] = 0x23A6; + xkeysym_unicode_map[0x08AB] = 0x239B; + xkeysym_unicode_map[0x08AC] = 0x239D; + xkeysym_unicode_map[0x08AD] = 0x239E; + xkeysym_unicode_map[0x08AE] = 0x23A0; + xkeysym_unicode_map[0x08AF] = 0x23A8; + xkeysym_unicode_map[0x08B0] = 0x23AC; + xkeysym_unicode_map[0x08BC] = 0x2264; + xkeysym_unicode_map[0x08BD] = 0x2260; + xkeysym_unicode_map[0x08BE] = 0x2265; + xkeysym_unicode_map[0x08BF] = 0x222B; + xkeysym_unicode_map[0x08C0] = 0x2234; + xkeysym_unicode_map[0x08C1] = 0x221D; + xkeysym_unicode_map[0x08C2] = 0x221E; + xkeysym_unicode_map[0x08C5] = 0x2207; + xkeysym_unicode_map[0x08C8] = 0x223C; + xkeysym_unicode_map[0x08C9] = 0x2243; + xkeysym_unicode_map[0x08CD] = 0x21D4; + xkeysym_unicode_map[0x08CE] = 0x21D2; + xkeysym_unicode_map[0x08CF] = 0x2261; + xkeysym_unicode_map[0x08D6] = 0x221A; + xkeysym_unicode_map[0x08DA] = 0x2282; + xkeysym_unicode_map[0x08DB] = 0x2283; + xkeysym_unicode_map[0x08DC] = 0x2229; + xkeysym_unicode_map[0x08DD] = 0x222A; + xkeysym_unicode_map[0x08DE] = 0x2227; + xkeysym_unicode_map[0x08DF] = 0x2228; + xkeysym_unicode_map[0x08EF] = 0x2202; + xkeysym_unicode_map[0x08F6] = 0x0192; + xkeysym_unicode_map[0x08FB] = 0x2190; + xkeysym_unicode_map[0x08FC] = 0x2191; + xkeysym_unicode_map[0x08FD] = 0x2192; + xkeysym_unicode_map[0x08FE] = 0x2193; + xkeysym_unicode_map[0x09E0] = 0x25C6; + xkeysym_unicode_map[0x09E1] = 0x2592; + xkeysym_unicode_map[0x09E2] = 0x2409; + xkeysym_unicode_map[0x09E3] = 0x240C; + xkeysym_unicode_map[0x09E4] = 0x240D; + xkeysym_unicode_map[0x09E5] = 0x240A; + xkeysym_unicode_map[0x09E8] = 0x2424; + xkeysym_unicode_map[0x09E9] = 0x240B; + xkeysym_unicode_map[0x09EA] = 0x2518; + xkeysym_unicode_map[0x09EB] = 0x2510; + xkeysym_unicode_map[0x09EC] = 0x250C; + xkeysym_unicode_map[0x09ED] = 0x2514; + xkeysym_unicode_map[0x09EE] = 0x253C; + xkeysym_unicode_map[0x09EF] = 0x23BA; + xkeysym_unicode_map[0x09F0] = 0x23BB; + xkeysym_unicode_map[0x09F1] = 0x2500; + xkeysym_unicode_map[0x09F2] = 0x23BC; + xkeysym_unicode_map[0x09F3] = 0x23BD; + xkeysym_unicode_map[0x09F4] = 0x251C; + xkeysym_unicode_map[0x09F5] = 0x2524; + xkeysym_unicode_map[0x09F6] = 0x2534; + xkeysym_unicode_map[0x09F7] = 0x252C; + xkeysym_unicode_map[0x09F8] = 0x2502; + xkeysym_unicode_map[0x0AA1] = 0x2003; + xkeysym_unicode_map[0x0AA2] = 0x2002; + xkeysym_unicode_map[0x0AA3] = 0x2004; + xkeysym_unicode_map[0x0AA4] = 0x2005; + xkeysym_unicode_map[0x0AA5] = 0x2007; + xkeysym_unicode_map[0x0AA6] = 0x2008; + xkeysym_unicode_map[0x0AA7] = 0x2009; + xkeysym_unicode_map[0x0AA8] = 0x200A; + xkeysym_unicode_map[0x0AA9] = 0x2014; + xkeysym_unicode_map[0x0AAA] = 0x2013; + xkeysym_unicode_map[0x0AAE] = 0x2026; + xkeysym_unicode_map[0x0AAF] = 0x2025; + xkeysym_unicode_map[0x0AB0] = 0x2153; + xkeysym_unicode_map[0x0AB1] = 0x2154; + xkeysym_unicode_map[0x0AB2] = 0x2155; + xkeysym_unicode_map[0x0AB3] = 0x2156; + xkeysym_unicode_map[0x0AB4] = 0x2157; + xkeysym_unicode_map[0x0AB5] = 0x2158; + xkeysym_unicode_map[0x0AB6] = 0x2159; + xkeysym_unicode_map[0x0AB7] = 0x215A; + xkeysym_unicode_map[0x0AB8] = 0x2105; + xkeysym_unicode_map[0x0ABB] = 0x2012; + xkeysym_unicode_map[0x0ABC] = 0x2329; + xkeysym_unicode_map[0x0ABE] = 0x232A; + xkeysym_unicode_map[0x0AC3] = 0x215B; + xkeysym_unicode_map[0x0AC4] = 0x215C; + xkeysym_unicode_map[0x0AC5] = 0x215D; + xkeysym_unicode_map[0x0AC6] = 0x215E; + xkeysym_unicode_map[0x0AC9] = 0x2122; + xkeysym_unicode_map[0x0ACA] = 0x2613; + xkeysym_unicode_map[0x0ACC] = 0x25C1; + xkeysym_unicode_map[0x0ACD] = 0x25B7; + xkeysym_unicode_map[0x0ACE] = 0x25CB; + xkeysym_unicode_map[0x0ACF] = 0x25AF; + xkeysym_unicode_map[0x0AD0] = 0x2018; + xkeysym_unicode_map[0x0AD1] = 0x2019; + xkeysym_unicode_map[0x0AD2] = 0x201C; + xkeysym_unicode_map[0x0AD3] = 0x201D; + xkeysym_unicode_map[0x0AD4] = 0x211E; + xkeysym_unicode_map[0x0AD6] = 0x2032; + xkeysym_unicode_map[0x0AD7] = 0x2033; + xkeysym_unicode_map[0x0AD9] = 0x271D; + xkeysym_unicode_map[0x0ADB] = 0x25AC; + xkeysym_unicode_map[0x0ADC] = 0x25C0; + xkeysym_unicode_map[0x0ADD] = 0x25B6; + xkeysym_unicode_map[0x0ADE] = 0x25CF; + xkeysym_unicode_map[0x0ADF] = 0x25AE; + xkeysym_unicode_map[0x0AE0] = 0x25E6; + xkeysym_unicode_map[0x0AE1] = 0x25AB; + xkeysym_unicode_map[0x0AE2] = 0x25AD; + xkeysym_unicode_map[0x0AE3] = 0x25B3; + xkeysym_unicode_map[0x0AE4] = 0x25BD; + xkeysym_unicode_map[0x0AE5] = 0x2606; + xkeysym_unicode_map[0x0AE6] = 0x2022; + xkeysym_unicode_map[0x0AE7] = 0x25AA; + xkeysym_unicode_map[0x0AE8] = 0x25B2; + xkeysym_unicode_map[0x0AE9] = 0x25BC; + xkeysym_unicode_map[0x0AEA] = 0x261C; + xkeysym_unicode_map[0x0AEB] = 0x261E; + xkeysym_unicode_map[0x0AEC] = 0x2663; + xkeysym_unicode_map[0x0AED] = 0x2666; + xkeysym_unicode_map[0x0AEE] = 0x2665; + xkeysym_unicode_map[0x0AF0] = 0x2720; + xkeysym_unicode_map[0x0AF1] = 0x2020; + xkeysym_unicode_map[0x0AF2] = 0x2021; + xkeysym_unicode_map[0x0AF3] = 0x2713; + xkeysym_unicode_map[0x0AF4] = 0x2717; + xkeysym_unicode_map[0x0AF5] = 0x266F; + xkeysym_unicode_map[0x0AF6] = 0x266D; + xkeysym_unicode_map[0x0AF7] = 0x2642; + xkeysym_unicode_map[0x0AF8] = 0x2640; + xkeysym_unicode_map[0x0AF9] = 0x260E; + xkeysym_unicode_map[0x0AFA] = 0x2315; + xkeysym_unicode_map[0x0AFB] = 0x2117; + xkeysym_unicode_map[0x0AFC] = 0x2038; + xkeysym_unicode_map[0x0AFD] = 0x201A; + xkeysym_unicode_map[0x0AFE] = 0x201E; + xkeysym_unicode_map[0x0BA3] = 0x003C; + xkeysym_unicode_map[0x0BA6] = 0x003E; + xkeysym_unicode_map[0x0BA8] = 0x2228; + xkeysym_unicode_map[0x0BA9] = 0x2227; + xkeysym_unicode_map[0x0BC0] = 0x00AF; + xkeysym_unicode_map[0x0BC2] = 0x22A5; + xkeysym_unicode_map[0x0BC3] = 0x2229; + xkeysym_unicode_map[0x0BC4] = 0x230A; + xkeysym_unicode_map[0x0BC6] = 0x005F; + xkeysym_unicode_map[0x0BCA] = 0x2218; + xkeysym_unicode_map[0x0BCC] = 0x2395; + xkeysym_unicode_map[0x0BCE] = 0x22A4; + xkeysym_unicode_map[0x0BCF] = 0x25CB; + xkeysym_unicode_map[0x0BD3] = 0x2308; + xkeysym_unicode_map[0x0BD6] = 0x222A; + xkeysym_unicode_map[0x0BD8] = 0x2283; + xkeysym_unicode_map[0x0BDA] = 0x2282; + xkeysym_unicode_map[0x0BDC] = 0x22A2; + xkeysym_unicode_map[0x0BFC] = 0x22A3; + xkeysym_unicode_map[0x0CDF] = 0x2017; + xkeysym_unicode_map[0x0CE0] = 0x05D0; + xkeysym_unicode_map[0x0CE1] = 0x05D1; + xkeysym_unicode_map[0x0CE2] = 0x05D2; + xkeysym_unicode_map[0x0CE3] = 0x05D3; + xkeysym_unicode_map[0x0CE4] = 0x05D4; + xkeysym_unicode_map[0x0CE5] = 0x05D5; + xkeysym_unicode_map[0x0CE6] = 0x05D6; + xkeysym_unicode_map[0x0CE7] = 0x05D7; + xkeysym_unicode_map[0x0CE8] = 0x05D8; + xkeysym_unicode_map[0x0CE9] = 0x05D9; + xkeysym_unicode_map[0x0CEA] = 0x05DA; + xkeysym_unicode_map[0x0CEB] = 0x05DB; + xkeysym_unicode_map[0x0CEC] = 0x05DC; + xkeysym_unicode_map[0x0CED] = 0x05DD; + xkeysym_unicode_map[0x0CEE] = 0x05DE; + xkeysym_unicode_map[0x0CEF] = 0x05DF; + xkeysym_unicode_map[0x0CF0] = 0x05E0; + xkeysym_unicode_map[0x0CF1] = 0x05E1; + xkeysym_unicode_map[0x0CF2] = 0x05E2; + xkeysym_unicode_map[0x0CF3] = 0x05E3; + xkeysym_unicode_map[0x0CF4] = 0x05E4; + xkeysym_unicode_map[0x0CF5] = 0x05E5; + xkeysym_unicode_map[0x0CF6] = 0x05E6; + xkeysym_unicode_map[0x0CF7] = 0x05E7; + xkeysym_unicode_map[0x0CF8] = 0x05E8; + xkeysym_unicode_map[0x0CF9] = 0x05E9; + xkeysym_unicode_map[0x0CFA] = 0x05EA; + xkeysym_unicode_map[0x0DA1] = 0x0E01; + xkeysym_unicode_map[0x0DA2] = 0x0E02; + xkeysym_unicode_map[0x0DA3] = 0x0E03; + xkeysym_unicode_map[0x0DA4] = 0x0E04; + xkeysym_unicode_map[0x0DA5] = 0x0E05; + xkeysym_unicode_map[0x0DA6] = 0x0E06; + xkeysym_unicode_map[0x0DA7] = 0x0E07; + xkeysym_unicode_map[0x0DA8] = 0x0E08; + xkeysym_unicode_map[0x0DA9] = 0x0E09; + xkeysym_unicode_map[0x0DAA] = 0x0E0A; + xkeysym_unicode_map[0x0DAB] = 0x0E0B; + xkeysym_unicode_map[0x0DAC] = 0x0E0C; + xkeysym_unicode_map[0x0DAD] = 0x0E0D; + xkeysym_unicode_map[0x0DAE] = 0x0E0E; + xkeysym_unicode_map[0x0DAF] = 0x0E0F; + xkeysym_unicode_map[0x0DB0] = 0x0E10; + xkeysym_unicode_map[0x0DB1] = 0x0E11; + xkeysym_unicode_map[0x0DB2] = 0x0E12; + xkeysym_unicode_map[0x0DB3] = 0x0E13; + xkeysym_unicode_map[0x0DB4] = 0x0E14; + xkeysym_unicode_map[0x0DB5] = 0x0E15; + xkeysym_unicode_map[0x0DB6] = 0x0E16; + xkeysym_unicode_map[0x0DB7] = 0x0E17; + xkeysym_unicode_map[0x0DB8] = 0x0E18; + xkeysym_unicode_map[0x0DB9] = 0x0E19; + xkeysym_unicode_map[0x0DBA] = 0x0E1A; + xkeysym_unicode_map[0x0DBB] = 0x0E1B; + xkeysym_unicode_map[0x0DBC] = 0x0E1C; + xkeysym_unicode_map[0x0DBD] = 0x0E1D; + xkeysym_unicode_map[0x0DBE] = 0x0E1E; + xkeysym_unicode_map[0x0DBF] = 0x0E1F; + xkeysym_unicode_map[0x0DC0] = 0x0E20; + xkeysym_unicode_map[0x0DC1] = 0x0E21; + xkeysym_unicode_map[0x0DC2] = 0x0E22; + xkeysym_unicode_map[0x0DC3] = 0x0E23; + xkeysym_unicode_map[0x0DC4] = 0x0E24; + xkeysym_unicode_map[0x0DC5] = 0x0E25; + xkeysym_unicode_map[0x0DC6] = 0x0E26; + xkeysym_unicode_map[0x0DC7] = 0x0E27; + xkeysym_unicode_map[0x0DC8] = 0x0E28; + xkeysym_unicode_map[0x0DC9] = 0x0E29; + xkeysym_unicode_map[0x0DCA] = 0x0E2A; + xkeysym_unicode_map[0x0DCB] = 0x0E2B; + xkeysym_unicode_map[0x0DCC] = 0x0E2C; + xkeysym_unicode_map[0x0DCD] = 0x0E2D; + xkeysym_unicode_map[0x0DCE] = 0x0E2E; + xkeysym_unicode_map[0x0DCF] = 0x0E2F; + xkeysym_unicode_map[0x0DD0] = 0x0E30; + xkeysym_unicode_map[0x0DD1] = 0x0E31; + xkeysym_unicode_map[0x0DD2] = 0x0E32; + xkeysym_unicode_map[0x0DD3] = 0x0E33; + xkeysym_unicode_map[0x0DD4] = 0x0E34; + xkeysym_unicode_map[0x0DD5] = 0x0E35; + xkeysym_unicode_map[0x0DD6] = 0x0E36; + xkeysym_unicode_map[0x0DD7] = 0x0E37; + xkeysym_unicode_map[0x0DD8] = 0x0E38; + xkeysym_unicode_map[0x0DD9] = 0x0E39; + xkeysym_unicode_map[0x0DDA] = 0x0E3A; + xkeysym_unicode_map[0x0DDF] = 0x0E3F; + xkeysym_unicode_map[0x0DE0] = 0x0E40; + xkeysym_unicode_map[0x0DE1] = 0x0E41; + xkeysym_unicode_map[0x0DE2] = 0x0E42; + xkeysym_unicode_map[0x0DE3] = 0x0E43; + xkeysym_unicode_map[0x0DE4] = 0x0E44; + xkeysym_unicode_map[0x0DE5] = 0x0E45; + xkeysym_unicode_map[0x0DE6] = 0x0E46; + xkeysym_unicode_map[0x0DE7] = 0x0E47; + xkeysym_unicode_map[0x0DE8] = 0x0E48; + xkeysym_unicode_map[0x0DE9] = 0x0E49; + xkeysym_unicode_map[0x0DEA] = 0x0E4A; + xkeysym_unicode_map[0x0DEB] = 0x0E4B; + xkeysym_unicode_map[0x0DEC] = 0x0E4C; + xkeysym_unicode_map[0x0DED] = 0x0E4D; + xkeysym_unicode_map[0x0DF0] = 0x0E50; + xkeysym_unicode_map[0x0DF1] = 0x0E51; + xkeysym_unicode_map[0x0DF2] = 0x0E52; + xkeysym_unicode_map[0x0DF3] = 0x0E53; + xkeysym_unicode_map[0x0DF4] = 0x0E54; + xkeysym_unicode_map[0x0DF5] = 0x0E55; + xkeysym_unicode_map[0x0DF6] = 0x0E56; + xkeysym_unicode_map[0x0DF7] = 0x0E57; + xkeysym_unicode_map[0x0DF8] = 0x0E58; + xkeysym_unicode_map[0x0DF9] = 0x0E59; + xkeysym_unicode_map[0x0EA1] = 0x3131; + xkeysym_unicode_map[0x0EA2] = 0x3132; + xkeysym_unicode_map[0x0EA3] = 0x3133; + xkeysym_unicode_map[0x0EA4] = 0x3134; + xkeysym_unicode_map[0x0EA5] = 0x3135; + xkeysym_unicode_map[0x0EA6] = 0x3136; + xkeysym_unicode_map[0x0EA7] = 0x3137; + xkeysym_unicode_map[0x0EA8] = 0x3138; + xkeysym_unicode_map[0x0EA9] = 0x3139; + xkeysym_unicode_map[0x0EAA] = 0x313A; + xkeysym_unicode_map[0x0EAB] = 0x313B; + xkeysym_unicode_map[0x0EAC] = 0x313C; + xkeysym_unicode_map[0x0EAD] = 0x313D; + xkeysym_unicode_map[0x0EAE] = 0x313E; + xkeysym_unicode_map[0x0EAF] = 0x313F; + xkeysym_unicode_map[0x0EB0] = 0x3140; + xkeysym_unicode_map[0x0EB1] = 0x3141; + xkeysym_unicode_map[0x0EB2] = 0x3142; + xkeysym_unicode_map[0x0EB3] = 0x3143; + xkeysym_unicode_map[0x0EB4] = 0x3144; + xkeysym_unicode_map[0x0EB5] = 0x3145; + xkeysym_unicode_map[0x0EB6] = 0x3146; + xkeysym_unicode_map[0x0EB7] = 0x3147; + xkeysym_unicode_map[0x0EB8] = 0x3148; + xkeysym_unicode_map[0x0EB9] = 0x3149; + xkeysym_unicode_map[0x0EBA] = 0x314A; + xkeysym_unicode_map[0x0EBB] = 0x314B; + xkeysym_unicode_map[0x0EBC] = 0x314C; + xkeysym_unicode_map[0x0EBD] = 0x314D; + xkeysym_unicode_map[0x0EBE] = 0x314E; + xkeysym_unicode_map[0x0EBF] = 0x314F; + xkeysym_unicode_map[0x0EC0] = 0x3150; + xkeysym_unicode_map[0x0EC1] = 0x3151; + xkeysym_unicode_map[0x0EC2] = 0x3152; + xkeysym_unicode_map[0x0EC3] = 0x3153; + xkeysym_unicode_map[0x0EC4] = 0x3154; + xkeysym_unicode_map[0x0EC5] = 0x3155; + xkeysym_unicode_map[0x0EC6] = 0x3156; + xkeysym_unicode_map[0x0EC7] = 0x3157; + xkeysym_unicode_map[0x0EC8] = 0x3158; + xkeysym_unicode_map[0x0EC9] = 0x3159; + xkeysym_unicode_map[0x0ECA] = 0x315A; + xkeysym_unicode_map[0x0ECB] = 0x315B; + xkeysym_unicode_map[0x0ECC] = 0x315C; + xkeysym_unicode_map[0x0ECD] = 0x315D; + xkeysym_unicode_map[0x0ECE] = 0x315E; + xkeysym_unicode_map[0x0ECF] = 0x315F; + xkeysym_unicode_map[0x0ED0] = 0x3160; + xkeysym_unicode_map[0x0ED1] = 0x3161; + xkeysym_unicode_map[0x0ED2] = 0x3162; + xkeysym_unicode_map[0x0ED3] = 0x3163; + xkeysym_unicode_map[0x0ED4] = 0x11A8; + xkeysym_unicode_map[0x0ED5] = 0x11A9; + xkeysym_unicode_map[0x0ED6] = 0x11AA; + xkeysym_unicode_map[0x0ED7] = 0x11AB; + xkeysym_unicode_map[0x0ED8] = 0x11AC; + xkeysym_unicode_map[0x0ED9] = 0x11AD; + xkeysym_unicode_map[0x0EDA] = 0x11AE; + xkeysym_unicode_map[0x0EDB] = 0x11AF; + xkeysym_unicode_map[0x0EDC] = 0x11B0; + xkeysym_unicode_map[0x0EDD] = 0x11B1; + xkeysym_unicode_map[0x0EDE] = 0x11B2; + xkeysym_unicode_map[0x0EDF] = 0x11B3; + xkeysym_unicode_map[0x0EE0] = 0x11B4; + xkeysym_unicode_map[0x0EE1] = 0x11B5; + xkeysym_unicode_map[0x0EE2] = 0x11B6; + xkeysym_unicode_map[0x0EE3] = 0x11B7; + xkeysym_unicode_map[0x0EE4] = 0x11B8; + xkeysym_unicode_map[0x0EE5] = 0x11B9; + xkeysym_unicode_map[0x0EE6] = 0x11BA; + xkeysym_unicode_map[0x0EE7] = 0x11BB; + xkeysym_unicode_map[0x0EE8] = 0x11BC; + xkeysym_unicode_map[0x0EE9] = 0x11BD; + xkeysym_unicode_map[0x0EEA] = 0x11BE; + xkeysym_unicode_map[0x0EEB] = 0x11BF; + xkeysym_unicode_map[0x0EEC] = 0x11C0; + xkeysym_unicode_map[0x0EED] = 0x11C1; + xkeysym_unicode_map[0x0EEE] = 0x11C2; + xkeysym_unicode_map[0x0EEF] = 0x316D; + xkeysym_unicode_map[0x0EF0] = 0x3171; + xkeysym_unicode_map[0x0EF1] = 0x3178; + xkeysym_unicode_map[0x0EF2] = 0x317F; + xkeysym_unicode_map[0x0EF3] = 0x3181; + xkeysym_unicode_map[0x0EF4] = 0x3184; + xkeysym_unicode_map[0x0EF5] = 0x3186; + xkeysym_unicode_map[0x0EF6] = 0x318D; + xkeysym_unicode_map[0x0EF7] = 0x318E; + xkeysym_unicode_map[0x0EF8] = 0x11EB; + xkeysym_unicode_map[0x0EF9] = 0x11F0; + xkeysym_unicode_map[0x0EFA] = 0x11F9; + xkeysym_unicode_map[0x0EFF] = 0x20A9; + xkeysym_unicode_map[0x13A4] = 0x20AC; + xkeysym_unicode_map[0x13BC] = 0x0152; + xkeysym_unicode_map[0x13BD] = 0x0153; + xkeysym_unicode_map[0x13BE] = 0x0178; + xkeysym_unicode_map[0x20AC] = 0x20AC; } -unsigned int KeyMappingX11::get_xlibcode(Key p_keysym) { - unsigned int code = 0; - for (int i = 0; _scancode_to_keycode[i].keysym != Key::UNKNOWN; i++) { - if (_scancode_to_keycode[i].keysym == p_keysym) { - code = _scancode_to_keycode[i].keycode; - break; +Key KeyMappingX11::get_keycode(KeySym p_keysym) { + if (p_keysym >= 0x20 && p_keysym < 0x7E) { // ASCII, maps 1-1 + if (p_keysym > 0x60 && p_keysym < 0x7B) { // Lowercase ASCII. + return (Key)(p_keysym - 32); + } else { + return (Key)p_keysym; } } - return code; -} - -Key KeyMappingX11::get_keycode(KeySym p_keysym) { - // kinda bruteforce.. could optimize. - - if (p_keysym < 0x100) { // Latin 1, maps 1-1 - return (Key)p_keysym; + const Key *key = xkeysym_map.getptr(p_keysym); + if (key) { + return *key; } + return Key::NONE; +} - // look for special key - for (int idx = 0; _xkeysym_to_keycode[idx].keysym != 0; idx++) { - if (_xkeysym_to_keycode[idx].keysym == p_keysym) { - return _xkeysym_to_keycode[idx].keycode; - } +Key KeyMappingX11::get_scancode(unsigned int p_code) { + const Key *key = scancode_map.getptr(p_code); + if (key) { + return *key; } return Key::NONE; } -KeySym KeyMappingX11::get_keysym(Key p_code) { - // kinda bruteforce.. could optimize. - - if (p_code < Key::END_LATIN1) { // Latin 1, maps 1-1 - return (KeySym)p_code; - } - - // look for special key - for (int idx = 0; _xkeysym_to_keycode[idx].keysym != 0; idx++) { - if (_xkeysym_to_keycode[idx].keycode == p_code) { - return _xkeysym_to_keycode[idx].keysym; - } +unsigned int KeyMappingX11::get_xlibcode(Key p_keysym) { + const unsigned int *key = scancode_map_inv.getptr(p_keysym); + if (key) { + return *key; } - - return (KeySym)Key::NONE; + return 0x00; } -/***** UNICODE CONVERSION ******/ - -// Tables taken from FOX toolkit - -struct _XTranslateUnicodePair { - KeySym keysym; - unsigned int unicode; -}; - -enum { - _KEYSYM_MAX = 759 -}; - -static _XTranslateUnicodePair _xkeysym_to_unicode[_KEYSYM_MAX] = { - { 0x01A1, 0x0104 }, - { 0x01A2, 0x02D8 }, - { 0x01A3, 0x0141 }, - { 0x01A5, 0x013D }, - { 0x01A6, 0x015A }, - { 0x01A9, 0x0160 }, - { 0x01AA, 0x015E }, - { 0x01AB, 0x0164 }, - { 0x01AC, 0x0179 }, - { 0x01AE, 0x017D }, - { 0x01AF, 0x017B }, - { 0x01B1, 0x0105 }, - { 0x01B2, 0x02DB }, - { 0x01B3, 0x0142 }, - { 0x01B5, 0x013E }, - { 0x01B6, 0x015B }, - { 0x01B7, 0x02C7 }, - { 0x01B9, 0x0161 }, - { 0x01BA, 0x015F }, - { 0x01BB, 0x0165 }, - { 0x01BC, 0x017A }, - { 0x01BD, 0x02DD }, - { 0x01BE, 0x017E }, - { 0x01BF, 0x017C }, - { 0x01C0, 0x0154 }, - { 0x01C3, 0x0102 }, - { 0x01C5, 0x0139 }, - { 0x01C6, 0x0106 }, - { 0x01C8, 0x010C }, - { 0x01CA, 0x0118 }, - { 0x01CC, 0x011A }, - { 0x01CF, 0x010E }, - { 0x01D0, 0x0110 }, - { 0x01D1, 0x0143 }, - { 0x01D2, 0x0147 }, - { 0x01D5, 0x0150 }, - { 0x01D8, 0x0158 }, - { 0x01D9, 0x016E }, - { 0x01DB, 0x0170 }, - { 0x01DE, 0x0162 }, - { 0x01E0, 0x0155 }, - { 0x01E3, 0x0103 }, - { 0x01E5, 0x013A }, - { 0x01E6, 0x0107 }, - { 0x01E8, 0x010D }, - { 0x01EA, 0x0119 }, - { 0x01EC, 0x011B }, - { 0x01EF, 0x010F }, - { 0x01F0, 0x0111 }, - { 0x01F1, 0x0144 }, - { 0x01F2, 0x0148 }, - { 0x01F5, 0x0151 }, - { 0x01F8, 0x0159 }, - { 0x01F9, 0x016F }, - { 0x01FB, 0x0171 }, - { 0x01FE, 0x0163 }, - { 0x01FF, 0x02D9 }, - { 0x02A1, 0x0126 }, - { 0x02A6, 0x0124 }, - { 0x02A9, 0x0130 }, - { 0x02AB, 0x011E }, - { 0x02AC, 0x0134 }, - { 0x02B1, 0x0127 }, - { 0x02B6, 0x0125 }, - { 0x02B9, 0x0131 }, - { 0x02BB, 0x011F }, - { 0x02BC, 0x0135 }, - { 0x02C5, 0x010A }, - { 0x02C6, 0x0108 }, - { 0x02D5, 0x0120 }, - { 0x02D8, 0x011C }, - { 0x02DD, 0x016C }, - { 0x02DE, 0x015C }, - { 0x02E5, 0x010B }, - { 0x02E6, 0x0109 }, - { 0x02F5, 0x0121 }, - { 0x02F8, 0x011D }, - { 0x02FD, 0x016D }, - { 0x02FE, 0x015D }, - { 0x03A2, 0x0138 }, - { 0x03A3, 0x0156 }, - { 0x03A5, 0x0128 }, - { 0x03A6, 0x013B }, - { 0x03AA, 0x0112 }, - { 0x03AB, 0x0122 }, - { 0x03AC, 0x0166 }, - { 0x03B3, 0x0157 }, - { 0x03B5, 0x0129 }, - { 0x03B6, 0x013C }, - { 0x03BA, 0x0113 }, - { 0x03BB, 0x0123 }, - { 0x03BC, 0x0167 }, - { 0x03BD, 0x014A }, - { 0x03BF, 0x014B }, - { 0x03C0, 0x0100 }, - { 0x03C7, 0x012E }, - { 0x03CC, 0x0116 }, - { 0x03CF, 0x012A }, - { 0x03D1, 0x0145 }, - { 0x03D2, 0x014C }, - { 0x03D3, 0x0136 }, - { 0x03D9, 0x0172 }, - { 0x03DD, 0x0168 }, - { 0x03DE, 0x016A }, - { 0x03E0, 0x0101 }, - { 0x03E7, 0x012F }, - { 0x03EC, 0x0117 }, - { 0x03EF, 0x012B }, - { 0x03F1, 0x0146 }, - { 0x03F2, 0x014D }, - { 0x03F3, 0x0137 }, - { 0x03F9, 0x0173 }, - { 0x03FD, 0x0169 }, - { 0x03FE, 0x016B }, - { 0x047E, 0x203E }, - { 0x04A1, 0x3002 }, - { 0x04A2, 0x300C }, - { 0x04A3, 0x300D }, - { 0x04A4, 0x3001 }, - { 0x04A5, 0x30FB }, - { 0x04A6, 0x30F2 }, - { 0x04A7, 0x30A1 }, - { 0x04A8, 0x30A3 }, - { 0x04A9, 0x30A5 }, - { 0x04AA, 0x30A7 }, - { 0x04AB, 0x30A9 }, - { 0x04AC, 0x30E3 }, - { 0x04AD, 0x30E5 }, - { 0x04AE, 0x30E7 }, - { 0x04AF, 0x30C3 }, - { 0x04B0, 0x30FC }, - { 0x04B1, 0x30A2 }, - { 0x04B2, 0x30A4 }, - { 0x04B3, 0x30A6 }, - { 0x04B4, 0x30A8 }, - { 0x04B5, 0x30AA }, - { 0x04B6, 0x30AB }, - { 0x04B7, 0x30AD }, - { 0x04B8, 0x30AF }, - { 0x04B9, 0x30B1 }, - { 0x04BA, 0x30B3 }, - { 0x04BB, 0x30B5 }, - { 0x04BC, 0x30B7 }, - { 0x04BD, 0x30B9 }, - { 0x04BE, 0x30BB }, - { 0x04BF, 0x30BD }, - { 0x04C0, 0x30BF }, - { 0x04C1, 0x30C1 }, - { 0x04C2, 0x30C4 }, - { 0x04C3, 0x30C6 }, - { 0x04C4, 0x30C8 }, - { 0x04C5, 0x30CA }, - { 0x04C6, 0x30CB }, - { 0x04C7, 0x30CC }, - { 0x04C8, 0x30CD }, - { 0x04C9, 0x30CE }, - { 0x04CA, 0x30CF }, - { 0x04CB, 0x30D2 }, - { 0x04CC, 0x30D5 }, - { 0x04CD, 0x30D8 }, - { 0x04CE, 0x30DB }, - { 0x04CF, 0x30DE }, - { 0x04D0, 0x30DF }, - { 0x04D1, 0x30E0 }, - { 0x04D2, 0x30E1 }, - { 0x04D3, 0x30E2 }, - { 0x04D4, 0x30E4 }, - { 0x04D5, 0x30E6 }, - { 0x04D6, 0x30E8 }, - { 0x04D7, 0x30E9 }, - { 0x04D8, 0x30EA }, - { 0x04D9, 0x30EB }, - { 0x04DA, 0x30EC }, - { 0x04DB, 0x30ED }, - { 0x04DC, 0x30EF }, - { 0x04DD, 0x30F3 }, - { 0x04DE, 0x309B }, - { 0x04DF, 0x309C }, - { 0x05AC, 0x060C }, - { 0x05BB, 0x061B }, - { 0x05BF, 0x061F }, - { 0x05C1, 0x0621 }, - { 0x05C2, 0x0622 }, - { 0x05C3, 0x0623 }, - { 0x05C4, 0x0624 }, - { 0x05C5, 0x0625 }, - { 0x05C6, 0x0626 }, - { 0x05C7, 0x0627 }, - { 0x05C8, 0x0628 }, - { 0x05C9, 0x0629 }, - { 0x05CA, 0x062A }, - { 0x05CB, 0x062B }, - { 0x05CC, 0x062C }, - { 0x05CD, 0x062D }, - { 0x05CE, 0x062E }, - { 0x05CF, 0x062F }, - { 0x05D0, 0x0630 }, - { 0x05D1, 0x0631 }, - { 0x05D2, 0x0632 }, - { 0x05D3, 0x0633 }, - { 0x05D4, 0x0634 }, - { 0x05D5, 0x0635 }, - { 0x05D6, 0x0636 }, - { 0x05D7, 0x0637 }, - { 0x05D8, 0x0638 }, - { 0x05D9, 0x0639 }, - { 0x05DA, 0x063A }, - { 0x05E0, 0x0640 }, - { 0x05E1, 0x0641 }, - { 0x05E2, 0x0642 }, - { 0x05E3, 0x0643 }, - { 0x05E4, 0x0644 }, - { 0x05E5, 0x0645 }, - { 0x05E6, 0x0646 }, - { 0x05E7, 0x0647 }, - { 0x05E8, 0x0648 }, - { 0x05E9, 0x0649 }, - { 0x05EA, 0x064A }, - { 0x05EB, 0x064B }, - { 0x05EC, 0x064C }, - { 0x05ED, 0x064D }, - { 0x05EE, 0x064E }, - { 0x05EF, 0x064F }, - { 0x05F0, 0x0650 }, - { 0x05F1, 0x0651 }, - { 0x05F2, 0x0652 }, - { 0x06A1, 0x0452 }, - { 0x06A2, 0x0453 }, - { 0x06A3, 0x0451 }, - { 0x06A4, 0x0454 }, - { 0x06A5, 0x0455 }, - { 0x06A6, 0x0456 }, - { 0x06A7, 0x0457 }, - { 0x06A8, 0x0458 }, - { 0x06A9, 0x0459 }, - { 0x06AA, 0x045A }, - { 0x06AB, 0x045B }, - { 0x06AC, 0x045C }, - { 0x06AE, 0x045E }, - { 0x06AF, 0x045F }, - { 0x06B0, 0x2116 }, - { 0x06B1, 0x0402 }, - { 0x06B2, 0x0403 }, - { 0x06B3, 0x0401 }, - { 0x06B4, 0x0404 }, - { 0x06B5, 0x0405 }, - { 0x06B6, 0x0406 }, - { 0x06B7, 0x0407 }, - { 0x06B8, 0x0408 }, - { 0x06B9, 0x0409 }, - { 0x06BA, 0x040A }, - { 0x06BB, 0x040B }, - { 0x06BC, 0x040C }, - { 0x06BE, 0x040E }, - { 0x06BF, 0x040F }, - { 0x06C0, 0x044E }, - { 0x06C1, 0x0430 }, - { 0x06C2, 0x0431 }, - { 0x06C3, 0x0446 }, - { 0x06C4, 0x0434 }, - { 0x06C5, 0x0435 }, - { 0x06C6, 0x0444 }, - { 0x06C7, 0x0433 }, - { 0x06C8, 0x0445 }, - { 0x06C9, 0x0438 }, - { 0x06CA, 0x0439 }, - { 0x06CB, 0x043A }, - { 0x06CC, 0x043B }, - { 0x06CD, 0x043C }, - { 0x06CE, 0x043D }, - { 0x06CF, 0x043E }, - { 0x06D0, 0x043F }, - { 0x06D1, 0x044F }, - { 0x06D2, 0x0440 }, - { 0x06D3, 0x0441 }, - { 0x06D4, 0x0442 }, - { 0x06D5, 0x0443 }, - { 0x06D6, 0x0436 }, - { 0x06D7, 0x0432 }, - { 0x06D8, 0x044C }, - { 0x06D9, 0x044B }, - { 0x06DA, 0x0437 }, - { 0x06DB, 0x0448 }, - { 0x06DC, 0x044D }, - { 0x06DD, 0x0449 }, - { 0x06DE, 0x0447 }, - { 0x06DF, 0x044A }, - { 0x06E0, 0x042E }, - { 0x06E1, 0x0410 }, - { 0x06E2, 0x0411 }, - { 0x06E3, 0x0426 }, - { 0x06E4, 0x0414 }, - { 0x06E5, 0x0415 }, - { 0x06E6, 0x0424 }, - { 0x06E7, 0x0413 }, - { 0x06E8, 0x0425 }, - { 0x06E9, 0x0418 }, - { 0x06EA, 0x0419 }, - { 0x06EB, 0x041A }, - { 0x06EC, 0x041B }, - { 0x06ED, 0x041C }, - { 0x06EE, 0x041D }, - { 0x06EF, 0x041E }, - { 0x06F0, 0x041F }, - { 0x06F1, 0x042F }, - { 0x06F2, 0x0420 }, - { 0x06F3, 0x0421 }, - { 0x06F4, 0x0422 }, - { 0x06F5, 0x0423 }, - { 0x06F6, 0x0416 }, - { 0x06F7, 0x0412 }, - { 0x06F8, 0x042C }, - { 0x06F9, 0x042B }, - { 0x06FA, 0x0417 }, - { 0x06FB, 0x0428 }, - { 0x06FC, 0x042D }, - { 0x06FD, 0x0429 }, - { 0x06FE, 0x0427 }, - { 0x06FF, 0x042A }, - { 0x07A1, 0x0386 }, - { 0x07A2, 0x0388 }, - { 0x07A3, 0x0389 }, - { 0x07A4, 0x038A }, - { 0x07A5, 0x03AA }, - { 0x07A7, 0x038C }, - { 0x07A8, 0x038E }, - { 0x07A9, 0x03AB }, - { 0x07AB, 0x038F }, - { 0x07AE, 0x0385 }, - { 0x07AF, 0x2015 }, - { 0x07B1, 0x03AC }, - { 0x07B2, 0x03AD }, - { 0x07B3, 0x03AE }, - { 0x07B4, 0x03AF }, - { 0x07B5, 0x03CA }, - { 0x07B6, 0x0390 }, - { 0x07B7, 0x03CC }, - { 0x07B8, 0x03CD }, - { 0x07B9, 0x03CB }, - { 0x07BA, 0x03B0 }, - { 0x07BB, 0x03CE }, - { 0x07C1, 0x0391 }, - { 0x07C2, 0x0392 }, - { 0x07C3, 0x0393 }, - { 0x07C4, 0x0394 }, - { 0x07C5, 0x0395 }, - { 0x07C6, 0x0396 }, - { 0x07C7, 0x0397 }, - { 0x07C8, 0x0398 }, - { 0x07C9, 0x0399 }, - { 0x07CA, 0x039A }, - { 0x07CB, 0x039B }, - { 0x07CC, 0x039C }, - { 0x07CD, 0x039D }, - { 0x07CE, 0x039E }, - { 0x07CF, 0x039F }, - { 0x07D0, 0x03A0 }, - { 0x07D1, 0x03A1 }, - { 0x07D2, 0x03A3 }, - { 0x07D4, 0x03A4 }, - { 0x07D5, 0x03A5 }, - { 0x07D6, 0x03A6 }, - { 0x07D7, 0x03A7 }, - { 0x07D8, 0x03A8 }, - { 0x07D9, 0x03A9 }, - { 0x07E1, 0x03B1 }, - { 0x07E2, 0x03B2 }, - { 0x07E3, 0x03B3 }, - { 0x07E4, 0x03B4 }, - { 0x07E5, 0x03B5 }, - { 0x07E6, 0x03B6 }, - { 0x07E7, 0x03B7 }, - { 0x07E8, 0x03B8 }, - { 0x07E9, 0x03B9 }, - { 0x07EA, 0x03BA }, - { 0x07EB, 0x03BB }, - { 0x07EC, 0x03BC }, - { 0x07ED, 0x03BD }, - { 0x07EE, 0x03BE }, - { 0x07EF, 0x03BF }, - { 0x07F0, 0x03C0 }, - { 0x07F1, 0x03C1 }, - { 0x07F2, 0x03C3 }, - { 0x07F3, 0x03C2 }, - { 0x07F4, 0x03C4 }, - { 0x07F5, 0x03C5 }, - { 0x07F6, 0x03C6 }, - { 0x07F7, 0x03C7 }, - { 0x07F8, 0x03C8 }, - { 0x07F9, 0x03C9 }, - { 0x08A1, 0x23B7 }, - { 0x08A2, 0x250C }, - { 0x08A3, 0x2500 }, - { 0x08A4, 0x2320 }, - { 0x08A5, 0x2321 }, - { 0x08A6, 0x2502 }, - { 0x08A7, 0x23A1 }, - { 0x08A8, 0x23A3 }, - { 0x08A9, 0x23A4 }, - { 0x08AA, 0x23A6 }, - { 0x08AB, 0x239B }, - { 0x08AC, 0x239D }, - { 0x08AD, 0x239E }, - { 0x08AE, 0x23A0 }, - { 0x08AF, 0x23A8 }, - { 0x08B0, 0x23AC }, - { 0x08BC, 0x2264 }, - { 0x08BD, 0x2260 }, - { 0x08BE, 0x2265 }, - { 0x08BF, 0x222B }, - { 0x08C0, 0x2234 }, - { 0x08C1, 0x221D }, - { 0x08C2, 0x221E }, - { 0x08C5, 0x2207 }, - { 0x08C8, 0x223C }, - { 0x08C9, 0x2243 }, - { 0x08CD, 0x21D4 }, - { 0x08CE, 0x21D2 }, - { 0x08CF, 0x2261 }, - { 0x08D6, 0x221A }, - { 0x08DA, 0x2282 }, - { 0x08DB, 0x2283 }, - { 0x08DC, 0x2229 }, - { 0x08DD, 0x222A }, - { 0x08DE, 0x2227 }, - { 0x08DF, 0x2228 }, - { 0x08EF, 0x2202 }, - { 0x08F6, 0x0192 }, - { 0x08FB, 0x2190 }, - { 0x08FC, 0x2191 }, - { 0x08FD, 0x2192 }, - { 0x08FE, 0x2193 }, - { 0x09E0, 0x25C6 }, - { 0x09E1, 0x2592 }, - { 0x09E2, 0x2409 }, - { 0x09E3, 0x240C }, - { 0x09E4, 0x240D }, - { 0x09E5, 0x240A }, - { 0x09E8, 0x2424 }, - { 0x09E9, 0x240B }, - { 0x09EA, 0x2518 }, - { 0x09EB, 0x2510 }, - { 0x09EC, 0x250C }, - { 0x09ED, 0x2514 }, - { 0x09EE, 0x253C }, - { 0x09EF, 0x23BA }, - { 0x09F0, 0x23BB }, - { 0x09F1, 0x2500 }, - { 0x09F2, 0x23BC }, - { 0x09F3, 0x23BD }, - { 0x09F4, 0x251C }, - { 0x09F5, 0x2524 }, - { 0x09F6, 0x2534 }, - { 0x09F7, 0x252C }, - { 0x09F8, 0x2502 }, - { 0x0AA1, 0x2003 }, - { 0x0AA2, 0x2002 }, - { 0x0AA3, 0x2004 }, - { 0x0AA4, 0x2005 }, - { 0x0AA5, 0x2007 }, - { 0x0AA6, 0x2008 }, - { 0x0AA7, 0x2009 }, - { 0x0AA8, 0x200A }, - { 0x0AA9, 0x2014 }, - { 0x0AAA, 0x2013 }, - { 0x0AAE, 0x2026 }, - { 0x0AAF, 0x2025 }, - { 0x0AB0, 0x2153 }, - { 0x0AB1, 0x2154 }, - { 0x0AB2, 0x2155 }, - { 0x0AB3, 0x2156 }, - { 0x0AB4, 0x2157 }, - { 0x0AB5, 0x2158 }, - { 0x0AB6, 0x2159 }, - { 0x0AB7, 0x215A }, - { 0x0AB8, 0x2105 }, - { 0x0ABB, 0x2012 }, - { 0x0ABC, 0x2329 }, - { 0x0ABE, 0x232A }, - { 0x0AC3, 0x215B }, - { 0x0AC4, 0x215C }, - { 0x0AC5, 0x215D }, - { 0x0AC6, 0x215E }, - { 0x0AC9, 0x2122 }, - { 0x0ACA, 0x2613 }, - { 0x0ACC, 0x25C1 }, - { 0x0ACD, 0x25B7 }, - { 0x0ACE, 0x25CB }, - { 0x0ACF, 0x25AF }, - { 0x0AD0, 0x2018 }, - { 0x0AD1, 0x2019 }, - { 0x0AD2, 0x201C }, - { 0x0AD3, 0x201D }, - { 0x0AD4, 0x211E }, - { 0x0AD6, 0x2032 }, - { 0x0AD7, 0x2033 }, - { 0x0AD9, 0x271D }, - { 0x0ADB, 0x25AC }, - { 0x0ADC, 0x25C0 }, - { 0x0ADD, 0x25B6 }, - { 0x0ADE, 0x25CF }, - { 0x0ADF, 0x25AE }, - { 0x0AE0, 0x25E6 }, - { 0x0AE1, 0x25AB }, - { 0x0AE2, 0x25AD }, - { 0x0AE3, 0x25B3 }, - { 0x0AE4, 0x25BD }, - { 0x0AE5, 0x2606 }, - { 0x0AE6, 0x2022 }, - { 0x0AE7, 0x25AA }, - { 0x0AE8, 0x25B2 }, - { 0x0AE9, 0x25BC }, - { 0x0AEA, 0x261C }, - { 0x0AEB, 0x261E }, - { 0x0AEC, 0x2663 }, - { 0x0AED, 0x2666 }, - { 0x0AEE, 0x2665 }, - { 0x0AF0, 0x2720 }, - { 0x0AF1, 0x2020 }, - { 0x0AF2, 0x2021 }, - { 0x0AF3, 0x2713 }, - { 0x0AF4, 0x2717 }, - { 0x0AF5, 0x266F }, - { 0x0AF6, 0x266D }, - { 0x0AF7, 0x2642 }, - { 0x0AF8, 0x2640 }, - { 0x0AF9, 0x260E }, - { 0x0AFA, 0x2315 }, - { 0x0AFB, 0x2117 }, - { 0x0AFC, 0x2038 }, - { 0x0AFD, 0x201A }, - { 0x0AFE, 0x201E }, - { 0x0BA3, 0x003C }, - { 0x0BA6, 0x003E }, - { 0x0BA8, 0x2228 }, - { 0x0BA9, 0x2227 }, - { 0x0BC0, 0x00AF }, - { 0x0BC2, 0x22A5 }, - { 0x0BC3, 0x2229 }, - { 0x0BC4, 0x230A }, - { 0x0BC6, 0x005F }, - { 0x0BCA, 0x2218 }, - { 0x0BCC, 0x2395 }, - { 0x0BCE, 0x22A4 }, - { 0x0BCF, 0x25CB }, - { 0x0BD3, 0x2308 }, - { 0x0BD6, 0x222A }, - { 0x0BD8, 0x2283 }, - { 0x0BDA, 0x2282 }, - { 0x0BDC, 0x22A2 }, - { 0x0BFC, 0x22A3 }, - { 0x0CDF, 0x2017 }, - { 0x0CE0, 0x05D0 }, - { 0x0CE1, 0x05D1 }, - { 0x0CE2, 0x05D2 }, - { 0x0CE3, 0x05D3 }, - { 0x0CE4, 0x05D4 }, - { 0x0CE5, 0x05D5 }, - { 0x0CE6, 0x05D6 }, - { 0x0CE7, 0x05D7 }, - { 0x0CE8, 0x05D8 }, - { 0x0CE9, 0x05D9 }, - { 0x0CEA, 0x05DA }, - { 0x0CEB, 0x05DB }, - { 0x0CEC, 0x05DC }, - { 0x0CED, 0x05DD }, - { 0x0CEE, 0x05DE }, - { 0x0CEF, 0x05DF }, - { 0x0CF0, 0x05E0 }, - { 0x0CF1, 0x05E1 }, - { 0x0CF2, 0x05E2 }, - { 0x0CF3, 0x05E3 }, - { 0x0CF4, 0x05E4 }, - { 0x0CF5, 0x05E5 }, - { 0x0CF6, 0x05E6 }, - { 0x0CF7, 0x05E7 }, - { 0x0CF8, 0x05E8 }, - { 0x0CF9, 0x05E9 }, - { 0x0CFA, 0x05EA }, - { 0x0DA1, 0x0E01 }, - { 0x0DA2, 0x0E02 }, - { 0x0DA3, 0x0E03 }, - { 0x0DA4, 0x0E04 }, - { 0x0DA5, 0x0E05 }, - { 0x0DA6, 0x0E06 }, - { 0x0DA7, 0x0E07 }, - { 0x0DA8, 0x0E08 }, - { 0x0DA9, 0x0E09 }, - { 0x0DAA, 0x0E0A }, - { 0x0DAB, 0x0E0B }, - { 0x0DAC, 0x0E0C }, - { 0x0DAD, 0x0E0D }, - { 0x0DAE, 0x0E0E }, - { 0x0DAF, 0x0E0F }, - { 0x0DB0, 0x0E10 }, - { 0x0DB1, 0x0E11 }, - { 0x0DB2, 0x0E12 }, - { 0x0DB3, 0x0E13 }, - { 0x0DB4, 0x0E14 }, - { 0x0DB5, 0x0E15 }, - { 0x0DB6, 0x0E16 }, - { 0x0DB7, 0x0E17 }, - { 0x0DB8, 0x0E18 }, - { 0x0DB9, 0x0E19 }, - { 0x0DBA, 0x0E1A }, - { 0x0DBB, 0x0E1B }, - { 0x0DBC, 0x0E1C }, - { 0x0DBD, 0x0E1D }, - { 0x0DBE, 0x0E1E }, - { 0x0DBF, 0x0E1F }, - { 0x0DC0, 0x0E20 }, - { 0x0DC1, 0x0E21 }, - { 0x0DC2, 0x0E22 }, - { 0x0DC3, 0x0E23 }, - { 0x0DC4, 0x0E24 }, - { 0x0DC5, 0x0E25 }, - { 0x0DC6, 0x0E26 }, - { 0x0DC7, 0x0E27 }, - { 0x0DC8, 0x0E28 }, - { 0x0DC9, 0x0E29 }, - { 0x0DCA, 0x0E2A }, - { 0x0DCB, 0x0E2B }, - { 0x0DCC, 0x0E2C }, - { 0x0DCD, 0x0E2D }, - { 0x0DCE, 0x0E2E }, - { 0x0DCF, 0x0E2F }, - { 0x0DD0, 0x0E30 }, - { 0x0DD1, 0x0E31 }, - { 0x0DD2, 0x0E32 }, - { 0x0DD3, 0x0E33 }, - { 0x0DD4, 0x0E34 }, - { 0x0DD5, 0x0E35 }, - { 0x0DD6, 0x0E36 }, - { 0x0DD7, 0x0E37 }, - { 0x0DD8, 0x0E38 }, - { 0x0DD9, 0x0E39 }, - { 0x0DDA, 0x0E3A }, - { 0x0DDF, 0x0E3F }, - { 0x0DE0, 0x0E40 }, - { 0x0DE1, 0x0E41 }, - { 0x0DE2, 0x0E42 }, - { 0x0DE3, 0x0E43 }, - { 0x0DE4, 0x0E44 }, - { 0x0DE5, 0x0E45 }, - { 0x0DE6, 0x0E46 }, - { 0x0DE7, 0x0E47 }, - { 0x0DE8, 0x0E48 }, - { 0x0DE9, 0x0E49 }, - { 0x0DEA, 0x0E4A }, - { 0x0DEB, 0x0E4B }, - { 0x0DEC, 0x0E4C }, - { 0x0DED, 0x0E4D }, - { 0x0DF0, 0x0E50 }, - { 0x0DF1, 0x0E51 }, - { 0x0DF2, 0x0E52 }, - { 0x0DF3, 0x0E53 }, - { 0x0DF4, 0x0E54 }, - { 0x0DF5, 0x0E55 }, - { 0x0DF6, 0x0E56 }, - { 0x0DF7, 0x0E57 }, - { 0x0DF8, 0x0E58 }, - { 0x0DF9, 0x0E59 }, - { 0x0EA1, 0x3131 }, - { 0x0EA2, 0x3132 }, - { 0x0EA3, 0x3133 }, - { 0x0EA4, 0x3134 }, - { 0x0EA5, 0x3135 }, - { 0x0EA6, 0x3136 }, - { 0x0EA7, 0x3137 }, - { 0x0EA8, 0x3138 }, - { 0x0EA9, 0x3139 }, - { 0x0EAA, 0x313A }, - { 0x0EAB, 0x313B }, - { 0x0EAC, 0x313C }, - { 0x0EAD, 0x313D }, - { 0x0EAE, 0x313E }, - { 0x0EAF, 0x313F }, - { 0x0EB0, 0x3140 }, - { 0x0EB1, 0x3141 }, - { 0x0EB2, 0x3142 }, - { 0x0EB3, 0x3143 }, - { 0x0EB4, 0x3144 }, - { 0x0EB5, 0x3145 }, - { 0x0EB6, 0x3146 }, - { 0x0EB7, 0x3147 }, - { 0x0EB8, 0x3148 }, - { 0x0EB9, 0x3149 }, - { 0x0EBA, 0x314A }, - { 0x0EBB, 0x314B }, - { 0x0EBC, 0x314C }, - { 0x0EBD, 0x314D }, - { 0x0EBE, 0x314E }, - { 0x0EBF, 0x314F }, - { 0x0EC0, 0x3150 }, - { 0x0EC1, 0x3151 }, - { 0x0EC2, 0x3152 }, - { 0x0EC3, 0x3153 }, - { 0x0EC4, 0x3154 }, - { 0x0EC5, 0x3155 }, - { 0x0EC6, 0x3156 }, - { 0x0EC7, 0x3157 }, - { 0x0EC8, 0x3158 }, - { 0x0EC9, 0x3159 }, - { 0x0ECA, 0x315A }, - { 0x0ECB, 0x315B }, - { 0x0ECC, 0x315C }, - { 0x0ECD, 0x315D }, - { 0x0ECE, 0x315E }, - { 0x0ECF, 0x315F }, - { 0x0ED0, 0x3160 }, - { 0x0ED1, 0x3161 }, - { 0x0ED2, 0x3162 }, - { 0x0ED3, 0x3163 }, - { 0x0ED4, 0x11A8 }, - { 0x0ED5, 0x11A9 }, - { 0x0ED6, 0x11AA }, - { 0x0ED7, 0x11AB }, - { 0x0ED8, 0x11AC }, - { 0x0ED9, 0x11AD }, - { 0x0EDA, 0x11AE }, - { 0x0EDB, 0x11AF }, - { 0x0EDC, 0x11B0 }, - { 0x0EDD, 0x11B1 }, - { 0x0EDE, 0x11B2 }, - { 0x0EDF, 0x11B3 }, - { 0x0EE0, 0x11B4 }, - { 0x0EE1, 0x11B5 }, - { 0x0EE2, 0x11B6 }, - { 0x0EE3, 0x11B7 }, - { 0x0EE4, 0x11B8 }, - { 0x0EE5, 0x11B9 }, - { 0x0EE6, 0x11BA }, - { 0x0EE7, 0x11BB }, - { 0x0EE8, 0x11BC }, - { 0x0EE9, 0x11BD }, - { 0x0EEA, 0x11BE }, - { 0x0EEB, 0x11BF }, - { 0x0EEC, 0x11C0 }, - { 0x0EED, 0x11C1 }, - { 0x0EEE, 0x11C2 }, - { 0x0EEF, 0x316D }, - { 0x0EF0, 0x3171 }, - { 0x0EF1, 0x3178 }, - { 0x0EF2, 0x317F }, - { 0x0EF3, 0x3181 }, - { 0x0EF4, 0x3184 }, - { 0x0EF5, 0x3186 }, - { 0x0EF6, 0x318D }, - { 0x0EF7, 0x318E }, - { 0x0EF8, 0x11EB }, - { 0x0EF9, 0x11F0 }, - { 0x0EFA, 0x11F9 }, - { 0x0EFF, 0x20A9 }, - { 0x13A4, 0x20AC }, - { 0x13BC, 0x0152 }, - { 0x13BD, 0x0153 }, - { 0x13BE, 0x0178 }, - { 0x20AC, 0x20AC }, -}; - -unsigned int KeyMappingX11::get_unicode_from_keysym(KeySym p_keysym) { - /* Latin-1 */ - if (p_keysym >= 0x20 && p_keysym <= 0x7e) { +char32_t KeyMappingX11::get_unicode_from_keysym(KeySym p_keysym) { + // Latin-1 + if (p_keysym >= 0x20 && p_keysym <= 0x7E) { return p_keysym; } - if (p_keysym >= 0xa0 && p_keysym <= 0xff) { + if (p_keysym >= 0xA0 && p_keysym <= 0xFF) { return p_keysym; } - // keypad to latin1 is easy - if (p_keysym >= 0xffaa && p_keysym <= 0xffb9) { - return p_keysym - 0xff80; - } - - /* Unicode (may be present)*/ - if ((p_keysym & 0xff000000) == 0x01000000) { - return p_keysym & 0x00ffffff; + // Keypad to Latin-1. + if (p_keysym >= 0xFFAA && p_keysym <= 0xFFB9) { + return p_keysym - 0xFF80; } - int middle, low = 0, high = _KEYSYM_MAX - 1; - do { - middle = (high + low) / 2; - if (_xkeysym_to_unicode[middle].keysym == p_keysym) { - return _xkeysym_to_unicode[middle].unicode; - } - if (_xkeysym_to_unicode[middle].keysym <= p_keysym) { - low = middle + 1; - } else { - high = middle - 1; - } - } while (high >= low); - - return 0; -} - -struct _XTranslateUnicodePairReverse { - unsigned int unicode; - KeySym keysym; -}; - -enum { - _UNICODE_MAX = 750 -}; - -static _XTranslateUnicodePairReverse _unicode_to_xkeysym[_UNICODE_MAX] = { - { 0x0ABD, 0x002E }, - { 0x0BA3, 0x003C }, - { 0x0BA6, 0x003E }, - { 0x0BC6, 0x005F }, - { 0x0BC0, 0x00AF }, - { 0x03C0, 0x0100 }, - { 0x03E0, 0x0101 }, - { 0x01C3, 0x0102 }, - { 0x01E3, 0x0103 }, - { 0x01A1, 0x0104 }, - { 0x01B1, 0x0105 }, - { 0x01C6, 0x0106 }, - { 0x01E6, 0x0107 }, - { 0x02C6, 0x0108 }, - { 0x02E6, 0x0109 }, - { 0x02C5, 0x010A }, - { 0x02E5, 0x010B }, - { 0x01C8, 0x010C }, - { 0x01E8, 0x010D }, - { 0x01CF, 0x010E }, - { 0x01EF, 0x010F }, - { 0x01D0, 0x0110 }, - { 0x01F0, 0x0111 }, - { 0x03AA, 0x0112 }, - { 0x03BA, 0x0113 }, - { 0x03CC, 0x0116 }, - { 0x03EC, 0x0117 }, - { 0x01CA, 0x0118 }, - { 0x01EA, 0x0119 }, - { 0x01CC, 0x011A }, - { 0x01EC, 0x011B }, - { 0x02D8, 0x011C }, - { 0x02F8, 0x011D }, - { 0x02AB, 0x011E }, - { 0x02BB, 0x011F }, - { 0x02D5, 0x0120 }, - { 0x02F5, 0x0121 }, - { 0x03AB, 0x0122 }, - { 0x03BB, 0x0123 }, - { 0x02A6, 0x0124 }, - { 0x02B6, 0x0125 }, - { 0x02A1, 0x0126 }, - { 0x02B1, 0x0127 }, - { 0x03A5, 0x0128 }, - { 0x03B5, 0x0129 }, - { 0x03CF, 0x012A }, - { 0x03EF, 0x012B }, - { 0x03C7, 0x012E }, - { 0x03E7, 0x012F }, - { 0x02A9, 0x0130 }, - { 0x02B9, 0x0131 }, - { 0x02AC, 0x0134 }, - { 0x02BC, 0x0135 }, - { 0x03D3, 0x0136 }, - { 0x03F3, 0x0137 }, - { 0x03A2, 0x0138 }, - { 0x01C5, 0x0139 }, - { 0x01E5, 0x013A }, - { 0x03A6, 0x013B }, - { 0x03B6, 0x013C }, - { 0x01A5, 0x013D }, - { 0x01B5, 0x013E }, - { 0x01A3, 0x0141 }, - { 0x01B3, 0x0142 }, - { 0x01D1, 0x0143 }, - { 0x01F1, 0x0144 }, - { 0x03D1, 0x0145 }, - { 0x03F1, 0x0146 }, - { 0x01D2, 0x0147 }, - { 0x01F2, 0x0148 }, - { 0x03BD, 0x014A }, - { 0x03BF, 0x014B }, - { 0x03D2, 0x014C }, - { 0x03F2, 0x014D }, - { 0x01D5, 0x0150 }, - { 0x01F5, 0x0151 }, - { 0x13BC, 0x0152 }, - { 0x13BD, 0x0153 }, - { 0x01C0, 0x0154 }, - { 0x01E0, 0x0155 }, - { 0x03A3, 0x0156 }, - { 0x03B3, 0x0157 }, - { 0x01D8, 0x0158 }, - { 0x01F8, 0x0159 }, - { 0x01A6, 0x015A }, - { 0x01B6, 0x015B }, - { 0x02DE, 0x015C }, - { 0x02FE, 0x015D }, - { 0x01AA, 0x015E }, - { 0x01BA, 0x015F }, - { 0x01A9, 0x0160 }, - { 0x01B9, 0x0161 }, - { 0x01DE, 0x0162 }, - { 0x01FE, 0x0163 }, - { 0x01AB, 0x0164 }, - { 0x01BB, 0x0165 }, - { 0x03AC, 0x0166 }, - { 0x03BC, 0x0167 }, - { 0x03DD, 0x0168 }, - { 0x03FD, 0x0169 }, - { 0x03DE, 0x016A }, - { 0x03FE, 0x016B }, - { 0x02DD, 0x016C }, - { 0x02FD, 0x016D }, - { 0x01D9, 0x016E }, - { 0x01F9, 0x016F }, - { 0x01DB, 0x0170 }, - { 0x01FB, 0x0171 }, - { 0x03D9, 0x0172 }, - { 0x03F9, 0x0173 }, - { 0x13BE, 0x0178 }, - { 0x01AC, 0x0179 }, - { 0x01BC, 0x017A }, - { 0x01AF, 0x017B }, - { 0x01BF, 0x017C }, - { 0x01AE, 0x017D }, - { 0x01BE, 0x017E }, - { 0x08F6, 0x0192 }, - { 0x01B7, 0x02C7 }, - { 0x01A2, 0x02D8 }, - { 0x01FF, 0x02D9 }, - { 0x01B2, 0x02DB }, - { 0x01BD, 0x02DD }, - { 0x07AE, 0x0385 }, - { 0x07A1, 0x0386 }, - { 0x07A2, 0x0388 }, - { 0x07A3, 0x0389 }, - { 0x07A4, 0x038A }, - { 0x07A7, 0x038C }, - { 0x07A8, 0x038E }, - { 0x07AB, 0x038F }, - { 0x07B6, 0x0390 }, - { 0x07C1, 0x0391 }, - { 0x07C2, 0x0392 }, - { 0x07C3, 0x0393 }, - { 0x07C4, 0x0394 }, - { 0x07C5, 0x0395 }, - { 0x07C6, 0x0396 }, - { 0x07C7, 0x0397 }, - { 0x07C8, 0x0398 }, - { 0x07C9, 0x0399 }, - { 0x07CA, 0x039A }, - { 0x07CB, 0x039B }, - { 0x07CC, 0x039C }, - { 0x07CD, 0x039D }, - { 0x07CE, 0x039E }, - { 0x07CF, 0x039F }, - { 0x07D0, 0x03A0 }, - { 0x07D1, 0x03A1 }, - { 0x07D2, 0x03A3 }, - { 0x07D4, 0x03A4 }, - { 0x07D5, 0x03A5 }, - { 0x07D6, 0x03A6 }, - { 0x07D7, 0x03A7 }, - { 0x07D8, 0x03A8 }, - { 0x07D9, 0x03A9 }, - { 0x07A5, 0x03AA }, - { 0x07A9, 0x03AB }, - { 0x07B1, 0x03AC }, - { 0x07B2, 0x03AD }, - { 0x07B3, 0x03AE }, - { 0x07B4, 0x03AF }, - { 0x07BA, 0x03B0 }, - { 0x07E1, 0x03B1 }, - { 0x07E2, 0x03B2 }, - { 0x07E3, 0x03B3 }, - { 0x07E4, 0x03B4 }, - { 0x07E5, 0x03B5 }, - { 0x07E6, 0x03B6 }, - { 0x07E7, 0x03B7 }, - { 0x07E8, 0x03B8 }, - { 0x07E9, 0x03B9 }, - { 0x07EA, 0x03BA }, - { 0x07EB, 0x03BB }, - { 0x07EC, 0x03BC }, - { 0x07ED, 0x03BD }, - { 0x07EE, 0x03BE }, - { 0x07EF, 0x03BF }, - { 0x07F0, 0x03C0 }, - { 0x07F1, 0x03C1 }, - { 0x07F3, 0x03C2 }, - { 0x07F2, 0x03C3 }, - { 0x07F4, 0x03C4 }, - { 0x07F5, 0x03C5 }, - { 0x07F6, 0x03C6 }, - { 0x07F7, 0x03C7 }, - { 0x07F8, 0x03C8 }, - { 0x07F9, 0x03C9 }, - { 0x07B5, 0x03CA }, - { 0x07B9, 0x03CB }, - { 0x07B7, 0x03CC }, - { 0x07B8, 0x03CD }, - { 0x07BB, 0x03CE }, - { 0x06B3, 0x0401 }, - { 0x06B1, 0x0402 }, - { 0x06B2, 0x0403 }, - { 0x06B4, 0x0404 }, - { 0x06B5, 0x0405 }, - { 0x06B6, 0x0406 }, - { 0x06B7, 0x0407 }, - { 0x06B8, 0x0408 }, - { 0x06B9, 0x0409 }, - { 0x06BA, 0x040A }, - { 0x06BB, 0x040B }, - { 0x06BC, 0x040C }, - { 0x06BE, 0x040E }, - { 0x06BF, 0x040F }, - { 0x06E1, 0x0410 }, - { 0x06E2, 0x0411 }, - { 0x06F7, 0x0412 }, - { 0x06E7, 0x0413 }, - { 0x06E4, 0x0414 }, - { 0x06E5, 0x0415 }, - { 0x06F6, 0x0416 }, - { 0x06FA, 0x0417 }, - { 0x06E9, 0x0418 }, - { 0x06EA, 0x0419 }, - { 0x06EB, 0x041A }, - { 0x06EC, 0x041B }, - { 0x06ED, 0x041C }, - { 0x06EE, 0x041D }, - { 0x06EF, 0x041E }, - { 0x06F0, 0x041F }, - { 0x06F2, 0x0420 }, - { 0x06F3, 0x0421 }, - { 0x06F4, 0x0422 }, - { 0x06F5, 0x0423 }, - { 0x06E6, 0x0424 }, - { 0x06E8, 0x0425 }, - { 0x06E3, 0x0426 }, - { 0x06FE, 0x0427 }, - { 0x06FB, 0x0428 }, - { 0x06FD, 0x0429 }, - { 0x06FF, 0x042A }, - { 0x06F9, 0x042B }, - { 0x06F8, 0x042C }, - { 0x06FC, 0x042D }, - { 0x06E0, 0x042E }, - { 0x06F1, 0x042F }, - { 0x06C1, 0x0430 }, - { 0x06C2, 0x0431 }, - { 0x06D7, 0x0432 }, - { 0x06C7, 0x0433 }, - { 0x06C4, 0x0434 }, - { 0x06C5, 0x0435 }, - { 0x06D6, 0x0436 }, - { 0x06DA, 0x0437 }, - { 0x06C9, 0x0438 }, - { 0x06CA, 0x0439 }, - { 0x06CB, 0x043A }, - { 0x06CC, 0x043B }, - { 0x06CD, 0x043C }, - { 0x06CE, 0x043D }, - { 0x06CF, 0x043E }, - { 0x06D0, 0x043F }, - { 0x06D2, 0x0440 }, - { 0x06D3, 0x0441 }, - { 0x06D4, 0x0442 }, - { 0x06D5, 0x0443 }, - { 0x06C6, 0x0444 }, - { 0x06C8, 0x0445 }, - { 0x06C3, 0x0446 }, - { 0x06DE, 0x0447 }, - { 0x06DB, 0x0448 }, - { 0x06DD, 0x0449 }, - { 0x06DF, 0x044A }, - { 0x06D9, 0x044B }, - { 0x06D8, 0x044C }, - { 0x06DC, 0x044D }, - { 0x06C0, 0x044E }, - { 0x06D1, 0x044F }, - { 0x06A3, 0x0451 }, - { 0x06A1, 0x0452 }, - { 0x06A2, 0x0453 }, - { 0x06A4, 0x0454 }, - { 0x06A5, 0x0455 }, - { 0x06A6, 0x0456 }, - { 0x06A7, 0x0457 }, - { 0x06A8, 0x0458 }, - { 0x06A9, 0x0459 }, - { 0x06AA, 0x045A }, - { 0x06AB, 0x045B }, - { 0x06AC, 0x045C }, - { 0x06AE, 0x045E }, - { 0x06AF, 0x045F }, - { 0x0CE0, 0x05D0 }, - { 0x0CE1, 0x05D1 }, - { 0x0CE2, 0x05D2 }, - { 0x0CE3, 0x05D3 }, - { 0x0CE4, 0x05D4 }, - { 0x0CE5, 0x05D5 }, - { 0x0CE6, 0x05D6 }, - { 0x0CE7, 0x05D7 }, - { 0x0CE8, 0x05D8 }, - { 0x0CE9, 0x05D9 }, - { 0x0CEA, 0x05DA }, - { 0x0CEB, 0x05DB }, - { 0x0CEC, 0x05DC }, - { 0x0CED, 0x05DD }, - { 0x0CEE, 0x05DE }, - { 0x0CEF, 0x05DF }, - { 0x0CF0, 0x05E0 }, - { 0x0CF1, 0x05E1 }, - { 0x0CF2, 0x05E2 }, - { 0x0CF3, 0x05E3 }, - { 0x0CF4, 0x05E4 }, - { 0x0CF5, 0x05E5 }, - { 0x0CF6, 0x05E6 }, - { 0x0CF7, 0x05E7 }, - { 0x0CF8, 0x05E8 }, - { 0x0CF9, 0x05E9 }, - { 0x0CFA, 0x05EA }, - { 0x05AC, 0x060C }, - { 0x05BB, 0x061B }, - { 0x05BF, 0x061F }, - { 0x05C1, 0x0621 }, - { 0x05C2, 0x0622 }, - { 0x05C3, 0x0623 }, - { 0x05C4, 0x0624 }, - { 0x05C5, 0x0625 }, - { 0x05C6, 0x0626 }, - { 0x05C7, 0x0627 }, - { 0x05C8, 0x0628 }, - { 0x05C9, 0x0629 }, - { 0x05CA, 0x062A }, - { 0x05CB, 0x062B }, - { 0x05CC, 0x062C }, - { 0x05CD, 0x062D }, - { 0x05CE, 0x062E }, - { 0x05CF, 0x062F }, - { 0x05D0, 0x0630 }, - { 0x05D1, 0x0631 }, - { 0x05D2, 0x0632 }, - { 0x05D3, 0x0633 }, - { 0x05D4, 0x0634 }, - { 0x05D5, 0x0635 }, - { 0x05D6, 0x0636 }, - { 0x05D7, 0x0637 }, - { 0x05D8, 0x0638 }, - { 0x05D9, 0x0639 }, - { 0x05DA, 0x063A }, - { 0x05E0, 0x0640 }, - { 0x05E1, 0x0641 }, - { 0x05E2, 0x0642 }, - { 0x05E3, 0x0643 }, - { 0x05E4, 0x0644 }, - { 0x05E5, 0x0645 }, - { 0x05E6, 0x0646 }, - { 0x05E7, 0x0647 }, - { 0x05E8, 0x0648 }, - { 0x05E9, 0x0649 }, - { 0x05EA, 0x064A }, - { 0x05EB, 0x064B }, - { 0x05EC, 0x064C }, - { 0x05ED, 0x064D }, - { 0x05EE, 0x064E }, - { 0x05EF, 0x064F }, - { 0x05F0, 0x0650 }, - { 0x05F1, 0x0651 }, - { 0x05F2, 0x0652 }, - { 0x0DA1, 0x0E01 }, - { 0x0DA2, 0x0E02 }, - { 0x0DA3, 0x0E03 }, - { 0x0DA4, 0x0E04 }, - { 0x0DA5, 0x0E05 }, - { 0x0DA6, 0x0E06 }, - { 0x0DA7, 0x0E07 }, - { 0x0DA8, 0x0E08 }, - { 0x0DA9, 0x0E09 }, - { 0x0DAA, 0x0E0A }, - { 0x0DAB, 0x0E0B }, - { 0x0DAC, 0x0E0C }, - { 0x0DAD, 0x0E0D }, - { 0x0DAE, 0x0E0E }, - { 0x0DAF, 0x0E0F }, - { 0x0DB0, 0x0E10 }, - { 0x0DB1, 0x0E11 }, - { 0x0DB2, 0x0E12 }, - { 0x0DB3, 0x0E13 }, - { 0x0DB4, 0x0E14 }, - { 0x0DB5, 0x0E15 }, - { 0x0DB6, 0x0E16 }, - { 0x0DB7, 0x0E17 }, - { 0x0DB8, 0x0E18 }, - { 0x0DB9, 0x0E19 }, - { 0x0DBA, 0x0E1A }, - { 0x0DBB, 0x0E1B }, - { 0x0DBC, 0x0E1C }, - { 0x0DBD, 0x0E1D }, - { 0x0DBE, 0x0E1E }, - { 0x0DBF, 0x0E1F }, - { 0x0DC0, 0x0E20 }, - { 0x0DC1, 0x0E21 }, - { 0x0DC2, 0x0E22 }, - { 0x0DC3, 0x0E23 }, - { 0x0DC4, 0x0E24 }, - { 0x0DC5, 0x0E25 }, - { 0x0DC6, 0x0E26 }, - { 0x0DC7, 0x0E27 }, - { 0x0DC8, 0x0E28 }, - { 0x0DC9, 0x0E29 }, - { 0x0DCA, 0x0E2A }, - { 0x0DCB, 0x0E2B }, - { 0x0DCC, 0x0E2C }, - { 0x0DCD, 0x0E2D }, - { 0x0DCE, 0x0E2E }, - { 0x0DCF, 0x0E2F }, - { 0x0DD0, 0x0E30 }, - { 0x0DD1, 0x0E31 }, - { 0x0DD2, 0x0E32 }, - { 0x0DD3, 0x0E33 }, - { 0x0DD4, 0x0E34 }, - { 0x0DD5, 0x0E35 }, - { 0x0DD6, 0x0E36 }, - { 0x0DD7, 0x0E37 }, - { 0x0DD8, 0x0E38 }, - { 0x0DD9, 0x0E39 }, - { 0x0DDA, 0x0E3A }, - { 0x0DDF, 0x0E3F }, - { 0x0DE0, 0x0E40 }, - { 0x0DE1, 0x0E41 }, - { 0x0DE2, 0x0E42 }, - { 0x0DE3, 0x0E43 }, - { 0x0DE4, 0x0E44 }, - { 0x0DE5, 0x0E45 }, - { 0x0DE6, 0x0E46 }, - { 0x0DE7, 0x0E47 }, - { 0x0DE8, 0x0E48 }, - { 0x0DE9, 0x0E49 }, - { 0x0DEA, 0x0E4A }, - { 0x0DEB, 0x0E4B }, - { 0x0DEC, 0x0E4C }, - { 0x0DED, 0x0E4D }, - { 0x0DF0, 0x0E50 }, - { 0x0DF1, 0x0E51 }, - { 0x0DF2, 0x0E52 }, - { 0x0DF3, 0x0E53 }, - { 0x0DF4, 0x0E54 }, - { 0x0DF5, 0x0E55 }, - { 0x0DF6, 0x0E56 }, - { 0x0DF7, 0x0E57 }, - { 0x0DF8, 0x0E58 }, - { 0x0DF9, 0x0E59 }, - { 0x0ED4, 0x11A8 }, - { 0x0ED5, 0x11A9 }, - { 0x0ED6, 0x11AA }, - { 0x0ED7, 0x11AB }, - { 0x0ED8, 0x11AC }, - { 0x0ED9, 0x11AD }, - { 0x0EDA, 0x11AE }, - { 0x0EDB, 0x11AF }, - { 0x0EDC, 0x11B0 }, - { 0x0EDD, 0x11B1 }, - { 0x0EDE, 0x11B2 }, - { 0x0EDF, 0x11B3 }, - { 0x0EE0, 0x11B4 }, - { 0x0EE1, 0x11B5 }, - { 0x0EE2, 0x11B6 }, - { 0x0EE3, 0x11B7 }, - { 0x0EE4, 0x11B8 }, - { 0x0EE5, 0x11B9 }, - { 0x0EE6, 0x11BA }, - { 0x0EE7, 0x11BB }, - { 0x0EE8, 0x11BC }, - { 0x0EE9, 0x11BD }, - { 0x0EEA, 0x11BE }, - { 0x0EEB, 0x11BF }, - { 0x0EEC, 0x11C0 }, - { 0x0EED, 0x11C1 }, - { 0x0EEE, 0x11C2 }, - { 0x0EF8, 0x11EB }, - { 0x0EFA, 0x11F9 }, - { 0x0AA2, 0x2002 }, - { 0x0AA1, 0x2003 }, - { 0x0AA3, 0x2004 }, - { 0x0AA4, 0x2005 }, - { 0x0AA5, 0x2007 }, - { 0x0AA6, 0x2008 }, - { 0x0AA7, 0x2009 }, - { 0x0AA8, 0x200A }, - { 0x0ABB, 0x2012 }, - { 0x0AAA, 0x2013 }, - { 0x0AA9, 0x2014 }, - { 0x07AF, 0x2015 }, - { 0x0CDF, 0x2017 }, - { 0x0AD0, 0x2018 }, - { 0x0AD1, 0x2019 }, - { 0x0AFD, 0x201A }, - { 0x0AD2, 0x201C }, - { 0x0AD3, 0x201D }, - { 0x0AFE, 0x201E }, - { 0x0AF1, 0x2020 }, - { 0x0AF2, 0x2021 }, - { 0x0AE6, 0x2022 }, - { 0x0AAE, 0x2026 }, - { 0x0AD6, 0x2032 }, - { 0x0AD7, 0x2033 }, - { 0x0AFC, 0x2038 }, - { 0x047E, 0x203E }, - { 0x20A0, 0x20A0 }, - { 0x20A1, 0x20A1 }, - { 0x20A2, 0x20A2 }, - { 0x20A3, 0x20A3 }, - { 0x20A4, 0x20A4 }, - { 0x20A5, 0x20A5 }, - { 0x20A6, 0x20A6 }, - { 0x20A7, 0x20A7 }, - { 0x20A8, 0x20A8 }, - { 0x0EFF, 0x20A9 }, - { 0x20A9, 0x20A9 }, - { 0x20AA, 0x20AA }, - { 0x20AB, 0x20AB }, - { 0x20AC, 0x20AC }, - { 0x0AB8, 0x2105 }, - { 0x06B0, 0x2116 }, - { 0x0AFB, 0x2117 }, - { 0x0AD4, 0x211E }, - { 0x0AC9, 0x2122 }, - { 0x0AB0, 0x2153 }, - { 0x0AB1, 0x2154 }, - { 0x0AB2, 0x2155 }, - { 0x0AB3, 0x2156 }, - { 0x0AB4, 0x2157 }, - { 0x0AB5, 0x2158 }, - { 0x0AB6, 0x2159 }, - { 0x0AB7, 0x215A }, - { 0x0AC3, 0x215B }, - { 0x0AC4, 0x215C }, - { 0x0AC5, 0x215D }, - { 0x0AC6, 0x215E }, - { 0x08FB, 0x2190 }, - { 0x08FC, 0x2191 }, - { 0x08FD, 0x2192 }, - { 0x08FE, 0x2193 }, - { 0x08CE, 0x21D2 }, - { 0x08CD, 0x21D4 }, - { 0x08EF, 0x2202 }, - { 0x08C5, 0x2207 }, - { 0x0BCA, 0x2218 }, - { 0x08D6, 0x221A }, - { 0x08C1, 0x221D }, - { 0x08C2, 0x221E }, - { 0x08DE, 0x2227 }, - { 0x0BA9, 0x2227 }, - { 0x08DF, 0x2228 }, - { 0x0BA8, 0x2228 }, - { 0x08DC, 0x2229 }, - { 0x0BC3, 0x2229 }, - { 0x08DD, 0x222A }, - { 0x0BD6, 0x222A }, - { 0x08BF, 0x222B }, - { 0x08C0, 0x2234 }, - { 0x08C8, 0x2245 }, - { 0x08BD, 0x2260 }, - { 0x08CF, 0x2261 }, - { 0x08BC, 0x2264 }, - { 0x08BE, 0x2265 }, - { 0x08DA, 0x2282 }, - { 0x0BDA, 0x2282 }, - { 0x08DB, 0x2283 }, - { 0x0BD8, 0x2283 }, - { 0x0BFC, 0x22A2 }, - { 0x0BDC, 0x22A3 }, - { 0x0BC2, 0x22A4 }, - { 0x0BCE, 0x22A5 }, - { 0x0BD3, 0x2308 }, - { 0x0BC4, 0x230A }, - { 0x0AFA, 0x2315 }, - { 0x08A4, 0x2320 }, - { 0x08A5, 0x2321 }, - { 0x0ABC, 0x2329 }, - { 0x0ABE, 0x232A }, - { 0x0BCC, 0x2395 }, - { 0x09E2, 0x2409 }, - { 0x09E5, 0x240A }, - { 0x09E9, 0x240B }, - { 0x09E3, 0x240C }, - { 0x09E4, 0x240D }, - { 0x09DF, 0x2422 }, - { 0x09E8, 0x2424 }, - { 0x09F1, 0x2500 }, - { 0x08A6, 0x2502 }, - { 0x09F8, 0x2502 }, - { 0x09EC, 0x250C }, - { 0x09EB, 0x2510 }, - { 0x09ED, 0x2514 }, - { 0x09EA, 0x2518 }, - { 0x09F4, 0x251C }, - { 0x09F5, 0x2524 }, - { 0x09F7, 0x252C }, - { 0x09F6, 0x2534 }, - { 0x09EE, 0x253C }, - { 0x09E1, 0x2592 }, - { 0x0ADF, 0x25A0 }, - { 0x0ACF, 0x25A1 }, - { 0x0AE7, 0x25AA }, - { 0x0AE1, 0x25AB }, - { 0x0ADB, 0x25AC }, - { 0x0AE2, 0x25AD }, - { 0x0AE8, 0x25B2 }, - { 0x0AE3, 0x25B3 }, - { 0x0ADD, 0x25B6 }, - { 0x0ACD, 0x25B7 }, - { 0x0AE9, 0x25BC }, - { 0x0AE4, 0x25BD }, - { 0x0ADC, 0x25C0 }, - { 0x0ACC, 0x25C1 }, - { 0x09E0, 0x25C6 }, - { 0x0ACE, 0x25CB }, - { 0x0BCF, 0x25CB }, - { 0x0ADE, 0x25CF }, - { 0x0AE0, 0x25E6 }, - { 0x0AE5, 0x2606 }, - { 0x0AF9, 0x260E }, - { 0x0ACA, 0x2613 }, - { 0x0AEA, 0x261C }, - { 0x0AEB, 0x261E }, - { 0x0AF8, 0x2640 }, - { 0x0AF7, 0x2642 }, - { 0x0AEC, 0x2663 }, - { 0x0AEE, 0x2665 }, - { 0x0AED, 0x2666 }, - { 0x0AF6, 0x266D }, - { 0x0AF5, 0x266F }, - { 0x0AF3, 0x2713 }, - { 0x0AF4, 0x2717 }, - { 0x0AD9, 0x271D }, - { 0x0AF0, 0x2720 }, - { 0x04A4, 0x3001 }, - { 0x04A1, 0x3002 }, - { 0x04A2, 0x300C }, - { 0x04A3, 0x300D }, - { 0x04DE, 0x309B }, - { 0x04DF, 0x309C }, - { 0x04A7, 0x30A1 }, - { 0x04B1, 0x30A2 }, - { 0x04A8, 0x30A3 }, - { 0x04B2, 0x30A4 }, - { 0x04A9, 0x30A5 }, - { 0x04B3, 0x30A6 }, - { 0x04AA, 0x30A7 }, - { 0x04B4, 0x30A8 }, - { 0x04AB, 0x30A9 }, - { 0x04B5, 0x30AA }, - { 0x04B6, 0x30AB }, - { 0x04B7, 0x30AD }, - { 0x04B8, 0x30AF }, - { 0x04B9, 0x30B1 }, - { 0x04BA, 0x30B3 }, - { 0x04BB, 0x30B5 }, - { 0x04BC, 0x30B7 }, - { 0x04BD, 0x30B9 }, - { 0x04BE, 0x30BB }, - { 0x04BF, 0x30BD }, - { 0x04C0, 0x30BF }, - { 0x04C1, 0x30C1 }, - { 0x04AF, 0x30C3 }, - { 0x04C2, 0x30C4 }, - { 0x04C3, 0x30C6 }, - { 0x04C4, 0x30C8 }, - { 0x04C5, 0x30CA }, - { 0x04C6, 0x30CB }, - { 0x04C7, 0x30CC }, - { 0x04C8, 0x30CD }, - { 0x04C9, 0x30CE }, - { 0x04CA, 0x30CF }, - { 0x04CB, 0x30D2 }, - { 0x04CC, 0x30D5 }, - { 0x04CD, 0x30D8 }, - { 0x04CE, 0x30DB }, - { 0x04CF, 0x30DE }, - { 0x04D0, 0x30DF }, - { 0x04D1, 0x30E0 }, - { 0x04D2, 0x30E1 }, - { 0x04D3, 0x30E2 }, - { 0x04AC, 0x30E3 }, - { 0x04D4, 0x30E4 }, - { 0x04AD, 0x30E5 }, - { 0x04D5, 0x30E6 }, - { 0x04AE, 0x30E7 }, - { 0x04D6, 0x30E8 }, - { 0x04D7, 0x30E9 }, - { 0x04D8, 0x30EA }, - { 0x04D9, 0x30EB }, - { 0x04DA, 0x30EC }, - { 0x04DB, 0x30ED }, - { 0x04DC, 0x30EF }, - { 0x04A6, 0x30F2 }, - { 0x04DD, 0x30F3 }, - { 0x04A5, 0x30FB }, - { 0x04B0, 0x30FC }, - { 0x0EA1, 0x3131 }, - { 0x0EA2, 0x3132 }, - { 0x0EA3, 0x3133 }, - { 0x0EA4, 0x3134 }, - { 0x0EA5, 0x3135 }, - { 0x0EA6, 0x3136 }, - { 0x0EA7, 0x3137 }, - { 0x0EA8, 0x3138 }, - { 0x0EA9, 0x3139 }, - { 0x0EAA, 0x313A }, - { 0x0EAB, 0x313B }, - { 0x0EAC, 0x313C }, - { 0x0EAD, 0x313D }, - { 0x0EAE, 0x313E }, - { 0x0EAF, 0x313F }, - { 0x0EB0, 0x3140 }, - { 0x0EB1, 0x3141 }, - { 0x0EB2, 0x3142 }, - { 0x0EB3, 0x3143 }, - { 0x0EB4, 0x3144 }, - { 0x0EB5, 0x3145 }, - { 0x0EB6, 0x3146 }, - { 0x0EB7, 0x3147 }, - { 0x0EB8, 0x3148 }, - { 0x0EB9, 0x3149 }, - { 0x0EBA, 0x314A }, - { 0x0EBB, 0x314B }, - { 0x0EBC, 0x314C }, - { 0x0EBD, 0x314D }, - { 0x0EBE, 0x314E }, - { 0x0EBF, 0x314F }, - { 0x0EC0, 0x3150 }, - { 0x0EC1, 0x3151 }, - { 0x0EC2, 0x3152 }, - { 0x0EC3, 0x3153 }, - { 0x0EC4, 0x3154 }, - { 0x0EC5, 0x3155 }, - { 0x0EC6, 0x3156 }, - { 0x0EC7, 0x3157 }, - { 0x0EC8, 0x3158 }, - { 0x0EC9, 0x3159 }, - { 0x0ECA, 0x315A }, - { 0x0ECB, 0x315B }, - { 0x0ECC, 0x315C }, - { 0x0ECD, 0x315D }, - { 0x0ECE, 0x315E }, - { 0x0ECF, 0x315F }, - { 0x0ED0, 0x3160 }, - { 0x0ED1, 0x3161 }, - { 0x0ED2, 0x3162 }, - { 0x0ED3, 0x3163 }, - { 0x0EEF, 0x316D }, - { 0x0EF0, 0x3171 }, - { 0x0EF1, 0x3178 }, - { 0x0EF2, 0x317F }, - { 0x0EF4, 0x3184 }, - { 0x0EF5, 0x3186 }, - { 0x0EF6, 0x318D }, - { 0x0EF7, 0x318E } -}; - -KeySym KeyMappingX11::get_keysym_from_unicode(unsigned int p_unicode) { - /* Latin 1 */ - - if (p_unicode >= 0x20 && p_unicode <= 0x7e) { - return p_unicode; + // Unicode (may be present). + if ((p_keysym & 0xFF000000) == 0x01000000) { + return p_keysym & 0x00FFFFFF; } - if (p_unicode >= 0xa0 && p_unicode <= 0xff) { - return p_unicode; + const char32_t *c = xkeysym_unicode_map.getptr(p_keysym); + if (c) { + return *c; } - - int middle, low = 0, high = _UNICODE_MAX - 1; - do { - middle = (high + low) / 2; - if (_unicode_to_xkeysym[middle].keysym == p_unicode) { - return _unicode_to_xkeysym[middle].keysym; - } - if (_unicode_to_xkeysym[middle].keysym <= p_unicode) { - low = middle + 1; - } else { - high = middle - 1; - } - } while (high >= low); - - // if not found, let's hope X understands it as unicode - return p_unicode | 0x01000000; + return 0; } diff --git a/platform/linuxbsd/x11/key_mapping_x11.h b/platform/linuxbsd/x11/key_mapping_x11.h index b7b8a3b787..ae8fd67f27 100644 --- a/platform/linuxbsd/x11/key_mapping_x11.h +++ b/platform/linuxbsd/x11/key_mapping_x11.h @@ -1,55 +1,69 @@ -/*************************************************************************/ -/* key_mapping_x11.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* key_mapping_x11.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 KEY_MAPPING_X11_H #define KEY_MAPPING_X11_H +#include "core/os/keyboard.h" +#include "core/templates/hash_map.h" + #include <X11/XF86keysym.h> #include <X11/Xlib.h> + #define XK_MISCELLANY #define XK_LATIN1 #define XK_XKB_KEYS #include <X11/keysymdef.h> -#include "core/os/keyboard.h" - class KeyMappingX11 { + struct HashMapHasherKeys { + static _FORCE_INLINE_ uint32_t hash(const Key p_key) { return hash_fmix32(static_cast<uint32_t>(p_key)); } + static _FORCE_INLINE_ uint32_t hash(const char32_t p_uchar) { return hash_fmix32(p_uchar); } + static _FORCE_INLINE_ uint32_t hash(const unsigned p_key) { return hash_fmix32(p_key); } + static _FORCE_INLINE_ uint32_t hash(const KeySym p_key) { return hash_fmix32(p_key); } + }; + + static inline HashMap<KeySym, Key, HashMapHasherKeys> xkeysym_map; + static inline HashMap<unsigned int, Key, HashMapHasherKeys> scancode_map; + static inline HashMap<Key, unsigned int, HashMapHasherKeys> scancode_map_inv; + static inline HashMap<KeySym, char32_t, HashMapHasherKeys> xkeysym_unicode_map; + KeyMappingX11() {} public: + static void initialize(); + static Key get_keycode(KeySym p_keysym); static unsigned int get_xlibcode(Key p_keysym); static Key get_scancode(unsigned int p_code); - static KeySym get_keysym(Key p_code); - static unsigned int get_unicode_from_keysym(KeySym p_keysym); - static KeySym get_keysym_from_unicode(unsigned int p_unicode); + static char32_t get_unicode_from_keysym(KeySym p_keysym); }; #endif // KEY_MAPPING_X11_H diff --git a/platform/linuxbsd/x11/vulkan_context_x11.cpp b/platform/linuxbsd/x11/vulkan_context_x11.cpp index 92aaf33b05..d240480f61 100644 --- a/platform/linuxbsd/x11/vulkan_context_x11.cpp +++ b/platform/linuxbsd/x11/vulkan_context_x11.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* vulkan_context_x11.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* vulkan_context_x11.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ #ifdef VULKAN_ENABLED diff --git a/platform/linuxbsd/x11/vulkan_context_x11.h b/platform/linuxbsd/x11/vulkan_context_x11.h index 0adb50ef44..294fdc710e 100644 --- a/platform/linuxbsd/x11/vulkan_context_x11.h +++ b/platform/linuxbsd/x11/vulkan_context_x11.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* vulkan_context_x11.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* vulkan_context_x11.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 VULKAN_CONTEXT_X11_H #define VULKAN_CONTEXT_X11_H @@ -34,6 +34,7 @@ #ifdef VULKAN_ENABLED #include "drivers/vulkan/vulkan_context.h" + #include <X11/Xlib.h> class VulkanContextX11 : public VulkanContext { diff --git a/platform/linuxbsd/xkbcommon-so_wrap.c b/platform/linuxbsd/xkbcommon-so_wrap.c new file mode 100644 index 0000000000..3382e2e553 --- /dev/null +++ b/platform/linuxbsd/xkbcommon-so_wrap.c @@ -0,0 +1,1015 @@ +// This file is generated. Do not edit! +// see https://github.com/hpvb/dynload-wrapper for details +// generated by generate-wrapper.py 0.3 on 2023-01-30 10:40:26 +// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/xkbcommon/xkbcommon.h --include ./thirdparty/linuxbsd_headers/xkbcommon/xkbcommon-compose.h --include ./thirdparty/linuxbsd_headers/xkbcommon/xkbcommon-keysyms.h --sys-include "./thirdparty/linuxbsd_headers/xkbcommon/xkbcommon.h" --sys-include "./thirdparty/linuxbsd_headers/xkbcommon/xkbcommon-compose.h" --sys-include "./thirdparty/linuxbsd_headers/xkbcommon/xkbcommon-keysyms.h" --soname libxkbcommon.so.0 --init-name xkbcommon --output-header ./platform/linuxbsd/xkbcommon-so_wrap.h --output-implementation ./platform/linuxbsd/xkbcommon-so_wrap.c +// +#include <stdint.h> + +#define xkb_keysym_get_name xkb_keysym_get_name_dylibloader_orig_xkbcommon +#define xkb_keysym_from_name xkb_keysym_from_name_dylibloader_orig_xkbcommon +#define xkb_keysym_to_utf8 xkb_keysym_to_utf8_dylibloader_orig_xkbcommon +#define xkb_keysym_to_utf32 xkb_keysym_to_utf32_dylibloader_orig_xkbcommon +#define xkb_utf32_to_keysym xkb_utf32_to_keysym_dylibloader_orig_xkbcommon +#define xkb_keysym_to_upper xkb_keysym_to_upper_dylibloader_orig_xkbcommon +#define xkb_keysym_to_lower xkb_keysym_to_lower_dylibloader_orig_xkbcommon +#define xkb_context_new xkb_context_new_dylibloader_orig_xkbcommon +#define xkb_context_ref xkb_context_ref_dylibloader_orig_xkbcommon +#define xkb_context_unref xkb_context_unref_dylibloader_orig_xkbcommon +#define xkb_context_set_user_data xkb_context_set_user_data_dylibloader_orig_xkbcommon +#define xkb_context_get_user_data xkb_context_get_user_data_dylibloader_orig_xkbcommon +#define xkb_context_include_path_append xkb_context_include_path_append_dylibloader_orig_xkbcommon +#define xkb_context_include_path_append_default xkb_context_include_path_append_default_dylibloader_orig_xkbcommon +#define xkb_context_include_path_reset_defaults xkb_context_include_path_reset_defaults_dylibloader_orig_xkbcommon +#define xkb_context_include_path_clear xkb_context_include_path_clear_dylibloader_orig_xkbcommon +#define xkb_context_num_include_paths xkb_context_num_include_paths_dylibloader_orig_xkbcommon +#define xkb_context_include_path_get xkb_context_include_path_get_dylibloader_orig_xkbcommon +#define xkb_context_set_log_level xkb_context_set_log_level_dylibloader_orig_xkbcommon +#define xkb_context_get_log_level xkb_context_get_log_level_dylibloader_orig_xkbcommon +#define xkb_context_set_log_verbosity xkb_context_set_log_verbosity_dylibloader_orig_xkbcommon +#define xkb_context_get_log_verbosity xkb_context_get_log_verbosity_dylibloader_orig_xkbcommon +#define xkb_context_set_log_fn xkb_context_set_log_fn_dylibloader_orig_xkbcommon +#define xkb_keymap_new_from_names xkb_keymap_new_from_names_dylibloader_orig_xkbcommon +#define xkb_keymap_new_from_file xkb_keymap_new_from_file_dylibloader_orig_xkbcommon +#define xkb_keymap_new_from_string xkb_keymap_new_from_string_dylibloader_orig_xkbcommon +#define xkb_keymap_new_from_buffer xkb_keymap_new_from_buffer_dylibloader_orig_xkbcommon +#define xkb_keymap_ref xkb_keymap_ref_dylibloader_orig_xkbcommon +#define xkb_keymap_unref xkb_keymap_unref_dylibloader_orig_xkbcommon +#define xkb_keymap_get_as_string xkb_keymap_get_as_string_dylibloader_orig_xkbcommon +#define xkb_keymap_min_keycode xkb_keymap_min_keycode_dylibloader_orig_xkbcommon +#define xkb_keymap_max_keycode xkb_keymap_max_keycode_dylibloader_orig_xkbcommon +#define xkb_keymap_key_for_each xkb_keymap_key_for_each_dylibloader_orig_xkbcommon +#define xkb_keymap_key_get_name xkb_keymap_key_get_name_dylibloader_orig_xkbcommon +#define xkb_keymap_key_by_name xkb_keymap_key_by_name_dylibloader_orig_xkbcommon +#define xkb_keymap_num_mods xkb_keymap_num_mods_dylibloader_orig_xkbcommon +#define xkb_keymap_mod_get_name xkb_keymap_mod_get_name_dylibloader_orig_xkbcommon +#define xkb_keymap_mod_get_index xkb_keymap_mod_get_index_dylibloader_orig_xkbcommon +#define xkb_keymap_num_layouts xkb_keymap_num_layouts_dylibloader_orig_xkbcommon +#define xkb_keymap_layout_get_name xkb_keymap_layout_get_name_dylibloader_orig_xkbcommon +#define xkb_keymap_layout_get_index xkb_keymap_layout_get_index_dylibloader_orig_xkbcommon +#define xkb_keymap_num_leds xkb_keymap_num_leds_dylibloader_orig_xkbcommon +#define xkb_keymap_led_get_name xkb_keymap_led_get_name_dylibloader_orig_xkbcommon +#define xkb_keymap_led_get_index xkb_keymap_led_get_index_dylibloader_orig_xkbcommon +#define xkb_keymap_num_layouts_for_key xkb_keymap_num_layouts_for_key_dylibloader_orig_xkbcommon +#define xkb_keymap_num_levels_for_key xkb_keymap_num_levels_for_key_dylibloader_orig_xkbcommon +#define xkb_keymap_key_get_mods_for_level xkb_keymap_key_get_mods_for_level_dylibloader_orig_xkbcommon +#define xkb_keymap_key_get_syms_by_level xkb_keymap_key_get_syms_by_level_dylibloader_orig_xkbcommon +#define xkb_keymap_key_repeats xkb_keymap_key_repeats_dylibloader_orig_xkbcommon +#define xkb_state_new xkb_state_new_dylibloader_orig_xkbcommon +#define xkb_state_ref xkb_state_ref_dylibloader_orig_xkbcommon +#define xkb_state_unref xkb_state_unref_dylibloader_orig_xkbcommon +#define xkb_state_get_keymap xkb_state_get_keymap_dylibloader_orig_xkbcommon +#define xkb_state_update_key xkb_state_update_key_dylibloader_orig_xkbcommon +#define xkb_state_update_mask xkb_state_update_mask_dylibloader_orig_xkbcommon +#define xkb_state_key_get_syms xkb_state_key_get_syms_dylibloader_orig_xkbcommon +#define xkb_state_key_get_utf8 xkb_state_key_get_utf8_dylibloader_orig_xkbcommon +#define xkb_state_key_get_utf32 xkb_state_key_get_utf32_dylibloader_orig_xkbcommon +#define xkb_state_key_get_one_sym xkb_state_key_get_one_sym_dylibloader_orig_xkbcommon +#define xkb_state_key_get_layout xkb_state_key_get_layout_dylibloader_orig_xkbcommon +#define xkb_state_key_get_level xkb_state_key_get_level_dylibloader_orig_xkbcommon +#define xkb_state_serialize_mods xkb_state_serialize_mods_dylibloader_orig_xkbcommon +#define xkb_state_serialize_layout xkb_state_serialize_layout_dylibloader_orig_xkbcommon +#define xkb_state_mod_name_is_active xkb_state_mod_name_is_active_dylibloader_orig_xkbcommon +#define xkb_state_mod_names_are_active xkb_state_mod_names_are_active_dylibloader_orig_xkbcommon +#define xkb_state_mod_index_is_active xkb_state_mod_index_is_active_dylibloader_orig_xkbcommon +#define xkb_state_mod_indices_are_active xkb_state_mod_indices_are_active_dylibloader_orig_xkbcommon +#define xkb_state_key_get_consumed_mods2 xkb_state_key_get_consumed_mods2_dylibloader_orig_xkbcommon +#define xkb_state_key_get_consumed_mods xkb_state_key_get_consumed_mods_dylibloader_orig_xkbcommon +#define xkb_state_mod_index_is_consumed2 xkb_state_mod_index_is_consumed2_dylibloader_orig_xkbcommon +#define xkb_state_mod_index_is_consumed xkb_state_mod_index_is_consumed_dylibloader_orig_xkbcommon +#define xkb_state_mod_mask_remove_consumed xkb_state_mod_mask_remove_consumed_dylibloader_orig_xkbcommon +#define xkb_state_layout_name_is_active xkb_state_layout_name_is_active_dylibloader_orig_xkbcommon +#define xkb_state_layout_index_is_active xkb_state_layout_index_is_active_dylibloader_orig_xkbcommon +#define xkb_state_led_name_is_active xkb_state_led_name_is_active_dylibloader_orig_xkbcommon +#define xkb_state_led_index_is_active xkb_state_led_index_is_active_dylibloader_orig_xkbcommon +#define xkb_compose_table_new_from_locale xkb_compose_table_new_from_locale_dylibloader_orig_xkbcommon +#define xkb_compose_table_new_from_file xkb_compose_table_new_from_file_dylibloader_orig_xkbcommon +#define xkb_compose_table_new_from_buffer xkb_compose_table_new_from_buffer_dylibloader_orig_xkbcommon +#define xkb_compose_table_ref xkb_compose_table_ref_dylibloader_orig_xkbcommon +#define xkb_compose_table_unref xkb_compose_table_unref_dylibloader_orig_xkbcommon +#define xkb_compose_state_new xkb_compose_state_new_dylibloader_orig_xkbcommon +#define xkb_compose_state_ref xkb_compose_state_ref_dylibloader_orig_xkbcommon +#define xkb_compose_state_unref xkb_compose_state_unref_dylibloader_orig_xkbcommon +#define xkb_compose_state_get_compose_table xkb_compose_state_get_compose_table_dylibloader_orig_xkbcommon +#define xkb_compose_state_feed xkb_compose_state_feed_dylibloader_orig_xkbcommon +#define xkb_compose_state_reset xkb_compose_state_reset_dylibloader_orig_xkbcommon +#define xkb_compose_state_get_status xkb_compose_state_get_status_dylibloader_orig_xkbcommon +#define xkb_compose_state_get_utf8 xkb_compose_state_get_utf8_dylibloader_orig_xkbcommon +#define xkb_compose_state_get_one_sym xkb_compose_state_get_one_sym_dylibloader_orig_xkbcommon +#include "./thirdparty/linuxbsd_headers/xkbcommon/xkbcommon.h" +#include "./thirdparty/linuxbsd_headers/xkbcommon/xkbcommon-compose.h" +#include "./thirdparty/linuxbsd_headers/xkbcommon/xkbcommon-keysyms.h" +#undef xkb_keysym_get_name +#undef xkb_keysym_from_name +#undef xkb_keysym_to_utf8 +#undef xkb_keysym_to_utf32 +#undef xkb_utf32_to_keysym +#undef xkb_keysym_to_upper +#undef xkb_keysym_to_lower +#undef xkb_context_new +#undef xkb_context_ref +#undef xkb_context_unref +#undef xkb_context_set_user_data +#undef xkb_context_get_user_data +#undef xkb_context_include_path_append +#undef xkb_context_include_path_append_default +#undef xkb_context_include_path_reset_defaults +#undef xkb_context_include_path_clear +#undef xkb_context_num_include_paths +#undef xkb_context_include_path_get +#undef xkb_context_set_log_level +#undef xkb_context_get_log_level +#undef xkb_context_set_log_verbosity +#undef xkb_context_get_log_verbosity +#undef xkb_context_set_log_fn +#undef xkb_keymap_new_from_names +#undef xkb_keymap_new_from_file +#undef xkb_keymap_new_from_string +#undef xkb_keymap_new_from_buffer +#undef xkb_keymap_ref +#undef xkb_keymap_unref +#undef xkb_keymap_get_as_string +#undef xkb_keymap_min_keycode +#undef xkb_keymap_max_keycode +#undef xkb_keymap_key_for_each +#undef xkb_keymap_key_get_name +#undef xkb_keymap_key_by_name +#undef xkb_keymap_num_mods +#undef xkb_keymap_mod_get_name +#undef xkb_keymap_mod_get_index +#undef xkb_keymap_num_layouts +#undef xkb_keymap_layout_get_name +#undef xkb_keymap_layout_get_index +#undef xkb_keymap_num_leds +#undef xkb_keymap_led_get_name +#undef xkb_keymap_led_get_index +#undef xkb_keymap_num_layouts_for_key +#undef xkb_keymap_num_levels_for_key +#undef xkb_keymap_key_get_mods_for_level +#undef xkb_keymap_key_get_syms_by_level +#undef xkb_keymap_key_repeats +#undef xkb_state_new +#undef xkb_state_ref +#undef xkb_state_unref +#undef xkb_state_get_keymap +#undef xkb_state_update_key +#undef xkb_state_update_mask +#undef xkb_state_key_get_syms +#undef xkb_state_key_get_utf8 +#undef xkb_state_key_get_utf32 +#undef xkb_state_key_get_one_sym +#undef xkb_state_key_get_layout +#undef xkb_state_key_get_level +#undef xkb_state_serialize_mods +#undef xkb_state_serialize_layout +#undef xkb_state_mod_name_is_active +#undef xkb_state_mod_names_are_active +#undef xkb_state_mod_index_is_active +#undef xkb_state_mod_indices_are_active +#undef xkb_state_key_get_consumed_mods2 +#undef xkb_state_key_get_consumed_mods +#undef xkb_state_mod_index_is_consumed2 +#undef xkb_state_mod_index_is_consumed +#undef xkb_state_mod_mask_remove_consumed +#undef xkb_state_layout_name_is_active +#undef xkb_state_layout_index_is_active +#undef xkb_state_led_name_is_active +#undef xkb_state_led_index_is_active +#undef xkb_compose_table_new_from_locale +#undef xkb_compose_table_new_from_file +#undef xkb_compose_table_new_from_buffer +#undef xkb_compose_table_ref +#undef xkb_compose_table_unref +#undef xkb_compose_state_new +#undef xkb_compose_state_ref +#undef xkb_compose_state_unref +#undef xkb_compose_state_get_compose_table +#undef xkb_compose_state_feed +#undef xkb_compose_state_reset +#undef xkb_compose_state_get_status +#undef xkb_compose_state_get_utf8 +#undef xkb_compose_state_get_one_sym +#include <dlfcn.h> +#include <stdio.h> +int (*xkb_keysym_get_name_dylibloader_wrapper_xkbcommon)( xkb_keysym_t, char*, size_t); +xkb_keysym_t (*xkb_keysym_from_name_dylibloader_wrapper_xkbcommon)(const char*,enum xkb_keysym_flags); +int (*xkb_keysym_to_utf8_dylibloader_wrapper_xkbcommon)( xkb_keysym_t, char*, size_t); +uint32_t (*xkb_keysym_to_utf32_dylibloader_wrapper_xkbcommon)( xkb_keysym_t); +xkb_keysym_t (*xkb_utf32_to_keysym_dylibloader_wrapper_xkbcommon)( uint32_t); +xkb_keysym_t (*xkb_keysym_to_upper_dylibloader_wrapper_xkbcommon)( xkb_keysym_t); +xkb_keysym_t (*xkb_keysym_to_lower_dylibloader_wrapper_xkbcommon)( xkb_keysym_t); +struct xkb_context* (*xkb_context_new_dylibloader_wrapper_xkbcommon)(enum xkb_context_flags); +struct xkb_context* (*xkb_context_ref_dylibloader_wrapper_xkbcommon)(struct xkb_context*); +void (*xkb_context_unref_dylibloader_wrapper_xkbcommon)(struct xkb_context*); +void (*xkb_context_set_user_data_dylibloader_wrapper_xkbcommon)(struct xkb_context*, void*); +void* (*xkb_context_get_user_data_dylibloader_wrapper_xkbcommon)(struct xkb_context*); +int (*xkb_context_include_path_append_dylibloader_wrapper_xkbcommon)(struct xkb_context*,const char*); +int (*xkb_context_include_path_append_default_dylibloader_wrapper_xkbcommon)(struct xkb_context*); +int (*xkb_context_include_path_reset_defaults_dylibloader_wrapper_xkbcommon)(struct xkb_context*); +void (*xkb_context_include_path_clear_dylibloader_wrapper_xkbcommon)(struct xkb_context*); +unsigned int (*xkb_context_num_include_paths_dylibloader_wrapper_xkbcommon)(struct xkb_context*); +const char* (*xkb_context_include_path_get_dylibloader_wrapper_xkbcommon)(struct xkb_context*, unsigned int); +void (*xkb_context_set_log_level_dylibloader_wrapper_xkbcommon)(struct xkb_context*,enum xkb_log_level); +enum xkb_log_level (*xkb_context_get_log_level_dylibloader_wrapper_xkbcommon)(struct xkb_context*); +void (*xkb_context_set_log_verbosity_dylibloader_wrapper_xkbcommon)(struct xkb_context*, int); +int (*xkb_context_get_log_verbosity_dylibloader_wrapper_xkbcommon)(struct xkb_context*); +void (*xkb_context_set_log_fn_dylibloader_wrapper_xkbcommon)(struct xkb_context*, void*); +struct xkb_keymap* (*xkb_keymap_new_from_names_dylibloader_wrapper_xkbcommon)(struct xkb_context*,struct xkb_rule_names*,enum xkb_keymap_compile_flags); +struct xkb_keymap* (*xkb_keymap_new_from_file_dylibloader_wrapper_xkbcommon)(struct xkb_context*, FILE*,enum xkb_keymap_format,enum xkb_keymap_compile_flags); +struct xkb_keymap* (*xkb_keymap_new_from_string_dylibloader_wrapper_xkbcommon)(struct xkb_context*,const char*,enum xkb_keymap_format,enum xkb_keymap_compile_flags); +struct xkb_keymap* (*xkb_keymap_new_from_buffer_dylibloader_wrapper_xkbcommon)(struct xkb_context*,const char*, size_t,enum xkb_keymap_format,enum xkb_keymap_compile_flags); +struct xkb_keymap* (*xkb_keymap_ref_dylibloader_wrapper_xkbcommon)(struct xkb_keymap*); +void (*xkb_keymap_unref_dylibloader_wrapper_xkbcommon)(struct xkb_keymap*); +char* (*xkb_keymap_get_as_string_dylibloader_wrapper_xkbcommon)(struct xkb_keymap*,enum xkb_keymap_format); +xkb_keycode_t (*xkb_keymap_min_keycode_dylibloader_wrapper_xkbcommon)(struct xkb_keymap*); +xkb_keycode_t (*xkb_keymap_max_keycode_dylibloader_wrapper_xkbcommon)(struct xkb_keymap*); +void (*xkb_keymap_key_for_each_dylibloader_wrapper_xkbcommon)(struct xkb_keymap*, xkb_keymap_key_iter_t, void*); +const char* (*xkb_keymap_key_get_name_dylibloader_wrapper_xkbcommon)(struct xkb_keymap*, xkb_keycode_t); +xkb_keycode_t (*xkb_keymap_key_by_name_dylibloader_wrapper_xkbcommon)(struct xkb_keymap*,const char*); +xkb_mod_index_t (*xkb_keymap_num_mods_dylibloader_wrapper_xkbcommon)(struct xkb_keymap*); +const char* (*xkb_keymap_mod_get_name_dylibloader_wrapper_xkbcommon)(struct xkb_keymap*, xkb_mod_index_t); +xkb_mod_index_t (*xkb_keymap_mod_get_index_dylibloader_wrapper_xkbcommon)(struct xkb_keymap*,const char*); +xkb_layout_index_t (*xkb_keymap_num_layouts_dylibloader_wrapper_xkbcommon)(struct xkb_keymap*); +const char* (*xkb_keymap_layout_get_name_dylibloader_wrapper_xkbcommon)(struct xkb_keymap*, xkb_layout_index_t); +xkb_layout_index_t (*xkb_keymap_layout_get_index_dylibloader_wrapper_xkbcommon)(struct xkb_keymap*,const char*); +xkb_led_index_t (*xkb_keymap_num_leds_dylibloader_wrapper_xkbcommon)(struct xkb_keymap*); +const char* (*xkb_keymap_led_get_name_dylibloader_wrapper_xkbcommon)(struct xkb_keymap*, xkb_led_index_t); +xkb_led_index_t (*xkb_keymap_led_get_index_dylibloader_wrapper_xkbcommon)(struct xkb_keymap*,const char*); +xkb_layout_index_t (*xkb_keymap_num_layouts_for_key_dylibloader_wrapper_xkbcommon)(struct xkb_keymap*, xkb_keycode_t); +xkb_level_index_t (*xkb_keymap_num_levels_for_key_dylibloader_wrapper_xkbcommon)(struct xkb_keymap*, xkb_keycode_t, xkb_layout_index_t); +size_t (*xkb_keymap_key_get_mods_for_level_dylibloader_wrapper_xkbcommon)(struct xkb_keymap*, xkb_keycode_t, xkb_layout_index_t, xkb_level_index_t, xkb_mod_mask_t*, size_t); +int (*xkb_keymap_key_get_syms_by_level_dylibloader_wrapper_xkbcommon)(struct xkb_keymap*, xkb_keycode_t, xkb_layout_index_t, xkb_level_index_t,const xkb_keysym_t**); +int (*xkb_keymap_key_repeats_dylibloader_wrapper_xkbcommon)(struct xkb_keymap*, xkb_keycode_t); +struct xkb_state* (*xkb_state_new_dylibloader_wrapper_xkbcommon)(struct xkb_keymap*); +struct xkb_state* (*xkb_state_ref_dylibloader_wrapper_xkbcommon)(struct xkb_state*); +void (*xkb_state_unref_dylibloader_wrapper_xkbcommon)(struct xkb_state*); +struct xkb_keymap* (*xkb_state_get_keymap_dylibloader_wrapper_xkbcommon)(struct xkb_state*); +enum xkb_state_component (*xkb_state_update_key_dylibloader_wrapper_xkbcommon)(struct xkb_state*, xkb_keycode_t,enum xkb_key_direction); +enum xkb_state_component (*xkb_state_update_mask_dylibloader_wrapper_xkbcommon)(struct xkb_state*, xkb_mod_mask_t, xkb_mod_mask_t, xkb_mod_mask_t, xkb_layout_index_t, xkb_layout_index_t, xkb_layout_index_t); +int (*xkb_state_key_get_syms_dylibloader_wrapper_xkbcommon)(struct xkb_state*, xkb_keycode_t,const xkb_keysym_t**); +int (*xkb_state_key_get_utf8_dylibloader_wrapper_xkbcommon)(struct xkb_state*, xkb_keycode_t, char*, size_t); +uint32_t (*xkb_state_key_get_utf32_dylibloader_wrapper_xkbcommon)(struct xkb_state*, xkb_keycode_t); +xkb_keysym_t (*xkb_state_key_get_one_sym_dylibloader_wrapper_xkbcommon)(struct xkb_state*, xkb_keycode_t); +xkb_layout_index_t (*xkb_state_key_get_layout_dylibloader_wrapper_xkbcommon)(struct xkb_state*, xkb_keycode_t); +xkb_level_index_t (*xkb_state_key_get_level_dylibloader_wrapper_xkbcommon)(struct xkb_state*, xkb_keycode_t, xkb_layout_index_t); +xkb_mod_mask_t (*xkb_state_serialize_mods_dylibloader_wrapper_xkbcommon)(struct xkb_state*,enum xkb_state_component); +xkb_layout_index_t (*xkb_state_serialize_layout_dylibloader_wrapper_xkbcommon)(struct xkb_state*,enum xkb_state_component); +int (*xkb_state_mod_name_is_active_dylibloader_wrapper_xkbcommon)(struct xkb_state*,const char*,enum xkb_state_component); +int (*xkb_state_mod_names_are_active_dylibloader_wrapper_xkbcommon)(struct xkb_state*,enum xkb_state_component,enum xkb_state_match,...); +int (*xkb_state_mod_index_is_active_dylibloader_wrapper_xkbcommon)(struct xkb_state*, xkb_mod_index_t,enum xkb_state_component); +int (*xkb_state_mod_indices_are_active_dylibloader_wrapper_xkbcommon)(struct xkb_state*,enum xkb_state_component,enum xkb_state_match,...); +xkb_mod_mask_t (*xkb_state_key_get_consumed_mods2_dylibloader_wrapper_xkbcommon)(struct xkb_state*, xkb_keycode_t,enum xkb_consumed_mode); +xkb_mod_mask_t (*xkb_state_key_get_consumed_mods_dylibloader_wrapper_xkbcommon)(struct xkb_state*, xkb_keycode_t); +int (*xkb_state_mod_index_is_consumed2_dylibloader_wrapper_xkbcommon)(struct xkb_state*, xkb_keycode_t, xkb_mod_index_t,enum xkb_consumed_mode); +int (*xkb_state_mod_index_is_consumed_dylibloader_wrapper_xkbcommon)(struct xkb_state*, xkb_keycode_t, xkb_mod_index_t); +xkb_mod_mask_t (*xkb_state_mod_mask_remove_consumed_dylibloader_wrapper_xkbcommon)(struct xkb_state*, xkb_keycode_t, xkb_mod_mask_t); +int (*xkb_state_layout_name_is_active_dylibloader_wrapper_xkbcommon)(struct xkb_state*,const char*,enum xkb_state_component); +int (*xkb_state_layout_index_is_active_dylibloader_wrapper_xkbcommon)(struct xkb_state*, xkb_layout_index_t,enum xkb_state_component); +int (*xkb_state_led_name_is_active_dylibloader_wrapper_xkbcommon)(struct xkb_state*,const char*); +int (*xkb_state_led_index_is_active_dylibloader_wrapper_xkbcommon)(struct xkb_state*, xkb_led_index_t); +struct xkb_compose_table* (*xkb_compose_table_new_from_locale_dylibloader_wrapper_xkbcommon)(struct xkb_context*,const char*,enum xkb_compose_compile_flags); +struct xkb_compose_table* (*xkb_compose_table_new_from_file_dylibloader_wrapper_xkbcommon)(struct xkb_context*, FILE*,const char*,enum xkb_compose_format,enum xkb_compose_compile_flags); +struct xkb_compose_table* (*xkb_compose_table_new_from_buffer_dylibloader_wrapper_xkbcommon)(struct xkb_context*,const char*, size_t,const char*,enum xkb_compose_format,enum xkb_compose_compile_flags); +struct xkb_compose_table* (*xkb_compose_table_ref_dylibloader_wrapper_xkbcommon)(struct xkb_compose_table*); +void (*xkb_compose_table_unref_dylibloader_wrapper_xkbcommon)(struct xkb_compose_table*); +struct xkb_compose_state* (*xkb_compose_state_new_dylibloader_wrapper_xkbcommon)(struct xkb_compose_table*,enum xkb_compose_state_flags); +struct xkb_compose_state* (*xkb_compose_state_ref_dylibloader_wrapper_xkbcommon)(struct xkb_compose_state*); +void (*xkb_compose_state_unref_dylibloader_wrapper_xkbcommon)(struct xkb_compose_state*); +struct xkb_compose_table* (*xkb_compose_state_get_compose_table_dylibloader_wrapper_xkbcommon)(struct xkb_compose_state*); +enum xkb_compose_feed_result (*xkb_compose_state_feed_dylibloader_wrapper_xkbcommon)(struct xkb_compose_state*, xkb_keysym_t); +void (*xkb_compose_state_reset_dylibloader_wrapper_xkbcommon)(struct xkb_compose_state*); +enum xkb_compose_status (*xkb_compose_state_get_status_dylibloader_wrapper_xkbcommon)(struct xkb_compose_state*); +int (*xkb_compose_state_get_utf8_dylibloader_wrapper_xkbcommon)(struct xkb_compose_state*, char*, size_t); +xkb_keysym_t (*xkb_compose_state_get_one_sym_dylibloader_wrapper_xkbcommon)(struct xkb_compose_state*); +int initialize_xkbcommon(int verbose) { + void *handle; + char *error; + handle = dlopen("libxkbcommon.so.0", RTLD_LAZY); + if (!handle) { + if (verbose) { + fprintf(stderr, "%s\n", dlerror()); + } + return(1); + } + dlerror(); +// xkb_keysym_get_name + *(void **) (&xkb_keysym_get_name_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_keysym_get_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_keysym_from_name + *(void **) (&xkb_keysym_from_name_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_keysym_from_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_keysym_to_utf8 + *(void **) (&xkb_keysym_to_utf8_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_keysym_to_utf8"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_keysym_to_utf32 + *(void **) (&xkb_keysym_to_utf32_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_keysym_to_utf32"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_utf32_to_keysym + *(void **) (&xkb_utf32_to_keysym_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_utf32_to_keysym"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_keysym_to_upper + *(void **) (&xkb_keysym_to_upper_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_keysym_to_upper"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_keysym_to_lower + *(void **) (&xkb_keysym_to_lower_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_keysym_to_lower"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_context_new + *(void **) (&xkb_context_new_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_context_new"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_context_ref + *(void **) (&xkb_context_ref_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_context_ref"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_context_unref + *(void **) (&xkb_context_unref_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_context_unref"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_context_set_user_data + *(void **) (&xkb_context_set_user_data_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_context_set_user_data"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_context_get_user_data + *(void **) (&xkb_context_get_user_data_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_context_get_user_data"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_context_include_path_append + *(void **) (&xkb_context_include_path_append_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_context_include_path_append"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_context_include_path_append_default + *(void **) (&xkb_context_include_path_append_default_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_context_include_path_append_default"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_context_include_path_reset_defaults + *(void **) (&xkb_context_include_path_reset_defaults_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_context_include_path_reset_defaults"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_context_include_path_clear + *(void **) (&xkb_context_include_path_clear_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_context_include_path_clear"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_context_num_include_paths + *(void **) (&xkb_context_num_include_paths_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_context_num_include_paths"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_context_include_path_get + *(void **) (&xkb_context_include_path_get_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_context_include_path_get"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_context_set_log_level + *(void **) (&xkb_context_set_log_level_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_context_set_log_level"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_context_get_log_level + *(void **) (&xkb_context_get_log_level_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_context_get_log_level"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_context_set_log_verbosity + *(void **) (&xkb_context_set_log_verbosity_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_context_set_log_verbosity"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_context_get_log_verbosity + *(void **) (&xkb_context_get_log_verbosity_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_context_get_log_verbosity"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_context_set_log_fn + *(void **) (&xkb_context_set_log_fn_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_context_set_log_fn"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_keymap_new_from_names + *(void **) (&xkb_keymap_new_from_names_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_keymap_new_from_names"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_keymap_new_from_file + *(void **) (&xkb_keymap_new_from_file_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_keymap_new_from_file"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_keymap_new_from_string + *(void **) (&xkb_keymap_new_from_string_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_keymap_new_from_string"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_keymap_new_from_buffer + *(void **) (&xkb_keymap_new_from_buffer_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_keymap_new_from_buffer"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_keymap_ref + *(void **) (&xkb_keymap_ref_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_keymap_ref"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_keymap_unref + *(void **) (&xkb_keymap_unref_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_keymap_unref"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_keymap_get_as_string + *(void **) (&xkb_keymap_get_as_string_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_keymap_get_as_string"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_keymap_min_keycode + *(void **) (&xkb_keymap_min_keycode_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_keymap_min_keycode"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_keymap_max_keycode + *(void **) (&xkb_keymap_max_keycode_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_keymap_max_keycode"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_keymap_key_for_each + *(void **) (&xkb_keymap_key_for_each_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_keymap_key_for_each"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_keymap_key_get_name + *(void **) (&xkb_keymap_key_get_name_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_keymap_key_get_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_keymap_key_by_name + *(void **) (&xkb_keymap_key_by_name_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_keymap_key_by_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_keymap_num_mods + *(void **) (&xkb_keymap_num_mods_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_keymap_num_mods"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_keymap_mod_get_name + *(void **) (&xkb_keymap_mod_get_name_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_keymap_mod_get_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_keymap_mod_get_index + *(void **) (&xkb_keymap_mod_get_index_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_keymap_mod_get_index"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_keymap_num_layouts + *(void **) (&xkb_keymap_num_layouts_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_keymap_num_layouts"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_keymap_layout_get_name + *(void **) (&xkb_keymap_layout_get_name_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_keymap_layout_get_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_keymap_layout_get_index + *(void **) (&xkb_keymap_layout_get_index_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_keymap_layout_get_index"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_keymap_num_leds + *(void **) (&xkb_keymap_num_leds_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_keymap_num_leds"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_keymap_led_get_name + *(void **) (&xkb_keymap_led_get_name_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_keymap_led_get_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_keymap_led_get_index + *(void **) (&xkb_keymap_led_get_index_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_keymap_led_get_index"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_keymap_num_layouts_for_key + *(void **) (&xkb_keymap_num_layouts_for_key_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_keymap_num_layouts_for_key"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_keymap_num_levels_for_key + *(void **) (&xkb_keymap_num_levels_for_key_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_keymap_num_levels_for_key"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_keymap_key_get_mods_for_level + *(void **) (&xkb_keymap_key_get_mods_for_level_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_keymap_key_get_mods_for_level"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_keymap_key_get_syms_by_level + *(void **) (&xkb_keymap_key_get_syms_by_level_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_keymap_key_get_syms_by_level"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_keymap_key_repeats + *(void **) (&xkb_keymap_key_repeats_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_keymap_key_repeats"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_state_new + *(void **) (&xkb_state_new_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_state_new"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_state_ref + *(void **) (&xkb_state_ref_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_state_ref"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_state_unref + *(void **) (&xkb_state_unref_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_state_unref"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_state_get_keymap + *(void **) (&xkb_state_get_keymap_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_state_get_keymap"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_state_update_key + *(void **) (&xkb_state_update_key_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_state_update_key"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_state_update_mask + *(void **) (&xkb_state_update_mask_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_state_update_mask"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_state_key_get_syms + *(void **) (&xkb_state_key_get_syms_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_state_key_get_syms"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_state_key_get_utf8 + *(void **) (&xkb_state_key_get_utf8_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_state_key_get_utf8"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_state_key_get_utf32 + *(void **) (&xkb_state_key_get_utf32_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_state_key_get_utf32"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_state_key_get_one_sym + *(void **) (&xkb_state_key_get_one_sym_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_state_key_get_one_sym"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_state_key_get_layout + *(void **) (&xkb_state_key_get_layout_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_state_key_get_layout"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_state_key_get_level + *(void **) (&xkb_state_key_get_level_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_state_key_get_level"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_state_serialize_mods + *(void **) (&xkb_state_serialize_mods_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_state_serialize_mods"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_state_serialize_layout + *(void **) (&xkb_state_serialize_layout_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_state_serialize_layout"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_state_mod_name_is_active + *(void **) (&xkb_state_mod_name_is_active_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_state_mod_name_is_active"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_state_mod_names_are_active + *(void **) (&xkb_state_mod_names_are_active_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_state_mod_names_are_active"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_state_mod_index_is_active + *(void **) (&xkb_state_mod_index_is_active_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_state_mod_index_is_active"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_state_mod_indices_are_active + *(void **) (&xkb_state_mod_indices_are_active_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_state_mod_indices_are_active"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_state_key_get_consumed_mods2 + *(void **) (&xkb_state_key_get_consumed_mods2_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_state_key_get_consumed_mods2"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_state_key_get_consumed_mods + *(void **) (&xkb_state_key_get_consumed_mods_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_state_key_get_consumed_mods"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_state_mod_index_is_consumed2 + *(void **) (&xkb_state_mod_index_is_consumed2_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_state_mod_index_is_consumed2"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_state_mod_index_is_consumed + *(void **) (&xkb_state_mod_index_is_consumed_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_state_mod_index_is_consumed"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_state_mod_mask_remove_consumed + *(void **) (&xkb_state_mod_mask_remove_consumed_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_state_mod_mask_remove_consumed"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_state_layout_name_is_active + *(void **) (&xkb_state_layout_name_is_active_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_state_layout_name_is_active"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_state_layout_index_is_active + *(void **) (&xkb_state_layout_index_is_active_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_state_layout_index_is_active"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_state_led_name_is_active + *(void **) (&xkb_state_led_name_is_active_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_state_led_name_is_active"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_state_led_index_is_active + *(void **) (&xkb_state_led_index_is_active_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_state_led_index_is_active"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_compose_table_new_from_locale + *(void **) (&xkb_compose_table_new_from_locale_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_compose_table_new_from_locale"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_compose_table_new_from_file + *(void **) (&xkb_compose_table_new_from_file_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_compose_table_new_from_file"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_compose_table_new_from_buffer + *(void **) (&xkb_compose_table_new_from_buffer_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_compose_table_new_from_buffer"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_compose_table_ref + *(void **) (&xkb_compose_table_ref_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_compose_table_ref"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_compose_table_unref + *(void **) (&xkb_compose_table_unref_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_compose_table_unref"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_compose_state_new + *(void **) (&xkb_compose_state_new_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_compose_state_new"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_compose_state_ref + *(void **) (&xkb_compose_state_ref_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_compose_state_ref"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_compose_state_unref + *(void **) (&xkb_compose_state_unref_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_compose_state_unref"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_compose_state_get_compose_table + *(void **) (&xkb_compose_state_get_compose_table_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_compose_state_get_compose_table"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_compose_state_feed + *(void **) (&xkb_compose_state_feed_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_compose_state_feed"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_compose_state_reset + *(void **) (&xkb_compose_state_reset_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_compose_state_reset"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_compose_state_get_status + *(void **) (&xkb_compose_state_get_status_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_compose_state_get_status"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_compose_state_get_utf8 + *(void **) (&xkb_compose_state_get_utf8_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_compose_state_get_utf8"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// xkb_compose_state_get_one_sym + *(void **) (&xkb_compose_state_get_one_sym_dylibloader_wrapper_xkbcommon) = dlsym(handle, "xkb_compose_state_get_one_sym"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +return 0; +} diff --git a/platform/linuxbsd/xkbcommon-so_wrap.h b/platform/linuxbsd/xkbcommon-so_wrap.h new file mode 100644 index 0000000000..4ae69fdf1f --- /dev/null +++ b/platform/linuxbsd/xkbcommon-so_wrap.h @@ -0,0 +1,380 @@ +#ifndef DYLIBLOAD_WRAPPER_XKBCOMMON +#define DYLIBLOAD_WRAPPER_XKBCOMMON +// This file is generated. Do not edit! +// see https://github.com/hpvb/dynload-wrapper for details +// generated by generate-wrapper.py 0.3 on 2023-01-30 10:40:26 +// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/xkbcommon/xkbcommon.h --include ./thirdparty/linuxbsd_headers/xkbcommon/xkbcommon-compose.h --include ./thirdparty/linuxbsd_headers/xkbcommon/xkbcommon-keysyms.h --sys-include "./thirdparty/linuxbsd_headers/xkbcommon/xkbcommon.h" --sys-include "./thirdparty/linuxbsd_headers/xkbcommon/xkbcommon-compose.h" --sys-include "./thirdparty/linuxbsd_headers/xkbcommon/xkbcommon-keysyms.h" --soname libxkbcommon.so.0 --init-name xkbcommon --output-header ./platform/linuxbsd/xkbcommon-so_wrap.h --output-implementation ./platform/linuxbsd/xkbcommon-so_wrap.c +// +#include <stdint.h> + +#define xkb_keysym_get_name xkb_keysym_get_name_dylibloader_orig_xkbcommon +#define xkb_keysym_from_name xkb_keysym_from_name_dylibloader_orig_xkbcommon +#define xkb_keysym_to_utf8 xkb_keysym_to_utf8_dylibloader_orig_xkbcommon +#define xkb_keysym_to_utf32 xkb_keysym_to_utf32_dylibloader_orig_xkbcommon +#define xkb_utf32_to_keysym xkb_utf32_to_keysym_dylibloader_orig_xkbcommon +#define xkb_keysym_to_upper xkb_keysym_to_upper_dylibloader_orig_xkbcommon +#define xkb_keysym_to_lower xkb_keysym_to_lower_dylibloader_orig_xkbcommon +#define xkb_context_new xkb_context_new_dylibloader_orig_xkbcommon +#define xkb_context_ref xkb_context_ref_dylibloader_orig_xkbcommon +#define xkb_context_unref xkb_context_unref_dylibloader_orig_xkbcommon +#define xkb_context_set_user_data xkb_context_set_user_data_dylibloader_orig_xkbcommon +#define xkb_context_get_user_data xkb_context_get_user_data_dylibloader_orig_xkbcommon +#define xkb_context_include_path_append xkb_context_include_path_append_dylibloader_orig_xkbcommon +#define xkb_context_include_path_append_default xkb_context_include_path_append_default_dylibloader_orig_xkbcommon +#define xkb_context_include_path_reset_defaults xkb_context_include_path_reset_defaults_dylibloader_orig_xkbcommon +#define xkb_context_include_path_clear xkb_context_include_path_clear_dylibloader_orig_xkbcommon +#define xkb_context_num_include_paths xkb_context_num_include_paths_dylibloader_orig_xkbcommon +#define xkb_context_include_path_get xkb_context_include_path_get_dylibloader_orig_xkbcommon +#define xkb_context_set_log_level xkb_context_set_log_level_dylibloader_orig_xkbcommon +#define xkb_context_get_log_level xkb_context_get_log_level_dylibloader_orig_xkbcommon +#define xkb_context_set_log_verbosity xkb_context_set_log_verbosity_dylibloader_orig_xkbcommon +#define xkb_context_get_log_verbosity xkb_context_get_log_verbosity_dylibloader_orig_xkbcommon +#define xkb_context_set_log_fn xkb_context_set_log_fn_dylibloader_orig_xkbcommon +#define xkb_keymap_new_from_names xkb_keymap_new_from_names_dylibloader_orig_xkbcommon +#define xkb_keymap_new_from_file xkb_keymap_new_from_file_dylibloader_orig_xkbcommon +#define xkb_keymap_new_from_string xkb_keymap_new_from_string_dylibloader_orig_xkbcommon +#define xkb_keymap_new_from_buffer xkb_keymap_new_from_buffer_dylibloader_orig_xkbcommon +#define xkb_keymap_ref xkb_keymap_ref_dylibloader_orig_xkbcommon +#define xkb_keymap_unref xkb_keymap_unref_dylibloader_orig_xkbcommon +#define xkb_keymap_get_as_string xkb_keymap_get_as_string_dylibloader_orig_xkbcommon +#define xkb_keymap_min_keycode xkb_keymap_min_keycode_dylibloader_orig_xkbcommon +#define xkb_keymap_max_keycode xkb_keymap_max_keycode_dylibloader_orig_xkbcommon +#define xkb_keymap_key_for_each xkb_keymap_key_for_each_dylibloader_orig_xkbcommon +#define xkb_keymap_key_get_name xkb_keymap_key_get_name_dylibloader_orig_xkbcommon +#define xkb_keymap_key_by_name xkb_keymap_key_by_name_dylibloader_orig_xkbcommon +#define xkb_keymap_num_mods xkb_keymap_num_mods_dylibloader_orig_xkbcommon +#define xkb_keymap_mod_get_name xkb_keymap_mod_get_name_dylibloader_orig_xkbcommon +#define xkb_keymap_mod_get_index xkb_keymap_mod_get_index_dylibloader_orig_xkbcommon +#define xkb_keymap_num_layouts xkb_keymap_num_layouts_dylibloader_orig_xkbcommon +#define xkb_keymap_layout_get_name xkb_keymap_layout_get_name_dylibloader_orig_xkbcommon +#define xkb_keymap_layout_get_index xkb_keymap_layout_get_index_dylibloader_orig_xkbcommon +#define xkb_keymap_num_leds xkb_keymap_num_leds_dylibloader_orig_xkbcommon +#define xkb_keymap_led_get_name xkb_keymap_led_get_name_dylibloader_orig_xkbcommon +#define xkb_keymap_led_get_index xkb_keymap_led_get_index_dylibloader_orig_xkbcommon +#define xkb_keymap_num_layouts_for_key xkb_keymap_num_layouts_for_key_dylibloader_orig_xkbcommon +#define xkb_keymap_num_levels_for_key xkb_keymap_num_levels_for_key_dylibloader_orig_xkbcommon +#define xkb_keymap_key_get_mods_for_level xkb_keymap_key_get_mods_for_level_dylibloader_orig_xkbcommon +#define xkb_keymap_key_get_syms_by_level xkb_keymap_key_get_syms_by_level_dylibloader_orig_xkbcommon +#define xkb_keymap_key_repeats xkb_keymap_key_repeats_dylibloader_orig_xkbcommon +#define xkb_state_new xkb_state_new_dylibloader_orig_xkbcommon +#define xkb_state_ref xkb_state_ref_dylibloader_orig_xkbcommon +#define xkb_state_unref xkb_state_unref_dylibloader_orig_xkbcommon +#define xkb_state_get_keymap xkb_state_get_keymap_dylibloader_orig_xkbcommon +#define xkb_state_update_key xkb_state_update_key_dylibloader_orig_xkbcommon +#define xkb_state_update_mask xkb_state_update_mask_dylibloader_orig_xkbcommon +#define xkb_state_key_get_syms xkb_state_key_get_syms_dylibloader_orig_xkbcommon +#define xkb_state_key_get_utf8 xkb_state_key_get_utf8_dylibloader_orig_xkbcommon +#define xkb_state_key_get_utf32 xkb_state_key_get_utf32_dylibloader_orig_xkbcommon +#define xkb_state_key_get_one_sym xkb_state_key_get_one_sym_dylibloader_orig_xkbcommon +#define xkb_state_key_get_layout xkb_state_key_get_layout_dylibloader_orig_xkbcommon +#define xkb_state_key_get_level xkb_state_key_get_level_dylibloader_orig_xkbcommon +#define xkb_state_serialize_mods xkb_state_serialize_mods_dylibloader_orig_xkbcommon +#define xkb_state_serialize_layout xkb_state_serialize_layout_dylibloader_orig_xkbcommon +#define xkb_state_mod_name_is_active xkb_state_mod_name_is_active_dylibloader_orig_xkbcommon +#define xkb_state_mod_names_are_active xkb_state_mod_names_are_active_dylibloader_orig_xkbcommon +#define xkb_state_mod_index_is_active xkb_state_mod_index_is_active_dylibloader_orig_xkbcommon +#define xkb_state_mod_indices_are_active xkb_state_mod_indices_are_active_dylibloader_orig_xkbcommon +#define xkb_state_key_get_consumed_mods2 xkb_state_key_get_consumed_mods2_dylibloader_orig_xkbcommon +#define xkb_state_key_get_consumed_mods xkb_state_key_get_consumed_mods_dylibloader_orig_xkbcommon +#define xkb_state_mod_index_is_consumed2 xkb_state_mod_index_is_consumed2_dylibloader_orig_xkbcommon +#define xkb_state_mod_index_is_consumed xkb_state_mod_index_is_consumed_dylibloader_orig_xkbcommon +#define xkb_state_mod_mask_remove_consumed xkb_state_mod_mask_remove_consumed_dylibloader_orig_xkbcommon +#define xkb_state_layout_name_is_active xkb_state_layout_name_is_active_dylibloader_orig_xkbcommon +#define xkb_state_layout_index_is_active xkb_state_layout_index_is_active_dylibloader_orig_xkbcommon +#define xkb_state_led_name_is_active xkb_state_led_name_is_active_dylibloader_orig_xkbcommon +#define xkb_state_led_index_is_active xkb_state_led_index_is_active_dylibloader_orig_xkbcommon +#define xkb_compose_table_new_from_locale xkb_compose_table_new_from_locale_dylibloader_orig_xkbcommon +#define xkb_compose_table_new_from_file xkb_compose_table_new_from_file_dylibloader_orig_xkbcommon +#define xkb_compose_table_new_from_buffer xkb_compose_table_new_from_buffer_dylibloader_orig_xkbcommon +#define xkb_compose_table_ref xkb_compose_table_ref_dylibloader_orig_xkbcommon +#define xkb_compose_table_unref xkb_compose_table_unref_dylibloader_orig_xkbcommon +#define xkb_compose_state_new xkb_compose_state_new_dylibloader_orig_xkbcommon +#define xkb_compose_state_ref xkb_compose_state_ref_dylibloader_orig_xkbcommon +#define xkb_compose_state_unref xkb_compose_state_unref_dylibloader_orig_xkbcommon +#define xkb_compose_state_get_compose_table xkb_compose_state_get_compose_table_dylibloader_orig_xkbcommon +#define xkb_compose_state_feed xkb_compose_state_feed_dylibloader_orig_xkbcommon +#define xkb_compose_state_reset xkb_compose_state_reset_dylibloader_orig_xkbcommon +#define xkb_compose_state_get_status xkb_compose_state_get_status_dylibloader_orig_xkbcommon +#define xkb_compose_state_get_utf8 xkb_compose_state_get_utf8_dylibloader_orig_xkbcommon +#define xkb_compose_state_get_one_sym xkb_compose_state_get_one_sym_dylibloader_orig_xkbcommon +#include "./thirdparty/linuxbsd_headers/xkbcommon/xkbcommon.h" +#include "./thirdparty/linuxbsd_headers/xkbcommon/xkbcommon-compose.h" +#include "./thirdparty/linuxbsd_headers/xkbcommon/xkbcommon-keysyms.h" +#undef xkb_keysym_get_name +#undef xkb_keysym_from_name +#undef xkb_keysym_to_utf8 +#undef xkb_keysym_to_utf32 +#undef xkb_utf32_to_keysym +#undef xkb_keysym_to_upper +#undef xkb_keysym_to_lower +#undef xkb_context_new +#undef xkb_context_ref +#undef xkb_context_unref +#undef xkb_context_set_user_data +#undef xkb_context_get_user_data +#undef xkb_context_include_path_append +#undef xkb_context_include_path_append_default +#undef xkb_context_include_path_reset_defaults +#undef xkb_context_include_path_clear +#undef xkb_context_num_include_paths +#undef xkb_context_include_path_get +#undef xkb_context_set_log_level +#undef xkb_context_get_log_level +#undef xkb_context_set_log_verbosity +#undef xkb_context_get_log_verbosity +#undef xkb_context_set_log_fn +#undef xkb_keymap_new_from_names +#undef xkb_keymap_new_from_file +#undef xkb_keymap_new_from_string +#undef xkb_keymap_new_from_buffer +#undef xkb_keymap_ref +#undef xkb_keymap_unref +#undef xkb_keymap_get_as_string +#undef xkb_keymap_min_keycode +#undef xkb_keymap_max_keycode +#undef xkb_keymap_key_for_each +#undef xkb_keymap_key_get_name +#undef xkb_keymap_key_by_name +#undef xkb_keymap_num_mods +#undef xkb_keymap_mod_get_name +#undef xkb_keymap_mod_get_index +#undef xkb_keymap_num_layouts +#undef xkb_keymap_layout_get_name +#undef xkb_keymap_layout_get_index +#undef xkb_keymap_num_leds +#undef xkb_keymap_led_get_name +#undef xkb_keymap_led_get_index +#undef xkb_keymap_num_layouts_for_key +#undef xkb_keymap_num_levels_for_key +#undef xkb_keymap_key_get_mods_for_level +#undef xkb_keymap_key_get_syms_by_level +#undef xkb_keymap_key_repeats +#undef xkb_state_new +#undef xkb_state_ref +#undef xkb_state_unref +#undef xkb_state_get_keymap +#undef xkb_state_update_key +#undef xkb_state_update_mask +#undef xkb_state_key_get_syms +#undef xkb_state_key_get_utf8 +#undef xkb_state_key_get_utf32 +#undef xkb_state_key_get_one_sym +#undef xkb_state_key_get_layout +#undef xkb_state_key_get_level +#undef xkb_state_serialize_mods +#undef xkb_state_serialize_layout +#undef xkb_state_mod_name_is_active +#undef xkb_state_mod_names_are_active +#undef xkb_state_mod_index_is_active +#undef xkb_state_mod_indices_are_active +#undef xkb_state_key_get_consumed_mods2 +#undef xkb_state_key_get_consumed_mods +#undef xkb_state_mod_index_is_consumed2 +#undef xkb_state_mod_index_is_consumed +#undef xkb_state_mod_mask_remove_consumed +#undef xkb_state_layout_name_is_active +#undef xkb_state_layout_index_is_active +#undef xkb_state_led_name_is_active +#undef xkb_state_led_index_is_active +#undef xkb_compose_table_new_from_locale +#undef xkb_compose_table_new_from_file +#undef xkb_compose_table_new_from_buffer +#undef xkb_compose_table_ref +#undef xkb_compose_table_unref +#undef xkb_compose_state_new +#undef xkb_compose_state_ref +#undef xkb_compose_state_unref +#undef xkb_compose_state_get_compose_table +#undef xkb_compose_state_feed +#undef xkb_compose_state_reset +#undef xkb_compose_state_get_status +#undef xkb_compose_state_get_utf8 +#undef xkb_compose_state_get_one_sym +#ifdef __cplusplus +extern "C" { +#endif +#define xkb_keysym_get_name xkb_keysym_get_name_dylibloader_wrapper_xkbcommon +#define xkb_keysym_from_name xkb_keysym_from_name_dylibloader_wrapper_xkbcommon +#define xkb_keysym_to_utf8 xkb_keysym_to_utf8_dylibloader_wrapper_xkbcommon +#define xkb_keysym_to_utf32 xkb_keysym_to_utf32_dylibloader_wrapper_xkbcommon +#define xkb_utf32_to_keysym xkb_utf32_to_keysym_dylibloader_wrapper_xkbcommon +#define xkb_keysym_to_upper xkb_keysym_to_upper_dylibloader_wrapper_xkbcommon +#define xkb_keysym_to_lower xkb_keysym_to_lower_dylibloader_wrapper_xkbcommon +#define xkb_context_new xkb_context_new_dylibloader_wrapper_xkbcommon +#define xkb_context_ref xkb_context_ref_dylibloader_wrapper_xkbcommon +#define xkb_context_unref xkb_context_unref_dylibloader_wrapper_xkbcommon +#define xkb_context_set_user_data xkb_context_set_user_data_dylibloader_wrapper_xkbcommon +#define xkb_context_get_user_data xkb_context_get_user_data_dylibloader_wrapper_xkbcommon +#define xkb_context_include_path_append xkb_context_include_path_append_dylibloader_wrapper_xkbcommon +#define xkb_context_include_path_append_default xkb_context_include_path_append_default_dylibloader_wrapper_xkbcommon +#define xkb_context_include_path_reset_defaults xkb_context_include_path_reset_defaults_dylibloader_wrapper_xkbcommon +#define xkb_context_include_path_clear xkb_context_include_path_clear_dylibloader_wrapper_xkbcommon +#define xkb_context_num_include_paths xkb_context_num_include_paths_dylibloader_wrapper_xkbcommon +#define xkb_context_include_path_get xkb_context_include_path_get_dylibloader_wrapper_xkbcommon +#define xkb_context_set_log_level xkb_context_set_log_level_dylibloader_wrapper_xkbcommon +#define xkb_context_get_log_level xkb_context_get_log_level_dylibloader_wrapper_xkbcommon +#define xkb_context_set_log_verbosity xkb_context_set_log_verbosity_dylibloader_wrapper_xkbcommon +#define xkb_context_get_log_verbosity xkb_context_get_log_verbosity_dylibloader_wrapper_xkbcommon +#define xkb_context_set_log_fn xkb_context_set_log_fn_dylibloader_wrapper_xkbcommon +#define xkb_keymap_new_from_names xkb_keymap_new_from_names_dylibloader_wrapper_xkbcommon +#define xkb_keymap_new_from_file xkb_keymap_new_from_file_dylibloader_wrapper_xkbcommon +#define xkb_keymap_new_from_string xkb_keymap_new_from_string_dylibloader_wrapper_xkbcommon +#define xkb_keymap_new_from_buffer xkb_keymap_new_from_buffer_dylibloader_wrapper_xkbcommon +#define xkb_keymap_ref xkb_keymap_ref_dylibloader_wrapper_xkbcommon +#define xkb_keymap_unref xkb_keymap_unref_dylibloader_wrapper_xkbcommon +#define xkb_keymap_get_as_string xkb_keymap_get_as_string_dylibloader_wrapper_xkbcommon +#define xkb_keymap_min_keycode xkb_keymap_min_keycode_dylibloader_wrapper_xkbcommon +#define xkb_keymap_max_keycode xkb_keymap_max_keycode_dylibloader_wrapper_xkbcommon +#define xkb_keymap_key_for_each xkb_keymap_key_for_each_dylibloader_wrapper_xkbcommon +#define xkb_keymap_key_get_name xkb_keymap_key_get_name_dylibloader_wrapper_xkbcommon +#define xkb_keymap_key_by_name xkb_keymap_key_by_name_dylibloader_wrapper_xkbcommon +#define xkb_keymap_num_mods xkb_keymap_num_mods_dylibloader_wrapper_xkbcommon +#define xkb_keymap_mod_get_name xkb_keymap_mod_get_name_dylibloader_wrapper_xkbcommon +#define xkb_keymap_mod_get_index xkb_keymap_mod_get_index_dylibloader_wrapper_xkbcommon +#define xkb_keymap_num_layouts xkb_keymap_num_layouts_dylibloader_wrapper_xkbcommon +#define xkb_keymap_layout_get_name xkb_keymap_layout_get_name_dylibloader_wrapper_xkbcommon +#define xkb_keymap_layout_get_index xkb_keymap_layout_get_index_dylibloader_wrapper_xkbcommon +#define xkb_keymap_num_leds xkb_keymap_num_leds_dylibloader_wrapper_xkbcommon +#define xkb_keymap_led_get_name xkb_keymap_led_get_name_dylibloader_wrapper_xkbcommon +#define xkb_keymap_led_get_index xkb_keymap_led_get_index_dylibloader_wrapper_xkbcommon +#define xkb_keymap_num_layouts_for_key xkb_keymap_num_layouts_for_key_dylibloader_wrapper_xkbcommon +#define xkb_keymap_num_levels_for_key xkb_keymap_num_levels_for_key_dylibloader_wrapper_xkbcommon +#define xkb_keymap_key_get_mods_for_level xkb_keymap_key_get_mods_for_level_dylibloader_wrapper_xkbcommon +#define xkb_keymap_key_get_syms_by_level xkb_keymap_key_get_syms_by_level_dylibloader_wrapper_xkbcommon +#define xkb_keymap_key_repeats xkb_keymap_key_repeats_dylibloader_wrapper_xkbcommon +#define xkb_state_new xkb_state_new_dylibloader_wrapper_xkbcommon +#define xkb_state_ref xkb_state_ref_dylibloader_wrapper_xkbcommon +#define xkb_state_unref xkb_state_unref_dylibloader_wrapper_xkbcommon +#define xkb_state_get_keymap xkb_state_get_keymap_dylibloader_wrapper_xkbcommon +#define xkb_state_update_key xkb_state_update_key_dylibloader_wrapper_xkbcommon +#define xkb_state_update_mask xkb_state_update_mask_dylibloader_wrapper_xkbcommon +#define xkb_state_key_get_syms xkb_state_key_get_syms_dylibloader_wrapper_xkbcommon +#define xkb_state_key_get_utf8 xkb_state_key_get_utf8_dylibloader_wrapper_xkbcommon +#define xkb_state_key_get_utf32 xkb_state_key_get_utf32_dylibloader_wrapper_xkbcommon +#define xkb_state_key_get_one_sym xkb_state_key_get_one_sym_dylibloader_wrapper_xkbcommon +#define xkb_state_key_get_layout xkb_state_key_get_layout_dylibloader_wrapper_xkbcommon +#define xkb_state_key_get_level xkb_state_key_get_level_dylibloader_wrapper_xkbcommon +#define xkb_state_serialize_mods xkb_state_serialize_mods_dylibloader_wrapper_xkbcommon +#define xkb_state_serialize_layout xkb_state_serialize_layout_dylibloader_wrapper_xkbcommon +#define xkb_state_mod_name_is_active xkb_state_mod_name_is_active_dylibloader_wrapper_xkbcommon +#define xkb_state_mod_names_are_active xkb_state_mod_names_are_active_dylibloader_wrapper_xkbcommon +#define xkb_state_mod_index_is_active xkb_state_mod_index_is_active_dylibloader_wrapper_xkbcommon +#define xkb_state_mod_indices_are_active xkb_state_mod_indices_are_active_dylibloader_wrapper_xkbcommon +#define xkb_state_key_get_consumed_mods2 xkb_state_key_get_consumed_mods2_dylibloader_wrapper_xkbcommon +#define xkb_state_key_get_consumed_mods xkb_state_key_get_consumed_mods_dylibloader_wrapper_xkbcommon +#define xkb_state_mod_index_is_consumed2 xkb_state_mod_index_is_consumed2_dylibloader_wrapper_xkbcommon +#define xkb_state_mod_index_is_consumed xkb_state_mod_index_is_consumed_dylibloader_wrapper_xkbcommon +#define xkb_state_mod_mask_remove_consumed xkb_state_mod_mask_remove_consumed_dylibloader_wrapper_xkbcommon +#define xkb_state_layout_name_is_active xkb_state_layout_name_is_active_dylibloader_wrapper_xkbcommon +#define xkb_state_layout_index_is_active xkb_state_layout_index_is_active_dylibloader_wrapper_xkbcommon +#define xkb_state_led_name_is_active xkb_state_led_name_is_active_dylibloader_wrapper_xkbcommon +#define xkb_state_led_index_is_active xkb_state_led_index_is_active_dylibloader_wrapper_xkbcommon +#define xkb_compose_table_new_from_locale xkb_compose_table_new_from_locale_dylibloader_wrapper_xkbcommon +#define xkb_compose_table_new_from_file xkb_compose_table_new_from_file_dylibloader_wrapper_xkbcommon +#define xkb_compose_table_new_from_buffer xkb_compose_table_new_from_buffer_dylibloader_wrapper_xkbcommon +#define xkb_compose_table_ref xkb_compose_table_ref_dylibloader_wrapper_xkbcommon +#define xkb_compose_table_unref xkb_compose_table_unref_dylibloader_wrapper_xkbcommon +#define xkb_compose_state_new xkb_compose_state_new_dylibloader_wrapper_xkbcommon +#define xkb_compose_state_ref xkb_compose_state_ref_dylibloader_wrapper_xkbcommon +#define xkb_compose_state_unref xkb_compose_state_unref_dylibloader_wrapper_xkbcommon +#define xkb_compose_state_get_compose_table xkb_compose_state_get_compose_table_dylibloader_wrapper_xkbcommon +#define xkb_compose_state_feed xkb_compose_state_feed_dylibloader_wrapper_xkbcommon +#define xkb_compose_state_reset xkb_compose_state_reset_dylibloader_wrapper_xkbcommon +#define xkb_compose_state_get_status xkb_compose_state_get_status_dylibloader_wrapper_xkbcommon +#define xkb_compose_state_get_utf8 xkb_compose_state_get_utf8_dylibloader_wrapper_xkbcommon +#define xkb_compose_state_get_one_sym xkb_compose_state_get_one_sym_dylibloader_wrapper_xkbcommon +extern int (*xkb_keysym_get_name_dylibloader_wrapper_xkbcommon)( xkb_keysym_t, char*, size_t); +extern xkb_keysym_t (*xkb_keysym_from_name_dylibloader_wrapper_xkbcommon)(const char*,enum xkb_keysym_flags); +extern int (*xkb_keysym_to_utf8_dylibloader_wrapper_xkbcommon)( xkb_keysym_t, char*, size_t); +extern uint32_t (*xkb_keysym_to_utf32_dylibloader_wrapper_xkbcommon)( xkb_keysym_t); +extern xkb_keysym_t (*xkb_utf32_to_keysym_dylibloader_wrapper_xkbcommon)( uint32_t); +extern xkb_keysym_t (*xkb_keysym_to_upper_dylibloader_wrapper_xkbcommon)( xkb_keysym_t); +extern xkb_keysym_t (*xkb_keysym_to_lower_dylibloader_wrapper_xkbcommon)( xkb_keysym_t); +extern struct xkb_context* (*xkb_context_new_dylibloader_wrapper_xkbcommon)(enum xkb_context_flags); +extern struct xkb_context* (*xkb_context_ref_dylibloader_wrapper_xkbcommon)(struct xkb_context*); +extern void (*xkb_context_unref_dylibloader_wrapper_xkbcommon)(struct xkb_context*); +extern void (*xkb_context_set_user_data_dylibloader_wrapper_xkbcommon)(struct xkb_context*, void*); +extern void* (*xkb_context_get_user_data_dylibloader_wrapper_xkbcommon)(struct xkb_context*); +extern int (*xkb_context_include_path_append_dylibloader_wrapper_xkbcommon)(struct xkb_context*,const char*); +extern int (*xkb_context_include_path_append_default_dylibloader_wrapper_xkbcommon)(struct xkb_context*); +extern int (*xkb_context_include_path_reset_defaults_dylibloader_wrapper_xkbcommon)(struct xkb_context*); +extern void (*xkb_context_include_path_clear_dylibloader_wrapper_xkbcommon)(struct xkb_context*); +extern unsigned int (*xkb_context_num_include_paths_dylibloader_wrapper_xkbcommon)(struct xkb_context*); +extern const char* (*xkb_context_include_path_get_dylibloader_wrapper_xkbcommon)(struct xkb_context*, unsigned int); +extern void (*xkb_context_set_log_level_dylibloader_wrapper_xkbcommon)(struct xkb_context*,enum xkb_log_level); +extern enum xkb_log_level (*xkb_context_get_log_level_dylibloader_wrapper_xkbcommon)(struct xkb_context*); +extern void (*xkb_context_set_log_verbosity_dylibloader_wrapper_xkbcommon)(struct xkb_context*, int); +extern int (*xkb_context_get_log_verbosity_dylibloader_wrapper_xkbcommon)(struct xkb_context*); +extern void (*xkb_context_set_log_fn_dylibloader_wrapper_xkbcommon)(struct xkb_context*, void*); +extern struct xkb_keymap* (*xkb_keymap_new_from_names_dylibloader_wrapper_xkbcommon)(struct xkb_context*,struct xkb_rule_names*,enum xkb_keymap_compile_flags); +extern struct xkb_keymap* (*xkb_keymap_new_from_file_dylibloader_wrapper_xkbcommon)(struct xkb_context*, FILE*,enum xkb_keymap_format,enum xkb_keymap_compile_flags); +extern struct xkb_keymap* (*xkb_keymap_new_from_string_dylibloader_wrapper_xkbcommon)(struct xkb_context*,const char*,enum xkb_keymap_format,enum xkb_keymap_compile_flags); +extern struct xkb_keymap* (*xkb_keymap_new_from_buffer_dylibloader_wrapper_xkbcommon)(struct xkb_context*,const char*, size_t,enum xkb_keymap_format,enum xkb_keymap_compile_flags); +extern struct xkb_keymap* (*xkb_keymap_ref_dylibloader_wrapper_xkbcommon)(struct xkb_keymap*); +extern void (*xkb_keymap_unref_dylibloader_wrapper_xkbcommon)(struct xkb_keymap*); +extern char* (*xkb_keymap_get_as_string_dylibloader_wrapper_xkbcommon)(struct xkb_keymap*,enum xkb_keymap_format); +extern xkb_keycode_t (*xkb_keymap_min_keycode_dylibloader_wrapper_xkbcommon)(struct xkb_keymap*); +extern xkb_keycode_t (*xkb_keymap_max_keycode_dylibloader_wrapper_xkbcommon)(struct xkb_keymap*); +extern void (*xkb_keymap_key_for_each_dylibloader_wrapper_xkbcommon)(struct xkb_keymap*, xkb_keymap_key_iter_t, void*); +extern const char* (*xkb_keymap_key_get_name_dylibloader_wrapper_xkbcommon)(struct xkb_keymap*, xkb_keycode_t); +extern xkb_keycode_t (*xkb_keymap_key_by_name_dylibloader_wrapper_xkbcommon)(struct xkb_keymap*,const char*); +extern xkb_mod_index_t (*xkb_keymap_num_mods_dylibloader_wrapper_xkbcommon)(struct xkb_keymap*); +extern const char* (*xkb_keymap_mod_get_name_dylibloader_wrapper_xkbcommon)(struct xkb_keymap*, xkb_mod_index_t); +extern xkb_mod_index_t (*xkb_keymap_mod_get_index_dylibloader_wrapper_xkbcommon)(struct xkb_keymap*,const char*); +extern xkb_layout_index_t (*xkb_keymap_num_layouts_dylibloader_wrapper_xkbcommon)(struct xkb_keymap*); +extern const char* (*xkb_keymap_layout_get_name_dylibloader_wrapper_xkbcommon)(struct xkb_keymap*, xkb_layout_index_t); +extern xkb_layout_index_t (*xkb_keymap_layout_get_index_dylibloader_wrapper_xkbcommon)(struct xkb_keymap*,const char*); +extern xkb_led_index_t (*xkb_keymap_num_leds_dylibloader_wrapper_xkbcommon)(struct xkb_keymap*); +extern const char* (*xkb_keymap_led_get_name_dylibloader_wrapper_xkbcommon)(struct xkb_keymap*, xkb_led_index_t); +extern xkb_led_index_t (*xkb_keymap_led_get_index_dylibloader_wrapper_xkbcommon)(struct xkb_keymap*,const char*); +extern xkb_layout_index_t (*xkb_keymap_num_layouts_for_key_dylibloader_wrapper_xkbcommon)(struct xkb_keymap*, xkb_keycode_t); +extern xkb_level_index_t (*xkb_keymap_num_levels_for_key_dylibloader_wrapper_xkbcommon)(struct xkb_keymap*, xkb_keycode_t, xkb_layout_index_t); +extern size_t (*xkb_keymap_key_get_mods_for_level_dylibloader_wrapper_xkbcommon)(struct xkb_keymap*, xkb_keycode_t, xkb_layout_index_t, xkb_level_index_t, xkb_mod_mask_t*, size_t); +extern int (*xkb_keymap_key_get_syms_by_level_dylibloader_wrapper_xkbcommon)(struct xkb_keymap*, xkb_keycode_t, xkb_layout_index_t, xkb_level_index_t,const xkb_keysym_t**); +extern int (*xkb_keymap_key_repeats_dylibloader_wrapper_xkbcommon)(struct xkb_keymap*, xkb_keycode_t); +extern struct xkb_state* (*xkb_state_new_dylibloader_wrapper_xkbcommon)(struct xkb_keymap*); +extern struct xkb_state* (*xkb_state_ref_dylibloader_wrapper_xkbcommon)(struct xkb_state*); +extern void (*xkb_state_unref_dylibloader_wrapper_xkbcommon)(struct xkb_state*); +extern struct xkb_keymap* (*xkb_state_get_keymap_dylibloader_wrapper_xkbcommon)(struct xkb_state*); +extern enum xkb_state_component (*xkb_state_update_key_dylibloader_wrapper_xkbcommon)(struct xkb_state*, xkb_keycode_t,enum xkb_key_direction); +extern enum xkb_state_component (*xkb_state_update_mask_dylibloader_wrapper_xkbcommon)(struct xkb_state*, xkb_mod_mask_t, xkb_mod_mask_t, xkb_mod_mask_t, xkb_layout_index_t, xkb_layout_index_t, xkb_layout_index_t); +extern int (*xkb_state_key_get_syms_dylibloader_wrapper_xkbcommon)(struct xkb_state*, xkb_keycode_t,const xkb_keysym_t**); +extern int (*xkb_state_key_get_utf8_dylibloader_wrapper_xkbcommon)(struct xkb_state*, xkb_keycode_t, char*, size_t); +extern uint32_t (*xkb_state_key_get_utf32_dylibloader_wrapper_xkbcommon)(struct xkb_state*, xkb_keycode_t); +extern xkb_keysym_t (*xkb_state_key_get_one_sym_dylibloader_wrapper_xkbcommon)(struct xkb_state*, xkb_keycode_t); +extern xkb_layout_index_t (*xkb_state_key_get_layout_dylibloader_wrapper_xkbcommon)(struct xkb_state*, xkb_keycode_t); +extern xkb_level_index_t (*xkb_state_key_get_level_dylibloader_wrapper_xkbcommon)(struct xkb_state*, xkb_keycode_t, xkb_layout_index_t); +extern xkb_mod_mask_t (*xkb_state_serialize_mods_dylibloader_wrapper_xkbcommon)(struct xkb_state*,enum xkb_state_component); +extern xkb_layout_index_t (*xkb_state_serialize_layout_dylibloader_wrapper_xkbcommon)(struct xkb_state*,enum xkb_state_component); +extern int (*xkb_state_mod_name_is_active_dylibloader_wrapper_xkbcommon)(struct xkb_state*,const char*,enum xkb_state_component); +extern int (*xkb_state_mod_names_are_active_dylibloader_wrapper_xkbcommon)(struct xkb_state*,enum xkb_state_component,enum xkb_state_match,...); +extern int (*xkb_state_mod_index_is_active_dylibloader_wrapper_xkbcommon)(struct xkb_state*, xkb_mod_index_t,enum xkb_state_component); +extern int (*xkb_state_mod_indices_are_active_dylibloader_wrapper_xkbcommon)(struct xkb_state*,enum xkb_state_component,enum xkb_state_match,...); +extern xkb_mod_mask_t (*xkb_state_key_get_consumed_mods2_dylibloader_wrapper_xkbcommon)(struct xkb_state*, xkb_keycode_t,enum xkb_consumed_mode); +extern xkb_mod_mask_t (*xkb_state_key_get_consumed_mods_dylibloader_wrapper_xkbcommon)(struct xkb_state*, xkb_keycode_t); +extern int (*xkb_state_mod_index_is_consumed2_dylibloader_wrapper_xkbcommon)(struct xkb_state*, xkb_keycode_t, xkb_mod_index_t,enum xkb_consumed_mode); +extern int (*xkb_state_mod_index_is_consumed_dylibloader_wrapper_xkbcommon)(struct xkb_state*, xkb_keycode_t, xkb_mod_index_t); +extern xkb_mod_mask_t (*xkb_state_mod_mask_remove_consumed_dylibloader_wrapper_xkbcommon)(struct xkb_state*, xkb_keycode_t, xkb_mod_mask_t); +extern int (*xkb_state_layout_name_is_active_dylibloader_wrapper_xkbcommon)(struct xkb_state*,const char*,enum xkb_state_component); +extern int (*xkb_state_layout_index_is_active_dylibloader_wrapper_xkbcommon)(struct xkb_state*, xkb_layout_index_t,enum xkb_state_component); +extern int (*xkb_state_led_name_is_active_dylibloader_wrapper_xkbcommon)(struct xkb_state*,const char*); +extern int (*xkb_state_led_index_is_active_dylibloader_wrapper_xkbcommon)(struct xkb_state*, xkb_led_index_t); +extern struct xkb_compose_table* (*xkb_compose_table_new_from_locale_dylibloader_wrapper_xkbcommon)(struct xkb_context*,const char*,enum xkb_compose_compile_flags); +extern struct xkb_compose_table* (*xkb_compose_table_new_from_file_dylibloader_wrapper_xkbcommon)(struct xkb_context*, FILE*,const char*,enum xkb_compose_format,enum xkb_compose_compile_flags); +extern struct xkb_compose_table* (*xkb_compose_table_new_from_buffer_dylibloader_wrapper_xkbcommon)(struct xkb_context*,const char*, size_t,const char*,enum xkb_compose_format,enum xkb_compose_compile_flags); +extern struct xkb_compose_table* (*xkb_compose_table_ref_dylibloader_wrapper_xkbcommon)(struct xkb_compose_table*); +extern void (*xkb_compose_table_unref_dylibloader_wrapper_xkbcommon)(struct xkb_compose_table*); +extern struct xkb_compose_state* (*xkb_compose_state_new_dylibloader_wrapper_xkbcommon)(struct xkb_compose_table*,enum xkb_compose_state_flags); +extern struct xkb_compose_state* (*xkb_compose_state_ref_dylibloader_wrapper_xkbcommon)(struct xkb_compose_state*); +extern void (*xkb_compose_state_unref_dylibloader_wrapper_xkbcommon)(struct xkb_compose_state*); +extern struct xkb_compose_table* (*xkb_compose_state_get_compose_table_dylibloader_wrapper_xkbcommon)(struct xkb_compose_state*); +extern enum xkb_compose_feed_result (*xkb_compose_state_feed_dylibloader_wrapper_xkbcommon)(struct xkb_compose_state*, xkb_keysym_t); +extern void (*xkb_compose_state_reset_dylibloader_wrapper_xkbcommon)(struct xkb_compose_state*); +extern enum xkb_compose_status (*xkb_compose_state_get_status_dylibloader_wrapper_xkbcommon)(struct xkb_compose_state*); +extern int (*xkb_compose_state_get_utf8_dylibloader_wrapper_xkbcommon)(struct xkb_compose_state*, char*, size_t); +extern xkb_keysym_t (*xkb_compose_state_get_one_sym_dylibloader_wrapper_xkbcommon)(struct xkb_compose_state*); +int initialize_xkbcommon(int verbose); +#ifdef __cplusplus +} +#endif +#endif diff --git a/platform/macos/README.md b/platform/macos/README.md index feead80736..205c59e05d 100644 --- a/platform/macos/README.md +++ b/platform/macos/README.md @@ -11,7 +11,7 @@ packaging macOS export templates. ## Documentation -- [Compiling for macOS](https://docs.godotengine.org/en/latest/development/compiling/compiling_for_macos.html) +- [Compiling for macOS](https://docs.godotengine.org/en/latest/contributing/development/compiling/compiling_for_macos.html) - Instructions on building this platform port from source. - [Exporting for macOS](https://docs.godotengine.org/en/latest/tutorials/export/exporting_for_macos.html) - Instructions on using the compiled export templates to export a project. diff --git a/platform/macos/crash_handler_macos.h b/platform/macos/crash_handler_macos.h index c9b0e77dc4..f821283167 100644 --- a/platform/macos/crash_handler_macos.h +++ b/platform/macos/crash_handler_macos.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* crash_handler_macos.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* crash_handler_macos.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 CRASH_HANDLER_MACOS_H #define CRASH_HANDLER_MACOS_H diff --git a/platform/macos/crash_handler_macos.mm b/platform/macos/crash_handler_macos.mm index 74bd012f0c..7f9a88121e 100644 --- a/platform/macos/crash_handler_macos.mm +++ b/platform/macos/crash_handler_macos.mm @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* crash_handler_macos.mm */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* crash_handler_macos.mm */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "crash_handler_macos.h" diff --git a/platform/macos/detect.py b/platform/macos/detect.py index e73c5322ea..7b8d3fd853 100644 --- a/platform/macos/detect.py +++ b/platform/macos/detect.py @@ -39,6 +39,16 @@ def get_opts(): ] +def get_doc_classes(): + return [ + "EditorExportPlatformMacOS", + ] + + +def get_doc_path(): + return "doc_classes" + + def get_flags(): return [ ("arch", detect_arch()), @@ -108,10 +118,10 @@ def configure(env: "Environment"): env.Append(CCFLAGS=["-arch", "arm64", "-mmacosx-version-min=11.0"]) env.Append(LINKFLAGS=["-arch", "arm64", "-mmacosx-version-min=11.0"]) elif env["arch"] == "x86_64": - print("Building for macOS 10.12+.") - 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"]) + print("Building for macOS 10.13+.") + env.Append(ASFLAGS=["-arch", "x86_64", "-mmacosx-version-min=10.13"]) + env.Append(CCFLAGS=["-arch", "x86_64", "-mmacosx-version-min=10.13"]) + env.Append(LINKFLAGS=["-arch", "x86_64", "-mmacosx-version-min=10.13"]) env.Append(CCFLAGS=["-fobjc-arc"]) @@ -144,7 +154,7 @@ def configure(env: "Environment"): env["CC"] = basecmd + "cc" env["CXX"] = basecmd + "c++" else: - # there aren't any ccache wrappers available for OS X cross-compile, + # there aren't any ccache wrappers available for macOS cross-compile, # to enable caching we need to prepend the path to the ccache binary env["CC"] = ccache_path + " " + basecmd + "cc" env["CXX"] = ccache_path + " " + basecmd + "c++" @@ -225,13 +235,14 @@ def configure(env: "Environment"): "CoreMedia", "-framework", "QuartzCore", + "-framework", + "Security", ] ) env.Append(LIBS=["pthread", "z"]) if env["opengl3"]: - env.Append(CPPDEFINES=["GLES_ENABLED", "GLES3_ENABLED"]) - env.Append(CCFLAGS=["-Wno-deprecated-declarations"]) # Disable deprecation warnings + env.Append(CPPDEFINES=["GLES3_ENABLED"]) env.Append(LINKFLAGS=["-framework", "OpenGL"]) env.Append(LINKFLAGS=["-rpath", "@executable_path/../Frameworks", "-rpath", "@executable_path"]) @@ -242,18 +253,24 @@ def configure(env: "Environment"): if not env["use_volk"]: env.Append(LINKFLAGS=["-lMoltenVK"]) mvk_found = False + + mvk_list = [get_mvk_sdk_path(), "/opt/homebrew/lib", "/usr/local/homebrew/lib", "/opt/local/lib"] if env["vulkan_sdk_path"] != "": - mvk_path = os.path.join( - os.path.expanduser(env["vulkan_sdk_path"]), "MoltenVK/MoltenVK.xcframework/macos-arm64_x86_64/" + mvk_list.insert(0, os.path.expanduser(env["vulkan_sdk_path"])) + mvk_list.insert( + 0, + 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() + + for mvk_path in mvk_list: if mvk_path and os.path.isfile(os.path.join(mvk_path, "libMoltenVK.a")): mvk_found = True + print("MoltenVK found at: " + mvk_path) env.Append(LINKFLAGS=["-L" + mvk_path]) + break + if not mvk_found: print( "MoltenVK SDK installation directory not found, use 'vulkan_sdk_path' SCons parameter to specify SDK path." diff --git a/platform/macos/dir_access_macos.h b/platform/macos/dir_access_macos.h index c76b2835e8..64556999a7 100644 --- a/platform/macos/dir_access_macos.h +++ b/platform/macos/dir_access_macos.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* dir_access_macos.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* dir_access_macos.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 DIR_ACCESS_MACOS_H #define DIR_ACCESS_MACOS_H diff --git a/platform/macos/dir_access_macos.mm b/platform/macos/dir_access_macos.mm index 22ebac2db4..2413d7bcf3 100644 --- a/platform/macos/dir_access_macos.mm +++ b/platform/macos/dir_access_macos.mm @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* dir_access_macos.mm */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* dir_access_macos.mm */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "dir_access_macos.h" diff --git a/platform/macos/display_server_macos.h b/platform/macos/display_server_macos.h index 618da6b388..93fa93b259 100644 --- a/platform/macos/display_server_macos.h +++ b/platform/macos/display_server_macos.h @@ -1,38 +1,36 @@ -/*************************************************************************/ -/* display_server_macos.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* display_server_macos.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 DISPLAY_SERVER_MACOS_H #define DISPLAY_SERVER_MACOS_H -#define BitMap _QDBitMap // Suppress deprecated QuickDraw definition. - #include "core/input/input.h" #include "servers/display_server.h" @@ -41,10 +39,13 @@ #endif // GLES3_ENABLED #if defined(VULKAN_ENABLED) +#include "vulkan_context_macos.h" + #include "drivers/vulkan/rendering_device_vulkan.h" -#include "platform/macos/vulkan_context_macos.h" #endif // VULKAN_ENABLED +#define BitMap _QDBitMap // Suppress deprecated QuickDraw definition. + #import <AppKit/AppKit.h> #import <AppKit/NSCursor.h> #import <ApplicationServices/ApplicationServices.h> @@ -56,7 +57,7 @@ #undef CursorShape class DisplayServerMacOS : public DisplayServer { - GDCLASS(DisplayServerMacOS, DisplayServer) + // No need to register with GDCLASS, it's platform-specific and nothing is added. _THREAD_SAFE_CLASS_ @@ -69,6 +70,7 @@ public: bool raw = false; Key keycode = Key::NONE; Key physical_keycode = Key::NONE; + Key key_label = Key::NONE; uint32_t unicode = 0; }; @@ -99,6 +101,8 @@ public: Callable drop_files_callback; ObjectID instance_id; + bool fs_transition = false; + bool initial_size = true; WindowID transient_parent = INVALID_WINDOW_ID; bool exclusive = false; @@ -106,11 +110,14 @@ public: bool layered_window = false; bool fullscreen = false; + bool exclusive_fullscreen = false; bool on_top = false; bool borderless = false; bool resize_disabled = false; bool no_focus = false; bool is_popup = false; + bool mpass = false; + bool focused = false; Rect2i parent_safe_rect; }; @@ -151,7 +158,7 @@ private: CGEventSourceRef event_source; MouseMode mouse_mode = MOUSE_MODE_VISIBLE; - MouseButton last_button_state = MouseButton::NONE; + BitField<MouseButtonMask> last_button_state; bool drop_events = false; bool in_dispatch_input_event = false; @@ -183,7 +190,7 @@ private: Variant tag; Callable callback; }; - Vector<MenuCall> deferred_menu_calls; + List<MenuCall> deferred_menu_calls; const NSMenu *_get_menu_root(const String &p_menu_root) const; NSMenu *_get_menu_root(const String &p_menu_root); @@ -197,8 +204,6 @@ private: Point2i _get_native_screen_position(int p_screen) const; static void _displays_arrangement_changed(CGDirectDisplayID display_id, CGDisplayChangeSummaryFlags flags, void *user_info); - WindowID _get_focused_window_or_popup() const; - static void _dispatch_input_events(const Ref<InputEvent> &p_event); void _dispatch_input_event(const Ref<InputEvent> &p_event); void _push_input(const Ref<InputEvent> &p_event); @@ -225,6 +230,7 @@ public: 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 pop_last_key_event(); void update_im_text(const Point2i &p_selection, const String &p_text); void set_last_focused_window(WindowID p_window); bool mouse_process_popups(bool p_close = false); @@ -232,6 +238,8 @@ public: void popup_close(WindowID p_window); void set_is_resizing(bool p_is_resizing); bool get_is_resizing() const; + void reparent_check(WindowID p_window); + WindowID _get_focused_window_or_popup() const; void window_update(WindowID p_window); void window_destroy(WindowID p_window); @@ -313,13 +321,15 @@ public: bool update_mouse_wrap(WindowData &p_wd, NSPoint &r_delta, NSPoint &r_mpos, NSTimeInterval p_timestamp); virtual void warp_mouse(const Point2i &p_position) override; virtual Point2i mouse_get_position() const override; - void mouse_set_button_state(MouseButton p_state); - virtual MouseButton mouse_get_button_state() const override; + void mouse_set_button_state(BitField<MouseButtonMask> p_state); + virtual BitField<MouseButtonMask> mouse_get_button_state() const override; virtual void clipboard_set(const String &p_text) override; virtual String clipboard_get() const override; virtual int get_screen_count() const override; + virtual int get_primary_screen() const override; + virtual int get_keyboard_focus_screen() const override; virtual Point2i screen_get_position(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; virtual Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; virtual int screen_get_dpi(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; @@ -327,6 +337,8 @@ public: virtual float screen_get_max_scale() const override; virtual Rect2i screen_get_usable_rect(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; virtual float screen_get_refresh_rate(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; + virtual Color screen_get_pixel(const Point2i &p_position) const override; + virtual Ref<Image> screen_get_image(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; virtual void screen_set_keep_on(bool p_enable) override; virtual bool screen_is_kept_on() const override; @@ -353,6 +365,7 @@ public: virtual void window_set_current_screen(int p_screen, WindowID p_window = MAIN_WINDOW_ID) override; virtual Point2i window_get_position(WindowID p_window = MAIN_WINDOW_ID) const override; + virtual Point2i window_get_position_with_decorations(WindowID p_window = MAIN_WINDOW_ID) const override; virtual void window_set_position(const Point2i &p_position, WindowID p_window = MAIN_WINDOW_ID) override; virtual void window_set_transient(WindowID p_window, WindowID p_parent) override; @@ -366,7 +379,7 @@ public: virtual void window_set_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID) override; virtual Size2i window_get_size(WindowID p_window = MAIN_WINDOW_ID) const override; - virtual Size2i window_get_real_size(WindowID p_window = MAIN_WINDOW_ID) const override; + virtual Size2i window_get_size_with_decorations(WindowID p_window = MAIN_WINDOW_ID) const override; virtual void window_set_mode(WindowMode p_mode, WindowID p_window = MAIN_WINDOW_ID) override; virtual WindowMode window_get_mode(WindowID p_window = MAIN_WINDOW_ID) const override; @@ -378,6 +391,7 @@ public: virtual void window_request_attention(WindowID p_window = MAIN_WINDOW_ID) override; virtual void window_move_to_foreground(WindowID p_window = MAIN_WINDOW_ID) override; + virtual bool window_is_focused(WindowID p_window = MAIN_WINDOW_ID) const override; virtual bool window_can_draw(WindowID p_window = MAIN_WINDOW_ID) const override; @@ -430,12 +444,12 @@ public: virtual void set_native_icon(const String &p_filename) override; virtual void set_icon(const Ref<Image> &p_icon) override; - static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error); + static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error); static Vector<String> get_rendering_drivers_func(); static void register_macos_driver(); - DisplayServerMacOS(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error); + DisplayServerMacOS(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error); ~DisplayServerMacOS(); }; diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm index 4478a635a8..a0a851b7dc 100644 --- a/platform/macos/display_server_macos.mm +++ b/platform/macos/display_server_macos.mm @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* display_server_macos.mm */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* display_server_macos.mm */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "display_server_macos.h" @@ -38,7 +38,6 @@ #include "godot_window_delegate.h" #include "key_mapping_macos.h" #include "os_macos.h" - #include "tts_macos.h" #include "core/config/project_settings.h" @@ -48,13 +47,6 @@ #include "main/main.h" #include "scene/resources/texture.h" -#import <Carbon/Carbon.h> -#import <Cocoa/Cocoa.h> -#import <IOKit/IOCFPlugIn.h> -#import <IOKit/IOKitLib.h> -#import <IOKit/hid/IOHIDKeys.h> -#import <IOKit/hid/IOHIDLib.h> - #if defined(GLES3_ENABLED) #include "drivers/gles3/rasterizer_gles3.h" #endif @@ -63,6 +55,13 @@ #include "servers/rendering/renderer_rd/renderer_compositor_rd.h" #endif +#import <Carbon/Carbon.h> +#import <Cocoa/Cocoa.h> +#import <IOKit/IOCFPlugIn.h> +#import <IOKit/IOKitLib.h> +#import <IOKit/hid/IOHIDKeys.h> +#import <IOKit/hid/IOHIDLib.h> + const NSMenu *DisplayServerMacOS::_get_menu_root(const String &p_menu_root) const { const NSMenu *menu = nullptr; if (p_menu_root == "" || p_menu_root.to_lower() == "_main") { @@ -119,15 +118,26 @@ DisplayServerMacOS::WindowID DisplayServerMacOS::_create_window(WindowMode p_mod ERR_FAIL_COND_V_MSG(wd.window_delegate == nil, INVALID_WINDOW_ID, "Can't create a window delegate"); [wd.window_delegate setWindowID:window_id_counter]; - Point2i position = p_rect.position; - // OS X native y-coordinate relative to _get_screens_origin() is negative, + int rq_screen = get_screen_from_rect(p_rect); + if (rq_screen < 0) { + rq_screen = get_primary_screen(); // Requested window rect is outside any screen bounds. + } + + Rect2i srect = screen_get_usable_rect(rq_screen); + Point2i wpos = p_rect.position; + if (srect != Rect2i()) { + wpos.x = CLAMP(wpos.x, srect.position.x, srect.position.x + srect.size.width - p_rect.size.width / 3); + wpos.y = CLAMP(wpos.y, srect.position.y, srect.position.y + srect.size.height - p_rect.size.height / 3); + } + // macOS native y-coordinate relative to _get_screens_origin() is negative, // Godot passes a positive value. - position.y *= -1; - position += _get_screens_origin(); + wpos.y *= -1; + wpos += _get_screens_origin(); + wpos /= scale; // initWithContentRect uses bottom-left corner of the window’s frame as origin. wd.window_object = [[GodotWindow alloc] - initWithContentRect:NSMakeRect(position.x / scale, (position.y - p_rect.size.height) / scale, p_rect.size.width / scale, p_rect.size.height / scale) + initWithContentRect:NSMakeRect(100, 100, p_rect.size.width / scale, p_rect.size.height / scale) styleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable backing:NSBackingStoreBuffered defer:NO]; @@ -155,6 +165,17 @@ DisplayServerMacOS::WindowID DisplayServerMacOS::_create_window(WindowMode p_mod layer.contentsScale = scale; } + NSColor *bg_color = [NSColor windowBackgroundColor]; + Color _bg_color; + if (_get_window_early_clear_override(_bg_color)) { + bg_color = [NSColor colorWithCalibratedRed:_bg_color.r green:_bg_color.g blue:_bg_color.b alpha:1.f]; + } + + [wd.window_object setBackgroundColor:bg_color]; + if (layer) { + [layer setBackgroundColor:bg_color.CGColor]; + } + #if defined(VULKAN_ENABLED) if (context_vulkan) { Error err = context_vulkan->window_create(window_id_counter, p_vsync_mode, wd.window_view, p_rect.size.width, p_rect.size.height); @@ -166,8 +187,19 @@ DisplayServerMacOS::WindowID DisplayServerMacOS::_create_window(WindowMode p_mod Error err = gl_manager->window_create(window_id_counter, wd.window_view, p_rect.size.width, p_rect.size.height); ERR_FAIL_COND_V_MSG(err != OK, INVALID_WINDOW_ID, "Can't create an OpenGL context"); } + window_set_vsync_mode(p_vsync_mode, window_id_counter); #endif [wd.window_view updateLayerDelegate]; + + const NSRect contentRect = [wd.window_view frame]; + const NSRect windowRect = [wd.window_object frame]; + const NSRect nsrect = [wd.window_object convertRectToScreen:contentRect]; + Point2i offset; + offset.x = (nsrect.origin.x - windowRect.origin.x); + offset.y = (nsrect.origin.y + nsrect.size.height); + offset.y -= (windowRect.origin.y + windowRect.size.height); + [wd.window_object setFrameTopLeftPoint:NSMakePoint(wpos.x - offset.x, wpos.y - offset.y)]; + id = window_id_counter++; windows[id] = wd; } @@ -251,12 +283,17 @@ void DisplayServerMacOS::_set_window_per_pixel_transparency_enabled(bool p_enabl #endif wd.layered_window = true; } else { - [wd.window_object setBackgroundColor:[NSColor colorWithCalibratedWhite:1 alpha:1]]; + NSColor *bg_color = [NSColor windowBackgroundColor]; + Color _bg_color; + if (_get_window_early_clear_override(_bg_color)) { + bg_color = [NSColor colorWithCalibratedRed:_bg_color.r green:_bg_color.g blue:_bg_color.b alpha:1.f]; + } + [wd.window_object setBackgroundColor:bg_color]; [wd.window_object setOpaque:YES]; [wd.window_object setHasShadow:YES]; CALayer *layer = [(NSView *)wd.window_view layer]; if (layer) { - [layer setBackgroundColor:[NSColor colorWithCalibratedWhite:1 alpha:1].CGColor]; + [layer setBackgroundColor:bg_color.CGColor]; [layer setOpaque:YES]; } #if defined(GLES3_ENABLED) @@ -291,7 +328,7 @@ 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. + // to convert between macOS native screen coordinates and the ones expected by Godot. if (displays_arrangement_dirty) { const_cast<DisplayServerMacOS *>(this)->_update_displays_arrangement(); @@ -304,7 +341,7 @@ 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]; - // Return the top-left corner of the screen, for OS X the y starts at the bottom. + // Return the top-left corner of the screen, for macOS the y starts at the bottom. return Point2i(nsrect.origin.x, nsrect.origin.y + nsrect.size.height) * screen_get_max_scale(); } @@ -396,7 +433,8 @@ void DisplayServerMacOS::_process_key_events() { k->set_pressed(ke.pressed); k->set_echo(ke.echo); k->set_keycode(ke.keycode); - k->set_physical_keycode((Key)ke.physical_keycode); + k->set_physical_keycode(ke.physical_keycode); + k->set_key_label(ke.key_label); k->set_unicode(ke.unicode); _push_input(k); @@ -411,6 +449,7 @@ void DisplayServerMacOS::_process_key_events() { k->set_echo(ke.echo); k->set_keycode(Key::NONE); k->set_physical_keycode(Key::NONE); + k->set_key_label(Key::NONE); k->set_unicode(ke.unicode); _push_input(k); @@ -423,7 +462,8 @@ void DisplayServerMacOS::_process_key_events() { k->set_pressed(ke.pressed); k->set_echo(ke.echo); k->set_keycode(ke.keycode); - k->set_physical_keycode((Key)ke.physical_keycode); + k->set_physical_keycode(ke.physical_keycode); + k->set_key_label(ke.key_label); if (i + 1 < key_event_pos && key_event_buffer[i + 1].keycode == Key::NONE) { k->set_unicode(key_event_buffer[i + 1].unicode); @@ -595,6 +635,7 @@ void DisplayServerMacOS::send_event(NSEvent *p_event) { k->set_pressed(true); k->set_keycode(Key::PERIOD); k->set_physical_keycode(Key::PERIOD); + k->set_key_label(Key::PERIOD); k->set_echo([p_event isARepeat]); Input::get_singleton()->parse_input_event(k); @@ -636,6 +677,12 @@ void DisplayServerMacOS::update_mouse_pos(DisplayServerMacOS::WindowData &p_wd, Input::get_singleton()->set_mouse_position(p_wd.mouse_pos); } +void DisplayServerMacOS::pop_last_key_event() { + if (key_event_pos > 0) { + key_event_pos--; + } +} + 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); @@ -717,6 +764,7 @@ bool DisplayServerMacOS::has_feature(Feature p_feature) const { case FEATURE_SWAP_BUFFERS: case FEATURE_TEXT_TO_SPEECH: case FEATURE_EXTEND_TO_TITLE: + case FEATURE_SCREEN_CAPTURE: return true; default: { } @@ -1692,37 +1740,37 @@ void DisplayServerMacOS::global_menu_clear(const String &p_menu_root) { } bool DisplayServerMacOS::tts_is_speaking() const { - ERR_FAIL_COND_V(!tts, false); + ERR_FAIL_COND_V_MSG(!tts, false, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); return [tts isSpeaking]; } bool DisplayServerMacOS::tts_is_paused() const { - ERR_FAIL_COND_V(!tts, false); + ERR_FAIL_COND_V_MSG(!tts, false, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); return [tts isPaused]; } TypedArray<Dictionary> DisplayServerMacOS::tts_get_voices() const { - ERR_FAIL_COND_V(!tts, Array()); + ERR_FAIL_COND_V_MSG(!tts, Array(), "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); return [tts getVoices]; } 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); + ERR_FAIL_COND_MSG(!tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); [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 DisplayServerMacOS::tts_pause() { - ERR_FAIL_COND(!tts); + ERR_FAIL_COND_MSG(!tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); [tts pauseSpeaking]; } void DisplayServerMacOS::tts_resume() { - ERR_FAIL_COND(!tts); + ERR_FAIL_COND_MSG(!tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); [tts resumeSpeaking]; } void DisplayServerMacOS::tts_stop() { - ERR_FAIL_COND(!tts); + ERR_FAIL_COND_MSG(!tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); [tts stopSpeaking]; } @@ -1791,9 +1839,9 @@ Error DisplayServerMacOS::dialog_show(String p_title, String p_description, Vect if (!p_callback.is_null()) { Variant button = button_pressed; Variant *buttonp = &button; - Variant ret; + Variant fun_ret; Callable::CallError ce; - p_callback.callp((const Variant **)&buttonp, 1, ret, ce); + p_callback.callp((const Variant **)&buttonp, 1, fun_ret, ce); } return OK; @@ -1823,9 +1871,9 @@ Error DisplayServerMacOS::dialog_input_text(String p_title, String p_description if (!p_callback.is_null()) { Variant text = ret; Variant *textp = &text; - Variant ret; + Variant fun_ret; Callable::CallError ce; - p_callback.callp((const Variant **)&textp, 1, ret, ce); + p_callback.callp((const Variant **)&textp, 1, fun_ret, ce); } return OK; @@ -1843,11 +1891,22 @@ void DisplayServerMacOS::mouse_set_mode(MouseMode p_mode) { window_id = MAIN_WINDOW_ID; } WindowData &wd = windows[window_id]; + + bool show_cursor = (p_mode == MOUSE_MODE_VISIBLE || p_mode == MOUSE_MODE_CONFINED); + bool previously_shown = (mouse_mode == MOUSE_MODE_VISIBLE || mouse_mode == MOUSE_MODE_CONFINED); + + if (show_cursor && !previously_shown) { + window_id = get_window_at_screen_position(mouse_get_position()); + if (window_id != INVALID_WINDOW_ID) { + send_window_event(windows[window_id], WINDOW_EVENT_MOUSE_ENTER); + } + } + if (p_mode == MOUSE_MODE_CAPTURED) { // Apple Docs state that the display parameter is not used. // "This parameter is not used. By default, you may pass kCGDirectMainDisplay." // https://developer.apple.com/library/mac/documentation/graphicsimaging/reference/Quartz_Services_Ref/Reference/reference.html - if (mouse_mode == MOUSE_MODE_VISIBLE || mouse_mode == MOUSE_MODE_CONFINED) { + if (previously_shown) { CGDisplayHideCursor(kCGDirectMainDisplay); } CGAssociateMouseAndMouseCursorPosition(false); @@ -1858,7 +1917,7 @@ void DisplayServerMacOS::mouse_set_mode(MouseMode p_mode) { CGPoint lMouseWarpPos = { pointOnScreen.x, CGDisplayBounds(CGMainDisplayID()).size.height - pointOnScreen.y }; CGWarpMouseCursorPosition(lMouseWarpPos); } else if (p_mode == MOUSE_MODE_HIDDEN) { - if (mouse_mode == MOUSE_MODE_VISIBLE || mouse_mode == MOUSE_MODE_CONFINED) { + if (previously_shown) { CGDisplayHideCursor(kCGDirectMainDisplay); } [wd.window_object setMovable:YES]; @@ -1868,7 +1927,7 @@ void DisplayServerMacOS::mouse_set_mode(MouseMode p_mode) { [wd.window_object setMovable:NO]; CGAssociateMouseAndMouseCursorPosition(false); } else if (p_mode == MOUSE_MODE_CONFINED_HIDDEN) { - if (mouse_mode == MOUSE_MODE_VISIBLE || mouse_mode == MOUSE_MODE_CONFINED) { + if (previously_shown) { CGDisplayHideCursor(kCGDirectMainDisplay); } [wd.window_object setMovable:NO]; @@ -1884,7 +1943,7 @@ void DisplayServerMacOS::mouse_set_mode(MouseMode p_mode) { warp_events.clear(); mouse_mode = p_mode; - if (mouse_mode == MOUSE_MODE_VISIBLE || mouse_mode == MOUSE_MODE_CONFINED) { + if (show_cursor) { cursor_update_shape(); } } @@ -1965,7 +2024,7 @@ void DisplayServerMacOS::warp_mouse(const Point2i &p_position) { // Local point in window coords. const NSRect contentRect = [wd.window_view frame]; const float scale = screen_get_max_scale(); - NSRect pointInWindowRect = NSMakeRect(p_position.x / scale, contentRect.size.height - (p_position.y / scale - 1), 0, 0); + NSRect pointInWindowRect = NSMakeRect(p_position.x / scale, contentRect.size.height - (p_position.y / scale), scale, scale); NSPoint pointOnScreen = [[wd.window_view window] convertRectToScreen:pointInWindowRect].origin; // Point in scren coords. @@ -2001,11 +2060,11 @@ Point2i DisplayServerMacOS::mouse_get_position() const { return Vector2i(); } -void DisplayServerMacOS::mouse_set_button_state(MouseButton p_state) { +void DisplayServerMacOS::mouse_set_button_state(BitField<MouseButtonMask> p_state) { last_button_state = p_state; } -MouseButton DisplayServerMacOS::mouse_get_button_state() const { +BitField<MouseButtonMask> DisplayServerMacOS::mouse_get_button_state() const { return last_button_state; } @@ -2048,15 +2107,21 @@ int DisplayServerMacOS::get_screen_count() const { return [screenArray count]; } +int DisplayServerMacOS::get_primary_screen() const { + return 0; +} + +int DisplayServerMacOS::get_keyboard_focus_screen() const { + const NSUInteger index = [[NSScreen screens] indexOfObject:[NSScreen mainScreen]]; + return (index == NSNotFound) ? 0 : index; +} + Point2i DisplayServerMacOS::screen_get_position(int p_screen) const { _THREAD_SAFE_METHOD_ - if (p_screen == SCREEN_OF_MAIN_WINDOW) { - p_screen = window_get_current_screen(); - } - + p_screen = _get_screen_index(p_screen); Point2i position = _get_native_screen_position(p_screen) - _get_screens_origin(); - // OS X native y-coordinate relative to _get_screens_origin() is negative, + // macOS native y-coordinate relative to _get_screens_origin() is negative, // Godot expects a positive value. position.y *= -1; return position; @@ -2065,10 +2130,7 @@ Point2i DisplayServerMacOS::screen_get_position(int p_screen) const { Size2i DisplayServerMacOS::screen_get_size(int p_screen) const { _THREAD_SAFE_METHOD_ - if (p_screen == SCREEN_OF_MAIN_WINDOW) { - p_screen = window_get_current_screen(); - } - + p_screen = _get_screen_index(p_screen); NSArray *screenArray = [NSScreen screens]; if ((NSUInteger)p_screen < [screenArray count]) { // Note: Use frame to get the whole screen size. @@ -2082,10 +2144,7 @@ Size2i DisplayServerMacOS::screen_get_size(int p_screen) const { int DisplayServerMacOS::screen_get_dpi(int p_screen) const { _THREAD_SAFE_METHOD_ - if (p_screen == SCREEN_OF_MAIN_WINDOW) { - p_screen = window_get_current_screen(); - } - + p_screen = _get_screen_index(p_screen); NSArray *screenArray = [NSScreen screens]; if ((NSUInteger)p_screen < [screenArray count]) { NSDictionary *description = [[screenArray objectAtIndex:p_screen] deviceDescription]; @@ -2106,9 +2165,7 @@ int DisplayServerMacOS::screen_get_dpi(int p_screen) const { float DisplayServerMacOS::screen_get_scale(int p_screen) const { _THREAD_SAFE_METHOD_ - if (p_screen == SCREEN_OF_MAIN_WINDOW) { - p_screen = window_get_current_screen(); - } + p_screen = _get_screen_index(p_screen); if (OS::get_singleton()->is_hidpi_allowed()) { NSArray *screenArray = [NSScreen screens]; if ((NSUInteger)p_screen < [screenArray count]) { @@ -2131,10 +2188,7 @@ float DisplayServerMacOS::screen_get_max_scale() const { Rect2i DisplayServerMacOS::screen_get_usable_rect(int p_screen) const { _THREAD_SAFE_METHOD_ - if (p_screen == SCREEN_OF_MAIN_WINDOW) { - p_screen = window_get_current_screen(); - } - + p_screen = _get_screen_index(p_screen); NSArray *screenArray = [NSScreen screens]; if ((NSUInteger)p_screen < [screenArray count]) { const float scale = screen_get_max_scale(); @@ -2150,13 +2204,82 @@ Rect2i DisplayServerMacOS::screen_get_usable_rect(int p_screen) const { return Rect2i(); } -float DisplayServerMacOS::screen_get_refresh_rate(int p_screen) const { - _THREAD_SAFE_METHOD_ +Color DisplayServerMacOS::screen_get_pixel(const Point2i &p_position) const { + Point2i position = p_position; + // macOS native y-coordinate relative to _get_screens_origin() is negative, + // Godot passes a positive value. + position.y *= -1; + position += _get_screens_origin(); + position /= screen_get_max_scale(); - if (p_screen == SCREEN_OF_MAIN_WINDOW) { - p_screen = window_get_current_screen(); + for (NSScreen *screen in [NSScreen screens]) { + NSRect frame = [screen frame]; + if (NSMouseInRect(NSMakePoint(position.x, position.y), frame, NO)) { + NSDictionary *screenDescription = [screen deviceDescription]; + CGDirectDisplayID display_id = [[screenDescription objectForKey:@"NSScreenNumber"] unsignedIntValue]; + CGImageRef image = CGDisplayCreateImageForRect(display_id, CGRectMake(position.x - frame.origin.x, frame.size.height - (position.y - frame.origin.y), 1, 1)); + if (image) { + NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc] initWithCGImage:image]; + CGImageRelease(image); + NSColor *color = [bitmap colorAtX:0 y:0]; + if (color) { + CGFloat components[4]; + [color getRed:&components[0] green:&components[1] blue:&components[2] alpha:&components[3]]; + return Color(components[0], components[1], components[2], components[3]); + } + } + } } + return Color(); +} + +Ref<Image> DisplayServerMacOS::screen_get_image(int p_screen) const { + ERR_FAIL_INDEX_V(p_screen, get_screen_count(), Ref<Image>()); + switch (p_screen) { + case SCREEN_PRIMARY: { + p_screen = get_primary_screen(); + } break; + case SCREEN_OF_MAIN_WINDOW: { + p_screen = window_get_current_screen(MAIN_WINDOW_ID); + } break; + default: + break; + } + + Ref<Image> img; + NSArray *screenArray = [NSScreen screens]; + if ((NSUInteger)p_screen < [screenArray count]) { + NSRect nsrect = [[screenArray objectAtIndex:p_screen] frame]; + NSDictionary *screenDescription = [[screenArray objectAtIndex:p_screen] deviceDescription]; + CGDirectDisplayID display_id = [[screenDescription objectForKey:@"NSScreenNumber"] unsignedIntValue]; + CGImageRef image = CGDisplayCreateImageForRect(display_id, CGRectMake(0, 0, nsrect.size.width, nsrect.size.height)); + if (image) { + CGColorSpaceRef color_space = CGColorSpaceCreateDeviceRGB(); + if (color_space) { + NSUInteger width = CGImageGetWidth(image); + NSUInteger height = CGImageGetHeight(image); + + Vector<uint8_t> img_data; + img_data.resize(height * width * 4); + CGContextRef context = CGBitmapContextCreate(img_data.ptrw(), width, height, 8, 4 * width, color_space, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); + if (context) { + CGContextDrawImage(context, CGRectMake(0, 0, width, height), image); + img = Image::create_from_data(width, height, false, Image::FORMAT_RGBA8, img_data); + CGContextRelease(context); + } + CGColorSpaceRelease(color_space); + } + CGImageRelease(image); + } + } + return img; +} + +float DisplayServerMacOS::screen_get_refresh_rate(int p_screen) const { + _THREAD_SAFE_METHOD_ + + p_screen = _get_screen_index(p_screen); NSArray *screenArray = [NSScreen screens]; if ((NSUInteger)p_screen < [screenArray count]) { NSDictionary *description = [[screenArray objectAtIndex:p_screen] deviceDescription]; @@ -2215,7 +2338,7 @@ void DisplayServerMacOS::show_window(WindowID p_id) { popup_open(p_id); if ([wd.window_object isMiniaturized]) { return; - } else if (wd.no_focus || wd.is_popup) { + } else if (wd.no_focus) { [wd.window_object orderFront:nil]; } else { [wd.window_object makeKeyAndOrderFront:nil]; @@ -2316,8 +2439,14 @@ void DisplayServerMacOS::window_set_current_screen(int p_screen, WindowID p_wind was_fullscreen = true; } + Rect2i srect = screen_get_usable_rect(p_screen); Point2i wpos = window_get_position(p_window) - screen_get_position(window_get_current_screen(p_window)); - window_set_position(wpos + screen_get_position(p_screen), p_window); + Size2i wsize = window_get_size(p_window); + wpos += srect.position; + + wpos.x = CLAMP(wpos.x, srect.position.x, srect.position.x + srect.size.width - wsize.width / 3); + wpos.y = CLAMP(wpos.y, srect.position.y, srect.position.y + srect.size.height - wsize.height / 3); + window_set_position(wpos, p_window); if (was_fullscreen) { // Re-enter fullscreen mode. @@ -2325,24 +2454,60 @@ void DisplayServerMacOS::window_set_current_screen(int p_screen, WindowID p_wind } } -void DisplayServerMacOS::window_set_exclusive(WindowID p_window, bool p_exclusive) { - _THREAD_SAFE_METHOD_ +void DisplayServerMacOS::reparent_check(WindowID p_window) { ERR_FAIL_COND(!windows.has(p_window)); WindowData &wd = windows[p_window]; - if (wd.exclusive != p_exclusive) { - wd.exclusive = p_exclusive; - if (wd.transient_parent != INVALID_WINDOW_ID) { - WindowData &wd_parent = windows[wd.transient_parent]; - if (wd.exclusive) { - ERR_FAIL_COND_MSG([[wd_parent.window_object childWindows] count] > 0, "Transient parent has another exclusive child."); + NSScreen *screen = [wd.window_object screen]; + + if (wd.transient_parent != INVALID_WINDOW_ID) { + WindowData &wd_parent = windows[wd.transient_parent]; + NSScreen *parent_screen = [wd_parent.window_object screen]; + + if (parent_screen == screen) { + if (![[wd_parent.window_object childWindows] containsObject:wd.window_object]) { + [wd.window_object setCollectionBehavior:NSWindowCollectionBehaviorFullScreenAuxiliary]; [wd_parent.window_object addChildWindow:wd.window_object ordered:NSWindowAbove]; - } else { + } + } else { + if ([[wd_parent.window_object childWindows] containsObject:wd.window_object]) { [wd_parent.window_object removeChildWindow:wd.window_object]; + [wd.window_object setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; + [wd.window_object orderFront:nil]; + } + } + } + + for (const WindowID &child : wd.transient_children) { + WindowData &wd_child = windows[child]; + NSScreen *child_screen = [wd_child.window_object screen]; + + if (child_screen == screen) { + if (![[wd.window_object childWindows] containsObject:wd_child.window_object]) { + if (wd_child.fullscreen) { + [wd_child.window_object toggleFullScreen:nil]; + } + [wd_child.window_object setCollectionBehavior:NSWindowCollectionBehaviorFullScreenAuxiliary]; + [wd.window_object addChildWindow:wd_child.window_object ordered:NSWindowAbove]; + } + } else { + if ([[wd.window_object childWindows] containsObject:wd_child.window_object]) { + [wd.window_object removeChildWindow:wd_child.window_object]; + [wd_child.window_object setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; } } } } +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]; + if (wd.exclusive != p_exclusive) { + wd.exclusive = p_exclusive; + reparent_check(p_window); + } +} + Point2i DisplayServerMacOS::window_get_position(WindowID p_window) const { _THREAD_SAFE_METHOD_ @@ -2354,13 +2519,34 @@ Point2i DisplayServerMacOS::window_get_position(WindowID p_window) const { const NSRect nsrect = [wd.window_object convertRectToScreen:contentRect]; Point2i pos; - // Return the position of the top-left corner, for OS X the y starts at the bottom. + // Return the position of the top-left corner, for macOS the y starts at the bottom. + const float scale = screen_get_max_scale(); + pos.x = nsrect.origin.x; + pos.y = (nsrect.origin.y + nsrect.size.height); + pos *= scale; + pos -= _get_screens_origin(); + // macOS native y-coordinate relative to _get_screens_origin() is negative, + // Godot expects a positive value. + pos.y *= -1; + return pos; +} + +Point2i DisplayServerMacOS::window_get_position_with_decorations(WindowID p_window) const { + _THREAD_SAFE_METHOD_ + + ERR_FAIL_COND_V(!windows.has(p_window), Point2i()); + const WindowData &wd = windows[p_window]; + + const NSRect nsrect = [wd.window_object frame]; + Point2i pos; + + // Return the position of the top-left corner, for macOS the y starts at the bottom. const float scale = screen_get_max_scale(); pos.x = nsrect.origin.x; pos.y = (nsrect.origin.y + nsrect.size.height); pos *= scale; pos -= _get_screens_origin(); - // OS X native y-coordinate relative to _get_screens_origin() is negative, + // macOS native y-coordinate relative to _get_screens_origin() is negative, // Godot expects a positive value. pos.y *= -1; return pos; @@ -2372,12 +2558,12 @@ void DisplayServerMacOS::window_set_position(const Point2i &p_position, WindowID ERR_FAIL_COND(!windows.has(p_window)); WindowData &wd = windows[p_window]; - if ([wd.window_object isZoomed]) { + if (NSEqualRects([wd.window_object frame], [[wd.window_object screen] visibleFrame])) { return; } Point2i position = p_position; - // OS X native y-coordinate relative to _get_screens_origin() is negative, + // macOS native y-coordinate relative to _get_screens_origin() is negative, // Godot passes a positive value. position.y *= -1; position += _get_screens_origin(); @@ -2417,11 +2603,10 @@ void DisplayServerMacOS::window_set_transient(WindowID p_window, WindowID p_pare wd_window.transient_parent = INVALID_WINDOW_ID; wd_parent.transient_children.erase(p_window); - [wd_window.window_object setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; - - if (wd_window.exclusive) { + if ([[wd_parent.window_object childWindows] containsObject:wd_window.window_object]) { [wd_parent.window_object removeChildWindow:wd_window.window_object]; } + [wd_window.window_object setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; } else { ERR_FAIL_COND(!windows.has(p_parent)); ERR_FAIL_COND_MSG(wd_window.transient_parent != INVALID_WINDOW_ID, "Window already has a transient parent"); @@ -2429,11 +2614,7 @@ void DisplayServerMacOS::window_set_transient(WindowID p_window, WindowID p_pare wd_window.transient_parent = p_parent; wd_parent.transient_children.insert(p_window); - [wd_window.window_object setCollectionBehavior:NSWindowCollectionBehaviorFullScreenAuxiliary]; - - if (wd_window.exclusive) { - [wd_parent.window_object addChildWindow:wd_window.window_object ordered:NSWindowAbove]; - } + reparent_check(p_window); } } @@ -2500,7 +2681,7 @@ void DisplayServerMacOS::window_set_size(const Size2i p_size, WindowID p_window) ERR_FAIL_COND(!windows.has(p_window)); WindowData &wd = windows[p_window]; - if ([wd.window_object isZoomed]) { + if (NSEqualRects([wd.window_object frame], [[wd.window_object screen] visibleFrame])) { return; } @@ -2530,7 +2711,7 @@ Size2i DisplayServerMacOS::window_get_size(WindowID p_window) const { return wd.size; } -Size2i DisplayServerMacOS::window_get_real_size(WindowID p_window) const { +Size2i DisplayServerMacOS::window_get_size_with_decorations(WindowID p_window) const { _THREAD_SAFE_METHOD_ ERR_FAIL_COND_V(!windows.has(p_window), Size2i()); @@ -2573,10 +2754,16 @@ void DisplayServerMacOS::window_set_mode(WindowMode p_mode, WindowID p_window) { [wd.window_object setContentMaxSize:NSMakeSize(size.x, size.y)]; } [wd.window_object toggleFullScreen:nil]; + + if (old_mode == WINDOW_MODE_EXCLUSIVE_FULLSCREEN) { + [NSApp setPresentationOptions:NSApplicationPresentationDefault]; + } + wd.fullscreen = false; + wd.exclusive_fullscreen = false; } break; case WINDOW_MODE_MAXIMIZED: { - if ([wd.window_object isZoomed]) { + if (NSEqualRects([wd.window_object frame], [[wd.window_object screen] visibleFrame])) { [wd.window_object zoom:nil]; } } break; @@ -2598,10 +2785,18 @@ void DisplayServerMacOS::window_set_mode(WindowMode p_mode, WindowID p_window) { [wd.window_object setContentMinSize:NSMakeSize(0, 0)]; [wd.window_object setContentMaxSize:NSMakeSize(FLT_MAX, FLT_MAX)]; [wd.window_object toggleFullScreen:nil]; + wd.fullscreen = true; + if (p_mode == WINDOW_MODE_EXCLUSIVE_FULLSCREEN) { + const NSUInteger presentationOptions = NSApplicationPresentationHideDock | NSApplicationPresentationHideMenuBar; + [NSApp setPresentationOptions:presentationOptions]; + wd.exclusive_fullscreen = true; + } else { + wd.exclusive_fullscreen = false; + } } break; case WINDOW_MODE_MAXIMIZED: { - if (![wd.window_object isZoomed]) { + if (!NSEqualRects([wd.window_object frame], [[wd.window_object screen] visibleFrame])) { [wd.window_object zoom:nil]; } } break; @@ -2615,9 +2810,13 @@ DisplayServer::WindowMode DisplayServerMacOS::window_get_mode(WindowID p_window) const WindowData &wd = windows[p_window]; if (wd.fullscreen) { // If fullscreen, it's not in another mode. - return WINDOW_MODE_FULLSCREEN; + if (wd.exclusive_fullscreen) { + return WINDOW_MODE_EXCLUSIVE_FULLSCREEN; + } else { + return WINDOW_MODE_FULLSCREEN; + } } - if ([wd.window_object isZoomed] && !wd.resize_disabled) { + if (NSEqualRects([wd.window_object frame], [[wd.window_object screen] visibleFrame])) { return WINDOW_MODE_MAXIMIZED; } if ([wd.window_object respondsToSelector:@selector(isMiniaturized)]) { @@ -2727,8 +2926,10 @@ void DisplayServerMacOS::window_set_flag(WindowFlags p_flag, bool p_enabled, Win } if (p_enabled) { [wd.window_object setStyleMask:[wd.window_object styleMask] & ~NSWindowStyleMaskResizable]; + [[wd.window_object standardWindowButton:NSWindowZoomButton] setEnabled:NO]; } else { [wd.window_object setStyleMask:[wd.window_object styleMask] | NSWindowStyleMaskResizable]; + [[wd.window_object standardWindowButton:NSWindowZoomButton] setEnabled:YES]; } } break; case WINDOW_FLAG_EXTEND_TO_TITLE: { @@ -2771,7 +2972,7 @@ void DisplayServerMacOS::window_set_flag(WindowFlags p_flag, bool p_enabled, Win if ([wd.window_object isVisible]) { if ([wd.window_object isMiniaturized]) { return; - } else if (wd.no_focus || wd.is_popup) { + } else if (wd.no_focus) { [wd.window_object orderFront:nil]; } else { [wd.window_object makeKeyAndOrderFront:nil]; @@ -2800,6 +3001,9 @@ void DisplayServerMacOS::window_set_flag(WindowFlags p_flag, bool p_enabled, Win case WINDOW_FLAG_NO_FOCUS: { wd.no_focus = p_enabled; } break; + case WINDOW_FLAG_MOUSE_PASSTHROUGH: { + wd.mpass = p_enabled; + } break; case WINDOW_FLAG_POPUP: { ERR_FAIL_COND_MSG(p_window == MAIN_WINDOW_ID, "Main window can't be popup."); ERR_FAIL_COND_MSG([wd.window_object isVisible] && (wd.is_popup != p_enabled), "Popup flag can't changed while window is opened."); @@ -2839,6 +3043,9 @@ bool DisplayServerMacOS::window_get_flag(WindowFlags p_flag, WindowID p_window) case WINDOW_FLAG_NO_FOCUS: { return wd.no_focus; } break; + case WINDOW_FLAG_MOUSE_PASSTHROUGH: { + return wd.mpass; + } break; case WINDOW_FLAG_POPUP: { return wd.is_popup; } break; @@ -2868,6 +3075,15 @@ void DisplayServerMacOS::window_move_to_foreground(WindowID p_window) { } } +bool DisplayServerMacOS::window_is_focused(WindowID p_window) const { + _THREAD_SAFE_METHOD_ + + ERR_FAIL_COND_V(!windows.has(p_window), false); + const WindowData &wd = windows[p_window]; + + return wd.focused; +} + bool DisplayServerMacOS::window_can_draw(WindowID p_window) const { return window_get_mode(p_window) != WINDOW_MODE_MINIMIZED; } @@ -2932,6 +3148,14 @@ int64_t DisplayServerMacOS::window_get_native_handle(HandleType p_handle_type, W case WINDOW_VIEW: { return (int64_t)windows[p_window].window_view; } +#ifdef GLES3_ENABLED + case OPENGL_CONTEXT: { + if (gl_manager) { + return (int64_t)gl_manager->get_context(p_window); + } + return 0; + } +#endif default: { return 0; } @@ -2954,7 +3178,9 @@ ObjectID DisplayServerMacOS::window_get_attached_instance_id(WindowID p_window) void DisplayServerMacOS::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 } @@ -2962,7 +3188,7 @@ void DisplayServerMacOS::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_ _THREAD_SAFE_METHOD_ #if defined(GLES3_ENABLED) if (gl_manager) { - gl_manager->set_use_vsync(p_vsync_mode); + gl_manager->set_use_vsync(p_vsync_mode != DisplayServer::VSYNC_DISABLED); } #endif #if defined(VULKAN_ENABLED) @@ -3084,6 +3310,8 @@ DisplayServerMacOS::CursorShape DisplayServerMacOS::cursor_get_shape() const { void DisplayServerMacOS::cursor_set_custom_image(const Ref<Resource> &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { _THREAD_SAFE_METHOD_ + ERR_FAIL_INDEX(p_shape, CURSOR_MAX); + if (p_cursor.is_valid()) { HashMap<CursorShape, Vector<Variant>>::Iterator cursor_c = cursors_cache.find(p_shape); @@ -3096,16 +3324,12 @@ void DisplayServerMacOS::cursor_set_custom_image(const Ref<Resource> &p_cursor, } Ref<Texture2D> texture = p_cursor; + ERR_FAIL_COND(!texture.is_valid()); Ref<AtlasTexture> atlas_texture = p_cursor; - Ref<Image> image; Size2 texture_size; Rect2 atlas_rect; - if (texture.is_valid()) { - image = texture->get_image(); - } - - if (!image.is_valid() && atlas_texture.is_valid()) { + if (atlas_texture.is_valid()) { texture = atlas_texture->get_atlas(); atlas_rect.size.width = texture->get_width(); @@ -3115,19 +3339,23 @@ void DisplayServerMacOS::cursor_set_custom_image(const Ref<Resource> &p_cursor, texture_size.width = atlas_texture->get_region().size.x; texture_size.height = atlas_texture->get_region().size.y; - } else if (image.is_valid()) { + } else { texture_size.width = texture->get_width(); texture_size.height = texture->get_height(); } - ERR_FAIL_COND(!texture.is_valid()); ERR_FAIL_COND(p_hotspot.x < 0 || p_hotspot.y < 0); ERR_FAIL_COND(texture_size.width > 256 || texture_size.height > 256); ERR_FAIL_COND(p_hotspot.x > texture_size.width || p_hotspot.y > texture_size.height); - image = texture->get_image(); + Ref<Image> image = texture->get_image(); ERR_FAIL_COND(!image.is_valid()); + if (image->is_compressed()) { + image = image->duplicate(true); + Error err = image->decompress(); + ERR_FAIL_COND_MSG(err != OK, "Couldn't decompress VRAM-compressed custom mouse cursor image. Switch to a lossless compression mode in the Import dock."); + } NSBitmapImageRep *imgrep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:nullptr @@ -3261,14 +3489,14 @@ String DisplayServerMacOS::keyboard_get_layout_name(int p_index) const { } Key DisplayServerMacOS::keyboard_get_keycode_from_physical(Key p_keycode) const { - if (p_keycode == Key::PAUSE) { + if (p_keycode == Key::PAUSE || p_keycode == Key::NONE) { return p_keycode; } Key modifiers = p_keycode & KeyModifierMask::MODIFIER_MASK; Key keycode_no_mod = p_keycode & KeyModifierMask::CODE_MASK; - unsigned int macos_keycode = KeyMappingMacOS::unmap_key((Key)keycode_no_mod); - return (Key)(KeyMappingMacOS::remap_key(macos_keycode, 0) | modifiers); + unsigned int macos_keycode = KeyMappingMacOS::unmap_key(keycode_no_mod); + return (Key)(KeyMappingMacOS::remap_key(macos_keycode, 0, false) | modifiers); } void DisplayServerMacOS::process_events() { @@ -3289,14 +3517,16 @@ void DisplayServerMacOS::process_events() { } // Process "menu_callback"s. - for (MenuCall &E : deferred_menu_calls) { - Variant tag = E.tag; + while (List<MenuCall>::Element *call_p = deferred_menu_calls.front()) { + MenuCall call = call_p->get(); + deferred_menu_calls.pop_front(); // Remove before call to avoid infinite loop in case callback is using `process_events` (e.g. EditorProgress). + + Variant tag = call.tag; Variant *tagp = &tag; Variant ret; Callable::CallError ce; - E.callback.callp((const Variant **)&tagp, 1, ret, ce); + call.callback.callp((const Variant **)&tagp, 1, ret, ce); } - deferred_menu_calls.clear(); if (!drop_events) { _process_key_events(); @@ -3305,7 +3535,11 @@ void DisplayServerMacOS::process_events() { for (KeyValue<WindowID, WindowData> &E : windows) { WindowData &wd = E.value; - if (wd.mpath.size() > 0) { + if (wd.mpass) { + if (![wd.window_object ignoresMouseEvents]) { + [wd.window_object setIgnoresMouseEvents:YES]; + } + } else if (wd.mpath.size() > 0) { update_mouse_pos(wd, [wd.window_object mouseLocationOutsideOfEventStream]); if (Geometry2D::is_point_in_polygon(wd.mouse_pos, wd.mpath)) { if ([wd.window_object ignoresMouseEvents]) { @@ -3405,28 +3639,28 @@ void DisplayServerMacOS::set_icon(const Ref<Image> &p_icon) { [NSApp setApplicationIconImage:nsimg]; } -DisplayServer *DisplayServerMacOS::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error) { - DisplayServer *ds = memnew(DisplayServerMacOS(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, 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_position, const Vector2i &p_resolution, int p_screen, Error &r_error) { + DisplayServer *ds = memnew(DisplayServerMacOS(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, p_screen, r_error)); if (r_error != OK) { if (p_rendering_driver == "vulkan") { String executable_command; if (OS::get_singleton()->get_bundle_resource_dir() == OS::get_singleton()->get_executable_path().get_base_dir()) { - executable_command = vformat("%s --rendering-driver opengl3", OS::get_singleton()->get_executable_path()); + executable_command = vformat("\"%s\" --rendering-driver opengl3", OS::get_singleton()->get_executable_path()); } else { - executable_command = vformat("open %s --args --rendering-driver opengl3", OS::get_singleton()->get_bundle_resource_dir().path_join("../..").simplify_path()); - } - OS::get_singleton()->alert("Your video card driver does not support the selected Vulkan version.\n" - "Please try updating your GPU driver or try using the OpenGL 3 driver.\n" - "You can enable the OpenGL 3 driver by starting the engine from the\n" - "command line with the command: '" + - executable_command + "'.\n" - "If you have updated your graphics drivers recently, try rebooting.", - "Unable to initialize Video driver"); + executable_command = vformat("open \"%s\" --args --rendering-driver opengl3", OS::get_singleton()->get_bundle_resource_dir().path_join("../..").simplify_path()); + } + OS::get_singleton()->alert( + vformat("Your video card drivers seem not to support the required Vulkan version.\n\n" + "If possible, consider updating your macOS version or using the OpenGL 3 driver.\n\n" + "You can enable the OpenGL 3 driver by starting the engine from the\n" + "command line with the command:\n\n %s", + executable_command), + "Unable to initialize Vulkan video driver"); } else { - OS::get_singleton()->alert("Your video card driver does not support the selected OpenGL version.\n" - "Please try updating your GPU driver.\n" - "If you have updated your graphics drivers recently, try rebooting.", - "Unable to initialize Video driver"); + OS::get_singleton()->alert( + "Your video card drivers seem not to support the required OpenGL 3.3 version.\n\n" + "If possible, consider updating your macOS version.", + "Unable to initialize OpenGL video driver"); } } return ds; @@ -3477,8 +3711,23 @@ Rect2i DisplayServerMacOS::window_get_popup_safe_rect(WindowID p_window) const { void DisplayServerMacOS::popup_open(WindowID p_window) { _THREAD_SAFE_METHOD_ + bool has_popup_ancestor = false; + WindowID transient_root = p_window; + while (true) { + WindowID parent = windows[transient_root].transient_parent; + if (parent == INVALID_WINDOW_ID) { + break; + } else { + transient_root = parent; + if (windows[parent].is_popup) { + has_popup_ancestor = true; + break; + } + } + } + WindowData &wd = windows[p_window]; - if (wd.is_popup) { + if (wd.is_popup || has_popup_ancestor) { bool was_empty = popup_list.is_empty(); // Find current popup parent, or root popup if new window is not transient. List<WindowID>::Element *C = nullptr; @@ -3575,7 +3824,9 @@ bool DisplayServerMacOS::mouse_process_popups(bool p_close) { return closed; } -DisplayServerMacOS::DisplayServerMacOS(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, 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_position, const Vector2i &p_resolution, int p_screen, Error &r_error) { + KeyMappingMacOS::initialize(); + Input::get_singleton()->set_event_dispatch_function(_dispatch_input_events); r_error = OK; @@ -3602,7 +3853,10 @@ DisplayServerMacOS::DisplayServerMacOS(const String &p_rendering_driver, WindowM CGDisplayRegisterReconfigurationCallback(_displays_arrangement_changed, nullptr); // Init TTS - tts = [[TTS_MacOS alloc] init]; + bool tts_enabled = GLOBAL_GET("audio/general/text_to_speech"); + if (tts_enabled) { + tts = [[TTS_MacOS alloc] init]; + } NSMenuItem *menu_item; NSString *title; @@ -3665,7 +3919,6 @@ DisplayServerMacOS::DisplayServerMacOS(const String &p_rendering_driver, WindowM gl_manager = nullptr; r_error = ERR_UNAVAILABLE; ERR_FAIL_MSG("Could not initialize OpenGL"); - return; } } #endif @@ -3681,12 +3934,14 @@ DisplayServerMacOS::DisplayServerMacOS(const String &p_rendering_driver, WindowM } #endif - Point2i window_position( - screen_get_position(0).x + (screen_get_size(0).width - p_resolution.width) / 2, - screen_get_position(0).y + (screen_get_size(0).height - p_resolution.height) / 2); - + Point2i window_position; if (p_position != nullptr) { window_position = *p_position; + } else { + if (p_screen == SCREEN_OF_MAIN_WINDOW) { + p_screen = SCREEN_PRIMARY; + } + window_position = screen_get_position(p_screen) + (screen_get_size(p_screen) - p_resolution) / 2; } WindowID main_window = _create_window(p_mode, p_vsync_mode, Rect2i(window_position, p_resolution)); @@ -3697,6 +3952,7 @@ DisplayServerMacOS::DisplayServerMacOS(const String &p_rendering_driver, WindowM } } show_window(MAIN_WINDOW_ID); + force_process_and_drop_events(); #if defined(GLES3_ENABLED) if (rendering_driver == "opengl3") { diff --git a/platform/macos/doc_classes/EditorExportPlatformMacOS.xml b/platform/macos/doc_classes/EditorExportPlatformMacOS.xml new file mode 100644 index 0000000000..cef837de07 --- /dev/null +++ b/platform/macos/doc_classes/EditorExportPlatformMacOS.xml @@ -0,0 +1,299 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="EditorExportPlatformMacOS" inherits="EditorExportPlatform" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> + <brief_description> + Exporter for macOS. + </brief_description> + <description> + </description> + <tutorials> + <link title="Exporting for macOS">$DOCS_URL/tutorials/export/exporting_for_macos.html</link> + <link title="Running Godot apps on macOS">$DOCS_URL/tutorials//export/running_on_macos.html</link> + </tutorials> + <members> + <member name="application/app_category" type="String" setter="" getter=""> + Application category for the App Store. + </member> + <member name="application/bundle_identifier" type="String" setter="" getter=""> + Unique application identifier in a reverse-DNS format, can only contain alphanumeric characters ([code]A-Z[/code], [code]a-z[/code], and [code]0-9[/code]), hyphens ([code]-[/code]), and periods ([code].[/code]). + </member> + <member name="application/copyright" type="String" setter="" getter=""> + Copyright notice for the bundle visible to the user (in English). + </member> + <member name="application/copyright_localized" type="Dictionary" setter="" getter=""> + Copyright notice for the bundle visible to the user (localized). + </member> + <member name="application/icon" type="String" setter="" getter=""> + Application icon file. If left empty, it will fallback to [member ProjectSettings.application/config/macos_native_icon], and then to [member ProjectSettings.application/config/icon]. + </member> + <member name="application/icon_interpolation" type="int" setter="" getter=""> + Interpolation method used to resize application icon. + </member> + <member name="application/min_macos_version" type="String" setter="" getter=""> + Minimum version of macOS required for this application to run in the [code]major.minor.patch[/code] or [code]major.minor[/code] format, can only contain numeric characters ([code]0-9[/code]) and periods ([code].[/code]). + </member> + <member name="application/short_version" type="String" setter="" getter=""> + Application version visible to the user, can only contain numeric characters ([code]0-9[/code]) and periods ([code].[/code]). + </member> + <member name="application/signature" type="String" setter="" getter=""> + A four-character creator code that is specific to the bundle. Optional. + </member> + <member name="application/version" type="String" setter="" getter=""> + Machine-readable application version, in the [code]major.minor.patch[/code] format, can only contain numeric characters ([code]0-9[/code]) and periods ([code].[/code]). + </member> + <member name="binary_format/architecture" type="String" setter="" getter=""> + Application executable architecture. + Supported architectures: [code]x86_64[/code], [code]arm64[/code], and [code]universal[/code] ([code]x86_64 + arm64[/code]). + Official export templates include [code]universal[/code] binaries only. + </member> + <member name="codesign/apple_team_id" type="String" setter="" getter=""> + Apple Team ID, unique 10-character string. To locate your Team ID check "Membership details" section in your Apple developer account dashboard, or "Organizational Unit" of your code signing certificate. See [url=https://developer.apple.com/help/account/manage-your-team/locate-your-team-id]Locate your Team ID[/url]. + </member> + <member name="codesign/certificate_file" type="String" setter="" getter=""> + PKCS #12 certificate file used to sign [code].app[/code] bundle. + Can be overridden with the environment variable [code]GODOT_MACOS_CODESIGN_CERTIFICATE_FILE[/code]. + </member> + <member name="codesign/certificate_password" type="String" setter="" getter=""> + Password for the certificate file used to sign [code].app[/code] bundle. + Can be overridden with the environment variable [code]GODOT_MACOS_CODESIGN_CERTIFICATE_PASSWORD[/code]. + </member> + <member name="codesign/codesign" type="int" setter="" getter=""> + Tool to use for code signing. + </member> + <member name="codesign/custom_options" type="PackedStringArray" setter="" getter=""> + Array of the additional command line arguments passed to the code signing tool. + </member> + <member name="codesign/entitlements/address_book" type="bool" setter="" getter=""> + Enable to allow access to contacts in the user's address book, if it's enabled you should also provide usage message in the [code]privacy/address_book_usage_description[/code] option. See [url=https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_personal-information_addressbook]com.apple.security.personal-information.addressbook[/url]. + </member> + <member name="codesign/entitlements/allow_dyld_environment_variables" type="bool" setter="" getter=""> + Allows app to use dynamic linker environment variables to inject code. If you are using add-ons with dynamic or self-modifying native code, enable them according to the add-on documentation. See [url=https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_cs_allow-dyld-environment-variables]com.apple.security.cs.allow-dyld-environment-variables[/url]. + </member> + <member name="codesign/entitlements/allow_jit_code_execution" type="bool" setter="" getter=""> + Allows creating writable and executable memory for JIT code. If you are using add-ons with dynamic or self-modifying native code, enable them according to the add-on documentation. See [url=https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_cs_allow-jit]com.apple.security.cs.allow-jit[/url]. + </member> + <member name="codesign/entitlements/allow_unsigned_executable_memory" type="bool" setter="" getter=""> + Allows creating writable and executable memory without JIT restrictions. If you are using add-ons with dynamic or self-modifying native code, enable them according to the add-on documentation. See [url=https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_cs_allow-unsigned-executable-memory]com.apple.security.cs.allow-unsigned-executable-memory[/url]. + </member> + <member name="codesign/entitlements/app_sandbox/device_bluetooth" type="bool" setter="" getter=""> + Enable to allow app to interact with Bluetooth devices. This entitlement is required to use wireless controllers. See [url=https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_device_bluetooth]com.apple.security.device.bluetooth[/url]. + </member> + <member name="codesign/entitlements/app_sandbox/device_usb" type="bool" setter="" getter=""> + Enable to allow app to interact with USB devices. This entitlement is required to use wired controllers. See [url=https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_device_usb]com.apple.security.device.usb[/url]. + </member> + <member name="codesign/entitlements/app_sandbox/enabled" type="bool" setter="" getter=""> + Enables App Sandbox. The App Sandbox restricts access to user data, networking, and devices. Sandboxed apps can't access most of the file system, can't use custom file dialogs and execute binaries outside the .app bundle. See [url=https://developer.apple.com/documentation/security/app_sandbox]App Sandbox[/url]. + [b]Note:[/b] To distribute an app through the App Store, you must enable the App Sandbox. + </member> + <member name="codesign/entitlements/app_sandbox/files_downloads" type="int" setter="" getter=""> + Allows read or write access to the user's "Downloads" folder. See [url=https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_files_downloads_read-write]com.apple.security.files.downloads.read-write[/url]. + </member> + <member name="codesign/entitlements/app_sandbox/files_movies" type="int" setter="" getter=""> + Allows read or write access to the user's "Movies" folder. See [url=https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_assets_movies_read-write]com.apple.security.files.movies.read-write[/url]. + </member> + <member name="codesign/entitlements/app_sandbox/files_music" type="int" setter="" getter=""> + Allows read or write access to the user's "Music" folder. See [url=https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_assets_music_read-write]com.apple.security.files.music.read-write[/url]. + </member> + <member name="codesign/entitlements/app_sandbox/files_pictures" type="int" setter="" getter=""> + Allows read or write access to the user's "Pictures" folder. See [url=https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_assets_pictures_read-write]com.apple.security.files.pictures.read-write[/url]. + </member> + <member name="codesign/entitlements/app_sandbox/helper_executables" type="Array" setter="" getter=""> + List of helper executables to embedded to the app bundle. Sandboxed app are limited to execute only these executable. See [url=https://developer.apple.com/documentation/xcode/embedding-a-helper-tool-in-a-sandboxed-app]Embedding a command-line tool in a sandboxed app[/url]. + </member> + <member name="codesign/entitlements/app_sandbox/network_client" type="bool" setter="" getter=""> + Enable to allow app to establish outgoing network connections. See [url=https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_network_client]com.apple.security.network.client[/url]. + </member> + <member name="codesign/entitlements/app_sandbox/network_server" type="bool" setter="" getter=""> + Enable to allow app to listen for incoming network connections. See [url=https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_network_server]com.apple.security.network.server[/url]. + </member> + <member name="codesign/entitlements/apple_events" type="bool" setter="" getter=""> + Enable to allow app to send Apple events to other apps. See [url=https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_automation_apple-events]com.apple.security.automation.apple-events[/url]. + </member> + <member name="codesign/entitlements/audio_input" type="bool" setter="" getter=""> + Enable if you need to use the microphone or other audio input sources, if it's enabled you should also provide usage message in the [code]privacy/microphone_usage_description[/code] option. See [url=https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_device_audio-input]com.apple.security.device.audio-input[/url]. + </member> + <member name="codesign/entitlements/calendars" type="bool" setter="" getter=""> + Enable to allow access to the user's calendar, if it's enabled you should also provide usage message in the [code]privacy/calendar_usage_description[/code] option. See [url=https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_personal-information_calendars]com.apple.security.personal-information.calendars[/url]. + </member> + <member name="codesign/entitlements/camera" type="bool" setter="" getter=""> + Enable if you need to use the camera, if it's enabled you should also provide usage message in the [code]privacy/camera_usage_description[/code] option. See [url=https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_device_camera]com.apple.security.device.camera[/url]. + </member> + <member name="codesign/entitlements/custom_file" type="String" setter="" getter=""> + Custom entitlements [code].plist[/code] file, if specified the rest of entitlements in the export config are ignored. + </member> + <member name="codesign/entitlements/debugging" type="bool" setter="" getter=""> + You can temporarily enable this entitlement to use native debugger (GDB, LLDB) with the exported app. This entitlement should be disabled for production export. See [url=https://developer.apple.com/documentation/xcode/embedding-a-helper-tool-in-a-sandboxed-app]Embedding a command-line tool in a sandboxed app[/url]. + </member> + <member name="codesign/entitlements/disable_library_validation" type="bool" setter="" getter=""> + Allows app to load arbitrary libraries and frameworks (not signed with the same Team ID as the main executable or by Apple). Enable it if you are using GDExtension add-ons or ad-hoc signing, or want to support user-provided external add-ons. See [url=https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_cs_disable-library-validation]com.apple.security.cs.disable-library-validation[/url]. + </member> + <member name="codesign/entitlements/location" type="bool" setter="" getter=""> + Enable if you need to use location information from Location Services, if it's enabled you should also provide usage message in the [code]privacy/location_usage_description[/code] option. See [url=https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_personal-information_location]com.apple.security.personal-information.location[/url]. + </member> + <member name="codesign/entitlements/photos_library" type="bool" setter="" getter=""> + Enable to allow access to the user's Photos library, if it's enabled you should also provide usage message in the [code]privacy/photos_library_usage_description[/code] option. See [url=https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_personal-information_photos-library]com.apple.security.personal-information.photos-library[/url]. + </member> + <member name="codesign/identity" type="String" setter="" getter=""> + The "Full Name", "Common Name" or SHA-1 hash of the signing identity used to sign [code].app[/code] bundle. + </member> + <member name="codesign/installer_identity" type="String" setter="" getter=""> + The "Full Name", "Common Name" or SHA-1 hash of the signing identity used to sign [code].pkg[/code] installer package for App Store distribution, use [code]3rd Party Mac Developer Installer: Name.[/code] identity. + </member> + <member name="codesign/provisioning_profile" type="String" setter="" getter=""> + Provisioning profile file downloaded from Apple developer account dashboard. See [url=https://developer.apple.com/help/account/manage-profiles/edit-download-or-delete-profiles]Edit, download, or delete provisioning profiles[/url]. + Can be overridden with the environment variable [code]GODOT_MACOS_CODESIGN_PROVISIONING_PROFILE[/code]. + </member> + <member name="custom_template/debug" type="String" setter="" getter=""> + Path to the custom export template. If left empty, default template is used. + </member> + <member name="custom_template/release" type="String" setter="" getter=""> + Path to the custom export template. If left empty, default template is used. + </member> + <member name="debug/export_console_wrapper" type="int" setter="" getter=""> + If enabled, a wrapper that can be used to run the application with console output is created alongside the exported application. + </member> + <member name="display/high_res" type="bool" setter="" getter=""> + If [code]true[/code], the application is rendered at native display resolution, otherwise it is always rendered at loHPI resolution and upscaled by OS when required. + </member> + <member name="export/distribution_type" type="int" setter="" getter=""> + Application distribution target. + </member> + <member name="notarization/api_key" type="String" setter="" getter=""> + Apple App Store Connect API issuer key file. + Can be overridden with the environment variable [code]GODOT_MACOS_NOTARIZATION_API_KEY[/code]. + </member> + <member name="notarization/api_key_id" type="String" setter="" getter=""> + Apple App Store Connect API issuer key ID. + Can be overridden with the environment variable [code]GODOT_MACOS_NOTARIZATION_API_KEY_ID[/code]. + </member> + <member name="notarization/api_uuid" type="String" setter="" getter=""> + Apple App Store Connect API issuer UUID. + Can be overridden with the environment variable [code]GODOT_MACOS_NOTARIZATION_API_UUID[/code]. + </member> + <member name="notarization/apple_id_name" type="String" setter="" getter=""> + Apple ID account name (email address). + Can be overridden with the environment variable [code]GODOT_MACOS_NOTARIZATION_APPLE_ID_NAME[/code]. + </member> + <member name="notarization/apple_id_password" type="String" setter="" getter=""> + Apple ID app-specific password. + Can be overridden with the environment variable [code]GODOT_MACOS_NOTARIZATION_APPLE_ID_PASSWORD[/code]. + </member> + <member name="notarization/notarization" type="int" setter="" getter=""> + Tool to use for notarization. + </member> + <member name="privacy/address_book_usage_description" type="String" setter="" getter=""> + A message displayed when requesting access to the user's contacts (in English). + </member> + <member name="privacy/address_book_usage_description_localized" type="Dictionary" setter="" getter=""> + A message displayed when requesting access to the user's contacts (localized). + </member> + <member name="privacy/calendar_usage_description" type="String" setter="" getter=""> + A message displayed when requesting access to the user's calendar data (in English). + </member> + <member name="privacy/calendar_usage_description_localized" type="Dictionary" setter="" getter=""> + A message displayed when requesting access to the user's calendar data (localized). + </member> + <member name="privacy/camera_usage_description" type="String" setter="" getter=""> + A message displayed when requesting access to the device's camera (in English). + </member> + <member name="privacy/camera_usage_description_localized" type="Dictionary" setter="" getter=""> + A message displayed when requesting access to the device's camera (localized). + </member> + <member name="privacy/desktop_folder_usage_description" type="String" setter="" getter=""> + A message displayed when requesting access to the user's "Desktop" folder (in English). + </member> + <member name="privacy/desktop_folder_usage_description_localized" type="Dictionary" setter="" getter=""> + A message displayed when requesting access to the user's "Desktop" folder (localized). + </member> + <member name="privacy/documents_folder_usage_description" type="String" setter="" getter=""> + A message displayed when requesting access to the user's "Documents" folder (in English). + </member> + <member name="privacy/documents_folder_usage_description_localized" type="Dictionary" setter="" getter=""> + A message displayed when requesting access to the user's "Documents" folder (localized). + </member> + <member name="privacy/downloads_folder_usage_description" type="String" setter="" getter=""> + A message displayed when requesting access to the user's "Downloads" folder (in English). + </member> + <member name="privacy/downloads_folder_usage_description_localized" type="Dictionary" setter="" getter=""> + A message displayed when requesting access to the user's "Downloads" folder (localized). + </member> + <member name="privacy/location_usage_description" type="String" setter="" getter=""> + A message displayed when requesting access to the user's location information (in English). + </member> + <member name="privacy/location_usage_description_localized" type="Dictionary" setter="" getter=""> + A message displayed when requesting access to the user's location information (localized). + </member> + <member name="privacy/microphone_usage_description" type="String" setter="" getter=""> + A message displayed when requesting access to the device's microphone (in English). + </member> + <member name="privacy/microphone_usage_description_localized" type="Dictionary" setter="" getter=""> + A message displayed when requesting access to the device's microphone (localized). + </member> + <member name="privacy/network_volumes_usage_description" type="String" setter="" getter=""> + A message displayed when requesting access to the user's network drives (in English). + </member> + <member name="privacy/network_volumes_usage_description_localized" type="Dictionary" setter="" getter=""> + A message displayed when requesting access to the user's network drives (localized). + </member> + <member name="privacy/photos_library_usage_description" type="String" setter="" getter=""> + A message displayed when requesting access to the user's photo library (in English). + </member> + <member name="privacy/photos_library_usage_description_localized" type="Dictionary" setter="" getter=""> + A message displayed when requesting access to the user's photo library (localized). + </member> + <member name="privacy/removable_volumes_usage_description" type="String" setter="" getter=""> + A message displayed when requesting access to the user's removable drives (in English). + </member> + <member name="privacy/removable_volumes_usage_description_localized" type="Dictionary" setter="" getter=""> + A message displayed when requesting access to the user's removable drives (localized). + </member> + <member name="ssh_remote_deploy/cleanup_script" type="String" setter="" getter=""> + Script code to execute on the remote host when app is finished. + The following variables can be used in the script: + - [code]{temp_dir}[/code] - Path of temporary folder on the remote, used to upload app and scripts to. + - [code]{archive_name}[/code] - Name of the ZIP containing uploaded application. + - [code]{exe_name}[/code] - Name of application executable. + - [code]{cmd_args}[/code] - Array of the command line argument for the application. + </member> + <member name="ssh_remote_deploy/enabled" type="bool" setter="" getter=""> + Enables remote deploy using SSH/SCP. + </member> + <member name="ssh_remote_deploy/extra_args_scp" type="String" setter="" getter=""> + Array of the additional command line arguments passed to the SCP. + </member> + <member name="ssh_remote_deploy/extra_args_ssh" type="String" setter="" getter=""> + Array of the additional command line arguments passed to the SSH. + </member> + <member name="ssh_remote_deploy/host" type="String" setter="" getter=""> + Remote host SSH user name and address, in [code]user@address[/code] format. + </member> + <member name="ssh_remote_deploy/port" type="String" setter="" getter=""> + Remote host SSH port number. + </member> + <member name="ssh_remote_deploy/run_script" type="String" setter="" getter=""> + Script code to execute on the remote host when running the app. + The following variables can be used in the script: + - [code]{temp_dir}[/code] - Path of temporary folder on the remote, used to upload app and scripts to. + - [code]{archive_name}[/code] - Name of the ZIP containing uploaded application. + - [code]{exe_name}[/code] - Name of application executable. + - [code]{cmd_args}[/code] - Array of the command line argument for the application. + </member> + <member name="xcode/platform_build" type="String" setter="" getter=""> + macOS build number used to build application executable. + </member> + <member name="xcode/sdk_build" type="String" setter="" getter=""> + macOS SDK build number used to build application executable. + </member> + <member name="xcode/sdk_name" type="String" setter="" getter=""> + macOS SDK name used to build application executable. + </member> + <member name="xcode/sdk_version" type="String" setter="" getter=""> + macOS SDK version used to build application executable in the [code]major.minor[/code] format. + </member> + <member name="xcode/xcode_build" type="String" setter="" getter=""> + Xcode build number used to build application executable. + </member> + <member name="xcode/xcode_version" type="String" setter="" getter=""> + Xcode version used to build application executable. + </member> + </members> +</class> diff --git a/platform/macos/export/codesign.cpp b/platform/macos/export/codesign.cpp index c2bdf555d0..a1ec06b5f6 100644 --- a/platform/macos/export/codesign.cpp +++ b/platform/macos/export/codesign.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* codesign.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* codesign.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "codesign.h" diff --git a/platform/macos/export/codesign.h b/platform/macos/export/codesign.h index 01e97bca81..3e61751a96 100644 --- a/platform/macos/export/codesign.h +++ b/platform/macos/export/codesign.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* codesign.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* codesign.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 MACOS_CODESIGN_H #define MACOS_CODESIGN_H @@ -41,6 +41,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. +#include "plist.h" + #include "core/crypto/crypto_core.h" #include "core/io/dir_access.h" #include "core/io/file_access.h" @@ -51,8 +53,6 @@ #include "modules/regex/regex.h" #endif -#include "plist.h" - #ifdef MODULE_REGEX_ENABLED /*************************************************************************/ diff --git a/platform/macos/export/export.cpp b/platform/macos/export/export.cpp index 5f9cf22ccf..8930974df9 100644 --- a/platform/macos/export/export.cpp +++ b/platform/macos/export/export.cpp @@ -1,37 +1,41 @@ -/*************************************************************************/ -/* export.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* export.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "export.h" #include "export_plugin.h" +void register_macos_exporter_types() { + GDREGISTER_VIRTUAL_CLASS(EditorExportPlatformMacOS); +} + void register_macos_exporter() { #ifndef ANDROID_ENABLED EDITOR_DEF("export/macos/rcodesign", ""); diff --git a/platform/macos/export/export.h b/platform/macos/export/export.h index 260c691209..a7a7dcad16 100644 --- a/platform/macos/export/export.h +++ b/platform/macos/export/export.h @@ -1,36 +1,37 @@ -/*************************************************************************/ -/* export.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* export.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 MACOS_EXPORT_H #define MACOS_EXPORT_H +void register_macos_exporter_types(); void register_macos_exporter(); #endif // MACOS_EXPORT_H diff --git a/platform/macos/export/export_plugin.cpp b/platform/macos/export/export_plugin.cpp index de6016cb9b..802c8d42c3 100644 --- a/platform/macos/export/export_plugin.cpp +++ b/platform/macos/export/export_plugin.cpp @@ -1,65 +1,252 @@ -/*************************************************************************/ -/* export_plugin.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* export_plugin.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "export_plugin.h" +#include "../logo_svg.gen.h" +#include "../run_icon_svg.gen.h" #include "codesign.h" #include "lipo.h" #include "macho.h" +#include "core/io/image_loader.h" #include "core/string/translation.h" #include "editor/editor_node.h" #include "editor/editor_paths.h" +#include "editor/editor_scale.h" -#include "modules/modules_enabled.gen.h" // For regex. +#include "modules/modules_enabled.gen.h" // For svg and regex. +#ifdef MODULE_SVG_ENABLED +#include "modules/svg/image_loader_svg.h" +#endif void EditorExportPlatformMacOS::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const { - if (p_preset->get("texture_format/s3tc")) { + r_features->push_back(p_preset->get("binary_format/architecture")); + String architecture = p_preset->get("binary_format/architecture"); + + if (architecture == "universal" || architecture == "x86_64") { r_features->push_back("s3tc"); - } - if (p_preset->get("texture_format/etc")) { - r_features->push_back("etc"); - } - if (p_preset->get("texture_format/etc2")) { + r_features->push_back("bptc"); + } else if (architecture == "arm64") { r_features->push_back("etc2"); + r_features->push_back("astc"); + } else { + ERR_PRINT("Invalid architecture"); } - r_features->push_back(p_preset->get("binary_format/architecture")); } -bool EditorExportPlatformMacOS::get_export_option_visibility(const EditorExportPreset *p_preset, const String &p_option, const HashMap<StringName, Variant> &p_options) const { +String EditorExportPlatformMacOS::get_export_option_warning(const EditorExportPreset *p_preset, const StringName &p_name) const { + if (p_preset) { + int dist_type = p_preset->get("export/distribution_type"); + bool ad_hoc = false; + int codesign_tool = p_preset->get("codesign/codesign"); + int notary_tool = p_preset->get("notarization/notarization"); + switch (codesign_tool) { + case 1: { // built-in ad-hoc + ad_hoc = true; + } break; + case 2: { // "rcodesign" + ad_hoc = p_preset->get_or_env("codesign/certificate_file", ENV_MAC_CODESIGN_CERT_FILE).operator String().is_empty() || p_preset->get_or_env("codesign/certificate_password", ENV_MAC_CODESIGN_CERT_FILE).operator String().is_empty(); + } break; +#ifdef MACOS_ENABLED + case 3: { // "codesign" + ad_hoc = (p_preset->get("codesign/identity") == "" || p_preset->get("codesign/identity") == "-"); + } break; +#endif + default: { + }; + } + + if (p_name == "application/bundle_identifier") { + String identifier = p_preset->get("application/bundle_identifier"); + String pn_err; + if (!is_package_name_valid(identifier, &pn_err)) { + return TTR("Invalid bundle identifier:") + " " + pn_err; + } + } + + if (p_name == "codesign/certificate_file" || p_name == "codesign/certificate_password" || p_name == "codesign/identity") { + if (dist_type == 2) { + if (ad_hoc) { + return TTR("App Store distribution with ad-hoc code signing is not supported."); + } + } else if (notary_tool > 0 && ad_hoc) { + return TTR("Notarization with an ad-hoc signature is not supported."); + } + } + + if (p_name == "codesign/apple_team_id") { + String team_id = p_preset->get("codesign/apple_team_id"); + if (team_id.is_empty()) { + if (dist_type == 2) { + return TTR("Apple Team ID is required for App Store distribution."); + } else if (notary_tool > 0) { + return TTR("Apple Team ID is required for notarization."); + } + } + } + + if (p_name == "codesign/provisioning_profile" && dist_type == 2) { + String pprof = p_preset->get_or_env("codesign/provisioning_profile", ENV_MAC_CODESIGN_PROFILE); + if (pprof.is_empty()) { + return TTR("Provisioning profile is required for App Store distribution."); + } + } + + if (p_name == "codesign/installer_identity" && dist_type == 2) { + String ident = p_preset->get("codesign/installer_identity"); + if (ident.is_empty()) { + return TTR("Installer signing identity is required for App Store distribution."); + } + } + + if (p_name == "codesign/entitlements/app_sandbox/enabled" && dist_type == 2) { + bool sandbox = p_preset->get("codesign/entitlements/app_sandbox/enabled"); + if (!sandbox) { + return TTR("App sandbox is required for App Store distribution."); + } + } + + if (p_name == "codesign/codesign") { + if (dist_type == 2) { + if (codesign_tool == 0) { + return TTR("Code signing is required for App Store distribution."); + } + if (codesign_tool == 1) { + return TTR("App Store distribution with ad-hoc code signing is not supported."); + } + } else if (notary_tool > 0) { + if (codesign_tool == 0) { + return TTR("Code signing is required for notarization."); + } + if (codesign_tool == 1) { + return TTR("Notarization with an ad-hoc signature is not supported."); + } + } + } + + if (notary_tool == 2 || notary_tool == 3) { + if (p_name == "notarization/apple_id_name" || p_name == "notarization/api_uuid") { + String apple_id = p_preset->get_or_env("notarization/apple_id_name", ENV_MAC_NOTARIZATION_APPLE_ID); + String api_uuid = p_preset->get_or_env("notarization/api_uuid", ENV_MAC_NOTARIZATION_UUID); + if (apple_id.is_empty() && api_uuid.is_empty()) { + return TTR("Neither Apple ID name nor App Store Connect issuer ID name not specified."); + } + if (!apple_id.is_empty() && !api_uuid.is_empty()) { + return TTR("Both Apple ID name and App Store Connect issuer ID name are specified, only one should be set at the same time."); + } + } + if (p_name == "notarization/apple_id_password") { + String apple_id = p_preset->get_or_env("notarization/apple_id_name", ENV_MAC_NOTARIZATION_APPLE_ID); + String apple_pass = p_preset->get_or_env("notarization/apple_id_password", ENV_MAC_NOTARIZATION_APPLE_PASS); + if (!apple_id.is_empty() && apple_pass.is_empty()) { + return TTR("Apple ID password not specified."); + } + } + if (p_name == "notarization/api_key_id") { + String api_uuid = p_preset->get_or_env("notarization/api_uuid", ENV_MAC_NOTARIZATION_UUID); + String api_key = p_preset->get_or_env("notarization/api_key_id", ENV_MAC_NOTARIZATION_KEY_ID); + if (!api_uuid.is_empty() && api_key.is_empty()) { + return TTR("App Store Connect API key ID not specified."); + } + } + } else if (notary_tool == 1) { + if (p_name == "notarization/api_uuid") { + String api_uuid = p_preset->get_or_env("notarization/api_uuid", ENV_MAC_NOTARIZATION_UUID); + if (api_uuid.is_empty()) { + return TTR("App Store Connect issuer ID name not specified."); + } + } + if (p_name == "notarization/api_key_id") { + String api_key = p_preset->get_or_env("notarization/api_key_id", ENV_MAC_NOTARIZATION_KEY_ID); + if (api_key.is_empty()) { + return TTR("App Store Connect API key ID not specified."); + } + } + } + + if (codesign_tool > 0) { + if (p_name == "privacy/microphone_usage_description") { + String discr = p_preset->get("privacy/microphone_usage_description"); + bool enabled = p_preset->get("codesign/entitlements/audio_input"); + if (enabled && discr.is_empty()) { + return TTR("Microphone access is enabled, but usage description is not specified."); + } + } + if (p_name == "privacy/camera_usage_description") { + String discr = p_preset->get("privacy/camera_usage_description"); + bool enabled = p_preset->get("codesign/entitlements/camera"); + if (enabled && discr.is_empty()) { + return TTR("Camera access is enabled, but usage description is not specified."); + } + } + if (p_name == "privacy/location_usage_description") { + String discr = p_preset->get("privacy/location_usage_description"); + bool enabled = p_preset->get("codesign/entitlements/location"); + if (enabled && discr.is_empty()) { + return TTR("Location information access is enabled, but usage description is not specified."); + } + } + if (p_name == "privacy/address_book_usage_description") { + String discr = p_preset->get("privacy/address_book_usage_description"); + bool enabled = p_preset->get("codesign/entitlements/address_book"); + if (enabled && discr.is_empty()) { + return TTR("Address book access is enabled, but usage description is not specified."); + } + } + if (p_name == "privacy/calendar_usage_description") { + String discr = p_preset->get("privacy/calendar_usage_description"); + bool enabled = p_preset->get("codesign/entitlements/calendars"); + if (enabled && discr.is_empty()) { + return TTR("Calendar access is enabled, but usage description is not specified."); + } + } + if (p_name == "privacy/photos_library_usage_description") { + String discr = p_preset->get("privacy/photos_library_usage_description"); + bool enabled = p_preset->get("codesign/entitlements/photos_library"); + if (enabled && discr.is_empty()) { + return TTR("Photo library access is enabled, but usage description is not specified."); + } + } + } + } + return String(); +} + +bool EditorExportPlatformMacOS::get_export_option_visibility(const EditorExportPreset *p_preset, const String &p_option) const { // Hide irrelevant code signing options. if (p_preset) { int codesign_tool = p_preset->get("codesign/codesign"); switch (codesign_tool) { case 1: { // built-in ad-hoc - if (p_option == "codesign/identity" || p_option == "codesign/certificate_file" || p_option == "codesign/certificate_password" || p_option == "codesign/custom_options") { + if (p_option == "codesign/identity" || p_option == "codesign/certificate_file" || p_option == "codesign/certificate_password" || p_option == "codesign/custom_options" || p_option == "codesign/team_id") { return false; } } break; @@ -76,25 +263,59 @@ bool EditorExportPlatformMacOS::get_export_option_visibility(const EditorExportP } break; #endif default: { // disabled - if (p_option == "codesign/identity" || p_option == "codesign/certificate_file" || p_option == "codesign/certificate_password" || p_option == "codesign/custom_options" || p_option.begins_with("codesign/entitlements")) { + if (p_option == "codesign/identity" || p_option == "codesign/certificate_file" || p_option == "codesign/certificate_password" || p_option == "codesign/custom_options" || p_option.begins_with("codesign/entitlements") || p_option == "codesign/team_id") { return false; } } break; } + // Distribution type. + int dist_type = p_preset->get("export/distribution_type"); + if (dist_type != 2 && p_option == "codesign/installer_identity") { + return false; + } + + if (dist_type == 2 && p_option.begins_with("notarization/")) { + return false; + } + + if (dist_type != 2 && p_option == "codesign/provisioning_profile") { + return false; + } + + String custom_prof = p_preset->get("codesign/entitlements/custom_file"); + if (!custom_prof.is_empty() && p_option != "codesign/entitlements/custom_file" && p_option.begins_with("codesign/entitlements/")) { + return false; + } + + // Hide sandbox entitlements. + bool sandbox = p_preset->get("codesign/entitlements/app_sandbox/enabled"); + if (!sandbox && p_option != "codesign/entitlements/app_sandbox/enabled" && p_option.begins_with("codesign/entitlements/app_sandbox/")) { + return false; + } + + // Hide SSH options. + bool ssh = p_preset->get("ssh_remote_deploy/enabled"); + if (!ssh && p_option != "ssh_remote_deploy/enabled" && p_option.begins_with("ssh_remote_deploy/")) { + return false; + } + // Hide irrelevant notarization options. int notary_tool = p_preset->get("notarization/notarization"); switch (notary_tool) { case 1: { // "rcodesign" - if (p_option == "notarization/apple_id_name" || p_option == "notarization/apple_id_password" || p_option == "notarization/apple_team_id") { + if (p_option == "notarization/apple_id_name" || p_option == "notarization/apple_id_password") { return false; } } break; - case 2: { // "altool" + case 2: { // "notarytool" + // All options are visible. + } break; + case 3: { // "altool" // All options are visible. } break; default: { // disabled - if (p_option == "notarization/apple_id_name" || p_option == "notarization/apple_id_password" || p_option == "notarization/apple_team_id" || p_option == "notarization/api_uuid" || p_option == "notarization/api_key") { + if (p_option == "notarization/apple_id_name" || p_option == "notarization/apple_id_password" || p_option == "notarization/api_uuid" || p_option == "notarization/api_key" || p_option == "notarization/api_key_id") { return false; } } break; @@ -110,34 +331,79 @@ bool EditorExportPlatformMacOS::get_export_option_visibility(const EditorExportP return true; } -void EditorExportPlatformMacOS::get_export_options(List<ExportOption> *r_options) { +List<String> EditorExportPlatformMacOS::get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const { + List<String> list; + + if (p_preset.is_valid()) { + int dist_type = p_preset->get("export/distribution_type"); + if (dist_type == 0) { +#ifdef MACOS_ENABLED + list.push_back("dmg"); +#endif + list.push_back("zip"); + list.push_back("app"); + } else if (dist_type == 1) { +#ifdef MACOS_ENABLED + list.push_back("dmg"); +#endif + list.push_back("zip"); + } else if (dist_type == 2) { +#ifdef MACOS_ENABLED + list.push_back("pkg"); +#endif + } + } + + return list; +} + +void EditorExportPlatformMacOS::get_export_options(List<ExportOption> *r_options) const { +#ifdef MACOS_ENABLED + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "export/distribution_type", PROPERTY_HINT_ENUM, "Testing,Distribution,App Store"), 1, true)); +#else + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "export/distribution_type", PROPERTY_HINT_ENUM, "Testing,Distribution"), 1, true)); +#endif + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "binary_format/architecture", PROPERTY_HINT_ENUM, "universal,x86_64,arm64", PROPERTY_USAGE_STORAGE), "universal")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "debug/export_console_script", PROPERTY_HINT_ENUM, "No,Debug Only,Debug and Release"), 1)); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/icon", PROPERTY_HINT_FILE, "*.png,*.icns"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/bundle_identifier", PROPERTY_HINT_PLACEHOLDER_TEXT, "com.example.game"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "debug/export_console_wrapper", PROPERTY_HINT_ENUM, "No,Debug Only,Debug and Release"), 1)); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/icon", PROPERTY_HINT_FILE, "*.icns,*.png,*.webp,*.svg"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "application/icon_interpolation", PROPERTY_HINT_ENUM, "Nearest neighbor,Bilinear,Cubic,Trilinear,Lanczos"), 4)); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/bundle_identifier", PROPERTY_HINT_PLACEHOLDER_TEXT, "com.example.game"), "", false, true)); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/signature"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/app_category", PROPERTY_HINT_ENUM, "Business,Developer-tools,Education,Entertainment,Finance,Games,Action-games,Adventure-games,Arcade-games,Board-games,Card-games,Casino-games,Dice-games,Educational-games,Family-games,Kids-games,Music-games,Puzzle-games,Racing-games,Role-playing-games,Simulation-games,Sports-games,Strategy-games,Trivia-games,Word-games,Graphics-design,Healthcare-fitness,Lifestyle,Medical,Music,News,Photography,Productivity,Reference,Social-networking,Sports,Travel,Utilities,Video,Weather"), "Games")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/short_version"), "1.0")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/version"), "1.0")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/copyright"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::DICTIONARY, "application/copyright_localized", PROPERTY_HINT_LOCALIZABLE_STRING), Dictionary())); - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "display/high_res"), false)); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/min_macos_version"), "10.12")); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "display/high_res"), true)); + + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "xcode/platform_build"), "14C18")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "xcode/sdk_version"), "13.1")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "xcode/sdk_build"), "22C55")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "xcode/sdk_name"), "macosx13.1")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "xcode/xcode_version"), "1420")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "xcode/xcode_build"), "14C18")); #ifdef MACOS_ENABLED - r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "codesign/codesign", PROPERTY_HINT_ENUM, "Disabled,Built-in (ad-hoc only),PyOxidizer rcodesign,Xcode codesign"), 3, true)); + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "codesign/codesign", PROPERTY_HINT_ENUM, "Disabled,Built-in (ad-hoc only),rcodesign,Xcode codesign"), 3, true)); #else - r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "codesign/codesign", PROPERTY_HINT_ENUM, "Disabled,Built-in (ad-hoc only),PyOxidizer rcodesign"), 1, true)); + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "codesign/codesign", PROPERTY_HINT_ENUM, "Disabled,Built-in (ad-hoc only),rcodesign"), 1, true, true)); #endif + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/installer_identity", PROPERTY_HINT_PLACEHOLDER_TEXT, "3rd Party Mac Developer Installer: (ID)"), "", false, true)); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/apple_team_id", PROPERTY_HINT_PLACEHOLDER_TEXT, "ID"), "", false, true)); // "codesign" only options: r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/identity", PROPERTY_HINT_PLACEHOLDER_TEXT, "Type: Name (ID)"), "")); // "rcodesign" only options: - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/certificate_file", PROPERTY_HINT_GLOBAL_FILE, "*.pfx,*.p12"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/certificate_password", PROPERTY_HINT_PASSWORD), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/certificate_file", PROPERTY_HINT_GLOBAL_FILE, "*.pfx,*.p12", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/certificate_password", PROPERTY_HINT_PASSWORD, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), "")); // "codesign" and "rcodesign" only options: - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/entitlements/custom_file", PROPERTY_HINT_GLOBAL_FILE, "*.plist"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/provisioning_profile", PROPERTY_HINT_GLOBAL_FILE, "*.provisionprofile", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), "", false, true)); + + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/entitlements/custom_file", PROPERTY_HINT_GLOBAL_FILE, "*.plist"), "", true)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/allow_jit_code_execution"), false)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/allow_unsigned_executable_memory"), false)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/allow_dyld_environment_variables"), false)); @@ -150,7 +416,7 @@ void EditorExportPlatformMacOS::get_export_options(List<ExportOption> *r_options r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/photos_library"), false)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/apple_events"), false)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/debugging"), false)); - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/app_sandbox/enabled"), false)); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/app_sandbox/enabled"), false, true, true)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/app_sandbox/network_server"), false)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/app_sandbox/network_client"), false)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/app_sandbox/device_usb"), false)); @@ -163,44 +429,57 @@ void EditorExportPlatformMacOS::get_export_options(List<ExportOption> *r_options r_options->push_back(ExportOption(PropertyInfo(Variant::PACKED_STRING_ARRAY, "codesign/custom_options"), PackedStringArray())); #ifdef MACOS_ENABLED - r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "notarization/notarization", PROPERTY_HINT_ENUM, "Disabled,PyOxidizer rcodesign,Xcode altool"), 0, true)); + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "notarization/notarization", PROPERTY_HINT_ENUM, "Disabled,rcodesign,Xcode notarytool,Xcode altool (deprecated)"), 0, true)); #else - r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "notarization/notarization", PROPERTY_HINT_ENUM, "Disabled,PyOxidizer rcodesign"), 0, true)); + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "notarization/notarization", PROPERTY_HINT_ENUM, "Disabled,rcodesign"), 0, true)); #endif - // "altool" only options: - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "notarization/apple_id_name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Apple ID email"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "notarization/apple_id_password", PROPERTY_HINT_PASSWORD, "Enable two-factor authentication and provide app-specific password"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "notarization/apple_team_id", PROPERTY_HINT_PLACEHOLDER_TEXT, "Provide team ID if your Apple ID belongs to multiple teams"), "")); - // "altool" and "rcodesign" only options: - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "notarization/api_uuid", PROPERTY_HINT_PLACEHOLDER_TEXT, "App Store Connect issuer ID"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "notarization/api_key", PROPERTY_HINT_PLACEHOLDER_TEXT, "App Store Connect API key ID"), "")); - - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/microphone_usage_description", PROPERTY_HINT_PLACEHOLDER_TEXT, "Provide a message if you need to use the microphone"), "")); + // "altool" and "notarytool" only options: + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "notarization/apple_id_name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Apple ID email", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), "", false, true)); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "notarization/apple_id_password", PROPERTY_HINT_PASSWORD, "Enable two-factor authentication and provide app-specific password", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), "", false, true)); + // "altool", "notarytool" and "rcodesign" only options: + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "notarization/api_uuid", PROPERTY_HINT_PLACEHOLDER_TEXT, "App Store Connect issuer ID UUID", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), "", false, true)); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "notarization/api_key", PROPERTY_HINT_GLOBAL_FILE, "*.p8", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), "", false, true)); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "notarization/api_key_id", PROPERTY_HINT_PLACEHOLDER_TEXT, "App Store Connect API key ID", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), "", false, true)); + + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/microphone_usage_description", PROPERTY_HINT_PLACEHOLDER_TEXT, "Provide a message if you need to use the microphone"), "", false, true)); r_options->push_back(ExportOption(PropertyInfo(Variant::DICTIONARY, "privacy/microphone_usage_description_localized", PROPERTY_HINT_LOCALIZABLE_STRING), Dictionary())); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/camera_usage_description", PROPERTY_HINT_PLACEHOLDER_TEXT, "Provide a message if you need to use the camera"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/camera_usage_description", PROPERTY_HINT_PLACEHOLDER_TEXT, "Provide a message if you need to use the camera"), "", false, true)); r_options->push_back(ExportOption(PropertyInfo(Variant::DICTIONARY, "privacy/camera_usage_description_localized", PROPERTY_HINT_LOCALIZABLE_STRING), Dictionary())); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/location_usage_description", PROPERTY_HINT_PLACEHOLDER_TEXT, "Provide a message if you need to use the location information"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/location_usage_description", PROPERTY_HINT_PLACEHOLDER_TEXT, "Provide a message if you need to use the location information"), "", false, true)); r_options->push_back(ExportOption(PropertyInfo(Variant::DICTIONARY, "privacy/location_usage_description_localized", PROPERTY_HINT_LOCALIZABLE_STRING), Dictionary())); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/address_book_usage_description", PROPERTY_HINT_PLACEHOLDER_TEXT, "Provide a message if you need to use the address book"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/address_book_usage_description", PROPERTY_HINT_PLACEHOLDER_TEXT, "Provide a message if you need to use the address book"), "", false, true)); r_options->push_back(ExportOption(PropertyInfo(Variant::DICTIONARY, "privacy/address_book_usage_description_localized", PROPERTY_HINT_LOCALIZABLE_STRING), Dictionary())); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/calendar_usage_description", PROPERTY_HINT_PLACEHOLDER_TEXT, "Provide a message if you need to use the calendar"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/calendar_usage_description", PROPERTY_HINT_PLACEHOLDER_TEXT, "Provide a message if you need to use the calendar"), "", false, true)); r_options->push_back(ExportOption(PropertyInfo(Variant::DICTIONARY, "privacy/calendar_usage_description_localized", PROPERTY_HINT_LOCALIZABLE_STRING), Dictionary())); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/photos_library_usage_description", PROPERTY_HINT_PLACEHOLDER_TEXT, "Provide a message if you need to use the photo library"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/photos_library_usage_description", PROPERTY_HINT_PLACEHOLDER_TEXT, "Provide a message if you need to use the photo library"), "", false, true)); r_options->push_back(ExportOption(PropertyInfo(Variant::DICTIONARY, "privacy/photos_library_usage_description_localized", PROPERTY_HINT_LOCALIZABLE_STRING), Dictionary())); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/desktop_folder_usage_description", PROPERTY_HINT_PLACEHOLDER_TEXT, "Provide a message if you need to use Desktop folder"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/desktop_folder_usage_description", PROPERTY_HINT_PLACEHOLDER_TEXT, "Provide a message if you need to use Desktop folder"), "", false, true)); r_options->push_back(ExportOption(PropertyInfo(Variant::DICTIONARY, "privacy/desktop_folder_usage_description_localized", PROPERTY_HINT_LOCALIZABLE_STRING), Dictionary())); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/documents_folder_usage_description", PROPERTY_HINT_PLACEHOLDER_TEXT, "Provide a message if you need to use Documents folder"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/documents_folder_usage_description", PROPERTY_HINT_PLACEHOLDER_TEXT, "Provide a message if you need to use Documents folder"), "", false, true)); r_options->push_back(ExportOption(PropertyInfo(Variant::DICTIONARY, "privacy/documents_folder_usage_description_localized", PROPERTY_HINT_LOCALIZABLE_STRING), Dictionary())); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/downloads_folder_usage_description", PROPERTY_HINT_PLACEHOLDER_TEXT, "Provide a message if you need to use Downloads folder"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/downloads_folder_usage_description", PROPERTY_HINT_PLACEHOLDER_TEXT, "Provide a message if you need to use Downloads folder"), "", false, true)); r_options->push_back(ExportOption(PropertyInfo(Variant::DICTIONARY, "privacy/downloads_folder_usage_description_localized", PROPERTY_HINT_LOCALIZABLE_STRING), Dictionary())); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/network_volumes_usage_description", PROPERTY_HINT_PLACEHOLDER_TEXT, "Provide a message if you need to use network volumes"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/network_volumes_usage_description", PROPERTY_HINT_PLACEHOLDER_TEXT, "Provide a message if you need to use network volumes"), "", false, true)); r_options->push_back(ExportOption(PropertyInfo(Variant::DICTIONARY, "privacy/network_volumes_usage_description_localized", PROPERTY_HINT_LOCALIZABLE_STRING), Dictionary())); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/removable_volumes_usage_description", PROPERTY_HINT_PLACEHOLDER_TEXT, "Provide a message if you need to use removable volumes"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/removable_volumes_usage_description", PROPERTY_HINT_PLACEHOLDER_TEXT, "Provide a message if you need to use removable volumes"), "", false, true)); r_options->push_back(ExportOption(PropertyInfo(Variant::DICTIONARY, "privacy/removable_volumes_usage_description_localized", PROPERTY_HINT_LOCALIZABLE_STRING), Dictionary())); - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/s3tc"), true)); - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/etc"), false)); - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/etc2"), false)); + String run_script = "#!/usr/bin/env bash\n" + "unzip -o -q \"{temp_dir}/{archive_name}\" -d \"{temp_dir}\"\n" + "open \"{temp_dir}/{exe_name}.app\" --args {cmd_args}"; + + String cleanup_script = "#!/usr/bin/env bash\n" + "kill $(pgrep -x -f \"{temp_dir}/{exe_name}.app/Contents/MacOS/{exe_name} {cmd_args}\")\n" + "rm -rf \"{temp_dir}\""; + + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "ssh_remote_deploy/enabled"), false, true)); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "ssh_remote_deploy/host"), "user@host_ip")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "ssh_remote_deploy/port"), "22")); + + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "ssh_remote_deploy/extra_args_ssh", PROPERTY_HINT_MULTILINE_TEXT), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "ssh_remote_deploy/extra_args_scp", PROPERTY_HINT_MULTILINE_TEXT), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "ssh_remote_deploy/run_script", PROPERTY_HINT_MULTILINE_TEXT), run_script)); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "ssh_remote_deploy/cleanup_script", PROPERTY_HINT_MULTILINE_TEXT), cleanup_script)); } void _rgba8_to_packbits_encode(int p_ch, int p_size, Vector<uint8_t> &p_source, Vector<uint8_t> &p_dest) { @@ -268,7 +547,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 EditorExportPlatformMacOS::_make_icon(const Ref<Image> &p_icon, Vector<uint8_t> &p_data) { +void EditorExportPlatformMacOS::_make_icon(const Ref<EditorExportPreset> &p_preset, const Ref<Image> &p_icon, Vector<uint8_t> &p_data) { Ref<ImageTexture> it = memnew(ImageTexture); Vector<uint8_t> data; @@ -302,7 +581,7 @@ void EditorExportPlatformMacOS::_make_icon(const Ref<Image> &p_icon, Vector<uint for (uint64_t i = 0; i < (sizeof(icon_infos) / sizeof(icon_infos[0])); ++i) { Ref<Image> copy = p_icon; // does this make sense? doesn't this just increase the reference count instead of making a copy? Do we even need a copy? copy->convert(Image::FORMAT_RGBA8); - copy->resize(icon_infos[i].size, icon_infos[i].size); + copy->resize(icon_infos[i].size, icon_infos[i].size, (Image::Interpolation)(p_preset->get("application/icon_interpolation").operator int())); if (icon_infos[i].is_png) { // Encode PNG icon. @@ -397,8 +676,22 @@ void EditorExportPlatformMacOS::_fix_plist(const Ref<EditorExportPreset> &p_pres strnew += lines[i].replace("$app_category", cat.to_lower()) + "\n"; } else if (lines[i].find("$copyright") != -1) { strnew += lines[i].replace("$copyright", p_preset->get("application/copyright")) + "\n"; + } else if (lines[i].find("$min_version") != -1) { + strnew += lines[i].replace("$min_version", p_preset->get("application/min_macos_version")) + "\n"; } else if (lines[i].find("$highres") != -1) { strnew += lines[i].replace("$highres", p_preset->get("display/high_res") ? "\t<true/>" : "\t<false/>") + "\n"; + } else if (lines[i].find("$platfbuild") != -1) { + strnew += lines[i].replace("$platfbuild", p_preset->get("xcode/platform_build")) + "\n"; + } else if (lines[i].find("$sdkver") != -1) { + strnew += lines[i].replace("$sdkver", p_preset->get("xcode/sdk_version")) + "\n"; + } else if (lines[i].find("$sdkname") != -1) { + strnew += lines[i].replace("$sdkname", p_preset->get("xcode/sdk_name")) + "\n"; + } else if (lines[i].find("$sdkbuild") != -1) { + strnew += lines[i].replace("$sdkbuild", p_preset->get("xcode/sdk_build")) + "\n"; + } else if (lines[i].find("$xcodever") != -1) { + strnew += lines[i].replace("$xcodever", p_preset->get("xcode/xcode_version")) + "\n"; + } else if (lines[i].find("$xcodebuild") != -1) { + strnew += lines[i].replace("$xcodebuild", p_preset->get("xcode/xcode_build")) + "\n"; } else if (lines[i].find("$usage_descriptions") != -1) { String descriptions; if (!((String)p_preset->get("privacy/microphone_usage_description")).is_empty()) { @@ -483,20 +776,25 @@ Error EditorExportPlatformMacOS::_notarize(const Ref<EditorExportPreset> &p_pres args.push_back("notary-submit"); - if (p_preset->get("notarization/api_uuid") == "") { + if (p_preset->get_or_env("notarization/api_uuid", ENV_MAC_NOTARIZATION_UUID) == "") { add_message(EXPORT_MESSAGE_ERROR, TTR("Notarization"), TTR("App Store Connect issuer ID name not specified.")); return Error::FAILED; } - if (p_preset->get("notarization/api_key") == "") { + if (p_preset->get_or_env("notarization/api_key", ENV_MAC_NOTARIZATION_KEY) == "") { add_message(EXPORT_MESSAGE_ERROR, TTR("Notarization"), TTR("App Store Connect API key ID not specified.")); return Error::FAILED; } args.push_back("--api-issuer"); - args.push_back(p_preset->get("notarization/api_uuid")); + args.push_back(p_preset->get_or_env("notarization/api_uuid", ENV_MAC_NOTARIZATION_UUID)); args.push_back("--api-key"); - args.push_back(p_preset->get("notarization/api_key")); + args.push_back(p_preset->get_or_env("notarization/api_key_id", ENV_MAC_NOTARIZATION_KEY_ID)); + + if (!p_preset->get_or_env("notarization/api_key", ENV_MAC_NOTARIZATION_KEY).operator String().is_empty()) { + args.push_back("--api-key-path"); + args.push_back(p_preset->get_or_env("notarization/api_key", ENV_MAC_NOTARIZATION_KEY)); + } args.push_back(p_path); @@ -517,7 +815,7 @@ Error EditorExportPlatformMacOS::_notarize(const Ref<EditorExportPreset> &p_pres } else { print_verbose("rcodesign (" + p_path + "):\n" + str); int next_nl = str.find("\n", rq_offset); - String request_uuid = (next_nl == -1) ? str.substr(rq_offset + 14, -1) : str.substr(rq_offset + 14, next_nl - rq_offset - 14); + String request_uuid = (next_nl == -1) ? str.substr(rq_offset + 23, -1) : str.substr(rq_offset + 23, next_nl - rq_offset - 23); add_message(EXPORT_MESSAGE_INFO, TTR("Notarization"), vformat(TTR("Notarization request UUID: \"%s\""), request_uuid)); add_message(EXPORT_MESSAGE_INFO, TTR("Notarization"), TTR("The notarization process generally takes less than an hour.")); add_message(EXPORT_MESSAGE_INFO, TTR("Notarization"), "\t" + TTR("You can check progress manually by opening a Terminal and running the following command:")); @@ -527,7 +825,91 @@ Error EditorExportPlatformMacOS::_notarize(const Ref<EditorExportPreset> &p_pres } } break; #ifdef MACOS_ENABLED - case 2: { // "altool" + case 2: { // "notarytool" + print_verbose("using notarytool notarization..."); + + if (!FileAccess::exists("/usr/bin/xcrun") && !FileAccess::exists("/bin/xcrun")) { + add_message(EXPORT_MESSAGE_ERROR, TTR("Notarization"), TTR("Xcode command line tools are not installed.")); + return Error::FAILED; + } + + List<String> args; + + args.push_back("notarytool"); + args.push_back("submit"); + + args.push_back(p_path); + + if (p_preset->get_or_env("notarization/apple_id_name", ENV_MAC_NOTARIZATION_APPLE_ID) == "" && p_preset->get_or_env("notarization/api_uuid", ENV_MAC_NOTARIZATION_UUID) == "") { + add_message(EXPORT_MESSAGE_ERROR, TTR("Notarization"), TTR("Neither Apple ID name nor App Store Connect issuer ID name not specified.")); + return Error::FAILED; + } + if (p_preset->get_or_env("notarization/apple_id_name", ENV_MAC_NOTARIZATION_APPLE_ID) != "" && p_preset->get_or_env("notarization/api_uuid", ENV_MAC_NOTARIZATION_UUID) != "") { + add_message(EXPORT_MESSAGE_ERROR, TTR("Notarization"), TTR("Both Apple ID name and App Store Connect issuer ID name are specified, only one should be set at the same time.")); + return Error::FAILED; + } + + if (p_preset->get_or_env("notarization/apple_id_name", ENV_MAC_NOTARIZATION_APPLE_ID) != "") { + if (p_preset->get_or_env("notarization/apple_id_password", ENV_MAC_NOTARIZATION_APPLE_PASS) == "") { + add_message(EXPORT_MESSAGE_ERROR, TTR("Notarization"), TTR("Apple ID password not specified.")); + return Error::FAILED; + } + args.push_back("--apple-id"); + args.push_back(p_preset->get_or_env("notarization/apple_id_name", ENV_MAC_NOTARIZATION_APPLE_ID)); + + args.push_back("--password"); + args.push_back(p_preset->get_or_env("notarization/apple_id_password", ENV_MAC_NOTARIZATION_APPLE_PASS)); + } else { + if (p_preset->get_or_env("notarization/api_key_id", ENV_MAC_NOTARIZATION_KEY_ID) == "") { + add_message(EXPORT_MESSAGE_ERROR, TTR("Notarization"), TTR("App Store Connect API key ID not specified.")); + return Error::FAILED; + } + args.push_back("--issuer"); + args.push_back(p_preset->get_or_env("notarization/api_uuid", ENV_MAC_NOTARIZATION_UUID)); + + if (!p_preset->get_or_env("notarization/api_key", ENV_MAC_NOTARIZATION_KEY).operator String().is_empty()) { + args.push_back("--key"); + args.push_back(p_preset->get_or_env("notarization/api_key", ENV_MAC_NOTARIZATION_KEY)); + } + + args.push_back("--key-id"); + args.push_back(p_preset->get_or_env("notarization/api_key_id", ENV_MAC_NOTARIZATION_KEY_ID)); + } + + args.push_back("--no-progress"); + + if (p_preset->get("codesign/apple_team_id")) { + args.push_back("--team-id"); + args.push_back(p_preset->get("codesign/apple_team_id")); + } + + String str; + int exitcode = 0; + Error err = OS::get_singleton()->execute("xcrun", args, &str, &exitcode, true); + if (err != OK) { + add_message(EXPORT_MESSAGE_WARNING, TTR("Notarization"), TTR("Could not start xcrun executable.")); + return err; + } + + int rq_offset = str.find("id:"); + if (exitcode != 0 || rq_offset == -1) { + print_line("notarytool (" + p_path + "):\n" + str); + add_message(EXPORT_MESSAGE_WARNING, TTR("Notarization"), TTR("Notarization failed, see editor log for details.")); + return Error::FAILED; + } else { + print_verbose("notarytool (" + p_path + "):\n" + str); + int next_nl = str.find("\n", rq_offset); + String request_uuid = (next_nl == -1) ? str.substr(rq_offset + 4, -1) : str.substr(rq_offset + 4, next_nl - rq_offset - 4); + add_message(EXPORT_MESSAGE_INFO, TTR("Notarization"), vformat(TTR("Notarization request UUID: \"%s\""), request_uuid)); + add_message(EXPORT_MESSAGE_INFO, TTR("Notarization"), TTR("The notarization process generally takes less than an hour.")); + add_message(EXPORT_MESSAGE_INFO, TTR("Notarization"), "\t" + TTR("You can check progress manually by opening a Terminal and running the following command:")); + add_message(EXPORT_MESSAGE_INFO, TTR("Notarization"), "\t\t\"xcrun notarytool log <request uuid> --issuer <api uuid> --key-id <api key id> --key <api key path>\" or"); + add_message(EXPORT_MESSAGE_INFO, TTR("Notarization"), "\t\t\"xcrun notarytool log <request uuid> --apple-id <your email> --password <app-specific pwd>>\""); + add_message(EXPORT_MESSAGE_INFO, TTR("Notarization"), "\t" + TTR("Run the following command to staple the notarization ticket to the exported application (optional):")); + add_message(EXPORT_MESSAGE_INFO, TTR("Notarization"), "\t\t\"xcrun stapler staple <app path>\""); + } + } break; + case 3: { // "altool" print_verbose("using altool notarization..."); if (!FileAccess::exists("/usr/bin/xcrun") && !FileAccess::exists("/bin/xcrun")) { @@ -543,43 +925,43 @@ Error EditorExportPlatformMacOS::_notarize(const Ref<EditorExportPreset> &p_pres args.push_back("--primary-bundle-id"); args.push_back(p_preset->get("application/bundle_identifier")); - if (p_preset->get("notarization/apple_id_name") == "" && p_preset->get("notarization/api_uuid") == "") { + if (p_preset->get_or_env("notarization/apple_id_name", ENV_MAC_NOTARIZATION_APPLE_ID) == "" && p_preset->get_or_env("notarization/api_uuid", ENV_MAC_NOTARIZATION_UUID) == "") { add_message(EXPORT_MESSAGE_ERROR, TTR("Notarization"), TTR("Neither Apple ID name nor App Store Connect issuer ID name not specified.")); return Error::FAILED; } - if (p_preset->get("notarization/apple_id_name") != "" && p_preset->get("notarization/api_uuid") != "") { + if (p_preset->get_or_env("notarization/apple_id_name", ENV_MAC_NOTARIZATION_APPLE_ID) != "" && p_preset->get_or_env("notarization/api_uuid", ENV_MAC_NOTARIZATION_UUID) != "") { add_message(EXPORT_MESSAGE_ERROR, TTR("Notarization"), TTR("Both Apple ID name and App Store Connect issuer ID name are specified, only one should be set at the same time.")); return Error::FAILED; } - if (p_preset->get("notarization/apple_id_name") != "") { - if (p_preset->get("notarization/apple_id_password") == "") { + if (p_preset->get_or_env("notarization/apple_id_name", ENV_MAC_NOTARIZATION_APPLE_ID) != "") { + if (p_preset->get_or_env("notarization/apple_id_password", ENV_MAC_NOTARIZATION_APPLE_PASS) == "") { add_message(EXPORT_MESSAGE_ERROR, TTR("Notarization"), TTR("Apple ID password not specified.")); return Error::FAILED; } args.push_back("--username"); - args.push_back(p_preset->get("notarization/apple_id_name")); + args.push_back(p_preset->get_or_env("notarization/apple_id_name", ENV_MAC_NOTARIZATION_APPLE_ID)); args.push_back("--password"); - args.push_back(p_preset->get("notarization/apple_id_password")); + args.push_back(p_preset->get_or_env("notarization/apple_id_password", ENV_MAC_NOTARIZATION_APPLE_PASS)); } else { - if (p_preset->get("notarization/api_key") == "") { + if (p_preset->get_or_env("notarization/api_key", ENV_MAC_NOTARIZATION_KEY) == "") { add_message(EXPORT_MESSAGE_ERROR, TTR("Notarization"), TTR("App Store Connect API key ID not specified.")); return Error::FAILED; } args.push_back("--apiIssuer"); - args.push_back(p_preset->get("notarization/api_uuid")); + args.push_back(p_preset->get_or_env("notarization/api_uuid", ENV_MAC_NOTARIZATION_UUID)); args.push_back("--apiKey"); - args.push_back(p_preset->get("notarization/api_key")); + args.push_back(p_preset->get_or_env("notarization/api_key_id", ENV_MAC_NOTARIZATION_KEY_ID)); } args.push_back("--type"); args.push_back("osx"); - if (p_preset->get("notarization/apple_team_id")) { + if (p_preset->get("codesign/apple_team_id")) { args.push_back("--asc-provider"); - args.push_back(p_preset->get("notarization/apple_team_id")); + args.push_back(p_preset->get("codesign/apple_team_id")); } args.push_back("--file"); @@ -593,7 +975,7 @@ Error EditorExportPlatformMacOS::_notarize(const Ref<EditorExportPreset> &p_pres return err; } - int rq_offset = str.find("RequestUUID"); + int rq_offset = str.find("RequestUUID:"); if (exitcode != 0 || rq_offset == -1) { print_line("xcrun altool (" + p_path + "):\n" + str); add_message(EXPORT_MESSAGE_WARNING, TTR("Notarization"), TTR("Notarization failed, see editor log for details.")); @@ -601,7 +983,7 @@ Error EditorExportPlatformMacOS::_notarize(const Ref<EditorExportPreset> &p_pres } else { print_verbose("xcrun altool (" + p_path + "):\n" + str); int next_nl = str.find("\n", rq_offset); - String request_uuid = (next_nl == -1) ? str.substr(rq_offset + 14, -1) : str.substr(rq_offset + 14, next_nl - rq_offset - 14); + String request_uuid = (next_nl == -1) ? str.substr(rq_offset + 13, -1) : str.substr(rq_offset + 13, next_nl - rq_offset - 13); add_message(EXPORT_MESSAGE_INFO, TTR("Notarization"), vformat(TTR("Notarization request UUID: \"%s\""), request_uuid)); add_message(EXPORT_MESSAGE_INFO, TTR("Notarization"), TTR("The notarization process generally takes less than an hour. When the process is completed, you'll receive an email.")); add_message(EXPORT_MESSAGE_INFO, TTR("Notarization"), "\t" + TTR("You can check progress manually by opening a Terminal and running the following command:")); @@ -650,9 +1032,9 @@ Error EditorExportPlatformMacOS::_code_sign(const Ref<EditorExportPreset> &p_pre args.push_back(p_ent_path); } - String certificate_file = p_preset->get("codesign/certificate_file"); - String certificate_pass = p_preset->get("codesign/certificate_password"); - if (!certificate_file.is_empty() && !certificate_file.is_empty()) { + String certificate_file = p_preset->get_or_env("codesign/certificate_file", ENV_MAC_CODESIGN_CERT_FILE); + String certificate_pass = p_preset->get_or_env("codesign/certificate_password", ENV_MAC_CODESIGN_CERT_PASS); + if (!certificate_file.is_empty() && !certificate_pass.is_empty()) { args.push_back("--p12-file"); args.push_back(certificate_file); args.push_back("--p12-password"); @@ -726,7 +1108,7 @@ Error EditorExportPlatformMacOS::_code_sign(const Ref<EditorExportPreset> &p_pre String str; int exitcode = 0; - Error err = OS::get_singleton()->execute("codesign", args, &str, nullptr, true); + Error err = OS::get_singleton()->execute("codesign", args, &str, &exitcode, true); if (err != OK) { add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), TTR("Could not start codesign executable, make sure Xcode command line tools are installed.")); return err; @@ -862,6 +1244,42 @@ Error EditorExportPlatformMacOS::_export_macos_plugins_for(Ref<EditorExportPlugi return error; } +Error EditorExportPlatformMacOS::_create_pkg(const Ref<EditorExportPreset> &p_preset, const String &p_pkg_path, const String &p_app_path_name) { + List<String> args; + + if (FileAccess::exists(p_pkg_path)) { + OS::get_singleton()->move_to_trash(p_pkg_path); + } + + args.push_back("productbuild"); + args.push_back("--component"); + args.push_back(p_app_path_name); + args.push_back("/Applications"); + String ident = p_preset->get("codesign/installer_identity"); + if (!ident.is_empty()) { + args.push_back("--timestamp"); + args.push_back("--sign"); + args.push_back(ident); + } + args.push_back("--quiet"); + args.push_back(p_pkg_path); + + String str; + Error err = OS::get_singleton()->execute("xcrun", args, &str, nullptr, true); + if (err != OK) { + add_message(EXPORT_MESSAGE_ERROR, TTR("PKG Creation"), TTR("Could not start productbuild executable.")); + return err; + } + + print_verbose("productbuild returned: " + str); + if (str.find("productbuild: error:") != -1) { + add_message(EXPORT_MESSAGE_ERROR, TTR("PKG Creation"), TTR("`productbuild` failed.")); + return FAILED; + } + + return OK; +} + Error EditorExportPlatformMacOS::_create_dmg(const String &p_dmg_path, const String &p_pkg_name, const String &p_app_path_name) { List<String> args; @@ -898,7 +1316,7 @@ Error EditorExportPlatformMacOS::_create_dmg(const String &p_dmg_path, const Str return OK; } -bool EditorExportPlatformMacOS::is_shbang(const String &p_path) const { +bool EditorExportPlatformMacOS::is_shebang(const String &p_path) const { Ref<FileAccess> fb = FileAccess::open(p_path, FileAccess::READ); ERR_FAIL_COND_V_MSG(fb.is_null(), false, vformat("Can't open file: \"%s\".", p_path)); uint16_t magic = fb->get_16(); @@ -906,7 +1324,7 @@ bool EditorExportPlatformMacOS::is_shbang(const String &p_path) const { } bool EditorExportPlatformMacOS::is_executable(const String &p_path) const { - return MachO::is_macho(p_path) || LipO::is_lipo(p_path) || is_shbang(p_path); + return MachO::is_macho(p_path) || LipO::is_lipo(p_path) || is_shebang(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) { @@ -987,16 +1405,19 @@ Error EditorExportPlatformMacOS::export_project(const Ref<EditorExportPreset> &p } else { pkg_name = "Unnamed"; } - pkg_name = OS::get_singleton()->get_safe_dir_name(pkg_name); String export_format; - if (use_dmg() && p_path.ends_with("dmg")) { - export_format = "dmg"; - } else if (p_path.ends_with("zip")) { + if (p_path.ends_with("zip")) { export_format = "zip"; } else if (p_path.ends_with("app")) { export_format = "app"; +#ifdef MACOS_ENABLED + } else if (p_path.ends_with("dmg")) { + export_format = "dmg"; + } else if (p_path.ends_with("pkg")) { + export_format = "pkg"; +#endif } else { add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), TTR("Invalid export format.")); return ERR_CANT_CREATE; @@ -1253,16 +1674,18 @@ Error EditorExportPlatformMacOS::export_project(const Ref<EditorExportPreset> &p if (file == "Contents/Resources/icon.icns") { // See if there is an icon. - String iconpath; + String icon_path; if (p_preset->get("application/icon") != "") { - iconpath = p_preset->get("application/icon"); + icon_path = p_preset->get("application/icon"); + } else if (GLOBAL_GET("application/config/macos_native_icon") != "") { + icon_path = GLOBAL_GET("application/config/macos_native_icon"); } else { - iconpath = GLOBAL_GET("application/config/icon"); + icon_path = GLOBAL_GET("application/config/icon"); } - if (!iconpath.is_empty()) { - if (iconpath.get_extension() == "icns") { - Ref<FileAccess> icon = FileAccess::open(iconpath, FileAccess::READ); + if (!icon_path.is_empty()) { + if (icon_path.get_extension() == "icns") { + Ref<FileAccess> icon = FileAccess::open(icon_path, FileAccess::READ); if (icon.is_valid()) { data.resize(icon->get_length()); icon->get_buffer(&data.write[0], icon->get_length()); @@ -1270,9 +1693,9 @@ Error EditorExportPlatformMacOS::export_project(const Ref<EditorExportPreset> &p } else { Ref<Image> icon; icon.instantiate(); - icon->load(iconpath); - if (!icon->is_empty()) { - _make_icon(icon, data); + err = ImageLoader::load_image(icon_path, icon); + if (err == OK && !icon->is_empty()) { + _make_icon(p_preset, icon, data); } } } @@ -1316,14 +1739,14 @@ Error EditorExportPlatformMacOS::export_project(const Ref<EditorExportPreset> &p err = ERR_FILE_NOT_FOUND; } - // Save console script. + // Save console wrapper. if (err == OK) { - int con_scr = p_preset->get("debug/export_console_script"); + int con_scr = p_preset->get("debug/export_console_wrapper"); if ((con_scr == 1 && p_debug) || (con_scr == 2)) { err = _export_debug_script(p_preset, pkg_name, tmp_app_path_name.get_file() + "/Contents/MacOS/" + pkg_name, scr_path); FileAccess::set_unix_permissions(scr_path, 0755); if (err != OK) { - add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), TTR("Could not create console script.")); + add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), TTR("Could not create console wrapper.")); } } } @@ -1342,7 +1765,7 @@ Error EditorExportPlatformMacOS::export_project(const Ref<EditorExportPreset> &p ad_hoc = true; } break; case 2: { // "rcodesign" - ad_hoc = p_preset->get("codesign/certificate_file").operator String().is_empty() || p_preset->get("codesign/certificate_password").operator String().is_empty(); + ad_hoc = p_preset->get_or_env("codesign/certificate_file", ENV_MAC_CODESIGN_CERT_FILE).operator String().is_empty() || p_preset->get_or_env("codesign/certificate_password", ENV_MAC_CODESIGN_CERT_PASS).operator String().is_empty(); } break; #ifdef MACOS_ENABLED case 3: { // "codesign" @@ -1434,6 +1857,19 @@ Error EditorExportPlatformMacOS::export_project(const Ref<EditorExportPreset> &p ent_f->store_line("<true/>"); } + int dist_type = p_preset->get("export/distribution_type"); + if (dist_type == 2) { + String pprof = p_preset->get_or_env("codesign/provisioning_profile", ENV_MAC_CODESIGN_PROFILE); + String teamid = p_preset->get("codesign/apple_team_id"); + String bid = p_preset->get("application/bundle_identifier"); + if (!pprof.is_empty() && !teamid.is_empty()) { + ent_f->store_line("<key>com.apple.developer.team-identifier</key>"); + ent_f->store_line("<string>" + teamid + "</string>"); + ent_f->store_line("<key>com.apple.application-identifier</key>"); + ent_f->store_line("<string>" + teamid + "." + bid + "</string>"); + } + } + if ((bool)p_preset->get("codesign/entitlements/app_sandbox/enabled")) { ent_f->store_line("<key>com.apple.security.app-sandbox</key>"); ent_f->store_line("<true/>"); @@ -1554,6 +1990,15 @@ Error EditorExportPlatformMacOS::export_project(const Ref<EditorExportPreset> &p } if (err == OK && sign_enabled) { + int dist_type = p_preset->get("export/distribution_type"); + if (dist_type == 2) { + String pprof = p_preset->get_or_env("codesign/provisioning_profile", ENV_MAC_CODESIGN_PROFILE).operator String(); + if (!pprof.is_empty()) { + Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + err = da->copy(pprof, tmp_app_path_name + "/Contents/embedded.provisionprofile"); + } + } + if (ep.step(TTR("Code signing bundle"), 2)) { return ERR_SKIP; } @@ -1575,6 +2020,14 @@ Error EditorExportPlatformMacOS::export_project(const Ref<EditorExportPreset> &p } err = _code_sign(p_preset, p_path, ent_path, false); } + } else if (export_format == "pkg") { + // Create a Installer. + if (err == OK) { + if (ep.step(TTR("Making PKG installer"), 3)) { + return ERR_SKIP; + } + err = _create_pkg(p_preset, p_path, tmp_app_path_name); + } } else if (export_format == "zip") { // Create ZIP. if (err == OK) { @@ -1589,7 +2042,7 @@ Error EditorExportPlatformMacOS::export_project(const Ref<EditorExportPreset> &p zlib_filefunc_def io_dst = zipio_create_io(&io_fa_dst); zipFile zip = zipOpen2(p_path.utf8().get_data(), APPEND_STATUS_CREATE, nullptr, &io_dst); - _zip_folder_recursive(zip, tmp_base_path_name, "", pkg_name); + zip_folder_recursive(zip, tmp_base_path_name, "", pkg_name); zipClose(zip, nullptr); } @@ -1597,7 +2050,7 @@ Error EditorExportPlatformMacOS::export_project(const Ref<EditorExportPreset> &p bool noto_enabled = (p_preset->get("notarization/notarization").operator int() > 0); if (err == OK && noto_enabled) { - if (export_format == "app") { + if (export_format == "app" || export_format == "pkg") { add_message(EXPORT_MESSAGE_INFO, TTR("Notarization"), TTR("Notarization requires the app to be archived first, select the DMG or ZIP export format instead.")); } else { if (ep.step(TTR("Sending archive for notarization"), 4)) { @@ -1628,119 +2081,6 @@ Error EditorExportPlatformMacOS::export_project(const Ref<EditorExportPreset> &p return err; } -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.path_join(p_folder); - - Ref<DirAccess> da = DirAccess::open(dir); - da->list_dir_begin(); - String f = da->get_next(); - while (!f.is_empty()) { - if (f == "." || f == "..") { - f = da->get_next(); - continue; - } - if (da->is_link(f)) { - OS::DateTime dt = OS::get_singleton()->get_datetime(); - - zip_fileinfo zipfi; - zipfi.tmz_date.tm_year = dt.year; - zipfi.tmz_date.tm_mon = dt.month - 1; // Note: "tm" month range - 0..11, Godot month range - 1..12, https://www.cplusplus.com/reference/ctime/tm/ - zipfi.tmz_date.tm_mday = dt.day; - zipfi.tmz_date.tm_hour = dt.hour; - zipfi.tmz_date.tm_min = dt.minute; - zipfi.tmz_date.tm_sec = dt.second; - zipfi.dosDate = 0; - // 0120000: symbolic link type - // 0000755: permissions rwxr-xr-x - // 0000644: permissions rw-r--r-- - uint32_t _mode = 0120644; - zipfi.external_fa = (_mode << 16L) | !(_mode & 0200); - zipfi.internal_fa = 0; - - zipOpenNewFileInZip4(p_zip, - p_folder.path_join(f).utf8().get_data(), - &zipfi, - nullptr, - 0, - nullptr, - 0, - nullptr, - Z_DEFLATED, - Z_DEFAULT_COMPRESSION, - 0, - -MAX_WBITS, - DEF_MEM_LEVEL, - Z_DEFAULT_STRATEGY, - nullptr, - 0, - 0x0314, // "version made by", 0x03 - Unix, 0x14 - ZIP specification version 2.0, required to store Unix file permissions - 0); - - String target = da->read_link(f); - zipWriteInFileInZip(p_zip, target.utf8().get_data(), target.utf8().size()); - zipCloseFileInZip(p_zip); - } else if (da->current_is_dir()) { - _zip_folder_recursive(p_zip, p_root_path, p_folder.path_join(f), p_pkg_name); - } else { - OS::DateTime dt = OS::get_singleton()->get_datetime(); - - zip_fileinfo zipfi; - zipfi.tmz_date.tm_year = dt.year; - zipfi.tmz_date.tm_mon = dt.month - 1; // Note: "tm" month range - 0..11, Godot month range - 1..12, https://www.cplusplus.com/reference/ctime/tm/ - zipfi.tmz_date.tm_mday = dt.day; - zipfi.tmz_date.tm_hour = dt.hour; - zipfi.tmz_date.tm_min = dt.minute; - zipfi.tmz_date.tm_sec = dt.second; - zipfi.dosDate = 0; - // 0100000: regular file type - // 0000755: permissions rwxr-xr-x - // 0000644: permissions rw-r--r-- - uint32_t _mode = (is_executable(dir.path_join(f)) ? 0100755 : 0100644); - zipfi.external_fa = (_mode << 16L) | !(_mode & 0200); - zipfi.internal_fa = 0; - - zipOpenNewFileInZip4(p_zip, - p_folder.path_join(f).utf8().get_data(), - &zipfi, - nullptr, - 0, - nullptr, - 0, - nullptr, - Z_DEFLATED, - Z_DEFAULT_COMPRESSION, - 0, - -MAX_WBITS, - DEF_MEM_LEVEL, - Z_DEFAULT_STRATEGY, - nullptr, - 0, - 0x0314, // "version made by", 0x03 - Unix, 0x14 - ZIP specification version 2.0, required to store Unix file permissions - 0); - - Ref<FileAccess> fa = FileAccess::open(dir.path_join(f), FileAccess::READ); - if (fa.is_null()) { - add_message(EXPORT_MESSAGE_ERROR, TTR("ZIP Creation"), vformat(TTR("Could not open file to read from path \"%s\"."), dir.path_join(f))); - return; - } - const int bufsize = 16384; - uint8_t buf[bufsize]; - - while (true) { - uint64_t got = fa->get_buffer(buf, bufsize); - if (got == 0) { - break; - } - zipWriteInFileInZip(p_zip, buf, got); - } - - zipCloseFileInZip(p_zip); - } - f = da->get_next(); - } - da->list_dir_end(); -} - bool EditorExportPlatformMacOS::has_valid_export_configuration(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const { String err; bool valid = false; @@ -1762,6 +2102,24 @@ bool EditorExportPlatformMacOS::has_valid_export_configuration(const Ref<EditorE } } + String architecture = p_preset->get("binary_format/architecture"); + + if (architecture == "universal" || architecture == "x86_64") { + const String bc_error = test_bc(); + if (!bc_error.is_empty()) { + valid = false; + err += bc_error; + } + } else if (architecture == "arm64") { + const String etc_error = test_etc2(); + if (!etc_error.is_empty()) { + valid = false; + err += etc_error; + } + } else { + ERR_PRINT("Invalid architecture"); + } + // Look for export templates (official templates, check only is custom templates are not set). if (!dvalid || !rvalid) { dvalid = exists_export_template("macos.zip", &err); @@ -1782,21 +2140,16 @@ bool EditorExportPlatformMacOS::has_valid_project_configuration(const Ref<Editor String err; bool valid = true; - String identifier = p_preset->get("application/bundle_identifier"); - String pn_err; - if (!is_package_name_valid(identifier, &pn_err)) { - err += TTR("Invalid bundle identifier:") + " " + pn_err + "\n"; - valid = false; - } - + int dist_type = p_preset->get("export/distribution_type"); bool ad_hoc = false; int codesign_tool = p_preset->get("codesign/codesign"); + int notary_tool = p_preset->get("notarization/notarization"); switch (codesign_tool) { case 1: { // built-in ad-hoc ad_hoc = true; } break; case 2: { // "rcodesign" - ad_hoc = p_preset->get("codesign/certificate_file").operator String().is_empty() || p_preset->get("codesign/certificate_password").operator String().is_empty(); + ad_hoc = p_preset->get_or_env("codesign/certificate_file", ENV_MAC_CODESIGN_CERT_FILE).operator String().is_empty() || p_preset->get_or_env("codesign/certificate_password", ENV_MAC_CODESIGN_CERT_PASS).operator String().is_empty(); } break; #ifdef MACOS_ENABLED case 3: { // "codesign" @@ -1806,63 +2159,41 @@ bool EditorExportPlatformMacOS::has_valid_project_configuration(const Ref<Editor default: { }; } - int notary_tool = p_preset->get("notarization/notarization"); - if (notary_tool > 0) { - if (ad_hoc) { - err += TTR("Notarization: Notarization with an ad-hoc signature is not supported.") + "\n"; - valid = false; - } - if (codesign_tool == 0) { - err += TTR("Notarization: Code signing is required for notarization.") + "\n"; - valid = false; - } - if (notary_tool == 2) { - if (!FileAccess::exists("/usr/bin/xcrun") && !FileAccess::exists("/bin/xcrun")) { - err += TTR("Notarization: Xcode command line tools are not installed.") + "\n"; - valid = false; + List<ExportOption> options; + get_export_options(&options); + for (const EditorExportPlatform::ExportOption &E : options) { + if (get_export_option_visibility(p_preset.ptr(), E.option.name)) { + String warn = get_export_option_warning(p_preset.ptr(), E.option.name); + if (!warn.is_empty()) { + err += warn + "\n"; + if (E.required) { + valid = false; + } } - if (p_preset->get("notarization/apple_id_name") == "" && p_preset->get("notarization/api_uuid") == "") { - err += TTR("Notarization: Neither Apple ID name nor App Store Connect issuer ID name not specified.") + "\n"; - valid = false; - } else if (p_preset->get("notarization/apple_id_name") != "" && p_preset->get("notarization/api_uuid") != "") { - err += TTR("Notarization: Both Apple ID name and App Store Connect issuer ID name are specified, only one should be set at the same time.") + "\n"; - valid = false; - } else { - if (p_preset->get("notarization/apple_id_name") != "") { - if (p_preset->get("notarization/apple_id_password") == "") { - err += TTR("Notarization: Apple ID password not specified.") + "\n"; - } + } + } + + if (dist_type != 2) { + if (notary_tool > 0) { + if (notary_tool == 2 || notary_tool == 3) { + if (!FileAccess::exists("/usr/bin/xcrun") && !FileAccess::exists("/bin/xcrun")) { + err += TTR("Notarization: Xcode command line tools are not installed.") + "\n"; valid = false; } - if (p_preset->get("notarization/api_uuid") != "") { - if (p_preset->get("notarization/api_key") == "") { - err += TTR("Notarization: App Store Connect API key ID not specified.") + "\n"; - valid = false; - } + } else if (notary_tool == 1) { + String rcodesign = EDITOR_GET("export/macos/rcodesign").operator String(); + if (rcodesign.is_empty()) { + err += TTR("Notarization: rcodesign path is not set. Configure rcodesign path in the Editor Settings (Export > macOS > rcodesign).") + "\n"; + valid = false; } } - } else if (notary_tool == 1) { - if (p_preset->get("notarization/api_uuid") == "") { - err += TTR("Notarization: App Store Connect issuer ID name not specified.") + "\n"; - valid = false; - } - if (p_preset->get("notarization/api_key") == "") { - err += TTR("Notarization: App Store Connect API key ID not specified.") + "\n"; - valid = false; - } - - String rcodesign = EDITOR_GET("export/macos/rcodesign").operator String(); - if (rcodesign.is_empty()) { - err += TTR("Notarization: rcodesign path is not set. Configure rcodesign path in the Editor Settings (Export > macOS > rcodesign).") + "\n"; - valid = false; + } else { + err += TTR("Warning: Notarization is disabled. The exported project will be blocked by Gatekeeper if it's downloaded from an unknown source.") + "\n"; + if (codesign_tool == 0) { + err += TTR("Code signing is disabled. The exported project will not run on Macs with enabled Gatekeeper and Apple Silicon powered Macs.") + "\n"; } } - } else { - err += TTR("Warning: Notarization is disabled. The exported project will be blocked by Gatekeeper if it's downloaded from an unknown source.") + "\n"; - if (codesign_tool == 0) { - err += TTR("Code signing is disabled. The exported project will not run on Macs with enabled Gatekeeper and Apple Silicon powered Macs.") + "\n"; - } } if (codesign_tool > 0) { @@ -1881,41 +2212,252 @@ bool EditorExportPlatformMacOS::has_valid_project_configuration(const Ref<Editor valid = false; } } - if ((bool)p_preset->get("codesign/entitlements/audio_input") && ((String)p_preset->get("privacy/microphone_usage_description")).is_empty()) { - err += TTR("Privacy: Microphone access is enabled, but usage description is not specified.") + "\n"; - valid = false; + } + + if (!err.is_empty()) { + r_error = err; + } + return valid; +} + +Ref<Texture2D> EditorExportPlatformMacOS::get_run_icon() const { + return run_icon; +} + +bool EditorExportPlatformMacOS::poll_export() { + Ref<EditorExportPreset> preset; + + for (int i = 0; i < EditorExport::get_singleton()->get_export_preset_count(); i++) { + Ref<EditorExportPreset> ep = EditorExport::get_singleton()->get_export_preset(i); + if (ep->is_runnable() && ep->get_platform() == this) { + preset = ep; + break; } - if ((bool)p_preset->get("codesign/entitlements/camera") && ((String)p_preset->get("privacy/camera_usage_description")).is_empty()) { - err += TTR("Privacy: Camera access is enabled, but usage description is not specified.") + "\n"; - valid = false; + } + + int prev = menu_options; + menu_options = (preset.is_valid() && preset->get("ssh_remote_deploy/enabled").operator bool()); + if (ssh_pid != 0 || !cleanup_commands.is_empty()) { + if (menu_options == 0) { + cleanup(); + } else { + menu_options += 1; } - if ((bool)p_preset->get("codesign/entitlements/location") && ((String)p_preset->get("privacy/location_usage_description")).is_empty()) { - err += TTR("Privacy: Location information access is enabled, but usage description is not specified.") + "\n"; - valid = false; + } + return menu_options != prev; +} + +Ref<ImageTexture> EditorExportPlatformMacOS::get_option_icon(int p_index) const { + return p_index == 1 ? stop_icon : EditorExportPlatform::get_option_icon(p_index); +} + +int EditorExportPlatformMacOS::get_options_count() const { + return menu_options; +} + +String EditorExportPlatformMacOS::get_option_label(int p_index) const { + return (p_index) ? TTR("Stop and uninstall") : TTR("Run on remote macOS system"); +} + +String EditorExportPlatformMacOS::get_option_tooltip(int p_index) const { + return (p_index) ? TTR("Stop and uninstall running project from the remote system") : TTR("Run exported project on remote macOS system"); +} + +void EditorExportPlatformMacOS::cleanup() { + if (ssh_pid != 0 && OS::get_singleton()->is_process_running(ssh_pid)) { + print_line("Terminating connection..."); + OS::get_singleton()->kill(ssh_pid); + OS::get_singleton()->delay_usec(1000); + } + + if (!cleanup_commands.is_empty()) { + print_line("Stopping and deleting previous version..."); + for (const SSHCleanupCommand &cmd : cleanup_commands) { + if (cmd.wait) { + ssh_run_on_remote(cmd.host, cmd.port, cmd.ssh_args, cmd.cmd_args); + } else { + ssh_run_on_remote_no_wait(cmd.host, cmd.port, cmd.ssh_args, cmd.cmd_args); + } } - if ((bool)p_preset->get("codesign/entitlements/address_book") && ((String)p_preset->get("privacy/address_book_usage_description")).is_empty()) { - err += TTR("Privacy: Address book access is enabled, but usage description is not specified.") + "\n"; - valid = false; + } + ssh_pid = 0; + cleanup_commands.clear(); +} + +Error EditorExportPlatformMacOS::run(const Ref<EditorExportPreset> &p_preset, int p_device, int p_debug_flags) { + cleanup(); + if (p_device) { // Stop command, cleanup only. + return OK; + } + + EditorProgress ep("run", TTR("Running..."), 5); + + const String dest = EditorPaths::get_singleton()->get_cache_dir().path_join("macos"); + Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + if (!da->dir_exists(dest)) { + Error err = da->make_dir_recursive(dest); + if (err != OK) { + EditorNode::get_singleton()->show_warning(TTR("Could not create temp directory:") + "\n" + dest); + return err; } - if ((bool)p_preset->get("codesign/entitlements/calendars") && ((String)p_preset->get("privacy/calendar_usage_description")).is_empty()) { - err += TTR("Privacy: Calendar access is enabled, but usage description is not specified.") + "\n"; - valid = false; + } + + String pkg_name; + if (String(ProjectSettings::get_singleton()->get("application/config/name")) != "") { + pkg_name = String(ProjectSettings::get_singleton()->get("application/config/name")); + } else { + pkg_name = "Unnamed"; + } + pkg_name = OS::get_singleton()->get_safe_dir_name(pkg_name); + + String host = p_preset->get("ssh_remote_deploy/host").operator String(); + String port = p_preset->get("ssh_remote_deploy/port").operator String(); + if (port.is_empty()) { + port = "22"; + } + Vector<String> extra_args_ssh = p_preset->get("ssh_remote_deploy/extra_args_ssh").operator String().split(" ", false); + Vector<String> extra_args_scp = p_preset->get("ssh_remote_deploy/extra_args_scp").operator String().split(" ", false); + + const String basepath = dest.path_join("tmp_macos_export"); + +#define CLEANUP_AND_RETURN(m_err) \ + { \ + if (da->file_exists(basepath + ".zip")) { \ + da->remove(basepath + ".zip"); \ + } \ + if (da->file_exists(basepath + "_start.sh")) { \ + da->remove(basepath + "_start.sh"); \ + } \ + if (da->file_exists(basepath + "_clean.sh")) { \ + da->remove(basepath + "_clean.sh"); \ + } \ + return m_err; \ + } \ + ((void)0) + + if (ep.step(TTR("Exporting project..."), 1)) { + return ERR_SKIP; + } + Error err = export_project(p_preset, true, basepath + ".zip", p_debug_flags); + if (err != OK) { + DirAccess::remove_file_or_error(basepath + ".zip"); + return err; + } + + String cmd_args; + { + Vector<String> cmd_args_list; + gen_debug_flags(cmd_args_list, p_debug_flags); + for (int i = 0; i < cmd_args_list.size(); i++) { + if (i != 0) { + cmd_args += " "; + } + cmd_args += cmd_args_list[i]; } - if ((bool)p_preset->get("codesign/entitlements/photos_library") && ((String)p_preset->get("privacy/photos_library_usage_description")).is_empty()) { - err += TTR("Privacy: Photo library access is enabled, but usage description is not specified.") + "\n"; - valid = false; + } + + const bool use_remote = (p_debug_flags & DEBUG_FLAG_REMOTE_DEBUG) || (p_debug_flags & DEBUG_FLAG_DUMB_CLIENT); + int dbg_port = EditorSettings::get_singleton()->get("network/debug/remote_port"); + + print_line("Creating temporary directory..."); + ep.step(TTR("Creating temporary directory..."), 2); + String temp_dir; + err = ssh_run_on_remote(host, port, extra_args_ssh, "mktemp -d", &temp_dir); + if (err != OK || temp_dir.is_empty()) { + CLEANUP_AND_RETURN(err); + } + + print_line("Uploading archive..."); + ep.step(TTR("Uploading archive..."), 3); + err = ssh_push_to_remote(host, port, extra_args_scp, basepath + ".zip", temp_dir); + if (err != OK) { + CLEANUP_AND_RETURN(err); + } + + { + String run_script = p_preset->get("ssh_remote_deploy/run_script"); + run_script = run_script.replace("{temp_dir}", temp_dir); + run_script = run_script.replace("{archive_name}", basepath.get_file() + ".zip"); + run_script = run_script.replace("{exe_name}", pkg_name); + run_script = run_script.replace("{cmd_args}", cmd_args); + + Ref<FileAccess> f = FileAccess::open(basepath + "_start.sh", FileAccess::WRITE); + if (f.is_null()) { + CLEANUP_AND_RETURN(err); } + + f->store_string(run_script); } - if (!err.is_empty()) { - r_error = err; + { + String clean_script = p_preset->get("ssh_remote_deploy/cleanup_script"); + clean_script = clean_script.replace("{temp_dir}", temp_dir); + clean_script = clean_script.replace("{archive_name}", basepath.get_file() + ".zip"); + clean_script = clean_script.replace("{exe_name}", pkg_name); + clean_script = clean_script.replace("{cmd_args}", cmd_args); + + Ref<FileAccess> f = FileAccess::open(basepath + "_clean.sh", FileAccess::WRITE); + if (f.is_null()) { + CLEANUP_AND_RETURN(err); + } + + f->store_string(clean_script); } - return valid; + + print_line("Uploading scripts..."); + ep.step(TTR("Uploading scripts..."), 4); + err = ssh_push_to_remote(host, port, extra_args_scp, basepath + "_start.sh", temp_dir); + if (err != OK) { + CLEANUP_AND_RETURN(err); + } + err = ssh_run_on_remote(host, port, extra_args_ssh, vformat("chmod +x \"%s/%s\"", temp_dir, basepath.get_file() + "_start.sh")); + if (err != OK || temp_dir.is_empty()) { + CLEANUP_AND_RETURN(err); + } + err = ssh_push_to_remote(host, port, extra_args_scp, basepath + "_clean.sh", temp_dir); + if (err != OK) { + CLEANUP_AND_RETURN(err); + } + err = ssh_run_on_remote(host, port, extra_args_ssh, vformat("chmod +x \"%s/%s\"", temp_dir, basepath.get_file() + "_clean.sh")); + if (err != OK || temp_dir.is_empty()) { + CLEANUP_AND_RETURN(err); + } + + print_line("Starting project..."); + ep.step(TTR("Starting project..."), 5); + err = ssh_run_on_remote_no_wait(host, port, extra_args_ssh, vformat("\"%s/%s\"", temp_dir, basepath.get_file() + "_start.sh"), &ssh_pid, (use_remote) ? dbg_port : -1); + if (err != OK) { + CLEANUP_AND_RETURN(err); + } + + cleanup_commands.clear(); + cleanup_commands.push_back(SSHCleanupCommand(host, port, extra_args_ssh, vformat("\"%s/%s\"", temp_dir, basepath.get_file() + "_clean.sh"))); + + print_line("Project started."); + + CLEANUP_AND_RETURN(OK); +#undef CLEANUP_AND_RETURN } EditorExportPlatformMacOS::EditorExportPlatformMacOS() { - logo = ImageTexture::create_from_image(memnew(Image(_macos_logo))); -} + if (EditorNode::get_singleton()) { +#ifdef MODULE_SVG_ENABLED + Ref<Image> img = memnew(Image); + const bool upsample = !Math::is_equal_approx(Math::round(EDSCALE), EDSCALE); + + ImageLoaderSVG img_loader; + img_loader.create_image_from_string(img, _macos_logo_svg, EDSCALE, upsample, false); + logo = ImageTexture::create_from_image(img); -EditorExportPlatformMacOS::~EditorExportPlatformMacOS() { + img_loader.create_image_from_string(img, _macos_run_icon_svg, EDSCALE, upsample, false); + run_icon = ImageTexture::create_from_image(img); +#endif + + Ref<Theme> theme = EditorNode::get_singleton()->get_editor_theme(); + if (theme.is_valid()) { + stop_icon = theme->get_icon(SNAME("Stop"), SNAME("EditorIcons")); + } else { + stop_icon.instantiate(); + } + } } diff --git a/platform/macos/export/export_plugin.h b/platform/macos/export/export_plugin.h index b6ad587caa..0477a8c0cc 100644 --- a/platform/macos/export/export_plugin.h +++ b/platform/macos/export/export_plugin.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* export_plugin.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* export_plugin.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 MACOS_EXPORT_PLUGIN_H #define MACOS_EXPORT_PLUGIN_H @@ -36,15 +36,24 @@ #include "core/io/file_access.h" #include "core/io/marshalls.h" #include "core/io/resource_saver.h" -#include "core/io/zip_io.h" #include "core/os/os.h" #include "core/version.h" #include "editor/editor_settings.h" #include "editor/export/editor_export.h" -#include "platform/macos/logo.gen.h" #include <sys/stat.h> +// Optional environment variables for defining confidential information. If any +// of these is set, they will override the values set in the credentials file. +const String ENV_MAC_CODESIGN_CERT_FILE = "GODOT_MACOS_CODESIGN_CERTIFICATE_FILE"; +const String ENV_MAC_CODESIGN_CERT_PASS = "GODOT_MACOS_CODESIGN_CERTIFICATE_PASSWORD"; +const String ENV_MAC_CODESIGN_PROFILE = "GODOT_MACOS_CODESIGN_PROVISIONING_PROFILE"; +const String ENV_MAC_NOTARIZATION_UUID = "GODOT_MACOS_NOTARIZATION_API_UUID"; +const String ENV_MAC_NOTARIZATION_KEY = "GODOT_MACOS_NOTARIZATION_API_KEY"; +const String ENV_MAC_NOTARIZATION_KEY_ID = "GODOT_MACOS_NOTARIZATION_API_KEY_ID"; +const String ENV_MAC_NOTARIZATION_APPLE_ID = "GODOT_MACOS_NOTARIZATION_APPLE_ID_NAME"; +const String ENV_MAC_NOTARIZATION_APPLE_PASS = "GODOT_MACOS_NOTARIZATION_APPLE_ID_PASSWORD"; + class EditorExportPlatformMacOS : public EditorExportPlatform { GDCLASS(EditorExportPlatformMacOS, EditorExportPlatform); @@ -52,8 +61,32 @@ class EditorExportPlatformMacOS : public EditorExportPlatform { Ref<ImageTexture> logo; + struct SSHCleanupCommand { + String host; + String port; + Vector<String> ssh_args; + String cmd_args; + bool wait = false; + + SSHCleanupCommand(){}; + SSHCleanupCommand(const String &p_host, const String &p_port, const Vector<String> &p_ssh_arg, const String &p_cmd_args, bool p_wait = false) { + host = p_host; + port = p_port; + ssh_args = p_ssh_arg; + cmd_args = p_cmd_args; + wait = p_wait; + }; + }; + + Ref<ImageTexture> run_icon; + Ref<ImageTexture> stop_icon; + + Vector<SSHCleanupCommand> cleanup_commands; + OS::ProcessID ssh_pid = 0; + int menu_options = 0; + void _fix_plist(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &plist, const String &p_binary); - void _make_icon(const Ref<Image> &p_icon, Vector<uint8_t> &p_data); + void _make_icon(const Ref<EditorExportPreset> &p_preset, const Ref<Image> &p_icon, Vector<uint8_t> &p_data); Error _notarize(const Ref<EditorExportPreset> &p_preset, const String &p_path); Error _code_sign(const Ref<EditorExportPreset> &p_preset, const String &p_path, const String &p_ent_path, bool p_warn = true); @@ -65,15 +98,10 @@ class EditorExportPlatformMacOS : public EditorExportPlatform { 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); - void _zip_folder_recursive(zipFile &p_zip, const String &p_root_path, const String &p_folder, const String &p_pkg_name); + Error _create_pkg(const Ref<EditorExportPreset> &p_preset, const String &p_pkg_path, const String &p_app_path_name); 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 MACOS_ENABLED - bool use_dmg() const { return true; } -#else - bool use_dmg() const { return false; } -#endif bool is_package_name_valid(const String &p_package, String *r_error = nullptr) const { String pname = p_package; @@ -97,28 +125,27 @@ class EditorExportPlatformMacOS : public EditorExportPlatform { return true; } - bool is_shbang(const String &p_path) const; + bool is_shebang(const String &p_path) const; protected: virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const override; - virtual void get_export_options(List<ExportOption> *r_options) override; - virtual bool get_export_option_visibility(const EditorExportPreset *p_preset, const String &p_option, const HashMap<StringName, Variant> &p_options) const override; + virtual void get_export_options(List<ExportOption> *r_options) const override; + virtual bool get_export_option_visibility(const EditorExportPreset *p_preset, const String &p_option) const override; + virtual String get_export_option_warning(const EditorExportPreset *p_preset, const StringName &p_name) const override; public: - virtual String get_name() const override { return "macOS"; } - virtual String get_os_name() const override { return "macOS"; } - virtual Ref<Texture2D> get_logo() const override { return logo; } + virtual String get_name() const override { + return "macOS"; + } + virtual String get_os_name() const override { + return "macOS"; + } + virtual Ref<Texture2D> get_logo() const override { + return logo; + } virtual bool is_executable(const String &p_path) const override; - virtual List<String> get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const override { - List<String> list; - if (use_dmg()) { - list.push_back("dmg"); - } - list.push_back("zip"); - list.push_back("app"); - return list; - } + virtual List<String> get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const override; virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0) override; virtual bool has_valid_export_configuration(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const override; @@ -133,8 +160,16 @@ public: virtual void resolve_platform_feature_priorities(const Ref<EditorExportPreset> &p_preset, HashSet<String> &p_features) override { } + virtual Ref<Texture2D> get_run_icon() const override; + virtual bool poll_export() override; + virtual Ref<ImageTexture> get_option_icon(int p_index) const override; + virtual int get_options_count() const override; + virtual String get_option_label(int p_index) const override; + virtual String get_option_tooltip(int p_index) const override; + virtual Error run(const Ref<EditorExportPreset> &p_preset, int p_device, int p_debug_flags) override; + virtual void cleanup() override; + EditorExportPlatformMacOS(); - ~EditorExportPlatformMacOS(); }; #endif // MACOS_EXPORT_PLUGIN_H diff --git a/platform/macos/export/lipo.cpp b/platform/macos/export/lipo.cpp index 76d4eee418..2d77e5960d 100644 --- a/platform/macos/export/lipo.cpp +++ b/platform/macos/export/lipo.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* lipo.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* lipo.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "lipo.h" @@ -45,25 +45,27 @@ bool LipO::create_file(const String &p_output_path, const PackedStringArray &p_f uint64_t max_size = 0; for (int i = 0; i < p_files.size(); i++) { - MachO mh; - if (!mh.open_file(p_files[i])) { - ERR_FAIL_V_MSG(false, vformat("LipO: Invalid MachO file: \"%s.\"", p_files[i])); - } + { + MachO mh; + if (!mh.open_file(p_files[i])) { + ERR_FAIL_V_MSG(false, vformat("LipO: Invalid MachO file: \"%s\".", p_files[i])); + } - FatArch arch; - arch.cputype = mh.get_cputype(); - arch.cpusubtype = mh.get_cpusubtype(); - arch.offset = 0; - arch.size = mh.get_size(); - arch.align = mh.get_align(); - max_size += arch.size; + FatArch arch; + arch.cputype = mh.get_cputype(); + arch.cpusubtype = mh.get_cpusubtype(); + arch.offset = 0; + arch.size = mh.get_size(); + arch.align = mh.get_align(); + max_size += arch.size; - archs.push_back(arch); + archs.push_back(arch); + } Ref<FileAccess> fb = FileAccess::open(p_files[i], FileAccess::READ); if (fb.is_null()) { close(); - ERR_FAIL_V_MSG(false, vformat("LipO: Can't open file: \"%s.\"", p_files[i])); + ERR_FAIL_V_MSG(false, vformat("LipO: Can't open file: \"%s\".", p_files[i])); } } @@ -100,7 +102,7 @@ bool LipO::create_file(const String &p_output_path, const PackedStringArray &p_f Ref<FileAccess> fb = FileAccess::open(p_files[i], FileAccess::READ); if (fb.is_null()) { close(); - ERR_FAIL_V_MSG(false, vformat("LipO: Can't open file: \"%s.\"", p_files[i])); + ERR_FAIL_V_MSG(false, vformat("LipO: Can't open file: \"%s\".", p_files[i])); } uint64_t cur = fa->get_position(); for (uint64_t j = cur; j < archs[i].offset; j++) { diff --git a/platform/macos/export/lipo.h b/platform/macos/export/lipo.h index bd8b7f6f2c..e375fc5a66 100644 --- a/platform/macos/export/lipo.h +++ b/platform/macos/export/lipo.h @@ -1,43 +1,43 @@ -/*************************************************************************/ -/* lipo.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* lipo.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 MACOS_LIPO_H #define MACOS_LIPO_H // Universal / Universal 2 fat binary file creator and extractor. +#include "macho.h" + #include "core/io/file_access.h" #include "core/object/ref_counted.h" -#include "macho.h" - class LipO : public RefCounted { struct FatArch { uint32_t cputype; diff --git a/platform/macos/export/macho.cpp b/platform/macos/export/macho.cpp index 642d99e098..c7556c1964 100644 --- a/platform/macos/export/macho.cpp +++ b/platform/macos/export/macho.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* macho.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* macho.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "macho.h" diff --git a/platform/macos/export/macho.h b/platform/macos/export/macho.h index 0c954e66b1..37975f0820 100644 --- a/platform/macos/export/macho.h +++ b/platform/macos/export/macho.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* macho.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* macho.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 MACOS_MACHO_H #define MACOS_MACHO_H diff --git a/platform/macos/export/plist.cpp b/platform/macos/export/plist.cpp index cad014e65b..f494c58fc9 100644 --- a/platform/macos/export/plist.cpp +++ b/platform/macos/export/plist.cpp @@ -1,35 +1,148 @@ -/*************************************************************************/ -/* plist.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* plist.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "plist.h" +PList::PLNodeType PListNode::get_type() const { + return data_type; +} + +Variant PListNode::get_value() const { + switch (data_type) { + case PList::PL_NODE_TYPE_NIL: { + return Variant(); + } break; + case PList::PL_NODE_TYPE_STRING: { + return String::utf8(data_string.get_data()); + } break; + case PList::PL_NODE_TYPE_ARRAY: { + Array arr; + for (const Ref<PListNode> &E : data_array) { + arr.push_back(E); + } + return arr; + } break; + case PList::PL_NODE_TYPE_DICT: { + Dictionary dict; + for (const KeyValue<String, Ref<PListNode>> &E : data_dict) { + dict[E.key] = E.value; + } + return dict; + } break; + case PList::PL_NODE_TYPE_BOOLEAN: { + return data_bool; + } break; + case PList::PL_NODE_TYPE_INTEGER: { + return data_int; + } break; + case PList::PL_NODE_TYPE_REAL: { + return data_real; + } break; + case PList::PL_NODE_TYPE_DATA: { + int strlen = data_string.length(); + + size_t arr_len = 0; + Vector<uint8_t> buf; + { + buf.resize(strlen / 4 * 3 + 1); + uint8_t *w = buf.ptrw(); + + ERR_FAIL_COND_V(CryptoCore::b64_decode(&w[0], buf.size(), &arr_len, (unsigned char *)data_string.get_data(), strlen) != OK, Vector<uint8_t>()); + } + buf.resize(arr_len); + return buf; + } break; + case PList::PL_NODE_TYPE_DATE: { + return String(data_string.get_data()); + } break; + } + return Variant(); +} + +Ref<PListNode> PListNode::new_node(const Variant &p_value) { + Ref<PListNode> node; + node.instantiate(); + + switch (p_value.get_type()) { + case Variant::NIL: { + node->data_type = PList::PL_NODE_TYPE_NIL; + } break; + case Variant::BOOL: { + node->data_type = PList::PL_NODE_TYPE_BOOLEAN; + node->data_bool = p_value; + } break; + case Variant::INT: { + node->data_type = PList::PL_NODE_TYPE_INTEGER; + node->data_int = p_value; + } break; + case Variant::FLOAT: { + node->data_type = PList::PL_NODE_TYPE_REAL; + node->data_real = p_value; + } break; + case Variant::STRING_NAME: + case Variant::STRING: { + node->data_type = PList::PL_NODE_TYPE_STRING; + node->data_string = p_value.operator String().utf8(); + } break; + case Variant::DICTIONARY: { + node->data_type = PList::PL_NODE_TYPE_DICT; + Dictionary dict = p_value; + const Variant *next = dict.next(nullptr); + while (next) { + Ref<PListNode> sub_node = dict[*next]; + ERR_FAIL_COND_V_MSG(sub_node.is_null(), Ref<PListNode>(), "Invalid dictionary element, should be PListNode."); + node->data_dict[*next] = sub_node; + next = dict.next(next); + } + } break; + case Variant::ARRAY: { + node->data_type = PList::PL_NODE_TYPE_ARRAY; + Array ar = p_value; + for (int i = 0; i < ar.size(); i++) { + Ref<PListNode> sub_node = ar[i]; + ERR_FAIL_COND_V_MSG(sub_node.is_null(), Ref<PListNode>(), "Invalid array element, should be PListNode."); + node->data_array.push_back(sub_node); + } + } break; + case Variant::PACKED_BYTE_ARRAY: { + node->data_type = PList::PL_NODE_TYPE_DATA; + PackedByteArray buf = p_value; + node->data_string = CryptoCore::b64_encode_str(buf.ptr(), buf.size()).utf8(); + } break; + default: { + ERR_FAIL_V_MSG(Ref<PListNode>(), "Unsupported data type."); + } break; + } + return node; +} + Ref<PListNode> PListNode::new_array() { Ref<PListNode> node = memnew(PListNode()); ERR_FAIL_COND_V(node.is_null(), Ref<PListNode>()); @@ -65,6 +178,7 @@ Ref<PListNode> PListNode::new_date(const String &p_string) { ERR_FAIL_COND_V(node.is_null(), Ref<PListNode>()); node->data_type = PList::PLNodeType::PL_NODE_TYPE_DATE; node->data_string = p_string.utf8(); + node->data_real = (double)Time::get_singleton()->get_unix_time_from_datetime_string(p_string) - 978307200.0; return node; } @@ -76,7 +190,7 @@ Ref<PListNode> PListNode::new_bool(bool p_bool) { return node; } -Ref<PListNode> PListNode::new_int(int32_t p_int) { +Ref<PListNode> PListNode::new_int(int64_t p_int) { Ref<PListNode> node = memnew(PListNode()); ERR_FAIL_COND_V(node.is_null(), Ref<PListNode>()); node->data_type = PList::PLNodeType::PL_NODE_TYPE_INTEGER; @@ -84,7 +198,7 @@ Ref<PListNode> PListNode::new_int(int32_t p_int) { return node; } -Ref<PListNode> PListNode::new_real(float p_real) { +Ref<PListNode> PListNode::new_real(double p_real) { Ref<PListNode> node = memnew(PListNode()); ERR_FAIL_COND_V(node.is_null(), Ref<PListNode>()); node->data_type = PList::PLNodeType::PL_NODE_TYPE_REAL; @@ -337,6 +451,168 @@ PList::PList(const String &p_string) { load_string(p_string); } +uint64_t PList::read_bplist_var_size_int(Ref<FileAccess> p_file, uint8_t p_size) { + uint64_t pos = p_file->get_position(); + uint64_t ret = 0; + switch (p_size) { + case 1: { + ret = p_file->get_8(); + } break; + case 2: { + ret = BSWAP16(p_file->get_16()); + } break; + case 3: { + ret = BSWAP32(p_file->get_32() & 0x00FFFFFF); + } break; + case 4: { + ret = BSWAP32(p_file->get_32()); + } break; + case 5: { + ret = BSWAP64(p_file->get_64() & 0x000000FFFFFFFFFF); + } break; + case 6: { + ret = BSWAP64(p_file->get_64() & 0x0000FFFFFFFFFFFF); + } break; + case 7: { + ret = BSWAP64(p_file->get_64() & 0x00FFFFFFFFFFFFFF); + } break; + case 8: { + ret = BSWAP64(p_file->get_64()); + } break; + default: { + ret = 0; + } + } + p_file->seek(pos + p_size); + + return ret; +} + +Ref<PListNode> PList::read_bplist_obj(Ref<FileAccess> p_file, uint64_t p_offset_idx) { + Ref<PListNode> node; + node.instantiate(); + + uint64_t ot_off = trailer.offset_table_start + p_offset_idx * trailer.offset_size; + p_file->seek(ot_off); + uint64_t marker_off = read_bplist_var_size_int(p_file, trailer.offset_size); + ERR_FAIL_COND_V_MSG(marker_off == 0, Ref<PListNode>(), "Invalid marker size."); + + p_file->seek(marker_off); + uint8_t marker = p_file->get_8(); + uint8_t marker_type = marker & 0xF0; + uint64_t marker_size = marker & 0x0F; + + switch (marker_type) { + case 0x00: { + if (marker_size == 0x00) { + node->data_type = PL_NODE_TYPE_NIL; + } else if (marker_size == 0x08) { + node->data_type = PL_NODE_TYPE_BOOLEAN; + node->data_bool = false; + } else if (marker_size == 0x09) { + node->data_type = PL_NODE_TYPE_BOOLEAN; + node->data_bool = true; + } else { + ERR_FAIL_V_MSG(Ref<PListNode>(), "Invalid nil/bool marker value."); + } + } break; + case 0x10: { + node->data_type = PL_NODE_TYPE_INTEGER; + node->data_int = static_cast<int64_t>(read_bplist_var_size_int(p_file, pow(2, marker_size))); + } break; + case 0x20: { + node->data_type = PL_NODE_TYPE_REAL; + node->data_int = static_cast<int64_t>(read_bplist_var_size_int(p_file, pow(2, marker_size))); + } break; + case 0x30: { + node->data_type = PL_NODE_TYPE_DATE; + node->data_int = BSWAP64(p_file->get_64()); + node->data_string = Time::get_singleton()->get_datetime_string_from_unix_time(node->data_real + 978307200.0).utf8(); + } break; + case 0x40: { + if (marker_size == 0x0F) { + uint8_t ext = p_file->get_8() & 0xF; + marker_size = read_bplist_var_size_int(p_file, pow(2, ext)); + } + node->data_type = PL_NODE_TYPE_DATA; + PackedByteArray buf; + buf.resize(marker_size + 1); + p_file->get_buffer(reinterpret_cast<uint8_t *>(buf.ptrw()), marker_size); + node->data_string = CryptoCore::b64_encode_str(buf.ptr(), buf.size()).utf8(); + } break; + case 0x50: { + if (marker_size == 0x0F) { + uint8_t ext = p_file->get_8() & 0xF; + marker_size = read_bplist_var_size_int(p_file, pow(2, ext)); + } + node->data_type = PL_NODE_TYPE_STRING; + node->data_string.resize(marker_size + 1); + p_file->get_buffer(reinterpret_cast<uint8_t *>(node->data_string.ptrw()), marker_size); + } break; + case 0x60: { + if (marker_size == 0x0F) { + uint8_t ext = p_file->get_8() & 0xF; + marker_size = read_bplist_var_size_int(p_file, pow(2, ext)); + } + Char16String cs16; + cs16.resize(marker_size + 1); + for (uint64_t i = 0; i < marker_size; i++) { + cs16[i] = BSWAP16(p_file->get_16()); + } + node->data_type = PL_NODE_TYPE_STRING; + node->data_string = String::utf16(cs16.ptr(), cs16.length()).utf8(); + } break; + case 0x80: { + node->data_type = PL_NODE_TYPE_INTEGER; + node->data_int = static_cast<int64_t>(read_bplist_var_size_int(p_file, marker_size + 1)); + } break; + case 0xA0: + case 0xC0: { + if (marker_size == 0x0F) { + uint8_t ext = p_file->get_8() & 0xF; + marker_size = read_bplist_var_size_int(p_file, pow(2, ext)); + } + uint64_t pos = p_file->get_position(); + + node->data_type = PL_NODE_TYPE_ARRAY; + for (uint64_t i = 0; i < marker_size; i++) { + p_file->seek(pos + trailer.ref_size * i); + uint64_t ref = read_bplist_var_size_int(p_file, trailer.ref_size); + + Ref<PListNode> element = read_bplist_obj(p_file, ref); + ERR_FAIL_COND_V(element.is_null(), Ref<PListNode>()); + node->data_array.push_back(element); + } + } break; + case 0xD0: { + if (marker_size == 0x0F) { + uint8_t ext = p_file->get_8() & 0xF; + marker_size = read_bplist_var_size_int(p_file, pow(2, ext)); + } + uint64_t pos = p_file->get_position(); + + node->data_type = PL_NODE_TYPE_DICT; + for (uint64_t i = 0; i < marker_size; i++) { + p_file->seek(pos + trailer.ref_size * i); + uint64_t key_ref = read_bplist_var_size_int(p_file, trailer.ref_size); + + p_file->seek(pos + trailer.ref_size * (i + marker_size)); + uint64_t obj_ref = read_bplist_var_size_int(p_file, trailer.ref_size); + + Ref<PListNode> element_key = read_bplist_obj(p_file, key_ref); + ERR_FAIL_COND_V(element_key.is_null() || element_key->data_type != PL_NODE_TYPE_STRING, Ref<PListNode>()); + Ref<PListNode> element = read_bplist_obj(p_file, obj_ref); + ERR_FAIL_COND_V(element.is_null(), Ref<PListNode>()); + node->data_dict[String::utf8(element_key->data_string.ptr(), element_key->data_string.length())] = element; + } + } break; + default: { + ERR_FAIL_V_MSG(Ref<PListNode>(), "Invalid marker type."); + } + } + return node; +} + bool PList::load_file(const String &p_filename) { root = Ref<PListNode>(); @@ -349,11 +625,19 @@ bool PList::load_file(const String &p_filename) { fb->get_buffer(magic, 8); if (String((const char *)magic, 8) == "bplist00") { - ERR_FAIL_V_MSG(false, "PList: Binary property lists are not supported."); + fb->seek_end(-26); + trailer.offset_size = fb->get_8(); + trailer.ref_size = fb->get_8(); + trailer.object_num = BSWAP64(fb->get_64()); + trailer.root_offset_idx = BSWAP64(fb->get_64()); + trailer.offset_table_start = BSWAP64(fb->get_64()); + root = read_bplist_obj(fb, trailer.root_offset_idx); + + return root.is_valid(); } else { // Load text plist. Error err; - Vector<uint8_t> array = FileAccess::get_file_as_array(p_filename, &err); + Vector<uint8_t> array = FileAccess::get_file_as_bytes(p_filename, &err); ERR_FAIL_COND_V(err != OK, false); String ret; diff --git a/platform/macos/export/plist.h b/platform/macos/export/plist.h index 97331a3629..28b02e4eb7 100644 --- a/platform/macos/export/plist.h +++ b/platform/macos/export/plist.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* plist.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* plist.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 MACOS_PLIST_H #define MACOS_PLIST_H @@ -35,6 +35,7 @@ #include "core/crypto/crypto_core.h" #include "core/io/file_access.h" +#include "core/os/time.h" class PListNode; @@ -55,8 +56,20 @@ public: }; private: + struct PListTrailer { + uint8_t offset_size; + uint8_t ref_size; + uint64_t object_num; + uint64_t root_offset_idx; + uint64_t offset_table_start; + }; + + PListTrailer trailer; Ref<PListNode> root; + uint64_t read_bplist_var_size_int(Ref<FileAccess> p_file, uint8_t p_size); + Ref<PListNode> read_bplist_obj(Ref<FileAccess> p_file, uint64_t p_offset_idx); + public: PList(); PList(const String &p_string); @@ -82,19 +95,23 @@ public: Vector<Ref<PListNode>> data_array; HashMap<String, Ref<PListNode>> data_dict; union { - int32_t data_int; + int64_t data_int; bool data_bool; - float data_real; + double data_real; }; + PList::PLNodeType get_type() const; + Variant get_value() const; + + static Ref<PListNode> new_node(const Variant &p_value); static Ref<PListNode> new_array(); static Ref<PListNode> new_dict(); static Ref<PListNode> new_string(const String &p_string); static Ref<PListNode> new_data(const String &p_string); static Ref<PListNode> new_date(const String &p_string); static Ref<PListNode> new_bool(bool p_bool); - static Ref<PListNode> new_int(int32_t p_int); - static Ref<PListNode> new_real(float p_real); + static Ref<PListNode> new_int(int64_t p_int); + static Ref<PListNode> new_real(double p_real); bool push_subnode(const Ref<PListNode> &p_node, const String &p_key = ""); diff --git a/platform/macos/gl_manager_macos_legacy.h b/platform/macos/gl_manager_macos_legacy.h index 8752086551..94d966f4ed 100644 --- a/platform/macos/gl_manager_macos_legacy.h +++ b/platform/macos/gl_manager_macos_legacy.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* gl_manager_macos_legacy.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* gl_manager_macos_legacy.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 GL_MANAGER_MACOS_LEGACY_H #define GL_MANAGER_MACOS_LEGACY_H @@ -42,6 +42,9 @@ #import <ApplicationServices/ApplicationServices.h> #import <CoreVideo/CoreVideo.h> +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" // OpenGL is deprecated in macOS 10.14 + class GLManager_MacOS { public: enum ContextType { @@ -89,10 +92,14 @@ public: void set_use_vsync(bool p_use); bool is_using_vsync() const; + NSOpenGLContext *get_context(DisplayServer::WindowID p_window_id); + GLManager_MacOS(ContextType p_context_type); ~GLManager_MacOS(); }; +#pragma clang diagnostic push + #endif // MACOS_ENABLED && GLES3_ENABLED #endif // GL_MANAGER_MACOS_LEGACY_H diff --git a/platform/macos/gl_manager_macos_legacy.mm b/platform/macos/gl_manager_macos_legacy.mm index dec4821b86..550e2d5c59 100644 --- a/platform/macos/gl_manager_macos_legacy.mm +++ b/platform/macos/gl_manager_macos_legacy.mm @@ -1,41 +1,43 @@ -/*************************************************************************/ -/* gl_manager_macos_legacy.mm */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* gl_manager_macos_legacy.mm */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "gl_manager_macos_legacy.h" -#ifdef MACOS_ENABLED -#ifdef GLES3_ENABLED +#if defined(MACOS_ENABLED) && defined(GLES3_ENABLED) #include <stdio.h> #include <stdlib.h> +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" // OpenGL is deprecated in macOS 10.14 + Error GLManager_MacOS::create_context(GLWindow &win) { NSOpenGLPixelFormatAttribute attributes[] = { NSOpenGLPFADoubleBuffer, @@ -215,6 +217,15 @@ bool GLManager_MacOS::is_using_vsync() const { return use_vsync; } +NSOpenGLContext *GLManager_MacOS::get_context(DisplayServer::WindowID p_window_id) { + if (!windows.has(p_window_id)) { + return nullptr; + } + + GLWindow &win = windows[p_window_id]; + return win.context; +} + GLManager_MacOS::GLManager_MacOS(ContextType p_context_type) { context_type = p_context_type; } @@ -223,5 +234,6 @@ GLManager_MacOS::~GLManager_MacOS() { release_current(); } -#endif // GLES3_ENABLED -#endif // MACOS_ENABLED +#pragma clang diagnostic pop + +#endif // MACOS_ENABLED && GLES3_ENABLED diff --git a/platform/macos/godot_application.h b/platform/macos/godot_application.h index 8d48a659f3..8749c8fbb0 100644 --- a/platform/macos/godot_application.h +++ b/platform/macos/godot_application.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* godot_application.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* godot_application.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 GODOT_APPLICATION_H #define GODOT_APPLICATION_H @@ -35,6 +35,7 @@ #import <AppKit/AppKit.h> #import <Foundation/Foundation.h> +#import <IOKit/hidsystem/ev_keymap.h> @interface GodotApplication : NSApplication @end diff --git a/platform/macos/godot_application.mm b/platform/macos/godot_application.mm index 3f71c77fd1..e3a744caa2 100644 --- a/platform/macos/godot_application.mm +++ b/platform/macos/godot_application.mm @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* godot_application.mm */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* godot_application.mm */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "godot_application.h" @@ -34,7 +34,81 @@ @implementation GodotApplication +- (void)mediaKeyEvent:(int)key state:(BOOL)state repeat:(BOOL)repeat { + Key keycode = Key::NONE; + switch (key) { + case NX_KEYTYPE_SOUND_UP: { + keycode = Key::VOLUMEUP; + } break; + case NX_KEYTYPE_SOUND_DOWN: { + keycode = Key::VOLUMEUP; + } break; + //NX_KEYTYPE_BRIGHTNESS_UP + //NX_KEYTYPE_BRIGHTNESS_DOWN + case NX_KEYTYPE_CAPS_LOCK: { + keycode = Key::CAPSLOCK; + } break; + case NX_KEYTYPE_HELP: { + keycode = Key::HELP; + } break; + case NX_POWER_KEY: { + keycode = Key::STANDBY; + } break; + case NX_KEYTYPE_MUTE: { + keycode = Key::VOLUMEMUTE; + } break; + //NX_KEYTYPE_CONTRAST_UP + //NX_KEYTYPE_CONTRAST_DOWN + //NX_KEYTYPE_LAUNCH_PANEL + //NX_KEYTYPE_EJECT + //NX_KEYTYPE_VIDMIRROR + //NX_KEYTYPE_FAST + //NX_KEYTYPE_REWIND + //NX_KEYTYPE_ILLUMINATION_UP + //NX_KEYTYPE_ILLUMINATION_DOWN + //NX_KEYTYPE_ILLUMINATION_TOGGLE + case NX_KEYTYPE_PLAY: { + keycode = Key::MEDIAPLAY; + } break; + case NX_KEYTYPE_NEXT: { + keycode = Key::MEDIANEXT; + } break; + case NX_KEYTYPE_PREVIOUS: { + keycode = Key::MEDIAPREVIOUS; + } break; + default: { + keycode = Key::NONE; + } break; + } + + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); + if (ds && keycode != Key::NONE) { + DisplayServerMacOS::KeyEvent ke; + + ke.window_id = ds->_get_focused_window_or_popup(); + ke.macos_state = 0; + ke.pressed = state; + ke.echo = repeat; + ke.keycode = keycode; + ke.physical_keycode = keycode; + ke.key_label = keycode; + ke.unicode = 0; + ke.raw = true; + + ds->push_to_key_event_buffer(ke); + } +} + - (void)sendEvent:(NSEvent *)event { + if ([event type] == NSSystemDefined && [event subtype] == 8) { + int keyCode = (([event data1] & 0xFFFF0000) >> 16); + int keyFlags = ([event data1] & 0x0000FFFF); + int keyState = (((keyFlags & 0xFF00) >> 8)) == 0xA; + int keyRepeat = (keyFlags & 0x1); + + [self mediaKeyEvent:keyCode state:keyState repeat:keyRepeat]; + } + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (ds) { if ([event type] == NSEventTypeLeftMouseDown || [event type] == NSEventTypeRightMouseDown || [event type] == NSEventTypeOtherMouseDown) { diff --git a/platform/macos/godot_application_delegate.h b/platform/macos/godot_application_delegate.h index f5b67b580f..2426fb0b1c 100644 --- a/platform/macos/godot_application_delegate.h +++ b/platform/macos/godot_application_delegate.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* godot_application_delegate.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* godot_application_delegate.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 GODOT_APPLICATION_DELEGATE_H #define GODOT_APPLICATION_DELEGATE_H diff --git a/platform/macos/godot_application_delegate.mm b/platform/macos/godot_application_delegate.mm index bacdcc2bc4..a1925195b8 100644 --- a/platform/macos/godot_application_delegate.mm +++ b/platform/macos/godot_application_delegate.mm @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* godot_application_delegate.mm */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* godot_application_delegate.mm */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "godot_application_delegate.h" @@ -61,7 +61,9 @@ - (void)applicationDidFinishLaunching:(NSNotification *)notice { NSString *nsappname = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"]; - if (nsappname == nil || isatty(STDOUT_FILENO) || isatty(STDIN_FILENO) || isatty(STDERR_FILENO)) { + NSString *nsbundleid_env = [NSString stringWithUTF8String:getenv("__CFBundleIdentifier")]; + NSString *nsbundleid = [[NSBundle mainBundle] bundleIdentifier]; + if (nsappname == nil || isatty(STDOUT_FILENO) || isatty(STDIN_FILENO) || isatty(STDERR_FILENO) || ![nsbundleid isEqualToString:nsbundleid_env]) { // If the executable is started from terminal or is not bundled, macOS WindowServer won't register and activate app window correctly (menu and title bar are grayed out and input ignored). [self performSelector:@selector(forceUnbundledWindowActivationHackStep1) withObject:nil afterDelay:0.02]; } diff --git a/platform/macos/godot_button_view.h b/platform/macos/godot_button_view.h index ef1d5fe412..cbf13f7e5e 100644 --- a/platform/macos/godot_button_view.h +++ b/platform/macos/godot_button_view.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* godot_button_view.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* godot_button_view.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 GODOT_BUTTON_VIEW_H #define GODOT_BUTTON_VIEW_H diff --git a/platform/macos/godot_button_view.mm b/platform/macos/godot_button_view.mm index 7d380cbe11..db4be0441d 100644 --- a/platform/macos/godot_button_view.mm +++ b/platform/macos/godot_button_view.mm @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* godot_button_view.mm */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* godot_button_view.mm */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "godot_button_view.h" diff --git a/platform/macos/godot_content_view.h b/platform/macos/godot_content_view.h index a6318ab903..0d18ac742a 100644 --- a/platform/macos/godot_content_view.h +++ b/platform/macos/godot_content_view.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* godot_content_view.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* godot_content_view.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 GODOT_CONTENT_VIEW_H #define GODOT_CONTENT_VIEW_H @@ -53,6 +53,9 @@ @end +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" // OpenGL is deprecated in macOS 10.14 + @interface GodotContentView : RootView <NSTextInputClient> { DisplayServer::WindowID window_id; NSTrackingArea *tracking_area; @@ -61,16 +64,19 @@ bool mouse_down_control; bool ignore_momentum_scroll; bool last_pen_inverted; + bool ime_suppress_next_keyup; id layer_delegate; } - (void)processScrollEvent:(NSEvent *)event button:(MouseButton)button factor:(double)factor; - (void)processPanEvent:(NSEvent *)event dx:(double)dx dy:(double)dy; -- (void)processMouseEvent:(NSEvent *)event index:(MouseButton)index mask:(MouseButton)mask pressed:(bool)pressed; +- (void)processMouseEvent:(NSEvent *)event index:(MouseButton)index pressed:(bool)pressed; - (void)setWindowID:(DisplayServer::WindowID)wid; - (void)updateLayerDelegate; - (void)cancelComposition; @end +#pragma clang diagnostic pop + #endif // GODOT_CONTENT_VIEW_H diff --git a/platform/macos/godot_content_view.mm b/platform/macos/godot_content_view.mm index cb70a5db86..3467bf90a1 100644 --- a/platform/macos/godot_content_view.mm +++ b/platform/macos/godot_content_view.mm @@ -1,37 +1,38 @@ -/*************************************************************************/ -/* godot_content_view.mm */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* godot_content_view.mm */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "godot_content_view.h" #include "display_server_macos.h" #include "key_mapping_macos.h" + #include "main/main.h" @implementation GodotContentLayerDelegate @@ -65,16 +66,28 @@ if (ds && ds->has_window(window_id)) { DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); NSRect frameRect = [wd.window_object frame]; - bool left = (wd.last_frame_rect.origin.x != frameRect.origin.x); - bool top = (wd.last_frame_rect.origin.y == frameRect.origin.y); - if (left && top) { - self.layerContentsPlacement = NSViewLayerContentsPlacementBottomRight; - } else if (left && !top) { - self.layerContentsPlacement = NSViewLayerContentsPlacementTopRight; - } else if (!left && top) { - self.layerContentsPlacement = NSViewLayerContentsPlacementBottomLeft; + if (wd.fs_transition || wd.initial_size) { + self.layerContentsPlacement = NSViewLayerContentsPlacementScaleAxesIndependently; + wd.initial_size = false; } else { - self.layerContentsPlacement = NSViewLayerContentsPlacementTopLeft; + bool left = (wd.last_frame_rect.origin.x != frameRect.origin.x); + bool bottom = (wd.last_frame_rect.origin.y != frameRect.origin.y); + bool right = (wd.last_frame_rect.origin.x + wd.last_frame_rect.size.width != frameRect.origin.x + frameRect.size.width); + bool top = (wd.last_frame_rect.origin.y + wd.last_frame_rect.size.height != frameRect.origin.y + frameRect.size.height); + + if (left && top) { + self.layerContentsPlacement = NSViewLayerContentsPlacementBottomRight; + } else if (left && bottom) { + self.layerContentsPlacement = NSViewLayerContentsPlacementTopRight; + } else if (left) { + self.layerContentsPlacement = NSViewLayerContentsPlacementRight; + } else if (right && top) { + self.layerContentsPlacement = NSViewLayerContentsPlacementBottomLeft; + } else if (right && bottom) { + self.layerContentsPlacement = NSViewLayerContentsPlacementTopLeft; + } else if (right) { + self.layerContentsPlacement = NSViewLayerContentsPlacementLeft; + } } wd.last_frame_rect = frameRect; } @@ -103,13 +116,7 @@ self.layerContentsRedrawPolicy = NSViewLayerContentsRedrawDuringViewResize; self.layerContentsPlacement = NSViewLayerContentsPlacementTopLeft; - if (@available(macOS 10.13, *)) { - [self registerForDraggedTypes:[NSArray arrayWithObject:NSPasteboardTypeFileURL]]; -#if !defined(__aarch64__) // Do not build deprectead 10.13 code on ARM. - } else { - [self registerForDraggedTypes:[NSArray arrayWithObject:NSFilenamesPboardType]]; -#endif - } + [self registerForDraggedTypes:[NSArray arrayWithObject:NSPasteboardTypeFileURL]]; marked_text = [[NSMutableAttributedString alloc] init]; return self; } @@ -173,6 +180,7 @@ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); if (wd.im_active) { ime_input_event_in_progress = true; + ds->pop_last_key_event(); ds->update_im_text(Point2i(selectedRange.location, selectedRange.length), String::utf8([[marked_text mutableString] UTF8String])); } } @@ -182,6 +190,9 @@ } - (void)unmarkText { + if (ime_input_event_in_progress) { + ime_suppress_next_keyup = true; + } ime_input_event_in_progress = false; [[marked_text mutableString] setString:@""]; @@ -233,8 +244,6 @@ } - (void)insertText:(id)aString replacementRange:(NSRange)replacementRange { - NSEvent *event = [NSApp currentEvent]; - NSString *characters; if ([aString isKindOfClass:[NSAttributedString class]]) { characters = [aString string]; @@ -272,13 +281,14 @@ DisplayServerMacOS::KeyEvent ke; ke.window_id = window_id; - ke.macos_state = [event modifierFlags]; + ke.macos_state = 0; ke.pressed = true; ke.echo = false; ke.raw = false; // IME input event. ke.keycode = Key::NONE; ke.physical_keycode = Key::NONE; - ke.unicode = codepoint; + ke.key_label = Key::NONE; + ke.unicode = fix_unicode(codepoint); ds->push_to_key_event_buffer(ke); } @@ -306,20 +316,11 @@ Vector<String> files; NSPasteboard *pboard = [sender draggingPasteboard]; - if (@available(macOS 10.13, *)) { - NSArray *items = pboard.pasteboardItems; - for (NSPasteboardItem *item in items) { - NSString *url = [item stringForType:NSPasteboardTypeFileURL]; - NSString *file = [NSURL URLWithString:url].path; - files.push_back(String::utf8([file UTF8String])); - } -#if !defined(__aarch64__) // Do not build deprectead 10.13 code on ARM. - } else { - NSArray *filenames = [pboard propertyListForType:NSFilenamesPboardType]; - for (NSString *file in filenames) { - files.push_back(String::utf8([file UTF8String])); - } -#endif + NSArray *items = pboard.pasteboardItems; + for (NSPasteboardItem *item in items) { + NSString *url = [item stringForType:NSPasteboardTypeFileURL]; + NSString *file = [NSURL URLWithString:url].path; + files.push_back(String::utf8([file UTF8String])); } Variant v = files; @@ -341,7 +342,7 @@ } DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); - return !wd.no_focus && !wd.is_popup; + return !wd.no_focus; } - (BOOL)acceptsFirstResponder { @@ -359,19 +360,21 @@ ds->cursor_update_shape(); } -- (void)processMouseEvent:(NSEvent *)event index:(MouseButton)index mask:(MouseButton)mask pressed:(bool)pressed { +- (void)processMouseEvent:(NSEvent *)event index:(MouseButton)index pressed:(bool)pressed { DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (!ds || !ds->has_window(window_id)) { return; } DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); - MouseButton last_button_state = ds->mouse_get_button_state(); + BitField<MouseButtonMask> last_button_state = ds->mouse_get_button_state(); + + MouseButtonMask mask = mouse_button_to_mask(index); if (pressed) { - last_button_state |= mask; + last_button_state.set_flag(mask); } else { - last_button_state &= (MouseButton)~mask; + last_button_state.clear_flag(mask); } ds->mouse_set_button_state(last_button_state); @@ -395,10 +398,10 @@ - (void)mouseDown:(NSEvent *)event { if (([event modifierFlags] & NSEventModifierFlagControl)) { mouse_down_control = true; - [self processMouseEvent:event index:MouseButton::RIGHT mask:MouseButton::MASK_RIGHT pressed:true]; + [self processMouseEvent:event index:MouseButton::RIGHT pressed:true]; } else { mouse_down_control = false; - [self processMouseEvent:event index:MouseButton::LEFT mask:MouseButton::MASK_LEFT pressed:true]; + [self processMouseEvent:event index:MouseButton::LEFT pressed:true]; } } @@ -408,9 +411,9 @@ - (void)mouseUp:(NSEvent *)event { if (mouse_down_control) { - [self processMouseEvent:event index:MouseButton::RIGHT mask:MouseButton::MASK_RIGHT pressed:false]; + [self processMouseEvent:event index:MouseButton::RIGHT pressed:false]; } else { - [self processMouseEvent:event index:MouseButton::LEFT mask:MouseButton::MASK_LEFT pressed:false]; + [self processMouseEvent:event index:MouseButton::LEFT pressed:false]; } } @@ -440,7 +443,7 @@ NSEventSubtype subtype = [event subtype]; if (subtype == NSEventSubtypeTabletPoint) { const NSPoint p = [event tilt]; - mm->set_tilt(Vector2(p.x, p.y)); + 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. @@ -457,7 +460,7 @@ } - (void)rightMouseDown:(NSEvent *)event { - [self processMouseEvent:event index:MouseButton::RIGHT mask:MouseButton::MASK_RIGHT pressed:true]; + [self processMouseEvent:event index:MouseButton::RIGHT pressed:true]; } - (void)rightMouseDragged:(NSEvent *)event { @@ -465,16 +468,16 @@ } - (void)rightMouseUp:(NSEvent *)event { - [self processMouseEvent:event index:MouseButton::RIGHT mask:MouseButton::MASK_RIGHT pressed:false]; + [self processMouseEvent:event index:MouseButton::RIGHT pressed:false]; } - (void)otherMouseDown:(NSEvent *)event { if ((int)[event buttonNumber] == 2) { - [self processMouseEvent:event index:MouseButton::MIDDLE mask:MouseButton::MASK_MIDDLE pressed:true]; + [self processMouseEvent:event index:MouseButton::MIDDLE pressed:true]; } else if ((int)[event buttonNumber] == 3) { - [self processMouseEvent:event index:MouseButton::MB_XBUTTON1 mask:MouseButton::MASK_XBUTTON1 pressed:true]; + [self processMouseEvent:event index:MouseButton::MB_XBUTTON1 pressed:true]; } else if ((int)[event buttonNumber] == 4) { - [self processMouseEvent:event index:MouseButton::MB_XBUTTON2 mask:MouseButton::MASK_XBUTTON2 pressed:true]; + [self processMouseEvent:event index:MouseButton::MB_XBUTTON2 pressed:true]; } else { return; } @@ -486,11 +489,11 @@ - (void)otherMouseUp:(NSEvent *)event { if ((int)[event buttonNumber] == 2) { - [self processMouseEvent:event index:MouseButton::MIDDLE mask:MouseButton::MASK_MIDDLE pressed:false]; + [self processMouseEvent:event index:MouseButton::MIDDLE pressed:false]; } else if ((int)[event buttonNumber] == 3) { - [self processMouseEvent:event index:MouseButton::MB_XBUTTON1 mask:MouseButton::MASK_XBUTTON1 pressed:false]; + [self processMouseEvent:event index:MouseButton::MB_XBUTTON1 pressed:false]; } else if ((int)[event buttonNumber] == 4) { - [self processMouseEvent:event index:MouseButton::MB_XBUTTON2 mask:MouseButton::MASK_XBUTTON2 pressed:false]; + [self processMouseEvent:event index:MouseButton::MB_XBUTTON2 pressed:false]; } else { return; } @@ -570,7 +573,7 @@ NSString *characters = [event characters]; NSUInteger length = [characters length]; - if (!wd.im_active && length > 0 && keycode_has_unicode(KeyMappingMacOS::remap_key([event keyCode], [event modifierFlags]))) { + if (!wd.im_active && length > 0 && keycode_has_unicode(KeyMappingMacOS::remap_key([event keyCode], [event modifierFlags], true))) { // Fallback unicode character handler used if IME is not active. Char16String text; text.resize([characters length] + 1); @@ -588,10 +591,11 @@ ke.macos_state = [event modifierFlags]; ke.pressed = true; ke.echo = [event isARepeat]; - ke.keycode = KeyMappingMacOS::remap_key([event keyCode], [event modifierFlags]); + ke.keycode = KeyMappingMacOS::remap_key([event keyCode], [event modifierFlags], false); ke.physical_keycode = KeyMappingMacOS::translate_key([event keyCode]); + ke.key_label = KeyMappingMacOS::remap_key([event keyCode], [event modifierFlags], true); + ke.unicode = fix_unicode(codepoint); ke.raw = true; - ke.unicode = codepoint; ds->push_to_key_event_buffer(ke); } @@ -602,10 +606,11 @@ ke.macos_state = [event modifierFlags]; ke.pressed = true; ke.echo = [event isARepeat]; - ke.keycode = KeyMappingMacOS::remap_key([event keyCode], [event modifierFlags]); + ke.keycode = KeyMappingMacOS::remap_key([event keyCode], [event modifierFlags], false); ke.physical_keycode = KeyMappingMacOS::translate_key([event keyCode]); - ke.raw = false; + ke.key_label = KeyMappingMacOS::remap_key([event keyCode], [event modifierFlags], true); ke.unicode = 0; + ke.raw = false; ds->push_to_key_event_buffer(ke); } @@ -624,56 +629,54 @@ } ignore_momentum_scroll = true; - // Ignore all input if IME input is in progress - if (!ime_input_event_in_progress) { - DisplayServerMacOS::KeyEvent ke; + DisplayServerMacOS::KeyEvent ke; - ke.window_id = window_id; - ke.echo = false; - ke.raw = true; + ke.window_id = window_id; + ke.echo = false; + ke.raw = true; - int key = [event keyCode]; - int mod = [event modifierFlags]; + int key = [event keyCode]; + int mod = [event modifierFlags]; - if (key == 0x36 || key == 0x37) { - if (mod & NSEventModifierFlagCommand) { - mod &= ~NSEventModifierFlagCommand; - ke.pressed = true; - } else { - ke.pressed = false; - } - } else if (key == 0x38 || key == 0x3c) { - if (mod & NSEventModifierFlagShift) { - mod &= ~NSEventModifierFlagShift; - ke.pressed = true; - } else { - ke.pressed = false; - } - } else if (key == 0x3a || key == 0x3d) { - if (mod & NSEventModifierFlagOption) { - mod &= ~NSEventModifierFlagOption; - ke.pressed = true; - } else { - ke.pressed = false; - } - } else if (key == 0x3b || key == 0x3e) { - if (mod & NSEventModifierFlagControl) { - mod &= ~NSEventModifierFlagControl; - ke.pressed = true; - } else { - ke.pressed = false; - } + if (key == 0x36 || key == 0x37) { + if (mod & NSEventModifierFlagCommand) { + mod &= ~NSEventModifierFlagCommand; + ke.pressed = true; } else { - return; + ke.pressed = false; + } + } else if (key == 0x38 || key == 0x3c) { + if (mod & NSEventModifierFlagShift) { + mod &= ~NSEventModifierFlagShift; + ke.pressed = true; + } else { + ke.pressed = false; + } + } else if (key == 0x3a || key == 0x3d) { + if (mod & NSEventModifierFlagOption) { + mod &= ~NSEventModifierFlagOption; + ke.pressed = true; + } else { + ke.pressed = false; } + } else if (key == 0x3b || key == 0x3e) { + if (mod & NSEventModifierFlagControl) { + mod &= ~NSEventModifierFlagControl; + ke.pressed = true; + } else { + ke.pressed = false; + } + } else { + return; + } - ke.macos_state = mod; - ke.keycode = KeyMappingMacOS::remap_key(key, mod); - ke.physical_keycode = KeyMappingMacOS::translate_key(key); - ke.unicode = 0; + ke.macos_state = mod; + ke.keycode = KeyMappingMacOS::remap_key(key, mod, false); + ke.physical_keycode = KeyMappingMacOS::translate_key(key); + ke.key_label = KeyMappingMacOS::remap_key(key, mod, true); + ke.unicode = 0; - ds->push_to_key_event_buffer(ke); - } + ds->push_to_key_event_buffer(ke); } - (void)keyUp:(NSEvent *)event { @@ -682,51 +685,26 @@ return; } - DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); - // Ignore all input if IME input is in progress. - if (!ime_input_event_in_progress) { - NSString *characters = [event characters]; - NSUInteger length = [characters length]; - - // Fallback unicode character handler used if IME is not active. - 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])]; - - String u32text; - u32text.parse_utf16(text.ptr(), text.length()); - - for (int i = 0; i < u32text.length(); i++) { - const char32_t codepoint = u32text[i]; - DisplayServerMacOS::KeyEvent ke; - - ke.window_id = window_id; - ke.macos_state = [event modifierFlags]; - ke.pressed = false; - ke.echo = [event isARepeat]; - ke.keycode = KeyMappingMacOS::remap_key([event keyCode], [event modifierFlags]); - ke.physical_keycode = KeyMappingMacOS::translate_key([event keyCode]); - ke.raw = true; - ke.unicode = codepoint; + if (ime_suppress_next_keyup) { + ime_suppress_next_keyup = false; + return; + } - ds->push_to_key_event_buffer(ke); - } - } else { - DisplayServerMacOS::KeyEvent ke; + if (!ime_input_event_in_progress) { + DisplayServerMacOS::KeyEvent ke; - ke.window_id = window_id; - ke.macos_state = [event modifierFlags]; - ke.pressed = false; - ke.echo = [event isARepeat]; - ke.keycode = KeyMappingMacOS::remap_key([event keyCode], [event modifierFlags]); - ke.physical_keycode = KeyMappingMacOS::translate_key([event keyCode]); - ke.raw = true; - ke.unicode = 0; + ke.window_id = window_id; + ke.macos_state = [event modifierFlags]; + ke.pressed = false; + ke.echo = [event isARepeat]; + ke.keycode = KeyMappingMacOS::remap_key([event keyCode], [event modifierFlags], false); + ke.physical_keycode = KeyMappingMacOS::translate_key([event keyCode]); + ke.key_label = KeyMappingMacOS::remap_key([event keyCode], [event modifierFlags], true); + ke.unicode = 0; + ke.raw = true; - ds->push_to_key_event_buffer(ke); - } + ds->push_to_key_event_buffer(ke); } } @@ -739,7 +717,8 @@ } DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); - MouseButton mask = mouse_button_to_mask(button); + MouseButtonMask mask = mouse_button_to_mask(button); + BitField<MouseButtonMask> last_button_state = ds->mouse_get_button_state(); Ref<InputEventMouseButton> sc; sc.instantiate(); @@ -751,7 +730,7 @@ sc->set_pressed(true); sc->set_position(wd.mouse_pos); sc->set_global_position(wd.mouse_pos); - MouseButton last_button_state = ds->mouse_get_button_state() | (MouseButton)mask; + last_button_state.set_flag(mask); sc->set_button_mask(last_button_state); ds->mouse_set_button_state(last_button_state); @@ -764,7 +743,7 @@ sc->set_pressed(false); sc->set_position(wd.mouse_pos); sc->set_global_position(wd.mouse_pos); - last_button_state &= (MouseButton)~mask; + last_button_state.clear_flag(mask); sc->set_button_mask(last_button_state); ds->mouse_set_button_state(last_button_state); diff --git a/platform/macos/godot_main_macos.mm b/platform/macos/godot_main_macos.mm index 66071f1404..58263471b0 100644 --- a/platform/macos/godot_main_macos.mm +++ b/platform/macos/godot_main_macos.mm @@ -1,37 +1,37 @@ -/*************************************************************************/ -/* godot_main_macos.mm */ -/*************************************************************************/ -/* 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 "main/main.h" +/**************************************************************************/ +/* godot_main_macos.mm */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "os_macos.h" +#include "main/main.h" + #include <string.h> #include <unistd.h> @@ -53,21 +53,12 @@ int main(int argc, char **argv) { int first_arg = 1; const char *dbg_arg = "-NSDocumentRevisionsDebugMode"; - printf("arguments\n"); for (int i = 0; i < argc; i++) { if (strcmp(dbg_arg, argv[i]) == 0) { first_arg = i + 2; } - printf("%i: %s\n", i, argv[i]); } -#ifdef DEBUG_ENABLED - // Lets report the path we made current after all that. - char cwd[4096]; - getcwd(cwd, 4096); - printf("Current path: %s\n", cwd); -#endif - OS_MacOS os; Error err; diff --git a/platform/macos/godot_menu_delegate.h b/platform/macos/godot_menu_delegate.h index 805ac0c4a3..c2da3ad09e 100644 --- a/platform/macos/godot_menu_delegate.h +++ b/platform/macos/godot_menu_delegate.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* godot_menu_delegate.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* godot_menu_delegate.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 GODOT_MENU_DELEGATE_H #define GODOT_MENU_DELEGATE_H diff --git a/platform/macos/godot_menu_delegate.mm b/platform/macos/godot_menu_delegate.mm index 376f28d1d0..ebfe8b1f6d 100644 --- a/platform/macos/godot_menu_delegate.mm +++ b/platform/macos/godot_menu_delegate.mm @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* godot_menu_delegate.mm */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* godot_menu_delegate.mm */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "godot_menu_delegate.h" @@ -41,7 +41,7 @@ - (BOOL)menuHasKeyEquivalent:(NSMenu *)menu forEvent:(NSEvent *)event target:(id *)target action:(SEL *)action { NSString *ev_key = [[event charactersIgnoringModifiers] lowercaseString]; - NSUInteger ev_modifiers = [event modifierFlags] & NSDeviceIndependentModifierFlagsMask; + NSUInteger ev_modifiers = [event modifierFlags] & NSEventModifierFlagDeviceIndependentFlagsMask; for (int i = 0; i < [menu numberOfItems]; i++) { const NSMenuItem *menu_item = [menu itemAtIndex:i]; if ([menu_item isEnabled] && [[menu_item keyEquivalent] compare:ev_key] == NSOrderedSame) { diff --git a/platform/macos/godot_menu_item.h b/platform/macos/godot_menu_item.h index e96f5dc1cf..8876ceae6a 100644 --- a/platform/macos/godot_menu_item.h +++ b/platform/macos/godot_menu_item.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* godot_menu_item.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* godot_menu_item.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 GODOT_MENU_ITEM_H #define GODOT_MENU_ITEM_H diff --git a/platform/macos/godot_menu_item.mm b/platform/macos/godot_menu_item.mm index ea35e35d19..30dac9be9b 100644 --- a/platform/macos/godot_menu_item.mm +++ b/platform/macos/godot_menu_item.mm @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* godot_menu_item.mm */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* godot_menu_item.mm */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "godot_menu_item.h" diff --git a/platform/macos/godot_window.h b/platform/macos/godot_window.h index d3653fda82..72aa042069 100644 --- a/platform/macos/godot_window.h +++ b/platform/macos/godot_window.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* godot_window.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* godot_window.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 GODOT_WINDOW_H #define GODOT_WINDOW_H diff --git a/platform/macos/godot_window.mm b/platform/macos/godot_window.mm index bc51da4f72..f4516e5c85 100644 --- a/platform/macos/godot_window.mm +++ b/platform/macos/godot_window.mm @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* godot_window.mm */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* godot_window.mm */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "godot_window.h" @@ -65,7 +65,7 @@ } DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); - return !wd.no_focus && !wd.is_popup; + return !wd.no_focus; } - (BOOL)canBecomeMainWindow { diff --git a/platform/macos/godot_window_delegate.h b/platform/macos/godot_window_delegate.h index 01cc13a016..de80102958 100644 --- a/platform/macos/godot_window_delegate.h +++ b/platform/macos/godot_window_delegate.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* godot_window_delegate.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* godot_window_delegate.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 GODOT_WINDOW_DELEGATE_H #define GODOT_WINDOW_DELEGATE_H @@ -38,8 +38,6 @@ @interface GodotWindowDelegate : NSObject <NSWindowDelegate> { DisplayServer::WindowID window_id; - NSRect old_frame; - NSWindowStyleMask old_style_mask; } - (void)setWindowID:(DisplayServer::WindowID)wid; diff --git a/platform/macos/godot_window_delegate.mm b/platform/macos/godot_window_delegate.mm index 279fd2a359..1c6dbb1981 100644 --- a/platform/macos/godot_window_delegate.mm +++ b/platform/macos/godot_window_delegate.mm @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* godot_window_delegate.mm */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* godot_window_delegate.mm */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "godot_window_delegate.h" @@ -70,24 +70,24 @@ ds->window_destroy(window_id); } -- (NSArray<NSWindow *> *)customWindowsToEnterFullScreenForWindow:(NSWindow *)window { +- (void)windowWillEnterFullScreen:(NSNotification *)notification { DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (!ds || !ds->has_window(window_id)) { - return nullptr; + return; } - old_frame = [window frame]; - old_style_mask = [window styleMask]; - - NSMutableArray<NSWindow *> *windows = [[NSMutableArray alloc] init]; - [windows addObject:window]; - - return windows; + DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); + wd.fs_transition = true; } -- (void)window:(NSWindow *)window startCustomAnimationToEnterFullScreenWithDuration:(NSTimeInterval)duration { - [(GodotWindow *)window setAnimDuration:duration]; - [window setFrame:[[window screen] frame] display:YES animate:YES]; +- (void)windowDidFailToEnterFullScreen:(NSWindow *)window { + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); + if (!ds || !ds->has_window(window_id)) { + return; + } + + DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); + wd.fs_transition = false; } - (void)windowDidEnterFullScreen:(NSNotification *)notification { @@ -98,29 +98,31 @@ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); wd.fullscreen = true; + wd.fs_transition = false; // Reset window size limits. [wd.window_object setContentMinSize:NSMakeSize(0, 0)]; [wd.window_object setContentMaxSize:NSMakeSize(FLT_MAX, FLT_MAX)]; - [(GodotWindow *)wd.window_object setAnimDuration:-1.0f]; // Reset custom window buttons. if ([wd.window_object styleMask] & NSWindowStyleMaskFullSizeContentView) { ds->window_set_custom_window_buttons(wd, false); } - // Force window resize event. - [self windowDidResize:notification]; ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_TITLEBAR_CHANGE); + + // Force window resize event and redraw. + [self windowDidResize:notification]; } -- (NSArray<NSWindow *> *)customWindowsToExitFullScreenForWindow:(NSWindow *)window { +- (void)windowWillExitFullScreen:(NSNotification *)notification { DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (!ds || !ds->has_window(window_id)) { - return nullptr; + return; } DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); + wd.fs_transition = true; // Restore custom window buttons. if ([wd.window_object styleMask] & NSWindowStyleMaskFullSizeContentView) { @@ -128,16 +130,22 @@ } ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_TITLEBAR_CHANGE); - - NSMutableArray<NSWindow *> *windows = [[NSMutableArray alloc] init]; - [windows addObject:wd.window_object]; - return windows; } -- (void)window:(NSWindow *)window startCustomAnimationToExitFullScreenWithDuration:(NSTimeInterval)duration { - [(GodotWindow *)window setAnimDuration:duration]; - [window setStyleMask:old_style_mask]; - [window setFrame:old_frame display:YES animate:YES]; +- (void)windowDidFailToExitFullScreen:(NSWindow *)window { + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); + if (!ds || !ds->has_window(window_id)) { + return; + } + + DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); + wd.fs_transition = false; + + if ([wd.window_object styleMask] & NSWindowStyleMaskFullSizeContentView) { + ds->window_set_custom_window_buttons(wd, false); + } + + ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_TITLEBAR_CHANGE); } - (void)windowDidExitFullScreen:(NSNotification *)notification { @@ -147,9 +155,13 @@ } DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); - wd.fullscreen = false; + if (wd.exclusive_fullscreen) { + [NSApp setPresentationOptions:NSApplicationPresentationDefault]; + } - [(GodotWindow *)wd.window_object setAnimDuration:-1.0f]; + wd.fullscreen = false; + wd.exclusive_fullscreen = false; + wd.fs_transition = false; // Set window size limits. const float scale = ds->screen_get_max_scale(); @@ -172,7 +184,7 @@ [wd.window_object setLevel:NSFloatingWindowLevel]; } - // Force window resize event. + // Force window resize event and redraw. [self windowDidResize:notification]; } @@ -251,6 +263,15 @@ } } +- (void)windowDidChangeScreen:(NSNotification *)notification { + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); + if (!ds || !ds->has_window(window_id)) { + return; + } + + ds->reparent_check(window_id); +} + - (void)windowDidMove:(NSNotification *)notification { DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (!ds || !ds->has_window(window_id)) { @@ -291,6 +312,9 @@ ds->update_mouse_pos(wd, [wd.window_object mouseLocationOutsideOfEventStream]); } + [self windowDidResize:notification]; // Emit resize event, to ensure content is resized if the window was resized while it was hidden. + + wd.focused = true; ds->set_last_focused_window(window_id); ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_FOCUS_IN); } @@ -307,6 +331,7 @@ [(GodotButtonView *)wd.window_button_view displayButtons]; } + wd.focused = false; ds->release_pressed_events(); ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_FOCUS_OUT); } @@ -319,6 +344,7 @@ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); + wd.focused = false; ds->release_pressed_events(); ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_FOCUS_OUT); } @@ -330,9 +356,11 @@ } DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); - - ds->set_last_focused_window(window_id); - ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_FOCUS_IN); + if ([wd.window_object isKeyWindow]) { + wd.focused = true; + ds->set_last_focused_window(window_id); + ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_FOCUS_IN); + } } @end diff --git a/platform/macos/joypad_macos.cpp b/platform/macos/joypad_macos.cpp index 1ddcfec1b5..1fcd636a4b 100644 --- a/platform/macos/joypad_macos.cpp +++ b/platform/macos/joypad_macos.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* joypad_macos.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* joypad_macos.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "joypad_macos.h" @@ -316,7 +316,7 @@ bool JoypadMacOS::configure_joypad(IOHIDDeviceRef p_device_ref, joypad *p_joy) { if (vendor && product_id) { char uid[128]; - sprintf(uid, "%08x%08x%08x%08x", OSSwapHostToBigInt32(3), OSSwapHostToBigInt32(vendor), OSSwapHostToBigInt32(product_id), OSSwapHostToBigInt32(version)); + snprintf(uid, 128, "%08x%08x%08x%08x", OSSwapHostToBigInt32(3), OSSwapHostToBigInt32(vendor), OSSwapHostToBigInt32(product_id), OSSwapHostToBigInt32(version)); input->joy_connection_changed(id, true, name, uid); } else { // Bluetooth device. @@ -402,10 +402,10 @@ bool joypad::check_ff_features() { return false; } -static HatMask process_hat_value(int p_min, int p_max, int p_value, bool p_offset_hat) { +static BitField<HatMask> process_hat_value(int p_min, int p_max, int p_value, bool p_offset_hat) { int range = (p_max - p_min + 1); int value = p_value - p_min; - HatMask hat_value = HatMask::CENTER; + BitField<HatMask> hat_value; if (range == 4) { value *= 2; } @@ -415,31 +415,34 @@ static HatMask process_hat_value(int p_min, int p_max, int p_value, bool p_offse switch (value) { case 0: - hat_value = HatMask::UP; + hat_value.set_flag(HatMask::UP); break; case 1: - hat_value = (HatMask::UP | HatMask::RIGHT); + hat_value.set_flag(HatMask::UP); + hat_value.set_flag(HatMask::RIGHT); break; case 2: - hat_value = HatMask::RIGHT; + hat_value.set_flag(HatMask::RIGHT); break; case 3: - hat_value = (HatMask::DOWN | HatMask::RIGHT); + hat_value.set_flag(HatMask::DOWN); + hat_value.set_flag(HatMask::RIGHT); break; case 4: - hat_value = HatMask::DOWN; + hat_value.set_flag(HatMask::DOWN); break; case 5: - hat_value = (HatMask::DOWN | HatMask::LEFT); + hat_value.set_flag(HatMask::DOWN); + hat_value.set_flag(HatMask::LEFT); break; case 6: - hat_value = HatMask::LEFT; + hat_value.set_flag(HatMask::LEFT); break; case 7: - hat_value = (HatMask::UP | HatMask::LEFT); + hat_value.set_flag(HatMask::UP); + hat_value.set_flag(HatMask::LEFT); break; default: - hat_value = HatMask::CENTER; break; } return hat_value; @@ -474,7 +477,7 @@ void JoypadMacOS::process_joypads() { for (int j = 0; j < joy.hat_elements.size(); j++) { rec_element &elem = joy.hat_elements.write[j]; int value = joy.get_hid_element_state(&elem); - HatMask hat_value = process_hat_value(elem.min, elem.max, value, joy.offset_hat); + BitField<HatMask> hat_value = process_hat_value(elem.min, elem.max, value, joy.offset_hat); input->joy_hat(joy.id, hat_value); } diff --git a/platform/macos/joypad_macos.h b/platform/macos/joypad_macos.h index 8743fc91a9..6a2af11b51 100644 --- a/platform/macos/joypad_macos.h +++ b/platform/macos/joypad_macos.h @@ -1,43 +1,43 @@ -/*************************************************************************/ -/* joypad_macos.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* joypad_macos.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 JOYPAD_MACOS_H #define JOYPAD_MACOS_H +#include "core/input/input.h" + #import <ForceFeedback/ForceFeedback.h> #import <ForceFeedback/ForceFeedbackConstants.h> #import <IOKit/hid/IOHIDLib.h> #import <Kernel/IOKit/hidsystem/IOHIDUsageTables.h> -#include "core/input/input.h" - struct rec_element { IOHIDElementRef ref; IOHIDElementCookie cookie; diff --git a/platform/macos/key_mapping_macos.h b/platform/macos/key_mapping_macos.h index fc5b791e44..1bda4eb406 100644 --- a/platform/macos/key_mapping_macos.h +++ b/platform/macos/key_mapping_macos.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* key_mapping_macos.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* key_mapping_macos.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 KEY_MAPPING_MACOS_H #define KEY_MAPPING_MACOS_H @@ -36,13 +36,15 @@ class KeyMappingMacOS { KeyMappingMacOS() {} - static bool is_numpad_key(unsigned int key); + static bool is_numpad_key(unsigned int p_key); public: + static void initialize(); + // Mappings input. - static Key translate_key(unsigned int key); - static unsigned int unmap_key(Key key); - static Key remap_key(unsigned int key, unsigned int state); + static Key translate_key(unsigned int p_key); + static unsigned int unmap_key(Key p_key); + static Key remap_key(unsigned int p_key, unsigned int p_state, bool p_unicode); // Mapping for menu shortcuts. static String keycode_get_native_string(Key p_keycode); diff --git a/platform/macos/key_mapping_macos.mm b/platform/macos/key_mapping_macos.mm index f6cff7124b..db3fa4e02d 100644 --- a/platform/macos/key_mapping_macos.mm +++ b/platform/macos/key_mapping_macos.mm @@ -1,309 +1,377 @@ -/*************************************************************************/ -/* key_mapping_macos.mm */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* key_mapping_macos.mm */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "key_mapping_macos.h" +#include "core/templates/hash_map.h" +#include "core/templates/hash_set.h" + #import <Carbon/Carbon.h> #import <Cocoa/Cocoa.h> -bool KeyMappingMacOS::is_numpad_key(unsigned int key) { - static const unsigned int table[] = { - 0x41, /* kVK_ANSI_KeypadDecimal */ - 0x43, /* kVK_ANSI_KeypadMultiply */ - 0x45, /* kVK_ANSI_KeypadPlus */ - 0x47, /* kVK_ANSI_KeypadClear */ - 0x4b, /* kVK_ANSI_KeypadDivide */ - 0x4c, /* kVK_ANSI_KeypadEnter */ - 0x4e, /* kVK_ANSI_KeypadMinus */ - 0x51, /* kVK_ANSI_KeypadEquals */ - 0x52, /* kVK_ANSI_Keypad0 */ - 0x53, /* kVK_ANSI_Keypad1 */ - 0x54, /* kVK_ANSI_Keypad2 */ - 0x55, /* kVK_ANSI_Keypad3 */ - 0x56, /* kVK_ANSI_Keypad4 */ - 0x57, /* kVK_ANSI_Keypad5 */ - 0x58, /* kVK_ANSI_Keypad6 */ - 0x59, /* kVK_ANSI_Keypad7 */ - 0x5b, /* kVK_ANSI_Keypad8 */ - 0x5c, /* kVK_ANSI_Keypad9 */ - 0x5f, /* kVK_JIS_KeypadComma */ - 0x00 - }; - for (int i = 0; table[i] != 0; i++) { - if (key == table[i]) { - return true; - } +struct HashMapHasherKeys { + static _FORCE_INLINE_ uint32_t hash(const Key p_key) { return hash_fmix32(static_cast<uint32_t>(p_key)); } + static _FORCE_INLINE_ uint32_t hash(const char32_t p_uchar) { return hash_fmix32(p_uchar); } + static _FORCE_INLINE_ uint32_t hash(const unsigned p_key) { return hash_fmix32(p_key); } +}; + +HashSet<unsigned int> numpad_keys; +HashMap<unsigned int, Key, HashMapHasherKeys> keysym_map; +HashMap<Key, unsigned int, HashMapHasherKeys> keysym_map_inv; +HashMap<Key, char32_t, HashMapHasherKeys> keycode_map; + +void KeyMappingMacOS::initialize() { + numpad_keys.insert(0x41); //kVK_ANSI_KeypadDecimal + numpad_keys.insert(0x43); //kVK_ANSI_KeypadMultiply + numpad_keys.insert(0x45); //kVK_ANSI_KeypadPlus + numpad_keys.insert(0x47); //kVK_ANSI_KeypadClear + numpad_keys.insert(0x4b); //kVK_ANSI_KeypadDivide + numpad_keys.insert(0x4c); //kVK_ANSI_KeypadEnter + numpad_keys.insert(0x4e); //kVK_ANSI_KeypadMinus + numpad_keys.insert(0x51); //kVK_ANSI_KeypadEquals + numpad_keys.insert(0x52); //kVK_ANSI_Keypad0 + numpad_keys.insert(0x53); //kVK_ANSI_Keypad1 + numpad_keys.insert(0x54); //kVK_ANSI_Keypad2 + numpad_keys.insert(0x55); //kVK_ANSI_Keypad3 + numpad_keys.insert(0x56); //kVK_ANSI_Keypad4 + numpad_keys.insert(0x57); //kVK_ANSI_Keypad5 + numpad_keys.insert(0x58); //kVK_ANSI_Keypad6 + numpad_keys.insert(0x59); //kVK_ANSI_Keypad7 + numpad_keys.insert(0x5b); //kVK_ANSI_Keypad8 + numpad_keys.insert(0x5c); //kVK_ANSI_Keypad9 + numpad_keys.insert(0x5f); //kVK_JIS_KeypadComma + + keysym_map[0x00] = Key::A; + keysym_map[0x01] = Key::S; + keysym_map[0x02] = Key::D; + keysym_map[0x03] = Key::F; + keysym_map[0x04] = Key::H; + keysym_map[0x05] = Key::G; + keysym_map[0x06] = Key::Z; + keysym_map[0x07] = Key::X; + keysym_map[0x08] = Key::C; + keysym_map[0x09] = Key::V; + keysym_map[0x0a] = Key::SECTION; + keysym_map[0x0b] = Key::B; + keysym_map[0x0c] = Key::Q; + keysym_map[0x0d] = Key::W; + keysym_map[0x0e] = Key::E; + keysym_map[0x0f] = Key::R; + keysym_map[0x10] = Key::Y; + keysym_map[0x11] = Key::T; + keysym_map[0x12] = Key::KEY_1; + keysym_map[0x13] = Key::KEY_2; + keysym_map[0x14] = Key::KEY_3; + keysym_map[0x15] = Key::KEY_4; + keysym_map[0x16] = Key::KEY_6; + keysym_map[0x17] = Key::KEY_5; + keysym_map[0x18] = Key::EQUAL; + keysym_map[0x19] = Key::KEY_9; + keysym_map[0x1a] = Key::KEY_7; + keysym_map[0x1b] = Key::MINUS; + keysym_map[0x1c] = Key::KEY_8; + keysym_map[0x1d] = Key::KEY_0; + keysym_map[0x1e] = Key::BRACKETRIGHT; + keysym_map[0x1f] = Key::O; + keysym_map[0x20] = Key::U; + keysym_map[0x21] = Key::BRACKETLEFT; + keysym_map[0x22] = Key::I; + keysym_map[0x23] = Key::P; + keysym_map[0x24] = Key::ENTER; + keysym_map[0x25] = Key::L; + keysym_map[0x26] = Key::J; + keysym_map[0x27] = Key::APOSTROPHE; + keysym_map[0x28] = Key::K; + keysym_map[0x29] = Key::SEMICOLON; + keysym_map[0x2a] = Key::BACKSLASH; + keysym_map[0x2b] = Key::COMMA; + keysym_map[0x2c] = Key::SLASH; + keysym_map[0x2d] = Key::N; + keysym_map[0x2e] = Key::M; + keysym_map[0x2f] = Key::PERIOD; + keysym_map[0x30] = Key::TAB; + keysym_map[0x31] = Key::SPACE; + keysym_map[0x32] = Key::QUOTELEFT; + keysym_map[0x33] = Key::BACKSPACE; + keysym_map[0x35] = Key::ESCAPE; + keysym_map[0x36] = Key::META; + keysym_map[0x37] = Key::META; + keysym_map[0x38] = Key::SHIFT; + keysym_map[0x39] = Key::CAPSLOCK; + keysym_map[0x3a] = Key::ALT; + keysym_map[0x3b] = Key::CTRL; + keysym_map[0x3c] = Key::SHIFT; + keysym_map[0x3d] = Key::ALT; + keysym_map[0x3e] = Key::CTRL; + keysym_map[0x40] = Key::F17; + keysym_map[0x41] = Key::KP_PERIOD; + keysym_map[0x43] = Key::KP_MULTIPLY; + keysym_map[0x45] = Key::KP_ADD; + keysym_map[0x47] = Key::NUMLOCK; + keysym_map[0x48] = Key::VOLUMEUP; + keysym_map[0x49] = Key::VOLUMEDOWN; + keysym_map[0x4a] = Key::VOLUMEMUTE; + keysym_map[0x4b] = Key::KP_DIVIDE; + keysym_map[0x4c] = Key::KP_ENTER; + keysym_map[0x4e] = Key::KP_SUBTRACT; + keysym_map[0x4f] = Key::F18; + keysym_map[0x50] = Key::F19; + keysym_map[0x51] = Key::EQUAL; + keysym_map[0x52] = Key::KP_0; + keysym_map[0x53] = Key::KP_1; + keysym_map[0x54] = Key::KP_2; + keysym_map[0x55] = Key::KP_3; + keysym_map[0x56] = Key::KP_4; + keysym_map[0x57] = Key::KP_5; + keysym_map[0x58] = Key::KP_6; + keysym_map[0x59] = Key::KP_7; + keysym_map[0x5a] = Key::F20; + keysym_map[0x5b] = Key::KP_8; + keysym_map[0x5c] = Key::KP_9; + keysym_map[0x5d] = Key::YEN; + keysym_map[0x5e] = Key::UNDERSCORE; + keysym_map[0x5f] = Key::COMMA; + keysym_map[0x60] = Key::F5; + keysym_map[0x61] = Key::F6; + keysym_map[0x62] = Key::F7; + keysym_map[0x63] = Key::F3; + keysym_map[0x64] = Key::F8; + keysym_map[0x65] = Key::F9; + keysym_map[0x66] = Key::JIS_EISU; + keysym_map[0x67] = Key::F11; + keysym_map[0x68] = Key::JIS_KANA; + keysym_map[0x69] = Key::F13; + keysym_map[0x6a] = Key::F16; + keysym_map[0x6b] = Key::F14; + keysym_map[0x6d] = Key::F10; + keysym_map[0x6e] = Key::MENU; + keysym_map[0x6f] = Key::F12; + keysym_map[0x71] = Key::F15; + keysym_map[0x72] = Key::INSERT; + keysym_map[0x73] = Key::HOME; + keysym_map[0x74] = Key::PAGEUP; + keysym_map[0x75] = Key::KEY_DELETE; + keysym_map[0x76] = Key::F4; + keysym_map[0x77] = Key::END; + keysym_map[0x78] = Key::F2; + keysym_map[0x79] = Key::PAGEDOWN; + keysym_map[0x7a] = Key::F1; + keysym_map[0x7b] = Key::LEFT; + keysym_map[0x7c] = Key::RIGHT; + keysym_map[0x7d] = Key::DOWN; + keysym_map[0x7e] = Key::UP; + + for (const KeyValue<unsigned int, Key> &E : keysym_map) { + keysym_map_inv[E.value] = E.key; } - return false; + + keycode_map[Key::ESCAPE] = 0x001B; + keycode_map[Key::TAB] = 0x0009; + keycode_map[Key::BACKTAB] = 0x007F; + keycode_map[Key::BACKSPACE] = 0x0008; + keycode_map[Key::ENTER] = 0x000D; + keycode_map[Key::INSERT] = NSInsertFunctionKey; + keycode_map[Key::KEY_DELETE] = 0x007F; + keycode_map[Key::PAUSE] = NSPauseFunctionKey; + keycode_map[Key::PRINT] = NSPrintScreenFunctionKey; + keycode_map[Key::SYSREQ] = NSSysReqFunctionKey; + keycode_map[Key::CLEAR] = NSClearLineFunctionKey; + keycode_map[Key::HOME] = 0x2196; + keycode_map[Key::END] = 0x2198; + keycode_map[Key::LEFT] = 0x001C; + keycode_map[Key::UP] = 0x001E; + keycode_map[Key::RIGHT] = 0x001D; + keycode_map[Key::DOWN] = 0x001F; + keycode_map[Key::PAGEUP] = 0x21DE; + keycode_map[Key::PAGEDOWN] = 0x21DF; + keycode_map[Key::NUMLOCK] = NSClearLineFunctionKey; + keycode_map[Key::SCROLLLOCK] = NSScrollLockFunctionKey; + keycode_map[Key::F1] = NSF1FunctionKey; + keycode_map[Key::F2] = NSF2FunctionKey; + keycode_map[Key::F3] = NSF3FunctionKey; + keycode_map[Key::F4] = NSF4FunctionKey; + keycode_map[Key::F5] = NSF5FunctionKey; + keycode_map[Key::F6] = NSF6FunctionKey; + keycode_map[Key::F7] = NSF7FunctionKey; + keycode_map[Key::F8] = NSF8FunctionKey; + keycode_map[Key::F9] = NSF9FunctionKey; + keycode_map[Key::F10] = NSF10FunctionKey; + keycode_map[Key::F11] = NSF11FunctionKey; + keycode_map[Key::F12] = NSF12FunctionKey; + keycode_map[Key::F13] = NSF13FunctionKey; + keycode_map[Key::F14] = NSF14FunctionKey; + keycode_map[Key::F15] = NSF15FunctionKey; + keycode_map[Key::F16] = NSF16FunctionKey; + keycode_map[Key::F17] = NSF17FunctionKey; + keycode_map[Key::F18] = NSF18FunctionKey; + keycode_map[Key::F19] = NSF19FunctionKey; + keycode_map[Key::F20] = NSF20FunctionKey; + keycode_map[Key::F21] = NSF21FunctionKey; + keycode_map[Key::F22] = NSF22FunctionKey; + keycode_map[Key::F23] = NSF23FunctionKey; + keycode_map[Key::F24] = NSF24FunctionKey; + keycode_map[Key::F25] = NSF25FunctionKey; + keycode_map[Key::F26] = NSF26FunctionKey; + keycode_map[Key::F27] = NSF27FunctionKey; + keycode_map[Key::F28] = NSF28FunctionKey; + keycode_map[Key::F29] = NSF29FunctionKey; + keycode_map[Key::F30] = NSF30FunctionKey; + keycode_map[Key::F31] = NSF31FunctionKey; + keycode_map[Key::F32] = NSF32FunctionKey; + keycode_map[Key::F33] = NSF33FunctionKey; + keycode_map[Key::F34] = NSF34FunctionKey; + keycode_map[Key::F35] = NSF35FunctionKey; + keycode_map[Key::MENU] = NSMenuFunctionKey; + keycode_map[Key::HELP] = NSHelpFunctionKey; + keycode_map[Key::STOP] = NSStopFunctionKey; + keycode_map[Key::LAUNCH0] = NSUserFunctionKey; + keycode_map[Key::SPACE] = 0x0020; + keycode_map[Key::EXCLAM] = '!'; + keycode_map[Key::QUOTEDBL] = '\"'; + keycode_map[Key::NUMBERSIGN] = '#'; + keycode_map[Key::DOLLAR] = '$'; + keycode_map[Key::PERCENT] = '\%'; + keycode_map[Key::AMPERSAND] = '&'; + keycode_map[Key::APOSTROPHE] = '\''; + keycode_map[Key::PARENLEFT] = '('; + keycode_map[Key::PARENRIGHT] = ')'; + keycode_map[Key::ASTERISK] = '*'; + keycode_map[Key::PLUS] = '+'; + keycode_map[Key::COMMA] = ','; + keycode_map[Key::MINUS] = '-'; + keycode_map[Key::PERIOD] = '.'; + keycode_map[Key::SLASH] = '/'; + keycode_map[Key::KEY_0] = '0'; + keycode_map[Key::KEY_1] = '1'; + keycode_map[Key::KEY_2] = '2'; + keycode_map[Key::KEY_3] = '3'; + keycode_map[Key::KEY_4] = '4'; + keycode_map[Key::KEY_5] = '5'; + keycode_map[Key::KEY_6] = '6'; + keycode_map[Key::KEY_7] = '7'; + keycode_map[Key::KEY_8] = '8'; + keycode_map[Key::KEY_9] = '9'; + keycode_map[Key::COLON] = ':'; + keycode_map[Key::SEMICOLON] = ';'; + keycode_map[Key::LESS] = '<'; + keycode_map[Key::EQUAL] = '='; + keycode_map[Key::GREATER] = '>'; + keycode_map[Key::QUESTION] = '?'; + keycode_map[Key::AT] = '@'; + keycode_map[Key::A] = 'a'; + keycode_map[Key::B] = 'b'; + keycode_map[Key::C] = 'c'; + keycode_map[Key::D] = 'd'; + keycode_map[Key::E] = 'e'; + keycode_map[Key::F] = 'f'; + keycode_map[Key::G] = 'g'; + keycode_map[Key::H] = 'h'; + keycode_map[Key::I] = 'i'; + keycode_map[Key::J] = 'j'; + keycode_map[Key::K] = 'k'; + keycode_map[Key::L] = 'l'; + keycode_map[Key::M] = 'm'; + keycode_map[Key::N] = 'n'; + keycode_map[Key::O] = 'o'; + keycode_map[Key::P] = 'p'; + keycode_map[Key::Q] = 'q'; + keycode_map[Key::R] = 'r'; + keycode_map[Key::S] = 's'; + keycode_map[Key::T] = 't'; + keycode_map[Key::U] = 'u'; + keycode_map[Key::V] = 'v'; + keycode_map[Key::W] = 'w'; + keycode_map[Key::X] = 'x'; + keycode_map[Key::Y] = 'y'; + keycode_map[Key::Z] = 'z'; + keycode_map[Key::BRACKETLEFT] = '['; + keycode_map[Key::BACKSLASH] = '\\'; + keycode_map[Key::BRACKETRIGHT] = ']'; + keycode_map[Key::ASCIICIRCUM] = '^'; + keycode_map[Key::UNDERSCORE] = '_'; + keycode_map[Key::QUOTELEFT] = '`'; + keycode_map[Key::BRACELEFT] = '{'; + keycode_map[Key::BAR] = '|'; + keycode_map[Key::BRACERIGHT] = '}'; + keycode_map[Key::ASCIITILDE] = '~'; } -// Keyboard symbol translation table. -static const Key _macos_to_godot_table[128] = { - /* 00 */ Key::A, - /* 01 */ Key::S, - /* 02 */ Key::D, - /* 03 */ Key::F, - /* 04 */ Key::H, - /* 05 */ Key::G, - /* 06 */ Key::Z, - /* 07 */ Key::X, - /* 08 */ Key::C, - /* 09 */ Key::V, - /* 0a */ Key::SECTION, /* ISO Section */ - /* 0b */ Key::B, - /* 0c */ Key::Q, - /* 0d */ Key::W, - /* 0e */ Key::E, - /* 0f */ Key::R, - /* 10 */ Key::Y, - /* 11 */ Key::T, - /* 12 */ Key::KEY_1, - /* 13 */ Key::KEY_2, - /* 14 */ Key::KEY_3, - /* 15 */ Key::KEY_4, - /* 16 */ Key::KEY_6, - /* 17 */ Key::KEY_5, - /* 18 */ Key::EQUAL, - /* 19 */ Key::KEY_9, - /* 1a */ Key::KEY_7, - /* 1b */ Key::MINUS, - /* 1c */ Key::KEY_8, - /* 1d */ Key::KEY_0, - /* 1e */ Key::BRACERIGHT, - /* 1f */ Key::O, - /* 20 */ Key::U, - /* 21 */ Key::BRACELEFT, - /* 22 */ Key::I, - /* 23 */ Key::P, - /* 24 */ Key::ENTER, - /* 25 */ Key::L, - /* 26 */ Key::J, - /* 27 */ Key::APOSTROPHE, - /* 28 */ Key::K, - /* 29 */ Key::SEMICOLON, - /* 2a */ Key::BACKSLASH, - /* 2b */ Key::COMMA, - /* 2c */ Key::SLASH, - /* 2d */ Key::N, - /* 2e */ Key::M, - /* 2f */ Key::PERIOD, - /* 30 */ Key::TAB, - /* 31 */ Key::SPACE, - /* 32 */ Key::QUOTELEFT, - /* 33 */ Key::BACKSPACE, - /* 34 */ Key::UNKNOWN, - /* 35 */ Key::ESCAPE, - /* 36 */ Key::META, - /* 37 */ Key::META, - /* 38 */ Key::SHIFT, - /* 39 */ Key::CAPSLOCK, - /* 3a */ Key::ALT, - /* 3b */ Key::CTRL, - /* 3c */ Key::SHIFT, - /* 3d */ Key::ALT, - /* 3e */ Key::CTRL, - /* 3f */ Key::UNKNOWN, /* Function */ - /* 40 */ Key::F17, - /* 41 */ Key::KP_PERIOD, - /* 42 */ Key::UNKNOWN, - /* 43 */ Key::KP_MULTIPLY, - /* 44 */ Key::UNKNOWN, - /* 45 */ Key::KP_ADD, - /* 46 */ Key::UNKNOWN, - /* 47 */ Key::NUMLOCK, /* Really KeypadClear... */ - /* 48 */ Key::VOLUMEUP, /* VolumeUp */ - /* 49 */ Key::VOLUMEDOWN, /* VolumeDown */ - /* 4a */ Key::VOLUMEMUTE, /* Mute */ - /* 4b */ Key::KP_DIVIDE, - /* 4c */ Key::KP_ENTER, - /* 4d */ Key::UNKNOWN, - /* 4e */ Key::KP_SUBTRACT, - /* 4f */ Key::F18, - /* 50 */ Key::F19, - /* 51 */ Key::EQUAL, /* KeypadEqual */ - /* 52 */ Key::KP_0, - /* 53 */ Key::KP_1, - /* 54 */ Key::KP_2, - /* 55 */ Key::KP_3, - /* 56 */ Key::KP_4, - /* 57 */ Key::KP_5, - /* 58 */ Key::KP_6, - /* 59 */ Key::KP_7, - /* 5a */ Key::F20, - /* 5b */ Key::KP_8, - /* 5c */ Key::KP_9, - /* 5d */ Key::YEN, /* JIS Yen */ - /* 5e */ Key::UNDERSCORE, /* JIS Underscore */ - /* 5f */ Key::COMMA, /* JIS KeypadComma */ - /* 60 */ Key::F5, - /* 61 */ Key::F6, - /* 62 */ Key::F7, - /* 63 */ Key::F3, - /* 64 */ Key::F8, - /* 65 */ Key::F9, - /* 66 */ Key::UNKNOWN, /* JIS Eisu */ - /* 67 */ Key::F11, - /* 68 */ Key::UNKNOWN, /* JIS Kana */ - /* 69 */ Key::F13, - /* 6a */ Key::F16, - /* 6b */ Key::F14, - /* 6c */ Key::UNKNOWN, - /* 6d */ Key::F10, - /* 6e */ Key::MENU, - /* 6f */ Key::F12, - /* 70 */ Key::UNKNOWN, - /* 71 */ Key::F15, - /* 72 */ Key::INSERT, /* Really Help... */ - /* 73 */ Key::HOME, - /* 74 */ Key::PAGEUP, - /* 75 */ Key::KEY_DELETE, - /* 76 */ Key::F4, - /* 77 */ Key::END, - /* 78 */ Key::F2, - /* 79 */ Key::PAGEDOWN, - /* 7a */ Key::F1, - /* 7b */ Key::LEFT, - /* 7c */ Key::RIGHT, - /* 7d */ Key::DOWN, - /* 7e */ Key::UP, - /* 7f */ Key::UNKNOWN, -}; +bool KeyMappingMacOS::is_numpad_key(unsigned int p_key) { + return numpad_keys.has(p_key); +} -// Translates a OS X keycode to a Godot keycode. -Key KeyMappingMacOS::translate_key(unsigned int key) { - if (key >= 128) { - return Key::UNKNOWN; +// Translates a macOS keycode to a Godot keycode. +Key KeyMappingMacOS::translate_key(unsigned int p_key) { + const Key *key = keysym_map.getptr(p_key); + if (key) { + return *key; } - - return _macos_to_godot_table[key]; + return Key::NONE; } // Translates a Godot keycode back to a macOS keycode. -unsigned int KeyMappingMacOS::unmap_key(Key key) { - for (int i = 0; i <= 126; i++) { - if (_macos_to_godot_table[i] == key) { - return i; - } +unsigned int KeyMappingMacOS::unmap_key(Key p_key) { + const unsigned int *key = keysym_map_inv.getptr(p_key); + if (key) { + return *key; } return 127; } -struct _KeyCodeMap { - UniChar kchar; - Key kcode; -}; - -static const _KeyCodeMap _keycodes[55] = { - { '`', Key::QUOTELEFT }, - { '~', Key::ASCIITILDE }, - { '0', Key::KEY_0 }, - { '1', Key::KEY_1 }, - { '2', Key::KEY_2 }, - { '3', Key::KEY_3 }, - { '4', Key::KEY_4 }, - { '5', Key::KEY_5 }, - { '6', Key::KEY_6 }, - { '7', Key::KEY_7 }, - { '8', Key::KEY_8 }, - { '9', Key::KEY_9 }, - { '-', Key::MINUS }, - { '_', Key::UNDERSCORE }, - { '=', Key::EQUAL }, - { '+', Key::PLUS }, - { 'q', Key::Q }, - { 'w', Key::W }, - { 'e', Key::E }, - { 'r', Key::R }, - { 't', Key::T }, - { 'y', Key::Y }, - { 'u', Key::U }, - { 'i', Key::I }, - { 'o', Key::O }, - { 'p', Key::P }, - { '[', Key::BRACELEFT }, - { ']', Key::BRACERIGHT }, - { '{', Key::BRACELEFT }, - { '}', Key::BRACERIGHT }, - { 'a', Key::A }, - { 's', Key::S }, - { 'd', Key::D }, - { 'f', Key::F }, - { 'g', Key::G }, - { 'h', Key::H }, - { 'j', Key::J }, - { 'k', Key::K }, - { 'l', Key::L }, - { ';', Key::SEMICOLON }, - { ':', Key::COLON }, - { '\'', Key::APOSTROPHE }, - { '\"', Key::QUOTEDBL }, - { '\\', Key::BACKSLASH }, - { '#', Key::NUMBERSIGN }, - { 'z', Key::Z }, - { 'x', Key::X }, - { 'c', Key::C }, - { 'v', Key::V }, - { 'b', Key::B }, - { 'n', Key::N }, - { 'm', Key::M }, - { ',', Key::COMMA }, - { '.', Key::PERIOD }, - { '/', Key::SLASH } -}; - // Remap key according to current keyboard layout. -Key KeyMappingMacOS::remap_key(unsigned int key, unsigned int state) { - if (is_numpad_key(key)) { - return translate_key(key); +Key KeyMappingMacOS::remap_key(unsigned int p_key, unsigned int p_state, bool p_unicode) { + if (is_numpad_key(p_key)) { + return translate_key(p_key); } TISInputSourceRef current_keyboard = TISCopyCurrentKeyboardInputSource(); if (!current_keyboard) { - return translate_key(key); + return translate_key(p_key); } CFDataRef layout_data = (CFDataRef)TISGetInputSourceProperty(current_keyboard, kTISPropertyUnicodeKeyLayoutData); if (!layout_data) { - return translate_key(key); + return translate_key(p_key); } const UCKeyboardLayout *keyboard_layout = (const UCKeyboardLayout *)CFDataGetBytePtr(layout_data); + String keysym; UInt32 keys_down = 0; - UniChar chars[4]; - UniCharCount real_length; + UniChar chars[256] = {}; + UniCharCount real_length = 0; OSStatus err = UCKeyTranslate(keyboard_layout, - key, + p_key, kUCKeyActionDisplay, - (state >> 8) & 0xFF, + (p_unicode) ? 0 : (p_state >> 8) & 0xFF, LMGetKbdType(), kUCKeyTranslateNoDeadKeysBit, &keys_down, @@ -312,165 +380,26 @@ Key KeyMappingMacOS::remap_key(unsigned int key, unsigned int state) { chars); if (err != noErr) { - return translate_key(key); + return translate_key(p_key); } - for (unsigned int i = 0; i < 55; i++) { - if (_keycodes[i].kchar == chars[0]) { - return _keycodes[i].kcode; - } + keysym = String::utf16((char16_t *)chars, real_length); + if (keysym.is_empty()) { + return translate_key(p_key); } - return translate_key(key); -} - -struct _KeyCodeText { - Key code; - char32_t text; -}; -static const _KeyCodeText _native_keycodes[] = { - /* clang-format off */ - {Key::ESCAPE ,0x001B}, - {Key::TAB ,0x0009}, - {Key::BACKTAB ,0x007F}, - {Key::BACKSPACE ,0x0008}, - {Key::ENTER ,0x000D}, - {Key::INSERT ,NSInsertFunctionKey}, - {Key::KEY_DELETE ,0x007F}, - {Key::PAUSE ,NSPauseFunctionKey}, - {Key::PRINT ,NSPrintScreenFunctionKey}, - {Key::SYSREQ ,NSSysReqFunctionKey}, - {Key::CLEAR ,NSClearLineFunctionKey}, - {Key::HOME ,0x2196}, - {Key::END ,0x2198}, - {Key::LEFT ,0x001C}, - {Key::UP ,0x001E}, - {Key::RIGHT ,0x001D}, - {Key::DOWN ,0x001F}, - {Key::PAGEUP ,0x21DE}, - {Key::PAGEDOWN ,0x21DF}, - {Key::NUMLOCK ,NSClearLineFunctionKey}, - {Key::SCROLLLOCK ,NSScrollLockFunctionKey}, - {Key::F1 ,NSF1FunctionKey}, - {Key::F2 ,NSF2FunctionKey}, - {Key::F3 ,NSF3FunctionKey}, - {Key::F4 ,NSF4FunctionKey}, - {Key::F5 ,NSF5FunctionKey}, - {Key::F6 ,NSF6FunctionKey}, - {Key::F7 ,NSF7FunctionKey}, - {Key::F8 ,NSF8FunctionKey}, - {Key::F9 ,NSF9FunctionKey}, - {Key::F10 ,NSF10FunctionKey}, - {Key::F11 ,NSF11FunctionKey}, - {Key::F12 ,NSF12FunctionKey}, - {Key::F13 ,NSF13FunctionKey}, - {Key::F14 ,NSF14FunctionKey}, - {Key::F15 ,NSF15FunctionKey}, - {Key::F16 ,NSF16FunctionKey}, - {Key::F17 ,NSF17FunctionKey}, - {Key::F18 ,NSF18FunctionKey}, - {Key::F19 ,NSF19FunctionKey}, - {Key::F20 ,NSF20FunctionKey}, - {Key::F21 ,NSF21FunctionKey}, - {Key::F22 ,NSF22FunctionKey}, - {Key::F23 ,NSF23FunctionKey}, - {Key::F24 ,NSF24FunctionKey}, - {Key::F25 ,NSF25FunctionKey}, - {Key::F26 ,NSF26FunctionKey}, - {Key::F27 ,NSF27FunctionKey}, - {Key::F28 ,NSF28FunctionKey}, - {Key::F29 ,NSF29FunctionKey}, - {Key::F30 ,NSF30FunctionKey}, - {Key::F31 ,NSF31FunctionKey}, - {Key::F32 ,NSF32FunctionKey}, - {Key::F33 ,NSF33FunctionKey}, - {Key::F34 ,NSF34FunctionKey}, - {Key::F35 ,NSF35FunctionKey}, - {Key::MENU ,NSMenuFunctionKey}, - {Key::HELP ,NSHelpFunctionKey}, - {Key::STOP ,NSStopFunctionKey}, - {Key::LAUNCH0 ,NSUserFunctionKey}, - {Key::SPACE ,0x0020}, - {Key::EXCLAM ,'!'}, - {Key::QUOTEDBL ,'\"'}, - {Key::NUMBERSIGN ,'#'}, - {Key::DOLLAR ,'$'}, - {Key::PERCENT ,'\%'}, - {Key::AMPERSAND ,'&'}, - {Key::APOSTROPHE ,'\''}, - {Key::PARENLEFT ,'('}, - {Key::PARENRIGHT ,')'}, - {Key::ASTERISK ,'*'}, - {Key::PLUS ,'+'}, - {Key::COMMA ,','}, - {Key::MINUS ,'-'}, - {Key::PERIOD ,'.'}, - {Key::SLASH ,'/'}, - {Key::KEY_0 ,'0'}, - {Key::KEY_1 ,'1'}, - {Key::KEY_2 ,'2'}, - {Key::KEY_3 ,'3'}, - {Key::KEY_4 ,'4'}, - {Key::KEY_5 ,'5'}, - {Key::KEY_6 ,'6'}, - {Key::KEY_7 ,'7'}, - {Key::KEY_8 ,'8'}, - {Key::KEY_9 ,'9'}, - {Key::COLON ,':'}, - {Key::SEMICOLON ,';'}, - {Key::LESS ,'<'}, - {Key::EQUAL ,'='}, - {Key::GREATER ,'>'}, - {Key::QUESTION ,'?'}, - {Key::AT ,'@'}, - {Key::A ,'a'}, - {Key::B ,'b'}, - {Key::C ,'c'}, - {Key::D ,'d'}, - {Key::E ,'e'}, - {Key::F ,'f'}, - {Key::G ,'g'}, - {Key::H ,'h'}, - {Key::I ,'i'}, - {Key::J ,'j'}, - {Key::K ,'k'}, - {Key::L ,'l'}, - {Key::M ,'m'}, - {Key::N ,'n'}, - {Key::O ,'o'}, - {Key::P ,'p'}, - {Key::Q ,'q'}, - {Key::R ,'r'}, - {Key::S ,'s'}, - {Key::T ,'t'}, - {Key::U ,'u'}, - {Key::V ,'v'}, - {Key::W ,'w'}, - {Key::X ,'x'}, - {Key::Y ,'y'}, - {Key::Z ,'z'}, - {Key::BRACKETLEFT ,'['}, - {Key::BACKSLASH ,'\\'}, - {Key::BRACKETRIGHT ,']'}, - {Key::ASCIICIRCUM ,'^'}, - {Key::UNDERSCORE ,'_'}, - {Key::QUOTELEFT ,'`'}, - {Key::BRACELEFT ,'{'}, - {Key::BAR ,'|'}, - {Key::BRACERIGHT ,'}'}, - {Key::ASCIITILDE ,'~'}, - {Key::NONE ,0x0000} - /* clang-format on */ -}; + char32_t c = keysym[0]; + if (p_unicode) { + return fix_key_label(c, translate_key(p_key)); + } else { + return fix_keycode(c, translate_key(p_key)); + } +} String KeyMappingMacOS::keycode_get_native_string(Key p_keycode) { - const _KeyCodeText *kct = &_native_keycodes[0]; - - while (kct->text) { - if (kct->code == p_keycode) { - return String::chr(kct->text); - } - kct++; + const char32_t *key = keycode_map.getptr(p_keycode); + if (key) { + return String::chr(*key); } return String(); } diff --git a/platform/macos/logo.png b/platform/macos/logo.png Binary files differdeleted file mode 100644 index b5a660b165..0000000000 --- a/platform/macos/logo.png +++ /dev/null diff --git a/platform/macos/logo.svg b/platform/macos/logo.svg new file mode 100644 index 0000000000..759583d76b --- /dev/null +++ b/platform/macos/logo.svg @@ -0,0 +1 @@ +<svg height="32" viewBox="0 0 25.6 25.6" width="32" xmlns="http://www.w3.org/2000/svg"><path d="M.948 19.474V6.126c0-2.767 2.42-5.178 5.178-5.178h6.904s-2.992 7.506-2.992 13.233c0 .346.337.69.69.69h2.877c0 6.648.906 8.436 1.266 9.781H6.126c-2.75 0-5.178-2.407-5.178-5.178z" fill="#1c9ef8"/><path d="M7.162 8.312v1.496" fill="none" stroke="#323232" stroke-linecap="round" stroke-width="1.036"/><path d="M10.729 14.871c-.352 0-.69-.344-.69-.69C10.038 8.414 13.03.948 13.03.948h6.444c2.77 0 5.178 2.416 5.178 5.178v13.348c0 2.754-2.407 5.178-5.178 5.178h-4.603c-.357-1.333-1.266-2.887-1.266-9.78z" fill="#e1e6ed"/><g fill="none" stroke="#323232" stroke-linecap="round"><path d="M17.575 8.255V9.75" stroke-width="1.036"/><path d="M5.55 16.943c1.037 1.794 3.907 2.876 6.79 2.876 2.877 0 5.745-1.068 6.789-2.876" stroke-width=".69"/></g></svg> diff --git a/platform/macos/macos_terminal_logger.h b/platform/macos/macos_terminal_logger.h index a811a5cbaf..0120240c4f 100644 --- a/platform/macos/macos_terminal_logger.h +++ b/platform/macos/macos_terminal_logger.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* macos_terminal_logger.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* macos_terminal_logger.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 MACOS_TERMINAL_LOGGER_H #define MACOS_TERMINAL_LOGGER_H diff --git a/platform/macos/macos_terminal_logger.mm b/platform/macos/macos_terminal_logger.mm index b5ea2938ee..44f37dc396 100644 --- a/platform/macos/macos_terminal_logger.mm +++ b/platform/macos/macos_terminal_logger.mm @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* macos_terminal_logger.mm */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* macos_terminal_logger.mm */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "macos_terminal_logger.h" diff --git a/platform/macos/os_macos.h b/platform/macos/os_macos.h index 46e7c17ebe..ab61649d19 100644 --- a/platform/macos/os_macos.h +++ b/platform/macos/os_macos.h @@ -1,42 +1,43 @@ -/*************************************************************************/ -/* os_macos.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* os_macos.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 OS_MACOS_H #define OS_MACOS_H -#include "core/input/input.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_macos.h" + +#include "core/input/input.h" +#import "drivers/coreaudio/audio_driver_coreaudio.h" +#import "drivers/coremidi/midi_driver_coremidi.h" +#include "drivers/unix/os_unix.h" #include "servers/audio_server.h" class OS_MacOS : public OS_Unix { @@ -57,6 +58,10 @@ class OS_MacOS : public OS_Unix { List<String> launch_service_args; + CGFloat _weight_to_ct(int p_weight) const; + CGFloat _stretch_to_ct(int p_stretch) const; + String _get_default_fontname(const String &p_font_name) const; + 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); @@ -94,11 +99,13 @@ public: virtual String get_system_dir(SystemDir p_dir, bool p_shared_storage = true) const override; virtual Error shell_open(String p_uri) override; + virtual Error shell_show_in_file_manager(String p_path, bool p_open_folder) override; virtual String get_locale() const override; virtual Vector<String> get_system_fonts() const override; - virtual String get_system_font_path(const String &p_font_name, bool p_bold = false, bool p_italic = false) const override; + virtual String get_system_font_path(const String &p_font_name, int p_weight = 400, int p_stretch = 100, bool p_italic = false) const override; + virtual Vector<String> get_system_font_path_for_text(const String &p_font_name, const String &p_text, const String &p_locale = String(), const String &p_script = String(), int p_weight = 400, int p_stretch = 100, bool p_italic = false) const override; virtual String get_executable_path() const override; virtual Error create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id = nullptr, bool p_open_console = false) override; virtual Error create_instance(const List<String> &p_arguments, ProcessID *r_child_id = nullptr) override; @@ -113,6 +120,9 @@ public: virtual Error move_to_trash(const String &p_path) override; + virtual String get_system_ca_certificates() override; + virtual OS::PreferredTextureFormat get_preferred_texture_format() const override; + void run(); OS_MacOS(); diff --git a/platform/macos/os_macos.mm b/platform/macos/os_macos.mm index e620b058d3..fe6d8d9fb0 100644 --- a/platform/macos/os_macos.mm +++ b/platform/macos/os_macos.mm @@ -1,60 +1,51 @@ -/*************************************************************************/ -/* os_macos.mm */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* os_macos.mm */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "os_macos.h" -#include "core/version_generated.gen.h" -#include "main/main.h" - #include "dir_access_macos.h" #include "display_server_macos.h" #include "godot_application.h" #include "godot_application_delegate.h" #include "macos_terminal_logger.h" +#include "core/crypto/crypto_core.h" +#include "core/version_generated.gen.h" +#include "main/main.h" + #include <dlfcn.h> #include <libproc.h> #include <mach-o/dyld.h> #include <os/log.h> #include <sys/sysctl.h> -_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.path_join(p_path.get_file().get_basename()))) { - return p_path.path_join(p_path.get_file().get_basename()); - } else { - return p_path; - } -} - 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 modal popup display. // Do not redraw when rendering is done from the separate thread, it will conflict with the OpenGL context updates. @@ -162,6 +153,28 @@ void OS_MacOS::alert(const String &p_alert, const String &p_title) { } } +_FORCE_INLINE_ String OS_MacOS::get_framework_executable(const String &p_path) { + Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + + // Read framework bundle to get executable name. + NSURL *url = [NSURL fileURLWithPath:@(p_path.utf8().get_data())]; + NSBundle *bundle = [NSBundle bundleWithURL:url]; + if (bundle) { + String exe_path = String::utf8([[bundle executablePath] UTF8String]); + if (da->file_exists(exe_path)) { + return exe_path; + } + } + + // Try default executable name (invalid framework). + if (da->dir_exists(p_path) && da->file_exists(p_path.path_join(p_path.get_file().get_basename()))) { + return p_path.path_join(p_path.get_file().get_basename()); + } + + // Not a framework, try loading as .dylib. + return p_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); @@ -190,14 +203,6 @@ MainLoop *OS_MacOS::get_main_loop() 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()) { - return get_environment("XDG_CONFIG_HOME"); - } else { - WARN_PRINT_ONCE("`XDG_CONFIG_HOME` is a relative path. Ignoring its value and falling back to `$HOME/Library/Application Support` or `.` per the XDG Base Directory specification."); - } - } if (has_environment("HOME")) { return get_environment("HOME").path_join("Library/Application Support"); } @@ -205,26 +210,10 @@ String OS_MacOS::get_config_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()) { - return get_environment("XDG_DATA_HOME"); - } else { - WARN_PRINT_ONCE("`XDG_DATA_HOME` is a relative path. Ignoring its value and falling back to `get_config_path()` per the XDG Base Directory specification."); - } - } return get_config_path(); } 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()) { - return get_environment("XDG_CACHE_HOME"); - } else { - WARN_PRINT_ONCE("`XDG_CACHE_HOME` is a relative path. Ignoring its value and falling back to `$HOME/Library/Caches` or `get_config_path()` per the XDG Base Directory specification."); - } - } if (has_environment("HOME")) { return get_environment("HOME").path_join("Library/Caches"); } @@ -299,6 +288,27 @@ String OS_MacOS::get_system_dir(SystemDir p_dir, bool p_shared_storage) const { return ret; } +Error OS_MacOS::shell_show_in_file_manager(String p_path, bool p_open_folder) { + bool open_folder = false; + if (DirAccess::dir_exists_absolute(p_path) && p_open_folder) { + open_folder = true; + } + + if (!p_path.begins_with("file://")) { + p_path = String("file://") + p_path; + } + + NSString *string = [NSString stringWithUTF8String:p_path.utf8().get_data()]; + NSURL *uri = [[NSURL alloc] initWithString:[string stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLFragmentAllowedCharacterSet]]]; + + if (open_folder) { + [[NSWorkspace sharedWorkspace] openURL:uri]; + } else { + [[NSWorkspace sharedWorkspace] activateFileViewerSelectingURLs:@[ uri ]]; + } + return OK; +} + Error OS_MacOS::shell_open(String p_uri) { NSString *string = [NSString stringWithUTF8String:p_uri.utf8().get_data()]; NSURL *uri = [[NSURL alloc] initWithString:string]; @@ -336,9 +346,7 @@ Vector<String> OS_MacOS::get_system_fonts() const { return ret; } -String OS_MacOS::get_system_font_path(const String &p_font_name, bool p_bold, bool p_italic) const { - String ret; - +String OS_MacOS::_get_default_fontname(const String &p_font_name) const { String font_name = p_font_name; if (font_name.to_lower() == "sans-serif") { font_name = "Helvetica"; @@ -351,21 +359,153 @@ String OS_MacOS::get_system_font_path(const String &p_font_name, bool p_bold, bo } else if (font_name.to_lower() == "cursive") { font_name = "Apple Chancery"; }; + return font_name; +} + +CGFloat OS_MacOS::_weight_to_ct(int p_weight) const { + if (p_weight < 150) { + return -0.80; + } else if (p_weight < 250) { + return -0.60; + } else if (p_weight < 350) { + return -0.40; + } else if (p_weight < 450) { + return 0.0; + } else if (p_weight < 550) { + return 0.23; + } else if (p_weight < 650) { + return 0.30; + } else if (p_weight < 750) { + return 0.40; + } else if (p_weight < 850) { + return 0.56; + } else if (p_weight < 925) { + return 0.62; + } else { + return 1.00; + } +} + +CGFloat OS_MacOS::_stretch_to_ct(int p_stretch) const { + if (p_stretch < 56) { + return -0.5; + } else if (p_stretch < 69) { + return -0.37; + } else if (p_stretch < 81) { + return -0.25; + } else if (p_stretch < 93) { + return -0.13; + } else if (p_stretch < 106) { + return 0.0; + } else if (p_stretch < 137) { + return 0.13; + } else if (p_stretch < 144) { + return 0.25; + } else if (p_stretch < 162) { + return 0.37; + } else { + return 0.5; + } +} + +Vector<String> OS_MacOS::get_system_font_path_for_text(const String &p_font_name, const String &p_text, const String &p_locale, const String &p_script, int p_weight, int p_stretch, bool p_italic) const { + Vector<String> ret; + String font_name = _get_default_fontname(p_font_name); + + CFStringRef name = CFStringCreateWithCString(kCFAllocatorDefault, font_name.utf8().get_data(), kCFStringEncodingUTF8); + CTFontSymbolicTraits traits = 0; + if (p_weight >= 700) { + traits |= kCTFontBoldTrait; + } + if (p_italic) { + traits |= kCTFontItalicTrait; + } + if (p_stretch < 100) { + traits |= kCTFontCondensedTrait; + } else if (p_stretch > 100) { + traits |= kCTFontExpandedTrait; + } + + CFNumberRef sym_traits = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &traits); + CFMutableDictionaryRef traits_dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, nullptr, nullptr); + CFDictionaryAddValue(traits_dict, kCTFontSymbolicTrait, sym_traits); + + CGFloat weight = _weight_to_ct(p_weight); + CFNumberRef font_weight = CFNumberCreate(kCFAllocatorDefault, kCFNumberCGFloatType, &weight); + CFDictionaryAddValue(traits_dict, kCTFontWeightTrait, font_weight); + + CGFloat stretch = _stretch_to_ct(p_stretch); + CFNumberRef font_stretch = CFNumberCreate(kCFAllocatorDefault, kCFNumberCGFloatType, &stretch); + CFDictionaryAddValue(traits_dict, kCTFontWidthTrait, font_stretch); + + CFMutableDictionaryRef attributes = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, nullptr, nullptr); + CFDictionaryAddValue(attributes, kCTFontFamilyNameAttribute, name); + CFDictionaryAddValue(attributes, kCTFontTraitsAttribute, traits_dict); + + CTFontDescriptorRef font = CTFontDescriptorCreateWithAttributes(attributes); + if (font) { + CTFontRef family = CTFontCreateWithFontDescriptor(font, 0, nullptr); + CFStringRef string = CFStringCreateWithCString(kCFAllocatorDefault, p_text.utf8().get_data(), kCFStringEncodingUTF8); + CFRange range = CFRangeMake(0, CFStringGetLength(string)); + CTFontRef fallback_family = CTFontCreateForString(family, string, range); + if (fallback_family) { + CTFontDescriptorRef fallback_font = CTFontCopyFontDescriptor(fallback_family); + if (fallback_font) { + CFURLRef url = (CFURLRef)CTFontDescriptorCopyAttribute(fallback_font, kCTFontURLAttribute); + if (url) { + NSString *font_path = [NSString stringWithString:[(__bridge NSURL *)url path]]; + ret.push_back(String::utf8([font_path UTF8String])); + CFRelease(url); + } + CFRelease(fallback_font); + } + CFRelease(fallback_family); + } + CFRelease(string); + CFRelease(font); + } + + CFRelease(attributes); + CFRelease(traits_dict); + CFRelease(sym_traits); + CFRelease(font_stretch); + CFRelease(font_weight); + CFRelease(name); + + return ret; +} + +String OS_MacOS::get_system_font_path(const String &p_font_name, int p_weight, int p_stretch, bool p_italic) const { + String ret; + String font_name = _get_default_fontname(p_font_name); CFStringRef name = CFStringCreateWithCString(kCFAllocatorDefault, font_name.utf8().get_data(), kCFStringEncodingUTF8); CTFontSymbolicTraits traits = 0; - if (p_bold) { + if (p_weight > 700) { traits |= kCTFontBoldTrait; } if (p_italic) { traits |= kCTFontItalicTrait; } + if (p_stretch < 100) { + traits |= kCTFontCondensedTrait; + } else if (p_stretch > 100) { + traits |= kCTFontExpandedTrait; + } CFNumberRef sym_traits = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &traits); CFMutableDictionaryRef traits_dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, nullptr, nullptr); CFDictionaryAddValue(traits_dict, kCTFontSymbolicTrait, sym_traits); + CGFloat weight = _weight_to_ct(p_weight); + CFNumberRef font_weight = CFNumberCreate(kCFAllocatorDefault, kCFNumberCGFloatType, &weight); + CFDictionaryAddValue(traits_dict, kCTFontWeightTrait, font_weight); + + CGFloat stretch = _stretch_to_ct(p_stretch); + CFNumberRef font_stretch = CFNumberCreate(kCFAllocatorDefault, kCFNumberCGFloatType, &stretch); + CFDictionaryAddValue(traits_dict, kCTFontWidthTrait, font_stretch); + CFMutableDictionaryRef attributes = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, nullptr, nullptr); CFDictionaryAddValue(attributes, kCTFontFamilyNameAttribute, name); CFDictionaryAddValue(attributes, kCTFontTraitsAttribute, traits_dict); @@ -384,6 +524,8 @@ String OS_MacOS::get_system_font_path(const String &p_font_name, bool p_bold, bo CFRelease(attributes); CFRelease(traits_dict); CFRelease(sym_traits); + CFRelease(font_stretch); + CFRelease(font_weight); CFRelease(name); return ret; @@ -530,6 +672,40 @@ Error OS_MacOS::move_to_trash(const String &p_path) { return OK; } +String OS_MacOS::get_system_ca_certificates() { + CFArrayRef result; + SecCertificateRef item; + CFDataRef der; + + OSStatus ret = SecTrustCopyAnchorCertificates(&result); + ERR_FAIL_COND_V(ret != noErr, ""); + + CFIndex l = CFArrayGetCount(result); + String certs; + PackedByteArray pba; + for (CFIndex i = 0; i < l; i++) { + item = (SecCertificateRef)CFArrayGetValueAtIndex(result, i); + der = SecCertificateCopyData(item); + int derlen = CFDataGetLength(der); + if (pba.size() < derlen * 3) { + pba.resize(derlen * 3); + } + size_t b64len = 0; + Error err = CryptoCore::b64_encode(pba.ptrw(), pba.size(), &b64len, (unsigned char *)CFDataGetBytePtr(der), derlen); + CFRelease(der); + ERR_CONTINUE(err != OK); + certs += "-----BEGIN CERTIFICATE-----\n" + String((char *)pba.ptr(), b64len) + "\n-----END CERTIFICATE-----\n"; + } + CFRelease(result); + return certs; +} + +OS::PreferredTextureFormat OS_MacOS::get_preferred_texture_format() const { + // macOS supports both formats on ARM. Prefer S3TC/BPTC + // for better compatibility with x86 platforms. + return PREFERRED_TEXTURE_FORMAT_S3TC_BPTC; +} + void OS_MacOS::run() { if (!main_loop) { return; diff --git a/platform/macos/platform_config.h b/platform/macos/platform_config.h index e114606b82..65a898dcc1 100644 --- a/platform/macos/platform_config.h +++ b/platform/macos/platform_config.h @@ -1,34 +1,34 @@ -/*************************************************************************/ -/* platform_config.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* platform_config.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 <alloca.h> -#define OPENGL_INCLUDE_H "thirdparty/glad/glad/glad.h" +#define OPENGL_INCLUDE_H "thirdparty/glad/glad/gl.h" #define PTHREAD_RENAME_SELF diff --git a/platform/macos/run_icon.svg b/platform/macos/run_icon.svg new file mode 100644 index 0000000000..c7067bb4b6 --- /dev/null +++ b/platform/macos/run_icon.svg @@ -0,0 +1 @@ +<svg height="16" width="16" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><path style="color:#000;fill:#e0e0e0;fill-opacity:1;stroke-width:.93168;-inkscape-stroke:none" d="M4.418 1.055c-1.82 0-3.365 1.537-3.365 3.363v7.164c0 1.829 1.548 3.363 3.365 3.363h7.164c1.828 0 3.363-1.544 3.363-3.363V4.418c0-1.822-1.537-3.363-3.363-3.363H7.729Zm3.875 1.164h3.291c1.149 0 2.2 1.053 2.2 2.199v7.164c0 1.14-1.052 2.2-2.2 2.2h-2.15a8.884 8.884 0 0 1-.358-1.598c-.135.02-.487.082-.693.117a3.947 3.947 0 0 1-.049.004l-.008-.002a7.345 7.345 0 0 1-1.205-.004 7.114 7.114 0 0 1-.926-.139 6.057 6.057 0 0 1-.867-.271 3.843 3.843 0 0 1-.988-.566 3.214 3.214 0 0 1-.397-.378 2.8 2.8 0 0 1-.318-.441.558.558 0 0 1-.059-.424.564.564 0 0 1 .881-.299.56.56 0 0 1 .145.164c.083.138.188.26.312.362.096.082.2.158.307.224.12.075.243.142.371.201.285.139.583.247.89.319a5.35 5.35 0 0 0 1.282.158c.065 0 .129-.005.184-.006.056 0 .102-.005.148-.008l.096-.006c.114-.009.228-.02.31-.032.083-.013.11-.021.143-.028.099-.022.204-.058.327-.089a28.438 28.438 0 0 1-.06-1.929V8.53H6.887c.048-1.963.746-4.357 1.181-5.677.1-.293.184-.527.225-.633ZM4.973 5.03h.002a.562.562 0 0 1 .558.559v.805a.556.556 0 0 1-.558.558.56.56 0 0 1-.397-.162.565.565 0 0 1-.164-.396V5.59a.561.561 0 0 1 .559-.559Z"/><path style="color:#000;fill:#e0e0e0;fill-opacity:1;stroke-linecap:round;-inkscape-stroke:none" d="M26.117 11.467c.008.11.014.225.022.328.022.283.052.565.088.846l.012.053c1.238-.252 2.448-.829 3.011-1.803a.6.6 0 1 0-1.039-.6c-.28.486-1.161.936-2.094 1.176z" transform="translate(-15.37 .357) scale(.93168)"/><g style="fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-opacity:1"><path style="color:#000;fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:1.2;stroke-linecap:round;stroke-opacity:1;-inkscape-stroke:none" d="M27.836 5.585v.862" transform="translate(-15.37 .357) scale(.93168)"/><path style="color:#000;fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-linecap:round;stroke-opacity:1;-inkscape-stroke:none" d="M27.836 4.984a.6.6 0 0 0-.6.6v.863a.6.6 0 0 0 .6.6.6.6 0 0 0 .6-.6v-.863a.6.6 0 0 0-.6-.6Z" transform="translate(-15.37 .357) scale(.93168)"/></g></svg> diff --git a/platform/macos/tts_macos.h b/platform/macos/tts_macos.h index 344676868a..35205bd1ae 100644 --- a/platform/macos/tts_macos.h +++ b/platform/macos/tts_macos.h @@ -1,39 +1,39 @@ -/*************************************************************************/ -/* tts_macos.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* tts_macos.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 TTS_MACOS_H #define TTS_MACOS_H #include "core/string/ustring.h" +#include "core/templates/hash_map.h" #include "core/templates/list.h" -#include "core/templates/rb_map.h" #include "core/variant/array.h" #include "servers/display_server.h" diff --git a/platform/macos/tts_macos.mm b/platform/macos/tts_macos.mm index 56e15979c4..4e6744e211 100644 --- a/platform/macos/tts_macos.mm +++ b/platform/macos/tts_macos.mm @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* tts_macos.mm */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* tts_macos.mm */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "tts_macos.h" diff --git a/platform/macos/vulkan_context_macos.h b/platform/macos/vulkan_context_macos.h index 2a81336994..ab019384e2 100644 --- a/platform/macos/vulkan_context_macos.h +++ b/platform/macos/vulkan_context_macos.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* vulkan_context_macos.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* vulkan_context_macos.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 VULKAN_CONTEXT_MACOS_H #define VULKAN_CONTEXT_MACOS_H @@ -34,6 +34,7 @@ #ifdef VULKAN_ENABLED #include "drivers/vulkan/vulkan_context.h" + #import <AppKit/AppKit.h> class VulkanContextMacOS : public VulkanContext { diff --git a/platform/macos/vulkan_context_macos.mm b/platform/macos/vulkan_context_macos.mm index 1df6b3ed18..46a2d9f86a 100644 --- a/platform/macos/vulkan_context_macos.mm +++ b/platform/macos/vulkan_context_macos.mm @@ -1,35 +1,37 @@ -/*************************************************************************/ -/* vulkan_context_macos.mm */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* vulkan_context_macos.mm */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ -#ifdef VULKAN_ENABLED #include "vulkan_context_macos.h" + +#ifdef VULKAN_ENABLED + #ifdef USE_VOLK #include <volk.h> #else diff --git a/platform/register_platform_apis.h b/platform/register_platform_apis.h index 9dd90d9b20..bce486881e 100644 --- a/platform/register_platform_apis.h +++ b/platform/register_platform_apis.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* register_platform_apis.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* register_platform_apis.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 REGISTER_PLATFORM_APIS_H #define REGISTER_PLATFORM_APIS_H diff --git a/platform/uwp/README.md b/platform/uwp/README.md index 575f90e3c7..d69a8a8850 100644 --- a/platform/uwp/README.md +++ b/platform/uwp/README.md @@ -14,7 +14,7 @@ project template used for packaging the UWP export templates. ## Documentation -- [Compiling for Universal Windows Platform](https://docs.godotengine.org/en/latest/development/compiling/compiling_for_uwp.html) +- [Compiling for Universal Windows Platform](https://docs.godotengine.org/en/latest/contributing/development/compiling/compiling_for_uwp.html) - Instructions on building this platform port from source. - [Exporting for Universal Windows Platform](https://docs.godotengine.org/en/latest/tutorials/export/exporting_for_uwp.html) - Instructions on using the compiled export templates to export a project. diff --git a/platform/uwp/app_uwp.cpp b/platform/uwp/app_uwp.cpp index 6460c43447..789adb5e5b 100644 --- a/platform/uwp/app_uwp.cpp +++ b/platform/uwp/app_uwp.cpp @@ -1,36 +1,32 @@ -/*************************************************************************/ -/* app_uwp.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. */ -/*************************************************************************/ - -// -// This file demonstrates how to initialize EGL in a Windows Store app, using ICoreWindow. -// +/**************************************************************************/ +/* app_uwp.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "app_uwp.h" @@ -38,7 +34,6 @@ #include "core/io/file_access.h" #include "core/os/keyboard.h" #include "main/main.h" - #include "platform/windows/key_mapping_windows.h" #include <collection.h> diff --git a/platform/uwp/app_uwp.h b/platform/uwp/app_uwp.h index 82ad3ca01a..87c66bd679 100644 --- a/platform/uwp/app_uwp.h +++ b/platform/uwp/app_uwp.h @@ -1,42 +1,41 @@ -/*************************************************************************/ -/* app_uwp.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* app_uwp.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 APP_UWP_H #define APP_UWP_H -#include <string> +#include "os_uwp.h" +#include <GLES2/gl2.h> #include <wrl.h> - -#include "GLES2/gl2.h" -#include "os_uwp.h" +#include <string> /** clang-format does not play nice with this C++/CX hybrid, needs investigation. */ /* clang-format off */ diff --git a/platform/uwp/context_egl_uwp.cpp b/platform/uwp/context_egl_uwp.cpp index 8ec7bdfcee..aa8cfb4d49 100644 --- a/platform/uwp/context_egl_uwp.cpp +++ b/platform/uwp/context_egl_uwp.cpp @@ -1,36 +1,36 @@ -/*************************************************************************/ -/* context_egl_uwp.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* context_egl_uwp.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "context_egl_uwp.h" -#include "EGL/eglext.h" +#include <EGL/eglext.h> using Platform::Exception; diff --git a/platform/uwp/context_egl_uwp.h b/platform/uwp/context_egl_uwp.h index c547f39988..810c3dcbc1 100644 --- a/platform/uwp/context_egl_uwp.h +++ b/platform/uwp/context_egl_uwp.h @@ -1,43 +1,42 @@ -/*************************************************************************/ -/* context_egl_uwp.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* context_egl_uwp.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 CONTEXT_EGL_UWP_H #define CONTEXT_EGL_UWP_H -#include <wrl.h> - -#include <EGL/egl.h> - #include "core/error/error_list.h" #include "core/os/os.h" +#include <EGL/egl.h> +#include <wrl.h> + using namespace Windows::UI::Core; class ContextEGL_UWP { diff --git a/platform/uwp/export/app_packager.cpp b/platform/uwp/export/app_packager.cpp index 6f8966b9ff..ffb5e31851 100644 --- a/platform/uwp/export/app_packager.cpp +++ b/platform/uwp/export/app_packager.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* app_packager.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* app_packager.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "app_packager.h" diff --git a/platform/uwp/export/app_packager.h b/platform/uwp/export/app_packager.h index 18db3eb806..e989ba9b90 100644 --- a/platform/uwp/export/app_packager.h +++ b/platform/uwp/export/app_packager.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* app_packager.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* app_packager.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 UWP_APP_PACKAGER_H #define UWP_APP_PACKAGER_H diff --git a/platform/uwp/export/export.cpp b/platform/uwp/export/export.cpp index 31105824a5..3e229c7419 100644 --- a/platform/uwp/export/export.cpp +++ b/platform/uwp/export/export.cpp @@ -1,38 +1,44 @@ -/*************************************************************************/ -/* export.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* export.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "export.h" -#include "editor/editor_settings.h" #include "export_plugin.h" +#include "editor/editor_settings.h" +#include "editor/export/editor_export.h" + +void register_uwp_exporter_types() { + // GDREGISTER_VIRTUAL_CLASS(EditorExportPlatformUWP); +} + void register_uwp_exporter() { #ifdef WINDOWS_ENABLED EDITOR_DEF("export/uwp/signtool", ""); diff --git a/platform/uwp/export/export.h b/platform/uwp/export/export.h index c237a75b59..d2053e02b1 100644 --- a/platform/uwp/export/export.h +++ b/platform/uwp/export/export.h @@ -1,36 +1,37 @@ -/*************************************************************************/ -/* export.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* export.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 UWP_EXPORT_H #define UWP_EXPORT_H +void register_uwp_exporter_types(); void register_uwp_exporter(); #endif // UWP_EXPORT_H diff --git a/platform/uwp/export/export_plugin.cpp b/platform/uwp/export/export_plugin.cpp index ab0b20762f..69de383efc 100644 --- a/platform/uwp/export/export_plugin.cpp +++ b/platform/uwp/export/export_plugin.cpp @@ -1,37 +1,44 @@ -/*************************************************************************/ -/* export_plugin.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* export_plugin.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "export_plugin.h" +#include "../logo_svg.gen.h" + +#include "editor/editor_scale.h" #include "editor/editor_settings.h" -#include "platform/uwp/logo.gen.h" + +#include "modules/modules_enabled.gen.h" // For svg and regex. +#ifdef MODULE_SVG_ENABLED +#include "modules/svg/image_loader_svg.h" +#endif String EditorExportPlatformUWP::get_name() const { return "UWP"; @@ -56,7 +63,7 @@ void EditorExportPlatformUWP::get_preset_features(const Ref<EditorExportPreset> r_features->push_back(p_preset->get("binary_format/architecture")); } -void EditorExportPlatformUWP::get_export_options(List<ExportOption> *r_options) { +void EditorExportPlatformUWP::get_export_options(List<ExportOption> *r_options) const { 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"), "")); @@ -74,8 +81,8 @@ void EditorExportPlatformUWP::get_export_options(List<ExportOption> *r_options) r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "identity/product_guid", PROPERTY_HINT_PLACEHOLDER_TEXT, "00000000-0000-0000-0000-000000000000"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "identity/publisher_guid", PROPERTY_HINT_PLACEHOLDER_TEXT, "00000000-0000-0000-0000-000000000000"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "signing/certificate", PROPERTY_HINT_GLOBAL_FILE, "*.pfx"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "signing/password"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "signing/certificate", PROPERTY_HINT_GLOBAL_FILE, "*.pfx", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "signing/password", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "signing/algorithm", PROPERTY_HINT_ENUM, "MD5,SHA1,SHA256"), 2)); r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "version/major"), 1)); @@ -459,8 +466,8 @@ Error EditorExportPlatformUWP::export_project(const Ref<EditorExportPreset> &p_p int cert_alg = EDITOR_GET("export/uwp/debug_algorithm"); if (!p_debug) { - cert_path = p_preset->get("signing/certificate"); - cert_pass = p_preset->get("signing/password"); + cert_path = p_preset->get_or_env("signing/certificate", ENV_UWP_SIGNING_CERT); + cert_pass = p_preset->get_or_env("signing/password", ENV_UWP_SIGNING_PASS); cert_alg = p_preset->get("signing/algorithm"); } @@ -504,5 +511,13 @@ void EditorExportPlatformUWP::resolve_platform_feature_priorities(const Ref<Edit } EditorExportPlatformUWP::EditorExportPlatformUWP() { - logo = ImageTexture::create_from_image(memnew(Image(_uwp_logo))); +#ifdef MODULE_SVG_ENABLED + Ref<Image> img = memnew(Image); + const bool upsample = !Math::is_equal_approx(Math::round(EDSCALE), EDSCALE); + + ImageLoaderSVG img_loader; + img_loader.create_image_from_string(img, _uwp_logo_svg, EDSCALE, upsample, false); + + logo = ImageTexture::create_from_image(img); +#endif } diff --git a/platform/uwp/export/export_plugin.h b/platform/uwp/export/export_plugin.h index 74b9ab4875..999d54cb80 100644 --- a/platform/uwp/export/export_plugin.h +++ b/platform/uwp/export/export_plugin.h @@ -1,36 +1,38 @@ -/*************************************************************************/ -/* export_plugin.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* export_plugin.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 UWP_EXPORT_PLUGIN_H #define UWP_EXPORT_PLUGIN_H +#include "app_packager.h" + #include "core/config/project_settings.h" #include "core/crypto/crypto_core.h" #include "core/io/dir_access.h" @@ -46,8 +48,6 @@ #include "thirdparty/minizip/unzip.h" #include "thirdparty/minizip/zip.h" -#include "app_packager.h" - #include <zlib.h> // Capabilities @@ -85,6 +85,11 @@ static const char *uwp_device_capabilities[] = { nullptr }; +// Optional environment variables for defining confidential information. If any +// of these is set, they will override the values set in the credentials file. +const String ENV_UWP_SIGNING_CERT = "GODOT_UWP_SIGNING_CERTIFICATE"; +const String ENV_UWP_SIGNING_PASS = "GODOT_UWP_SIGNING_PASSWORD"; + class EditorExportPlatformUWP : public EditorExportPlatform { GDCLASS(EditorExportPlatformUWP, EditorExportPlatform); @@ -427,7 +432,7 @@ public: virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const override; - virtual void get_export_options(List<ExportOption> *r_options) override; + virtual void get_export_options(List<ExportOption> *r_options) const override; virtual bool has_valid_export_configuration(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const override; virtual bool has_valid_project_configuration(const Ref<EditorExportPreset> &p_preset, String &r_error) const override; diff --git a/platform/uwp/joypad_uwp.cpp b/platform/uwp/joypad_uwp.cpp index 85c8959cf1..e6a923c0c5 100644 --- a/platform/uwp/joypad_uwp.cpp +++ b/platform/uwp/joypad_uwp.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* joypad_uwp.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* joypad_uwp.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "joypad_uwp.h" diff --git a/platform/uwp/joypad_uwp.h b/platform/uwp/joypad_uwp.h index 81f84152b9..e9be647dd4 100644 --- a/platform/uwp/joypad_uwp.h +++ b/platform/uwp/joypad_uwp.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* joypad_uwp.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* joypad_uwp.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 JOYPAD_UWP_H #define JOYPAD_UWP_H diff --git a/platform/uwp/logo.png b/platform/uwp/logo.png Binary files differdeleted file mode 100644 index 9017a30636..0000000000 --- a/platform/uwp/logo.png +++ /dev/null diff --git a/platform/uwp/logo.svg b/platform/uwp/logo.svg new file mode 100644 index 0000000000..5bcbdcfcd4 --- /dev/null +++ b/platform/uwp/logo.svg @@ -0,0 +1 @@ +<svg height="32" width="32" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><g transform="translate(8.981 1.816)"><circle style="fill:#2f75bb;fill-opacity:1;stroke:none;stroke-width:.815427" cx="7.019" cy="14.184" r="13.825"/><path d="m-1.192 8.234 6.73-.927v6.503h-6.73Zm0 11.899 6.73.927v-6.422h-6.73Zm7.47 1.026 8.952 1.236v-7.757H6.278Zm0-13.951v6.602h8.952V5.973Z" fill="#00abed" style="fill:#fff;fill-opacity:1"/></g></svg> diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp index 141c28c713..df7923660c 100644 --- a/platform/uwp/os_uwp.cpp +++ b/platform/uwp/os_uwp.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* os_uwp.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* os_uwp.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "os_uwp.h" @@ -450,8 +450,7 @@ String OS_UWP::get_distribution_name() const { String OS_UWP::get_version() const { winrt::hstring df_version = VersionInfo().DeviceFamilyVersion(); - static String version = String(winrt::to_string(df_version).c_str()); - return version; + return String(winrt::to_string(df_version).c_str()); } OS::DateTime OS_UWP::get_datetime(bool p_utc) const { @@ -680,7 +679,7 @@ bool OS_UWP::set_environment(const String &p_var, const String &p_value) const { return false; } -String OS_UWP::get_stdin_string(bool p_block) { +String OS_UWP::get_stdin_string() { return String(); } diff --git a/platform/uwp/os_uwp.h b/platform/uwp/os_uwp.h index c1df7827cd..7f2195e4fd 100644 --- a/platform/uwp/os_uwp.h +++ b/platform/uwp/os_uwp.h @@ -1,43 +1,44 @@ -/*************************************************************************/ -/* os_uwp.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* os_uwp.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 OS_UWP_H #define OS_UWP_H #include "context_egl_uwp.h" +#include "joypad_uwp.h" + #include "core/input/input.h" #include "core/math/transform_2d.h" #include "core/os/os.h" #include "core/string/ustring.h" #include "drivers/xaudio2/audio_driver_xaudio2.h" -#include "joypad_uwp.h" #include "servers/audio_server.h" #include "servers/rendering/renderer_compositor.h" #include "servers/rendering_server.h" @@ -162,7 +163,7 @@ public: HANDLE mouse_mode_changed; virtual void alert(const String &p_alert, const String &p_title = "ALERT!"); - String get_stdin_string(bool p_block); + String get_stdin_string(); void set_mouse_mode(MouseMode p_mode); MouseMode get_mouse_mode() const; diff --git a/platform/uwp/platform_config.h b/platform/uwp/platform_config.h index dc398cba4c..964e341ce4 100644 --- a/platform/uwp/platform_config.h +++ b/platform/uwp/platform_config.h @@ -1,31 +1,31 @@ -/*************************************************************************/ -/* platform_config.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* platform_config.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 <malloc.h> diff --git a/platform/web/README.md b/platform/web/README.md index 1265ca09df..906eb508fe 100644 --- a/platform/web/README.md +++ b/platform/web/README.md @@ -10,7 +10,7 @@ this platform such as the html shell (web page). ## Documentation -- [Compiling for the Web](https://docs.godotengine.org/en/latest/development/compiling/compiling_for_web.html) +- [Compiling for the Web](https://docs.godotengine.org/en/latest/contributing/development/compiling/compiling_for_web.html) - Instructions on building this platform port from source. - [Exporting for the Web](https://docs.godotengine.org/en/latest/tutorials/export/exporting_for_web.html) - Instructions on using the compiled export templates to export a project. diff --git a/platform/web/SCsub b/platform/web/SCsub index 077024507a..e44e59bfb9 100644 --- a/platform/web/SCsub +++ b/platform/web/SCsub @@ -38,15 +38,20 @@ sys_env.AddJSLibraries( "js/libs/library_godot_webgl2.js", ] ) +sys_env.AddJSExterns( + [ + "js/libs/library_godot_webgl2.externs.js", + ] +) if env["javascript_eval"]: sys_env.AddJSLibraries(["js/libs/library_godot_javascript_singleton.js"]) for lib in sys_env["JS_LIBS"]: sys_env.Append(LINKFLAGS=["--js-library", lib.abspath]) -for js in env["JS_PRE"]: +for js in sys_env["JS_PRE"]: sys_env.Append(LINKFLAGS=["--pre-js", js.abspath]) -for ext in env["JS_EXTERNS"]: +for ext in sys_env["JS_EXTERNS"]: sys_env["ENV"]["EMCC_CLOSURE_ARGS"] += " --externs " + ext.abspath build = [] diff --git a/platform/web/api/api.cpp b/platform/web/api/api.cpp index e637f2aef2..ab7154b0fb 100644 --- a/platform/web/api/api.cpp +++ b/platform/web/api/api.cpp @@ -1,38 +1,40 @@ -/*************************************************************************/ -/* api.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* api.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "api.h" -#include "core/config/engine.h" + #include "javascript_bridge_singleton.h" #include "web_tools_editor_plugin.h" +#include "core/config/engine.h" + static JavaScriptBridge *javascript_bridge_singleton; void register_web_api() { @@ -73,10 +75,12 @@ void JavaScriptBridge::_bind_methods() { ClassDB::bind_method(D_METHOD("download_buffer", "buffer", "name", "mime"), &JavaScriptBridge::download_buffer, DEFVAL("application/octet-stream")); ClassDB::bind_method(D_METHOD("pwa_needs_update"), &JavaScriptBridge::pwa_needs_update); ClassDB::bind_method(D_METHOD("pwa_update"), &JavaScriptBridge::pwa_update); + ClassDB::bind_method(D_METHOD("force_fs_sync"), &JavaScriptBridge::force_fs_sync); ADD_SIGNAL(MethodInfo("pwa_update_available")); } #if !defined(WEB_ENABLED) || !defined(JAVASCRIPT_EVAL_ENABLED) + Variant JavaScriptBridge::eval(const String &p_code, bool p_use_global_exec_context) { return Variant(); } @@ -103,14 +107,23 @@ Variant JavaScriptBridge::_create_object_bind(const Variant **p_args, int p_argc } return Ref<JavaScriptObject>(); } + #endif + #if !defined(WEB_ENABLED) + bool JavaScriptBridge::pwa_needs_update() const { return false; } + Error JavaScriptBridge::pwa_update() { return ERR_UNAVAILABLE; } + +void JavaScriptBridge::force_fs_sync() { +} + void JavaScriptBridge::download_buffer(Vector<uint8_t> p_arr, const String &p_name, const String &p_mime) { } + #endif diff --git a/platform/web/api/api.h b/platform/web/api/api.h index f073e817d1..234bc6b326 100644 --- a/platform/web/api/api.h +++ b/platform/web/api/api.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* api.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* api.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 WEB_API_H #define WEB_API_H diff --git a/platform/web/api/javascript_bridge_singleton.h b/platform/web/api/javascript_bridge_singleton.h index 1e7b5a1699..456fa6b313 100644 --- a/platform/web/api/javascript_bridge_singleton.h +++ b/platform/web/api/javascript_bridge_singleton.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* javascript_bridge_singleton.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* javascript_bridge_singleton.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 JAVASCRIPT_BRIDGE_SINGLETON_H #define JAVASCRIPT_BRIDGE_SINGLETON_H @@ -61,6 +61,7 @@ public: void download_buffer(Vector<uint8_t> p_arr, const String &p_name, const String &p_mime = "application/octet-stream"); bool pwa_needs_update() const; Error pwa_update(); + void force_fs_sync(); static JavaScriptBridge *get_singleton(); JavaScriptBridge(); diff --git a/platform/web/api/web_tools_editor_plugin.cpp b/platform/web/api/web_tools_editor_plugin.cpp index 46fcb2d452..d39773bde2 100644 --- a/platform/web/api/web_tools_editor_plugin.cpp +++ b/platform/web/api/web_tools_editor_plugin.cpp @@ -1,36 +1,37 @@ -/*************************************************************************/ -/* web_tools_editor_plugin.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* web_tools_editor_plugin.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ -#if defined(TOOLS_ENABLED) && defined(WEB_ENABLED) #include "web_tools_editor_plugin.h" +#if defined(TOOLS_ENABLED) && defined(WEB_ENABLED) + #include "core/config/engine.h" #include "core/config/project_settings.h" #include "core/io/dir_access.h" @@ -57,7 +58,7 @@ WebToolsEditorPlugin::WebToolsEditorPlugin() { add_tool_menu_item("Download Project Source", callable_mp(this, &WebToolsEditorPlugin::_download_zip)); } -void WebToolsEditorPlugin::_download_zip(Variant p_v) { +void WebToolsEditorPlugin::_download_zip() { if (!Engine::get_singleton() || !Engine::get_singleton()->is_editor_hint()) { ERR_PRINT("Downloading the project as a ZIP archive is only available in Editor mode."); return; @@ -75,7 +76,7 @@ void WebToolsEditorPlugin::_download_zip(Variant p_v) { const String project_name_safe = project_name.to_lower().replace(" ", "_"); const String datetime_safe = Time::get_singleton()->get_datetime_string_from_system(false, true).replace(" ", "_"); - const String output_name = OS::get_singleton()->get_safe_dir_name(vformat("%s_%s.zip")); + const String output_name = OS::get_singleton()->get_safe_dir_name(vformat("%s_%s.zip", project_name_safe, datetime_safe)); const String output_path = String("/tmp").path_join(output_name); zipFile zip = zipOpen2(output_path.utf8().get_data(), APPEND_STATUS_CREATE, nullptr, &io); @@ -154,4 +155,5 @@ void WebToolsEditorPlugin::_zip_recursive(String p_path, String p_base_path, zip cur = dir->get_next(); } } -#endif + +#endif // TOOLS_ENABLED && WEB_ENABLED diff --git a/platform/web/api/web_tools_editor_plugin.h b/platform/web/api/web_tools_editor_plugin.h index 6af1dec3fb..ac0d5e20ec 100644 --- a/platform/web/api/web_tools_editor_plugin.h +++ b/platform/web/api/web_tools_editor_plugin.h @@ -1,37 +1,38 @@ -/*************************************************************************/ -/* web_tools_editor_plugin.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* web_tools_editor_plugin.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 WEB_TOOLS_EDITOR_PLUGIN_H #define WEB_TOOLS_EDITOR_PLUGIN_H #if defined(TOOLS_ENABLED) && defined(WEB_ENABLED) + #include "core/io/zip_io.h" #include "editor/editor_plugin.h" @@ -41,18 +42,21 @@ class WebToolsEditorPlugin : public EditorPlugin { private: void _zip_file(String p_path, String p_base_path, zipFile p_zip); void _zip_recursive(String p_path, String p_base_path, zipFile p_zip); - void _download_zip(Variant p_v); + void _download_zip(); public: static void initialize(); WebToolsEditorPlugin(); }; + #else + class WebToolsEditorPlugin { public: static void initialize() {} }; -#endif + +#endif // TOOLS_ENABLED && WEB_ENABLED #endif // WEB_TOOLS_EDITOR_PLUGIN_H diff --git a/platform/web/audio_driver_web.cpp b/platform/web/audio_driver_web.cpp index c4b27c782d..c6c67db3de 100644 --- a/platform/web/audio_driver_web.cpp +++ b/platform/web/audio_driver_web.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* audio_driver_web.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* audio_driver_web.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "audio_driver_web.h" @@ -103,7 +103,7 @@ void AudioDriverWeb::_audio_driver_capture(int p_from, int p_samples) { Error AudioDriverWeb::init() { int latency = GLOBAL_GET("audio/driver/output_latency"); if (!audio_context.inited) { - audio_context.mix_rate = GLOBAL_GET("audio/driver/mix_rate"); + audio_context.mix_rate = _get_configured_mix_rate(); audio_context.channel_count = godot_audio_init(&audio_context.mix_rate, latency, &_state_change_callback, &_latency_update_callback); audio_context.inited = true; } @@ -166,18 +166,18 @@ void AudioDriverWeb::finish() { } } -Error AudioDriverWeb::capture_start() { +Error AudioDriverWeb::input_start() { lock(); input_buffer_init(buffer_length); unlock(); - if (godot_audio_capture_start()) { + if (godot_audio_input_start()) { return FAILED; } return OK; } -Error AudioDriverWeb::capture_stop() { - godot_audio_capture_stop(); +Error AudioDriverWeb::input_stop() { + godot_audio_input_stop(); lock(); input_buffer.clear(); unlock(); diff --git a/platform/web/audio_driver_web.h b/platform/web/audio_driver_web.h index 0a322d61b4..7bfed834e1 100644 --- a/platform/web/audio_driver_web.h +++ b/platform/web/audio_driver_web.h @@ -1,42 +1,42 @@ -/*************************************************************************/ -/* audio_driver_web.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* audio_driver_web.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 AUDIO_DRIVER_WEB_H #define AUDIO_DRIVER_WEB_H +#include "godot_audio.h" + #include "core/os/mutex.h" #include "core/os/thread.h" #include "servers/audio_server.h" -#include "godot_audio.h" - class AudioDriverWeb : public AudioDriver { private: struct AudioContext { @@ -77,12 +77,12 @@ public: virtual void start() final; virtual void finish() final; - virtual float get_latency() override; virtual int get_mix_rate() const override; virtual SpeakerMode get_speaker_mode() const override; + virtual float get_latency() override; - virtual Error capture_start() override; - virtual Error capture_stop() override; + virtual Error input_start() override; + virtual Error input_stop() override; static void resume(); @@ -111,10 +111,12 @@ protected: virtual void finish_driver() override; public: - virtual const char *get_name() const override { return "AudioWorklet"; } + virtual const char *get_name() const override { + return "AudioWorklet"; + } - void lock() override; - void unlock() override; + virtual void lock() override; + virtual void unlock() override; }; #endif // AUDIO_DRIVER_WEB_H diff --git a/platform/web/detect.py b/platform/web/detect.py index 08c1ff7b4a..419d8918f2 100644 --- a/platform/web/detect.py +++ b/platform/web/detect.py @@ -48,6 +48,16 @@ def get_opts(): ] +def get_doc_classes(): + return [ + "EditorExportPlatformWeb", + ] + + +def get_doc_path(): + return "doc_classes" + + def get_flags(): return [ ("arch", "wasm32"), diff --git a/platform/web/display_server_web.cpp b/platform/web/display_server_web.cpp index 2c1e87e663..951ce110e0 100644 --- a/platform/web/display_server_web.cpp +++ b/platform/web/display_server_web.cpp @@ -1,47 +1,49 @@ -/*************************************************************************/ -/* display_server_web.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* display_server_web.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "display_server_web.h" +#include "dom_keys.inc" +#include "godot_js.h" +#include "os_web.h" + +#include "core/config/project_settings.h" +#include "servers/rendering/dummy/rasterizer_dummy.h" + #ifdef GLES3_ENABLED #include "drivers/gles3/rasterizer_gles3.h" #endif -#include "platform/web/os_web.h" -#include "servers/rendering/dummy/rasterizer_dummy.h" #include <emscripten.h> #include <png.h> -#include "dom_keys.inc" -#include "godot_js.h" - #define DOM_BUTTON_LEFT 0 #define DOM_BUTTON_MIDDLE 1 #define DOM_BUTTON_RIGHT 2 @@ -54,7 +56,15 @@ DisplayServerWeb *DisplayServerWeb::get_singleton() { // Window (canvas) bool DisplayServerWeb::check_size_force_redraw() { - return godot_js_display_size_update() != 0; + bool size_changed = godot_js_display_size_update() != 0; + if (size_changed && !rect_changed_callback.is_null()) { + Variant size = Rect2i(Point2i(), window_get_size()); // TODO use window_get_position if implemented. + Variant *vp = &size; + Variant ret; + Callable::CallError ce; + rect_changed_callback.callp((const Variant **)&vp, 1, ret, ce); + } + return size_changed; } void DisplayServerWeb::fullscreen_change_callback(int p_fullscreen) { @@ -100,11 +110,19 @@ void DisplayServerWeb::request_quit_callback() { // Keys -void DisplayServerWeb::dom2godot_mod(Ref<InputEventWithModifiers> ev, int p_mod) { - ev->set_shift_pressed(p_mod & 1); - ev->set_alt_pressed(p_mod & 2); - ev->set_ctrl_pressed(p_mod & 4); - ev->set_meta_pressed(p_mod & 8); +void DisplayServerWeb::dom2godot_mod(Ref<InputEventWithModifiers> ev, int p_mod, Key p_keycode) { + if (p_keycode != Key::SHIFT) { + ev->set_shift_pressed(p_mod & 1); + } + if (p_keycode != Key::ALT) { + ev->set_alt_pressed(p_mod & 2); + } + if (p_keycode != Key::CTRL) { + ev->set_ctrl_pressed(p_mod & 4); + } + if (p_keycode != Key::META) { + ev->set_meta_pressed(p_mod & 8); + } } void DisplayServerWeb::key_callback(int p_pressed, int p_repeat, int p_modifiers) { @@ -113,18 +131,25 @@ void DisplayServerWeb::key_callback(int p_pressed, int p_repeat, int p_modifiers // Resume audio context after input in case autoplay was denied. OS_Web::get_singleton()->resume_audio(); + char32_t c = 0x00; + String unicode = String::utf8(key_event.key); + if (unicode.length() == 1) { + c = unicode[0]; + } + + Key keycode = dom_code2godot_scancode(key_event.code, key_event.key, false); + Key scancode = dom_code2godot_scancode(key_event.code, key_event.key, true); + Ref<InputEventKey> ev; ev.instantiate(); ev->set_echo(p_repeat); - ev->set_keycode(dom_code2godot_scancode(key_event.code, key_event.key, false)); - ev->set_physical_keycode(dom_code2godot_scancode(key_event.code, key_event.key, true)); + ev->set_keycode(fix_keycode(c, keycode)); + ev->set_physical_keycode(scancode); + ev->set_key_label(fix_key_label(c, keycode)); + ev->set_unicode(fix_unicode(c)); ev->set_pressed(p_pressed); - dom2godot_mod(ev, p_modifiers); + dom2godot_mod(ev, p_modifiers, fix_keycode(c, keycode)); - String unicode = String::utf8(key_event.key); - if (unicode.length() == 1) { - ev->set_unicode(unicode[0]); - } Input::get_singleton()->parse_input_event(ev); // Make sure to flush all events so we can call restricted APIs inside the event. @@ -142,7 +167,7 @@ int DisplayServerWeb::mouse_button_callback(int p_pressed, int p_button, double ev->set_position(pos); ev->set_global_position(pos); ev->set_pressed(p_pressed); - dom2godot_mod(ev, p_modifiers); + dom2godot_mod(ev, p_modifiers, Key::NONE); switch (p_button) { case DOM_BUTTON_LEFT: @@ -185,12 +210,12 @@ int DisplayServerWeb::mouse_button_callback(int p_pressed, int p_button, double } } - MouseButton mask = Input::get_singleton()->get_mouse_button_mask(); - MouseButton button_flag = mouse_button_to_mask(ev->get_button_index()); + BitField<MouseButtonMask> mask = Input::get_singleton()->get_mouse_button_mask(); + MouseButtonMask button_flag = mouse_button_to_mask(ev->get_button_index()); if (ev->is_pressed()) { - mask |= button_flag; - } else if ((mask & button_flag) != MouseButton::NONE) { - mask &= ~button_flag; + mask.set_flag(button_flag); + } else if (mask.has_flag(button_flag)) { + mask.clear_flag(button_flag); } else { // Received release event, but press was outside the canvas, so ignore. return false; @@ -210,17 +235,17 @@ int DisplayServerWeb::mouse_button_callback(int p_pressed, int p_button, double } void DisplayServerWeb::mouse_move_callback(double p_x, double p_y, double p_rel_x, double p_rel_y, int p_modifiers) { - MouseButton input_mask = Input::get_singleton()->get_mouse_button_mask(); + BitField<MouseButtonMask> input_mask = Input::get_singleton()->get_mouse_button_mask(); // For motion outside the canvas, only read mouse movement if dragging // started inside the canvas; imitating desktop app behavior. - if (!get_singleton()->cursor_inside_canvas && input_mask == MouseButton::NONE) { + if (!get_singleton()->cursor_inside_canvas && input_mask.is_empty()) { return; } Point2 pos(p_x, p_y); Ref<InputEventMouseMotion> ev; ev.instantiate(); - dom2godot_mod(ev, p_modifiers); + dom2godot_mod(ev, p_modifiers, Key::NONE); ev->set_button_mask(input_mask); ev->set_position(pos); @@ -275,10 +300,12 @@ const char *DisplayServerWeb::godot2dom_cursor(DisplayServer::CursorShape p_shap } bool DisplayServerWeb::tts_is_speaking() const { + ERR_FAIL_COND_V_MSG(!tts, false, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); return godot_js_tts_is_speaking(); } bool DisplayServerWeb::tts_is_paused() const { + ERR_FAIL_COND_V_MSG(!tts, false, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); return godot_js_tts_is_paused(); } @@ -297,11 +324,13 @@ void DisplayServerWeb::update_voices_callback(int p_size, const char **p_voice) } TypedArray<Dictionary> DisplayServerWeb::tts_get_voices() const { + ERR_FAIL_COND_V_MSG(!tts, TypedArray<Dictionary>(), "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); godot_js_tts_get_voices(update_voices_callback); return voices; } void DisplayServerWeb::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_MSG(!tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); if (p_interrupt) { tts_stop(); } @@ -318,14 +347,17 @@ void DisplayServerWeb::tts_speak(const String &p_text, const String &p_voice, in } void DisplayServerWeb::tts_pause() { + ERR_FAIL_COND_MSG(!tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); godot_js_tts_pause(); } void DisplayServerWeb::tts_resume() { + ERR_FAIL_COND_MSG(!tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); godot_js_tts_resume(); } void DisplayServerWeb::tts_stop() { + ERR_FAIL_COND_MSG(!tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); for (const KeyValue<int, CharString> &E : utterance_ids) { tts_post_utterance_event(DisplayServer::TTS_UTTERANCE_CANCELED, E.key); } @@ -372,18 +404,15 @@ DisplayServer::CursorShape DisplayServerWeb::cursor_get_shape() const { } void DisplayServerWeb::cursor_set_custom_image(const Ref<Resource> &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { + ERR_FAIL_INDEX(p_shape, CURSOR_MAX); if (p_cursor.is_valid()) { Ref<Texture2D> texture = p_cursor; + ERR_FAIL_COND(!texture.is_valid()); Ref<AtlasTexture> atlas_texture = p_cursor; - Ref<Image> image; Size2 texture_size; Rect2 atlas_rect; - if (texture.is_valid()) { - image = texture->get_image(); - } - - if (!image.is_valid() && atlas_texture.is_valid()) { + if (atlas_texture.is_valid()) { texture = atlas_texture->get_atlas(); atlas_rect.size.width = texture->get_width(); @@ -393,21 +422,25 @@ void DisplayServerWeb::cursor_set_custom_image(const Ref<Resource> &p_cursor, Cu texture_size.width = atlas_texture->get_region().size.x; texture_size.height = atlas_texture->get_region().size.y; - } else if (image.is_valid()) { + } else { texture_size.width = texture->get_width(); texture_size.height = texture->get_height(); } - ERR_FAIL_COND(!texture.is_valid()); ERR_FAIL_COND(p_hotspot.x < 0 || p_hotspot.y < 0); ERR_FAIL_COND(texture_size.width > 256 || texture_size.height > 256); ERR_FAIL_COND(p_hotspot.x > texture_size.width || p_hotspot.y > texture_size.height); - image = texture->get_image(); + Ref<Image> image = texture->get_image(); ERR_FAIL_COND(!image.is_valid()); - image = image->duplicate(); + image = image->duplicate(true); + + if (image->is_compressed()) { + Error err = image->decompress(); + ERR_FAIL_COND_MSG(err != OK, "Couldn't decompress VRAM-compressed custom mouse cursor image. Switch to a lossless compression mode in the Import dock."); + } if (atlas_texture.is_valid()) { image->crop_from_point( @@ -517,15 +550,17 @@ int DisplayServerWeb::mouse_wheel_callback(double p_delta_x, double p_delta_y) { // Different browsers give wildly different delta values, and we can't // interpret deltaMode, so use default value for wheel events' factor. - MouseButton button_flag = mouse_button_to_mask(ev->get_button_index()); + MouseButtonMask button_flag = mouse_button_to_mask(ev->get_button_index()); + BitField<MouseButtonMask> button_mask = input->get_mouse_button_mask(); + button_mask.set_flag(button_flag); ev->set_pressed(true); - ev->set_button_mask(input->get_mouse_button_mask() | button_flag); + ev->set_button_mask(button_mask); input->parse_input_event(ev); Ref<InputEventMouseButton> release = ev->duplicate(); release->set_pressed(false); - release->set_button_mask(MouseButton(input->get_mouse_button_mask() & ~button_flag)); + release->set_button_mask(input->get_mouse_button_mask()); input->parse_input_event(release); return true; @@ -571,8 +606,8 @@ void DisplayServerWeb::touch_callback(int p_type, int p_count) { } } -bool DisplayServerWeb::screen_is_touchscreen(int p_screen) const { - return godot_js_display_touchscreen_is_available(); +bool DisplayServerWeb::is_touchscreen_available() const { + return godot_js_display_touchscreen_is_available() || (Input::get_singleton() && Input::get_singleton()->is_emulating_touch_from_mouse()); } // Virtual Keyboard @@ -738,13 +773,15 @@ void DisplayServerWeb::_dispatch_input_event(const Ref<InputEvent> &p_event) { } } -DisplayServer *DisplayServerWeb::create_func(const String &p_rendering_driver, WindowMode p_window_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Point2i *p_position, const Size2i &p_resolution, Error &r_error) { - return memnew(DisplayServerWeb(p_rendering_driver, p_window_mode, p_vsync_mode, p_flags, p_position, p_resolution, r_error)); +DisplayServer *DisplayServerWeb::create_func(const String &p_rendering_driver, WindowMode p_window_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Point2i *p_position, const Size2i &p_resolution, int p_screen, Error &r_error) { + return memnew(DisplayServerWeb(p_rendering_driver, p_window_mode, p_vsync_mode, p_flags, p_position, p_resolution, p_screen, r_error)); } -DisplayServerWeb::DisplayServerWeb(const String &p_rendering_driver, WindowMode p_window_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Point2i *p_position, const Size2i &p_resolution, Error &r_error) { +DisplayServerWeb::DisplayServerWeb(const String &p_rendering_driver, WindowMode p_window_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Point2i *p_position, const Size2i &p_resolution, int p_screen, Error &r_error) { r_error = OK; // Always succeeds for now. + tts = GLOBAL_GET("audio/general/text_to_speech"); + // Ensure the canvas ID. godot_js_config_canvas_id_get(canvas_id, 256); @@ -758,10 +795,8 @@ DisplayServerWeb::DisplayServerWeb(const String &p_rendering_driver, WindowMode godot_js_os_request_quit_cb(request_quit_callback); #ifdef GLES3_ENABLED - // TODO "vulkan" defaults to webgl2 for now. - bool wants_webgl2 = p_rendering_driver == "opengl3" || p_rendering_driver == "vulkan"; - bool webgl2_init_failed = wants_webgl2 && !godot_js_display_has_webgl(2); - if (wants_webgl2 && !webgl2_init_failed) { + bool webgl2_inited = false; + if (godot_js_display_has_webgl(2)) { EmscriptenWebGLContextAttributes attributes; emscripten_webgl_init_context_attributes(&attributes); attributes.alpha = OS::get_singleton()->is_layered_allowed(); @@ -770,20 +805,19 @@ DisplayServerWeb::DisplayServerWeb(const String &p_rendering_driver, WindowMode attributes.explicitSwapControl = true; webgl_ctx = emscripten_webgl_create_context(canvas_id, &attributes); - if (emscripten_webgl_make_context_current(webgl_ctx) != EMSCRIPTEN_RESULT_SUCCESS) { - webgl2_init_failed = true; - } else { - if (!emscripten_webgl_enable_extension(webgl_ctx, "OVR_multiview2")) { - // @todo Should we log this? - } - RasterizerGLES3::make_current(); - } - } - if (webgl2_init_failed) { - OS::get_singleton()->alert("Your browser does not seem to support WebGL2. Please update your browser version.", - "Unable to initialize video driver"); + webgl2_inited = webgl_ctx && emscripten_webgl_make_context_current(webgl_ctx) == EMSCRIPTEN_RESULT_SUCCESS; } - if (!wants_webgl2 || webgl2_init_failed) { + if (webgl2_inited) { + if (!emscripten_webgl_enable_extension(webgl_ctx, "OVR_multiview2")) { + print_verbose("Failed to enable WebXR extension."); + } + RasterizerGLES3::make_current(); + + } else { + OS::get_singleton()->alert( + "Your browser seems not to support WebGL 2.\n\n" + "If possible, consider updating your browser version and video card drivers.", + "Unable to initialize WebGL 2 video driver"); RasterizerDummy::make_current(); } #else @@ -843,7 +877,7 @@ bool DisplayServerWeb::has_feature(Feature p_feature) const { case FEATURE_VIRTUAL_KEYBOARD: return godot_js_display_vk_available() != 0; case FEATURE_TEXT_TO_SPEECH: - return godot_js_display_tts_available() != 0; + return tts && (godot_js_display_tts_available() != 0); default: return false; } @@ -861,6 +895,10 @@ int DisplayServerWeb::get_screen_count() const { return 1; } +int DisplayServerWeb::get_primary_screen() const { + return 0; +} + Point2i DisplayServerWeb::screen_get_position(int p_screen) const { return Point2i(); // TODO offsetX/Y? } @@ -908,7 +946,7 @@ ObjectID DisplayServerWeb::window_get_attached_instance_id(WindowID p_window) co } void DisplayServerWeb::window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window) { - // Not supported. + rect_changed_callback = p_callable; } void DisplayServerWeb::window_set_window_event_callback(const Callable &p_callable, WindowID p_window) { @@ -940,7 +978,11 @@ void DisplayServerWeb::window_set_current_screen(int p_screen, WindowID p_window } Point2i DisplayServerWeb::window_get_position(WindowID p_window) const { - return Point2i(); // TODO Does this need implementation? + return Point2i(); +} + +Point2i DisplayServerWeb::window_get_position_with_decorations(WindowID p_window) const { + return Point2i(); } void DisplayServerWeb::window_set_position(const Point2i &p_position, WindowID p_window) { @@ -977,7 +1019,7 @@ Size2i DisplayServerWeb::window_get_size(WindowID p_window) const { return Size2i(size[0], size[1]); } -Size2i DisplayServerWeb::window_get_real_size(WindowID p_window) const { +Size2i DisplayServerWeb::window_get_size_with_decorations(WindowID p_window) const { return window_get_size(p_window); } @@ -1031,6 +1073,10 @@ void DisplayServerWeb::window_move_to_foreground(WindowID p_window) { // Not supported. } +bool DisplayServerWeb::window_is_focused(WindowID p_window) const { + return true; +} + bool DisplayServerWeb::window_can_draw(WindowID p_window) const { return true; } @@ -1039,6 +1085,10 @@ bool DisplayServerWeb::can_any_window_draw() const { return true; } +DisplayServer::VSyncMode DisplayServerWeb::window_get_vsync_mode(WindowID p_vsync_mode) const { + return DisplayServer::VSYNC_ENABLED; +} + void DisplayServerWeb::process_events() { Input::get_singleton()->flush_buffered_events(); if (godot_js_input_gamepad_sample() == OK) { diff --git a/platform/web/display_server_web.h b/platform/web/display_server_web.h index 3222e2483e..a4fd75f33b 100644 --- a/platform/web/display_server_web.h +++ b/platform/web/display_server_web.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* display_server_web.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* display_server_web.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 DISPLAY_SERVER_WEB_H #define DISPLAY_SERVER_WEB_H @@ -37,6 +37,8 @@ #include <emscripten/html5.h> class DisplayServerWeb : public DisplayServer { + // No need to register with GDCLASS, it's platform-specific and nothing is added. + private: struct JSTouchEvent { uint32_t identifier[32] = { 0 }; @@ -60,6 +62,7 @@ private: WindowMode window_mode = WINDOW_MODE_WINDOWED; ObjectID window_attached_instance_id = {}; + Callable rect_changed_callback; Callable window_event_callback; Callable input_event_callback; Callable input_text_callback; @@ -78,9 +81,10 @@ private: MouseButton last_click_button_index = MouseButton::NONE; bool swap_cancel_ok = false; + bool tts = false; // utilities - static void dom2godot_mod(Ref<InputEventWithModifiers> ev, int p_mod); + static void dom2godot_mod(Ref<InputEventWithModifiers> ev, int p_mod, Key p_keycode); static const char *godot2dom_cursor(DisplayServer::CursorShape p_shape); // events @@ -96,7 +100,7 @@ private: static void _js_utterance_callback(int p_event, int p_id, int p_pos); static Vector<String> get_rendering_drivers_func(); - static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_window_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error); + static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_window_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error); static void _dispatch_input_event(const Ref<InputEvent> &p_event); @@ -142,7 +146,7 @@ public: virtual Point2i mouse_get_position() const override; // touch - virtual bool screen_is_touchscreen(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; + virtual bool is_touchscreen_available() const override; // clipboard virtual void clipboard_set(const String &p_text) override; @@ -150,6 +154,7 @@ public: // screen virtual int get_screen_count() const override; + virtual int get_primary_screen() const override; virtual Point2i screen_get_position(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; virtual Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; virtual Rect2i screen_get_usable_rect(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; @@ -181,6 +186,7 @@ public: virtual void window_set_current_screen(int p_screen, WindowID p_window = MAIN_WINDOW_ID) override; virtual Point2i window_get_position(WindowID p_window = MAIN_WINDOW_ID) const override; + virtual Point2i window_get_position_with_decorations(WindowID p_window = MAIN_WINDOW_ID) const override; virtual void window_set_position(const Point2i &p_position, WindowID p_window = MAIN_WINDOW_ID) override; virtual void window_set_transient(WindowID p_window, WindowID p_parent) override; @@ -193,7 +199,7 @@ public: virtual void window_set_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID) override; virtual Size2i window_get_size(WindowID p_window = MAIN_WINDOW_ID) const override; - virtual Size2i window_get_real_size(WindowID p_window = MAIN_WINDOW_ID) const override; + virtual Size2i window_get_size_with_decorations(WindowID p_window = MAIN_WINDOW_ID) const override; virtual void window_set_mode(WindowMode p_mode, WindowID p_window = MAIN_WINDOW_ID) override; virtual WindowMode window_get_mode(WindowID p_window = MAIN_WINDOW_ID) const override; @@ -205,11 +211,14 @@ public: virtual void window_request_attention(WindowID p_window = MAIN_WINDOW_ID) override; virtual void window_move_to_foreground(WindowID p_window = MAIN_WINDOW_ID) override; + virtual bool window_is_focused(WindowID p_window = MAIN_WINDOW_ID) const override; virtual bool window_can_draw(WindowID p_window = MAIN_WINDOW_ID) const override; virtual bool can_any_window_draw() const override; + virtual DisplayServer::VSyncMode window_get_vsync_mode(WindowID p_vsync_mode) const override; + // events virtual void process_events() override; @@ -221,7 +230,7 @@ public: virtual void swap_buffers() override; static void register_web_driver(); - DisplayServerWeb(const String &p_rendering_driver, WindowMode p_window_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Point2i *p_position, const Size2i &p_resolution, Error &r_error); + DisplayServerWeb(const String &p_rendering_driver, WindowMode p_window_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Point2i *p_position, const Size2i &p_resolution, int p_screen, Error &r_error); ~DisplayServerWeb(); }; diff --git a/platform/web/doc_classes/EditorExportPlatformWeb.xml b/platform/web/doc_classes/EditorExportPlatformWeb.xml new file mode 100644 index 0000000000..6e5a2ac078 --- /dev/null +++ b/platform/web/doc_classes/EditorExportPlatformWeb.xml @@ -0,0 +1,54 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="EditorExportPlatformWeb" inherits="EditorExportPlatform" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> + <brief_description> + Exporter for the Web. + </brief_description> + <description> + </description> + <tutorials> + <link title="Exporting for the Web">$DOCS_URL/tutorials/export/exporting_for_web.html</link> + </tutorials> + <members> + <member name="custom_template/debug" type="String" setter="" getter=""> + Path to the custom export template. If left empty, default template is used. + </member> + <member name="custom_template/release" type="String" setter="" getter=""> + Path to the custom export template. If left empty, default template is used. + </member> + <member name="html/canvas_resize_policy" type="int" setter="" getter=""> + The canvas resize policy determines how the canvas should be resized by Godot. + </member> + <member name="html/custom_html_shell" type="String" setter="" getter=""> + </member> + <member name="html/experimental_virtual_keyboard" type="bool" setter="" getter=""> + </member> + <member name="html/export_icon" type="bool" setter="" getter=""> + </member> + <member name="html/focus_canvas_on_start" type="bool" setter="" getter=""> + </member> + <member name="html/head_include" type="String" setter="" getter=""> + </member> + <member name="progressive_web_app/background_color" type="Color" setter="" getter=""> + </member> + <member name="progressive_web_app/display" type="int" setter="" getter=""> + </member> + <member name="progressive_web_app/enabled" type="bool" setter="" getter=""> + </member> + <member name="progressive_web_app/icon_144x144" type="String" setter="" getter=""> + </member> + <member name="progressive_web_app/icon_180x180" type="String" setter="" getter=""> + </member> + <member name="progressive_web_app/icon_512x512" type="String" setter="" getter=""> + </member> + <member name="progressive_web_app/offline_page" type="String" setter="" getter=""> + </member> + <member name="progressive_web_app/orientation" type="int" setter="" getter=""> + </member> + <member name="variant/extensions_support" type="bool" setter="" getter=""> + </member> + <member name="vram_texture_compression/for_desktop" type="bool" setter="" getter=""> + </member> + <member name="vram_texture_compression/for_mobile" type="bool" setter="" getter=""> + </member> + </members> +</class> diff --git a/platform/web/dom_keys.inc b/platform/web/dom_keys.inc index 115b5479e4..cd94b779c0 100644 --- a/platform/web/dom_keys.inc +++ b/platform/web/dom_keys.inc @@ -1,40 +1,40 @@ -/*************************************************************************/ -/* dom_keys.inc */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* dom_keys.inc */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "core/os/keyboard.h" // See https://w3c.github.io/uievents-code/#code-value-tables Key dom_code2godot_scancode(EM_UTF8 const p_code[32], EM_UTF8 const p_key[32], bool p_physical) { -#define DOM2GODOT(p_str, p_godot_code) \ - if (memcmp((const void *)p_str, (void *)p_code, strlen(p_str) + 1) == 0) { \ - return Key::p_godot_code; \ +#define DOM2GODOT(p_str, p_godot_code) \ + if (memcmp((const void *)p_str, (void *)(p_physical ? p_code : p_key), strlen(p_str) + 1) == 0) { \ + return Key::p_godot_code; \ } // Numpad section. @@ -51,6 +51,7 @@ Key dom_code2godot_scancode(EM_UTF8 const p_code[32], EM_UTF8 const p_key[32], b DOM2GODOT("Numpad9", KP_9); DOM2GODOT("NumpadAdd", KP_ADD); DOM2GODOT("NumpadBackspace", BACKSPACE); + DOM2GODOT("Clear", CLEAR); // NumLock on macOS. DOM2GODOT("NumpadClear", CLEAR); DOM2GODOT("NumpadClearEntry", CLEAR); //DOM2GODOT("NumpadComma", UNKNOWN); @@ -70,35 +71,6 @@ Key dom_code2godot_scancode(EM_UTF8 const p_code[32], EM_UTF8 const p_key[32], b DOM2GODOT("NumpadStar", KP_MULTIPLY); // or ASTERISK ? DOM2GODOT("NumpadSubtract", KP_SUBTRACT); - // Printable ASCII. - if (!p_physical) { - uint8_t b0 = (uint8_t)p_key[0]; - uint8_t b1 = (uint8_t)p_key[1]; - uint8_t b2 = (uint8_t)p_key[2]; - if (b1 == 0 && b0 > 0x1F && b0 < 0x7F) { // ASCII. - if (b0 > 0x60 && b0 < 0x7B) { // Lowercase ASCII. - b0 -= 32; - } - return (Key)b0; - } - -#define _U_2BYTES_MASK 0xE0 -#define _U_2BYTES 0xC0 - // Latin-1 codes. - if (b2 == 0 && (b0 & _U_2BYTES_MASK) == _U_2BYTES) { // 2-bytes utf8, only known latin. - uint32_t key = ((b0 & ~_U_2BYTES_MASK) << 6) | (b1 & 0x3F); - if (key >= 0xA0 && key <= 0xDF) { - return (Key)key; - } - if (key >= 0xE0 && key <= 0xFF) { // Lowercase known latin. - key -= 0x20; - return (Key)key; - } - } -#undef _U_2BYTES_MASK -#undef _U_2BYTES - } - // Alphanumeric section. DOM2GODOT("Backquote", QUOTELEFT); DOM2GODOT("Backslash", BACKSLASH); @@ -154,16 +126,22 @@ Key dom_code2godot_scancode(EM_UTF8 const p_code[32], EM_UTF8 const p_key[32], b DOM2GODOT("Slash", SLASH); // Functional keys in the Alphanumeric section. + DOM2GODOT("Alt", ALT); DOM2GODOT("AltLeft", ALT); DOM2GODOT("AltRight", ALT); DOM2GODOT("Backspace", BACKSPACE); DOM2GODOT("CapsLock", CAPSLOCK); DOM2GODOT("ContextMenu", MENU); + DOM2GODOT("Control", CTRL); DOM2GODOT("ControlLeft", CTRL); DOM2GODOT("ControlRight", CTRL); DOM2GODOT("Enter", ENTER); - DOM2GODOT("MetaLeft", SUPER_L); - DOM2GODOT("MetaRight", SUPER_R); + DOM2GODOT("Meta", META); + DOM2GODOT("MetaLeft", META); + DOM2GODOT("MetaRight", META); + DOM2GODOT("OSLeft", META); // Command on macOS. + DOM2GODOT("OSRight", META); // Command on macOS. + DOM2GODOT("Shift", SHIFT); DOM2GODOT("ShiftLeft", SHIFT); DOM2GODOT("ShiftRight", SHIFT); DOM2GODOT("Space", SPACE); @@ -227,6 +205,21 @@ Key dom_code2godot_scancode(EM_UTF8 const p_code[32], EM_UTF8 const p_key[32], b DOM2GODOT("AudioVolumeMute", VOLUMEMUTE); DOM2GODOT("AudioVolumeUp", VOLUMEUP); //DOM2GODOT("WakeUp", UNKNOWN); - return Key::UNKNOWN; + + // Printable ASCII. + uint8_t b0 = (uint8_t)p_key[0]; + uint8_t b1 = (uint8_t)p_key[1]; + if (b0 >= 0x20 && b0 < 0x7F) { // ASCII. + if (b0 > 0x60 && b0 < 0x7B) { // Lowercase ASCII. + b0 -= 32; + } + return (Key)b0; + } else if (b0 == 0xC2 && b1 == 0xA5) { + return Key::YEN; + } else if (b0 == 0xC2 && b1 == 0xA7) { + return Key::SECTION; + } + + return Key::NONE; #undef DOM2GODOT } diff --git a/platform/web/export/editor_http_server.h b/platform/web/export/editor_http_server.h index fa0010ec8d..3f87288537 100644 --- a/platform/web/export/editor_http_server.h +++ b/platform/web/export/editor_http_server.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* editor_http_server.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* editor_http_server.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 WEB_EDITOR_HTTP_SERVER_H #define WEB_EDITOR_HTTP_SERVER_H @@ -205,8 +205,7 @@ public: if (tls.is_null()) { tls = Ref<StreamPeerTLS>(StreamPeerTLS::create()); peer = tls; - tls->set_blocking_handshake_enabled(false); - if (tls->accept_stream(tcp, key, cert) != OK) { + if (tls->accept_stream(tcp, TLSOptions::server(key, cert)) != OK) { _clear_client(); return; } diff --git a/platform/web/export/export.cpp b/platform/web/export/export.cpp index 4b4e8b2705..168310c078 100644 --- a/platform/web/export/export.cpp +++ b/platform/web/export/export.cpp @@ -1,38 +1,44 @@ -/*************************************************************************/ -/* export.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* export.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "export.h" -#include "editor/editor_settings.h" #include "export_plugin.h" +#include "editor/editor_settings.h" +#include "editor/export/editor_export.h" + +void register_web_exporter_types() { + GDREGISTER_VIRTUAL_CLASS(EditorExportPlatformWeb); +} + void register_web_exporter() { #ifndef ANDROID_ENABLED EDITOR_DEF("export/web/http_host", "localhost"); diff --git a/platform/web/export/export.h b/platform/web/export/export.h index 7947f292a4..da02bd8d93 100644 --- a/platform/web/export/export.h +++ b/platform/web/export/export.h @@ -1,36 +1,37 @@ -/*************************************************************************/ -/* export.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* export.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 WEB_EXPORT_H #define WEB_EXPORT_H +void register_web_exporter_types(); void register_web_exporter(); #endif // WEB_EXPORT_H diff --git a/platform/web/export/export_plugin.cpp b/platform/web/export/export_plugin.cpp index f59ac54f20..a398593f90 100644 --- a/platform/web/export/export_plugin.cpp +++ b/platform/web/export/export_plugin.cpp @@ -1,37 +1,47 @@ -/*************************************************************************/ -/* export_plugin.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* export_plugin.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "export_plugin.h" +#include "../logo_svg.gen.h" +#include "../run_icon_svg.gen.h" + #include "core/config/project_settings.h" +#include "editor/editor_scale.h" #include "editor/editor_settings.h" +#include "editor/export/editor_export.h" + +#include "modules/modules_enabled.gen.h" // For svg. +#ifdef MODULE_SVG_ENABLED +#include "modules/svg/image_loader_svg.h" +#endif Error EditorExportPlatformWeb::_extract_template(const String &p_template, const String &p_dir, const String &p_name, bool pwa) { Ref<FileAccess> io_fa; @@ -133,7 +143,7 @@ void EditorExportPlatformWeb::_fix_html(Vector<uint8_t> &p_html, const Ref<Edito config["canvasResizePolicy"] = p_preset->get("html/canvas_resize_policy"); config["experimentalVK"] = p_preset->get("html/experimental_virtual_keyboard"); config["focusCanvas"] = p_preset->get("html/focus_canvas_on_start"); - config["gdnativeLibs"] = libs; + config["gdextensionLibs"] = libs; config["executable"] = p_name; config["args"] = args; config["fileSizes"] = p_file_sizes; @@ -153,7 +163,7 @@ void EditorExportPlatformWeb::_fix_html(Vector<uint8_t> &p_html, const Ref<Edito const String custom_head_include = p_preset->get("html/head_include"); HashMap<String, String> replaces; replaces["$GODOT_URL"] = p_name + ".js"; - replaces["$GODOT_PROJECT_NAME"] = ProjectSettings::get_singleton()->get_setting("application/config/name"); + replaces["$GODOT_PROJECT_NAME"] = GLOBAL_GET("application/config/name"); replaces["$GODOT_HEAD_INCLUDE"] = head_include + custom_head_include; replaces["$GODOT_CONFIG"] = str_config; _replace_strings(replaces, p_html); @@ -193,7 +203,7 @@ Error EditorExportPlatformWeb::_add_manifest_icon(const String &p_path, const St } Error EditorExportPlatformWeb::_build_pwa(const Ref<EditorExportPreset> &p_preset, const String p_path, const Vector<SharedObject> &p_shared_objects) { - String proj_name = ProjectSettings::get_singleton()->get_setting("application/config/name"); + String proj_name = GLOBAL_GET("application/config/name"); if (proj_name.is_empty()) { proj_name = "Godot Game"; } @@ -312,7 +322,7 @@ void EditorExportPlatformWeb::get_preset_features(const Ref<EditorExportPreset> r_features->push_back("wasm32"); } -void EditorExportPlatformWeb::get_export_options(List<ExportOption> *r_options) { +void EditorExportPlatformWeb::get_export_options(List<ExportOption> *r_options) const { 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"), "")); @@ -648,22 +658,37 @@ void EditorExportPlatformWeb::_server_thread_poll(void *data) { } EditorExportPlatformWeb::EditorExportPlatformWeb() { - server.instantiate(); - server_thread.start(_server_thread_poll, this); + if (EditorNode::get_singleton()) { + server.instantiate(); + server_thread.start(_server_thread_poll, this); - logo = ImageTexture::create_from_image(memnew(Image(_web_logo))); - run_icon = ImageTexture::create_from_image(memnew(Image(_web_run_icon))); +#ifdef MODULE_SVG_ENABLED + Ref<Image> img = memnew(Image); + const bool upsample = !Math::is_equal_approx(Math::round(EDSCALE), EDSCALE); - Ref<Theme> theme = EditorNode::get_singleton()->get_editor_theme(); - if (theme.is_valid()) { - stop_icon = theme->get_icon(SNAME("Stop"), SNAME("EditorIcons")); - } else { - stop_icon.instantiate(); + ImageLoaderSVG img_loader; + img_loader.create_image_from_string(img, _web_logo_svg, EDSCALE, upsample, false); + logo = ImageTexture::create_from_image(img); + + img_loader.create_image_from_string(img, _web_run_icon_svg, EDSCALE, upsample, false); + run_icon = ImageTexture::create_from_image(img); +#endif + + Ref<Theme> theme = EditorNode::get_singleton()->get_editor_theme(); + if (theme.is_valid()) { + stop_icon = theme->get_icon(SNAME("Stop"), SNAME("EditorIcons")); + } else { + stop_icon.instantiate(); + } } } EditorExportPlatformWeb::~EditorExportPlatformWeb() { - server->stop(); + if (server.is_valid()) { + server->stop(); + } server_quit = true; - server_thread.wait_to_finish(); + if (server_thread.is_started()) { + server_thread.wait_to_finish(); + } } diff --git a/platform/web/export/export_plugin.h b/platform/web/export/export_plugin.h index f11e38df09..a1d3fed2f3 100644 --- a/platform/web/export/export_plugin.h +++ b/platform/web/export/export_plugin.h @@ -1,36 +1,38 @@ -/*************************************************************************/ -/* export_plugin.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* export_plugin.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 WEB_EXPORT_PLUGIN_H #define WEB_EXPORT_PLUGIN_H +#include "editor_http_server.h" + #include "core/config/project_settings.h" #include "core/io/image_loader.h" #include "core/io/stream_peer_tls.h" @@ -39,10 +41,6 @@ #include "editor/editor_node.h" #include "editor/export/editor_export_platform.h" #include "main/splash.gen.h" -#include "platform/web/logo.gen.h" -#include "platform/web/run_icon.gen.h" - -#include "editor_http_server.h" class EditorExportPlatformWeb : public EditorExportPlatform { GDCLASS(EditorExportPlatformWeb, EditorExportPlatform); @@ -102,7 +100,7 @@ class EditorExportPlatformWeb : public EditorExportPlatform { public: virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const override; - virtual void get_export_options(List<ExportOption> *r_options) override; + virtual void get_export_options(List<ExportOption> *r_options) const override; virtual String get_name() const override; virtual String get_os_name() const override; diff --git a/platform/web/godot_audio.h b/platform/web/godot_audio.h index 3855b7301e..a32d5acd97 100644 --- a/platform/web/godot_audio.h +++ b/platform/web/godot_audio.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* godot_audio.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* godot_audio.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 GODOT_AUDIO_H #define GODOT_AUDIO_H @@ -35,7 +35,8 @@ extern "C" { #endif -#include "stddef.h" +#include <stddef.h> +#include <stdint.h> extern int godot_audio_is_available(); extern int godot_audio_has_worklet(); @@ -43,8 +44,8 @@ extern int godot_audio_has_script_processor(); extern int godot_audio_init(int *p_mix_rate, int p_latency, void (*_state_cb)(int), void (*_latency_cb)(float)); extern void godot_audio_resume(); -extern int godot_audio_capture_start(); -extern void godot_audio_capture_stop(); +extern int godot_audio_input_start(); +extern void godot_audio_input_stop(); // Worklet typedef int32_t GodotAudioState[4]; diff --git a/platform/web/godot_js.h b/platform/web/godot_js.h index a323f2d157..3341cf8a67 100644 --- a/platform/web/godot_js.h +++ b/platform/web/godot_js.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* godot_js.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* godot_js.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 GODOT_JS_H #define GODOT_JS_H @@ -35,7 +35,7 @@ extern "C" { #endif -#include "stddef.h" +#include <stddef.h> // Config extern void godot_js_config_locale_get(char *p_ptr, int p_ptr_max); @@ -49,6 +49,7 @@ extern void godot_js_os_fs_sync(void (*p_callback)()); extern int godot_js_os_execute(const char *p_json); extern void godot_js_os_shell_open(const char *p_uri); extern int godot_js_os_hw_concurrency_get(); +extern int godot_js_os_has_feature(const char *p_ftr); extern int godot_js_pwa_cb(void (*p_callback)()); extern int godot_js_pwa_update(); diff --git a/platform/web/godot_webgl2.h b/platform/web/godot_webgl2.h index ae6b23ae18..d2f46e125e 100644 --- a/platform/web/godot_webgl2.h +++ b/platform/web/godot_webgl2.h @@ -1,38 +1,38 @@ -/*************************************************************************/ -/* godot_webgl2.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* godot_webgl2.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 GODOT_WEBGL2_H #define GODOT_WEBGL2_H -#include "GLES3/gl3.h" -#include "webgl/webgl2.h" +#include <GLES3/gl3.h> +#include <webgl/webgl2.h> #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR 0x9630 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR 0x9632 diff --git a/platform/web/http_client_web.cpp b/platform/web/http_client_web.cpp index d045275826..3e4ba5a2ae 100644 --- a/platform/web/http_client_web.cpp +++ b/platform/web/http_client_web.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* http_client_web.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* http_client_web.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "http_client_web.h" @@ -37,20 +37,20 @@ void HTTPClientWeb::_parse_headers(int p_len, const char **p_headers, void *p_re } } -Error HTTPClientWeb::connect_to_host(const String &p_host, int p_port, bool p_tls, bool p_verify_host) { +Error HTTPClientWeb::connect_to_host(const String &p_host, int p_port, Ref<TLSOptions> p_tls_options) { + ERR_FAIL_COND_V(p_tls_options.is_valid() && p_tls_options->is_server(), ERR_INVALID_PARAMETER); + close(); - if (p_tls && !p_verify_host) { - WARN_PRINT("Disabling HTTPClientWeb's host verification is not supported for the Web platform, host will be verified"); - } port = p_port; - use_tls = p_tls; + use_tls = p_tls_options.is_valid(); host = p_host; String host_lower = host.to_lower(); if (host_lower.begins_with("http://")) { host = host.substr(7, host.length() - 7); + use_tls = false; } else if (host_lower.begins_with("https://")) { use_tls = true; host = host.substr(8, host.length() - 8); diff --git a/platform/web/http_client_web.h b/platform/web/http_client_web.h index 5059b4693e..bb9672ab82 100644 --- a/platform/web/http_client_web.h +++ b/platform/web/http_client_web.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* http_client_web.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* http_client_web.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 HTTP_CLIENT_WEB_H #define HTTP_CLIENT_WEB_H @@ -37,7 +37,7 @@ extern "C" { #endif -#include "stddef.h" +#include <stddef.h> typedef enum { GODOT_JS_FETCH_STATE_REQUESTING = 0, @@ -86,7 +86,7 @@ public: Error request(Method p_method, const String &p_url, const Vector<String> &p_headers, const uint8_t *p_body, int p_body_size) override; - Error connect_to_host(const String &p_host, int p_port = -1, bool p_tls = false, bool p_verify_host = true) override; + Error connect_to_host(const String &p_host, int p_port = -1, Ref<TLSOptions> p_tls_options = Ref<TLSOptions>()) override; void set_connection(const Ref<StreamPeer> &p_connection) override; Ref<StreamPeer> get_connection() const override; void close() override; diff --git a/platform/web/javascript_bridge_singleton.cpp b/platform/web/javascript_bridge_singleton.cpp index 69cd0cece1..45bce1b480 100644 --- a/platform/web/javascript_bridge_singleton.cpp +++ b/platform/web/javascript_bridge_singleton.cpp @@ -1,38 +1,39 @@ -/*************************************************************************/ -/* javascript_bridge_singleton.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* javascript_bridge_singleton.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "api/javascript_bridge_singleton.h" -#include "emscripten.h" #include "os_web.h" +#include <emscripten.h> + extern "C" { extern void godot_js_os_download_buffer(const uint8_t *p_buf, int p_buf_size, const char *p_name, const char *p_mime); } @@ -352,6 +353,7 @@ Variant JavaScriptBridge::eval(const String &p_code, bool p_use_global_exec_cont return Variant(); } } + #endif // JAVASCRIPT_EVAL_ENABLED void JavaScriptBridge::download_buffer(Vector<uint8_t> p_arr, const String &p_name, const String &p_mime) { @@ -361,6 +363,11 @@ void JavaScriptBridge::download_buffer(Vector<uint8_t> p_arr, const String &p_na bool JavaScriptBridge::pwa_needs_update() const { return OS_Web::get_singleton()->pwa_needs_update(); } + Error JavaScriptBridge::pwa_update() { return OS_Web::get_singleton()->pwa_update(); } + +void JavaScriptBridge::force_fs_sync() { + OS_Web::get_singleton()->force_fs_sync(); +} diff --git a/platform/web/js/engine/config.js b/platform/web/js/engine/config.js index 41be7b2512..6a30c253fb 100644 --- a/platform/web/js/engine/config.js +++ b/platform/web/js/engine/config.js @@ -127,7 +127,7 @@ const InternalConfig = function (initConfig) { // eslint-disable-line no-unused- * @ignore * @type {Array.<string>} */ - gdnativeLibs: [], + gdextensionLibs: [], /** * @ignore * @type {Array.<string>} @@ -257,7 +257,7 @@ const InternalConfig = function (initConfig) { // eslint-disable-line no-unused- this.experimentalVK = parse('experimentalVK', this.experimentalVK); this.focusCanvas = parse('focusCanvas', this.focusCanvas); this.serviceWorker = parse('serviceWorker', this.serviceWorker); - this.gdnativeLibs = parse('gdnativeLibs', this.gdnativeLibs); + this.gdextensionLibs = parse('gdextensionLibs', this.gdextensionLibs); this.fileSizes = parse('fileSizes', this.fileSizes); this.args = parse('args', this.args); this.onExecute = parse('onExecute', this.onExecute); @@ -275,7 +275,7 @@ const InternalConfig = function (initConfig) { // eslint-disable-line no-unused- 'print': this.onPrint, 'printErr': this.onPrintError, 'thisProgram': this.executable, - 'noExitRuntime': true, + 'noExitRuntime': false, 'dynamicLibraries': [`${loadPath}.side.wasm`], 'instantiateWasm': function (imports, onSuccess) { function done(result) { diff --git a/platform/web/js/engine/engine.js b/platform/web/js/engine/engine.js index 9227aa1f05..fb80bd55e1 100644 --- a/platform/web/js/engine/engine.js +++ b/platform/web/js/engine/engine.js @@ -162,9 +162,9 @@ const Engine = (function () { // Godot configuration. me.rtenv['initConfig'](config); - // Preload GDNative libraries. + // Preload GDExtension libraries. const libs = []; - me.config.gdnativeLibs.forEach(function (lib) { + me.config.gdextensionLibs.forEach(function (lib) { libs.push(me.rtenv['loadDynamicLibrary'](lib, { 'loadAsync': true })); }); return Promise.all(libs).then(function () { diff --git a/platform/web/js/engine/features.js b/platform/web/js/engine/features.js index f91a4eff81..b7c6c9d445 100644 --- a/platform/web/js/engine/features.js +++ b/platform/web/js/engine/features.js @@ -76,19 +76,19 @@ const Features = { // eslint-disable-line no-unused-vars getMissingFeatures: function () { const missing = []; if (!Features.isWebGLAvailable(2)) { - missing.push('WebGL2'); + missing.push('WebGL2 - Check web browser configuration and hardware support'); } if (!Features.isFetchAvailable()) { - missing.push('Fetch'); + missing.push('Fetch - Check web browser version'); } if (!Features.isSecureContext()) { - missing.push('Secure Context'); + missing.push('Secure Context - Check web server configuration (use HTTPS)'); } if (!Features.isCrossOriginIsolated()) { - missing.push('Cross Origin Isolation'); + missing.push('Cross Origin Isolation - Check web server configuration (send correct headers)'); } if (!Features.isSharedArrayBufferAvailable()) { - missing.push('SharedArrayBuffer'); + missing.push('SharedArrayBuffer - Check web server configuration (send correct headers)'); } // Audio is normally optional since we have a dummy fallback. return missing; diff --git a/platform/web/js/libs/audio.worklet.js b/platform/web/js/libs/audio.worklet.js index daf5c9ef12..89b581b3d6 100644 --- a/platform/web/js/libs/audio.worklet.js +++ b/platform/web/js/libs/audio.worklet.js @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* audio.worklet.js */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* audio.worklet.js */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ class RingBuffer { constructor(p_buffer, p_state, p_threads) { diff --git a/platform/web/js/libs/library_godot_audio.js b/platform/web/js/libs/library_godot_audio.js index 68e100cca0..1993d66310 100644 --- a/platform/web/js/libs/library_godot_audio.js +++ b/platform/web/js/libs/library_godot_audio.js @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* library_godot_audio.js */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* library_godot_audio.js */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ const GodotAudio = { $GodotAudio__deps: ['$GodotRuntime', '$GodotOS'], @@ -186,17 +186,17 @@ const GodotAudio = { } }, - godot_audio_capture_start__proxy: 'sync', - godot_audio_capture_start__sig: 'i', - godot_audio_capture_start: function () { + godot_audio_input_start__proxy: 'sync', + godot_audio_input_start__sig: 'i', + godot_audio_input_start: function () { return GodotAudio.create_input(function (input) { input.connect(GodotAudio.driver.get_node()); }); }, - godot_audio_capture_stop__proxy: 'sync', - godot_audio_capture_stop__sig: 'v', - godot_audio_capture_stop: function () { + godot_audio_input_stop__proxy: 'sync', + godot_audio_input_stop__sig: 'v', + godot_audio_input_stop: function () { if (GodotAudio.input) { const tracks = GodotAudio.input['mediaStream']['getTracks'](); for (let i = 0; i < tracks.length; i++) { diff --git a/platform/web/js/libs/library_godot_display.js b/platform/web/js/libs/library_godot_display.js index 39c8569655..23cbc67c16 100644 --- a/platform/web/js/libs/library_godot_display.js +++ b/platform/web/js/libs/library_godot_display.js @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* library_godot_display.js */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* library_godot_display.js */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ const GodotDisplayVK = { diff --git a/platform/web/js/libs/library_godot_fetch.js b/platform/web/js/libs/library_godot_fetch.js index 285e50a035..1bb48bfd6a 100644 --- a/platform/web/js/libs/library_godot_fetch.js +++ b/platform/web/js/libs/library_godot_fetch.js @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* library_godot_fetch.js */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* library_godot_fetch.js */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ const GodotFetch = { $GodotFetch__deps: ['$IDHandler', '$GodotRuntime'], @@ -50,17 +50,22 @@ const GodotFetch = { return; } let chunked = false; + let bodySize = -1; response.headers.forEach(function (value, header) { const v = value.toLowerCase().trim(); const h = header.toLowerCase().trim(); if (h === 'transfer-encoding' && v === 'chunked') { chunked = true; } + if (h === 'content-length') { + bodySize = parseInt(v, 10); + } }); obj.status = response.status; obj.response = response; obj.reader = response.body.getReader(); obj.chunked = chunked; + obj.bodySize = bodySize; }, onerror: function (id, err) { diff --git a/platform/web/js/libs/library_godot_input.js b/platform/web/js/libs/library_godot_input.js index 51571d64a2..1b221e78b3 100644 --- a/platform/web/js/libs/library_godot_input.js +++ b/platform/web/js/libs/library_godot_input.js @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* library_godot_input.js */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* library_godot_input.js */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ /* * Gamepad API helper. diff --git a/platform/web/js/libs/library_godot_javascript_singleton.js b/platform/web/js/libs/library_godot_javascript_singleton.js index c86cbbae45..dafc01a1fd 100644 --- a/platform/web/js/libs/library_godot_javascript_singleton.js +++ b/platform/web/js/libs/library_godot_javascript_singleton.js @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* library_godot_eval.js */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* library_godot_javascript_singleton.js */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ const GodotJSWrapper = { diff --git a/platform/web/js/libs/library_godot_os.js b/platform/web/js/libs/library_godot_os.js index ce64fb98c0..00ae399583 100644 --- a/platform/web/js/libs/library_godot_os.js +++ b/platform/web/js/libs/library_godot_os.js @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* library_godot_os.js */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* library_godot_os.js */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ const IDHandler = { $IDHandler: { @@ -291,6 +291,28 @@ const GodotOS = { }); }, + godot_js_os_has_feature__sig: 'ii', + godot_js_os_has_feature: function (p_ftr) { + const ftr = GodotRuntime.parseString(p_ftr); + const ua = navigator.userAgent; + if (ftr === 'web_macos') { + return (ua.indexOf('Mac') !== -1) ? 1 : 0; + } + if (ftr === 'web_windows') { + return (ua.indexOf('Windows') !== -1) ? 1 : 0; + } + if (ftr === 'web_android') { + return (ua.indexOf('Android') !== -1) ? 1 : 0; + } + if (ftr === 'web_ios') { + return ((ua.indexOf('iPhone') !== -1) || (ua.indexOf('iPad') !== -1) || (ua.indexOf('iPod') !== -1)) ? 1 : 0; + } + if (ftr === 'web_linuxbsd') { + return ((ua.indexOf('CrOS') !== -1) || (ua.indexOf('BSD') !== -1) || (ua.indexOf('Linux') !== -1) || (ua.indexOf('X11') !== -1)) ? 1 : 0; + } + return 0; + }, + godot_js_os_execute__sig: 'ii', godot_js_os_execute: function (p_json) { const json_args = GodotRuntime.parseString(p_json); diff --git a/platform/web/js/libs/library_godot_runtime.js b/platform/web/js/libs/library_godot_runtime.js index e2f7c8dca6..73581759b0 100644 --- a/platform/web/js/libs/library_godot_runtime.js +++ b/platform/web/js/libs/library_godot_runtime.js @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* library_godot_runtime.js */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* library_godot_runtime.js */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ const GodotRuntime = { $GodotRuntime: { diff --git a/platform/web/js/libs/library_godot_webgl2.externs.js b/platform/web/js/libs/library_godot_webgl2.externs.js new file mode 100644 index 0000000000..18d8d0815a --- /dev/null +++ b/platform/web/js/libs/library_godot_webgl2.externs.js @@ -0,0 +1,36 @@ + +/** + * @constructor OVR_multiview2 + */ +function OVR_multiview2() {} + +/** + * @type {number} + */ +OVR_multiview2.prototype.FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR; + +/** + * @type {number} + */ +OVR_multiview2.prototype.FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR; + +/** + * @type {number} + */ +OVR_multiview2.prototype.MAX_VIEWS_OVR; + +/** + * @type {number} + */ +OVR_multiview2.prototype.FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR; + +/** + * @param {number} target + * @param {number} attachment + * @param {WebGLTexture} texture + * @param {number} level + * @param {number} baseViewIndex + * @param {number} numViews + * @return {void} + */ +OVR_multiview2.prototype.framebufferTextureMultiviewOVR = function(target, attachment, texture, level, baseViewIndex, numViews) {}; diff --git a/platform/web/js/libs/library_godot_webgl2.js b/platform/web/js/libs/library_godot_webgl2.js index 365f712be7..8afbdf9e78 100644 --- a/platform/web/js/libs/library_godot_webgl2.js +++ b/platform/web/js/libs/library_godot_webgl2.js @@ -1,32 +1,33 @@ -/*************************************************************************/ +/**************************************************************************/ /* library_godot_webgl2.js */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ + const GodotWebGL2 = { $GodotWebGL2__deps: ['$GL', '$GodotRuntime'], $GodotWebGL2: {}, @@ -37,14 +38,15 @@ const GodotWebGL2 = { godot_webgl2_glFramebufferTextureMultiviewOVR: function (target, attachment, texture, level, base_view_index, num_views) { const context = GL.currentContext; if (typeof context.multiviewExt === 'undefined') { - const ext = context.GLctx.getExtension('OVR_multiview2'); + const /** OVR_multiview2 */ ext = context.GLctx.getExtension('OVR_multiview2'); if (!ext) { console.error('Trying to call glFramebufferTextureMultiviewOVR() without the OVR_multiview2 extension'); return; } context.multiviewExt = ext; } - context.multiviewExt.framebufferTextureMultiviewOVR(target, attachment, GL.textures[texture], level, base_view_index, num_views); + const /** OVR_multiview2 */ ext = context.multiviewExt; + ext.framebufferTextureMultiviewOVR(target, attachment, GL.textures[texture], level, base_view_index, num_views); }, }; diff --git a/platform/web/logo.png b/platform/web/logo.png Binary files differdeleted file mode 100644 index c046d87dc4..0000000000 --- a/platform/web/logo.png +++ /dev/null diff --git a/platform/web/logo.svg b/platform/web/logo.svg new file mode 100644 index 0000000000..567b6f3c77 --- /dev/null +++ b/platform/web/logo.svg @@ -0,0 +1 @@ +<svg height="32" width="32" xmlns="http://www.w3.org/2000/svg"><path d="M7 5h18v21H7z" fill="#fff"/><path d="M3.143 1 5.48 27.504 15.967 31l10.553-3.496L28.857 1zM23.78 9.565H11.473l.275 3.308h11.759l-.911 9.937-6.556 1.808v.02h-.073l-6.61-1.828-.402-5.076h3.195l.234 2.552 3.583.97 3.595-.97.402-4.165H8.788L7.93 6.37h16.145z" fill="#eb6428"/></svg> diff --git a/platform/web/os_web.cpp b/platform/web/os_web.cpp index 07c53e51d0..5115ff50da 100644 --- a/platform/web/os_web.cpp +++ b/platform/web/os_web.cpp @@ -1,40 +1,44 @@ -/*************************************************************************/ -/* os_web.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* os_web.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "os_web.h" +#include "api/javascript_bridge_singleton.h" +#include "display_server_web.h" +#include "godot_js.h" + +#include "core/config/project_settings.h" #include "core/debugger/engine_debugger.h" #include "drivers/unix/dir_access_unix.h" #include "drivers/unix/file_access_unix.h" #include "main/main.h" -#include "platform/web/display_server_web.h" #include "modules/modules_enabled.gen.h" // For websocket. @@ -42,9 +46,6 @@ #include <emscripten.h> #include <stdlib.h> -#include "api/javascript_bridge_singleton.h" -#include "godot_js.h" - void OS_Web::alert(const String &p_alert, const String &p_title) { godot_js_display_alert(p_alert.utf8().get_data()); } @@ -135,6 +136,9 @@ bool OS_Web::_check_internal_feature_support(const String &p_feature) { if (p_feature == "web") { return true; } + if (godot_js_os_has_feature(p_feature.utf8().get_data())) { + return true; + } return false; } @@ -157,7 +161,22 @@ void OS_Web::vibrate_handheld(int p_duration_ms) { } String OS_Web::get_user_data_dir() const { - return "/userfs"; + String userfs = "/userfs"; + String appname = get_safe_dir_name(GLOBAL_GET("application/config/name")); + if (!appname.is_empty()) { + bool use_custom_dir = GLOBAL_GET("application/config/use_custom_user_dir"); + if (use_custom_dir) { + String custom_dir = get_safe_dir_name(GLOBAL_GET("application/config/custom_user_dir_name"), true); + if (custom_dir.is_empty()) { + custom_dir = appname; + } + return userfs.path_join(custom_dir).replace("\\", "/"); + } else { + return userfs.path_join(get_godot_dir_name()).path_join("app_userdata").path_join(appname).replace("\\", "/"); + } + } + + return userfs.path_join(get_godot_dir_name()).path_join("app_userdata").path_join("[unnamed project]"); } String OS_Web::get_cache_path() const { @@ -196,6 +215,12 @@ void OS_Web::update_pwa_state_callback() { } } +void OS_Web::force_fs_sync() { + if (is_userfs_persistent()) { + idb_needs_sync = true; + } +} + Error OS_Web::pwa_update() { return godot_js_pwa_update() ? FAILED : OK; } diff --git a/platform/web/os_web.h b/platform/web/os_web.h index 64f3a4d133..b9570f9ca1 100644 --- a/platform/web/os_web.h +++ b/platform/web/os_web.h @@ -1,37 +1,38 @@ -/*************************************************************************/ -/* os_web.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* os_web.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 OS_WEB_H #define OS_WEB_H #include "audio_driver_web.h" + #include "core/input/input.h" #include "drivers/unix/os_unix.h" #include "servers/audio_server.h" @@ -69,6 +70,7 @@ public: bool pwa_needs_update() const { return pwa_is_waiting; } Error pwa_update(); + void force_fs_sync(); void initialize_joypads() override; diff --git a/platform/web/package-lock.json b/platform/web/package-lock.json index e1428546c6..4399e8243c 100644 --- a/platform/web/package-lock.json +++ b/platform/web/package-lock.json @@ -1529,9 +1529,9 @@ "dev": true }, "node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, "dependencies": { "minimist": "^1.2.0" @@ -3662,9 +3662,9 @@ "dev": true }, "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, "requires": { "minimist": "^1.2.0" diff --git a/platform/web/platform_config.h b/platform/web/platform_config.h index 5e48992af8..78deaadcfd 100644 --- a/platform/web/platform_config.h +++ b/platform/web/platform_config.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* platform_config.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* platform_config.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 <alloca.h> diff --git a/platform/web/run_icon.png b/platform/web/run_icon.png Binary files differdeleted file mode 100644 index 574abb0150..0000000000 --- a/platform/web/run_icon.png +++ /dev/null diff --git a/platform/web/run_icon.svg b/platform/web/run_icon.svg new file mode 100644 index 0000000000..494f53cb90 --- /dev/null +++ b/platform/web/run_icon.svg @@ -0,0 +1 @@ +<svg height="16" width="16" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><path d="M3.143 1 5.48 27.504 15.967 31l10.553-3.496L28.857 1ZM23.78 9.565H11.473l.275 3.308h11.759l-.911 9.937-6.556 1.808v.02h-.073l-6.61-1.828-.402-5.076h3.195l.234 2.552 3.583.97 3.595-.97.402-4.165H8.788L7.93 6.37h16.145Z" fill="#eb6428" style="fill:#e0e0e0;fill-opacity:1" transform="translate(.586 .586) scale(.46337)"/></svg> diff --git a/platform/web/web_main.cpp b/platform/web/web_main.cpp index a76b98f4e9..f199f8ffd8 100644 --- a/platform/web/web_main.cpp +++ b/platform/web/web_main.cpp @@ -1,70 +1,65 @@ -/*************************************************************************/ -/* web_main.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* web_main.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "display_server_web.h" +#include "godot_js.h" +#include "os_web.h" #include "core/config/engine.h" #include "core/io/resource_loader.h" #include "main/main.h" -#include "platform/web/display_server_web.h" -#include "platform/web/os_web.h" #include <emscripten/emscripten.h> #include <stdlib.h> -#include "godot_js.h" - static OS_Web *os = nullptr; static uint64_t target_ticks = 0; +static bool main_started = false; +static bool shutdown_complete = false; void exit_callback() { - emscripten_cancel_main_loop(); // After this, we can exit! - Main::cleanup(); + if (!shutdown_complete) { + return; // Still waiting. + } + if (main_started) { + Main::cleanup(); + main_started = false; + } int exit_code = OS_Web::get_singleton()->get_exit_code(); memdelete(os); os = nullptr; - emscripten_force_exit(exit_code); // No matter that we call cancel_main_loop, regular "exit" will not work, forcing. + emscripten_force_exit(exit_code); // Exit runtime. } void cleanup_after_sync() { - emscripten_set_main_loop(exit_callback, -1, false); -} - -void early_cleanup() { - emscripten_cancel_main_loop(); // After this, we can exit! - int exit_code = OS_Web::get_singleton()->get_exit_code(); - memdelete(os); - os = nullptr; - emscripten_force_exit(exit_code); // No matter that we call cancel_main_loop, regular "exit" will not work, forcing. -} - -void early_cleanup_sync() { - emscripten_set_main_loop(early_cleanup, -1, false); + shutdown_complete = true; } void main_loop_callback() { @@ -87,7 +82,8 @@ void main_loop_callback() { target_ticks += (uint64_t)(1000000 / max_fps); } if (os->main_loop_iterate()) { - emscripten_cancel_main_loop(); // Cancel current loop and wait for cleanup_after_sync. + emscripten_cancel_main_loop(); // Cancel current loop and set the cleanup one. + emscripten_set_main_loop(exit_callback, -1, false); godot_js_os_finish_async(cleanup_after_sync); } } @@ -109,10 +105,14 @@ extern EMSCRIPTEN_KEEPALIVE int godot_web_main(int argc, char *argv[]) { } os->set_exit_code(exit_code); // Will only exit after sync. - godot_js_os_finish_async(early_cleanup_sync); + emscripten_set_main_loop(exit_callback, -1, false); + godot_js_os_finish_async(cleanup_after_sync); return exit_code; } + os->set_exit_code(0); + main_started = true; + // Ease up compatibility. ResourceLoader::set_abort_on_missing_resources(false); diff --git a/platform/web/web_runtime.cpp b/platform/web/web_runtime.cpp index 93a1745a83..3c014b36a1 100644 --- a/platform/web/web_runtime.cpp +++ b/platform/web/web_runtime.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* web_runtime.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* web_runtime.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ extern int godot_web_main(int argc, char *argv[]); diff --git a/platform/windows/README.md b/platform/windows/README.md index c04032ae1d..bda9ddd924 100644 --- a/platform/windows/README.md +++ b/platform/windows/README.md @@ -7,9 +7,9 @@ used by this platform. ## Documentation -- [Compiling for Windows](https://docs.godotengine.org/en/latest/development/compiling/compiling_for_windows.html) +- [Compiling for Windows](https://docs.godotengine.org/en/latest/contributing/development/compiling/compiling_for_windows.html) - Instructions on building this platform port from source. - [Exporting for Windows](https://docs.godotengine.org/en/latest/tutorials/export/exporting_for_windows.html) - Instructions on using the compiled export templates to export a project. -- [Changing application icon for Windows](https://docs.godotengine.org/en/stable/tutorials/export/changing_application_icon_for_windows.html) +- [Changing application icon for Windows](https://docs.godotengine.org/en/latest/tutorials/export/changing_application_icon_for_windows.html) - Instructions on using a custom icon for the exported project executable. diff --git a/platform/windows/SCsub b/platform/windows/SCsub index 7e412b140f..efbb47d965 100644 --- a/platform/windows/SCsub +++ b/platform/windows/SCsub @@ -19,19 +19,44 @@ common_win = [ "gl_manager_windows.cpp", ] +common_win_wrap = [ + "console_wrapper_windows.cpp", +] + res_file = "godot_res.rc" res_target = "godot_res" + env["OBJSUFFIX"] res_obj = env.RES(res_target, res_file) prog = env.add_program("#bin/godot", common_win + res_obj, PROGSUFFIX=env["PROGSUFFIX"]) +# Build console wrapper app. +if env["windows_subsystem"] == "gui": + env_wrap = env.Clone() + res_wrap_file = "godot_res_wrap.rc" + res_wrap_target = "godot_res_wrap" + env["OBJSUFFIX"] + res_wrap_obj = env_wrap.RES(res_wrap_target, res_wrap_file) + + if env.msvc: + env_wrap.Append(LINKFLAGS=["/SUBSYSTEM:CONSOLE"]) + env_wrap.Append(LINKFLAGS=["version.lib"]) + else: + env_wrap.Append(LINKFLAGS=["-Wl,--subsystem,console"]) + env_wrap.Append(LIBS=["version"]) + + prog_wrap = env_wrap.add_program("#bin/godot", common_win_wrap + res_wrap_obj, PROGSUFFIX=env["PROGSUFFIX_WRAP"]) + # Microsoft Visual Studio Project Generation if env["vsproj"]: env.vs_srcs += ["platform/windows/" + res_file] env.vs_srcs += ["platform/windows/godot.natvis"] for x in common_win: env.vs_srcs += ["platform/windows/" + str(x)] + if env["windows_subsystem"] == "gui": + for x in common_win_wrap: + env.vs_srcs += ["platform/windows/" + str(x)] if not os.getenv("VCINSTALLDIR"): if env["debug_symbols"] and env["separate_debug_symbols"]: env.AddPostAction(prog, run_in_subprocess(platform_windows_builders.make_debug_mingw)) + if env["windows_subsystem"] == "gui": + env.AddPostAction(prog_wrap, run_in_subprocess(platform_windows_builders.make_debug_mingw)) diff --git a/platform/windows/console_wrapper_windows.cpp b/platform/windows/console_wrapper_windows.cpp new file mode 100644 index 0000000000..de751580b7 --- /dev/null +++ b/platform/windows/console_wrapper_windows.cpp @@ -0,0 +1,181 @@ +/**************************************************************************/ +/* console_wrapper_windows.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 <windows.h> + +#include <shlwapi.h> +#include <stdio.h> +#include <stdlib.h> + +#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING +#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x4 +#endif + +int main(int argc, char *argv[]) { + // Get executable name. + WCHAR exe_name[MAX_PATH] = {}; + if (!GetModuleFileNameW(nullptr, exe_name, MAX_PATH)) { + wprintf(L"GetModuleFileName failed, error %d\n", GetLastError()); + return -1; + } + + // Get product name from the resources and set console title. + DWORD ver_info_handle = 0; + DWORD ver_info_size = GetFileVersionInfoSizeW(exe_name, &ver_info_handle); + if (ver_info_size > 0) { + LPBYTE ver_info = (LPBYTE)malloc(ver_info_size); + if (ver_info) { + if (GetFileVersionInfoW(exe_name, ver_info_handle, ver_info_size, ver_info)) { + LPCWSTR text_ptr = nullptr; + UINT text_size = 0; + if (VerQueryValueW(ver_info, L"\\StringFileInfo\\040904b0\\ProductName", (void **)&text_ptr, &text_size) && (text_size > 0)) { + SetConsoleTitleW(text_ptr); + } + } + free(ver_info); + } + } + + // Enable virtual terminal sequences processing. + HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE); + DWORD out_mode = ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING; + SetConsoleMode(stdout_handle, out_mode); + + // Find main executable name and check if it exist. + static PCWSTR exe_renames[] = { + L".console.exe", + L"_console.exe", + L" console.exe", + L"console.exe", + nullptr, + }; + + bool rename_found = false; + for (int i = 0; exe_renames[i]; i++) { + PWSTR c = StrRStrIW(exe_name, nullptr, exe_renames[i]); + if (c) { + CopyMemory(c, L".exe", sizeof(WCHAR) * 5); + rename_found = true; + break; + } + } + if (!rename_found) { + wprintf(L"Invalid wrapper executable name.\n"); + return -1; + } + + DWORD file_attrib = GetFileAttributesW(exe_name); + if (file_attrib == INVALID_FILE_ATTRIBUTES || (file_attrib & FILE_ATTRIBUTE_DIRECTORY)) { + wprintf(L"Main executable %ls not found.\n", exe_name); + return -1; + } + + // Create job to monitor process tree. + HANDLE job_handle = CreateJobObjectW(nullptr, nullptr); + if (!job_handle) { + wprintf(L"CreateJobObject failed, error %d\n", GetLastError()); + return -1; + } + + HANDLE io_port_handle = CreateIoCompletionPort(INVALID_HANDLE_VALUE, nullptr, 0, 1); + if (!io_port_handle) { + wprintf(L"CreateIoCompletionPort failed, error %d\n", GetLastError()); + return -1; + } + + JOBOBJECT_ASSOCIATE_COMPLETION_PORT compl_port; + ZeroMemory(&compl_port, sizeof(compl_port)); + compl_port.CompletionKey = job_handle; + compl_port.CompletionPort = io_port_handle; + + if (!SetInformationJobObject(job_handle, JobObjectAssociateCompletionPortInformation, &compl_port, sizeof(compl_port))) { + wprintf(L"SetInformationJobObject(AssociateCompletionPortInformation) failed, error %d\n", GetLastError()); + return -1; + } + + JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli; + ZeroMemory(&jeli, sizeof(jeli)); + jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; + + if (!SetInformationJobObject(job_handle, JobObjectExtendedLimitInformation, &jeli, sizeof(jeli))) { + wprintf(L"SetInformationJobObject(ExtendedLimitInformation) failed, error %d\n", GetLastError()); + return -1; + } + + // Start the main process. + PROCESS_INFORMATION pi; + ZeroMemory(&pi, sizeof(pi)); + + STARTUPINFOW si; + ZeroMemory(&si, sizeof(si)); + si.cb = sizeof(si); + + WCHAR new_command_line[32767]; + _snwprintf_s(new_command_line, 32767, _TRUNCATE, L"%ls %ls", exe_name, PathGetArgsW(GetCommandLineW())); + + if (!CreateProcessW(nullptr, new_command_line, nullptr, nullptr, true, CREATE_SUSPENDED, nullptr, nullptr, &si, &pi)) { + wprintf(L"CreateProcess failed, error %d\n", GetLastError()); + return -1; + } + + if (!AssignProcessToJobObject(job_handle, pi.hProcess)) { + wprintf(L"AssignProcessToJobObject failed, error %d\n", GetLastError()); + return -1; + } + + ResumeThread(pi.hThread); + CloseHandle(pi.hThread); + + // Wait until main process and all of its children are finished. + DWORD completion_code = 0; + ULONG_PTR completion_key = 0; + LPOVERLAPPED overlapped = nullptr; + + while (GetQueuedCompletionStatus(io_port_handle, &completion_code, &completion_key, &overlapped, INFINITE)) { + if ((HANDLE)completion_key == job_handle && completion_code == JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO) { + break; + } + } + + CloseHandle(job_handle); + CloseHandle(io_port_handle); + + // Get exit code of the main process. + DWORD exit_code = 0; + GetExitCodeProcess(pi.hProcess, &exit_code); + + CloseHandle(pi.hProcess); + + return exit_code; +} + +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { + return main(0, nullptr); +} diff --git a/platform/windows/crash_handler_windows.cpp b/platform/windows/crash_handler_windows.cpp index b501ee78db..e32fbd47dd 100644 --- a/platform/windows/crash_handler_windows.cpp +++ b/platform/windows/crash_handler_windows.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* crash_handler_windows.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* crash_handler_windows.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "crash_handler_windows.h" @@ -47,9 +47,6 @@ #include <psapi.h> -#pragma comment(lib, "psapi.lib") -#pragma comment(lib, "dbghelp.lib") - // Some versions of imagehlp.dll lack the proper packing directives themselves // so we need to do it. #pragma pack(push, before_imagehlp, 8) @@ -157,7 +154,7 @@ DWORD CrashHandlerException(EXCEPTION_POINTERS *ep) { return EXCEPTION_CONTINUE_SEARCH; } - SymSetOptions(SymGetOptions() | SYMOPT_LOAD_LINES | SYMOPT_UNDNAME); + SymSetOptions(SymGetOptions() | SYMOPT_LOAD_LINES | SYMOPT_UNDNAME | SYMOPT_EXACT_SYMBOLS); EnumProcessModules(process, &module_handles[0], module_handles.size() * sizeof(HMODULE), &cbNeeded); module_handles.resize(cbNeeded / sizeof(HMODULE)); EnumProcessModules(process, &module_handles[0], module_handles.size() * sizeof(HMODULE), &cbNeeded); diff --git a/platform/windows/crash_handler_windows.h b/platform/windows/crash_handler_windows.h index ec8de3ffab..ef5831f10c 100644 --- a/platform/windows/crash_handler_windows.h +++ b/platform/windows/crash_handler_windows.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* crash_handler_windows.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* crash_handler_windows.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 CRASH_HANDLER_WINDOWS_H #define CRASH_HANDLER_WINDOWS_H diff --git a/platform/windows/detect.py b/platform/windows/detect.py index 705e83dace..3a6ca66449 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -188,9 +188,20 @@ def get_opts(): BoolVariable("use_llvm", "Use the LLVM compiler", False), BoolVariable("use_static_cpp", "Link MinGW/MSVC C++ runtime libraries statically", True), BoolVariable("use_asan", "Use address sanitizer (ASAN)", False), + BoolVariable("debug_crt", "Compile with MSVC's debug CRT (/MDd)", False), ] +def get_doc_classes(): + return [ + "EditorExportPlatformWindows", + ] + + +def get_doc_path(): + return "doc_classes" + + def get_flags(): arch = detect_build_env_arch() or detect_arch() @@ -339,10 +350,14 @@ def configure_msvc(env, vcvars_msvc_config): ## Compile/link flags - if env["use_static_cpp"]: - env.AppendUnique(CCFLAGS=["/MT"]) + if env["debug_crt"]: + # Always use dynamic runtime, static debug CRT breaks thread_local. + env.AppendUnique(CCFLAGS=["/MDd"]) else: - env.AppendUnique(CCFLAGS=["/MD"]) + if env["use_static_cpp"]: + env.AppendUnique(CCFLAGS=["/MT"]) + else: + env.AppendUnique(CCFLAGS=["/MD"]) if env["arch"] == "x86_32": env["x86_libtheora_opt_vc"] = True @@ -398,12 +413,16 @@ def configure_msvc(env, vcvars_msvc_config): "dxguid", "imm32", "bcrypt", + "Crypt32", "Avrt", "dwmapi", "dwrite", "wbemuuid", ] + if env.debug_features: + LIBS += ["psapi", "dbghelp"] + if env["vulkan"]: env.AppendUnique(CPPDEFINES=["VULKAN_ENABLED"]) if not env["use_volk"]: @@ -451,6 +470,7 @@ def configure_msvc(env, vcvars_msvc_config): env["BUILDERS"]["ProgramOriginal"] = env["BUILDERS"]["Program"] env["BUILDERS"]["Program"] = methods.precious_program + env.Append(LINKFLAGS=["/NATVIS:platform\windows\godot.natvis"]) env.AppendUnique(LINKFLAGS=["/STACK:" + str(STACK_SIZE)]) @@ -574,6 +594,7 @@ def configure_mingw(env): "ksuser", "imm32", "bcrypt", + "crypt32", "avrt", "uuid", "dwmapi", @@ -582,6 +603,9 @@ def configure_mingw(env): ] ) + if env.debug_features: + env.Append(LIBS=["psapi", "dbghelp"]) + if env["vulkan"]: env.Append(CPPDEFINES=["VULKAN_ENABLED"]) if not env["use_volk"]: diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index 9d0a2578fb..ea93c47ec5 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -1,41 +1,45 @@ -/*************************************************************************/ -/* display_server_windows.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* display_server_windows.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "display_server_windows.h" +#include "os_windows.h" + #include "core/io/marshalls.h" -#include "core/math/geometry_2d.h" #include "main/main.h" -#include "os_windows.h" #include "scene/resources/texture.h" +#if defined(GLES3_ENABLED) +#include "drivers/gles3/rasterizer_gles3.h" +#endif + #include <avrt.h> #include <dwmapi.h> @@ -43,10 +47,6 @@ #define DWMWA_USE_IMMERSIVE_DARK_MODE 20 #endif -#if defined(GLES3_ENABLED) -#include "drivers/gles3/rasterizer_gles3.h" -#endif - #if defined(__GNUC__) // Workaround GCC warning from -Wcast-function-type. #define GetProcAddress (void *)GetProcAddress @@ -90,6 +90,7 @@ bool DisplayServerWindows::has_feature(Feature p_feature) const { case FEATURE_SWAP_BUFFERS: case FEATURE_KEEP_SCREEN_ON: case FEATURE_TEXT_TO_SPEECH: + case FEATURE_SCREEN_CAPTURE: return true; default: return false; @@ -178,37 +179,37 @@ void DisplayServerWindows::_register_raw_input_devices(WindowID p_target_window) } bool DisplayServerWindows::tts_is_speaking() const { - ERR_FAIL_COND_V(!tts, false); + ERR_FAIL_COND_V_MSG(!tts, false, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); return tts->is_speaking(); } bool DisplayServerWindows::tts_is_paused() const { - ERR_FAIL_COND_V(!tts, false); + ERR_FAIL_COND_V_MSG(!tts, false, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); return tts->is_paused(); } TypedArray<Dictionary> DisplayServerWindows::tts_get_voices() const { - ERR_FAIL_COND_V(!tts, TypedArray<Dictionary>()); + ERR_FAIL_COND_V_MSG(!tts, TypedArray<Dictionary>(), "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); return tts->get_voices(); } void DisplayServerWindows::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); + ERR_FAIL_COND_MSG(!tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); tts->speak(p_text, p_voice, p_volume, p_pitch, p_rate, p_utterance_id, p_interrupt); } void DisplayServerWindows::tts_pause() { - ERR_FAIL_COND(!tts); + ERR_FAIL_COND_MSG(!tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); tts->pause(); } void DisplayServerWindows::tts_resume() { - ERR_FAIL_COND(!tts); + ERR_FAIL_COND_MSG(!tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); tts->resume(); } void DisplayServerWindows::tts_stop() { - ERR_FAIL_COND(!tts); + ERR_FAIL_COND_MSG(!tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); tts->stop(); } @@ -254,25 +255,25 @@ void DisplayServerWindows::warp_mouse(const Point2i &p_position) { Point2i DisplayServerWindows::mouse_get_position() const { POINT p; GetCursorPos(&p); - return Point2i(p.x, p.y); + return Point2i(p.x, p.y) - _get_screens_origin(); } -MouseButton DisplayServerWindows::mouse_get_button_state() const { +BitField<MouseButtonMask> DisplayServerWindows::mouse_get_button_state() const { return last_button_state; } void DisplayServerWindows::clipboard_set(const String &p_text) { _THREAD_SAFE_METHOD_ - if (!windows.has(last_focused_window)) { - return; // No focused window? + if (!windows.has(MAIN_WINDOW_ID)) { + return; } // Convert LF line endings to CRLF in clipboard content. // Otherwise, line endings won't be visible when pasted in other software. String text = p_text.replace("\r\n", "\n").replace("\n", "\r\n"); // Avoid \r\r\n. - if (!OpenClipboard(windows[last_focused_window].hWnd)) { + if (!OpenClipboard(windows[MAIN_WINDOW_ID].hWnd)) { ERR_FAIL_MSG("Unable to open clipboard."); } EmptyClipboard(); @@ -305,12 +306,12 @@ void DisplayServerWindows::clipboard_set(const String &p_text) { String DisplayServerWindows::clipboard_get() const { _THREAD_SAFE_METHOD_ - if (!windows.has(last_focused_window)) { - return String(); // No focused window? + if (!windows.has(MAIN_WINDOW_ID)) { + return String(); } String ret; - if (!OpenClipboard(windows[last_focused_window].hWnd)) { + if (!OpenClipboard(windows[MAIN_WINDOW_ID].hWnd)) { ERR_FAIL_V_MSG("", "Unable to open clipboard."); } @@ -346,6 +347,17 @@ typedef struct { HMONITOR monitor; } EnumScreenData; +static BOOL CALLBACK _MonitorEnumProcPrim(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) { + EnumScreenData *data = (EnumScreenData *)dwData; + if ((lprcMonitor->left == 0) && (lprcMonitor->top == 0)) { + data->screen = data->count; + return FALSE; + } + + data->count++; + return TRUE; +} + static BOOL CALLBACK _MonitorEnumProcScreen(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) { EnumScreenData *data = (EnumScreenData *)dwData; if (data->monitor == hMonitor) { @@ -370,6 +382,23 @@ int DisplayServerWindows::get_screen_count() const { return data; } +int DisplayServerWindows::get_primary_screen() const { + EnumScreenData data = { 0, 0, 0 }; + EnumDisplayMonitors(nullptr, nullptr, _MonitorEnumProcPrim, (LPARAM)&data); + return data.screen; +} + +int DisplayServerWindows::get_keyboard_focus_screen() const { + HWND hwnd = GetForegroundWindow(); + if (hwnd) { + EnumScreenData data = { 0, 0, MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST) }; + EnumDisplayMonitors(nullptr, nullptr, _MonitorEnumProcScreen, (LPARAM)&data); + return data.screen; + } else { + return get_primary_screen(); + } +} + typedef struct { int count; int screen; @@ -387,12 +416,29 @@ static BOOL CALLBACK _MonitorEnumProcPos(HMONITOR hMonitor, HDC hdcMonitor, LPRE return TRUE; } +static BOOL CALLBACK _MonitorEnumProcOrigin(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) { + EnumPosData *data = (EnumPosData *)dwData; + data->pos.x = MIN(data->pos.x, lprcMonitor->left); + data->pos.y = MIN(data->pos.y, lprcMonitor->top); + + return TRUE; +} + +Point2i DisplayServerWindows::_get_screens_origin() const { + _THREAD_SAFE_METHOD_ + + EnumPosData data = { 0, 0, Point2() }; + EnumDisplayMonitors(nullptr, nullptr, _MonitorEnumProcOrigin, (LPARAM)&data); + return data.pos; +} + Point2i DisplayServerWindows::screen_get_position(int p_screen) const { _THREAD_SAFE_METHOD_ - EnumPosData data = { 0, p_screen == SCREEN_OF_MAIN_WINDOW ? window_get_current_screen() : p_screen, Point2() }; + p_screen = _get_screen_index(p_screen); + EnumPosData data = { 0, p_screen, Point2() }; EnumDisplayMonitors(nullptr, nullptr, _MonitorEnumProcPos, (LPARAM)&data); - return data.pos; + return data.pos - _get_screens_origin(); } typedef struct { @@ -427,7 +473,8 @@ static BOOL CALLBACK _MonitorEnumProcSize(HMONITOR hMonitor, HDC hdcMonitor, LPR Size2i DisplayServerWindows::screen_get_size(int p_screen) const { _THREAD_SAFE_METHOD_ - EnumSizeData data = { 0, p_screen == SCREEN_OF_MAIN_WINDOW ? window_get_current_screen() : p_screen, Size2() }; + p_screen = _get_screen_index(p_screen); + EnumSizeData data = { 0, p_screen, Size2() }; EnumDisplayMonitors(nullptr, nullptr, _MonitorEnumProcSize, (LPARAM)&data); return data.size; } @@ -473,8 +520,10 @@ static BOOL CALLBACK _MonitorEnumProcRefreshRate(HMONITOR hMonitor, HDC hdcMonit Rect2i DisplayServerWindows::screen_get_usable_rect(int p_screen) const { _THREAD_SAFE_METHOD_ - EnumRectData data = { 0, p_screen == SCREEN_OF_MAIN_WINDOW ? window_get_current_screen() : p_screen, Rect2i() }; + p_screen = _get_screen_index(p_screen); + EnumRectData data = { 0, p_screen, Rect2i() }; EnumDisplayMonitors(nullptr, nullptr, _MonitorEnumProcUsableSize, (LPARAM)&data); + data.rect.position -= _get_screens_origin(); return data.rect; } @@ -549,14 +598,108 @@ static BOOL CALLBACK _MonitorEnumProcDpi(HMONITOR hMonitor, HDC hdcMonitor, LPRE int DisplayServerWindows::screen_get_dpi(int p_screen) const { _THREAD_SAFE_METHOD_ - EnumDpiData data = { 0, p_screen == SCREEN_OF_MAIN_WINDOW ? window_get_current_screen() : p_screen, 72 }; + p_screen = _get_screen_index(p_screen); + EnumDpiData data = { 0, p_screen, 72 }; EnumDisplayMonitors(nullptr, nullptr, _MonitorEnumProcDpi, (LPARAM)&data); return data.dpi; } + +Color DisplayServerWindows::screen_get_pixel(const Point2i &p_position) const { + Point2i pos = p_position + _get_screens_origin(); + + POINT p; + p.x = pos.x; + p.y = pos.y; + if (win81p_LogicalToPhysicalPointForPerMonitorDPI) { + win81p_LogicalToPhysicalPointForPerMonitorDPI(0, &p); + } + HDC dc = GetDC(0); + if (dc) { + COLORREF col = GetPixel(dc, p.x, p.y); + if (col != CLR_INVALID) { + ReleaseDC(NULL, dc); + return Color(float(col & 0x000000FF) / 256.0, float((col & 0x0000FF00) >> 8) / 256.0, float((col & 0x00FF0000) >> 16) / 256.0, 1.0); + } + ReleaseDC(NULL, dc); + } + + return Color(); +} + +Ref<Image> DisplayServerWindows::screen_get_image(int p_screen) const { + ERR_FAIL_INDEX_V(p_screen, get_screen_count(), Ref<Image>()); + + switch (p_screen) { + case SCREEN_PRIMARY: { + p_screen = get_primary_screen(); + } break; + case SCREEN_OF_MAIN_WINDOW: { + p_screen = window_get_current_screen(MAIN_WINDOW_ID); + } break; + default: + break; + } + + Point2i pos = screen_get_position(p_screen) + _get_screens_origin(); + Size2i size = screen_get_size(p_screen); + + POINT p1; + p1.x = pos.x; + p1.y = pos.y; + + POINT p2; + p2.x = pos.x + size.x; + p2.y = pos.y + size.y; + if (win81p_LogicalToPhysicalPointForPerMonitorDPI) { + win81p_LogicalToPhysicalPointForPerMonitorDPI(0, &p1); + win81p_LogicalToPhysicalPointForPerMonitorDPI(0, &p2); + } + + Ref<Image> img; + HDC dc = GetDC(0); + if (dc) { + HDC hdc = CreateCompatibleDC(dc); + int width = p2.x - p1.x; + int height = p2.y - p1.y; + if (hdc) { + HBITMAP hbm = CreateCompatibleBitmap(dc, width, height); + if (hbm) { + SelectObject(hdc, hbm); + BitBlt(hdc, 0, 0, width, height, dc, p1.x, p1.y, SRCCOPY); + + BITMAPINFO bmp_info = {}; + bmp_info.bmiHeader.biSize = sizeof(bmp_info.bmiHeader); + bmp_info.bmiHeader.biWidth = width; + bmp_info.bmiHeader.biHeight = -height; + bmp_info.bmiHeader.biPlanes = 1; + bmp_info.bmiHeader.biBitCount = 32; + bmp_info.bmiHeader.biCompression = BI_RGB; + + Vector<uint8_t> img_data; + img_data.resize(width * height * 4); + GetDIBits(hdc, hbm, 0, height, img_data.ptrw(), &bmp_info, DIB_RGB_COLORS); + + uint8_t *wr = (uint8_t *)img_data.ptrw(); + for (int i = 0; i < width * height; i++) { + SWAP(wr[i * 4 + 0], wr[i * 4 + 2]); + } + img = Image::create_from_data(width, height, false, Image::FORMAT_RGBA8, img_data); + + DeleteObject(hbm); + } + DeleteDC(hdc); + } + ReleaseDC(NULL, dc); + } + + return img; +} + float DisplayServerWindows::screen_get_refresh_rate(int p_screen) const { _THREAD_SAFE_METHOD_ - EnumRefreshRateData data = { 0, p_screen == SCREEN_OF_MAIN_WINDOW ? window_get_current_screen() : p_screen, SCREEN_REFRESH_RATE_FALLBACK }; + p_screen = _get_screen_index(p_screen); + EnumRefreshRateData data = { 0, p_screen, SCREEN_REFRESH_RATE_FALLBACK }; EnumDisplayMonitors(nullptr, nullptr, _MonitorEnumProcRefreshRate, (LPARAM)&data); return data.rate; } @@ -612,9 +755,10 @@ Vector<DisplayServer::WindowID> DisplayServerWindows::get_window_list() const { } DisplayServer::WindowID DisplayServerWindows::get_window_at_screen_position(const Point2i &p_position) const { + Point2i offset = _get_screens_origin(); POINT p; - p.x = p_position.x; - p.y = p_position.y; + p.x = p_position.x + offset.x; + p.y = p_position.y + offset.y; HWND hwnd = WindowFromPoint(p); for (const KeyValue<WindowID, WindowData> &E : windows) { if (E.value.hWnd == hwnd) { @@ -645,9 +789,23 @@ DisplayServer::WindowID DisplayServerWindows::create_sub_window(WindowMode p_mod if (p_flags & WINDOW_FLAG_NO_FOCUS_BIT) { wd.no_focus = true; } + if (p_flags & WINDOW_FLAG_MOUSE_PASSTHROUGH_BIT) { + wd.mpass = true; + } if (p_flags & WINDOW_FLAG_POPUP_BIT) { wd.is_popup = true; } + if (p_flags & WINDOW_FLAG_TRANSPARENT_BIT) { + DWM_BLURBEHIND bb; + ZeroMemory(&bb, sizeof(bb)); + HRGN hRgn = CreateRectRgn(0, 0, -1, -1); + bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION; + bb.hRgnBlur = hRgn; + bb.fEnable = TRUE; + DwmEnableBlurBehindWindow(wd.hWnd, &bb); + + wd.layered_window = true; + } // Inherit icons from MAIN_WINDOW for all sub windows. HICON mainwindow_icon = (HICON)SendMessage(windows[MAIN_WINDOW_ID].hWnd, WM_GETICON, ICON_SMALL, 0); @@ -677,14 +835,20 @@ void DisplayServerWindows::show_window(WindowID p_id) { SetFocus(wd.hWnd); // Set keyboard focus. } else if (wd.minimized) { ShowWindow(wd.hWnd, SW_SHOWMINIMIZED); - } else if (wd.no_focus || wd.is_popup) { + } else if (wd.no_focus) { // https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-showwindow ShowWindow(wd.hWnd, SW_SHOWNA); + } else if (wd.is_popup) { + ShowWindow(wd.hWnd, SW_SHOWNA); + SetFocus(wd.hWnd); // Set keyboard focus. } else { ShowWindow(wd.hWnd, SW_SHOW); SetForegroundWindow(wd.hWnd); // Slightly higher priority. SetFocus(wd.hWnd); // Set keyboard focus. } + if (wd.always_on_top) { + SetWindowPos(wd.hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | ((wd.no_focus || wd.is_popup) ? SWP_NOACTIVATE : 0)); + } } void DisplayServerWindows::delete_sub_window(WindowID p_window) { @@ -722,6 +886,10 @@ void DisplayServerWindows::delete_sub_window(WindowID p_window) { } DestroyWindow(windows[p_window].hWnd); windows.erase(p_window); + + if (last_focused_window == p_window) { + last_focused_window = INVALID_WINDOW_ID; + } } void DisplayServerWindows::gl_window_make_current(DisplayServer::WindowID p_window_id) { @@ -741,9 +909,20 @@ int64_t DisplayServerWindows::window_get_native_handle(HandleType p_handle_type, case WINDOW_HANDLE: { return (int64_t)windows[p_window].hWnd; } +#if defined(GLES3_ENABLED) case WINDOW_VIEW: { - return 0; // Not supported. + if (gl_manager) { + return (int64_t)gl_manager->get_hdc(p_window); + } + return 0; + } + case OPENGL_CONTEXT: { + if (gl_manager) { + return (int64_t)gl_manager->get_hglrc(p_window); + } + return 0; } +#endif default: { return 0; } @@ -817,7 +996,7 @@ void DisplayServerWindows::window_set_mouse_passthrough(const Vector<Vector2> &p void DisplayServerWindows::_update_window_mouse_passthrough(WindowID p_window) { ERR_FAIL_COND(!windows.has(p_window)); - if (windows[p_window].mpath.size() == 0) { + if (windows[p_window].mpass || windows[p_window].mpath.size() == 0) { SetWindowRgn(windows[p_window].hWnd, nullptr, TRUE); } else { POINT *points = (POINT *)memalloc(sizeof(POINT) * windows[p_window].mpath.size()); @@ -854,28 +1033,24 @@ void DisplayServerWindows::window_set_current_screen(int p_screen, WindowID p_wi ERR_FAIL_COND(!windows.has(p_window)); ERR_FAIL_INDEX(p_screen, get_screen_count()); + if (window_get_current_screen(p_window) == p_screen) { + return; + } const WindowData &wd = windows[p_window]; if (wd.fullscreen) { - int cs = window_get_current_screen(p_window); - if (cs == p_screen) { - return; - } - Point2 pos = screen_get_position(p_screen); + Point2 pos = screen_get_position(p_screen) + _get_screens_origin(); Size2 size = screen_get_size(p_screen); MoveWindow(wd.hWnd, pos.x, pos.y, size.width, size.height, TRUE); } else { - 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); - } + Rect2i srect = screen_get_usable_rect(p_screen); + Point2i wpos = window_get_position(p_window) - screen_get_position(window_get_current_screen(p_window)); + Size2i wsize = window_get_size(p_window); + wpos += srect.position; - // Don't let the mouse leave the window when resizing to a smaller resolution. - if (mouse_mode == MOUSE_MODE_CONFINED || mouse_mode == MOUSE_MODE_CONFINED_HIDDEN) { - RECT crect; - GetClientRect(wd.hWnd, &crect); - ClientToScreen(wd.hWnd, (POINT *)&crect.left); - ClientToScreen(wd.hWnd, (POINT *)&crect.right); - ClipCursor(&crect); + wpos.x = CLAMP(wpos.x, srect.position.x, srect.position.x + srect.size.width - wsize.width / 3); + wpos.y = CLAMP(wpos.y, srect.position.y, srect.position.y + srect.size.height - wsize.height / 3); + window_set_position(wpos, p_window); } } @@ -895,7 +1070,25 @@ Point2i DisplayServerWindows::window_get_position(WindowID p_window) const { ClientToScreen(wd.hWnd, &point); - return Point2i(point.x, point.y); + return Point2i(point.x, point.y) - _get_screens_origin(); +} + +Point2i DisplayServerWindows::window_get_position_with_decorations(WindowID p_window) const { + _THREAD_SAFE_METHOD_ + + ERR_FAIL_COND_V(!windows.has(p_window), Point2i()); + const WindowData &wd = windows[p_window]; + + if (wd.minimized) { + return wd.last_pos; + } + + RECT r; + if (GetWindowRect(wd.hWnd, &r)) { + return Point2i(r.left, r.top) - _get_screens_origin(); + } + + return Point2i(); } void DisplayServerWindows::_update_real_mouse_position(WindowID p_window) { @@ -922,11 +1115,13 @@ void DisplayServerWindows::window_set_position(const Point2i &p_position, Window return; } + Point2i offset = _get_screens_origin(); + RECT rc; - rc.left = p_position.x; - rc.right = p_position.x + wd.width; - rc.bottom = p_position.y + wd.height; - rc.top = p_position.y; + rc.left = p_position.x + offset.x; + rc.right = p_position.x + wd.width + offset.x; + rc.bottom = p_position.y + wd.height + offset.y; + rc.top = p_position.y + offset.y; const DWORD style = GetWindowLongPtr(wd.hWnd, GWL_STYLE); const DWORD exStyle = GetWindowLongPtr(wd.hWnd, GWL_EXSTYLE); @@ -934,15 +1129,6 @@ void DisplayServerWindows::window_set_position(const Point2i &p_position, Window AdjustWindowRectEx(&rc, style, false, exStyle); MoveWindow(wd.hWnd, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, TRUE); - // Don't let the mouse leave the window when moved. - if (mouse_mode == MOUSE_MODE_CONFINED || mouse_mode == MOUSE_MODE_CONFINED_HIDDEN) { - RECT rect; - GetClientRect(wd.hWnd, &rect); - ClientToScreen(wd.hWnd, (POINT *)&rect.left); - ClientToScreen(wd.hWnd, (POINT *)&rect.right); - ClipCursor(&rect); - } - wd.last_pos = p_position; _update_real_mouse_position(p_window); } @@ -1084,15 +1270,6 @@ void DisplayServerWindows::window_set_size(const Size2i p_size, WindowID p_windo } MoveWindow(wd.hWnd, rect.left, rect.top, w, h, TRUE); - - // Don't let the mouse leave the window when resizing to a smaller resolution. - if (mouse_mode == MOUSE_MODE_CONFINED || mouse_mode == MOUSE_MODE_CONFINED_HIDDEN) { - RECT crect; - GetClientRect(wd.hWnd, &crect); - ClientToScreen(wd.hWnd, (POINT *)&crect.left); - ClientToScreen(wd.hWnd, (POINT *)&crect.right); - ClipCursor(&crect); - } } Size2i DisplayServerWindows::window_get_size(WindowID p_window) const { @@ -1113,7 +1290,7 @@ Size2i DisplayServerWindows::window_get_size(WindowID p_window) const { return Size2(); } -Size2i DisplayServerWindows::window_get_real_size(WindowID p_window) const { +Size2i DisplayServerWindows::window_get_size_with_decorations(WindowID p_window) const { _THREAD_SAFE_METHOD_ ERR_FAIL_COND_V(!windows.has(p_window), Size2i()); @@ -1151,7 +1328,7 @@ void DisplayServerWindows::_get_window_style(bool p_main_window, bool p_fullscre r_style = WS_OVERLAPPEDWINDOW; } } else { - r_style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU; + r_style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX; } } @@ -1207,6 +1384,8 @@ void DisplayServerWindows::window_set_mode(WindowMode p_mode, WindowID p_window) wd.multiwindow_fs = false; wd.maximized = wd.was_maximized; + _update_window_style(p_window, false); + if (wd.pre_fs_valid) { rect = wd.pre_fs_rect; } else { @@ -1217,8 +1396,6 @@ void DisplayServerWindows::window_set_mode(WindowMode p_mode, WindowID p_window) wd.pre_fs_valid = true; } - _update_window_style(p_window, false); - MoveWindow(wd.hWnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, TRUE); if (restore_mouse_trails > 1) { @@ -1262,7 +1439,7 @@ void DisplayServerWindows::window_set_mode(WindowMode p_mode, WindowID p_window) } int cs = window_get_current_screen(p_window); - Point2 pos = screen_get_position(cs); + Point2 pos = screen_get_position(cs) + _get_screens_origin(); Size2 size = screen_get_size(cs); wd.fullscreen = true; @@ -1280,15 +1457,6 @@ void DisplayServerWindows::window_set_mode(WindowMode p_mode, WindowID p_window) SystemParametersInfoA(SPI_SETMOUSETRAILS, 0, 0, 0); } } - - // Don't let the mouse leave the window when resizing to a smaller resolution. - if (mouse_mode == MOUSE_MODE_CONFINED || mouse_mode == MOUSE_MODE_CONFINED_HIDDEN) { - RECT crect; - GetClientRect(wd.hWnd, &crect); - ClientToScreen(wd.hWnd, (POINT *)&crect.left); - ClientToScreen(wd.hWnd, (POINT *)&crect.right); - ClipCursor(&crect); - } } DisplayServer::WindowMode DisplayServerWindows::window_get_mode(WindowID p_window) const { @@ -1373,6 +1541,10 @@ void DisplayServerWindows::window_set_flag(WindowFlags p_flag, bool p_enabled, W wd.no_focus = p_enabled; _update_window_style(p_window); } break; + case WINDOW_FLAG_MOUSE_PASSTHROUGH: { + wd.mpass = p_enabled; + _update_window_mouse_passthrough(p_window); + } break; case WINDOW_FLAG_POPUP: { ERR_FAIL_COND_MSG(p_window == MAIN_WINDOW_ID, "Main window can't be popup."); ERR_FAIL_COND_MSG(IsWindowVisible(wd.hWnd) && (wd.is_popup != p_enabled), "Popup flag can't changed while window is opened."); @@ -1404,6 +1576,9 @@ bool DisplayServerWindows::window_get_flag(WindowFlags p_flag, WindowID p_window case WINDOW_FLAG_NO_FOCUS: { return wd.no_focus; } break; + case WINDOW_FLAG_MOUSE_PASSTHROUGH: { + return wd.mpass; + } break; case WINDOW_FLAG_POPUP: { return wd.is_popup; } break; @@ -1440,6 +1615,15 @@ void DisplayServerWindows::window_move_to_foreground(WindowID p_window) { } } +bool DisplayServerWindows::window_is_focused(WindowID p_window) const { + _THREAD_SAFE_METHOD_ + + ERR_FAIL_COND_V(!windows.has(p_window), false); + const WindowData &wd = windows[p_window]; + + return wd.window_focused; +} + bool DisplayServerWindows::window_can_draw(WindowID p_window) const { _THREAD_SAFE_METHOD_ @@ -1460,6 +1644,58 @@ bool DisplayServerWindows::can_any_window_draw() const { return false; } +Vector2i DisplayServerWindows::ime_get_selection() const { + _THREAD_SAFE_METHOD_ + + DisplayServer::WindowID window_id = _get_focused_window_or_popup(); + const WindowData &wd = windows[window_id]; + if (!wd.ime_active) { + return Vector2i(); + } + + int cursor = ImmGetCompositionStringW(wd.im_himc, GCS_CURSORPOS, nullptr, 0); + + int32_t length = ImmGetCompositionStringW(wd.im_himc, GCS_COMPSTR, nullptr, 0); + wchar_t *string = reinterpret_cast<wchar_t *>(memalloc(length)); + ImmGetCompositionStringW(wd.im_himc, GCS_COMPSTR, string, length); + + int32_t utf32_cursor = 0; + for (int32_t i = 0; i < length / int32_t(sizeof(wchar_t)); i++) { + if ((string[i] & 0xfffffc00) == 0xd800) { + i++; + } + if (i < cursor) { + utf32_cursor++; + } else { + break; + } + } + + memdelete(string); + + return Vector2i(utf32_cursor, 0); +} + +String DisplayServerWindows::ime_get_text() const { + _THREAD_SAFE_METHOD_ + + DisplayServer::WindowID window_id = _get_focused_window_or_popup(); + const WindowData &wd = windows[window_id]; + if (!wd.ime_active) { + return String(); + } + + String ret; + int32_t length = ImmGetCompositionStringW(wd.im_himc, GCS_COMPSTR, nullptr, 0); + wchar_t *string = reinterpret_cast<wchar_t *>(memalloc(length)); + ImmGetCompositionStringW(wd.im_himc, GCS_COMPSTR, string, length); + ret.parse_utf16((char16_t *)string, length / sizeof(wchar_t)); + + memdelete(string); + + return ret; +} + void DisplayServerWindows::window_set_ime_active(const bool p_active, WindowID p_window) { _THREAD_SAFE_METHOD_ @@ -1467,11 +1703,14 @@ void DisplayServerWindows::window_set_ime_active(const bool p_active, WindowID p WindowData &wd = windows[p_window]; if (p_active) { + wd.ime_active = true; ImmAssociateContext(wd.hWnd, wd.im_himc); - + CreateCaret(wd.hWnd, NULL, 1, 1); window_set_ime_position(wd.im_position, p_window); } else { ImmAssociateContext(wd.hWnd, (HIMC)0); + DestroyCaret(); + wd.ime_active = false; } } @@ -1489,7 +1728,7 @@ void DisplayServerWindows::window_set_ime_position(const Point2i &p_pos, WindowI } COMPOSITIONFORM cps; - cps.dwStyle = CFS_FORCE_POSITION; + cps.dwStyle = CFS_POINT; cps.ptCurrentPos.x = wd.im_position.x; cps.ptCurrentPos.y = wd.im_position.y; ImmSetCompositionWindow(himc, &cps); @@ -1546,6 +1785,8 @@ DisplayServer::CursorShape DisplayServerWindows::cursor_get_shape() const { void DisplayServerWindows::cursor_set_custom_image(const Ref<Resource> &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { _THREAD_SAFE_METHOD_ + ERR_FAIL_INDEX(p_shape, CURSOR_MAX); + if (p_cursor.is_valid()) { RBMap<CursorShape, Vector<Variant>>::Element *cursor_c = cursors_cache.find(p_shape); @@ -1559,38 +1800,37 @@ void DisplayServerWindows::cursor_set_custom_image(const Ref<Resource> &p_cursor } Ref<Texture2D> texture = p_cursor; + ERR_FAIL_COND(!texture.is_valid()); Ref<AtlasTexture> atlas_texture = p_cursor; - Ref<Image> image; Size2 texture_size; Rect2 atlas_rect; - if (texture.is_valid()) { - image = texture->get_image(); - } - - if (!image.is_valid() && atlas_texture.is_valid()) { + if (atlas_texture.is_valid()) { texture = atlas_texture->get_atlas(); atlas_rect.size.width = texture->get_width(); atlas_rect.size.height = texture->get_height(); atlas_rect.position.x = atlas_texture->get_region().position.x; atlas_rect.position.y = atlas_texture->get_region().position.y; - texture_size.width = atlas_texture->get_region().size.x; texture_size.height = atlas_texture->get_region().size.y; - } else if (image.is_valid()) { + } else { texture_size.width = texture->get_width(); texture_size.height = texture->get_height(); } - ERR_FAIL_COND(!texture.is_valid()); ERR_FAIL_COND(p_hotspot.x < 0 || p_hotspot.y < 0); ERR_FAIL_COND(texture_size.width > 256 || texture_size.height > 256); ERR_FAIL_COND(p_hotspot.x > texture_size.width || p_hotspot.y > texture_size.height); - image = texture->get_image(); + Ref<Image> image = texture->get_image(); ERR_FAIL_COND(!image.is_valid()); + if (image->is_compressed()) { + image = image->duplicate(true); + Error err = image->decompress(); + ERR_FAIL_COND_MSG(err != OK, "Couldn't decompress VRAM-compressed custom mouse cursor image. Switch to a lossless compression mode in the Import dock."); + } UINT image_size = texture_size.width * texture_size.height; @@ -1881,7 +2121,7 @@ void DisplayServerWindows::set_native_icon(const String &p_filename) { pos += sizeof(WORD); f->seek(pos); - icon_dir = (ICONDIR *)memrealloc(icon_dir, 3 * sizeof(WORD) + icon_dir->idCount * sizeof(ICONDIRENTRY)); + icon_dir = (ICONDIR *)memrealloc(icon_dir, sizeof(ICONDIR) - sizeof(ICONDIRENTRY) + icon_dir->idCount * sizeof(ICONDIRENTRY)); f->get_buffer((uint8_t *)&icon_dir->idEntries[0], icon_dir->idCount * sizeof(ICONDIRENTRY)); int small_icon_index = -1; // Select 16x16 with largest color count. @@ -2012,6 +2252,12 @@ void DisplayServerWindows::window_set_vsync_mode(DisplayServer::VSyncMode p_vsyn context_vulkan->set_vsync_mode(p_window, p_vsync_mode); } #endif + +#if defined(GLES3_ENABLED) + if (gl_manager) { + gl_manager->set_use_vsync(p_window, p_vsync_mode != DisplayServer::VSYNC_DISABLED); + } +#endif } DisplayServer::VSyncMode DisplayServerWindows::window_get_vsync_mode(WindowID p_window) const { @@ -2021,6 +2267,13 @@ DisplayServer::VSyncMode DisplayServerWindows::window_get_vsync_mode(WindowID p_ return context_vulkan->get_vsync_mode(p_window); } #endif + +#if defined(GLES3_ENABLED) + if (gl_manager) { + return gl_manager->is_using_vsync(p_window) ? DisplayServer::VSYNC_ENABLED : DisplayServer::VSYNC_DISABLED; + } +#endif + return DisplayServer::VSYNC_ENABLED; } @@ -2178,8 +2431,23 @@ Rect2i DisplayServerWindows::window_get_popup_safe_rect(WindowID p_window) const void DisplayServerWindows::popup_open(WindowID p_window) { _THREAD_SAFE_METHOD_ - const WindowData &wd = windows[p_window]; - if (wd.is_popup) { + bool has_popup_ancestor = false; + WindowID transient_root = p_window; + while (true) { + WindowID parent = windows[transient_root].transient_parent; + if (parent == INVALID_WINDOW_ID) { + break; + } else { + transient_root = parent; + if (windows[parent].is_popup) { + has_popup_ancestor = true; + break; + } + } + } + + WindowData &wd = windows[p_window]; + if (wd.is_popup || has_popup_ancestor) { // Find current popup parent, or root popup if new window is not transient. List<WindowID>::Element *C = nullptr; List<WindowID>::Element *E = popup_list.back(); @@ -2230,7 +2498,7 @@ LRESULT DisplayServerWindows::MouseProc(int code, WPARAM wParam, LPARAM lParam) case WM_RBUTTONDOWN: case WM_MBUTTONDOWN: { MOUSEHOOKSTRUCT *ms = (MOUSEHOOKSTRUCT *)lParam; - Point2i pos = Point2i(ms->pt.x, ms->pt.y); + Point2i pos = Point2i(ms->pt.x, ms->pt.y) - _get_screens_origin(); List<WindowID>::Element *C = nullptr; List<WindowID>::Element *E = popup_list.back(); // Find top popup to close. @@ -2325,6 +2593,11 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA // Process window messages. switch (uMsg) { + case WM_NCHITTEST: { + if (windows[window_id].mpass) { + return HTTRANSPARENT; + } + } break; case WM_MOUSEACTIVATE: { if (windows[window_id].no_focus) { return MA_NOACTIVATEANDEAT; // Do not activate, and discard mouse messages. @@ -2390,7 +2663,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA case WM_GETMINMAXINFO: { if (windows[window_id].resizable && !windows[window_id].fullscreen) { // Size of window decorations. - Size2 decor = window_get_real_size(window_id) - window_get_size(window_id); + Size2 decor = window_get_size_with_decorations(window_id) - window_get_size(window_id); MINMAXINFO *min_max_info = (MINMAXINFO *)lParam; if (windows[window_id].min_size != Size2()) { @@ -2404,6 +2677,25 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA return 0; } } break; + case WM_ERASEBKGND: { + Color early_color; + if (!_get_window_early_clear_override(early_color)) { + break; + } + bool must_recreate_brush = !window_bkg_brush || window_bkg_brush_color != early_color.to_argb32(); + if (must_recreate_brush) { + if (window_bkg_brush) { + DeleteObject(window_bkg_brush); + } + window_bkg_brush = CreateSolidBrush(RGB(early_color.get_r8(), early_color.get_g8(), early_color.get_b8())); + } + HDC hdc = (HDC)wParam; + RECT rect = {}; + if (GetUpdateRect(hWnd, &rect, true)) { + FillRect(hdc, &rect, window_bkg_brush); + } + return 1; + } break; case WM_PAINT: { Main::force_redraw(); } break; @@ -2449,6 +2741,10 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA window_mouseover_id = INVALID_WINDOW_ID; _send_window_event(windows[window_id], WINDOW_EVENT_MOUSE_EXIT); + } else if (window_mouseover_id != INVALID_WINDOW_ID && windows.has(window_mouseover_id)) { + // This is reached during drag and drop, after dropping in a different window. + // Once-off notification, must call again. + track_mouse_leave_event(windows[window_mouseover_id].hWnd); } } break; @@ -2684,7 +2980,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA // Mouse enter. if (mouse_mode != MOUSE_MODE_CAPTURED) { - if (window_mouseover_id != INVALID_WINDOW_ID) { + if (window_mouseover_id != INVALID_WINDOW_ID && windows.has(window_mouseover_id)) { // Leave previous window. _send_window_event(windows[window_mouseover_id], WINDOW_EVENT_MOUSE_EXIT); } @@ -2786,7 +3082,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA } DisplayServer::WindowID over_id = get_window_at_screen_position(mouse_get_position()); - if (!Rect2(window_get_position(over_id), Point2(windows[over_id].width, windows[over_id].height)).has_point(mouse_get_position())) { + if (windows.has(over_id) && !Rect2(window_get_position(over_id), Point2(windows[over_id].width, windows[over_id].height)).has_point(mouse_get_position())) { // Don't consider the windowborder as part of the window. over_id = INVALID_WINDOW_ID; } @@ -2794,12 +3090,12 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA // Mouse enter. if (mouse_mode != MOUSE_MODE_CAPTURED) { - if (window_mouseover_id != INVALID_WINDOW_ID) { + if (window_mouseover_id != INVALID_WINDOW_ID && windows.has(window_mouseover_id)) { // Leave previous window. _send_window_event(windows[window_mouseover_id], WINDOW_EVENT_MOUSE_EXIT); } - if (over_id != INVALID_WINDOW_ID) { + if (over_id != INVALID_WINDOW_ID && windows.has(over_id)) { _send_window_event(windows[over_id], WINDOW_EVENT_MOUSE_ENTER); } } @@ -2882,11 +3178,10 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA old_x = mm->get_position().x; old_y = mm->get_position().y; - if (!windows[receiving_window_id].window_has_focus) { - // In case of unfocused Popups, adjust event position. - Point2i pos = mm->get_position() - window_get_position(receiving_window_id) + window_get_position(window_id); - mm->set_position(pos); - mm->set_global_position(pos); + if (receiving_window_id != window_id) { + // Adjust event position relative to window distance when event is sent to a different window. + mm->set_position(mm->get_position() - window_get_position(receiving_window_id) + window_get_position(window_id)); + mm->set_global_position(mm->get_position()); } Input::get_singleton()->parse_input_event(mm); @@ -3020,9 +3315,9 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA mb->set_alt_pressed(alt_mem); // mb->is_alt_pressed()=(wParam&MK_MENU)!=0; if (mb->is_pressed()) { - last_button_state |= mouse_button_to_mask(mb->get_button_index()); + last_button_state.set_flag(mouse_button_to_mask(mb->get_button_index())); } else { - last_button_state &= ~mouse_button_to_mask(mb->get_button_index()); + last_button_state.clear_flag(mouse_button_to_mask(mb->get_button_index())); } mb->set_button_mask(last_button_state); @@ -3063,7 +3358,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA // Send release for mouse wheel. Ref<InputEventMouseButton> mbd = mb->duplicate(); mbd->set_window_id(window_id); - last_button_state &= ~mouse_button_to_mask(mbd->get_button_index()); + last_button_state.clear_flag(mouse_button_to_mask(mbd->get_button_index())); mbd->set_button_mask(last_button_state); mbd->set_pressed(false); Input::get_singleton()->parse_input_event(mbd); @@ -3080,10 +3375,12 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA ClientToScreen(hWnd, (POINT *)&rect.left); ClientToScreen(hWnd, (POINT *)&rect.right); window_client_rect = Rect2i(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top); + window_client_rect.position -= _get_screens_origin(); RECT wrect; GetWindowRect(hWnd, &wrect); window_rect = Rect2i(wrect.left, wrect.top, wrect.right - wrect.left, wrect.bottom - wrect.top); + window_rect.position -= _get_screens_origin(); } WINDOWPOS *window_pos_params = (WINDOWPOS *)lParam; @@ -3134,6 +3431,15 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA Callable::CallError ce; window.rect_changed_callback.callp(args, 1, ret, ce); } + + // Update cursor clip region after window rect has changed. + if (mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED || mouse_mode == MOUSE_MODE_CONFINED_HIDDEN) { + RECT crect; + GetClientRect(window.hWnd, &crect); + ClientToScreen(window.hWnd, (POINT *)&crect.left); + ClientToScreen(window.hWnd, (POINT *)&crect.right); + ClipCursor(&crect); + } } // Return here to prevent WM_MOVE and WM_SIZE from being sent @@ -3161,9 +3467,9 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA windows[window_id].focus_timer_id = 0U; } } break; - case WM_SYSKEYDOWN: case WM_SYSKEYUP: case WM_KEYUP: + case WM_SYSKEYDOWN: case WM_KEYDOWN: { if (wParam == VK_SHIFT) { shift_mem = (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN); @@ -3178,6 +3484,14 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA } } + if (windows[window_id].ime_suppress_next_keyup && (uMsg == WM_KEYUP || uMsg == WM_SYSKEYUP)) { + windows[window_id].ime_suppress_next_keyup = false; + break; + } + if (windows[window_id].ime_in_progress) { + break; + } + if (mouse_mode == MOUSE_MODE_CAPTURED) { // When SetCapture is used, ALT+F4 hotkey is ignored by Windows, so handle it ourselves if (wParam == VK_F4 && alt_mem && (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN)) { @@ -3210,9 +3524,49 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA key_event_buffer[key_event_pos++] = ke; } break; + case WM_IME_COMPOSITION: { + CANDIDATEFORM cf; + cf.dwIndex = 0; + + cf.dwStyle = CFS_CANDIDATEPOS; + cf.ptCurrentPos.x = windows[window_id].im_position.x; + cf.ptCurrentPos.y = windows[window_id].im_position.y; + ImmSetCandidateWindow(windows[window_id].im_himc, &cf); + + cf.dwStyle = CFS_EXCLUDE; + cf.rcArea.left = windows[window_id].im_position.x; + cf.rcArea.right = windows[window_id].im_position.x; + cf.rcArea.top = windows[window_id].im_position.y; + cf.rcArea.bottom = windows[window_id].im_position.y; + ImmSetCandidateWindow(windows[window_id].im_himc, &cf); + + if (windows[window_id].ime_active) { + SetCaretPos(windows[window_id].im_position.x, windows[window_id].im_position.y); + OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_OS_IME_UPDATE); + } + } break; case WM_INPUTLANGCHANGEREQUEST: { // FIXME: Do something? } break; + case WM_IME_STARTCOMPOSITION: { + if (windows[window_id].ime_active) { + windows[window_id].ime_in_progress = true; + if (key_event_pos > 0) { + key_event_pos--; + } + } + return 0; + } break; + case WM_IME_ENDCOMPOSITION: { + if (windows[window_id].ime_active) { + windows[window_id].ime_in_progress = false; + windows[window_id].ime_suppress_next_keyup = true; + } + return 0; + } break; + case WM_IME_NOTIFY: { + return 0; + } break; case WM_TOUCH: { BOOL bHandled = FALSE; UINT cInputs = LOWORD(wParam); @@ -3321,6 +3675,7 @@ void DisplayServerWindows::_process_activate_event(WindowID p_window_id, WPARAM alt_mem = false; control_mem = false; shift_mem = false; + gr_mem = false; // Restore mouse mode. _set_mouse_mode_impl(mouse_mode); @@ -3364,24 +3719,44 @@ void DisplayServerWindows::_process_key_events() { Ref<InputEventKey> k; k.instantiate(); + Key keycode = KeyMappingWindows::get_keysym(MapVirtualKey((ke.lParam >> 16) & 0xFF, MAPVK_VSC_TO_VK)); + Key key_label = keycode; + Key physical_keycode = KeyMappingWindows::get_scansym((ke.lParam >> 16) & 0xFF, ke.lParam & (1 << 24)); + + static BYTE keyboard_state[256]; + memset(keyboard_state, 0, 256); + wchar_t chars[256] = {}; + UINT extended_code = MapVirtualKey((ke.lParam >> 16) & 0xFF, MAPVK_VSC_TO_VK_EX); + if (!(ke.lParam & (1 << 24)) && ToUnicodeEx(extended_code, (ke.lParam >> 16) & 0xFF, keyboard_state, chars, 255, 4, GetKeyboardLayout(0)) > 0) { + String keysym = String::utf16((char16_t *)chars, 255); + if (!keysym.is_empty()) { + key_label = fix_key_label(keysym[0], keycode); + } + } + k->set_window_id(ke.window_id); - k->set_shift_pressed(ke.shift); - k->set_alt_pressed(ke.alt); - k->set_ctrl_pressed(ke.control); - k->set_meta_pressed(ke.meta); + if (keycode != Key::SHIFT) { + k->set_shift_pressed(ke.shift); + } + if (keycode != Key::ALT) { + k->set_alt_pressed(ke.alt); + } + if (keycode != Key::CTRL) { + k->set_ctrl_pressed(ke.control); + } + if (keycode != Key::META) { + k->set_meta_pressed(ke.meta); + } k->set_pressed(true); - k->set_keycode((Key)KeyMappingWindows::get_keysym(MapVirtualKey((ke.lParam >> 16) & 0xFF, MAPVK_VSC_TO_VK))); - k->set_physical_keycode((Key)(KeyMappingWindows::get_scansym((ke.lParam >> 16) & 0xFF, ke.lParam & (1 << 24)))); - k->set_unicode(unicode); + k->set_keycode(keycode); + k->set_physical_keycode(physical_keycode); + k->set_key_label(key_label); + k->set_unicode(fix_unicode(unicode)); if (k->get_unicode() && gr_mem) { k->set_alt_pressed(false); k->set_ctrl_pressed(false); } - if (k->get_unicode() < 32) { - k->set_unicode(0); - } - Input::get_singleton()->parse_input_event(k); } else { // Do nothing. @@ -3393,21 +3768,42 @@ void DisplayServerWindows::_process_key_events() { k.instantiate(); k->set_window_id(ke.window_id); - k->set_shift_pressed(ke.shift); - k->set_alt_pressed(ke.alt); - k->set_ctrl_pressed(ke.control); - k->set_meta_pressed(ke.meta); - k->set_pressed(ke.uMsg == WM_KEYDOWN); + Key keycode = KeyMappingWindows::get_keysym(ke.wParam); if ((ke.lParam & (1 << 24)) && (ke.wParam == VK_RETURN)) { // Special case for Numpad Enter key. - k->set_keycode(Key::KP_ENTER); - } else { - k->set_keycode((Key)KeyMappingWindows::get_keysym(ke.wParam)); + keycode = Key::KP_ENTER; + } + Key key_label = keycode; + Key physical_keycode = KeyMappingWindows::get_scansym((ke.lParam >> 16) & 0xFF, ke.lParam & (1 << 24)); + + static BYTE keyboard_state[256]; + memset(keyboard_state, 0, 256); + wchar_t chars[256] = {}; + UINT extended_code = MapVirtualKey((ke.lParam >> 16) & 0xFF, MAPVK_VSC_TO_VK_EX); + if (!(ke.lParam & (1 << 24)) && ToUnicodeEx(extended_code, (ke.lParam >> 16) & 0xFF, keyboard_state, chars, 255, 4, GetKeyboardLayout(0)) > 0) { + String keysym = String::utf16((char16_t *)chars, 255); + if (!keysym.is_empty()) { + key_label = fix_key_label(keysym[0], keycode); + } } - k->set_physical_keycode((Key)(KeyMappingWindows::get_scansym((ke.lParam >> 16) & 0xFF, ke.lParam & (1 << 24)))); + if (keycode != Key::SHIFT) { + k->set_shift_pressed(ke.shift); + } + if (keycode != Key::ALT) { + k->set_alt_pressed(ke.alt); + } + if (keycode != Key::CTRL) { + k->set_ctrl_pressed(ke.control); + } + if (keycode != Key::META) { + k->set_meta_pressed(ke.meta); + } + k->set_keycode(keycode); + k->set_physical_keycode(physical_keycode); + k->set_key_label(key_label); if (i + 1 < key_event_pos && key_event_buffer[i + 1].uMsg == WM_CHAR) { char32_t unicode = key_event_buffer[i + 1].wParam; @@ -3428,17 +3824,13 @@ void DisplayServerWindows::_process_key_events() { } else { prev_wck = 0; } - k->set_unicode(unicode); + k->set_unicode(fix_unicode(unicode)); } if (k->get_unicode() && gr_mem) { k->set_alt_pressed(false); k->set_ctrl_pressed(false); } - if (k->get_unicode() < 32) { - k->set_unicode(0); - } - k->set_echo((ke.uMsg == WM_KEYDOWN && (ke.lParam & (1 << 30)))); Input::get_singleton()->parse_input_event(k); @@ -3493,7 +3885,7 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode, DWORD dwExStyle; DWORD dwStyle; - _get_window_style(window_id_counter == MAIN_WINDOW_ID, (p_mode == WINDOW_MODE_FULLSCREEN || p_mode == WINDOW_MODE_EXCLUSIVE_FULLSCREEN), p_mode == WINDOW_MODE_EXCLUSIVE_FULLSCREEN, p_flags & WINDOW_FLAG_BORDERLESS_BIT, !(p_flags & WINDOW_FLAG_RESIZE_DISABLED_BIT), p_mode == WINDOW_MODE_MAXIMIZED, (p_flags & WINDOW_FLAG_NO_FOCUS_BIT), dwStyle, dwExStyle); + _get_window_style(window_id_counter == MAIN_WINDOW_ID, (p_mode == WINDOW_MODE_FULLSCREEN || p_mode == WINDOW_MODE_EXCLUSIVE_FULLSCREEN), p_mode != WINDOW_MODE_EXCLUSIVE_FULLSCREEN, p_flags & WINDOW_FLAG_BORDERLESS_BIT, !(p_flags & WINDOW_FLAG_RESIZE_DISABLED_BIT), p_mode == WINDOW_MODE_MAXIMIZED, (p_flags & WINDOW_FLAG_NO_FOCUS_BIT) | (p_flags & WINDOW_FLAG_POPUP), dwStyle, dwExStyle); RECT WindowRect; @@ -3502,27 +3894,38 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode, WindowRect.top = p_rect.position.y; WindowRect.bottom = p_rect.position.y + p_rect.size.y; + int rq_screen = get_screen_from_rect(p_rect); + if (rq_screen < 0) { + rq_screen = get_primary_screen(); // Requested window rect is outside any screen bounds. + } + if (p_mode == WINDOW_MODE_FULLSCREEN || p_mode == WINDOW_MODE_EXCLUSIVE_FULLSCREEN) { - int nearest_area = 0; - Rect2i screen_rect; - for (int i = 0; i < get_screen_count(); i++) { - Rect2i r; - r.position = screen_get_position(i); - r.size = screen_get_size(i); - Rect2 inters = r.intersection(p_rect); - int area = inters.size.width * inters.size.height; - if (area >= nearest_area) { - screen_rect = r; - nearest_area = area; - } - } + Rect2i screen_rect = Rect2i(screen_get_position(rq_screen), screen_get_size(rq_screen)); WindowRect.left = screen_rect.position.x; WindowRect.right = screen_rect.position.x + screen_rect.size.x; WindowRect.top = screen_rect.position.y; WindowRect.bottom = screen_rect.position.y + screen_rect.size.y; + } else { + Rect2i srect = screen_get_usable_rect(rq_screen); + Point2i wpos = p_rect.position; + if (srect != Rect2i()) { + wpos.x = CLAMP(wpos.x, srect.position.x, srect.position.x + srect.size.width - p_rect.size.width / 3); + wpos.y = CLAMP(wpos.y, srect.position.y, srect.position.y + srect.size.height - p_rect.size.height / 3); + } + + WindowRect.left = wpos.x; + WindowRect.right = wpos.x + p_rect.size.x; + WindowRect.top = wpos.y; + WindowRect.bottom = wpos.y + p_rect.size.y; } + Point2i offset = _get_screens_origin(); + WindowRect.left += offset.x; + WindowRect.right += offset.x; + WindowRect.top += offset.y; + WindowRect.bottom += offset.y; + AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle); WindowID id = window_id_counter; @@ -3586,6 +3989,7 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode, windows.erase(id); ERR_FAIL_V_MSG(INVALID_WINDOW_ID, "Failed to create an OpenGL window."); } + window_set_vsync_mode(p_vsync_mode, id); } #endif @@ -3637,14 +4041,23 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode, // IME. wd.im_himc = ImmGetContext(wd.hWnd); - ImmReleaseContext(wd.hWnd, wd.im_himc); + ImmAssociateContext(wd.hWnd, (HIMC)0); wd.im_position = Vector2(); - // FIXME this is wrong in cases where the window coordinates were changed due to full screen mode; use WindowRect - wd.last_pos = p_rect.position; - wd.width = p_rect.size.width; - wd.height = p_rect.size.height; + if (p_mode == WINDOW_MODE_FULLSCREEN || p_mode == WINDOW_MODE_EXCLUSIVE_FULLSCREEN || p_mode == WINDOW_MODE_MAXIMIZED) { + RECT r; + GetClientRect(wd.hWnd, &r); + ClientToScreen(wd.hWnd, (POINT *)&r.left); + ClientToScreen(wd.hWnd, (POINT *)&r.right); + wd.last_pos = Point2i(r.left, r.top) - _get_screens_origin(); + wd.width = r.right - r.left; + wd.height = r.bottom - r.top; + } else { + wd.last_pos = p_rect.position; + wd.width = p_rect.size.width; + wd.height = p_rect.size.height; + } window_id_counter++; } @@ -3663,7 +4076,6 @@ WTEnablePtr DisplayServerWindows::wintab_WTEnable = nullptr; // UXTheme API. bool DisplayServerWindows::dark_title_available = false; bool DisplayServerWindows::ux_theme_available = false; -IsDarkModeAllowedForAppPtr DisplayServerWindows::IsDarkModeAllowedForApp = nullptr; ShouldAppsUseDarkModePtr DisplayServerWindows::ShouldAppsUseDarkMode = nullptr; GetImmersiveColorFromColorSetExPtr DisplayServerWindows::GetImmersiveColorFromColorSetEx = nullptr; GetImmersiveColorTypeFromNamePtr DisplayServerWindows::GetImmersiveColorTypeFromName = nullptr; @@ -3673,6 +4085,7 @@ GetImmersiveUserColorSetPreferencePtr DisplayServerWindows::GetImmersiveUserColo bool DisplayServerWindows::winink_available = false; GetPointerTypePtr DisplayServerWindows::win8p_GetPointerType = nullptr; GetPointerPenInfoPtr DisplayServerWindows::win8p_GetPointerPenInfo = nullptr; +LogicalToPhysicalPointForPerMonitorDPIPtr DisplayServerWindows::win81p_LogicalToPhysicalPointForPerMonitorDPI = nullptr; typedef enum _SHC_PROCESS_DPI_AWARENESS { SHC_PROCESS_DPI_UNAWARE = 0, @@ -3681,7 +4094,7 @@ typedef enum _SHC_PROCESS_DPI_AWARENESS { } SHC_PROCESS_DPI_AWARENESS; bool DisplayServerWindows::is_dark_mode_supported() const { - return ux_theme_available && IsDarkModeAllowedForApp(); + return ux_theme_available; } bool DisplayServerWindows::is_dark_mode() const { @@ -3731,7 +4144,9 @@ void DisplayServerWindows::tablet_set_current_driver(const String &p_driver) { } } -DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error) { +DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error) { + KeyMappingWindows::initialize(); + drop_events = false; key_event_pos = 0; @@ -3749,7 +4164,10 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win rendering_driver = p_rendering_driver; // Init TTS - tts = memnew(TTS_Windows); + bool tts_enabled = GLOBAL_GET("audio/general/text_to_speech"); + if (tts_enabled) { + tts = memnew(TTS_Windows); + } // Enforce default keep screen on value. screen_set_keep_on(GLOBAL_GET("display/window/energy_saving/keep_screen_on")); @@ -3771,13 +4189,12 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win // Load UXTheme. HMODULE ux_theme_lib = LoadLibraryW(L"uxtheme.dll"); if (ux_theme_lib) { - IsDarkModeAllowedForApp = (IsDarkModeAllowedForAppPtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(136)); ShouldAppsUseDarkMode = (ShouldAppsUseDarkModePtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(132)); GetImmersiveColorFromColorSetEx = (GetImmersiveColorFromColorSetExPtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(95)); GetImmersiveColorTypeFromName = (GetImmersiveColorTypeFromNamePtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(96)); GetImmersiveUserColorSetPreference = (GetImmersiveUserColorSetPreferencePtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(98)); - ux_theme_available = IsDarkModeAllowedForApp && ShouldAppsUseDarkMode && GetImmersiveColorFromColorSetEx && GetImmersiveColorTypeFromName && GetImmersiveUserColorSetPreference; + ux_theme_available = ShouldAppsUseDarkMode && GetImmersiveColorFromColorSetEx && GetImmersiveColorTypeFromName && GetImmersiveUserColorSetPreference; if (os_ver.dwBuildNumber >= 22000) { dark_title_available = true; } @@ -3800,10 +4217,12 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win } // Note: Windows Ink API for pen input, available on Windows 8+ only. + // Note: DPI conversion API, available on Windows 8.1+ only. HMODULE user32_lib = LoadLibraryW(L"user32.dll"); if (user32_lib) { win8p_GetPointerType = (GetPointerTypePtr)GetProcAddress(user32_lib, "GetPointerType"); win8p_GetPointerPenInfo = (GetPointerPenInfoPtr)GetProcAddress(user32_lib, "GetPointerPenInfo"); + win81p_LogicalToPhysicalPointForPerMonitorDPI = (LogicalToPhysicalPointForPerMonitorDPIPtr)GetProcAddress(user32_lib, "LogicalToPhysicalPointForPerMonitorDPI"); winink_available = win8p_GetPointerType && win8p_GetPointerPenInfo; } @@ -3828,7 +4247,7 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win memset(&wc, 0, sizeof(WNDCLASSEXW)); wc.cbSize = sizeof(WNDCLASSEXW); - wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS; + wc.style = CS_OWNDC | CS_DBLCLKS; wc.lpfnWndProc = (WNDPROC)::WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; @@ -3840,7 +4259,7 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win wc.lpszClassName = L"Engine"; if (!RegisterClassExW(&wc)) { - MessageBox(nullptr, "Failed To Register The Window Class.", "ERROR", MB_OK | MB_ICONEXCLAMATION); + MessageBoxW(nullptr, L"Failed To Register The Window Class.", L"ERROR", MB_OK | MB_ICONEXCLAMATION); r_error = ERR_UNAVAILABLE; return; } @@ -3879,17 +4298,21 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win mouse_monitor = SetWindowsHookEx(WH_MOUSE, ::MouseProc, nullptr, GetCurrentThreadId()); - Point2i window_position( - (screen_get_size(0).width - p_resolution.width) / 2, - (screen_get_size(0).height - p_resolution.height) / 2); - + Point2i window_position; if (p_position != nullptr) { window_position = *p_position; + } else { + if (p_screen == SCREEN_OF_MAIN_WINDOW) { + p_screen = SCREEN_PRIMARY; + } + window_position = screen_get_position(p_screen) + (screen_get_size(p_screen) - p_resolution) / 2; } - WindowID main_window = _create_window(p_mode, p_vsync_mode, 0, Rect2i(window_position, p_resolution)); + WindowID main_window = _create_window(p_mode, p_vsync_mode, p_flags, Rect2i(window_position, p_resolution)); ERR_FAIL_COND_MSG(main_window == INVALID_WINDOW_ID, "Failed to create main window."); + joypad = new JoypadWindows(&windows[MAIN_WINDOW_ID].hWnd); + for (int i = 0; i < WINDOW_FLAG_MAX; i++) { if (p_flags & (1 << i)) { window_set_flag(WindowFlags(i), true, main_window); @@ -3915,7 +4338,7 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win // from making the system unresponsive. SetPriorityClass(GetCurrentProcess(), ABOVE_NORMAL_PRIORITY_CLASS); DWORD index = 0; - HANDLE handle = AvSetMmThreadCharacteristics("Games", &index); + HANDLE handle = AvSetMmThreadCharacteristicsW(L"Games", &index); if (handle) { AvSetMmThreadPriority(handle, AVRT_PRIORITY_CRITICAL); } @@ -3929,8 +4352,6 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win _update_real_mouse_position(MAIN_WINDOW_ID); - joypad = new JoypadWindows(&windows[MAIN_WINDOW_ID].hWnd); - r_error = OK; static_cast<OS_Windows *>(OS::get_singleton())->set_main_window(windows[MAIN_WINDOW_ID].hWnd); @@ -3950,23 +4371,25 @@ Vector<String> DisplayServerWindows::get_rendering_drivers_func() { return drivers; } -DisplayServer *DisplayServerWindows::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error) { - DisplayServer *ds = memnew(DisplayServerWindows(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, r_error)); +DisplayServer *DisplayServerWindows::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error) { + DisplayServer *ds = memnew(DisplayServerWindows(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, p_screen, r_error)); if (r_error != OK) { if (p_rendering_driver == "vulkan") { String executable_name = OS::get_singleton()->get_executable_path().get_file(); - OS::get_singleton()->alert("Your video card driver does not support the selected Vulkan version.\n" - "Please try updating your GPU driver or try using the OpenGL 3 driver.\n" - "You can enable the OpenGL 3 driver by starting the engine from the\n" - "command line with the command:\n'./" + - executable_name + " --rendering-driver opengl3'.\n " - "If you have updated your graphics drivers recently, try rebooting.", - "Unable to initialize Video driver"); + OS::get_singleton()->alert( + vformat("Your video card drivers seem not to support the required Vulkan version.\n\n" + "If possible, consider updating your video card drivers or using the OpenGL 3 driver.\n\n" + "You can enable the OpenGL 3 driver by starting the engine from the\n" + "command line with the command:\n\n \"%s\" --rendering-driver opengl3\n\n" + "If you have recently updated your video card drivers, try rebooting.", + executable_name), + "Unable to initialize Vulkan video driver"); } else { - OS::get_singleton()->alert("Your video card driver does not support the selected OpenGL version.\n" - "Please try updating your GPU driver.\n" - "If you have updated your graphics drivers recently, try rebooting.", - "Unable to initialize Video driver"); + OS::get_singleton()->alert( + "Your video card drivers seem not to support the required OpenGL 3.3 version.\n\n" + "If possible, consider updating your video card drivers.\n\n" + "If you have recently updated your video card drivers, try rebooting.", + "Unable to initialize OpenGL video driver"); } } return ds; @@ -4036,5 +4459,4 @@ DisplayServerWindows::~DisplayServerWindows() { if (tts) { memdelete(tts); } - CoUninitialize(); } diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h index 8ac0086d69..7228de7d31 100644 --- a/platform/windows/display_server_windows.h +++ b/platform/windows/display_server_windows.h @@ -1,60 +1,61 @@ -/*************************************************************************/ -/* display_server_windows.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* display_server_windows.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 DISPLAY_SERVER_WINDOWS_H #define DISPLAY_SERVER_WINDOWS_H -#include "servers/display_server.h" +#include "crash_handler_windows.h" +#include "joypad_windows.h" +#include "key_mapping_windows.h" +#include "tts_windows.h" #include "core/config/project_settings.h" #include "core/input/input.h" #include "core/os/os.h" -#include "crash_handler_windows.h" #include "drivers/unix/ip_unix.h" #include "drivers/wasapi/audio_driver_wasapi.h" #include "drivers/winmidi/midi_driver_winmidi.h" -#include "joypad_windows.h" -#include "key_mapping_windows.h" #include "servers/audio_server.h" +#include "servers/display_server.h" #include "servers/rendering/renderer_compositor.h" #include "servers/rendering/renderer_rd/renderer_compositor_rd.h" #include "servers/rendering_server.h" -#include "tts_windows.h" #ifdef XAUDIO2_ENABLED #include "drivers/xaudio2/audio_driver_xaudio2.h" #endif #if defined(VULKAN_ENABLED) +#include "vulkan_context_win.h" + #include "drivers/vulkan/rendering_device_vulkan.h" -#include "platform/windows/vulkan_context_win.h" #endif #if defined(GLES3_ENABLED) @@ -152,7 +153,6 @@ typedef UINT(WINAPI *WTInfoPtr)(UINT p_category, UINT p_index, LPVOID p_output); typedef BOOL(WINAPI *WTPacketPtr)(HANDLE p_ctx, UINT p_param, LPVOID p_packets); typedef BOOL(WINAPI *WTEnablePtr)(HANDLE p_ctx, BOOL p_enable); -typedef bool(WINAPI *IsDarkModeAllowedForAppPtr)(); typedef bool(WINAPI *ShouldAppsUseDarkModePtr)(); typedef DWORD(WINAPI *GetImmersiveColorFromColorSetExPtr)(UINT dwImmersiveColorSet, UINT dwImmersiveColorType, bool bIgnoreHighContrast, UINT dwHighContrastCacheMode); typedef int(WINAPI *GetImmersiveColorTypeFromNamePtr)(const WCHAR *name); @@ -260,6 +260,7 @@ typedef struct tagPOINTER_PEN_INFO { typedef BOOL(WINAPI *GetPointerTypePtr)(uint32_t p_id, POINTER_INPUT_TYPE *p_type); typedef BOOL(WINAPI *GetPointerPenInfoPtr)(uint32_t p_id, POINTER_PEN_INFO *p_pen_info); +typedef BOOL(WINAPI *LogicalToPhysicalPointForPerMonitorDPIPtr)(HWND hwnd, LPPOINT lpPoint); typedef struct { BYTE bWidth; // Width, in pixels, of the image @@ -280,15 +281,13 @@ typedef struct { } ICONDIR, *LPICONDIR; class DisplayServerWindows : public DisplayServer { - //No need to register, it's platform-specific and nothing is added - //GDCLASS(DisplayServerWindows, DisplayServer) + // No need to register with GDCLASS, it's platform-specific and nothing is added. _THREAD_SAFE_CLASS_ // UXTheme API static bool dark_title_available; static bool ux_theme_available; - static IsDarkModeAllowedForAppPtr IsDarkModeAllowedForApp; static ShouldAppsUseDarkModePtr ShouldAppsUseDarkMode; static GetImmersiveColorFromColorSetExPtr GetImmersiveColorFromColorSetEx; static GetImmersiveColorTypeFromNamePtr GetImmersiveColorTypeFromName; @@ -307,6 +306,9 @@ class DisplayServerWindows : public DisplayServer { static GetPointerTypePtr win8p_GetPointerType; static GetPointerPenInfoPtr win8p_GetPointerPenInfo; + // DPI conversion API + static LogicalToPhysicalPointForPerMonitorDPIPtr win81p_LogicalToPhysicalPointForPerMonitorDPI; + void _update_tablet_ctx(const String &p_old_driver, const String &p_new_driver); String tablet_driver; Vector<String> tablet_drivers; @@ -372,6 +374,7 @@ class DisplayServerWindows : public DisplayServer { bool window_has_focus = false; bool exclusive = false; bool context_created = false; + bool mpass = false; // Used to transfer data between events using timer. WPARAM saved_wparam; @@ -406,6 +409,9 @@ class DisplayServerWindows : public DisplayServer { // IME HIMC im_himc; Vector2 im_position; + bool ime_active = false; + bool ime_in_progress = false; + bool ime_suppress_next_keyup = false; bool layered_window = false; @@ -448,12 +454,14 @@ class DisplayServerWindows : public DisplayServer { bool shift_mem = false; bool control_mem = false; bool meta_mem = false; - MouseButton last_button_state = MouseButton::NONE; + BitField<MouseButtonMask> last_button_state; bool use_raw_input = false; bool drop_events = false; bool in_dispatch_input_event = false; WNDCLASSEXW wc; + HBRUSH window_bkg_brush = nullptr; + uint32_t window_bkg_brush_color = 0; HCURSOR cursors[CURSOR_MAX] = { nullptr }; CursorShape cursor_shape = CursorShape::CURSOR_ARROW; @@ -478,6 +486,7 @@ class DisplayServerWindows : public DisplayServer { void _dispatch_input_event(const Ref<InputEvent> &p_event); LRESULT _handle_early_window_message(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + Point2i _get_screens_origin() const; public: LRESULT WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); @@ -507,17 +516,21 @@ public: virtual void warp_mouse(const Point2i &p_position) override; virtual Point2i mouse_get_position() const override; - virtual MouseButton mouse_get_button_state() const override; + virtual BitField<MouseButtonMask> mouse_get_button_state() const override; virtual void clipboard_set(const String &p_text) override; virtual String clipboard_get() const override; virtual int get_screen_count() const override; + virtual int get_primary_screen() const override; + virtual int get_keyboard_focus_screen() const override; virtual Point2i screen_get_position(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; virtual Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; virtual Rect2i screen_get_usable_rect(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; virtual int screen_get_dpi(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; virtual float screen_get_refresh_rate(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; + virtual Color screen_get_pixel(const Point2i &p_position) const override; + virtual Ref<Image> screen_get_image(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; virtual void screen_set_keep_on(bool p_enable) override; //disable screensaver virtual bool screen_is_kept_on() const override; @@ -555,6 +568,7 @@ public: virtual void window_set_current_screen(int p_screen, WindowID p_window = MAIN_WINDOW_ID) override; virtual Point2i window_get_position(WindowID p_window = MAIN_WINDOW_ID) const override; + virtual Point2i window_get_position_with_decorations(WindowID p_window = MAIN_WINDOW_ID) const override; virtual void window_set_position(const Point2i &p_position, WindowID p_window = MAIN_WINDOW_ID) override; virtual void window_set_transient(WindowID p_window, WindowID p_parent) override; @@ -568,7 +582,7 @@ public: virtual void window_set_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID) override; virtual Size2i window_get_size(WindowID p_window = MAIN_WINDOW_ID) const override; - virtual Size2i window_get_real_size(WindowID p_window = MAIN_WINDOW_ID) const override; //wtf is this? should probable use proper name + virtual Size2i window_get_size_with_decorations(WindowID p_window = MAIN_WINDOW_ID) const override; virtual void window_set_mode(WindowMode p_mode, WindowID p_window = MAIN_WINDOW_ID) override; virtual WindowMode window_get_mode(WindowID p_window = MAIN_WINDOW_ID) const override; @@ -580,6 +594,7 @@ public: virtual void window_request_attention(WindowID p_window = MAIN_WINDOW_ID) override; virtual void window_move_to_foreground(WindowID p_window = MAIN_WINDOW_ID) override; + virtual bool window_is_focused(WindowID p_window = MAIN_WINDOW_ID) const override; virtual bool window_can_draw(WindowID p_window = MAIN_WINDOW_ID) const override; @@ -588,6 +603,9 @@ public: virtual void window_set_ime_active(const bool p_active, WindowID p_window = MAIN_WINDOW_ID) override; virtual void window_set_ime_position(const Point2i &p_pos, WindowID p_window = MAIN_WINDOW_ID) override; + virtual Point2i ime_get_selection() const override; + virtual String ime_get_text() const override; + virtual void window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window = MAIN_WINDOW_ID) override; virtual DisplayServer::VSyncMode window_get_vsync_mode(WindowID p_vsync_mode) const override; @@ -624,11 +642,11 @@ public: virtual void set_context(Context p_context) override; - static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error); + static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error); static Vector<String> get_rendering_drivers_func(); static void register_windows_driver(); - DisplayServerWindows(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error); + DisplayServerWindows(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error); ~DisplayServerWindows(); }; diff --git a/platform/windows/doc_classes/EditorExportPlatformWindows.xml b/platform/windows/doc_classes/EditorExportPlatformWindows.xml new file mode 100644 index 0000000000..7506ac09f0 --- /dev/null +++ b/platform/windows/doc_classes/EditorExportPlatformWindows.xml @@ -0,0 +1,136 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="EditorExportPlatformWindows" inherits="EditorExportPlatformPC" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> + <brief_description> + Exporter for Windows. + </brief_description> + <description> + </description> + <tutorials> + <link title="Exporting for Windows">$DOCS_URL/tutorials/export/exporting_for_windows.html</link> + </tutorials> + <members> + <member name="application/company_name" type="String" setter="" getter=""> + Company that produced the application. Required. See [url=https://learn.microsoft.com/en-us/windows/win32/menurc/stringfileinfo-block]StringFileInfo[/url]. + </member> + <member name="application/console_wrapper_icon" type="String" setter="" getter=""> + Console wrapper icon file. If left empty, it will fallback to [member application/icon], then to [member ProjectSettings.application/config/windows_native_icon], and lastly, [member ProjectSettings.application/config/icon]. + </member> + <member name="application/copyright" type="String" setter="" getter=""> + Copyright notice for the bundle visible to the user. Optional. See [url=https://learn.microsoft.com/en-us/windows/win32/menurc/stringfileinfo-block]StringFileInfo[/url]. + </member> + <member name="application/file_description" type="String" setter="" getter=""> + File description to be presented to users. Required. See [url=https://learn.microsoft.com/en-us/windows/win32/menurc/stringfileinfo-block]StringFileInfo[/url]. + </member> + <member name="application/file_version" type="String" setter="" getter=""> + Version number of the file. Required. See [url=https://learn.microsoft.com/en-us/windows/win32/menurc/stringfileinfo-block]StringFileInfo[/url]. + </member> + <member name="application/icon" type="String" setter="" getter=""> + Application icon file. If left empty, it will fallback to [member ProjectSettings.application/config/windows_native_icon], and then to [member ProjectSettings.application/config/icon]. + </member> + <member name="application/icon_interpolation" type="int" setter="" getter=""> + Interpolation method used to resize application icon. + </member> + <member name="application/modify_resources" type="bool" setter="" getter=""> + If enabled, icon and metadata of the exported executable is set according to the other [code]application/*[/code] values. + </member> + <member name="application/product_name" type="String" setter="" getter=""> + Name of the application. Required. See [url=https://learn.microsoft.com/en-us/windows/win32/menurc/stringfileinfo-block]StringFileInfo[/url]. + </member> + <member name="application/product_version" type="String" setter="" getter=""> + Application version visible to the user. Required. See [url=https://learn.microsoft.com/en-us/windows/win32/menurc/stringfileinfo-block]StringFileInfo[/url]. + </member> + <member name="application/trademarks" type="String" setter="" getter=""> + Trademarks and registered trademarks that apply to the file. Optional. See [url=https://learn.microsoft.com/en-us/windows/win32/menurc/stringfileinfo-block]StringFileInfo[/url]. + </member> + <member name="binary_format/architecture" type="String" setter="" getter=""> + Application executable architecture. + Supported architectures: [code]x86_32[/code], [code]x86_64[/code], and [code]arm64[/code]. + Official export templates include [code]x86_32[/code] and [code]x86_64[/code] binaries only. + </member> + <member name="binary_format/embed_pck" type="bool" setter="" getter=""> + If [code]true[/code], project resources are embedded into the executable. + </member> + <member name="codesign/custom_options" type="PackedStringArray" setter="" getter=""> + Array of the additional command line arguments passed to the code signing tool. See [url=https://learn.microsoft.com/en-us/dotnet/framework/tools/signtool-exe]Sign Tool[/url]. + </member> + <member name="codesign/description" type="String" setter="" getter=""> + Description of the signed content. See [url=https://learn.microsoft.com/en-us/dotnet/framework/tools/signtool-exe]Sign Tool[/url]. + </member> + <member name="codesign/digest_algorithm" type="int" setter="" getter=""> + Digest algorithm to use for creating signature. See [url=https://learn.microsoft.com/en-us/dotnet/framework/tools/signtool-exe]Sign Tool[/url]. + </member> + <member name="codesign/enable" type="bool" setter="" getter=""> + If [code]true[/code], executable signing is enabled. + </member> + <member name="codesign/identity" type="String" setter="" getter=""> + PKCS #12 certificate file used to sign executable or certificate SHA-1 hash (if [member codesign/identity_type] is set to "Use certificate store"). See [url=https://learn.microsoft.com/en-us/dotnet/framework/tools/signtool-exe]Sign Tool[/url]. + Can be overridden with the environment variable [code]GODOT_WINDOWS_CODESIGN_IDENTITY[/code]. + </member> + <member name="codesign/identity_type" type="int" setter="" getter=""> + Type of identity to use. See [url=https://learn.microsoft.com/en-us/dotnet/framework/tools/signtool-exe]Sign Tool[/url]. + Can be overridden with the environment variable [code]GODOT_WINDOWS_CODESIGN_IDENTITY_TYPE[/code]. + </member> + <member name="codesign/password" type="String" setter="" getter=""> + Password for the certificate file used to sign executable. See [url=https://learn.microsoft.com/en-us/dotnet/framework/tools/signtool-exe]Sign Tool[/url]. + Can be overridden with the environment variable [code]GODOT_WINDOWS_CODESIGN_PASSWORD[/code]. + </member> + <member name="codesign/timestamp" type="bool" setter="" getter=""> + If [code]true[/code], time-stamp is added to the signature. See [url=https://learn.microsoft.com/en-us/dotnet/framework/tools/signtool-exe]Sign Tool[/url]. + </member> + <member name="codesign/timestamp_server_url" type="String" setter="" getter=""> + URL of the time stamp server. If left empty, the default server is used. See [url=https://learn.microsoft.com/en-us/dotnet/framework/tools/signtool-exe]Sign Tool[/url]. + </member> + <member name="custom_template/debug" type="String" setter="" getter=""> + Path to the custom export template. If left empty, default template is used. + </member> + <member name="custom_template/release" type="String" setter="" getter=""> + Path to the custom export template. If left empty, default template is used. + </member> + <member name="debug/export_console_wrapper" type="int" setter="" getter=""> + If [code]true[/code], a console wrapper executable is exported alongside the main executable, which allows running the project with enabled console output. + </member> + <member name="ssh_remote_deploy/cleanup_script" type="String" setter="" getter=""> + Script code to execute on the remote host when app is finished. + The following variables can be used in the script: + - [code]{temp_dir}[/code] - Path of temporary folder on the remote, used to upload app and scripts to. + - [code]{archive_name}[/code] - Name of the ZIP containing uploaded application. + - [code]{exe_name}[/code] - Name of application executable. + - [code]{cmd_args}[/code] - Array of the command line argument for the application. + </member> + <member name="ssh_remote_deploy/enabled" type="bool" setter="" getter=""> + Enables remote deploy using SSH/SCP. + </member> + <member name="ssh_remote_deploy/extra_args_scp" type="String" setter="" getter=""> + Array of the additional command line arguments passed to the SCP. + </member> + <member name="ssh_remote_deploy/extra_args_ssh" type="String" setter="" getter=""> + Array of the additional command line arguments passed to the SSH. + </member> + <member name="ssh_remote_deploy/host" type="String" setter="" getter=""> + Remote host SSH user name and address, in [code]user@address[/code] format. + </member> + <member name="ssh_remote_deploy/port" type="String" setter="" getter=""> + Remote host SSH port number. + </member> + <member name="ssh_remote_deploy/run_script" type="String" setter="" getter=""> + Script code to execute on the remote host when running the app. + The following variables can be used in the script: + - [code]{temp_dir}[/code] - Path of temporary folder on the remote, used to upload app and scripts to. + - [code]{archive_name}[/code] - Name of the ZIP containing uploaded application. + - [code]{exe_name}[/code] - Name of application executable. + - [code]{cmd_args}[/code] - Array of the command line argument for the application. + </member> + <member name="texture_format/bptc" type="bool" setter="" getter=""> + If [code]true[/code], project textures are exported in the BPTC format. + </member> + <member name="texture_format/etc" type="bool" setter="" getter=""> + If [code]true[/code], project textures are exported in the ETC format. + </member> + <member name="texture_format/etc2" type="bool" setter="" getter=""> + If [code]true[/code], project textures are exported in the ETC2 format. + </member> + <member name="texture_format/s3tc" type="bool" setter="" getter=""> + If [code]true[/code], project textures are exported in the S3TC format. + </member> + </members> +</class> diff --git a/platform/windows/export/export.cpp b/platform/windows/export/export.cpp index 8f91756c02..7a65f74f0d 100644 --- a/platform/windows/export/export.cpp +++ b/platform/windows/export/export.cpp @@ -1,38 +1,43 @@ -/*************************************************************************/ -/* export.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* export.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "export.h" -#include "editor/export/editor_export.h" #include "export_plugin.h" +#include "editor/export/editor_export.h" + +void register_windows_exporter_types() { + GDREGISTER_VIRTUAL_CLASS(EditorExportPlatformWindows); +} + void register_windows_exporter() { #ifndef ANDROID_ENABLED EDITOR_DEF("export/windows/rcedit", ""); @@ -51,7 +56,6 @@ void register_windows_exporter() { Ref<EditorExportPlatformWindows> platform; platform.instantiate(); - 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 1054e04b1e..6c4020f0c8 100644 --- a/platform/windows/export/export.h +++ b/platform/windows/export/export.h @@ -1,36 +1,37 @@ -/*************************************************************************/ -/* export.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* export.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 WINDOWS_EXPORT_H #define WINDOWS_EXPORT_H +void register_windows_exporter_types(); void register_windows_exporter(); #endif // WINDOWS_EXPORT_H diff --git a/platform/windows/export/export_plugin.cpp b/platform/windows/export/export_plugin.cpp index f7b8e84618..7371e4daf7 100644 --- a/platform/windows/export/export_plugin.cpp +++ b/platform/windows/export/export_plugin.cpp @@ -1,79 +1,227 @@ -/*************************************************************************/ -/* export_plugin.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* export_plugin.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "export_plugin.h" +#include "../logo_svg.gen.h" +#include "../run_icon_svg.gen.h" + #include "core/config/project_settings.h" +#include "core/io/image_loader.h" #include "editor/editor_node.h" +#include "editor/editor_paths.h" +#include "editor/editor_scale.h" +#include "editor/export/editor_export.h" -Error EditorExportPlatformWindows::sign_shared_object(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path) { - if (p_preset->get("codesign/enable")) { - return _code_sign(p_preset, p_path); +#include "modules/modules_enabled.gen.h" // For svg. +#ifdef MODULE_SVG_ENABLED +#include "modules/svg/image_loader_svg.h" +#endif + +Error EditorExportPlatformWindows::_process_icon(const Ref<EditorExportPreset> &p_preset, const String &p_src_path, const String &p_dst_path) { + static const uint8_t icon_size[] = { 16, 32, 48, 64, 128, 0 /*256*/ }; + + struct IconData { + Vector<uint8_t> data; + uint8_t pal_colors = 0; + uint16_t planes = 0; + uint16_t bpp = 32; + }; + + HashMap<uint8_t, IconData> images; + Error err; + + if (p_src_path.get_extension() == "ico") { + Ref<FileAccess> f = FileAccess::open(p_src_path, FileAccess::READ, &err); + if (err != OK) { + return err; + } + + // Read ICONDIR. + f->get_16(); // Reserved. + uint16_t icon_type = f->get_16(); // Image type: 1 - ICO. + uint16_t icon_count = f->get_16(); // Number of images. + ERR_FAIL_COND_V(icon_type != 1, ERR_CANT_OPEN); + + for (uint16_t i = 0; i < icon_count; i++) { + // Read ICONDIRENTRY. + uint16_t w = f->get_8(); // Width in pixels. + uint16_t h = f->get_8(); // Height in pixels. + uint8_t pal_colors = f->get_8(); // Number of colors in the palette (0 - no palette). + f->get_8(); // Reserved. + uint16_t planes = f->get_16(); // Number of color planes. + uint16_t bpp = f->get_16(); // Bits per pixel. + uint32_t img_size = f->get_32(); // Image data size in bytes. + uint32_t img_offset = f->get_32(); // Image data offset. + if (w != h) { + continue; + } + + // Read image data. + uint64_t prev_offset = f->get_position(); + images[w].pal_colors = pal_colors; + images[w].planes = planes; + images[w].bpp = bpp; + images[w].data.resize(img_size); + f->seek(img_offset); + f->get_buffer(images[w].data.ptrw(), img_size); + f->seek(prev_offset); + } } else { - return OK; + Ref<Image> src_image; + src_image.instantiate(); + err = ImageLoader::load_image(p_src_path, src_image); + ERR_FAIL_COND_V(err != OK || src_image->is_empty(), ERR_CANT_OPEN); + for (size_t i = 0; i < sizeof(icon_size) / sizeof(icon_size[0]); ++i) { + int size = (icon_size[i] == 0) ? 256 : icon_size[i]; + + Ref<Image> res_image = src_image->duplicate(); + ERR_FAIL_COND_V(res_image.is_null() || res_image->is_empty(), ERR_CANT_OPEN); + res_image->resize(size, size, (Image::Interpolation)(p_preset->get("application/icon_interpolation").operator int())); + images[icon_size[i]].data = res_image->save_png_to_buffer(); + } } -} -Error EditorExportPlatformWindows::_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)); - return ERR_CANT_CREATE; + uint16_t valid_icon_count = 0; + for (size_t i = 0; i < sizeof(icon_size) / sizeof(icon_size[0]); ++i) { + if (images.has(icon_size[i])) { + valid_icon_count++; + } else { + int size = (icon_size[i] == 0) ? 256 : icon_size[i]; + add_message(EXPORT_MESSAGE_WARNING, TTR("Resources Modification"), vformat(TTR("Icon size \"%d\" is missing."), size)); + } } + ERR_FAIL_COND_V(valid_icon_count == 0, ERR_CANT_OPEN); - f->store_line("@echo off"); - f->store_line("title \"" + p_app_name + "\""); - f->store_line("\"%~dp0" + p_pkg_name + "\" \"%*\""); - f->store_line("pause > nul"); + Ref<FileAccess> fw = FileAccess::open(p_dst_path, FileAccess::WRITE, &err); + if (err != OK) { + return err; + } + // Write ICONDIR. + fw->store_16(0); // Reserved. + fw->store_16(1); // Image type: 1 - ICO. + fw->store_16(valid_icon_count); // Number of images. + + // Write ICONDIRENTRY. + uint32_t img_offset = 6 + 16 * valid_icon_count; + for (size_t i = 0; i < sizeof(icon_size) / sizeof(icon_size[0]); ++i) { + if (images.has(icon_size[i])) { + const IconData &di = images[icon_size[i]]; + fw->store_8(icon_size[i]); // Width in pixels. + fw->store_8(icon_size[i]); // Height in pixels. + fw->store_8(di.pal_colors); // Number of colors in the palette (0 - no palette). + fw->store_8(0); // Reserved. + fw->store_16(di.planes); // Number of color planes. + fw->store_16(di.bpp); // Bits per pixel. + fw->store_32(di.data.size()); // Image data size in bytes. + fw->store_32(img_offset); // Image data offset. + + img_offset += di.data.size(); + } + } + + // Write image data. + for (size_t i = 0; i < sizeof(icon_size) / sizeof(icon_size[0]); ++i) { + if (images.has(icon_size[i])) { + const IconData &di = images[icon_size[i]]; + fw->store_buffer(di.data.ptr(), di.data.size()); + } + } return OK; } +Error EditorExportPlatformWindows::sign_shared_object(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path) { + if (p_preset->get("codesign/enable")) { + return _code_sign(p_preset, p_path); + } else { + return OK; + } +} + Error EditorExportPlatformWindows::modify_template(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) { if (p_preset->get("application/modify_resources")) { - _rcedit_add_data(p_preset, p_path); + _rcedit_add_data(p_preset, p_path, true); + String wrapper_path = p_path.get_basename() + ".console.exe"; + if (FileAccess::exists(wrapper_path)) { + _rcedit_add_data(p_preset, wrapper_path, false); + } } return OK; } Error EditorExportPlatformWindows::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) { - String pck_path = p_path; - if (p_preset->get("binary_format/embed_pck")) { - pck_path = p_path.get_basename() + ".tmp"; + bool export_as_zip = p_path.ends_with("zip"); + bool embedded = p_preset->get("binary_format/embed_pck"); + + String pkg_name; + if (String(ProjectSettings::get_singleton()->get("application/config/name")) != "") { + pkg_name = String(ProjectSettings::get_singleton()->get("application/config/name")); + } else { + pkg_name = "Unnamed"; + } + + pkg_name = OS::get_singleton()->get_safe_dir_name(pkg_name); + + // Setup temp folder. + String path = p_path; + String tmp_dir_path = EditorPaths::get_singleton()->get_cache_dir().path_join(pkg_name); + Ref<DirAccess> tmp_app_dir = DirAccess::create_for_path(tmp_dir_path); + if (export_as_zip) { + if (tmp_app_dir.is_null()) { + return ERR_CANT_CREATE; + } + if (DirAccess::exists(tmp_dir_path)) { + if (tmp_app_dir->change_dir(tmp_dir_path) == OK) { + tmp_app_dir->erase_contents_recursive(); + } + } + tmp_app_dir->make_dir_recursive(tmp_dir_path); + path = tmp_dir_path.path_join(p_path.get_file().get_basename() + ".exe"); + } + + // Export project. + String pck_path = path; + if (embedded) { + pck_path = pck_path.get_basename() + ".tmp"; } Error err = EditorExportPlatformPC::export_project(p_preset, p_debug, pck_path, p_flags); if (p_preset->get("codesign/enable") && err == OK) { _code_sign(p_preset, pck_path); + String wrapper_path = p_path.get_basename() + ".console.exe"; + if (FileAccess::exists(wrapper_path)) { + _code_sign(p_preset, wrapper_path); + } } - if (p_preset->get("binary_format/embed_pck") && err == OK) { + if (embedded && err == OK) { Ref<DirAccess> tmp_dir = DirAccess::create_for_path(p_path.get_base_dir()); err = tmp_dir->rename(pck_path, p_path); if (err != OK) { @@ -81,22 +229,24 @@ Error EditorExportPlatformWindows::export_project(const Ref<EditorExportPreset> } } - String app_name; - if (String(GLOBAL_GET("application/config/name")) != "") { - app_name = String(GLOBAL_GET("application/config/name")); - } else { - app_name = "Unnamed"; - } - app_name = OS::get_singleton()->get_safe_dir_name(app_name); + // ZIP project. + if (export_as_zip) { + if (FileAccess::exists(p_path)) { + OS::get_singleton()->move_to_trash(p_path); + } - // Save console script. - if (err == OK) { - int con_scr = p_preset->get("debug/export_console_script"); - if ((con_scr == 1 && p_debug) || (con_scr == 2)) { - String scr_path = p_path.get_basename() + ".cmd"; - if (_export_debug_script(p_preset, app_name, p_path.get_file(), scr_path) != OK) { - add_message(EXPORT_MESSAGE_ERROR, TTR("Debug Script Export"), TTR("Could not create console script.")); - } + Ref<FileAccess> io_fa_dst; + zlib_filefunc_def io_dst = zipio_create_io(&io_fa_dst); + zipFile zip = zipOpen2(p_path.utf8().get_data(), APPEND_STATUS_CREATE, nullptr, &io_dst); + + zip_folder_recursive(zip, tmp_dir_path, "", pkg_name); + + zipClose(zip, nullptr); + + if (tmp_app_dir->change_dir(tmp_dir_path) == OK) { + tmp_app_dir->erase_contents_recursive(); + tmp_app_dir->change_dir(".."); + tmp_app_dir->remove(pkg_name); } } @@ -110,43 +260,121 @@ String EditorExportPlatformWindows::get_template_file_name(const String &p_targe List<String> EditorExportPlatformWindows::get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const { List<String> list; list.push_back("exe"); + list.push_back("zip"); return list; } -bool EditorExportPlatformWindows::get_export_option_visibility(const EditorExportPreset *p_preset, const String &p_option, const HashMap<StringName, Variant> &p_options) const { +String EditorExportPlatformWindows::get_export_option_warning(const EditorExportPreset *p_preset, const StringName &p_name) const { + if (p_preset) { + if (p_name == "application/icon") { + String icon_path = ProjectSettings::get_singleton()->globalize_path(p_preset->get("application/icon")); + if (!icon_path.is_empty() && !FileAccess::exists(icon_path)) { + return TTR("Invalid icon path."); + } + } else if (p_name == "application/file_version") { + String file_version = p_preset->get("application/file_version"); + if (!file_version.is_empty()) { + PackedStringArray version_array = file_version.split(".", false); + if (version_array.size() != 4 || !version_array[0].is_valid_int() || + !version_array[1].is_valid_int() || !version_array[2].is_valid_int() || + !version_array[3].is_valid_int() || file_version.find("-") > -1) { + return TTR("Invalid file version."); + } + } + } else if (p_name == "application/product_version") { + String product_version = p_preset->get("application/product_version"); + if (!product_version.is_empty()) { + PackedStringArray version_array = product_version.split(".", false); + if (version_array.size() != 4 || !version_array[0].is_valid_int() || + !version_array[1].is_valid_int() || !version_array[2].is_valid_int() || + !version_array[3].is_valid_int() || product_version.find("-") > -1) { + return TTR("Invalid product version."); + } + } + } + } + return EditorExportPlatformPC::get_export_option_warning(p_preset, p_name); +} + +bool EditorExportPlatformWindows::get_export_option_visibility(const EditorExportPreset *p_preset, const String &p_option) const { // This option is not supported by "osslsigncode", used on non-Windows host. if (!OS::get_singleton()->has_feature("windows") && p_option == "codesign/identity_type") { return false; } + + // Hide codesign. + bool codesign = p_preset->get("codesign/enable"); + if (!codesign && p_option != "codesign/enable" && p_option.begins_with("codesign/")) { + return false; + } + + // Hide resources. + bool mod_res = p_preset->get("application/modify_resources"); + if (!mod_res && p_option != "application/modify_resources" && p_option.begins_with("application/")) { + return false; + } + + // Hide SSH options. + bool ssh = p_preset->get("ssh_remote_deploy/enabled"); + if (!ssh && p_option != "ssh_remote_deploy/enabled" && p_option.begins_with("ssh_remote_deploy/")) { + return false; + } + return true; } -void EditorExportPlatformWindows::get_export_options(List<ExportOption> *r_options) { +void EditorExportPlatformWindows::get_export_options(List<ExportOption> *r_options) const { EditorExportPlatformPC::get_export_options(r_options); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "binary_format/architecture", PROPERTY_HINT_ENUM, "x86_64,x86_32,arm64"), "x86_64")); - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/enable"), false)); - r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "codesign/identity_type", PROPERTY_HINT_ENUM, "Select automatically,Use PKCS12 file (specify *.PFX/*.P12 file),Use certificate store (specify SHA1 hash)"), 0)); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/identity", PROPERTY_HINT_GLOBAL_FILE, "*.pfx,*.p12"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/password", PROPERTY_HINT_PASSWORD), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/enable"), false, true)); + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "codesign/identity_type", PROPERTY_HINT_ENUM, "Select automatically,Use PKCS12 file (specify *.PFX/*.P12 file),Use certificate store (specify SHA-1 hash)", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), 0)); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/identity", PROPERTY_HINT_GLOBAL_FILE, "*.pfx,*.p12", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/password", PROPERTY_HINT_PASSWORD, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/timestamp"), true)); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/timestamp_server_url"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "codesign/digest_algorithm", PROPERTY_HINT_ENUM, "SHA1,SHA256"), 1)); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/description"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::PACKED_STRING_ARRAY, "codesign/custom_options"), PackedStringArray())); - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "application/modify_resources"), true)); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/icon", PROPERTY_HINT_FILE, "*.ico"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/file_version", PROPERTY_HINT_PLACEHOLDER_TEXT, "1.0.0.0"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/product_version", PROPERTY_HINT_PLACEHOLDER_TEXT, "1.0.0.0"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "application/modify_resources"), true, true)); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/icon", PROPERTY_HINT_FILE, "*.ico,*.png,*.webp,*.svg"), "", false, true)); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/console_wrapper_icon", PROPERTY_HINT_FILE, "*.ico,*.png,*.webp,*.svg"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "application/icon_interpolation", PROPERTY_HINT_ENUM, "Nearest neighbor,Bilinear,Cubic,Trilinear,Lanczos"), 4)); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/file_version", PROPERTY_HINT_PLACEHOLDER_TEXT, "1.0.0.0"), "", false, true)); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/product_version", PROPERTY_HINT_PLACEHOLDER_TEXT, "1.0.0.0"), "", false, true)); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/company_name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Company Name"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/product_name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Game Name"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/file_description"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/copyright"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/trademarks"), "")); + + String run_script = "Expand-Archive -LiteralPath '{temp_dir}\\{archive_name}' -DestinationPath '{temp_dir}'\n" + "$action = New-ScheduledTaskAction -Execute '{temp_dir}\\{exe_name}' -Argument '{cmd_args}'\n" + "$trigger = New-ScheduledTaskTrigger -Once -At 00:00\n" + "$settings = New-ScheduledTaskSettingsSet\n" + "$task = New-ScheduledTask -Action $action -Trigger $trigger -Settings $settings\n" + "Register-ScheduledTask godot_remote_debug -InputObject $task -Force:$true\n" + "Start-ScheduledTask -TaskName godot_remote_debug\n" + "while (Get-ScheduledTask -TaskName godot_remote_debug | ? State -eq running) { Start-Sleep -Milliseconds 100 }\n" + "Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue"; + + String cleanup_script = "Stop-ScheduledTask -TaskName godot_remote_debug -ErrorAction:SilentlyContinue\n" + "Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue\n" + "Remove-Item -Recurse -Force '{temp_dir}'"; + + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "ssh_remote_deploy/enabled"), false, true)); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "ssh_remote_deploy/host"), "user@host_ip")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "ssh_remote_deploy/port"), "22")); + + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "ssh_remote_deploy/extra_args_ssh", PROPERTY_HINT_MULTILINE_TEXT), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "ssh_remote_deploy/extra_args_scp", PROPERTY_HINT_MULTILINE_TEXT), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "ssh_remote_deploy/run_script", PROPERTY_HINT_MULTILINE_TEXT), run_script)); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "ssh_remote_deploy/cleanup_script", PROPERTY_HINT_MULTILINE_TEXT), cleanup_script)); } -Error EditorExportPlatformWindows::_rcedit_add_data(const Ref<EditorExportPreset> &p_preset, const String &p_path) { +Error EditorExportPlatformWindows::_rcedit_add_data(const Ref<EditorExportPreset> &p_preset, const String &p_path, bool p_console_icon) { String rcedit_path = EDITOR_GET("export/windows/rcedit"); if (rcedit_path != String() && !FileAccess::exists(rcedit_path)) { @@ -172,7 +400,31 @@ Error EditorExportPlatformWindows::_rcedit_add_data(const Ref<EditorExportPreset } #endif - String icon_path = ProjectSettings::get_singleton()->globalize_path(p_preset->get("application/icon")); + String icon_path; + if (p_preset->get("application/icon") != "") { + icon_path = p_preset->get("application/icon"); + } else if (GLOBAL_GET("application/config/windows_native_icon") != "") { + icon_path = GLOBAL_GET("application/config/windows_native_icon"); + } else { + icon_path = GLOBAL_GET("application/config/icon"); + } + icon_path = ProjectSettings::get_singleton()->globalize_path(icon_path); + + if (p_console_icon) { + String console_icon_path = ProjectSettings::get_singleton()->globalize_path(p_preset->get("application/console_wrapper_icon")); + if (!console_icon_path.is_empty() && FileAccess::exists(console_icon_path)) { + icon_path = console_icon_path; + } + } + + String tmp_icon_path = EditorPaths::get_singleton()->get_cache_dir().path_join("_rcedit.ico"); + if (!icon_path.is_empty()) { + if (_process_icon(p_preset, icon_path, tmp_icon_path) != OK) { + add_message(EXPORT_MESSAGE_WARNING, TTR("Resources Modification"), vformat(TTR("Invalid icon file \"%s\"."), icon_path)); + icon_path = String(); + } + } + String file_verion = p_preset->get("application/file_version"); String product_version = p_preset->get("application/product_version"); String company_name = p_preset->get("application/company_name"); @@ -186,7 +438,7 @@ Error EditorExportPlatformWindows::_rcedit_add_data(const Ref<EditorExportPreset args.push_back(p_path); if (!icon_path.is_empty()) { args.push_back("--set-icon"); - args.push_back(icon_path); + args.push_back(tmp_icon_path); } if (!file_verion.is_empty()) { args.push_back("--set-file-version"); @@ -230,6 +482,11 @@ Error EditorExportPlatformWindows::_rcedit_add_data(const Ref<EditorExportPreset String str; Error err = OS::get_singleton()->execute(rcedit_path, args, &str, nullptr, true); + + if (FileAccess::exists(tmp_icon_path)) { + DirAccess::remove_file_or_error(tmp_icon_path); + } + if (err != OK || (str.find("not found") != -1) || (str.find("not recognized") != -1)) { add_message(EXPORT_MESSAGE_WARNING, TTR("Resources Modification"), TTR("Could not start rcedit executable. Configure rcedit path in the Editor Settings (Export > Windows > rcedit), or disable \"Application > Modify Resources\" in the export preset.")); return err; @@ -271,21 +528,21 @@ Error EditorExportPlatformWindows::_code_sign(const Ref<EditorExportPreset> &p_p //identity #ifdef WINDOWS_ENABLED - int id_type = p_preset->get("codesign/identity_type"); + int id_type = p_preset->get_or_env("codesign/identity_type", ENV_WIN_CODESIGN_ID_TYPE); if (id_type == 0) { //auto select args.push_back("/a"); } else if (id_type == 1) { //pkcs12 - if (p_preset->get("codesign/identity") != "") { + if (p_preset->get_or_env("codesign/identity", ENV_WIN_CODESIGN_ID) != "") { args.push_back("/f"); - args.push_back(p_preset->get("codesign/identity")); + args.push_back(p_preset->get_or_env("codesign/identity", ENV_WIN_CODESIGN_ID)); } else { add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), TTR("No identity found.")); return FAILED; } } else if (id_type == 2) { //Windows certificate store - if (p_preset->get("codesign/identity") != "") { + if (p_preset->get_or_env("codesign/identity", ENV_WIN_CODESIGN_ID) != "") { args.push_back("/sha1"); - args.push_back(p_preset->get("codesign/identity")); + args.push_back(p_preset->get_or_env("codesign/identity", ENV_WIN_CODESIGN_ID)); } else { add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), TTR("No identity found.")); return FAILED; @@ -295,9 +552,10 @@ Error EditorExportPlatformWindows::_code_sign(const Ref<EditorExportPreset> &p_p return FAILED; } #else - if (p_preset->get("codesign/identity") != "") { + int id_type = 1; + if (p_preset->get_or_env("codesign/identity", ENV_WIN_CODESIGN_ID) != "") { args.push_back("-pkcs12"); - args.push_back(p_preset->get("codesign/identity")); + args.push_back(p_preset->get_or_env("codesign/identity", ENV_WIN_CODESIGN_ID)); } else { add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), TTR("No identity found.")); return FAILED; @@ -305,13 +563,13 @@ Error EditorExportPlatformWindows::_code_sign(const Ref<EditorExportPreset> &p_p #endif //password - if (p_preset->get("codesign/password") != "") { + if ((id_type == 1) && (p_preset->get_or_env("codesign/password", ENV_WIN_CODESIGN_PASS) != "")) { #ifdef WINDOWS_ENABLED args.push_back("/p"); #else args.push_back("-pass"); #endif - args.push_back(p_preset->get("codesign/password")); + args.push_back(p_preset->get_or_env("codesign/password", ENV_WIN_CODESIGN_PASS)); } //timestamp @@ -379,7 +637,7 @@ Error EditorExportPlatformWindows::_code_sign(const Ref<EditorExportPreset> &p_p String str; Error err = OS::get_singleton()->execute(signtool_path, args, &str, nullptr, true); if (err != OK || (str.find("not found") != -1) || (str.find("not recognized") != -1)) { -#ifndef WINDOWS_ENABLED +#ifdef WINDOWS_ENABLED add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), TTR("Could not start signtool executable. Configure signtool path in the Editor Settings (Export > Windows > signtool), or disable \"Codesign\" in the export preset.")); #else add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), TTR("Could not start osslsigncode executable. Configure signtool path in the Editor Settings (Export > Windows > osslsigncode), or disable \"Codesign\" in the export preset.")); @@ -436,30 +694,17 @@ bool EditorExportPlatformWindows::has_valid_project_configuration(const Ref<Edit String err = ""; bool valid = true; - String icon_path = ProjectSettings::get_singleton()->globalize_path(p_preset->get("application/icon")); - if (!icon_path.is_empty() && !FileAccess::exists(icon_path)) { - err += TTR("Invalid icon path:") + " " + icon_path + "\n"; - } - - // Only non-negative integers can exist in the version string. - - String file_version = p_preset->get("application/file_version"); - if (!file_version.is_empty()) { - PackedStringArray version_array = file_version.split(".", false); - if (version_array.size() != 4 || !version_array[0].is_valid_int() || - !version_array[1].is_valid_int() || !version_array[2].is_valid_int() || - !version_array[3].is_valid_int() || file_version.find("-") > -1) { - err += TTR("Invalid file version:") + " " + file_version + "\n"; - } - } - - String product_version = p_preset->get("application/product_version"); - if (!product_version.is_empty()) { - PackedStringArray version_array = product_version.split(".", false); - if (version_array.size() != 4 || !version_array[0].is_valid_int() || - !version_array[1].is_valid_int() || !version_array[2].is_valid_int() || - !version_array[3].is_valid_int() || product_version.find("-") > -1) { - err += TTR("Invalid product version:") + " " + product_version + "\n"; + List<ExportOption> options; + get_export_options(&options); + for (const EditorExportPlatform::ExportOption &E : options) { + if (get_export_option_visibility(p_preset.ptr(), E.option.name)) { + String warn = get_export_option_warning(p_preset.ptr(), E.option.name); + if (!warn.is_empty()) { + err += warn + "\n"; + if (E.required) { + valid = false; + } + } } } @@ -548,3 +793,237 @@ Error EditorExportPlatformWindows::fixup_embedded_pck(const String &p_path, int6 } return OK; } + +Ref<Texture2D> EditorExportPlatformWindows::get_run_icon() const { + return run_icon; +} + +bool EditorExportPlatformWindows::poll_export() { + Ref<EditorExportPreset> preset; + + for (int i = 0; i < EditorExport::get_singleton()->get_export_preset_count(); i++) { + Ref<EditorExportPreset> ep = EditorExport::get_singleton()->get_export_preset(i); + if (ep->is_runnable() && ep->get_platform() == this) { + preset = ep; + break; + } + } + + int prev = menu_options; + menu_options = (preset.is_valid() && preset->get("ssh_remote_deploy/enabled").operator bool()); + if (ssh_pid != 0 || !cleanup_commands.is_empty()) { + if (menu_options == 0) { + cleanup(); + } else { + menu_options += 1; + } + } + return menu_options != prev; +} + +Ref<ImageTexture> EditorExportPlatformWindows::get_option_icon(int p_index) const { + return p_index == 1 ? stop_icon : EditorExportPlatform::get_option_icon(p_index); +} + +int EditorExportPlatformWindows::get_options_count() const { + return menu_options; +} + +String EditorExportPlatformWindows::get_option_label(int p_index) const { + return (p_index) ? TTR("Stop and uninstall") : TTR("Run on remote Windows system"); +} + +String EditorExportPlatformWindows::get_option_tooltip(int p_index) const { + return (p_index) ? TTR("Stop and uninstall running project from the remote system") : TTR("Run exported project on remote Windows system"); +} + +void EditorExportPlatformWindows::cleanup() { + if (ssh_pid != 0 && OS::get_singleton()->is_process_running(ssh_pid)) { + print_line("Terminating connection..."); + OS::get_singleton()->kill(ssh_pid); + OS::get_singleton()->delay_usec(1000); + } + + if (!cleanup_commands.is_empty()) { + print_line("Stopping and deleting previous version..."); + for (const SSHCleanupCommand &cmd : cleanup_commands) { + if (cmd.wait) { + ssh_run_on_remote(cmd.host, cmd.port, cmd.ssh_args, cmd.cmd_args); + } else { + ssh_run_on_remote_no_wait(cmd.host, cmd.port, cmd.ssh_args, cmd.cmd_args); + } + } + } + ssh_pid = 0; + cleanup_commands.clear(); +} + +Error EditorExportPlatformWindows::run(const Ref<EditorExportPreset> &p_preset, int p_device, int p_debug_flags) { + cleanup(); + if (p_device) { // Stop command, cleanup only. + return OK; + } + + EditorProgress ep("run", TTR("Running..."), 5); + + const String dest = EditorPaths::get_singleton()->get_cache_dir().path_join("windows"); + Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + if (!da->dir_exists(dest)) { + Error err = da->make_dir_recursive(dest); + if (err != OK) { + EditorNode::get_singleton()->show_warning(TTR("Could not create temp directory:") + "\n" + dest); + return err; + } + } + + String host = p_preset->get("ssh_remote_deploy/host").operator String(); + String port = p_preset->get("ssh_remote_deploy/port").operator String(); + if (port.is_empty()) { + port = "22"; + } + Vector<String> extra_args_ssh = p_preset->get("ssh_remote_deploy/extra_args_ssh").operator String().split(" ", false); + Vector<String> extra_args_scp = p_preset->get("ssh_remote_deploy/extra_args_scp").operator String().split(" ", false); + + const String basepath = dest.path_join("tmp_windows_export"); + +#define CLEANUP_AND_RETURN(m_err) \ + { \ + if (da->file_exists(basepath + ".zip")) { \ + da->remove(basepath + ".zip"); \ + } \ + if (da->file_exists(basepath + "_start.ps1")) { \ + da->remove(basepath + "_start.ps1"); \ + } \ + if (da->file_exists(basepath + "_clean.ps1")) { \ + da->remove(basepath + "_clean.ps1"); \ + } \ + return m_err; \ + } \ + ((void)0) + + if (ep.step(TTR("Exporting project..."), 1)) { + return ERR_SKIP; + } + Error err = export_project(p_preset, true, basepath + ".zip", p_debug_flags); + if (err != OK) { + DirAccess::remove_file_or_error(basepath + ".zip"); + return err; + } + + String cmd_args; + { + Vector<String> cmd_args_list; + gen_debug_flags(cmd_args_list, p_debug_flags); + for (int i = 0; i < cmd_args_list.size(); i++) { + if (i != 0) { + cmd_args += " "; + } + cmd_args += cmd_args_list[i]; + } + } + + const bool use_remote = (p_debug_flags & DEBUG_FLAG_REMOTE_DEBUG) || (p_debug_flags & DEBUG_FLAG_DUMB_CLIENT); + int dbg_port = EditorSettings::get_singleton()->get("network/debug/remote_port"); + + print_line("Creating temporary directory..."); + ep.step(TTR("Creating temporary directory..."), 2); + String temp_dir; +#ifndef WINDOWS_ENABLED + err = ssh_run_on_remote(host, port, extra_args_ssh, "powershell -command \\\"\\$tmp = Join-Path \\$Env:Temp \\$(New-Guid); New-Item -Type Directory -Path \\$tmp | Out-Null; Write-Output \\$tmp\\\"", &temp_dir); +#else + err = ssh_run_on_remote(host, port, extra_args_ssh, "powershell -command \"$tmp = Join-Path $Env:Temp $(New-Guid); New-Item -Type Directory -Path $tmp ^| Out-Null; Write-Output $tmp\"", &temp_dir); +#endif + if (err != OK || temp_dir.is_empty()) { + CLEANUP_AND_RETURN(err); + } + + print_line("Uploading archive..."); + ep.step(TTR("Uploading archive..."), 3); + err = ssh_push_to_remote(host, port, extra_args_scp, basepath + ".zip", temp_dir); + if (err != OK) { + CLEANUP_AND_RETURN(err); + } + + if (cmd_args.is_empty()) { + cmd_args = " "; + } + + { + String run_script = p_preset->get("ssh_remote_deploy/run_script"); + run_script = run_script.replace("{temp_dir}", temp_dir); + run_script = run_script.replace("{archive_name}", basepath.get_file() + ".zip"); + run_script = run_script.replace("{exe_name}", basepath.get_file() + ".exe"); + run_script = run_script.replace("{cmd_args}", cmd_args); + + Ref<FileAccess> f = FileAccess::open(basepath + "_start.ps1", FileAccess::WRITE); + if (f.is_null()) { + CLEANUP_AND_RETURN(err); + } + + f->store_string(run_script); + } + + { + String clean_script = p_preset->get("ssh_remote_deploy/cleanup_script"); + clean_script = clean_script.replace("{temp_dir}", temp_dir); + clean_script = clean_script.replace("{archive_name}", basepath.get_file() + ".zip"); + clean_script = clean_script.replace("{exe_name}", basepath.get_file() + ".exe"); + clean_script = clean_script.replace("{cmd_args}", cmd_args); + + Ref<FileAccess> f = FileAccess::open(basepath + "_clean.ps1", FileAccess::WRITE); + if (f.is_null()) { + CLEANUP_AND_RETURN(err); + } + + f->store_string(clean_script); + } + + print_line("Uploading scripts..."); + ep.step(TTR("Uploading scripts..."), 4); + err = ssh_push_to_remote(host, port, extra_args_scp, basepath + "_start.ps1", temp_dir); + if (err != OK) { + CLEANUP_AND_RETURN(err); + } + err = ssh_push_to_remote(host, port, extra_args_scp, basepath + "_clean.ps1", temp_dir); + if (err != OK) { + CLEANUP_AND_RETURN(err); + } + + print_line("Starting project..."); + ep.step(TTR("Starting project..."), 5); + err = ssh_run_on_remote_no_wait(host, port, extra_args_ssh, vformat("powershell -file \"%s\\%s\"", temp_dir, basepath.get_file() + "_start.ps1"), &ssh_pid, (use_remote) ? dbg_port : -1); + if (err != OK) { + CLEANUP_AND_RETURN(err); + } + + cleanup_commands.clear(); + cleanup_commands.push_back(SSHCleanupCommand(host, port, extra_args_ssh, vformat("powershell -file \"%s\\%s\"", temp_dir, basepath.get_file() + "_clean.ps1"))); + + print_line("Project started."); + + CLEANUP_AND_RETURN(OK); +#undef CLEANUP_AND_RETURN +} + +EditorExportPlatformWindows::EditorExportPlatformWindows() { + if (EditorNode::get_singleton()) { +#ifdef MODULE_SVG_ENABLED + Ref<Image> img = memnew(Image); + const bool upsample = !Math::is_equal_approx(Math::round(EDSCALE), EDSCALE); + + ImageLoaderSVG img_loader; + img_loader.create_image_from_string(img, _windows_logo_svg, EDSCALE, upsample, false); + set_logo(ImageTexture::create_from_image(img)); + + img_loader.create_image_from_string(img, _windows_run_icon_svg, EDSCALE, upsample, false); + run_icon = ImageTexture::create_from_image(img); +#endif + + Ref<Theme> theme = EditorNode::get_singleton()->get_editor_theme(); + if (theme.is_valid()) { + stop_icon = theme->get_icon(SNAME("Stop"), SNAME("EditorIcons")); + } else { + stop_icon.instantiate(); + } + } +} diff --git a/platform/windows/export/export_plugin.h b/platform/windows/export/export_plugin.h index f85331c898..184b2f96f8 100644 --- a/platform/windows/export/export_plugin.h +++ b/platform/windows/export/export_plugin.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* export_plugin.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* export_plugin.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 WINDOWS_EXPORT_PLUGIN_H #define WINDOWS_EXPORT_PLUGIN_H @@ -35,24 +35,68 @@ #include "core/os/os.h" #include "editor/editor_settings.h" #include "editor/export/editor_export_platform_pc.h" -#include "platform/windows/logo.gen.h" + +// Optional environment variables for defining confidential information. If any +// of these is set, they will override the values set in the credentials file. +const String ENV_WIN_CODESIGN_ID_TYPE = "GODOT_WINDOWS_CODESIGN_IDENTITY_TYPE"; +const String ENV_WIN_CODESIGN_ID = "GODOT_WINDOWS_CODESIGN_IDENTITY"; +const String ENV_WIN_CODESIGN_PASS = "GODOT_WINDOWS_CODESIGN_PASSWORD"; class EditorExportPlatformWindows : public EditorExportPlatformPC { - Error _rcedit_add_data(const Ref<EditorExportPreset> &p_preset, const String &p_path); + GDCLASS(EditorExportPlatformWindows, EditorExportPlatformPC); + + struct SSHCleanupCommand { + String host; + String port; + Vector<String> ssh_args; + String cmd_args; + bool wait = false; + + SSHCleanupCommand(){}; + SSHCleanupCommand(const String &p_host, const String &p_port, const Vector<String> &p_ssh_arg, const String &p_cmd_args, bool p_wait = false) { + host = p_host; + port = p_port; + ssh_args = p_ssh_arg; + cmd_args = p_cmd_args; + wait = p_wait; + }; + }; + + Ref<ImageTexture> run_icon; + Ref<ImageTexture> stop_icon; + + Vector<SSHCleanupCommand> cleanup_commands; + OS::ProcessID ssh_pid = 0; + int menu_options = 0; + + Error _process_icon(const Ref<EditorExportPreset> &p_preset, const String &p_src_path, const String &p_dst_path); + Error _rcedit_add_data(const Ref<EditorExportPreset> &p_preset, const String &p_path, bool p_console_icon); Error _code_sign(const Ref<EditorExportPreset> &p_preset, const String &p_path); - Error _export_debug_script(const Ref<EditorExportPreset> &p_preset, const String &p_app_name, const String &p_pkg_name, const String &p_path); public: virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0) override; virtual Error modify_template(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) override; virtual Error sign_shared_object(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path) override; virtual List<String> get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const override; - virtual void get_export_options(List<ExportOption> *r_options) override; + virtual void get_export_options(List<ExportOption> *r_options) const override; virtual bool has_valid_export_configuration(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const override; virtual bool has_valid_project_configuration(const Ref<EditorExportPreset> &p_preset, String &r_error) const override; - virtual bool get_export_option_visibility(const EditorExportPreset *p_preset, const String &p_option, const HashMap<StringName, Variant> &p_options) const override; + virtual bool get_export_option_visibility(const EditorExportPreset *p_preset, const String &p_option) const override; + virtual String get_export_option_warning(const EditorExportPreset *p_preset, const StringName &p_name) const override; + virtual String get_template_file_name(const String &p_target, const String &p_arch) const override; virtual Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size) override; + + virtual Ref<Texture2D> get_run_icon() const override; + virtual bool poll_export() override; + virtual Ref<ImageTexture> get_option_icon(int p_index) const override; + virtual int get_options_count() const override; + virtual String get_option_label(int p_index) const override; + virtual String get_option_tooltip(int p_index) const override; + virtual Error run(const Ref<EditorExportPreset> &p_preset, int p_device, int p_debug_flags) override; + virtual void cleanup() override; + + EditorExportPlatformWindows(); }; #endif // WINDOWS_EXPORT_PLUGIN_H diff --git a/platform/windows/gl_manager_windows.cpp b/platform/windows/gl_manager_windows.cpp index 7689751f1b..0334bdd973 100644 --- a/platform/windows/gl_manager_windows.cpp +++ b/platform/windows/gl_manager_windows.cpp @@ -1,42 +1,45 @@ -/*************************************************************************/ -/* gl_manager_windows.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* gl_manager_windows.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "gl_manager_windows.h" -#ifdef WINDOWS_ENABLED -#ifdef GLES3_ENABLED +#if defined(WINDOWS_ENABLED) && defined(GLES3_ENABLED) -#include <stdio.h> -#include <stdlib.h> +#include "core/config/project_settings.h" +#include "core/version.h" + +#include "thirdparty/nvapi/nvapi_minimal.h" #include <dwmapi.h> +#include <stdio.h> +#include <stdlib.h> #define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 #define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 @@ -66,6 +69,171 @@ static String format_error_message(DWORD id) { return msg; } +const int OGL_THREAD_CONTROL_ID = 0x20C1221E; +const int OGL_THREAD_CONTROL_DISABLE = 0x00000002; +const int OGL_THREAD_CONTROL_ENABLE = 0x00000001; + +typedef int(__cdecl *NvAPI_Initialize_t)(); +typedef int(__cdecl *NvAPI_Unload_t)(); +typedef int(__cdecl *NvAPI_GetErrorMessage_t)(unsigned int, NvAPI_ShortString); +typedef int(__cdecl *NvAPI_DRS_CreateSession_t)(NvDRSSessionHandle *); +typedef int(__cdecl *NvAPI_DRS_DestroySession_t)(NvDRSSessionHandle); +typedef int(__cdecl *NvAPI_DRS_LoadSettings_t)(NvDRSSessionHandle); +typedef int(__cdecl *NvAPI_DRS_CreateProfile_t)(NvDRSSessionHandle, NVDRS_PROFILE *, NvDRSProfileHandle *); +typedef int(__cdecl *NvAPI_DRS_CreateApplication_t)(NvDRSSessionHandle, NvDRSProfileHandle, NVDRS_APPLICATION *); +typedef int(__cdecl *NvAPI_DRS_SaveSettings_t)(NvDRSSessionHandle); +typedef int(__cdecl *NvAPI_DRS_SetSetting_t)(NvDRSSessionHandle, NvDRSProfileHandle, NVDRS_SETTING *); +typedef int(__cdecl *NvAPI_DRS_FindProfileByName_t)(NvDRSSessionHandle, NvAPI_UnicodeString, NvDRSProfileHandle *); +NvAPI_GetErrorMessage_t NvAPI_GetErrorMessage__; + +static bool nvapi_err_check(const char *msg, int status) { + if (status != 0) { + if (OS::get_singleton()->is_stdout_verbose()) { + NvAPI_ShortString err_desc = { 0 }; + NvAPI_GetErrorMessage__(status, err_desc); + print_verbose(vformat("%s: %s(code %d)", msg, err_desc, status)); + } + return false; + } + return true; +} + +// On windows we have to disable threaded optimization when using NVIDIA graphics cards +// to avoid stuttering, see https://github.com/microsoft/vscode-cpptools/issues/6592 +// also see https://github.com/Ryujinx/Ryujinx/blob/master/Ryujinx.Common/GraphicsDriver/NVThreadedOptimization.cs +void GLManager_Windows::_nvapi_disable_threaded_optimization() { + HMODULE nvapi = 0; +#ifdef _WIN64 + nvapi = LoadLibraryA("nvapi64.dll"); +#else + nvapi = LoadLibraryA("nvapi.dll"); +#endif + + if (nvapi == NULL) { + return; + } + + void *(__cdecl * NvAPI_QueryInterface)(unsigned int interface_id) = 0; + + NvAPI_QueryInterface = (void *(__cdecl *)(unsigned int))GetProcAddress(nvapi, "nvapi_QueryInterface"); + + if (NvAPI_QueryInterface == NULL) { + print_verbose("Error getting NVAPI NvAPI_QueryInterface"); + return; + } + + // Setup NVAPI function pointers + NvAPI_Initialize_t NvAPI_Initialize = (NvAPI_Initialize_t)NvAPI_QueryInterface(0x0150E828); + NvAPI_GetErrorMessage__ = (NvAPI_GetErrorMessage_t)NvAPI_QueryInterface(0x6C2D048C); + NvAPI_DRS_CreateSession_t NvAPI_DRS_CreateSession = (NvAPI_DRS_CreateSession_t)NvAPI_QueryInterface(0x0694D52E); + NvAPI_DRS_DestroySession_t NvAPI_DRS_DestroySession = (NvAPI_DRS_DestroySession_t)NvAPI_QueryInterface(0xDAD9CFF8); + NvAPI_Unload_t NvAPI_Unload = (NvAPI_Unload_t)NvAPI_QueryInterface(0xD22BDD7E); + NvAPI_DRS_LoadSettings_t NvAPI_DRS_LoadSettings = (NvAPI_DRS_LoadSettings_t)NvAPI_QueryInterface(0x375DBD6B); + NvAPI_DRS_CreateProfile_t NvAPI_DRS_CreateProfile = (NvAPI_DRS_CreateProfile_t)NvAPI_QueryInterface(0xCC176068); + NvAPI_DRS_CreateApplication_t NvAPI_DRS_CreateApplication = (NvAPI_DRS_CreateApplication_t)NvAPI_QueryInterface(0x4347A9DE); + NvAPI_DRS_SaveSettings_t NvAPI_DRS_SaveSettings = (NvAPI_DRS_SaveSettings_t)NvAPI_QueryInterface(0xFCBC7E14); + NvAPI_DRS_SetSetting_t NvAPI_DRS_SetSetting = (NvAPI_DRS_SetSetting_t)NvAPI_QueryInterface(0x577DD202); + NvAPI_DRS_FindProfileByName_t NvAPI_DRS_FindProfileByName = (NvAPI_DRS_FindProfileByName_t)NvAPI_QueryInterface(0x7E4A9A0B); + + if (!nvapi_err_check("NVAPI: Init failed", NvAPI_Initialize())) { + return; + } + + print_verbose("NVAPI: Init OK!"); + + NvDRSSessionHandle session_handle; + + if (!nvapi_err_check("NVAPI: Error creating DRS session", NvAPI_DRS_CreateSession(&session_handle))) { + NvAPI_Unload(); + return; + } + + if (!nvapi_err_check("NVAPI: Error loading DRS settings", NvAPI_DRS_LoadSettings(session_handle))) { + NvAPI_DRS_DestroySession(session_handle); + NvAPI_Unload(); + return; + } + + String app_executable_name = OS::get_singleton()->get_executable_path().get_file(); + String app_friendly_name = GLOBAL_GET("application/config/name"); + // We need a name anyways, so let's use the engine name if an application name is not available + // (this is used mostly by the Project Manager) + if (app_friendly_name.is_empty()) { + app_friendly_name = VERSION_NAME; + } + String app_profile_name = app_friendly_name + " Nvidia Profile"; + Char16String app_profile_name_u16 = app_profile_name.utf16(); + Char16String app_executable_name_u16 = app_executable_name.utf16(); + Char16String app_friendly_name_u16 = app_friendly_name.utf16(); + + NvDRSProfileHandle profile_handle = 0; + + int status = NvAPI_DRS_FindProfileByName(session_handle, (NvU16 *)(app_profile_name_u16.ptrw()), &profile_handle); + + if (status != 0) { + print_verbose("NVAPI: Profile not found, creating...."); + + NVDRS_PROFILE profile_info; + profile_info.version = NVDRS_PROFILE_VER; + profile_info.isPredefined = 0; + memcpy(profile_info.profileName, app_profile_name_u16.get_data(), sizeof(char16_t) * app_profile_name_u16.size()); + + if (!nvapi_err_check("NVAPI: Error creating profile", NvAPI_DRS_CreateProfile(session_handle, &profile_info, &profile_handle))) { + NvAPI_DRS_DestroySession(session_handle); + NvAPI_Unload(); + return; + } + + NVDRS_APPLICATION_V4 app; + app.version = NVDRS_APPLICATION_VER_V4; + app.isPredefined = 0; + app.isMetro = 1; + app.isCommandLine = 1; + memcpy(app.appName, app_executable_name_u16.get_data(), sizeof(char16_t) * app_executable_name_u16.size()); + memcpy(app.userFriendlyName, app_friendly_name_u16.get_data(), sizeof(char16_t) * app_friendly_name_u16.size()); + memcpy(app.launcher, L"", 1); + memcpy(app.fileInFolder, L"", 1); + + if (!nvapi_err_check("NVAPI: Error creating application", NvAPI_DRS_CreateApplication(session_handle, profile_handle, &app))) { + NvAPI_DRS_DestroySession(session_handle); + NvAPI_Unload(); + return; + } + } + + NVDRS_SETTING setting; + setting.version = NVDRS_SETTING_VER; + setting.settingId = OGL_THREAD_CONTROL_ID; + setting.settingType = NVDRS_DWORD_TYPE; + setting.settingLocation = NVDRS_CURRENT_PROFILE_LOCATION; + setting.isCurrentPredefined = 0; + setting.isPredefinedValid = 0; + int thread_control_val = OGL_THREAD_CONTROL_DISABLE; + if (!GLOBAL_GET("rendering/gl_compatibility/nvidia_disable_threaded_optimization")) { + thread_control_val = OGL_THREAD_CONTROL_ENABLE; + } + setting.u32CurrentValue = thread_control_val; + setting.u32PredefinedValue = thread_control_val; + + if (!nvapi_err_check("NVAPI: Error calling NvAPI_DRS_SetSetting", NvAPI_DRS_SetSetting(session_handle, profile_handle, &setting))) { + NvAPI_DRS_DestroySession(session_handle); + NvAPI_Unload(); + return; + } + + if (!nvapi_err_check("NVAPI: Error saving settings", NvAPI_DRS_SaveSettings(session_handle))) { + NvAPI_DRS_DestroySession(session_handle); + NvAPI_Unload(); + return; + } + if (thread_control_val == OGL_THREAD_CONTROL_DISABLE) { + print_verbose("NVAPI: Disabled OpenGL threaded optimization successfully"); + } else { + print_verbose("NVAPI: Enabled OpenGL threaded optimization successfully"); + } + NvAPI_DRS_DestroySession(session_handle); +} + int GLManager_Windows::_find_or_create_display(GLWindow &win) { // find display NYI, only 1 supported so far if (_displays.size()) { @@ -185,6 +353,10 @@ Error GLManager_Windows::_create_context(GLWindow &win, GLDisplay &gl_display) { return ERR_CANT_CREATE; } + if (!wglSwapIntervalEXT) { + wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT"); + } + return OK; } @@ -293,50 +465,41 @@ void GLManager_Windows::swap_buffers() { } Error GLManager_Windows::initialize() { - wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT"); - wglGetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXTPROC)wglGetProcAddress("wglGetSwapIntervalEXT"); - //glWrapperInit(wrapper_get_proc_address); - + _nvapi_disable_threaded_optimization(); return OK; } -void GLManager_Windows::set_use_vsync(bool p_use) { - /* - static bool setup = false; - static PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT = nullptr; - static PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalMESA = nullptr; - static PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalSGI = nullptr; - - if (!setup) { - setup = true; - String extensions = glXQueryExtensionsString(x11_display, DefaultScreen(x11_display)); - if (extensions.find("GLX_EXT_swap_control") != -1) { - glXSwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC)glXGetProcAddressARB((const GLubyte *)"glXSwapIntervalEXT"); - } - if (extensions.find("GLX_MESA_swap_control") != -1) { - glXSwapIntervalMESA = (PFNGLXSWAPINTERVALSGIPROC)glXGetProcAddressARB((const GLubyte *)"glXSwapIntervalMESA"); - } - if (extensions.find("GLX_SGI_swap_control") != -1) { - glXSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)glXGetProcAddressARB((const GLubyte *)"glXSwapIntervalSGI"); - } +void GLManager_Windows::set_use_vsync(DisplayServer::WindowID p_window_id, bool p_use) { + GLWindow &win = get_window(p_window_id); + GLWindow *current = _current_window; + + if (&win != _current_window) { + window_make_current(p_window_id); } - int val = p_use ? 1 : 0; - if (glXSwapIntervalMESA) { - glXSwapIntervalMESA(val); - } else if (glXSwapIntervalSGI) { - glXSwapIntervalSGI(val); - } else if (glXSwapIntervalEXT) { - GLXDrawable drawable = glXGetCurrentDrawable(); - glXSwapIntervalEXT(x11_display, drawable, val); - } else { - return; + + if (wglSwapIntervalEXT) { + win.use_vsync = p_use; + wglSwapIntervalEXT(p_use ? 1 : 0); + } + + if (current != _current_window) { + _current_window = current; + make_current(); } - use_vsync = p_use; - */ } -bool GLManager_Windows::is_using_vsync() const { - return use_vsync; +bool GLManager_Windows::is_using_vsync(DisplayServer::WindowID p_window_id) const { + return get_window(p_window_id).use_vsync; +} + +HDC GLManager_Windows::get_hdc(DisplayServer::WindowID p_window_id) { + return get_window(p_window_id).hDC; +} + +HGLRC GLManager_Windows::get_hglrc(DisplayServer::WindowID p_window_id) { + const GLWindow &win = get_window(p_window_id); + const GLDisplay &disp = get_display(win.gldisplay_id); + return disp.hRC; } GLManager_Windows::GLManager_Windows(ContextType p_context_type) { @@ -344,7 +507,6 @@ GLManager_Windows::GLManager_Windows(ContextType p_context_type) { direct_render = false; glx_minor = glx_major = 0; - use_vsync = false; _current_window = nullptr; } @@ -352,5 +514,4 @@ GLManager_Windows::~GLManager_Windows() { release_current(); } -#endif // GLES3_ENABLED -#endif // WINDOWS +#endif // WINDOWS_ENABLED && GLES3_ENABLED diff --git a/platform/windows/gl_manager_windows.h b/platform/windows/gl_manager_windows.h index 5e43a3de2a..482b00a1ba 100644 --- a/platform/windows/gl_manager_windows.h +++ b/platform/windows/gl_manager_windows.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* gl_manager_windows.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* gl_manager_windows.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 GL_MANAGER_WINDOWS_H #define GL_MANAGER_WINDOWS_H @@ -54,6 +54,7 @@ private: struct GLWindow { int width = 0; int height = 0; + bool use_vsync = false; // windows specific HDC hDC; @@ -72,8 +73,7 @@ private: GLWindow *_current_window = nullptr; - PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT; - PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT; + PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = nullptr; // funcs void _internal_set_current_window(GLWindow *p_win); @@ -86,10 +86,10 @@ private: bool direct_render; int glx_minor, glx_major; - bool use_vsync; ContextType context_type; private: + void _nvapi_disable_threaded_optimization(); int _find_or_create_display(GLWindow &win); Error _create_context(GLWindow &win, GLDisplay &gl_display); @@ -110,13 +110,16 @@ public: Error initialize(); - void set_use_vsync(bool p_use); - bool is_using_vsync() const; + void set_use_vsync(DisplayServer::WindowID p_window_id, bool p_use); + bool is_using_vsync(DisplayServer::WindowID p_window_id) const; + + HDC get_hdc(DisplayServer::WindowID p_window_id); + HGLRC get_hglrc(DisplayServer::WindowID p_window_id); GLManager_Windows(ContextType p_context_type); ~GLManager_Windows(); }; -#endif // defined(WINDOWS_ENABLED) && defined(GLES3_ENABLED) +#endif // WINDOWS_ENABLED && GLES3_ENABLED #endif // GL_MANAGER_WINDOWS_H diff --git a/platform/windows/godot.ico b/platform/windows/godot.ico Binary files differindex 25830ffdc6..f0bb68225d 100644 --- a/platform/windows/godot.ico +++ b/platform/windows/godot.ico diff --git a/platform/windows/godot_console.ico b/platform/windows/godot_console.ico Binary files differnew file mode 100644 index 0000000000..1d27e3d6ae --- /dev/null +++ b/platform/windows/godot_console.ico diff --git a/platform/windows/godot_res_wrap.rc b/platform/windows/godot_res_wrap.rc new file mode 100644 index 0000000000..9dd29afe51 --- /dev/null +++ b/platform/windows/godot_res_wrap.rc @@ -0,0 +1,33 @@ +#include "core/version.h" +#ifndef _STR +#define _STR(m_x) #m_x +#define _MKSTR(m_x) _STR(m_x) +#endif + +GODOT_ICON ICON platform/windows/godot_console.ico + +1 VERSIONINFO +FILEVERSION VERSION_MAJOR,VERSION_MINOR,VERSION_PATCH,0 +PRODUCTVERSION VERSION_MAJOR,VERSION_MINOR,VERSION_PATCH,0 +FILEOS 4 +FILETYPE 1 +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "Godot Engine" + VALUE "FileDescription", VERSION_NAME " (Console)" + VALUE "FileVersion", VERSION_NUMBER + VALUE "ProductName", VERSION_NAME " (Console)" + VALUE "Licence", "MIT" + VALUE "LegalCopyright", "Copyright (c) 2007-" _MKSTR(VERSION_YEAR) " Juan Linietsky, Ariel Manzur and contributors" + VALUE "Info", "https://godotengine.org" + VALUE "ProductVersion", VERSION_FULL_BUILD + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END diff --git a/platform/windows/godot_windows.cpp b/platform/windows/godot_windows.cpp index 13602f7cbc..8d63b1747e 100644 --- a/platform/windows/godot_windows.cpp +++ b/platform/windows/godot_windows.cpp @@ -1,36 +1,37 @@ -/*************************************************************************/ -/* godot_windows.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* godot_windows.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "main/main.h" #include "os_windows.h" +#include "main/main.h" + #include <locale.h> #include <stdio.h> diff --git a/platform/windows/joypad_windows.cpp b/platform/windows/joypad_windows.cpp index 2b5c8cad48..487cb56ba0 100644 --- a/platform/windows/joypad_windows.cpp +++ b/platform/windows/joypad_windows.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* joypad_windows.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* joypad_windows.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "joypad_windows.h" @@ -101,10 +101,26 @@ bool JoypadWindows::is_xinput_device(const GUID *p_guid) { static GUID IID_ValveStreamingGamepad = { MAKELONG(0x28DE, 0x11FF), 0x28DE, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } }; static GUID IID_X360WiredGamepad = { MAKELONG(0x045E, 0x02A1), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } }; static GUID IID_X360WirelessGamepad = { MAKELONG(0x045E, 0x028E), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } }; + static GUID IID_XSWirelessGamepad = { MAKELONG(0x045E, 0x0B13), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } }; + static GUID IID_XEliteWirelessGamepad = { MAKELONG(0x045E, 0x0B05), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } }; + static GUID IID_XOneWiredGamepad = { MAKELONG(0x045E, 0x02FF), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } }; + static GUID IID_XOneWirelessGamepad = { MAKELONG(0x045E, 0x02DD), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } }; + static GUID IID_XOneNewWirelessGamepad = { MAKELONG(0x045E, 0x02D1), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } }; + static GUID IID_XOneSWirelessGamepad = { MAKELONG(0x045E, 0x02EA), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } }; + static GUID IID_XOneSBluetoothGamepad = { MAKELONG(0x045E, 0x02E0), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } }; + static GUID IID_XOneEliteWirelessGamepad = { MAKELONG(0x045E, 0x02E3), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } }; if (memcmp(p_guid, &IID_ValveStreamingGamepad, sizeof(*p_guid)) == 0 || memcmp(p_guid, &IID_X360WiredGamepad, sizeof(*p_guid)) == 0 || - memcmp(p_guid, &IID_X360WirelessGamepad, sizeof(*p_guid)) == 0) + memcmp(p_guid, &IID_X360WirelessGamepad, sizeof(*p_guid)) == 0 || + memcmp(p_guid, &IID_XSWirelessGamepad, sizeof(*p_guid)) == 0 || + memcmp(p_guid, &IID_XEliteWirelessGamepad, sizeof(*p_guid)) == 0 || + memcmp(p_guid, &IID_XOneWiredGamepad, sizeof(*p_guid)) == 0 || + memcmp(p_guid, &IID_XOneWirelessGamepad, sizeof(*p_guid)) == 0 || + memcmp(p_guid, &IID_XOneNewWirelessGamepad, sizeof(*p_guid)) == 0 || + memcmp(p_guid, &IID_XOneSWirelessGamepad, sizeof(*p_guid)) == 0 || + memcmp(p_guid, &IID_XOneSBluetoothGamepad, sizeof(*p_guid)) == 0 || + memcmp(p_guid, &IID_XOneEliteWirelessGamepad, sizeof(*p_guid)) == 0) return true; PRAWINPUTDEVICELIST dev_list = nullptr; @@ -420,38 +436,43 @@ void JoypadWindows::process_joypads() { } void JoypadWindows::post_hat(int p_device, DWORD p_dpad) { - HatMask dpad_val = (HatMask)0; + BitField<HatMask> dpad_val; // Should be -1 when centered, but according to docs: // "Some drivers report the centered position of the POV indicator as 65,535. Determine whether the indicator is centered as follows: // BOOL POVCentered = (LOWORD(dwPOV) == 0xFFFF);" // https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ee416628(v%3Dvs.85)#remarks if (LOWORD(p_dpad) == 0xFFFF) { - dpad_val = (HatMask)HatMask::CENTER; + // Do nothing. + // dpad_val.set_flag(HatMask::CENTER); } if (p_dpad == 0) { - dpad_val = (HatMask)HatMask::UP; + dpad_val.set_flag(HatMask::UP); } else if (p_dpad == 4500) { - dpad_val = (HatMask)(HatMask::UP | HatMask::RIGHT); + dpad_val.set_flag(HatMask::UP); + dpad_val.set_flag(HatMask::RIGHT); } else if (p_dpad == 9000) { - dpad_val = (HatMask)HatMask::RIGHT; + dpad_val.set_flag(HatMask::RIGHT); } else if (p_dpad == 13500) { - dpad_val = (HatMask)(HatMask::RIGHT | HatMask::DOWN); + dpad_val.set_flag(HatMask::RIGHT); + dpad_val.set_flag(HatMask::DOWN); } else if (p_dpad == 18000) { - dpad_val = (HatMask)HatMask::DOWN; + dpad_val.set_flag(HatMask::DOWN); } else if (p_dpad == 22500) { - dpad_val = (HatMask)(HatMask::DOWN | HatMask::LEFT); + dpad_val.set_flag(HatMask::DOWN); + dpad_val.set_flag(HatMask::LEFT); } else if (p_dpad == 27000) { - dpad_val = (HatMask)HatMask::LEFT; + dpad_val.set_flag(HatMask::LEFT); } else if (p_dpad == 31500) { - dpad_val = (HatMask)(HatMask::LEFT | HatMask::UP); + dpad_val.set_flag(HatMask::LEFT); + dpad_val.set_flag(HatMask::UP); } input->joy_hat(p_device, dpad_val); } @@ -509,11 +530,13 @@ void JoypadWindows::joypad_vibration_stop_xinput(int p_device, uint64_t p_timest void JoypadWindows::load_xinput() { xinput_get_state = &_xinput_get_state; xinput_set_state = &_xinput_set_state; + bool legacy_xinput = false; xinput_dll = LoadLibrary("XInput1_4.dll"); if (!xinput_dll) { xinput_dll = LoadLibrary("XInput1_3.dll"); if (!xinput_dll) { xinput_dll = LoadLibrary("XInput9_1_0.dll"); + legacy_xinput = true; } } @@ -522,7 +545,9 @@ void JoypadWindows::load_xinput() { return; } - XInputGetState_t func = (XInputGetState_t)GetProcAddress((HMODULE)xinput_dll, "XInputGetState"); + // (LPCSTR)100 is the magic number to get XInputGetStateEx, which also provides the state for the guide button + LPCSTR get_state_func_name = legacy_xinput ? "XInputGetState" : (LPCSTR)100; + XInputGetState_t func = (XInputGetState_t)GetProcAddress((HMODULE)xinput_dll, get_state_func_name); XInputSetState_t set_func = (XInputSetState_t)GetProcAddress((HMODULE)xinput_dll, "XInputSetState"); if (!func || !set_func) { unload_xinput(); diff --git a/platform/windows/joypad_windows.h b/platform/windows/joypad_windows.h index 56a9f3e9c9..cfddbcc8dc 100644 --- a/platform/windows/joypad_windows.h +++ b/platform/windows/joypad_windows.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* joypad_windows.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* joypad_windows.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 JOYPAD_WINDOWS_H #define JOYPAD_WINDOWS_H @@ -35,7 +35,7 @@ #define DIRECTINPUT_VERSION 0x0800 #include <dinput.h> -#include <xinput.h> // on unix the file is called "xinput.h", on windows I'm sure it won't mind +#include <xinput.h> #ifndef SAFE_RELEASE // when Windows Media Device M? is not present #define SAFE_RELEASE(x) \ diff --git a/platform/windows/key_mapping_windows.cpp b/platform/windows/key_mapping_windows.cpp index 2d8d68a575..b376854c0c 100644 --- a/platform/windows/key_mapping_windows.cpp +++ b/platform/windows/key_mapping_windows.cpp @@ -1,519 +1,415 @@ -/*************************************************************************/ -/* key_mapping_windows.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* key_mapping_windows.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "key_mapping_windows.h" -#include <stdio.h> +#include "core/templates/hash_map.h" // This provides translation from Windows virtual key codes to Godot and back. // See WinUser.h and the below for documentation: // https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes -struct _WinTranslatePair { - Key keysym; - unsigned int keycode; +struct HashMapHasherKeys { + static _FORCE_INLINE_ uint32_t hash(const Key p_key) { return hash_fmix32(static_cast<uint32_t>(p_key)); } + static _FORCE_INLINE_ uint32_t hash(const char32_t p_uchar) { return hash_fmix32(p_uchar); } + static _FORCE_INLINE_ uint32_t hash(const unsigned p_key) { return hash_fmix32(p_key); } }; -static _WinTranslatePair _vk_to_keycode[] = { +HashMap<unsigned int, Key, HashMapHasherKeys> vk_map; +HashMap<unsigned int, Key, HashMapHasherKeys> scansym_map; +HashMap<Key, unsigned int, HashMapHasherKeys> scansym_map_inv; +HashMap<unsigned int, Key, HashMapHasherKeys> scansym_map_ext; + +void KeyMappingWindows::initialize() { // VK_LBUTTON (0x01) // VK_RBUTTON (0x02) // VK_CANCEL (0x03) // VK_MBUTTON (0x04) // VK_XBUTTON1 (0x05) - // VK_XBUTTON2 (0x06) - // We have no mappings for the above, as we only map keyboard buttons here. - + // VK_XBUTTON2 (0x06), We have no mappings for the above;as we only map keyboard buttons here. // 0x07 is undefined. - - { Key::BACKSPACE, VK_BACK }, // (0x08) - { Key::TAB, VK_TAB }, // (0x09) - + vk_map[VK_BACK] = Key::BACKSPACE; // (0x08) + vk_map[VK_TAB] = Key::TAB; // (0x09) // 0x0A-0B are reserved. - - { Key::CLEAR, VK_CLEAR }, // (0x0C) - { Key::ENTER, VK_RETURN }, // (0x0D) - + vk_map[VK_CLEAR] = Key::CLEAR; // (0x0C) + vk_map[VK_RETURN] = Key::ENTER; // (0x0D) // 0x0E-0F are undefined. - - { Key::SHIFT, VK_SHIFT }, // (0x10) - { Key::CTRL, VK_CONTROL }, // (0x11) - { Key::ALT, VK_MENU }, // (0x12) - { Key::PAUSE, VK_PAUSE }, // (0x13) - { Key::CAPSLOCK, VK_CAPITAL }, // (0x14) - - // 0x15-1A are IME keys. We have no mapping. - - { Key::ESCAPE, VK_ESCAPE }, // (0x1B) - - // 0x1C-1F are IME keys. We have no mapping. - - { Key::SPACE, VK_SPACE }, // (0x20) - { Key::PAGEUP, VK_PRIOR }, // (0x21) - { Key::PAGEDOWN, VK_NEXT }, // (0x22) - { Key::END, VK_END }, // (0x23) - { Key::HOME, VK_HOME }, // (0x24) - { Key::LEFT, VK_LEFT }, // (0x25) - { Key::UP, VK_UP }, // (0x26) - { Key::RIGHT, VK_RIGHT }, // (0x27) - { Key::DOWN, VK_DOWN }, // (0x28) - - // VK_SELECT (0x29) - // Old select key, e.g. on Digital Equipment Corporation keyboards. - // Old and uncommon, we have no mapping. - - { Key::PRINT, VK_PRINT }, // (0x2A) - // Old IBM key, modern keyboards use VK_SNAPSHOT. Map to VK_SNAPSHOT. - - // VK_EXECUTE (0x2B) - // Old and uncommon, we have no mapping. - - { Key::PRINT, VK_SNAPSHOT }, // (0x2C) - { Key::INSERT, VK_INSERT }, // (0x2D) - { Key::KEY_DELETE, VK_DELETE }, // (0x2E) - - { Key::HELP, VK_HELP }, // (0x2F) - // Old and uncommon, but we have a mapping. - - { Key::KEY_0, (0x30) }, // 0 key. - { Key::KEY_1, (0x31) }, // 1 key. - { Key::KEY_2, (0x32) }, // 2 key. - { Key::KEY_3, (0x33) }, // 3 key. - { Key::KEY_4, (0x34) }, // 4 key. - { Key::KEY_5, (0x35) }, // 5 key. - { Key::KEY_6, (0x36) }, // 6 key. - { Key::KEY_7, (0x37) }, // 7 key. - { Key::KEY_8, (0x38) }, // 8 key. - { Key::KEY_9, (0x39) }, // 9 key. + vk_map[VK_SHIFT] = Key::SHIFT; // (0x10) + vk_map[VK_CONTROL] = Key::CTRL; // (0x11) + vk_map[VK_MENU] = Key::ALT; // (0x12) + vk_map[VK_PAUSE] = Key::PAUSE; // (0x13) + vk_map[VK_CAPITAL] = Key::CAPSLOCK; // (0x14) + // 0x15-1A are IME keys. + vk_map[VK_ESCAPE] = Key::ESCAPE; // (0x1B) + // 0x1C-1F are IME keys. + vk_map[VK_SPACE] = Key::SPACE; // (0x20) + vk_map[VK_PRIOR] = Key::PAGEUP; // (0x21) + vk_map[VK_NEXT] = Key::PAGEDOWN; // (0x22) + vk_map[VK_END] = Key::END; // (0x23) + vk_map[VK_HOME] = Key::HOME; // (0x24) + vk_map[VK_LEFT] = Key::LEFT; // (0x25) + vk_map[VK_UP] = Key::UP; // (0x26) + vk_map[VK_RIGHT] = Key::RIGHT; // (0x27) + vk_map[VK_DOWN] = Key::DOWN; // (0x28) + // VK_SELECT (0x29), Old select key; e.g. on Digital Equipment Corporation keyboards. + vk_map[VK_PRINT] = Key::PRINT; // (0x2A), Old IBM key; modern keyboards use VK_SNAPSHOT. + // VK_EXECUTE (0x2B), Old and uncommon. + vk_map[VK_SNAPSHOT] = Key::PRINT; // (0x2C) + vk_map[VK_INSERT] = Key::INSERT; // (0x2D) + vk_map[VK_DELETE] = Key::KEY_DELETE; // (0x2E) + vk_map[VK_HELP] = Key::HELP; // (0x2F) + vk_map[0x30] = Key::KEY_0; // 0 key. + vk_map[0x31] = Key::KEY_1; // 1 key. + vk_map[0x32] = Key::KEY_2; // 2 key. + vk_map[0x33] = Key::KEY_3; // 3 key. + vk_map[0x34] = Key::KEY_4; // 4 key. + vk_map[0x35] = Key::KEY_5; // 5 key. + vk_map[0x36] = Key::KEY_6; // 6 key. + vk_map[0x37] = Key::KEY_7; // 7 key. + vk_map[0x38] = Key::KEY_8; // 8 key. + vk_map[0x39] = Key::KEY_9; // 9 key. // 0x3A-40 are undefined. - { Key::A, (0x41) }, // A key. - { Key::B, (0x42) }, // B key. - { Key::C, (0x43) }, // C key. - { Key::D, (0x44) }, // D key. - { Key::E, (0x45) }, // E key. - { Key::F, (0x46) }, // F key. - { Key::G, (0x47) }, // G key. - { Key::H, (0x48) }, // H key. - { Key::I, (0x49) }, // I key - { Key::J, (0x4A) }, // J key. - { Key::K, (0x4B) }, // K key. - { Key::L, (0x4C) }, // L key. - { Key::M, (0x4D) }, // M key. - { Key::N, (0x4E) }, // N key. - { Key::O, (0x4F) }, // O key. - { Key::P, (0x50) }, // P key. - { Key::Q, (0x51) }, // Q key. - { Key::R, (0x52) }, // R key. - { Key::S, (0x53) }, // S key. - { Key::T, (0x54) }, // T key. - { Key::U, (0x55) }, // U key. - { Key::V, (0x56) }, // V key. - { Key::W, (0x57) }, // W key. - { Key::X, (0x58) }, // X key. - { Key::Y, (0x59) }, // Y key. - { Key::Z, (0x5A) }, // Z key. - - { (Key)KeyModifierMask::META, VK_LWIN }, // (0x5B) - { (Key)KeyModifierMask::META, VK_RWIN }, // (0x5C) - { Key::MENU, VK_APPS }, // (0x5D) + vk_map[0x41] = Key::A; // A key. + vk_map[0x42] = Key::B; // B key. + vk_map[0x43] = Key::C; // C key. + vk_map[0x44] = Key::D; // D key. + vk_map[0x45] = Key::E; // E key. + vk_map[0x46] = Key::F; // F key. + vk_map[0x47] = Key::G; // G key. + vk_map[0x48] = Key::H; // H key. + vk_map[0x49] = Key::I; // I key + vk_map[0x4A] = Key::J; // J key. + vk_map[0x4B] = Key::K; // K key. + vk_map[0x4C] = Key::L; // L key. + vk_map[0x4D] = Key::M; // M key. + vk_map[0x4E] = Key::N; // N key. + vk_map[0x4F] = Key::O; // O key. + vk_map[0x50] = Key::P; // P key. + vk_map[0x51] = Key::Q; // Q key. + vk_map[0x52] = Key::R; // R key. + vk_map[0x53] = Key::S; // S key. + vk_map[0x54] = Key::T; // T key. + vk_map[0x55] = Key::U; // U key. + vk_map[0x56] = Key::V; // V key. + vk_map[0x57] = Key::W; // W key. + vk_map[0x58] = Key::X; // X key. + vk_map[0x59] = Key::Y; // Y key. + vk_map[0x5A] = Key::Z; // Z key. + vk_map[VK_LWIN] = (Key)Key::META; // (0x5B) + vk_map[VK_RWIN] = (Key)Key::META; // (0x5C) + vk_map[VK_APPS] = Key::MENU; // (0x5D) // 0x5E is reserved. - { Key::STANDBY, VK_SLEEP }, // (0x5F) - { Key::KP_0, VK_NUMPAD0 }, // (0x60) - { Key::KP_1, VK_NUMPAD1 }, // (0x61) - { Key::KP_2, VK_NUMPAD2 }, // (0x62) - { Key::KP_3, VK_NUMPAD3 }, // (0x63) - { Key::KP_4, VK_NUMPAD4 }, // (0x64) - { Key::KP_5, VK_NUMPAD5 }, // (0x65) - { Key::KP_6, VK_NUMPAD6 }, // (0x66) - { Key::KP_7, VK_NUMPAD7 }, // (0x67) - { Key::KP_8, VK_NUMPAD8 }, // (0x68) - { Key::KP_9, VK_NUMPAD9 }, // (0x69) - { Key::KP_MULTIPLY, VK_MULTIPLY }, // (0x6A) - { Key::KP_ADD, VK_ADD }, // (0x6B) - { Key::KP_PERIOD, VK_SEPARATOR }, // (0x6C) - // VK_SEPERATOR (key 0x6C) is not found on US keyboards. - // It is used on some Brazilian and Far East keyboards. - // We don't have a direct mapping, map to period. - { Key::KP_SUBTRACT, VK_SUBTRACT }, // (0x6D) - { Key::KP_PERIOD, VK_DECIMAL }, // (0x6E) - { Key::KP_DIVIDE, VK_DIVIDE }, // (0x6F) - { Key::F1, VK_F1 }, // (0x70) - { Key::F2, VK_F2 }, // (0x71) - { Key::F3, VK_F3 }, // (0x72) - { Key::F4, VK_F4 }, // (0x73) - { Key::F5, VK_F5 }, // (0x74) - { Key::F6, VK_F6 }, // (0x75) - { Key::F7, VK_F7 }, // (0x76) - { Key::F8, VK_F8 }, // (0x77) - { Key::F9, VK_F9 }, // (0x78) - { Key::F10, VK_F10 }, // (0x79) - { Key::F11, VK_F11 }, // (0x7A) - { Key::F12, VK_F12 }, // (0x7B) - { Key::F13, VK_F13 }, // (0x7C) - { Key::F14, VK_F14 }, // (0x7D) - { Key::F15, VK_F15 }, // (0x7E) - { Key::F16, VK_F16 }, // (0x7F) - { Key::F17, VK_F17 }, // (0x80) - { Key::F18, VK_F18 }, // (0x81) - { Key::F19, VK_F19 }, // (0x82) - { Key::F20, VK_F20 }, // (0x83) - { Key::F21, VK_F21 }, // (0x84) - { Key::F22, VK_F22 }, // (0x85) - { Key::F23, VK_F23 }, // (0x86) - { Key::F24, VK_F24 }, // (0x87) + vk_map[VK_SLEEP] = Key::STANDBY; // (0x5F) + vk_map[VK_NUMPAD0] = Key::KP_0; // (0x60) + vk_map[VK_NUMPAD1] = Key::KP_1; // (0x61) + vk_map[VK_NUMPAD2] = Key::KP_2; // (0x62) + vk_map[VK_NUMPAD3] = Key::KP_3; // (0x63) + vk_map[VK_NUMPAD4] = Key::KP_4; // (0x64) + vk_map[VK_NUMPAD5] = Key::KP_5; // (0x65) + vk_map[VK_NUMPAD6] = Key::KP_6; // (0x66) + vk_map[VK_NUMPAD7] = Key::KP_7; // (0x67) + vk_map[VK_NUMPAD8] = Key::KP_8; // (0x68) + vk_map[VK_NUMPAD9] = Key::KP_9; // (0x69) + vk_map[VK_MULTIPLY] = Key::KP_MULTIPLY; // (0x6A) + vk_map[VK_ADD] = Key::KP_ADD; // (0x6B) + vk_map[VK_SEPARATOR] = Key::KP_PERIOD; // (0x6C) + vk_map[VK_SUBTRACT] = Key::KP_SUBTRACT; // (0x6D) + vk_map[VK_DECIMAL] = Key::KP_PERIOD; // (0x6E) + vk_map[VK_DIVIDE] = Key::KP_DIVIDE; // (0x6F) + vk_map[VK_F1] = Key::F1; // (0x70) + vk_map[VK_F2] = Key::F2; // (0x71) + vk_map[VK_F3] = Key::F3; // (0x72) + vk_map[VK_F4] = Key::F4; // (0x73) + vk_map[VK_F5] = Key::F5; // (0x74) + vk_map[VK_F6] = Key::F6; // (0x75) + vk_map[VK_F7] = Key::F7; // (0x76) + vk_map[VK_F8] = Key::F8; // (0x77) + vk_map[VK_F9] = Key::F9; // (0x78) + vk_map[VK_F10] = Key::F10; // (0x79) + vk_map[VK_F11] = Key::F11; // (0x7A) + vk_map[VK_F12] = Key::F12; // (0x7B) + vk_map[VK_F13] = Key::F13; // (0x7C) + vk_map[VK_F14] = Key::F14; // (0x7D) + vk_map[VK_F15] = Key::F15; // (0x7E) + vk_map[VK_F16] = Key::F16; // (0x7F) + vk_map[VK_F17] = Key::F17; // (0x80) + vk_map[VK_F18] = Key::F18; // (0x81) + vk_map[VK_F19] = Key::F19; // (0x82) + vk_map[VK_F20] = Key::F20; // (0x83) + vk_map[VK_F21] = Key::F21; // (0x84) + vk_map[VK_F22] = Key::F22; // (0x85) + vk_map[VK_F23] = Key::F23; // (0x86) + vk_map[VK_F24] = Key::F24; // (0x87) // 0x88-8F are reserved for UI navigation. - { Key::NUMLOCK, VK_NUMLOCK }, // (0x90) - { Key::SCROLLLOCK, VK_SCROLL }, // (0x91) - - { Key::EQUAL, VK_OEM_NEC_EQUAL }, // (0x92) - // OEM NEC PC-9800 numpad '=' key. - - // 0x93-96 are OEM specific (e.g. used by Fujitsu/OASYS), we have no mappings. + vk_map[VK_NUMLOCK] = Key::NUMLOCK; // (0x90) + vk_map[VK_SCROLL] = Key::SCROLLLOCK; // (0x91) + vk_map[VK_OEM_NEC_EQUAL] = Key::EQUAL; // (0x92), OEM NEC PC-9800 numpad '=' key. + // 0x93-96 are OEM specific (e.g. used by Fujitsu/OASYS); // 0x97-9F are unassigned. - - { Key::SHIFT, VK_LSHIFT }, // (0xA0) - { Key::SHIFT, VK_RSHIFT }, // (0xA1) - { Key::CTRL, VK_LCONTROL }, // (0xA2) - { Key::CTRL, VK_RCONTROL }, // (0xA3) - { Key::MENU, VK_LMENU }, // (0xA4) - { Key::MENU, VK_RMENU }, // (0xA5) - - { Key::BACK, VK_BROWSER_BACK }, // (0xA6) - { Key::FORWARD, VK_BROWSER_FORWARD }, // (0xA7) - { Key::REFRESH, VK_BROWSER_REFRESH }, // (0xA8) - { Key::STOP, VK_BROWSER_STOP }, // (0xA9) - { Key::SEARCH, VK_BROWSER_SEARCH }, // (0xAA) - { Key::FAVORITES, VK_BROWSER_FAVORITES }, // (0xAB) - { Key::HOMEPAGE, VK_BROWSER_HOME }, // (0xAC) - { Key::VOLUMEMUTE, VK_VOLUME_MUTE }, // (0xAD) - { Key::VOLUMEDOWN, VK_VOLUME_DOWN }, // (0xAE) - { Key::VOLUMEUP, VK_VOLUME_UP }, // (0xAF) - { Key::MEDIANEXT, VK_MEDIA_NEXT_TRACK }, // (0xB0) - { Key::MEDIAPREVIOUS, VK_MEDIA_PREV_TRACK }, // (0xB1) - { Key::MEDIASTOP, VK_MEDIA_STOP }, // (0xB2) - - { Key::MEDIAPLAY, VK_MEDIA_PLAY_PAUSE }, // (0xB3) - // Media button play/pause toggle. - // Map to media play (there is no other 'play' mapping on Windows). - - { Key::LAUNCHMAIL, VK_LAUNCH_MAIL }, // (0xB4) - { Key::LAUNCHMEDIA, VK_LAUNCH_MEDIA_SELECT }, // (0xB5) - { Key::LAUNCH0, VK_LAUNCH_APP1 }, // (0xB6) - { Key::LAUNCH1, VK_LAUNCH_APP2 }, // (0xB7) - + vk_map[VK_LSHIFT] = Key::SHIFT; // (0xA0) + vk_map[VK_RSHIFT] = Key::SHIFT; // (0xA1) + vk_map[VK_LCONTROL] = Key::CTRL; // (0xA2) + vk_map[VK_RCONTROL] = Key::CTRL; // (0xA3) + vk_map[VK_LMENU] = Key::MENU; // (0xA4) + vk_map[VK_RMENU] = Key::MENU; // (0xA5) + vk_map[VK_BROWSER_BACK] = Key::BACK; // (0xA6) + vk_map[VK_BROWSER_FORWARD] = Key::FORWARD; // (0xA7) + vk_map[VK_BROWSER_REFRESH] = Key::REFRESH; // (0xA8) + vk_map[VK_BROWSER_STOP] = Key::STOP; // (0xA9) + vk_map[VK_BROWSER_SEARCH] = Key::SEARCH; // (0xAA) + vk_map[VK_BROWSER_FAVORITES] = Key::FAVORITES; // (0xAB) + vk_map[VK_BROWSER_HOME] = Key::HOMEPAGE; // (0xAC) + vk_map[VK_VOLUME_MUTE] = Key::VOLUMEMUTE; // (0xAD) + vk_map[VK_VOLUME_DOWN] = Key::VOLUMEDOWN; // (0xAE) + vk_map[VK_VOLUME_UP] = Key::VOLUMEUP; // (0xAF) + vk_map[VK_MEDIA_NEXT_TRACK] = Key::MEDIANEXT; // (0xB0) + vk_map[VK_MEDIA_PREV_TRACK] = Key::MEDIAPREVIOUS; // (0xB1) + vk_map[VK_MEDIA_STOP] = Key::MEDIASTOP; // (0xB2) + vk_map[VK_MEDIA_PLAY_PAUSE] = Key::MEDIAPLAY; // (0xB3), Media button play/pause toggle. + vk_map[VK_LAUNCH_MAIL] = Key::LAUNCHMAIL; // (0xB4) + vk_map[VK_LAUNCH_MEDIA_SELECT] = Key::LAUNCHMEDIA; // (0xB5) + vk_map[VK_LAUNCH_APP1] = Key::LAUNCH0; // (0xB6) + vk_map[VK_LAUNCH_APP2] = Key::LAUNCH1; // (0xB7) // 0xB8-B9 are reserved. - - { Key::SEMICOLON, VK_OEM_1 }, // (0xBA) - // Misc. character, can vary by keyboard/region. - // Windows 2000/XP: For US standard keyboards, the ';:' key. - - { Key::EQUAL, VK_OEM_PLUS }, // (0xBB) - // Windows 2000/XP: For any country/region, the '+' key. - { Key::COMMA, VK_OEM_COMMA }, // (0xBC) - // Windows 2000/XP: For any country/region, the ',' key. - { Key::MINUS, VK_OEM_MINUS }, // (0xBD) - // Windows 2000/XP: For any country/region, the '-' key. - { Key::PERIOD, VK_OEM_PERIOD }, // (0xBE) - // Windows 2000/XP: For any country/region, the '.' key. - - { Key::SLASH, VK_OEM_2 }, // (0xBF) - // Windows 2000/XP: For US standard keyboards, the '/?' key. - - { Key::QUOTELEFT, VK_OEM_3 }, // (0xC0) - // Windows 2000/XP: For US standard keyboards, the '`~' key. - + vk_map[VK_OEM_1] = Key::SEMICOLON; // (0xBA), Misc. character;can vary by keyboard/region. For US standard keyboards;the ';:' key. + vk_map[VK_OEM_PLUS] = Key::EQUAL; // (0xBB) + vk_map[VK_OEM_COMMA] = Key::COMMA; // (0xBC) + vk_map[VK_OEM_MINUS] = Key::MINUS; // (0xBD) + vk_map[VK_OEM_PERIOD] = Key::PERIOD; // (0xBE) + vk_map[VK_OEM_2] = Key::SLASH; // (0xBF), For US standard keyboards;the '/?' key. + vk_map[VK_OEM_3] = Key::QUOTELEFT; // (0xC0), For US standard keyboards;the '`~' key. // 0xC1-D7 are reserved. 0xD8-DA are unassigned. - // TODO: 0xC3-DA may be used for old gamepads? Maybe we want to support this? See WinUser.h. - - { Key::BRACKETLEFT, VK_OEM_4 }, // (0xDB) - // Misc. character, can vary by keyboard/region. - // Windows 2000/XP: For US standard keyboards, the '[{' key. - - { Key::BACKSLASH, VK_OEM_5 }, // (0xDC) - // Misc. character, can vary by keyboard/region. - // Windows 2000/XP: For US standard keyboards, the '\|' key. - - { Key::BRACKETRIGHT, VK_OEM_6 }, // (0xDD) - // Misc. character, can vary by keyboard/region. - // Windows 2000/XP: For US standard keyboards, the ']}' key. - - { Key::APOSTROPHE, VK_OEM_7 }, // (0xDE) - // Misc. character, can vary by keyboard/region. - // Windows 2000/XP: For US standard keyboards, single quote/double quote. - + // 0xC3-DA may be used for old gamepads? Maybe we want to support this? See WinUser.h. + vk_map[VK_OEM_4] = Key::BRACKETLEFT; // (0xDB), For US standard keyboards;the '[{' key. + vk_map[VK_OEM_5] = Key::BACKSLASH; // (0xDC), For US standard keyboards;the '\|' key. + vk_map[VK_OEM_6] = Key::BRACKETRIGHT; // (0xDD), For US standard keyboards;the ']}' key. + vk_map[VK_OEM_7] = Key::APOSTROPHE; // (0xDE), For US standard keyboards;single quote/double quote. // VK_OEM_8 (0xDF) - // Misc. character, can vary by keyboard/region. We have no mapping. - - // 0xE0 is reserved. 0xE1 is OEM specific, we have no mapping. - - // VK_OEM_102 (0xE2) - // Either angle bracket or backslash key on the RT 102-key keyboard. - // Old and uncommon, we have no mapping. - - { Key::HELP, VK_ICO_HELP }, // (0xE3) - // OEM (ICO) help key. Map to help. - - // 0xE4 is OEM (e.g. ICO) specific, we have no mapping. - - // VK_PROCESSKEY (0xE5) - // For IME, we have no mapping. - - { Key::CLEAR, VK_ICO_CLEAR }, // (0xE6) - // OEM (ICO) clear key. Map to clear. - - // VK_PACKET (0xE7) - // Used to pass Unicode characters as if they were keystrokes. - // See Win32 API docs. We have no mapping. - - // 0xE8 is unassigned, 0xE9-F5 are OEM (Nokia/Ericsson) specific, we have no mappings. - - { Key::ESCAPE, VK_ATTN }, // (0xF6) - // Old IBM 'ATTN' key used on midrange computers, e.g. AS/400, map to Escape. - - { Key::TAB, VK_CRSEL }, // (0xF7) - // Old IBM 3270 'CrSel' (cursor select) key, used to select data fields, map to Tab. - - // VK_EXSEL (0xF7) - // Old IBM 3270 extended selection key. No mapping. - - // VK_EREOF (0xF8) - // Old IBM 3270 erase to end of field key. No mapping. - - { Key::MEDIAPLAY, VK_PLAY }, // (0xFA) - // Old IBM 3270 'Play' key. Map to media play. - - // VK_ZOOM (0xFB) - // Old IBM 3290 'Zoom' key. No mapping. - - // VK_NONAME (0xFC) - // Reserved. No mapping. - - // VK_PA1 (0xFD) - // Old IBM 3270 PA1 key. No mapping. - - { Key::CLEAR, VK_OEM_CLEAR }, // (0xFE) - // OEM specific clear key. Unclear how it differs from normal clear. Map to clear. - - { Key::UNKNOWN, 0 } -}; + // 0xE0 is reserved. 0xE1 is OEM specific. + vk_map[VK_OEM_102] = Key::BAR; // (0xE2), Either angle bracket or backslash key on the RT 102-key keyboard. + vk_map[VK_ICO_HELP] = Key::HELP; // (0xE3) + // 0xE4 is OEM (e.g. ICO) specific. + // VK_PROCESSKEY (0xE5), For IME. + vk_map[VK_ICO_CLEAR] = Key::CLEAR; // (0xE6) + // VK_PACKET (0xE7), Used to pass Unicode characters as if they were keystrokes. + // 0xE8 is unassigned. + // 0xE9-F5 are OEM (Nokia/Ericsson) specific. + vk_map[VK_ATTN] = Key::ESCAPE; // (0xF6), Old IBM 'ATTN' key used on midrange computers ;e.g. AS/400. + vk_map[VK_CRSEL] = Key::TAB; // (0xF7), Old IBM 3270 'CrSel' (cursor select) key; used to select data fields. + // VK_EXSEL (0xF7), Old IBM 3270 extended selection key. + // VK_EREOF (0xF8), Old IBM 3270 erase to end of field key. + vk_map[VK_PLAY] = Key::MEDIAPLAY; // (0xFA), Old IBM 3270 'Play' key. + // VK_ZOOM (0xFB), Old IBM 3290 'Zoom' key. + // VK_NONAME (0xFC), Reserved. + // VK_PA1 (0xFD), Old IBM 3270 PA1 key. + vk_map[VK_OEM_CLEAR] = Key::CLEAR; // (0xFE), OEM specific clear key. Unclear how it differs from normal clear. + + scansym_map[0x00] = Key::PAUSE; + scansym_map[0x01] = Key::ESCAPE; + scansym_map[0x02] = Key::KEY_1; + scansym_map[0x03] = Key::KEY_2; + scansym_map[0x04] = Key::KEY_3; + scansym_map[0x05] = Key::KEY_4; + scansym_map[0x06] = Key::KEY_5; + scansym_map[0x07] = Key::KEY_6; + scansym_map[0x08] = Key::KEY_7; + scansym_map[0x09] = Key::KEY_8; + scansym_map[0x0A] = Key::KEY_9; + scansym_map[0x0B] = Key::KEY_0; + scansym_map[0x0C] = Key::MINUS; + scansym_map[0x0D] = Key::EQUAL; + scansym_map[0x0E] = Key::BACKSPACE; + scansym_map[0x0F] = Key::TAB; + scansym_map[0x10] = Key::Q; + scansym_map[0x11] = Key::W; + scansym_map[0x12] = Key::E; + scansym_map[0x13] = Key::R; + scansym_map[0x14] = Key::T; + scansym_map[0x15] = Key::Y; + scansym_map[0x16] = Key::U; + scansym_map[0x17] = Key::I; + scansym_map[0x18] = Key::O; + scansym_map[0x19] = Key::P; + scansym_map[0x1A] = Key::BRACKETLEFT; + scansym_map[0x1B] = Key::BRACKETRIGHT; + scansym_map[0x1C] = Key::ENTER; + scansym_map[0x1D] = Key::CTRL; + scansym_map[0x1E] = Key::A; + scansym_map[0x1F] = Key::S; + scansym_map[0x20] = Key::D; + scansym_map[0x21] = Key::F; + scansym_map[0x22] = Key::G; + scansym_map[0x23] = Key::H; + scansym_map[0x24] = Key::J; + scansym_map[0x25] = Key::K; + scansym_map[0x26] = Key::L; + scansym_map[0x27] = Key::SEMICOLON; + scansym_map[0x28] = Key::APOSTROPHE; + scansym_map[0x29] = Key::QUOTELEFT; + scansym_map[0x2A] = Key::SHIFT; + scansym_map[0x2B] = Key::BACKSLASH; + scansym_map[0x2C] = Key::Z; + scansym_map[0x2D] = Key::X; + scansym_map[0x2E] = Key::C; + scansym_map[0x2F] = Key::V; + scansym_map[0x30] = Key::B; + scansym_map[0x31] = Key::N; + scansym_map[0x32] = Key::M; + scansym_map[0x33] = Key::COMMA; + scansym_map[0x34] = Key::PERIOD; + scansym_map[0x35] = Key::SLASH; + scansym_map[0x36] = Key::SHIFT; + scansym_map[0x37] = Key::KP_MULTIPLY; + scansym_map[0x38] = Key::ALT; + scansym_map[0x39] = Key::SPACE; + scansym_map[0x3A] = Key::CAPSLOCK; + scansym_map[0x3B] = Key::F1; + scansym_map[0x3C] = Key::F2; + scansym_map[0x3D] = Key::F3; + scansym_map[0x3E] = Key::F4; + scansym_map[0x3F] = Key::F5; + scansym_map[0x40] = Key::F6; + scansym_map[0x41] = Key::F7; + scansym_map[0x42] = Key::F8; + scansym_map[0x43] = Key::F9; + scansym_map[0x44] = Key::F10; + scansym_map[0x45] = Key::NUMLOCK; + scansym_map[0x46] = Key::SCROLLLOCK; + scansym_map[0x47] = Key::KP_7; + scansym_map[0x48] = Key::KP_8; + scansym_map[0x49] = Key::KP_9; + scansym_map[0x4A] = Key::KP_SUBTRACT; + scansym_map[0x4B] = Key::KP_4; + scansym_map[0x4C] = Key::KP_5; + scansym_map[0x4D] = Key::KP_6; + scansym_map[0x4E] = Key::KP_ADD; + scansym_map[0x4F] = Key::KP_1; + scansym_map[0x50] = Key::KP_2; + scansym_map[0x51] = Key::KP_3; + scansym_map[0x52] = Key::KP_0; + scansym_map[0x53] = Key::KP_PERIOD; + scansym_map[0x56] = Key::SECTION; + scansym_map[0x57] = Key::F11; + scansym_map[0x58] = Key::F12; + scansym_map[0x5B] = Key::META; + scansym_map[0x5C] = Key::META; + scansym_map[0x5D] = Key::MENU; + scansym_map[0x64] = Key::F13; + scansym_map[0x65] = Key::F14; + scansym_map[0x66] = Key::F15; + scansym_map[0x67] = Key::F16; + scansym_map[0x68] = Key::F17; + scansym_map[0x69] = Key::F18; + scansym_map[0x6A] = Key::F19; + scansym_map[0x6B] = Key::F20; + scansym_map[0x6C] = Key::F21; + scansym_map[0x6D] = Key::F22; + scansym_map[0x6E] = Key::F23; + // scansym_map[0x71] = Key::JIS_KANA; + // scansym_map[0x72] = Key::JIS_EISU; + scansym_map[0x76] = Key::F24; + + for (const KeyValue<unsigned int, Key> &E : scansym_map) { + scansym_map_inv[E.value] = E.key; + } -static _WinTranslatePair _scancode_to_keycode[] = { - { Key::ESCAPE, 0x01 }, - { Key::KEY_1, 0x02 }, - { Key::KEY_2, 0x03 }, - { Key::KEY_3, 0x04 }, - { Key::KEY_4, 0x05 }, - { Key::KEY_5, 0x06 }, - { Key::KEY_6, 0x07 }, - { Key::KEY_7, 0x08 }, - { Key::KEY_8, 0x09 }, - { Key::KEY_9, 0x0A }, - { Key::KEY_0, 0x0B }, - { Key::MINUS, 0x0C }, - { Key::EQUAL, 0x0D }, - { Key::BACKSPACE, 0x0E }, - { Key::TAB, 0x0F }, - { Key::Q, 0x10 }, - { Key::W, 0x11 }, - { Key::E, 0x12 }, - { Key::R, 0x13 }, - { Key::T, 0x14 }, - { Key::Y, 0x15 }, - { Key::U, 0x16 }, - { Key::I, 0x17 }, - { Key::O, 0x18 }, - { Key::P, 0x19 }, - { Key::BRACELEFT, 0x1A }, - { Key::BRACERIGHT, 0x1B }, - { Key::ENTER, 0x1C }, - { Key::CTRL, 0x1D }, - { Key::A, 0x1E }, - { Key::S, 0x1F }, - { Key::D, 0x20 }, - { Key::F, 0x21 }, - { Key::G, 0x22 }, - { Key::H, 0x23 }, - { Key::J, 0x24 }, - { Key::K, 0x25 }, - { Key::L, 0x26 }, - { Key::SEMICOLON, 0x27 }, - { Key::APOSTROPHE, 0x28 }, - { Key::QUOTELEFT, 0x29 }, - { Key::SHIFT, 0x2A }, - { Key::BACKSLASH, 0x2B }, - { Key::Z, 0x2C }, - { Key::X, 0x2D }, - { Key::C, 0x2E }, - { Key::V, 0x2F }, - { Key::B, 0x30 }, - { Key::N, 0x31 }, - { Key::M, 0x32 }, - { Key::COMMA, 0x33 }, - { Key::PERIOD, 0x34 }, - { Key::SLASH, 0x35 }, - { Key::SHIFT, 0x36 }, - { Key::PRINT, 0x37 }, - { Key::ALT, 0x38 }, - { Key::SPACE, 0x39 }, - { Key::CAPSLOCK, 0x3A }, - { Key::F1, 0x3B }, - { Key::F2, 0x3C }, - { Key::F3, 0x3D }, - { Key::F4, 0x3E }, - { Key::F5, 0x3F }, - { Key::F6, 0x40 }, - { Key::F7, 0x41 }, - { Key::F8, 0x42 }, - { Key::F9, 0x43 }, - { Key::F10, 0x44 }, - { Key::NUMLOCK, 0x45 }, - { Key::SCROLLLOCK, 0x46 }, - { Key::HOME, 0x47 }, - { Key::UP, 0x48 }, - { Key::PAGEUP, 0x49 }, - { Key::KP_SUBTRACT, 0x4A }, - { Key::LEFT, 0x4B }, - { Key::KP_5, 0x4C }, - { Key::RIGHT, 0x4D }, - { Key::KP_ADD, 0x4E }, - { Key::END, 0x4F }, - { Key::DOWN, 0x50 }, - { Key::PAGEDOWN, 0x51 }, - { Key::INSERT, 0x52 }, - { Key::KEY_DELETE, 0x53 }, - { Key::F11, 0x57 }, - { Key::F12, 0x58 }, - { Key::META, 0x5B }, - { Key::META, 0x5C }, - { Key::MENU, 0x5D }, - { Key::F13, 0x64 }, - { Key::F14, 0x65 }, - { Key::F15, 0x66 }, - { Key::F16, 0x67 }, - { Key::F17, 0x68 }, - { Key::F18, 0x69 }, - { Key::F19, 0x6A }, - { Key::F20, 0x6B }, - { Key::F21, 0x6C }, - { Key::F22, 0x6D }, - { Key::F23, 0x6E }, - { Key::F24, 0x76 }, - { Key::UNKNOWN, 0 } -}; + scansym_map_ext[0x09] = Key::MENU; + scansym_map_ext[0x10] = Key::MEDIAPREVIOUS; + scansym_map_ext[0x19] = Key::MEDIANEXT; + scansym_map_ext[0x1C] = Key::KP_ENTER; + scansym_map_ext[0x20] = Key::VOLUMEMUTE; + scansym_map_ext[0x21] = Key::LAUNCH1; + scansym_map_ext[0x22] = Key::MEDIAPLAY; + scansym_map_ext[0x24] = Key::MEDIASTOP; + scansym_map_ext[0x2E] = Key::VOLUMEDOWN; + scansym_map_ext[0x30] = Key::VOLUMEUP; + scansym_map_ext[0x32] = Key::HOMEPAGE; + scansym_map_ext[0x35] = Key::KP_DIVIDE; + scansym_map_ext[0x37] = Key::PRINT; + scansym_map_ext[0x3A] = Key::KP_ADD; + scansym_map_ext[0x45] = Key::NUMLOCK; + scansym_map_ext[0x47] = Key::HOME; + scansym_map_ext[0x48] = Key::UP; + scansym_map_ext[0x49] = Key::PAGEUP; + scansym_map_ext[0x4A] = Key::KP_SUBTRACT; + scansym_map_ext[0x4B] = Key::LEFT; + scansym_map_ext[0x4C] = Key::KP_5; + scansym_map_ext[0x4D] = Key::RIGHT; + scansym_map_ext[0x4E] = Key::KP_ADD; + scansym_map_ext[0x4F] = Key::END; + scansym_map_ext[0x50] = Key::DOWN; + scansym_map_ext[0x51] = Key::PAGEDOWN; + scansym_map_ext[0x52] = Key::INSERT; + scansym_map_ext[0x53] = Key::KEY_DELETE; + scansym_map_ext[0x5D] = Key::MENU; + scansym_map_ext[0x5F] = Key::STANDBY; + scansym_map_ext[0x65] = Key::SEARCH; + scansym_map_ext[0x66] = Key::FAVORITES; + scansym_map_ext[0x67] = Key::REFRESH; + scansym_map_ext[0x68] = Key::STOP; + scansym_map_ext[0x69] = Key::FORWARD; + scansym_map_ext[0x6A] = Key::BACK; + scansym_map_ext[0x6B] = Key::LAUNCH0; + scansym_map_ext[0x6C] = Key::LAUNCHMAIL; + scansym_map_ext[0x6D] = Key::LAUNCHMEDIA; + scansym_map_ext[0x78] = Key::MEDIARECORD; +} Key KeyMappingWindows::get_keysym(unsigned int p_code) { - for (int i = 0; _vk_to_keycode[i].keysym != Key::UNKNOWN; i++) { - if (_vk_to_keycode[i].keycode == p_code) { - return _vk_to_keycode[i].keysym; - } + const Key *key = vk_map.getptr(p_code); + if (key) { + return *key; } - return Key::UNKNOWN; } unsigned int KeyMappingWindows::get_scancode(Key p_keycode) { - for (int i = 0; _scancode_to_keycode[i].keysym != Key::UNKNOWN; i++) { - if (_scancode_to_keycode[i].keysym == p_keycode) { - return _scancode_to_keycode[i].keycode; - } + const unsigned int *key = scansym_map_inv.getptr(p_keycode); + if (key) { + return *key; } - return 0; } Key KeyMappingWindows::get_scansym(unsigned int p_code, bool p_extended) { - Key keycode = Key::UNKNOWN; - for (int i = 0; _scancode_to_keycode[i].keysym != Key::UNKNOWN; i++) { - if (_scancode_to_keycode[i].keycode == p_code) { - keycode = _scancode_to_keycode[i].keysym; - break; - } - } - if (p_extended) { - switch (keycode) { - case Key::ENTER: { - keycode = Key::KP_ENTER; - } break; - case Key::SLASH: { - keycode = Key::KP_DIVIDE; - } break; - case Key::CAPSLOCK: { - keycode = Key::KP_ADD; - } break; - default: - break; - } - } else { - switch (keycode) { - case Key::NUMLOCK: { - keycode = Key::PAUSE; - } break; - case Key::HOME: { - keycode = Key::KP_7; - } break; - case Key::UP: { - keycode = Key::KP_8; - } break; - case Key::PAGEUP: { - keycode = Key::KP_9; - } break; - case Key::LEFT: { - keycode = Key::KP_4; - } break; - case Key::RIGHT: { - keycode = Key::KP_6; - } break; - case Key::END: { - keycode = Key::KP_1; - } break; - case Key::DOWN: { - keycode = Key::KP_2; - } break; - case Key::PAGEDOWN: { - keycode = Key::KP_3; - } break; - case Key::INSERT: { - keycode = Key::KP_0; - } break; - case Key::KEY_DELETE: { - keycode = Key::KP_PERIOD; - } break; - case Key::PRINT: { - keycode = Key::KP_MULTIPLY; - } break; - default: - break; + const Key *key = scansym_map_ext.getptr(p_code); + if (key) { + return *key; } } - - return keycode; + const Key *key = scansym_map.getptr(p_code); + if (key) { + return *key; + } + return Key::NONE; } bool KeyMappingWindows::is_extended_key(unsigned int p_code) { diff --git a/platform/windows/key_mapping_windows.h b/platform/windows/key_mapping_windows.h index 393432fa39..a98aa7ed68 100644 --- a/platform/windows/key_mapping_windows.h +++ b/platform/windows/key_mapping_windows.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* key_mapping_windows.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* key_mapping_windows.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 KEY_MAPPING_WINDOWS_H #define KEY_MAPPING_WINDOWS_H @@ -41,6 +41,8 @@ class KeyMappingWindows { KeyMappingWindows() {} public: + static void initialize(); + static Key get_keysym(unsigned int p_code); static unsigned int get_scancode(Key p_keycode); static Key get_scansym(unsigned int p_code, bool p_extended); diff --git a/platform/windows/lang_table.h b/platform/windows/lang_table.h index 5b022853e8..e1f4f72746 100644 --- a/platform/windows/lang_table.h +++ b/platform/windows/lang_table.h @@ -1,38 +1,36 @@ -/*************************************************************************/ -/* lang_table.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* lang_table.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 LANG_TABLE_H #define LANG_TABLE_H -//#include <windows.h> - struct _WinLocale { const char *locale; int main_lang; diff --git a/platform/windows/logo.png b/platform/windows/logo.png Binary files differdeleted file mode 100644 index f06b463850..0000000000 --- a/platform/windows/logo.png +++ /dev/null diff --git a/platform/windows/logo.svg b/platform/windows/logo.svg new file mode 100644 index 0000000000..77a0b20766 --- /dev/null +++ b/platform/windows/logo.svg @@ -0,0 +1 @@ +<svg height="32" width="32" xmlns="http://www.w3.org/2000/svg"><path d="m1 5.132 12.295-1.694v11.879H1zm0 21.736 12.295 1.695V16.83H1zm13.647 1.875L31 31V16.83H14.647zm0-25.486v12.06H31V1z" fill="#00abed"/></svg> diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index 36fd86c4f5..cb70f93a62 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -1,35 +1,40 @@ -/*************************************************************************/ -/* os_windows.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* os_windows.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "os_windows.h" +#include "display_server_windows.h" +#include "joypad_windows.h" +#include "lang_table.h" +#include "windows_terminal_logger.h" + #include "core/debugger/engine_debugger.h" #include "core/debugger/script_debugger.h" #include "core/io/marshalls.h" @@ -37,23 +42,27 @@ #include "drivers/unix/net_socket_posix.h" #include "drivers/windows/dir_access_windows.h" #include "drivers/windows/file_access_windows.h" -#include "joypad_windows.h" -#include "lang_table.h" #include "main/main.h" -#include "platform/windows/display_server_windows.h" #include "servers/audio_server.h" #include "servers/rendering/rendering_server_default.h" -#include "windows_terminal_logger.h" +#include "servers/text_server.h" #include <avrt.h> #include <bcrypt.h> #include <direct.h> -#include <dwrite.h> #include <knownfolders.h> #include <process.h> +#include <psapi.h> #include <regstr.h> #include <shlobj.h> #include <wbemcli.h> +#include <wincrypt.h> + +#ifdef DEBUG_ENABLED +#pragma pack(push, before_imagehlp, 8) +#include <imagehlp.h> +#pragma pack(pop, before_imagehlp) +#endif extern "C" { __declspec(dllexport) DWORD NvOptimusEnablement = 1; @@ -69,6 +78,11 @@ __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; #define WM_POINTERUPDATE 0x0245 #endif +// Missing in MinGW headers before 8.0. +#ifndef DWRITE_FONT_WEIGHT_SEMI_LIGHT +#define DWRITE_FONT_WEIGHT_SEMI_LIGHT (DWRITE_FONT_WEIGHT)350 +#endif + #if defined(__GNUC__) // Workaround GCC warning from -Wcast-function-type. #define GetProcAddress (void *)GetProcAddress @@ -83,7 +97,7 @@ static String format_error_message(DWORD id) { LocalFree(messageBuffer); - return msg; + return msg.replace("\r", "").replace("\n", ""); } void RedirectStream(const char *p_file_name, const char *p_mode, FILE *p_cpp_stream, const DWORD p_std_handle) { @@ -103,8 +117,6 @@ void RedirectIOToConsole() { RedirectStream("CONIN$", "r", stdin, STD_INPUT_HANDLE); RedirectStream("CONOUT$", "w", stdout, STD_OUTPUT_HANDLE); RedirectStream("CONOUT$", "w", stderr, STD_ERROR_HANDLE); - - printf("\n"); // Make sure our output is starting from the new line. } } @@ -191,6 +203,28 @@ void OS_Windows::initialize() { IPUnix::make_default(); main_loop = nullptr; + + HRESULT hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), reinterpret_cast<IUnknown **>(&dwrite_factory)); + if (SUCCEEDED(hr)) { + hr = dwrite_factory->GetSystemFontCollection(&font_collection, false); + if (SUCCEEDED(hr)) { + dwrite_init = true; + hr = dwrite_factory->QueryInterface(&dwrite_factory2); + if (SUCCEEDED(hr)) { + hr = dwrite_factory2->GetSystemFontFallback(&system_font_fallback); + if (SUCCEEDED(hr)) { + dwrite2_init = true; + } + } + } + } + if (!dwrite_init) { + print_verbose("Unable to load IDWriteFactory, system font support is disabled."); + } else if (!dwrite2_init) { + print_verbose("Unable to load IDWriteFactory2, automatic system font fallback is disabled."); + } + + FileAccessWindows::initialize(); } void OS_Windows::delete_main_loop() { @@ -205,6 +239,22 @@ void OS_Windows::set_main_loop(MainLoop *p_main_loop) { } void OS_Windows::finalize() { + if (dwrite_factory2) { + dwrite_factory2->Release(); + dwrite_factory2 = nullptr; + } + if (font_collection) { + font_collection->Release(); + font_collection = nullptr; + } + if (system_font_fallback) { + system_font_fallback->Release(); + system_font_fallback = nullptr; + } + if (dwrite_factory) { + dwrite_factory->Release(); + dwrite_factory = nullptr; + } #ifdef WINMIDI_ENABLED driver_midi.close(); #endif @@ -217,6 +267,8 @@ void OS_Windows::finalize() { } void OS_Windows::finalize_core() { + FileAccessWindows::finalize(); + timeEndPeriod(1); memdelete(process_map); @@ -233,11 +285,78 @@ Error OS_Windows::get_entropy(uint8_t *r_buffer, int p_bytes) { return OK; } +#ifdef DEBUG_ENABLED +void debug_dynamic_library_check_dependencies(const String &p_root_path, const String &p_path, HashSet<String> &r_checked, HashSet<String> &r_missing) { + if (r_checked.has(p_path)) { + return; + } + r_checked.insert(p_path); + + LOADED_IMAGE loaded_image; + HANDLE file = CreateFileW((LPCWSTR)p_path.utf16().get_data(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr); + if (file != INVALID_HANDLE_VALUE) { + HANDLE file_mapping = CreateFileMappingW(file, nullptr, PAGE_READONLY | SEC_COMMIT, 0, 0, nullptr); + if (file_mapping != INVALID_HANDLE_VALUE) { + PVOID mapping = MapViewOfFile(file_mapping, FILE_MAP_READ, 0, 0, 0); + if (mapping) { + PIMAGE_DOS_HEADER dos_header = (PIMAGE_DOS_HEADER)mapping; + PIMAGE_NT_HEADERS nt_header = nullptr; + if (dos_header->e_magic == IMAGE_DOS_SIGNATURE) { + PCHAR nt_header_ptr; + nt_header_ptr = ((PCHAR)mapping) + dos_header->e_lfanew; + nt_header = (PIMAGE_NT_HEADERS)nt_header_ptr; + if (nt_header->Signature != IMAGE_NT_SIGNATURE) { + nt_header = nullptr; + } + } + if (nt_header) { + loaded_image.ModuleName = nullptr; + loaded_image.hFile = file; + loaded_image.MappedAddress = (PUCHAR)mapping; + loaded_image.FileHeader = nt_header; + loaded_image.Sections = (PIMAGE_SECTION_HEADER)((LPBYTE)&nt_header->OptionalHeader + nt_header->FileHeader.SizeOfOptionalHeader); + loaded_image.NumberOfSections = nt_header->FileHeader.NumberOfSections; + loaded_image.SizeOfImage = GetFileSize(file, nullptr); + loaded_image.Characteristics = nt_header->FileHeader.Characteristics; + loaded_image.LastRvaSection = loaded_image.Sections; + loaded_image.fSystemImage = false; + loaded_image.fDOSImage = false; + loaded_image.Links.Flink = &loaded_image.Links; + loaded_image.Links.Blink = &loaded_image.Links; + + ULONG size = 0; + const IMAGE_IMPORT_DESCRIPTOR *import_desc = (const IMAGE_IMPORT_DESCRIPTOR *)ImageDirectoryEntryToData((HMODULE)loaded_image.MappedAddress, false, IMAGE_DIRECTORY_ENTRY_IMPORT, &size); + if (import_desc) { + for (; import_desc->Name && import_desc->FirstThunk; import_desc++) { + char16_t full_name_wc[MAX_PATH]; + const char *name_cs = (const char *)ImageRvaToVa(loaded_image.FileHeader, loaded_image.MappedAddress, import_desc->Name, 0); + String name = String(name_cs); + if (name.begins_with("api-ms-win-")) { + r_checked.insert(name); + } else if (SearchPathW(nullptr, (LPCWSTR)name.utf16().get_data(), nullptr, MAX_PATH, (LPWSTR)full_name_wc, nullptr)) { + debug_dynamic_library_check_dependencies(p_root_path, String::utf16(full_name_wc), r_checked, r_missing); + } else if (SearchPathW((LPCWSTR)(p_path.get_base_dir().utf16().get_data()), (LPCWSTR)name.utf16().get_data(), nullptr, MAX_PATH, (LPWSTR)full_name_wc, nullptr)) { + debug_dynamic_library_check_dependencies(p_root_path, String::utf16(full_name_wc), r_checked, r_missing); + } else { + r_missing.insert(name); + } + } + } + } + UnmapViewOfFile(mapping); + } + CloseHandle(file_mapping); + } + CloseHandle(file); + } +} +#endif + Error OS_Windows::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path, String *r_resolved_path) { String path = p_path.replace("/", "\\"); if (!FileAccess::exists(path)) { - //this code exists so gdnative can load .dll files from within the executable path + //this code exists so gdextension can load .dll files from within the executable path path = get_executable_path().get_base_dir().path_join(p_path.get_file()); } @@ -255,7 +374,29 @@ Error OS_Windows::open_dynamic_library(const String p_path, void *&p_library_han } p_library_handle = (void *)LoadLibraryExW((LPCWSTR)(path.utf16().get_data()), nullptr, (p_also_set_library_path && has_dll_directory_api) ? LOAD_LIBRARY_SEARCH_DEFAULT_DIRS : 0); - ERR_FAIL_COND_V_MSG(!p_library_handle, ERR_CANT_OPEN, "Can't open dynamic library: " + p_path + ", error: " + format_error_message(GetLastError()) + "."); +#ifdef DEBUG_ENABLED + if (!p_library_handle) { + DWORD err_code = GetLastError(); + + HashSet<String> checekd_libs; + HashSet<String> missing_libs; + debug_dynamic_library_check_dependencies(path, path, checekd_libs, missing_libs); + if (!missing_libs.is_empty()) { + String missing; + for (const String &E : missing_libs) { + if (!missing.is_empty()) { + missing += ", "; + } + missing += E; + } + ERR_FAIL_V_MSG(ERR_CANT_OPEN, vformat("Can't open dynamic library: %s, missing dependencies: (%s), error: \"%s\".", p_path, missing, format_error_message(err_code))); + } else { + ERR_FAIL_V_MSG(ERR_CANT_OPEN, vformat("Can't open dynamic library: %s, error: \"%s\"." + p_path, format_error_message(err_code))); + } + } +#else + ERR_FAIL_COND_V_MSG(!p_library_handle, ERR_CANT_OPEN, vformat("Can't open dynamic library: %s, error: \"%s\"." + p_path, format_error_message(GetLastError()))); +#endif if (cookie) { remove_dll_directory(cookie); @@ -279,7 +420,7 @@ Error OS_Windows::get_dynamic_library_symbol_handle(void *p_library_handle, cons p_symbol_handle = (void *)GetProcAddress((HMODULE)p_library_handle, p_name.utf8().get_data()); if (!p_symbol_handle) { if (!p_optional) { - ERR_FAIL_V_MSG(ERR_CANT_RESOLVE, "Can't resolve symbol " + p_name + ", error: " + String::num(GetLastError()) + "."); + ERR_FAIL_V_MSG(ERR_CANT_RESOLVE, vformat("Can't resolve symbol %s, error: \"%s\".", p_name, format_error_message(GetLastError()))); } else { return ERR_CANT_RESOLVE; } @@ -296,8 +437,6 @@ String OS_Windows::get_distribution_name() const { } String OS_Windows::get_version() const { - typedef LONG NTSTATUS; - typedef NTSTATUS(WINAPI * RtlGetVersionPtr)(PRTL_OSVERSIONINFOW); RtlGetVersionPtr version_ptr = (RtlGetVersionPtr)GetProcAddress(GetModuleHandle("ntdll.dll"), "RtlGetVersion"); if (version_ptr != nullptr) { RTL_OSVERSIONINFOW fow; @@ -311,26 +450,29 @@ String OS_Windows::get_version() const { } Vector<String> OS_Windows::get_video_adapter_driver_info() const { - if (RenderingServer::get_singleton()->get_rendering_device() == nullptr) { + if (RenderingServer::get_singleton() == nullptr) { return Vector<String>(); } + static Vector<String> info; + if (!info.is_empty()) { + return info; + } + REFCLSID clsid = CLSID_WbemLocator; // Unmarshaler CLSID REFIID uuid = IID_IWbemLocator; // Interface UUID IWbemLocator *wbemLocator = NULL; // to get the services IWbemServices *wbemServices = NULL; // to get the class IEnumWbemClassObject *iter = NULL; IWbemClassObject *pnpSDriverObject[1]; // contains driver name, version, etc. - static String driver_name; - static String driver_version; + String driver_name; + String driver_version; - const String device_name = RenderingServer::get_singleton()->get_rendering_device()->get_device_name(); + const String device_name = RenderingServer::get_singleton()->get_video_adapter_name(); if (device_name.is_empty()) { return Vector<String>(); } - CoInitialize(nullptr); - HRESULT hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, uuid, (LPVOID *)&wbemLocator); if (hr != S_OK) { return Vector<String>(); @@ -400,7 +542,6 @@ Vector<String> OS_Windows::get_video_adapter_driver_info() const { SAFE_RELEASE(wbemServices) SAFE_RELEASE(iter) - Vector<String> info; info.push_back(driver_name); info.push_back(driver_version); @@ -417,9 +558,9 @@ OS::DateTime OS_Windows::get_datetime(bool p_utc) const { //Get DST information from Windows, but only if p_utc is false. TIME_ZONE_INFORMATION info; - bool daylight = false; + bool is_daylight = false; if (!p_utc && GetTimeZoneInformation(&info) == TIME_ZONE_ID_DAYLIGHT) { - daylight = true; + is_daylight = true; } DateTime dt; @@ -430,20 +571,20 @@ OS::DateTime OS_Windows::get_datetime(bool p_utc) const { dt.hour = systemtime.wHour; dt.minute = systemtime.wMinute; dt.second = systemtime.wSecond; - dt.dst = daylight; + dt.dst = is_daylight; return dt; } OS::TimeZoneInfo OS_Windows::get_time_zone_info() const { TIME_ZONE_INFORMATION info; - bool daylight = false; + bool is_daylight = false; if (GetTimeZoneInformation(&info) == TIME_ZONE_ID_DAYLIGHT) { - daylight = true; + is_daylight = true; } // Daylight Bias needs to be added to the bias if DST is in effect, or else it will not properly update. TimeZoneInfo ret; - if (daylight) { + if (is_daylight) { ret.name = info.DaylightName; ret.bias = info.Bias + info.DaylightBias; } else { @@ -547,6 +688,43 @@ static void _append_to_pipe(char *p_bytes, int p_size, String *r_pipe, Mutex *p_ } } +Dictionary OS_Windows::get_memory_info() const { + Dictionary meminfo; + + meminfo["physical"] = -1; + meminfo["free"] = -1; + meminfo["available"] = -1; + meminfo["stack"] = -1; + + PERFORMANCE_INFORMATION pref_info; + pref_info.cb = sizeof(pref_info); + GetPerformanceInfo(&pref_info, sizeof(pref_info)); + + typedef void(WINAPI * PGetCurrentThreadStackLimits)(PULONG_PTR, PULONG_PTR); + PGetCurrentThreadStackLimits GetCurrentThreadStackLimits = (PGetCurrentThreadStackLimits)GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetCurrentThreadStackLimits"); + + ULONG_PTR LowLimit = 0; + ULONG_PTR HighLimit = 0; + if (GetCurrentThreadStackLimits) { + GetCurrentThreadStackLimits(&LowLimit, &HighLimit); + } + + if (pref_info.PhysicalTotal * pref_info.PageSize != 0) { + meminfo["physical"] = static_cast<int64_t>(pref_info.PhysicalTotal * pref_info.PageSize); + } + if (pref_info.PhysicalAvailable * pref_info.PageSize != 0) { + meminfo["free"] = static_cast<int64_t>(pref_info.PhysicalAvailable * pref_info.PageSize); + } + if (pref_info.CommitLimit * pref_info.PageSize != 0) { + meminfo["available"] = static_cast<int64_t>(pref_info.CommitLimit * pref_info.PageSize); + } + if (HighLimit - LowLimit != 0) { + meminfo["stack"] = static_cast<int64_t>(HighLimit - LowLimit); + } + + return meminfo; +} + Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex, bool p_open_console) { String path = p_path.replace("/", "\\"); String command = _quote_command_line_argument(path); @@ -634,9 +812,8 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments, } CloseHandle(pipe[0]); // Close pipe read handle. - } else { - WaitForSingleObject(pi.pi.hProcess, INFINITE); } + WaitForSingleObject(pi.pi.hProcess, INFINITE); if (r_exitcode) { DWORD ret2; @@ -683,15 +860,23 @@ Error OS_Windows::create_process(const String &p_path, const List<String> &p_arg } Error OS_Windows::kill(const ProcessID &p_pid) { - ERR_FAIL_COND_V(!process_map->has(p_pid), FAILED); + int ret = 0; + if (process_map->has(p_pid)) { + const PROCESS_INFORMATION pi = (*process_map)[p_pid].pi; + process_map->erase(p_pid); - const PROCESS_INFORMATION pi = (*process_map)[p_pid].pi; - process_map->erase(p_pid); + ret = TerminateProcess(pi.hProcess, 0); - const int ret = TerminateProcess(pi.hProcess, 0); + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + } else { + HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, false, (DWORD)p_pid); + if (hProcess != NULL) { + ret = TerminateProcess(hProcess, 0); - CloseHandle(pi.hProcess); - CloseHandle(pi.hThread); + CloseHandle(hProcess); + } + } return ret != 0 ? OK : FAILED; } @@ -728,21 +913,17 @@ Error OS_Windows::set_cwd(const String &p_cwd) { } Vector<String> OS_Windows::get_system_fonts() const { + if (!dwrite_init) { + return Vector<String>(); + } + Vector<String> ret; HashSet<String> font_names; - ComAutoreleaseRef<IDWriteFactory> dwrite_factory; - HRESULT hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), reinterpret_cast<IUnknown **>(&dwrite_factory.reference)); - ERR_FAIL_COND_V(FAILED(hr) || dwrite_factory.is_null(), ret); - - ComAutoreleaseRef<IDWriteFontCollection> font_collection; - hr = dwrite_factory->GetSystemFontCollection(&font_collection.reference, false); - ERR_FAIL_COND_V(FAILED(hr) || font_collection.is_null(), ret); - UINT32 family_count = font_collection->GetFontFamilyCount(); for (UINT32 i = 0; i < family_count; i++) { ComAutoreleaseRef<IDWriteFontFamily> family; - hr = font_collection->GetFontFamily(i, &family.reference); + HRESULT hr = font_collection->GetFontFamily(i, &family.reference); ERR_CONTINUE(FAILED(hr) || family.is_null()); ComAutoreleaseRef<IDWriteLocalizedStrings> family_names; @@ -773,7 +954,98 @@ Vector<String> OS_Windows::get_system_fonts() const { return ret; } -String OS_Windows::get_system_font_path(const String &p_font_name, bool p_bold, bool p_italic) const { +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" +#endif + +class FallbackTextAnalysisSource : public IDWriteTextAnalysisSource { + LONG _cRef = 1; + + bool rtl = false; + Char16String string; + Char16String locale; + IDWriteNumberSubstitution *n_sub = nullptr; + +public: + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, VOID **ppvInterface) override { + if (IID_IUnknown == riid) { + AddRef(); + *ppvInterface = (IUnknown *)this; + } else if (__uuidof(IMMNotificationClient) == riid) { + AddRef(); + *ppvInterface = (IMMNotificationClient *)this; + } else { + *ppvInterface = nullptr; + return E_NOINTERFACE; + } + return S_OK; + } + + ULONG STDMETHODCALLTYPE AddRef() override { + return InterlockedIncrement(&_cRef); + } + + ULONG STDMETHODCALLTYPE Release() override { + ULONG ulRef = InterlockedDecrement(&_cRef); + if (0 == ulRef) { + delete this; + } + return ulRef; + } + + HRESULT STDMETHODCALLTYPE GetTextAtPosition(UINT32 p_text_position, WCHAR const **r_text_string, UINT32 *r_text_length) override { + if (p_text_position >= (UINT32)string.length()) { + *r_text_string = nullptr; + *r_text_length = 0; + return S_OK; + } + *r_text_string = reinterpret_cast<const wchar_t *>(string.get_data()) + p_text_position; + *r_text_length = string.length() - p_text_position; + return S_OK; + } + + HRESULT STDMETHODCALLTYPE GetTextBeforePosition(UINT32 p_text_position, WCHAR const **r_text_string, UINT32 *r_text_length) override { + if (p_text_position < 1 || p_text_position >= (UINT32)string.length()) { + *r_text_string = nullptr; + *r_text_length = 0; + return S_OK; + } + *r_text_string = reinterpret_cast<const wchar_t *>(string.get_data()); + *r_text_length = p_text_position; + return S_OK; + } + + DWRITE_READING_DIRECTION STDMETHODCALLTYPE GetParagraphReadingDirection() override { + return (rtl) ? DWRITE_READING_DIRECTION_RIGHT_TO_LEFT : DWRITE_READING_DIRECTION_LEFT_TO_RIGHT; + } + + HRESULT STDMETHODCALLTYPE GetLocaleName(UINT32 p_text_position, UINT32 *r_text_length, WCHAR const **r_locale_name) override { + *r_locale_name = reinterpret_cast<const wchar_t *>(locale.get_data()); + return S_OK; + } + + HRESULT STDMETHODCALLTYPE GetNumberSubstitution(UINT32 p_text_position, UINT32 *r_text_length, IDWriteNumberSubstitution **r_number_substitution) override { + *r_number_substitution = n_sub; + return S_OK; + } + + FallbackTextAnalysisSource(const Char16String &p_text, const Char16String &p_locale, bool p_rtl, IDWriteNumberSubstitution *p_nsub) { + _cRef = 1; + string = p_text; + locale = p_locale; + n_sub = p_nsub; + rtl = p_rtl; + }; + + virtual ~FallbackTextAnalysisSource() {} +}; + +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic pop +#endif + +String OS_Windows::_get_default_fontname(const String &p_font_name) const { String font_name = p_font_name; if (font_name.to_lower() == "sans-serif") { font_name = "Arial"; @@ -786,19 +1058,158 @@ String OS_Windows::get_system_font_path(const String &p_font_name, bool p_bold, } else if (font_name.to_lower() == "fantasy") { font_name = "Gabriola"; } + return font_name; +} + +DWRITE_FONT_WEIGHT OS_Windows::_weight_to_dw(int p_weight) const { + if (p_weight < 150) { + return DWRITE_FONT_WEIGHT_THIN; + } else if (p_weight < 250) { + return DWRITE_FONT_WEIGHT_EXTRA_LIGHT; + } else if (p_weight < 325) { + return DWRITE_FONT_WEIGHT_LIGHT; + } else if (p_weight < 375) { + return DWRITE_FONT_WEIGHT_SEMI_LIGHT; + } else if (p_weight < 450) { + return DWRITE_FONT_WEIGHT_NORMAL; + } else if (p_weight < 550) { + return DWRITE_FONT_WEIGHT_MEDIUM; + } else if (p_weight < 650) { + return DWRITE_FONT_WEIGHT_DEMI_BOLD; + } else if (p_weight < 750) { + return DWRITE_FONT_WEIGHT_BOLD; + } else if (p_weight < 850) { + return DWRITE_FONT_WEIGHT_EXTRA_BOLD; + } else if (p_weight < 925) { + return DWRITE_FONT_WEIGHT_BLACK; + } else { + return DWRITE_FONT_WEIGHT_EXTRA_BLACK; + } +} + +DWRITE_FONT_STRETCH OS_Windows::_stretch_to_dw(int p_stretch) const { + if (p_stretch < 56) { + return DWRITE_FONT_STRETCH_ULTRA_CONDENSED; + } else if (p_stretch < 69) { + return DWRITE_FONT_STRETCH_EXTRA_CONDENSED; + } else if (p_stretch < 81) { + return DWRITE_FONT_STRETCH_CONDENSED; + } else if (p_stretch < 93) { + return DWRITE_FONT_STRETCH_SEMI_CONDENSED; + } else if (p_stretch < 106) { + return DWRITE_FONT_STRETCH_NORMAL; + } else if (p_stretch < 137) { + return DWRITE_FONT_STRETCH_SEMI_EXPANDED; + } else if (p_stretch < 144) { + return DWRITE_FONT_STRETCH_EXPANDED; + } else if (p_stretch < 162) { + return DWRITE_FONT_STRETCH_EXTRA_EXPANDED; + } else { + return DWRITE_FONT_STRETCH_ULTRA_EXPANDED; + } +} + +Vector<String> OS_Windows::get_system_font_path_for_text(const String &p_font_name, const String &p_text, const String &p_locale, const String &p_script, int p_weight, int p_stretch, bool p_italic) const { + if (!dwrite2_init) { + return Vector<String>(); + } - ComAutoreleaseRef<IDWriteFactory> dwrite_factory; - HRESULT hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), reinterpret_cast<IUnknown **>(&dwrite_factory.reference)); - ERR_FAIL_COND_V(FAILED(hr) || dwrite_factory.is_null(), String()); + String font_name = _get_default_fontname(p_font_name); - ComAutoreleaseRef<IDWriteFontCollection> font_collection; - hr = dwrite_factory->GetSystemFontCollection(&font_collection.reference, false); - ERR_FAIL_COND_V(FAILED(hr) || font_collection.is_null(), String()); + bool rtl = TS->is_locale_right_to_left(p_locale); + Char16String text = p_text.utf16(); + Char16String locale = p_locale.utf16(); + + ComAutoreleaseRef<IDWriteNumberSubstitution> number_substitution; + HRESULT hr = dwrite_factory->CreateNumberSubstitution(DWRITE_NUMBER_SUBSTITUTION_METHOD_NONE, reinterpret_cast<const wchar_t *>(locale.get_data()), true, &number_substitution.reference); + ERR_FAIL_COND_V(FAILED(hr) || number_substitution.is_null(), Vector<String>()); + + FallbackTextAnalysisSource fs = FallbackTextAnalysisSource(text, locale, rtl, number_substitution.reference); + UINT32 mapped_length = 0; + FLOAT scale = 0.0; + ComAutoreleaseRef<IDWriteFont> dwrite_font; + hr = system_font_fallback->MapCharacters( + &fs, + 0, + (UINT32)text.length(), + font_collection, + reinterpret_cast<const wchar_t *>(font_name.utf16().get_data()), + _weight_to_dw(p_weight), + p_italic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL, + _stretch_to_dw(p_stretch), + &mapped_length, + &dwrite_font.reference, + &scale); + + if (FAILED(hr) || dwrite_font.is_null()) { + return Vector<String>(); + } + + ComAutoreleaseRef<IDWriteFontFace> dwrite_face; + hr = dwrite_font->CreateFontFace(&dwrite_face.reference); + if (FAILED(hr) || dwrite_face.is_null()) { + return Vector<String>(); + } + + UINT32 number_of_files = 0; + hr = dwrite_face->GetFiles(&number_of_files, nullptr); + if (FAILED(hr)) { + return Vector<String>(); + } + Vector<ComAutoreleaseRef<IDWriteFontFile>> files; + files.resize(number_of_files); + hr = dwrite_face->GetFiles(&number_of_files, (IDWriteFontFile **)files.ptrw()); + if (FAILED(hr)) { + return Vector<String>(); + } + + Vector<String> ret; + for (UINT32 i = 0; i < number_of_files; i++) { + void const *reference_key = nullptr; + UINT32 reference_key_size = 0; + ComAutoreleaseRef<IDWriteLocalFontFileLoader> loader; + + hr = files.write[i]->GetLoader((IDWriteFontFileLoader **)&loader.reference); + if (FAILED(hr) || loader.is_null()) { + continue; + } + hr = files.write[i]->GetReferenceKey(&reference_key, &reference_key_size); + if (FAILED(hr)) { + continue; + } + + WCHAR file_path[MAX_PATH]; + hr = loader->GetFilePathFromKey(reference_key, reference_key_size, &file_path[0], MAX_PATH); + if (FAILED(hr)) { + continue; + } + String fpath = String::utf16((const char16_t *)&file_path[0]); + + WIN32_FIND_DATAW d; + HANDLE fnd = FindFirstFileW((LPCWSTR)&file_path[0], &d); + if (fnd != INVALID_HANDLE_VALUE) { + String fname = String::utf16((const char16_t *)d.cFileName); + if (!fname.is_empty()) { + fpath = fpath.get_base_dir().path_join(fname); + } + FindClose(fnd); + } + ret.push_back(fpath); + } + return ret; +} + +String OS_Windows::get_system_font_path(const String &p_font_name, int p_weight, int p_stretch, bool p_italic) const { + if (!dwrite_init) { + return String(); + } + + String font_name = _get_default_fontname(p_font_name); UINT32 index = 0; BOOL exists = false; - font_collection->FindFamilyName((const WCHAR *)font_name.utf16().get_data(), &index, &exists); - if (FAILED(hr)) { + HRESULT hr = font_collection->FindFamilyName((const WCHAR *)font_name.utf16().get_data(), &index, &exists); + if (FAILED(hr) || !exists) { return String(); } @@ -809,7 +1220,7 @@ String OS_Windows::get_system_font_path(const String &p_font_name, bool p_bold, } ComAutoreleaseRef<IDWriteFont> dwrite_font; - hr = family->GetFirstMatchingFont(p_bold ? DWRITE_FONT_WEIGHT_BOLD : DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STRETCH_NORMAL, p_italic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL, &dwrite_font.reference); + hr = family->GetFirstMatchingFont(_weight_to_dw(p_weight), _stretch_to_dw(p_stretch), p_italic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL, &dwrite_font.reference); if (FAILED(hr) || dwrite_font.is_null()) { return String(); } @@ -851,7 +1262,19 @@ String OS_Windows::get_system_font_path(const String &p_font_name, bool p_bold, if (FAILED(hr)) { continue; } - return String::utf16((const char16_t *)&file_path[0]); + String fpath = String::utf16((const char16_t *)&file_path[0]); + + WIN32_FIND_DATAW d; + HANDLE fnd = FindFirstFileW((LPCWSTR)&file_path[0], &d); + if (fnd != INVALID_HANDLE_VALUE) { + String fname = String::utf16((const char16_t *)d.cFileName); + if (!fname.is_empty()) { + fpath = fpath.get_base_dir().path_join(fname); + } + FindClose(fnd); + } + + return fpath; } return String(); } @@ -885,14 +1308,24 @@ String OS_Windows::get_environment(const String &p_var) const { return ""; } -bool OS_Windows::set_environment(const String &p_var, const String &p_value) const { - return (bool)SetEnvironmentVariableW((LPCWSTR)(p_var.utf16().get_data()), (LPCWSTR)(p_value.utf16().get_data())); +void OS_Windows::set_environment(const String &p_var, const String &p_value) const { + ERR_FAIL_COND_MSG(p_var.is_empty() || p_var.contains("="), vformat("Invalid environment variable name '%s', cannot be empty or include '='.", p_var)); + Char16String var = p_var.utf16(); + Char16String value = p_value.utf16(); + ERR_FAIL_COND_MSG(var.length() + value.length() + 2 > 32767, vformat("Invalid definition for environment variable '%s', cannot exceed 32767 characters.", p_var)); + SetEnvironmentVariableW((LPCWSTR)(var.get_data()), (LPCWSTR)(value.get_data())); +} + +void OS_Windows::unset_environment(const String &p_var) const { + ERR_FAIL_COND_MSG(p_var.is_empty() || p_var.contains("="), vformat("Invalid environment variable name '%s', cannot be empty or include '='.", p_var)); + SetEnvironmentVariableW((LPCWSTR)(p_var.utf16().get_data()), nullptr); // Null to delete. } -String OS_Windows::get_stdin_string(bool p_block) { - if (p_block) { - char buff[1024]; - return fgets(buff, 1024, stdin); +String OS_Windows::get_stdin_string() { + WCHAR buff[1024]; + DWORD count = 0; + if (ReadConsoleW(GetStdHandle(STD_INPUT_HANDLE), buff, 1024, &count, nullptr)) { + return String::utf16((const char16_t *)buff, count); } return String(); @@ -922,6 +1355,51 @@ Error OS_Windows::shell_open(String p_uri) { } } +Error OS_Windows::shell_show_in_file_manager(String p_path, bool p_open_folder) { + p_path = p_path.trim_suffix("file://"); + + bool open_folder = false; + if (DirAccess::dir_exists_absolute(p_path) && p_open_folder) { + open_folder = true; + } + + if (p_path.begins_with("\"")) { + p_path = String("\"") + p_path; + } + if (p_path.ends_with("\"")) { + p_path = p_path + String("\""); + } + p_path = p_path.replace("/", "\\"); + + INT_PTR ret = OK; + if (open_folder) { + ret = (INT_PTR)ShellExecuteW(nullptr, nullptr, L"explorer.exe", LPCWSTR(p_path.utf16().get_data()), nullptr, SW_SHOWNORMAL); + } else { + ret = (INT_PTR)ShellExecuteW(nullptr, nullptr, L"explorer.exe", LPCWSTR((String("/select,") + p_path).utf16().get_data()), nullptr, SW_SHOWNORMAL); + } + + if (ret > 32) { + return OK; + } else { + switch (ret) { + case ERROR_FILE_NOT_FOUND: + case SE_ERR_DLLNOTFOUND: + return ERR_FILE_NOT_FOUND; + case ERROR_PATH_NOT_FOUND: + return ERR_FILE_BAD_PATH; + case ERROR_BAD_FORMAT: + return ERR_FILE_CORRUPT; + case SE_ERR_ACCESSDENIED: + return ERR_UNAUTHORIZED; + case 0: + case SE_ERR_OOM: + return ERR_OUT_OF_MEMORY; + default: + return FAILED; + } + } +} + String OS_Windows::get_locale() const { const _WinLocale *wl = &_win_locales[0]; @@ -1063,14 +1541,6 @@ uint64_t OS_Windows::get_embedded_pck_offset() const { } String OS_Windows::get_config_path() const { - // The XDG Base Directory specification technically only applies on Linux/*BSD, but it doesn't hurt to support it on Windows as well. - if (has_environment("XDG_CONFIG_HOME")) { - if (get_environment("XDG_CONFIG_HOME").is_absolute_path()) { - return get_environment("XDG_CONFIG_HOME").replace("\\", "/"); - } else { - WARN_PRINT_ONCE("`XDG_CONFIG_HOME` is a relative path. Ignoring its value and falling back to `%APPDATA%` or `.` per the XDG Base Directory specification."); - } - } if (has_environment("APPDATA")) { return get_environment("APPDATA").replace("\\", "/"); } @@ -1078,29 +1548,13 @@ String OS_Windows::get_config_path() const { } String OS_Windows::get_data_path() const { - // The XDG Base Directory specification technically only applies on Linux/*BSD, but it doesn't hurt to support it on Windows as well. - if (has_environment("XDG_DATA_HOME")) { - if (get_environment("XDG_DATA_HOME").is_absolute_path()) { - return get_environment("XDG_DATA_HOME").replace("\\", "/"); - } else { - WARN_PRINT_ONCE("`XDG_DATA_HOME` is a relative path. Ignoring its value and falling back to `get_config_path()` per the XDG Base Directory specification."); - } - } return get_config_path(); } String OS_Windows::get_cache_path() const { static String cache_path_cache; if (cache_path_cache.is_empty()) { - // The XDG Base Directory specification technically only applies on Linux/*BSD, but it doesn't hurt to support it on Windows as well. - if (has_environment("XDG_CACHE_HOME")) { - if (get_environment("XDG_CACHE_HOME").is_absolute_path()) { - cache_path_cache = get_environment("XDG_CACHE_HOME").replace("\\", "/"); - } else { - WARN_PRINT_ONCE("`XDG_CACHE_HOME` is a relative path. Ignoring its value and falling back to `%LOCALAPPDATA%\\cache`, `%TEMP%` or `get_config_path()` per the XDG Base Directory specification."); - } - } - if (cache_path_cache.is_empty() && has_environment("LOCALAPPDATA")) { + if (has_environment("LOCALAPPDATA")) { cache_path_cache = get_environment("LOCALAPPDATA").replace("\\", "/"); } if (cache_path_cache.is_empty() && has_environment("TEMP")) { @@ -1182,7 +1636,7 @@ String OS_Windows::get_unique_id() const { bool OS_Windows::_check_internal_feature_support(const String &p_feature) { if (p_feature == "system_fonts") { - return true; + return dwrite_init; } if (p_feature == "pc") { return true; @@ -1227,9 +1681,41 @@ Error OS_Windows::move_to_trash(const String &p_path) { return OK; } +String OS_Windows::get_system_ca_certificates() { + HCERTSTORE cert_store = CertOpenSystemStoreA(0, "ROOT"); + ERR_FAIL_COND_V_MSG(!cert_store, "", "Failed to read the root certificate store."); + + FILETIME curr_time; + GetSystemTimeAsFileTime(&curr_time); + + String certs; + PCCERT_CONTEXT curr = CertEnumCertificatesInStore(cert_store, nullptr); + while (curr) { + FILETIME ft; + DWORD size = sizeof(ft); + // Check if the certificate is disallowed. + if (CertGetCertificateContextProperty(curr, CERT_DISALLOWED_FILETIME_PROP_ID, &ft, &size) && CompareFileTime(&curr_time, &ft) != -1) { + curr = CertEnumCertificatesInStore(cert_store, curr); + continue; + } + // Encode and add to certificate list. + bool success = CryptBinaryToStringA(curr->pbCertEncoded, curr->cbCertEncoded, CRYPT_STRING_BASE64HEADER | CRYPT_STRING_NOCR, nullptr, &size); + ERR_CONTINUE(!success); + PackedByteArray pba; + pba.resize(size); + CryptBinaryToStringA(curr->pbCertEncoded, curr->cbCertEncoded, CRYPT_STRING_BASE64HEADER | CRYPT_STRING_NOCR, (char *)pba.ptrw(), &size); + certs += String((char *)pba.ptr(), size); + curr = CertEnumCertificatesInStore(cert_store, curr); + } + CertCloseStore(cert_store, 0); + return certs; +} + OS_Windows::OS_Windows(HINSTANCE _hInstance) { hInstance = _hInstance; + CoInitializeEx(nullptr, COINIT_MULTITHREADED); + #ifdef WASAPI_ENABLED AudioDriverManager::add_driver(&driver_wasapi); #endif @@ -1257,4 +1743,5 @@ OS_Windows::OS_Windows(HINSTANCE _hInstance) { } OS_Windows::~OS_Windows() { + CoUninitialize(); } diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h index bf934bce64..e873fb8a13 100644 --- a/platform/windows/os_windows.h +++ b/platform/windows/os_windows.h @@ -1,44 +1,45 @@ -/*************************************************************************/ -/* os_windows.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* os_windows.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 OS_WINDOWS_H #define OS_WINDOWS_H +#include "crash_handler_windows.h" +#include "key_mapping_windows.h" + #include "core/config/project_settings.h" #include "core/input/input.h" #include "core/os/os.h" -#include "crash_handler_windows.h" #include "drivers/unix/ip_unix.h" #include "drivers/wasapi/audio_driver_wasapi.h" #include "drivers/winmidi/midi_driver_winmidi.h" -#include "key_mapping_windows.h" #include "servers/audio_server.h" #ifdef XAUDIO2_ENABLED @@ -46,8 +47,9 @@ #endif #if defined(VULKAN_ENABLED) +#include "vulkan_context_win.h" + #include "drivers/vulkan/rendering_device_vulkan.h" -#include "platform/windows/vulkan_context_win.h" #endif #include <io.h> @@ -55,6 +57,8 @@ #include <stdio.h> #define WIN32_LEAN_AND_MEAN +#include <dwrite.h> +#include <dwrite_2.h> #include <windows.h> #include <windowsx.h> @@ -63,6 +67,10 @@ #define WINDOWS_DEBUG_OUTPUT_ENABLED #endif +#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING +#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x4 +#endif + template <class T> class ComAutoreleaseRef { public: @@ -75,6 +83,9 @@ public: _FORCE_INLINE_ bool is_valid() const { return reference != nullptr; } _FORCE_INLINE_ bool is_null() const { return reference == nullptr; } ComAutoreleaseRef() {} + ComAutoreleaseRef(T *p_ref) { + reference = p_ref; + } ~ComAutoreleaseRef() { if (reference != nullptr) { reference->Release(); @@ -110,6 +121,18 @@ class OS_Windows : public OS { HWND main_window; + IDWriteFactory *dwrite_factory = nullptr; + IDWriteFactory2 *dwrite_factory2 = nullptr; + IDWriteFontCollection *font_collection = nullptr; + IDWriteFontFallback *system_font_fallback = nullptr; + + bool dwrite_init = false; + bool dwrite2_init = false; + + String _get_default_fontname(const String &p_font_name) const; + DWRITE_FONT_WEIGHT _weight_to_dw(int p_weight) const; + DWRITE_FONT_STRETCH _stretch_to_dw(int p_stretch) const; + // functions used by main to initialize/deinitialize the OS protected: virtual void initialize() override; @@ -119,7 +142,7 @@ protected: virtual void finalize() override; virtual void finalize_core() override; - virtual String get_stdin_string(bool p_block) override; + virtual String get_stdin_string() override; String _quote_command_line_argument(const String &p_text) const; @@ -157,6 +180,8 @@ public: virtual void delay_usec(uint32_t p_usec) const override; virtual uint64_t get_ticks_usec() const override; + virtual Dictionary get_memory_info() const override; + virtual Error execute(const String &p_path, const List<String> &p_arguments, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr, bool p_open_console = false) override; virtual Error create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id = nullptr, bool p_open_console = false) override; virtual Error kill(const ProcessID &p_pid) override; @@ -165,10 +190,12 @@ public: virtual bool has_environment(const String &p_var) const override; virtual String get_environment(const String &p_var) const override; - virtual bool set_environment(const String &p_var, const String &p_value) const override; + virtual void set_environment(const String &p_var, const String &p_value) const override; + virtual void unset_environment(const String &p_var) const override; virtual Vector<String> get_system_fonts() const override; - virtual String get_system_font_path(const String &p_font_name, bool p_bold = false, bool p_italic = false) const override; + virtual String get_system_font_path(const String &p_font_name, int p_weight = 400, int p_stretch = 100, bool p_italic = false) const override; + virtual Vector<String> get_system_font_path_for_text(const String &p_font_name, const String &p_text, const String &p_locale = String(), const String &p_script = String(), int p_weight = 400, int p_stretch = 100, bool p_italic = false) const override; virtual String get_executable_path() const override; @@ -189,6 +216,7 @@ public: virtual String get_unique_id() const override; virtual Error shell_open(String p_uri) override; + virtual Error shell_show_in_file_manager(String p_path, bool p_open_folder) override; void run(); @@ -200,6 +228,8 @@ public: virtual Error move_to_trash(const String &p_path) override; + virtual String get_system_ca_certificates() override; + void set_main_window(HWND p_main_window) { main_window = p_main_window; } HINSTANCE get_hinstance() { return hInstance; } diff --git a/platform/windows/platform_config.h b/platform/windows/platform_config.h index 8e80f8cacb..ae4e51e3fb 100644 --- a/platform/windows/platform_config.h +++ b/platform/windows/platform_config.h @@ -1,33 +1,33 @@ -/*************************************************************************/ -/* platform_config.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* platform_config.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 <malloc.h> -#define OPENGL_INCLUDE_H "thirdparty/glad/glad/glad.h" +#define OPENGL_INCLUDE_H "thirdparty/glad/glad/gl.h" diff --git a/platform/windows/platform_windows_builders.py b/platform/windows/platform_windows_builders.py index 33ca2e8ffa..b522a75a9c 100644 --- a/platform/windows/platform_windows_builders.py +++ b/platform/windows/platform_windows_builders.py @@ -4,18 +4,15 @@ All such functions are invoked in a subprocess on Windows to prevent build flaki """ import os +from detect import get_mingw_bin_prefix from platform_methods import subprocess_main def make_debug_mingw(target, source, env): - mingw_prefix = "" - if env["arch"] == "x86_32": - mingw_prefix = env["mingw_prefix_32"] - else: - mingw_prefix = env["mingw_prefix_64"] - os.system(mingw_prefix + "objcopy --only-keep-debug {0} {0}.debugsymbols".format(target[0])) - os.system(mingw_prefix + "strip --strip-debug --strip-unneeded {0}".format(target[0])) - os.system(mingw_prefix + "objcopy --add-gnu-debuglink={0}.debugsymbols {0}".format(target[0])) + mingw_bin_prefix = get_mingw_bin_prefix(env["mingw_prefix"], env["arch"]) + os.system(mingw_bin_prefix + "objcopy --only-keep-debug {0} {0}.debugsymbols".format(target[0])) + os.system(mingw_bin_prefix + "strip --strip-debug --strip-unneeded {0}".format(target[0])) + os.system(mingw_bin_prefix + "objcopy --add-gnu-debuglink={0}.debugsymbols {0}".format(target[0])) if __name__ == "__main__": diff --git a/platform/windows/run_icon.svg b/platform/windows/run_icon.svg new file mode 100644 index 0000000000..0897276ef7 --- /dev/null +++ b/platform/windows/run_icon.svg @@ -0,0 +1 @@ +<svg height="16" width="16" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><path d="m1.095 2.997 5.66-.78v5.469h-5.66zm0 10.006 5.66.78v-5.4h-5.66zm6.282.863 7.528 1.04V8.381H7.377Zm0-11.732v5.552h7.528V1.095Z" fill="#00abed" style="stroke-width:.460341;fill:#e0e0e0;fill-opacity:1"/></svg> diff --git a/platform/windows/tts_windows.cpp b/platform/windows/tts_windows.cpp index e5daf602e6..907096d890 100644 --- a/platform/windows/tts_windows.cpp +++ b/platform/windows/tts_windows.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* tts_windows.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* tts_windows.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "tts_windows.h" @@ -36,15 +36,16 @@ void __stdcall TTS_Windows::speech_event_callback(WPARAM wParam, LPARAM lParam) TTS_Windows *tts = TTS_Windows::get_singleton(); SPEVENT event; while (tts->synth->GetEvents(1, &event, NULL) == S_OK) { - if (tts->ids.has(event.ulStreamNum)) { + uint32_t stream_num = (uint32_t)event.ulStreamNum; + if (tts->ids.has(stream_num)) { if (event.eEventId == SPEI_START_INPUT_STREAM) { - DisplayServer::get_singleton()->tts_post_utterance_event(DisplayServer::TTS_UTTERANCE_STARTED, tts->ids[event.ulStreamNum].id); + DisplayServer::get_singleton()->tts_post_utterance_event(DisplayServer::TTS_UTTERANCE_STARTED, tts->ids[stream_num].id); } else if (event.eEventId == SPEI_END_INPUT_STREAM) { - DisplayServer::get_singleton()->tts_post_utterance_event(DisplayServer::TTS_UTTERANCE_ENDED, tts->ids[event.ulStreamNum].id); - tts->ids.erase(event.ulStreamNum); + DisplayServer::get_singleton()->tts_post_utterance_event(DisplayServer::TTS_UTTERANCE_ENDED, tts->ids[stream_num].id); + tts->ids.erase(stream_num); tts->_update_tts(); } else if (event.eEventId == SPEI_WORD_BOUNDARY) { - const Char16String &string = tts->ids[event.ulStreamNum].string; + const Char16String &string = tts->ids[stream_num].string; int pos = 0; for (int i = 0; i < MIN(event.lParam, string.length()); i++) { char16_t c = string[i]; @@ -53,7 +54,7 @@ void __stdcall TTS_Windows::speech_event_callback(WPARAM wParam, LPARAM lParam) } pos++; } - DisplayServer::get_singleton()->tts_post_utterance_event(DisplayServer::TTS_UTTERANCE_BOUNDARY, tts->ids[event.ulStreamNum].id, pos - tts->ids[event.ulStreamNum].offset); + DisplayServer::get_singleton()->tts_post_utterance_event(DisplayServer::TTS_UTTERANCE_BOUNDARY, tts->ids[stream_num].id, pos - tts->ids[stream_num].offset); } } } @@ -106,7 +107,7 @@ void TTS_Windows::_update_tts() { synth->SetRate(10.f * log10(message.rate) / log10(3.f)); synth->Speak((LPCWSTR)ut.string.get_data(), flags, &stream_number); - ids[stream_number] = ut; + ids[(uint32_t)stream_number] = ut; queue.pop_front(); } @@ -117,7 +118,7 @@ bool TTS_Windows::is_speaking() const { SPVOICESTATUS status; synth->GetStatus(&status, nullptr); - return (status.dwRunningState == SPRS_IS_SPEAKING); + return (status.dwRunningState == SPRS_IS_SPEAKING || status.dwRunningState == 0 /* Waiting To Speak */); } bool TTS_Windows::is_paused() const { @@ -230,9 +231,10 @@ void TTS_Windows::stop() { SPVOICESTATUS status; synth->GetStatus(&status, nullptr); - if (ids.has(status.ulCurrentStream)) { - DisplayServer::get_singleton()->tts_post_utterance_event(DisplayServer::TTS_UTTERANCE_CANCELED, ids[status.ulCurrentStream].id); - ids.erase(status.ulCurrentStream); + uint32_t current_stream = (uint32_t)status.ulCurrentStream; + if (ids.has(current_stream)) { + DisplayServer::get_singleton()->tts_post_utterance_event(DisplayServer::TTS_UTTERANCE_CANCELED, ids[current_stream].id); + ids.erase(current_stream); } for (DisplayServer::TTSUtterance &message : queue) { DisplayServer::get_singleton()->tts_post_utterance_event(DisplayServer::TTS_UTTERANCE_CANCELED, message.id); @@ -249,7 +251,6 @@ TTS_Windows *TTS_Windows::get_singleton() { TTS_Windows::TTS_Windows() { singleton = this; - CoInitialize(nullptr); if (SUCCEEDED(CoCreateInstance(CLSID_SpVoice, nullptr, CLSCTX_ALL, IID_ISpVoice, (void **)&synth))) { ULONGLONG event_mask = SPFEI(SPEI_END_INPUT_STREAM) | SPFEI(SPEI_START_INPUT_STREAM) | SPFEI(SPEI_WORD_BOUNDARY); diff --git a/platform/windows/tts_windows.h b/platform/windows/tts_windows.h index d84a3d273a..33b597c612 100644 --- a/platform/windows/tts_windows.h +++ b/platform/windows/tts_windows.h @@ -1,39 +1,39 @@ -/*************************************************************************/ -/* tts_windows.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* tts_windows.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 TTS_WINDOWS_H #define TTS_WINDOWS_H #include "core/string/ustring.h" +#include "core/templates/hash_map.h" #include "core/templates/list.h" -#include "core/templates/rb_map.h" #include "core/variant/array.h" #include "servers/display_server.h" @@ -54,7 +54,7 @@ class TTS_Windows { int offset; int id; }; - RBMap<ULONG, UTData> ids; + HashMap<uint32_t, UTData> ids; static void __stdcall speech_event_callback(WPARAM wParam, LPARAM lParam); void _update_tts(); diff --git a/platform/windows/vulkan_context_win.cpp b/platform/windows/vulkan_context_win.cpp index ff9318e47e..a60055dbec 100644 --- a/platform/windows/vulkan_context_win.cpp +++ b/platform/windows/vulkan_context_win.cpp @@ -1,36 +1,37 @@ -/*************************************************************************/ -/* vulkan_context_win.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* vulkan_context_win.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ #if defined(WINDOWS_ENABLED) && defined(VULKAN_ENABLED) #include "vulkan_context_win.h" + #ifdef USE_VOLK #include <volk.h> #else @@ -55,9 +56,13 @@ Error VulkanContextWindows::window_create(DisplayServer::WindowID p_window_id, D } VulkanContextWindows::VulkanContextWindows() { + // Workaround for Vulkan not working on setups with AMD integrated graphics + NVIDIA dedicated GPU (GH-57708). + // This prevents using AMD integrated graphics with Vulkan entirely, but it allows the engine to start + // even on outdated/broken driver setups. + OS::get_singleton()->set_environment("DISABLE_LAYER_AMD_SWITCHABLE_GRAPHICS_1", "1"); } VulkanContextWindows::~VulkanContextWindows() { } -#endif +#endif // WINDOWS_ENABLED && VULKAN_ENABLED diff --git a/platform/windows/vulkan_context_win.h b/platform/windows/vulkan_context_win.h index 9dedcabb2b..01ae2031e7 100644 --- a/platform/windows/vulkan_context_win.h +++ b/platform/windows/vulkan_context_win.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* vulkan_context_win.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* vulkan_context_win.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 VULKAN_CONTEXT_WIN_H #define VULKAN_CONTEXT_WIN_H diff --git a/platform/windows/windows_terminal_logger.cpp b/platform/windows/windows_terminal_logger.cpp index df21977698..bb223628a8 100644 --- a/platform/windows/windows_terminal_logger.cpp +++ b/platform/windows/windows_terminal_logger.cpp @@ -1,38 +1,39 @@ -/*************************************************************************/ -/* windows_terminal_logger.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* windows_terminal_logger.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "windows_terminal_logger.h" #ifdef WINDOWS_ENABLED #include <stdio.h> + #define WIN32_LEAN_AND_MEAN #include <windows.h> @@ -163,4 +164,4 @@ void WindowsTerminalLogger::log_error(const char *p_function, const char *p_file WindowsTerminalLogger::~WindowsTerminalLogger() {} -#endif +#endif // WINDOWS_ENABLED diff --git a/platform/windows/windows_terminal_logger.h b/platform/windows/windows_terminal_logger.h index 348a49c845..60d82bb935 100644 --- a/platform/windows/windows_terminal_logger.h +++ b/platform/windows/windows_terminal_logger.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* windows_terminal_logger.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* windows_terminal_logger.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 WINDOWS_TERMINAL_LOGGER_H #define WINDOWS_TERMINAL_LOGGER_H @@ -42,6 +42,6 @@ public: virtual ~WindowsTerminalLogger(); }; -#endif +#endif // WINDOWS_ENABLED #endif // WINDOWS_TERMINAL_LOGGER_H |
