summaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
Diffstat (limited to 'platform')
-rw-r--r--platform/android/android_input_handler.cpp76
-rw-r--r--platform/android/android_input_handler.h6
-rw-r--r--platform/android/android_keys_utils.cpp6
-rw-r--r--platform/android/android_keys_utils.h228
-rw-r--r--platform/android/audio_driver_opensl.h4
-rw-r--r--platform/android/detect.py4
-rw-r--r--platform/android/display_server_android.cpp18
-rw-r--r--platform/android/export/export_plugin.cpp85
-rw-r--r--platform/android/export/godot_plugin_config.cpp7
-rw-r--r--platform/android/export/gradle_export_util.cpp43
-rw-r--r--platform/android/export/gradle_export_util.h15
-rw-r--r--platform/android/java/app/AndroidManifest.xml5
-rw-r--r--platform/android/java/app/config.gradle8
-rw-r--r--platform/android/java/build.gradle14
-rw-r--r--platform/android/java/gradle/wrapper/gradle-wrapper.jarbin54329 -> 59203 bytes
-rw-r--r--platform/android/java/gradle/wrapper/gradle-wrapper.properties5
-rwxr-xr-xplatform/android/java/gradlew53
-rw-r--r--platform/android/java/gradlew.bat47
-rw-r--r--platform/android/java/lib/AndroidManifest.xml3
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/Godot.java15
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderService.java22
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java25
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotIO.java29
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotLib.java3
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java2
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/utils/GLUtils.java1
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/vulkan/VkRenderer.kt2
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/xr/XRMode.java2
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularFallbackConfigChooser.java3
-rw-r--r--platform/android/java_godot_lib_jni.cpp29
-rw-r--r--platform/android/java_godot_lib_jni.h2
-rw-r--r--platform/android/os_android.cpp13
-rw-r--r--platform/android/os_android.h4
-rw-r--r--platform/iphone/app_delegate.h4
-rw-r--r--platform/iphone/detect.py5
-rw-r--r--platform/iphone/display_layer.mm2
-rw-r--r--platform/iphone/display_server_iphone.mm16
-rw-r--r--platform/iphone/export/export_plugin.cpp25
-rw-r--r--platform/iphone/joypad_iphone.mm44
-rw-r--r--platform/iphone/keyboard_input_view.mm8
-rw-r--r--platform/iphone/platform_config.h2
-rw-r--r--platform/javascript/SCsub6
-rw-r--r--platform/javascript/detect.py23
-rw-r--r--platform/javascript/display_server_javascript.cpp151
-rw-r--r--platform/javascript/display_server_javascript.h9
-rw-r--r--platform/javascript/dom_keys.inc26
-rw-r--r--platform/javascript/export/export_plugin.cpp6
-rw-r--r--platform/javascript/js/libs/library_godot_input.js24
-rw-r--r--platform/javascript/os_javascript.cpp2
-rw-r--r--platform/javascript/os_javascript.h2
-rw-r--r--platform/javascript/package-lock.json6
-rw-r--r--platform/linuxbsd/SCsub2
-rw-r--r--platform/linuxbsd/context_gl_x11.cpp257
-rw-r--r--platform/linuxbsd/crash_handler_linuxbsd.cpp2
-rw-r--r--platform/linuxbsd/detect.py28
-rw-r--r--platform/linuxbsd/detect_prime_x11.cpp4
-rw-r--r--platform/linuxbsd/detect_prime_x11.h2
-rw-r--r--platform/linuxbsd/display_server_x11.cpp722
-rw-r--r--platform/linuxbsd/display_server_x11.h27
-rw-r--r--platform/linuxbsd/freedesktop_screensaver.cpp4
-rw-r--r--platform/linuxbsd/gl_manager_x11.cpp384
-rw-r--r--platform/linuxbsd/gl_manager_x11.h (renamed from platform/linuxbsd/context_gl_x11.h)86
-rw-r--r--platform/linuxbsd/joypad_linux.cpp16
-rw-r--r--platform/linuxbsd/joypad_linux.h2
-rw-r--r--platform/linuxbsd/key_mapping_x11.cpp498
-rw-r--r--platform/linuxbsd/key_mapping_x11.h6
-rw-r--r--platform/linuxbsd/platform_config.h2
-rw-r--r--platform/osx/SCsub2
-rw-r--r--platform/osx/context_gl_osx.mm161
-rw-r--r--platform/osx/crash_handler_osx.mm7
-rw-r--r--platform/osx/detect.py18
-rw-r--r--platform/osx/display_server_osx.h23
-rw-r--r--platform/osx/display_server_osx.mm593
-rw-r--r--platform/osx/export/export_plugin.cpp35
-rw-r--r--platform/osx/gl_manager_osx.h (renamed from platform/osx/context_gl_osx.h)74
-rw-r--r--platform/osx/gl_manager_osx.mm233
-rw-r--r--platform/osx/joypad_osx.cpp43
-rw-r--r--platform/osx/joypad_osx.h5
-rw-r--r--platform/osx/os_osx.h4
-rw-r--r--platform/osx/os_osx.mm83
-rw-r--r--platform/osx/platform_config.h1
-rw-r--r--platform/uwp/app_uwp.cpp3
-rw-r--r--platform/uwp/detect.py2
-rw-r--r--platform/uwp/export/export_plugin.cpp2
-rw-r--r--platform/uwp/export/export_plugin.h14
-rw-r--r--platform/uwp/joypad_uwp.cpp12
-rw-r--r--platform/uwp/os_uwp.cpp19
-rw-r--r--platform/uwp/os_uwp.h13
-rw-r--r--platform/windows/SCsub2
-rw-r--r--platform/windows/context_gl_windows.cpp186
-rw-r--r--platform/windows/detect.py19
-rw-r--r--platform/windows/display_server_windows.cpp158
-rw-r--r--platform/windows/display_server_windows.h17
-rw-r--r--platform/windows/gl_manager_windows.cpp346
-rw-r--r--platform/windows/gl_manager_windows.h (renamed from platform/windows/context_gl_windows.h)94
-rw-r--r--platform/windows/joypad_windows.cpp30
-rw-r--r--platform/windows/key_mapping_windows.cpp556
-rw-r--r--platform/windows/key_mapping_windows.h4
-rw-r--r--platform/windows/os_windows.cpp30
-rw-r--r--platform/windows/os_windows.h8
-rw-r--r--platform/windows/platform_config.h2
-rw-r--r--platform/windows/windows_terminal_logger.cpp2
-rw-r--r--platform/windows/windows_terminal_logger.h4
104 files changed, 3587 insertions, 2404 deletions
diff --git a/platform/android/android_input_handler.cpp b/platform/android/android_input_handler.cpp
index e03375e8d9..52f80b3080 100644
--- a/platform/android/android_input_handler.cpp
+++ b/platform/android/android_input_handler.cpp
@@ -45,7 +45,7 @@ void AndroidInputHandler::process_joy_event(AndroidInputHandler::JoypadEvent p_e
Input::get_singleton()->joy_axis(p_event.device, (JoyAxis)p_event.index, value);
break;
case JOY_EVENT_HAT:
- Input::get_singleton()->joy_hat(p_event.device, (HatMask)p_event.hat);
+ Input::get_singleton()->joy_hat(p_event.device, p_event.hat);
break;
default:
return;
@@ -82,37 +82,37 @@ void AndroidInputHandler::process_key_event(int p_keycode, int p_scancode, int p
Ref<InputEventKey> ev;
ev.instantiate();
int val = unicode;
- int keycode = android_get_keysym(p_keycode);
- int phy_keycode = android_get_keysym(p_scancode);
+ Key keycode = android_get_keysym(p_keycode);
+ Key phy_keycode = android_get_keysym(p_scancode);
- if (keycode == KEY_SHIFT) {
+ if (keycode == Key::SHIFT) {
shift_mem = p_pressed;
}
- if (keycode == KEY_ALT) {
+ if (keycode == Key::ALT) {
alt_mem = p_pressed;
}
- if (keycode == KEY_CTRL) {
+ if (keycode == Key::CTRL) {
control_mem = p_pressed;
}
- if (keycode == KEY_META) {
+ if (keycode == Key::META) {
meta_mem = p_pressed;
}
- ev->set_keycode((Key)keycode);
- ev->set_physical_keycode((Key)phy_keycode);
+ ev->set_keycode(keycode);
+ ev->set_physical_keycode(phy_keycode);
ev->set_unicode(val);
ev->set_pressed(p_pressed);
_set_key_modifier_state(ev);
if (val == '\n') {
- ev->set_keycode(KEY_ENTER);
+ ev->set_keycode(Key::ENTER);
} else if (val == 61448) {
- ev->set_keycode(KEY_BACKSPACE);
- ev->set_unicode(KEY_BACKSPACE);
+ ev->set_keycode(Key::BACKSPACE);
+ ev->set_unicode((char32_t)Key::BACKSPACE);
} else if (val == 61453) {
- ev->set_keycode(KEY_ENTER);
- ev->set_unicode(KEY_ENTER);
+ ev->set_keycode(Key::ENTER);
+ ev->set_unicode((char32_t)Key::ENTER);
} else if (p_keycode == 4) {
if (DisplayServerAndroid *dsa = Object::cast_to<DisplayServerAndroid>(DisplayServer::get_singleton())) {
dsa->send_window_event(DisplayServer::WINDOW_EVENT_GO_BACK_REQUEST, true);
@@ -223,7 +223,7 @@ void AndroidInputHandler::process_touch(int p_event, int p_pointer, const Vector
ev->set_pressed(false);
ev->set_position(touch[i].pos);
Input::get_singleton()->parse_input_event(ev);
- touch.remove(i);
+ touch.remove_at(i);
break;
}
@@ -305,15 +305,15 @@ void AndroidInputHandler::process_mouse_event(int input_device, int event_action
ev->set_pressed(true);
buttons_state = event_buttons_mask;
if (event_vertical_factor > 0) {
- _wheel_button_click(event_buttons_mask, ev, MOUSE_BUTTON_WHEEL_UP, event_vertical_factor);
+ _wheel_button_click(event_buttons_mask, ev, MouseButton::WHEEL_UP, event_vertical_factor);
} else if (event_vertical_factor < 0) {
- _wheel_button_click(event_buttons_mask, ev, MOUSE_BUTTON_WHEEL_DOWN, -event_vertical_factor);
+ _wheel_button_click(event_buttons_mask, ev, MouseButton::WHEEL_DOWN, -event_vertical_factor);
}
if (event_horizontal_factor > 0) {
- _wheel_button_click(event_buttons_mask, ev, MOUSE_BUTTON_WHEEL_RIGHT, event_horizontal_factor);
+ _wheel_button_click(event_buttons_mask, ev, MouseButton::WHEEL_RIGHT, event_horizontal_factor);
} else if (event_horizontal_factor < 0) {
- _wheel_button_click(event_buttons_mask, ev, MOUSE_BUTTON_WHEEL_LEFT, -event_horizontal_factor);
+ _wheel_button_click(event_buttons_mask, ev, MouseButton::WHEEL_LEFT, -event_horizontal_factor);
}
} break;
}
@@ -323,7 +323,7 @@ void AndroidInputHandler::_wheel_button_click(MouseButton event_buttons_mask, co
Ref<InputEventMouseButton> evd = ev->duplicate();
_set_key_modifier_state(evd);
evd->set_button_index(wheel_button);
- evd->set_button_mask(MouseButton(event_buttons_mask ^ (1 << (wheel_button - 1))));
+ evd->set_button_mask(MouseButton(event_buttons_mask ^ mouse_button_to_mask(wheel_button)));
evd->set_factor(factor);
Input::get_singleton()->parse_input_event(evd);
Ref<InputEventMouseButton> evdd = evd->duplicate();
@@ -339,7 +339,7 @@ void AndroidInputHandler::process_double_tap(int event_android_button_mask, Poin
_set_key_modifier_state(ev);
ev->set_position(p_pos);
ev->set_global_position(p_pos);
- ev->set_pressed(event_button_mask != 0);
+ ev->set_pressed(event_button_mask != MouseButton::NONE);
ev->set_button_index(_button_index_from_mask(event_button_mask));
ev->set_button_mask(event_button_mask);
ev->set_double_click(true);
@@ -348,37 +348,37 @@ void AndroidInputHandler::process_double_tap(int event_android_button_mask, Poin
MouseButton AndroidInputHandler::_button_index_from_mask(MouseButton button_mask) {
switch (button_mask) {
- case MOUSE_BUTTON_MASK_LEFT:
- return MOUSE_BUTTON_LEFT;
- case MOUSE_BUTTON_MASK_RIGHT:
- return MOUSE_BUTTON_RIGHT;
- case MOUSE_BUTTON_MASK_MIDDLE:
- return MOUSE_BUTTON_MIDDLE;
- case MOUSE_BUTTON_MASK_XBUTTON1:
- return MOUSE_BUTTON_XBUTTON1;
- case MOUSE_BUTTON_MASK_XBUTTON2:
- return MOUSE_BUTTON_XBUTTON2;
+ case MouseButton::MASK_LEFT:
+ return MouseButton::LEFT;
+ case MouseButton::MASK_RIGHT:
+ return MouseButton::RIGHT;
+ case MouseButton::MASK_MIDDLE:
+ return MouseButton::MIDDLE;
+ case MouseButton::MASK_XBUTTON1:
+ return MouseButton::MB_XBUTTON1;
+ case MouseButton::MASK_XBUTTON2:
+ return MouseButton::MB_XBUTTON2;
default:
- return MOUSE_BUTTON_NONE;
+ return MouseButton::NONE;
}
}
MouseButton AndroidInputHandler::_android_button_mask_to_godot_button_mask(int android_button_mask) {
- MouseButton godot_button_mask = MOUSE_BUTTON_NONE;
+ MouseButton godot_button_mask = MouseButton::NONE;
if (android_button_mask & AMOTION_EVENT_BUTTON_PRIMARY) {
- godot_button_mask |= MOUSE_BUTTON_MASK_LEFT;
+ godot_button_mask |= MouseButton::MASK_LEFT;
}
if (android_button_mask & AMOTION_EVENT_BUTTON_SECONDARY) {
- godot_button_mask |= MOUSE_BUTTON_MASK_RIGHT;
+ godot_button_mask |= MouseButton::MASK_RIGHT;
}
if (android_button_mask & AMOTION_EVENT_BUTTON_TERTIARY) {
- godot_button_mask |= MOUSE_BUTTON_MASK_MIDDLE;
+ godot_button_mask |= MouseButton::MASK_MIDDLE;
}
if (android_button_mask & AMOTION_EVENT_BUTTON_BACK) {
- godot_button_mask |= MOUSE_BUTTON_MASK_XBUTTON1;
+ godot_button_mask |= MouseButton::MASK_XBUTTON1;
}
if (android_button_mask & AMOTION_EVENT_BUTTON_FORWARD) {
- godot_button_mask |= MOUSE_BUTTON_MASK_XBUTTON2;
+ godot_button_mask |= MouseButton::MASK_XBUTTON2;
}
return godot_button_mask;
diff --git a/platform/android/android_input_handler.h b/platform/android/android_input_handler.h
index 2918ca300b..e0b4196f14 100644
--- a/platform/android/android_input_handler.h
+++ b/platform/android/android_input_handler.h
@@ -53,10 +53,10 @@ public:
struct JoypadEvent {
int device = 0;
int type = 0;
- int index = 0;
+ int index = 0; // Can be either JoyAxis or JoyButton.
bool pressed = false;
float value = 0;
- int hat = 0;
+ HatMask hat = HatMask::CENTER;
};
private:
@@ -65,7 +65,7 @@ private:
bool control_mem = false;
bool meta_mem = false;
- MouseButton buttons_state = MOUSE_BUTTON_NONE;
+ MouseButton buttons_state = MouseButton::NONE;
Vector<TouchPos> touch;
Point2 hover_prev_pos; // needed to calculate the relative position on hover events
diff --git a/platform/android/android_keys_utils.cpp b/platform/android/android_keys_utils.cpp
index 5aa546c17b..0cea0589ce 100644
--- a/platform/android/android_keys_utils.cpp
+++ b/platform/android/android_keys_utils.cpp
@@ -30,12 +30,12 @@
#include "android_keys_utils.h"
-unsigned int android_get_keysym(unsigned int p_code) {
- for (int i = 0; _ak_to_keycode[i].keysym != KEY_UNKNOWN; i++) {
+Key android_get_keysym(unsigned int p_code) {
+ for (int i = 0; _ak_to_keycode[i].keysym != Key::UNKNOWN; i++) {
if (_ak_to_keycode[i].keycode == p_code) {
return _ak_to_keycode[i].keysym;
}
}
- return KEY_UNKNOWN;
+ return Key::UNKNOWN;
}
diff --git a/platform/android/android_keys_utils.h b/platform/android/android_keys_utils.h
index 6d25a366a4..bac9bab6db 100644
--- a/platform/android/android_keys_utils.h
+++ b/platform/android/android_keys_utils.h
@@ -35,128 +35,128 @@
#include <core/os/keyboard.h>
struct _WinTranslatePair {
- unsigned int keysym = 0;
+ Key keysym = Key::NONE;
unsigned int keycode = 0;
};
static _WinTranslatePair _ak_to_keycode[] = {
- { KEY_TAB, AKEYCODE_TAB },
- { KEY_ENTER, AKEYCODE_ENTER },
- { KEY_SHIFT, AKEYCODE_SHIFT_LEFT },
- { KEY_SHIFT, AKEYCODE_SHIFT_RIGHT },
- { KEY_ALT, AKEYCODE_ALT_LEFT },
- { KEY_ALT, AKEYCODE_ALT_RIGHT },
- { KEY_MENU, AKEYCODE_MENU },
- { KEY_PAUSE, AKEYCODE_MEDIA_PLAY_PAUSE },
- { KEY_ESCAPE, AKEYCODE_BACK },
- { KEY_SPACE, AKEYCODE_SPACE },
- { KEY_PAGEUP, AKEYCODE_PAGE_UP },
- { KEY_PAGEDOWN, AKEYCODE_PAGE_DOWN },
- { KEY_HOME, AKEYCODE_HOME }, //(0x24)
- { KEY_LEFT, AKEYCODE_DPAD_LEFT },
- { KEY_UP, AKEYCODE_DPAD_UP },
- { KEY_RIGHT, AKEYCODE_DPAD_RIGHT },
- { KEY_DOWN, AKEYCODE_DPAD_DOWN },
- { KEY_PERIODCENTERED, AKEYCODE_DPAD_CENTER },
- { KEY_BACKSPACE, AKEYCODE_DEL },
- { KEY_0, AKEYCODE_0 }, ////0 key
- { KEY_1, AKEYCODE_1 }, ////1 key
- { KEY_2, AKEYCODE_2 }, ////2 key
- { KEY_3, AKEYCODE_3 }, ////3 key
- { KEY_4, AKEYCODE_4 }, ////4 key
- { KEY_5, AKEYCODE_5 }, ////5 key
- { KEY_6, AKEYCODE_6 }, ////6 key
- { KEY_7, AKEYCODE_7 }, ////7 key
- { KEY_8, AKEYCODE_8 }, ////8 key
- { KEY_9, AKEYCODE_9 }, ////9 key
- { KEY_A, AKEYCODE_A }, ////A key
- { KEY_B, AKEYCODE_B }, ////B key
- { KEY_C, AKEYCODE_C }, ////C key
- { KEY_D, AKEYCODE_D }, ////D key
- { KEY_E, AKEYCODE_E }, ////E key
- { KEY_F, AKEYCODE_F }, ////F key
- { KEY_G, AKEYCODE_G }, ////G key
- { KEY_H, AKEYCODE_H }, ////H key
- { KEY_I, AKEYCODE_I }, ////I key
- { KEY_J, AKEYCODE_J }, ////J key
- { KEY_K, AKEYCODE_K }, ////K key
- { KEY_L, AKEYCODE_L }, ////L key
- { KEY_M, AKEYCODE_M }, ////M key
- { KEY_N, AKEYCODE_N }, ////N key
- { KEY_O, AKEYCODE_O }, ////O key
- { KEY_P, AKEYCODE_P }, ////P key
- { KEY_Q, AKEYCODE_Q }, ////Q key
- { KEY_R, AKEYCODE_R }, ////R key
- { KEY_S, AKEYCODE_S }, ////S key
- { KEY_T, AKEYCODE_T }, ////T key
- { KEY_U, AKEYCODE_U }, ////U key
- { KEY_V, AKEYCODE_V }, ////V key
- { KEY_W, AKEYCODE_W }, ////W key
- { KEY_X, AKEYCODE_X }, ////X key
- { KEY_Y, AKEYCODE_Y }, ////Y key
- { KEY_Z, AKEYCODE_Z }, ////Z key
- { KEY_HOMEPAGE, AKEYCODE_EXPLORER },
- { KEY_LAUNCH0, AKEYCODE_BUTTON_A },
- { KEY_LAUNCH1, AKEYCODE_BUTTON_B },
- { KEY_LAUNCH2, AKEYCODE_BUTTON_C },
- { KEY_LAUNCH3, AKEYCODE_BUTTON_X },
- { KEY_LAUNCH4, AKEYCODE_BUTTON_Y },
- { KEY_LAUNCH5, AKEYCODE_BUTTON_Z },
- { KEY_LAUNCH6, AKEYCODE_BUTTON_L1 },
- { KEY_LAUNCH7, AKEYCODE_BUTTON_R1 },
- { KEY_LAUNCH8, AKEYCODE_BUTTON_L2 },
- { KEY_LAUNCH9, AKEYCODE_BUTTON_R2 },
- { KEY_LAUNCHA, AKEYCODE_BUTTON_THUMBL },
- { KEY_LAUNCHB, AKEYCODE_BUTTON_THUMBR },
- { KEY_LAUNCHC, AKEYCODE_BUTTON_START },
- { KEY_LAUNCHD, AKEYCODE_BUTTON_SELECT },
- { KEY_LAUNCHE, AKEYCODE_BUTTON_MODE },
- { KEY_VOLUMEMUTE, AKEYCODE_MUTE },
- { KEY_VOLUMEDOWN, AKEYCODE_VOLUME_DOWN },
- { KEY_VOLUMEUP, AKEYCODE_VOLUME_UP },
- { KEY_BACK, AKEYCODE_MEDIA_REWIND },
- { KEY_FORWARD, AKEYCODE_MEDIA_FAST_FORWARD },
- { KEY_MEDIANEXT, AKEYCODE_MEDIA_NEXT },
- { KEY_MEDIAPREVIOUS, AKEYCODE_MEDIA_PREVIOUS },
- { KEY_MEDIASTOP, AKEYCODE_MEDIA_STOP },
- { KEY_PLUS, AKEYCODE_PLUS },
- { KEY_EQUAL, AKEYCODE_EQUALS }, // the '+' key
- { KEY_COMMA, AKEYCODE_COMMA }, // the ',' key
- { KEY_MINUS, AKEYCODE_MINUS }, // the '-' key
- { KEY_SLASH, AKEYCODE_SLASH }, // the '/?' key
- { KEY_BACKSLASH, AKEYCODE_BACKSLASH },
- { KEY_BRACKETLEFT, AKEYCODE_LEFT_BRACKET },
- { KEY_BRACKETRIGHT, AKEYCODE_RIGHT_BRACKET },
- { KEY_CTRL, AKEYCODE_CTRL_LEFT },
- { KEY_CTRL, AKEYCODE_CTRL_RIGHT },
- { KEY_UNKNOWN, 0 }
+ { Key::TAB, AKEYCODE_TAB },
+ { Key::ENTER, AKEYCODE_ENTER },
+ { Key::SHIFT, AKEYCODE_SHIFT_LEFT },
+ { Key::SHIFT, AKEYCODE_SHIFT_RIGHT },
+ { Key::ALT, AKEYCODE_ALT_LEFT },
+ { Key::ALT, AKEYCODE_ALT_RIGHT },
+ { Key::MENU, AKEYCODE_MENU },
+ { Key::PAUSE, AKEYCODE_MEDIA_PLAY_PAUSE },
+ { Key::ESCAPE, AKEYCODE_BACK },
+ { Key::SPACE, AKEYCODE_SPACE },
+ { Key::PAGEUP, AKEYCODE_PAGE_UP },
+ { Key::PAGEDOWN, AKEYCODE_PAGE_DOWN },
+ { Key::HOME, AKEYCODE_HOME }, //(0x24)
+ { Key::LEFT, AKEYCODE_DPAD_LEFT },
+ { Key::UP, AKEYCODE_DPAD_UP },
+ { Key::RIGHT, AKEYCODE_DPAD_RIGHT },
+ { Key::DOWN, AKEYCODE_DPAD_DOWN },
+ { Key::PERIODCENTERED, AKEYCODE_DPAD_CENTER },
+ { Key::BACKSPACE, AKEYCODE_DEL },
+ { Key::KEY_0, AKEYCODE_0 },
+ { Key::KEY_1, AKEYCODE_1 },
+ { Key::KEY_2, AKEYCODE_2 },
+ { Key::KEY_3, AKEYCODE_3 },
+ { Key::KEY_4, AKEYCODE_4 },
+ { Key::KEY_5, AKEYCODE_5 },
+ { Key::KEY_6, AKEYCODE_6 },
+ { Key::KEY_7, AKEYCODE_7 },
+ { Key::KEY_8, AKEYCODE_8 },
+ { Key::KEY_9, AKEYCODE_9 },
+ { Key::A, AKEYCODE_A },
+ { Key::B, AKEYCODE_B },
+ { Key::C, AKEYCODE_C },
+ { Key::D, AKEYCODE_D },
+ { Key::E, AKEYCODE_E },
+ { Key::F, AKEYCODE_F },
+ { Key::G, AKEYCODE_G },
+ { Key::H, AKEYCODE_H },
+ { Key::I, AKEYCODE_I },
+ { Key::J, AKEYCODE_J },
+ { Key::K, AKEYCODE_K },
+ { Key::L, AKEYCODE_L },
+ { Key::M, AKEYCODE_M },
+ { Key::N, AKEYCODE_N },
+ { Key::O, AKEYCODE_O },
+ { Key::P, AKEYCODE_P },
+ { Key::Q, AKEYCODE_Q },
+ { Key::R, AKEYCODE_R },
+ { Key::S, AKEYCODE_S },
+ { Key::T, AKEYCODE_T },
+ { Key::U, AKEYCODE_U },
+ { Key::V, AKEYCODE_V },
+ { Key::W, AKEYCODE_W },
+ { Key::X, AKEYCODE_X },
+ { Key::Y, AKEYCODE_Y },
+ { Key::Z, AKEYCODE_Z },
+ { Key::HOMEPAGE, AKEYCODE_EXPLORER },
+ { Key::LAUNCH0, AKEYCODE_BUTTON_A },
+ { Key::LAUNCH1, AKEYCODE_BUTTON_B },
+ { Key::LAUNCH2, AKEYCODE_BUTTON_C },
+ { Key::LAUNCH3, AKEYCODE_BUTTON_X },
+ { Key::LAUNCH4, AKEYCODE_BUTTON_Y },
+ { Key::LAUNCH5, AKEYCODE_BUTTON_Z },
+ { Key::LAUNCH6, AKEYCODE_BUTTON_L1 },
+ { Key::LAUNCH7, AKEYCODE_BUTTON_R1 },
+ { Key::LAUNCH8, AKEYCODE_BUTTON_L2 },
+ { Key::LAUNCH9, AKEYCODE_BUTTON_R2 },
+ { Key::LAUNCHA, AKEYCODE_BUTTON_THUMBL },
+ { Key::LAUNCHB, AKEYCODE_BUTTON_THUMBR },
+ { Key::LAUNCHC, AKEYCODE_BUTTON_START },
+ { Key::LAUNCHD, AKEYCODE_BUTTON_SELECT },
+ { Key::LAUNCHE, AKEYCODE_BUTTON_MODE },
+ { Key::VOLUMEMUTE, AKEYCODE_MUTE },
+ { Key::VOLUMEDOWN, AKEYCODE_VOLUME_DOWN },
+ { Key::VOLUMEUP, AKEYCODE_VOLUME_UP },
+ { Key::BACK, AKEYCODE_MEDIA_REWIND },
+ { Key::FORWARD, AKEYCODE_MEDIA_FAST_FORWARD },
+ { Key::MEDIANEXT, AKEYCODE_MEDIA_NEXT },
+ { Key::MEDIAPREVIOUS, AKEYCODE_MEDIA_PREVIOUS },
+ { Key::MEDIASTOP, AKEYCODE_MEDIA_STOP },
+ { Key::PLUS, AKEYCODE_PLUS },
+ { Key::EQUAL, AKEYCODE_EQUALS }, // the '+' key
+ { Key::COMMA, AKEYCODE_COMMA }, // the ',' key
+ { Key::MINUS, AKEYCODE_MINUS }, // the '-' key
+ { Key::SLASH, AKEYCODE_SLASH }, // the '/?' key
+ { Key::BACKSLASH, AKEYCODE_BACKSLASH },
+ { Key::BRACKETLEFT, AKEYCODE_LEFT_BRACKET },
+ { Key::BRACKETRIGHT, AKEYCODE_RIGHT_BRACKET },
+ { Key::CTRL, AKEYCODE_CTRL_LEFT },
+ { Key::CTRL, AKEYCODE_CTRL_RIGHT },
+ { Key::UNKNOWN, 0 }
};
/*
TODO: map these android key:
- AKEYCODE_SOFT_LEFT = 1,
- AKEYCODE_SOFT_RIGHT = 2,
- AKEYCODE_CALL = 5,
- AKEYCODE_ENDCALL = 6,
- AKEYCODE_STAR = 17,
- AKEYCODE_POUND = 18,
- AKEYCODE_POWER = 26,
- AKEYCODE_CAMERA = 27,
- AKEYCODE_CLEAR = 28,
- AKEYCODE_SYM = 63,
- AKEYCODE_ENVELOPE = 65,
- AKEYCODE_GRAVE = 68,
- AKEYCODE_SEMICOLON = 74,
- AKEYCODE_APOSTROPHE = 75,
- AKEYCODE_AT = 77,
- AKEYCODE_NUM = 78,
- AKEYCODE_HEADSETHOOK = 79,
- AKEYCODE_FOCUS = 80, // *Camera* focus
- AKEYCODE_NOTIFICATION = 83,
- AKEYCODE_SEARCH = 84,
- AKEYCODE_PICTSYMBOLS = 94,
- AKEYCODE_SWITCH_CHARSET = 95,
+ AKEYCODE_SOFT_LEFT = 1,
+ AKEYCODE_SOFT_RIGHT = 2,
+ AKEYCODE_CALL = 5,
+ AKEYCODE_ENDCALL = 6,
+ AKEYCODE_STAR = 17,
+ AKEYCODE_POUND = 18,
+ AKEYCODE_POWER = 26,
+ AKEYCODE_CAMERA = 27,
+ AKEYCODE_CLEAR = 28,
+ AKEYCODE_SYM = 63,
+ AKEYCODE_ENVELOPE = 65,
+ AKEYCODE_GRAVE = 68,
+ AKEYCODE_SEMICOLON = 74,
+ AKEYCODE_APOSTROPHE = 75,
+ AKEYCODE_AT = 77,
+ AKEYCODE_NUM = 78,
+ AKEYCODE_HEADSETHOOK = 79,
+ AKEYCODE_FOCUS = 80, // *Camera* focus
+ AKEYCODE_NOTIFICATION = 83,
+ AKEYCODE_SEARCH = 84,
+ AKEYCODE_PICTSYMBOLS = 94,
+ AKEYCODE_SWITCH_CHARSET = 95,
*/
-unsigned int android_get_keysym(unsigned int p_code);
+Key android_get_keysym(unsigned int p_code);
#endif // ANDROID_KEYS_UTILS_H
diff --git a/platform/android/audio_driver_opensl.h b/platform/android/audio_driver_opensl.h
index e3efaddba2..fcc2513f3f 100644
--- a/platform/android/audio_driver_opensl.h
+++ b/platform/android/audio_driver_opensl.h
@@ -59,7 +59,6 @@ class AudioDriverOpenSL : public AudioDriver {
SLObjectItf sl;
SLEngineItf EngineItf;
SLObjectItf OutputMix;
- SLVolumeItf volumeItf;
SLObjectItf player;
SLObjectItf recorder;
SLAndroidSimpleBufferQueueItf bufferQueueItf;
@@ -68,7 +67,6 @@ class AudioDriverOpenSL : public AudioDriver {
SLDataFormat_PCM pcm;
SLDataSink audioSink;
SLDataLocator_OutputMix locator_outputmix;
- SLBufferQueueState state;
static AudioDriverOpenSL *s_ad;
@@ -89,8 +87,6 @@ class AudioDriverOpenSL : public AudioDriver {
virtual Error capture_init_device();
public:
- void set_singleton();
-
virtual const char *get_name() const;
virtual Error init();
diff --git a/platform/android/detect.py b/platform/android/detect.py
index 406f10de89..6f98dab2cc 100644
--- a/platform/android/detect.py
+++ b/platform/android/detect.py
@@ -197,12 +197,10 @@ def configure(env):
env.Append(CPPDEFINES=["NDEBUG"])
if can_vectorize:
env.Append(CCFLAGS=["-ftree-vectorize"])
- if env["target"] == "release_debug":
- env.Append(CPPDEFINES=["DEBUG_ENABLED"])
elif env["target"] == "debug":
env.Append(LINKFLAGS=["-O0"])
env.Append(CCFLAGS=["-O0", "-g", "-fno-limit-debug-info"])
- env.Append(CPPDEFINES=["_DEBUG", "DEBUG_ENABLED"])
+ env.Append(CPPDEFINES=["_DEBUG"])
env.Append(CPPFLAGS=["-UNDEBUG"])
# Compiler configuration
diff --git a/platform/android/display_server_android.cpp b/platform/android/display_server_android.cpp
index 720752d28f..505e7ac0eb 100644
--- a/platform/android/display_server_android.cpp
+++ b/platform/android/display_server_android.cpp
@@ -119,7 +119,9 @@ DisplayServer::ScreenOrientation DisplayServerAndroid::screen_get_orientation(in
GodotIOJavaWrapper *godot_io_java = OS_Android::get_singleton()->get_godot_io_java();
ERR_FAIL_COND_V(!godot_io_java, SCREEN_LANDSCAPE);
- return (ScreenOrientation)godot_io_java->get_screen_orientation();
+ const int orientation = godot_io_java->get_screen_orientation();
+ ERR_FAIL_INDEX_V_MSG(orientation, 7, SCREEN_LANDSCAPE, "Unrecognized screen orientation");
+ return (ScreenOrientation)orientation;
}
int DisplayServerAndroid::get_screen_count() const {
@@ -344,8 +346,8 @@ void DisplayServerAndroid::process_events() {
Vector<String> DisplayServerAndroid::get_rendering_drivers_func() {
Vector<String> drivers;
-#ifdef OPENGL_ENABLED
- drivers.push_back("opengl");
+#ifdef GLES3_ENABLED
+ drivers.push_back("opengl3");
#endif
#ifdef VULKAN_ENABLED
drivers.push_back("vulkan");
@@ -407,13 +409,13 @@ DisplayServerAndroid::DisplayServerAndroid(const String &p_rendering_driver, Dis
keep_screen_on = GLOBAL_GET("display/window/energy_saving/keep_screen_on");
-#if defined(OPENGL_ENABLED)
- if (rendering_driver == "opengl") {
+#if defined(GLES3_ENABLED)
+ if (rendering_driver == "opengl3") {
bool gl_initialization_error = false;
- if (RasterizerGLES2::is_viable() == OK) {
- RasterizerGLES2::register_config();
- RasterizerGLES2::make_current();
+ if (RasterizerGLES3::is_viable() == OK) {
+ RasterizerGLES3::register_config();
+ RasterizerGLES3::make_current();
} else {
gl_initialization_error = true;
}
diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp
index 6ef17faf06..c5d3cbd966 100644
--- a/platform/android/export/export_plugin.cpp
+++ b/platform/android/export/export_plugin.cpp
@@ -498,11 +498,11 @@ bool EditorExportPlatformAndroid::is_package_name_valid(const String &p_package,
bool EditorExportPlatformAndroid::_should_compress_asset(const String &p_path, const Vector<uint8_t> &p_data) {
/*
- * By not compressing files with little or not benefit in doing so,
- * a performance gain is expected attime. Moreover, if the APK is
- * zip-aligned, assets stored as they are can be efficiently read by
- * Android by memory-mapping them.
- */
+ * By not compressing files with little or not benefit in doing so,
+ * a performance gain is expected attime. Moreover, if the APK is
+ * zip-aligned, assets stored as they are can be efficiently read by
+ * Android by memory-mapping them.
+ */
// -- Unconditional uncompress to mimic AAPT plus some other
@@ -751,9 +751,9 @@ void EditorExportPlatformAndroid::_get_permissions(const Ref<EditorExportPreset>
}
int xr_mode_index = p_preset->get("xr_features/xr_mode");
- if (xr_mode_index == 1 /* XRMode.OVR */) {
+ if (xr_mode_index == XR_MODE_OPENXR) {
int hand_tracking_index = p_preset->get("xr_features/hand_tracking"); // 0: none, 1: optional, 2: required
- if (hand_tracking_index > 0) {
+ if (hand_tracking_index > XR_HAND_TRACKING_NONE) {
if (r_permissions.find("com.oculus.permission.HAND_TRACKING") == -1) {
r_permissions.push_back("com.oculus.permission.HAND_TRACKING");
}
@@ -851,16 +851,11 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref<EditorExportPreset> &p
int iofs = ofs + 8;
string_count = decode_uint32(&p_manifest[iofs]);
- //styles_count = decode_uint32(&p_manifest[iofs + 4]);
+ // iofs + 4 is `styles_count`.
string_flags = decode_uint32(&p_manifest[iofs + 8]);
string_data_offset = decode_uint32(&p_manifest[iofs + 12]);
- //styles_offset = decode_uint32(&p_manifest[iofs + 16]);
- /*
- printf("string count: %i\n",string_count);
- printf("flags: %i\n",string_flags);
- printf("sdata ofs: %i\n",string_data_offset);
- printf("styles ofs: %i\n",styles_offset);
- */
+ // iofs + 16 is `styles_offset`.
+
uint32_t st_offset = iofs + 20;
string_table.resize(string_count);
uint32_t string_end = 0;
@@ -969,6 +964,20 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref<EditorExportPreset> &p
}
}
+ if (tname == "meta-data" && attrname == "name" && value == "xr_mode_metadata_name") {
+ // Update the meta-data 'android:name' attribute based on the selected XR mode.
+ if (xr_mode_index == XR_MODE_OPENXR) {
+ string_table.write[attr_value] = "com.samsung.android.vr.application.mode";
+ }
+ }
+
+ if (tname == "meta-data" && attrname == "value" && value == "xr_mode_metadata_value") {
+ // Update the meta-data 'android:value' attribute based on the selected XR mode.
+ if (xr_mode_index == XR_MODE_OPENXR) {
+ string_table.write[attr_value] = "vr_only";
+ }
+ }
+
iofs += 20;
}
@@ -983,7 +992,7 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref<EditorExportPreset> &p
Vector<bool> feature_required_list;
Vector<int> feature_versions;
- if (xr_mode_index == 1 /* XRMode.OVR */) {
+ 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);
@@ -991,11 +1000,19 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref<EditorExportPreset> &p
// Check for hand tracking
int hand_tracking_index = p_preset->get("xr_features/hand_tracking"); // 0: none, 1: optional, 2: required
- if (hand_tracking_index > 0) {
+ if (hand_tracking_index > XR_HAND_TRACKING_NONE) {
feature_names.push_back("oculus.software.handtracking");
- feature_required_list.push_back(hand_tracking_index == 2);
+ 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);
+ }
}
if (feature_names.size() > 0) {
@@ -1617,11 +1634,11 @@ Vector<String> EditorExportPlatformAndroid::get_enabled_abis(const Ref<EditorExp
void EditorExportPlatformAndroid::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) {
String driver = ProjectSettings::get_singleton()->get("rendering/driver/driver_name");
- if (driver == "GLES2") {
+ if (driver == "opengl3") {
r_features->push_back("etc");
}
// FIXME: Review what texture formats are used for Vulkan.
- if (driver == "Vulkan") {
+ if (driver == "vulkan") {
r_features->push_back("etc2");
}
@@ -1672,11 +1689,11 @@ void EditorExportPlatformAndroid::get_export_options(List<ExportOption> *r_optio
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, launcher_adaptive_icon_foreground_option, PROPERTY_HINT_FILE, "*.png"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, launcher_adaptive_icon_background_option, PROPERTY_HINT_FILE, "*.png"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "graphics/32_bits_framebuffer"), true));
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,Oculus Mobile VR"), 0));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "xr_features/xr_mode", PROPERTY_HINT_ENUM, "Regular,OpenXR"), 0));
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "xr_features/hand_tracking", PROPERTY_HINT_ENUM, "None,Optional,Required"), 0));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "xr_features/passthrough", PROPERTY_HINT_ENUM, "None,Optional,Required"), 0));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/immersive_mode"), true));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/support_small"), true));
@@ -2143,10 +2160,17 @@ bool EditorExportPlatformAndroid::can_export(const Ref<EditorExportPreset> &p_pr
// 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");
- if (xr_mode_index != /* XRMode.OVR*/ 1) {
- if (hand_tracking > 0) {
+ 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 \"Oculus Mobile VR\".");
+ 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";
}
}
@@ -2188,7 +2212,7 @@ void EditorExportPlatformAndroid::get_command_line_flags(const Ref<EditorExportP
Vector<String> command_line_strings = cmdline.strip_edges().split(" ");
for (int i = 0; i < command_line_strings.size(); i++) {
if (command_line_strings[i].strip_edges().length() == 0) {
- command_line_strings.remove(i);
+ command_line_strings.remove_at(i);
i--;
}
}
@@ -2208,17 +2232,12 @@ void EditorExportPlatformAndroid::get_command_line_flags(const Ref<EditorExportP
}
int xr_mode_index = p_preset->get("xr_features/xr_mode");
- if (xr_mode_index == 1) {
- command_line_strings.push_back("--xr_mode_ovr");
+ if (xr_mode_index == XR_MODE_OPENXR) {
+ command_line_strings.push_back("--xr_mode_openxr");
} else { // XRMode.REGULAR is the default.
command_line_strings.push_back("--xr_mode_regular");
}
- bool use_32_bit_framebuffer = p_preset->get("graphics/32_bits_framebuffer");
- if (use_32_bit_framebuffer) {
- command_line_strings.push_back("--use_depth_32");
- }
-
bool immersive = p_preset->get("screen/immersive_mode");
if (immersive) {
command_line_strings.push_back("--use_immersive");
diff --git a/platform/android/export/godot_plugin_config.cpp b/platform/android/export/godot_plugin_config.cpp
index ba7b8ce6c7..205cba3350 100644
--- a/platform/android/export/godot_plugin_config.cpp
+++ b/platform/android/export/godot_plugin_config.cpp
@@ -78,14 +78,13 @@ Vector<PluginConfigAndroid> PluginConfigAndroid::get_prebuilt_plugins(String plu
bool PluginConfigAndroid::is_plugin_config_valid(PluginConfigAndroid plugin_config) {
bool valid_name = !plugin_config.name.is_empty();
bool valid_binary_type = plugin_config.binary_type == PluginConfigAndroid::BINARY_TYPE_LOCAL ||
- plugin_config.binary_type == PluginConfigAndroid::BINARY_TYPE_REMOTE;
+ plugin_config.binary_type == PluginConfigAndroid::BINARY_TYPE_REMOTE;
bool valid_binary = false;
if (valid_binary_type) {
valid_binary = !plugin_config.binary.is_empty() &&
- (plugin_config.binary_type == PluginConfigAndroid::BINARY_TYPE_REMOTE ||
-
- FileAccess::exists(plugin_config.binary));
+ (plugin_config.binary_type == PluginConfigAndroid::BINARY_TYPE_REMOTE ||
+ FileAccess::exists(plugin_config.binary));
}
bool valid_local_dependencies = true;
diff --git a/platform/android/export/gradle_export_util.cpp b/platform/android/export/gradle_export_util.cpp
index 851bd0ac52..658c0ecd0a 100644
--- a/platform/android/export/gradle_export_util.cpp
+++ b/platform/android/export/gradle_export_util.cpp
@@ -128,11 +128,26 @@ Error rename_and_store_file_in_gradle_project(void *p_userdata, const String &p_
return err;
}
+String _android_xml_escape(const String &p_string) {
+ // Android XML requires strings to be both valid XML (`xml_escape()`) but also
+ // to escape characters which are valid XML but have special meaning in Android XML.
+ // https://developer.android.com/guide/topics/resources/string-resource.html#FormattingAndStyling
+ // Note: Didn't handle U+XXXX unicode chars, could be done if needed.
+ return p_string
+ .replace("@", "\\@")
+ .replace("?", "\\?")
+ .replace("'", "\\'")
+ .replace("\"", "\\\"")
+ .replace("\n", "\\n")
+ .replace("\t", "\\t")
+ .xml_escape(false);
+}
+
// Creates strings.xml files inside the gradle project for different locales.
Error _create_project_name_strings_files(const Ref<EditorExportPreset> &p_preset, const String &project_name) {
print_verbose("Creating strings resources for supported locales for project " + project_name);
// Stores the string into the default values directory.
- String processed_default_xml_string = vformat(godot_project_name_xml_string, project_name.xml_escape(true));
+ String processed_default_xml_string = vformat(godot_project_name_xml_string, _android_xml_escape(project_name));
store_string_at_path("res://android/build/res/values/godot_project_name_string.xml", processed_default_xml_string);
// Searches the Gradle project res/ directory to find all supported locales
@@ -158,7 +173,7 @@ Error _create_project_name_strings_files(const Ref<EditorExportPreset> &p_preset
String locale_directory = "res://android/build/res/" + file + "/godot_project_name_string.xml";
if (ProjectSettings::get_singleton()->has_setting(property_name)) {
String locale_project_name = ProjectSettings::get_singleton()->get(property_name);
- String processed_xml_string = vformat(godot_project_name_xml_string, locale_project_name.xml_escape(true));
+ String processed_xml_string = vformat(godot_project_name_xml_string, _android_xml_escape(locale_project_name));
print_verbose("Storing project name for locale " + locale + " under " + locale_directory);
store_string_at_path(locale_directory, processed_xml_string);
} else {
@@ -176,7 +191,7 @@ String bool_to_string(bool v) {
String _get_gles_tag() {
bool min_gles3 = ProjectSettings::get_singleton()->get("rendering/driver/driver_name") == "GLES3" &&
- !ProjectSettings::get_singleton()->get("rendering/driver/fallback_to_gles2");
+ !ProjectSettings::get_singleton()->get("rendering/driver/fallback_to_gles2");
return min_gles3 ? " <uses-feature android:glEsVersion=\"0x00030000\" android:required=\"true\" />\n" : "";
}
@@ -196,16 +211,24 @@ String _get_screen_sizes_tag(const Ref<EditorExportPreset> &p_preset) {
String _get_xr_features_tag(const Ref<EditorExportPreset> &p_preset) {
String manifest_xr_features;
- bool uses_xr = (int)(p_preset->get("xr_features/xr_mode")) == 1;
+ 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 == 1) {
+ 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";
- } else if (hand_tracking_index == 2) {
+ } else if (hand_tracking_index == XR_HAND_TRACKING_REQUIRED) {
manifest_xr_features += " <uses-feature tools:node=\"replace\" android:name=\"oculus.software.handtracking\" android:required=\"true\" />\n";
}
+
+ int passthrough_mode = p_preset->get("xr_features/passthrough");
+ if (passthrough_mode == XR_PASSTHROUGH_OPTIONAL) {
+ manifest_xr_features += " <uses-feature tools:node=\"replace\" android:name=\"com.oculus.feature.PASSTHROUGH\" android:required=\"false\" />\n";
+ } else if (passthrough_mode == XR_PASSTHROUGH_REQUIRED) {
+ manifest_xr_features += " <uses-feature tools:node=\"replace\" android:name=\"com.oculus.feature.PASSTHROUGH\" android:required=\"true\" />\n";
+ }
}
return manifest_xr_features;
}
@@ -224,7 +247,8 @@ String _get_instrumentation_tag(const Ref<EditorExportPreset> &p_preset) {
}
String _get_activity_tag(const Ref<EditorExportPreset> &p_preset) {
- bool uses_xr = (int)(p_preset->get("xr_features/xr_mode")) == 1;
+ int xr_mode_index = (int)(p_preset->get("xr_features/xr_mode"));
+ bool uses_xr = xr_mode_index == XR_MODE_OPENXR;
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\" "
@@ -241,6 +265,8 @@ String _get_activity_tag(const Ref<EditorExportPreset> &p_preset) {
}
String _get_application_tag(const Ref<EditorExportPreset> &p_preset, bool p_has_storage_permission) {
+ int xr_mode_index = (int)(p_preset->get("xr_features/xr_mode"));
+ bool uses_xr = xr_mode_index == XR_MODE_OPENXR;
String manifest_application_text = vformat(
" <application android:label=\"@string/godot_project_name_string\"\n"
" android:allowBackup=\"%s\"\n"
@@ -255,6 +281,9 @@ String _get_application_tag(const Ref<EditorExportPreset> &p_preset, bool p_has_
bool_to_string(p_preset->get("package/retain_data_on_uninstall")),
bool_to_string(p_has_storage_permission));
+ if (uses_xr) {
+ manifest_application_text += " <meta-data tools:node=\"replace\" android:name=\"com.samsung.android.vr.application.mode\" android:value=\"vr_only\" />\n";
+ }
manifest_application_text += _get_activity_tag(p_preset);
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 744022f1f9..db05c7534c 100644
--- a/platform/android/export/gradle_export_util.h
+++ b/platform/android/export/gradle_export_util.h
@@ -44,6 +44,21 @@ const String godot_project_name_xml_string = R"(<?xml version="1.0" encoding="ut
</resources>
)";
+// 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;
+static const int XR_MODE_OPENXR = 1;
+
+// Supported XR hand tracking modes.
+static const int XR_HAND_TRACKING_NONE = 0;
+static const int XR_HAND_TRACKING_OPTIONAL = 1;
+static const int XR_HAND_TRACKING_REQUIRED = 2;
+
+// Supported XR passthrough modes.
+static const int XR_PASSTHROUGH_NONE = 0;
+static const int XR_PASSTHROUGH_OPTIONAL = 1;
+static const int XR_PASSTHROUGH_REQUIRED = 2;
+
struct CustomExportData {
String assets_directory;
bool debug;
diff --git a/platform/android/java/app/AndroidManifest.xml b/platform/android/java/app/AndroidManifest.xml
index d7bf6cef30..9ae6367b42 100644
--- a/platform/android/java/app/AndroidManifest.xml
+++ b/platform/android/java/app/AndroidManifest.xml
@@ -33,6 +33,11 @@
<!-- 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 mode metadata. This is modified by the exporter based on the selected xr mode. DO NOT CHANGE the values here. -->
+ <meta-data
+ android:name="xr_mode_metadata_name"
+ android:value="xr_mode_metadata_value" />
+
<activity
android:name=".GodotApp"
android:label="@string/godot_project_name_string"
diff --git a/platform/android/java/app/config.gradle b/platform/android/java/app/config.gradle
index fcee54e493..2a2850df0f 100644
--- a/platform/android/java/app/config.gradle
+++ b/platform/android/java/app/config.gradle
@@ -1,12 +1,12 @@
ext.versions = [
- androidGradlePlugin: '4.2.2',
+ androidGradlePlugin: '7.0.3',
compileSdk : 30,
- minSdk : 19,
- targetSdk : 30,
+ minSdk : 19, // Also update 'platform/android/java/lib/AndroidManifest.xml#minSdkVersion' value
+ targetSdk : 30, // Also update 'platform/android/java/lib/AndroidManifest.xml#targetSdkVersion' value
buildTools : '30.0.3',
kotlinVersion : '1.5.10',
fragmentVersion : '1.3.6',
- javaVersion : 1.8,
+ javaVersion : 11,
ndkVersion : '21.4.7075529' // Also update 'platform/android/detect.py#get_project_ndk_version()' when this is updated.
]
diff --git a/platform/android/java/build.gradle b/platform/android/java/build.gradle
index 87bb2ea218..efdcc6c77b 100644
--- a/platform/android/java/build.gradle
+++ b/platform/android/java/build.gradle
@@ -158,9 +158,9 @@ def templateBuildTasks() {
/**
* Master task used to coordinate the tasks defined above to generate the set of Godot templates.
*/
-task generateGodotTemplates(type: GradleBuild) {
- startParameter.excludedTaskNames = templateExcludedBuildTask()
- tasks = templateBuildTasks()
+task generateGodotTemplates {
+ gradle.startParameter.excludedTaskNames += templateExcludedBuildTask()
+ dependsOn = templateBuildTasks()
finalizedBy 'zipCustomBuild'
}
@@ -168,12 +168,12 @@ task generateGodotTemplates(type: GradleBuild) {
/**
* Generates the same output as generateGodotTemplates but with dev symbols
*/
-task generateDevTemplate (type: GradleBuild) {
+task generateDevTemplate {
// add parameter to set symbols to true
- startParameter.projectProperties += [doNotStrip: true]
+ gradle.startParameter.projectProperties += [doNotStrip: true]
- startParameter.excludedTaskNames = templateExcludedBuildTask()
- tasks = templateBuildTasks()
+ gradle.startParameter.excludedTaskNames += templateExcludedBuildTask()
+ dependsOn = templateBuildTasks()
finalizedBy 'zipCustomBuild'
}
diff --git a/platform/android/java/gradle/wrapper/gradle-wrapper.jar b/platform/android/java/gradle/wrapper/gradle-wrapper.jar
index f6b961fd5a..e708b1c023 100644
--- a/platform/android/java/gradle/wrapper/gradle-wrapper.jar
+++ b/platform/android/java/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/platform/android/java/gradle/wrapper/gradle-wrapper.properties b/platform/android/java/gradle/wrapper/gradle-wrapper.properties
index 74c5636f8a..ffed3a254e 100644
--- a/platform/android/java/gradle/wrapper/gradle-wrapper.properties
+++ b/platform/android/java/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,5 @@
-#Wed Jun 23 23:42:22 PDT 2021
distributionBase=GRADLE_USER_HOME
-distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-all.zip
distributionPath=wrapper/dists
-zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/platform/android/java/gradlew b/platform/android/java/gradlew
index cccdd3d517..4f906e0c81 100755
--- a/platform/android/java/gradlew
+++ b/platform/android/java/gradlew
@@ -1,5 +1,21 @@
#!/usr/bin/env sh
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
##############################################################################
##
## Gradle start up script for UN*X
@@ -28,7 +44,7 @@ APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS=""
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
@@ -66,6 +82,7 @@ esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
@@ -109,10 +126,11 @@ if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
-# For Cygwin, switch paths to Windows format before running java
-if $cygwin ; then
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
@@ -138,19 +156,19 @@ if $cygwin ; then
else
eval `echo args$i`="\"$arg\""
fi
- i=$((i+1))
+ i=`expr $i + 1`
done
case $i in
- (0) set -- ;;
- (1) set -- "$args0" ;;
- (2) set -- "$args0" "$args1" ;;
- (3) set -- "$args0" "$args1" "$args2" ;;
- (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
- (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
- (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
- (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
- (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
- (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
@@ -159,14 +177,9 @@ save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
-APP_ARGS=$(save "$@")
+APP_ARGS=`save "$@"`
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
-# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
-if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
- cd "$(dirname "$0")"
-fi
-
exec "$JAVACMD" "$@"
diff --git a/platform/android/java/gradlew.bat b/platform/android/java/gradlew.bat
index 11cc30edb0..107acd32c4 100644
--- a/platform/android/java/gradlew.bat
+++ b/platform/android/java/gradlew.bat
@@ -1,7 +1,23 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
-@rem Gradle startup script for Windows
+@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@@ -13,15 +29,18 @@ if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS=
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto init
+if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@@ -35,7 +54,7 @@ goto fail
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
-if exist "%JAVA_EXE%" goto init
+if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@@ -45,28 +64,14 @@ echo location of your Java installation.
goto fail
-:init
-@rem Get command-line arguments, handling Windows variants
-
-if not "%OS%" == "Windows_NT" goto win9xME_args
-
-:win9xME_args
-@rem Slurp the command line arguments.
-set CMD_LINE_ARGS=
-set _SKIP=2
-
-:win9xME_args_slurp
-if "x%~1" == "x" goto execute
-
-set CMD_LINE_ARGS=%*
-
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
@rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
@@ -75,7 +80,7 @@ if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
-if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
diff --git a/platform/android/java/lib/AndroidManifest.xml b/platform/android/java/lib/AndroidManifest.xml
index 3034794d69..2de62271c4 100644
--- a/platform/android/java/lib/AndroidManifest.xml
+++ b/platform/android/java/lib/AndroidManifest.xml
@@ -4,6 +4,9 @@
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="30" />
+
<application>
<!-- Records the version of the Godot library -->
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 70bc73b9ad..17ff3c75c0 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/Godot.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.java
@@ -119,7 +119,6 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
private Button mWiFiSettingsButton;
private XRMode xrMode = XRMode.REGULAR;
- private boolean use_32_bits = false;
private boolean use_immersive = false;
private boolean use_debug_opengl = false;
private boolean mStatePaused;
@@ -263,11 +262,10 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
GodotLib.setup(command_line);
final String videoDriver = GodotLib.getGlobal("rendering/driver/driver_name");
- if (videoDriver.equals("Vulkan")) {
+ if (videoDriver.equals("vulkan")) {
mRenderView = new GodotVulkanRenderView(activity, this);
} else {
- mRenderView = new GodotGLRenderView(activity, this, xrMode, use_32_bits,
- use_debug_opengl);
+ mRenderView = new GodotGLRenderView(activity, this, xrMode, use_debug_opengl);
}
View view = mRenderView.getView();
@@ -504,10 +502,8 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
boolean has_extra = i < command_line.length - 1;
if (command_line[i].equals(XRMode.REGULAR.cmdLineArg)) {
xrMode = XRMode.REGULAR;
- } else if (command_line[i].equals(XRMode.OVR.cmdLineArg)) {
- xrMode = XRMode.OVR;
- } else if (command_line[i].equals("--use_depth_32")) {
- use_32_bits = true;
+ } else if (command_line[i].equals(XRMode.OPENXR.cmdLineArg)) {
+ xrMode = XRMode.OPENXR;
} else if (command_line[i].equals("--debug_opengl")) {
use_debug_opengl = true;
} else if (command_line[i].equals("--use_immersive")) {
@@ -578,8 +574,7 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
if (!pack_valid) {
Intent notifierIntent = new Intent(activity, activity.getClass());
- notifierIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
- Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ notifierIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(activity, 0,
notifierIntent, PendingIntent.FLAG_UPDATE_CURRENT);
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 d33faab641..09337ef989 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderService.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderService.java
@@ -50,9 +50,9 @@ public class GodotDownloaderService extends DownloaderService {
};
/**
- * This public key comes from your Android Market publisher account, and it
- * used by the LVL to validate responses from Market on your behalf.
- */
+ * This public key comes from your Android Market publisher account, and it
+ * used by the LVL to validate responses from Market on your behalf.
+ */
@Override
public String getPublicKey() {
SharedPreferences prefs = getApplicationContext().getSharedPreferences("app_data_keys", Context.MODE_PRIVATE);
@@ -63,20 +63,20 @@ public class GodotDownloaderService extends DownloaderService {
}
/**
- * This is used by the preference obfuscater to make sure that your
- * obfuscated preferences are different than the ones used by other
- * applications.
- */
+ * This is used by the preference obfuscater to make sure that your
+ * obfuscated preferences are different than the ones used by other
+ * applications.
+ */
@Override
public byte[] getSALT() {
return SALT;
}
/**
- * Fill this in with the class name for your alarm receiver. We do this
- * because receivers must be unique across all of Android (it's a good idea
- * to make sure that your receiver is in your unique package)
- */
+ * Fill this in with the class name for your alarm receiver. We do this
+ * because receivers must be unique across all of Android (it's a good idea
+ * to make sure that your receiver is in your unique package)
+ */
@Override
public String getAlarmReceiverClassName() {
Log.d("GODOT", "getAlarmReceiverClassName()");
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 a9d45c943b..d5b0b67903 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java
@@ -78,10 +78,8 @@ public class GodotGLRenderView extends GLSurfaceView implements GodotRenderView
private final GodotRenderer godotRenderer;
private PointerIcon pointerIcon;
- public GodotGLRenderView(Context context, Godot godot, XRMode xrMode, boolean p_use_32_bits,
- boolean p_use_debug_opengl) {
+ public GodotGLRenderView(Context context, Godot godot, XRMode xrMode, boolean p_use_debug_opengl) {
super(context);
- GLUtils.use_32 = p_use_32_bits;
GLUtils.use_debug_opengl = p_use_debug_opengl;
this.godot = godot;
@@ -91,7 +89,7 @@ public class GodotGLRenderView extends GLSurfaceView implements GodotRenderView
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
pointerIcon = PointerIcon.getSystemIcon(getContext(), PointerIcon.TYPE_DEFAULT);
}
- init(xrMode, false, 16, 0);
+ init(xrMode, false);
}
@Override
@@ -172,11 +170,11 @@ public class GodotGLRenderView extends GLSurfaceView implements GodotRenderView
return pointerIcon;
}
- private void init(XRMode xrMode, boolean translucent, int depth, int stencil) {
+ private void init(XRMode xrMode, boolean translucent) {
setPreserveEGLContextOnPause(true);
setFocusableInTouchMode(true);
switch (xrMode) {
- case OVR:
+ case OPENXR:
// Replace the default egl config chooser.
setEGLConfigChooser(new OvrConfigChooser());
@@ -209,18 +207,9 @@ public class GodotGLRenderView extends GLSurfaceView implements GodotRenderView
* below.
*/
- if (GLUtils.use_32) {
- setEGLConfigChooser(translucent ?
- new RegularFallbackConfigChooser(8, 8, 8, 8, 24, stencil,
- new RegularConfigChooser(8, 8, 8, 8, 16, stencil)) :
- new RegularFallbackConfigChooser(8, 8, 8, 8, 24, stencil,
- new RegularConfigChooser(5, 6, 5, 0, 16, stencil)));
-
- } else {
- setEGLConfigChooser(translucent ?
- new RegularConfigChooser(8, 8, 8, 8, 16, stencil) :
- new RegularConfigChooser(5, 6, 5, 0, 16, stencil));
- }
+ setEGLConfigChooser(
+ new RegularFallbackConfigChooser(8, 8, 8, 8, 24, 0,
+ new RegularConfigChooser(8, 8, 8, 8, 16, 0)));
break;
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java
index d85d88ec6c..5f354b6b4c 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java
@@ -288,7 +288,34 @@ public class GodotIO {
}
public int getScreenOrientation() {
- return activity.getRequestedOrientation();
+ int orientation = activity.getRequestedOrientation();
+ switch (orientation) {
+ case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
+ return SCREEN_LANDSCAPE;
+ case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:
+ return SCREEN_PORTRAIT;
+ case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE:
+ return SCREEN_REVERSE_LANDSCAPE;
+ case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT:
+ return SCREEN_REVERSE_PORTRAIT;
+ case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE:
+ case ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE:
+ return SCREEN_SENSOR_LANDSCAPE;
+ case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT:
+ case ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT:
+ return SCREEN_SENSOR_PORTRAIT;
+ case ActivityInfo.SCREEN_ORIENTATION_SENSOR:
+ case ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR:
+ case ActivityInfo.SCREEN_ORIENTATION_FULL_USER:
+ return SCREEN_SENSOR;
+ case ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED:
+ case ActivityInfo.SCREEN_ORIENTATION_USER:
+ case ActivityInfo.SCREEN_ORIENTATION_BEHIND:
+ case ActivityInfo.SCREEN_ORIENTATION_NOSENSOR:
+ case ActivityInfo.SCREEN_ORIENTATION_LOCKED:
+ default:
+ return -1;
+ }
}
public void setEdit(GodotEditText _edit) {
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 95870acda1..a23d030d4c 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java
@@ -75,9 +75,8 @@ public class GodotLib {
/**
* Invoked on the render thread when the underlying Android surface is created or recreated.
* @param p_surface
- * @param p_32_bits
*/
- public static native void newcontext(Surface p_surface, boolean p_32_bits);
+ public static native void newcontext(Surface p_surface);
/**
* Forward {@link Activity#onBackPressed()} event from the main thread to the GL thread.
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java b/platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java
index 878a119c5c..12e452fc99 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java
@@ -70,7 +70,7 @@ class GodotRenderer implements GLSurfaceView.Renderer {
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
- GodotLib.newcontext(null, GLUtils.use_32);
+ GodotLib.newcontext(null);
for (GodotPlugin plugin : pluginRegistry.getAllPlugins()) {
plugin.onGLSurfaceCreated(gl, config);
}
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 d1e8ae5ca9..a98ecad594 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
@@ -191,9 +191,9 @@ public class GodotEditText extends EditText {
private boolean needHandlingInGodot(int keyCode, KeyEvent keyEvent) {
boolean isArrowKey = keyCode == KeyEvent.KEYCODE_DPAD_UP || keyCode == KeyEvent.KEYCODE_DPAD_DOWN ||
- keyCode == KeyEvent.KEYCODE_DPAD_LEFT || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT;
+ keyCode == KeyEvent.KEYCODE_DPAD_LEFT || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT;
boolean isModifiedKey = keyEvent.isAltPressed() || keyEvent.isCtrlPressed() || keyEvent.isSymPressed() ||
- keyEvent.isFunctionPressed() || keyEvent.isMetaPressed();
+ keyEvent.isFunctionPressed() || keyEvent.isMetaPressed();
return isArrowKey || keyCode == KeyEvent.KEYCODE_TAB || KeyEvent.isModifierKey(keyCode) ||
isModifiedKey;
}
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 19588f8465..09820fad5f 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
@@ -44,7 +44,6 @@ public class GLUtils {
public static final boolean DEBUG = false;
- public static boolean use_32 = false;
public static boolean use_debug_opengl = false;
private static final String[] ATTRIBUTES_NAMES = new String[] {
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 a35f6ec5a7..b13f9bfeab 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
@@ -58,7 +58,7 @@ internal class VkRenderer {
* Called when the surface is created and signals the beginning of rendering.
*/
fun onVkSurfaceCreated(surface: Surface) {
- GodotLib.newcontext(surface, false)
+ GodotLib.newcontext(surface)
for (plugin in pluginRegistry.getAllPlugins()) {
plugin.onVkSurfaceCreated(surface)
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 0995477baf..58f02b0396 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
@@ -35,7 +35,7 @@ package org.godotengine.godot.xr;
*/
public enum XRMode {
REGULAR(0, "Regular", "--xr_mode_regular", "Default Android Gamepad"), // Regular/flatscreen
- OVR(1, "Oculus Mobile VR", "--xr_mode_ovr", "");
+ OPENXR(1, "OpenXR", "--xr_mode_openxr", "");
final int index;
final String label;
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 e690c5b695..63c5381994 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
@@ -38,7 +38,7 @@ import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLDisplay;
-/* Fallback if 32bit View is not supported*/
+/* Fallback if the requested configuration is not supported */
public class RegularFallbackConfigChooser extends RegularConfigChooser {
private static final String TAG = RegularFallbackConfigChooser.class.getSimpleName();
@@ -55,7 +55,6 @@ public class RegularFallbackConfigChooser extends RegularConfigChooser {
if (ec == null) {
Log.w(TAG, "Trying ConfigChooser fallback");
ec = fallback.chooseConfig(egl, display, configs);
- GLUtils.use_32 = false;
}
return ec;
}
diff --git a/platform/android/java_godot_lib_jni.cpp b/platform/android/java_godot_lib_jni.cpp
index d971727269..3236512f5c 100644
--- a/platform/android/java_godot_lib_jni.cpp
+++ b/platform/android/java_godot_lib_jni.cpp
@@ -182,11 +182,10 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, j
}
}
-JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jclass clazz, jobject p_surface, jboolean p_32_bits) {
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jclass clazz, jobject p_surface) {
if (os_android) {
if (step.get() == 0) {
// During startup
- os_android->set_context_is_16_bits(!p_32_bits);
if (p_surface) {
ANativeWindow *native_window = ANativeWindow_fromSurface(env, p_surface);
os_android->set_native_window(native_window);
@@ -318,8 +317,9 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joybutton(JNIEnv *env
// Called on the UI thread
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyaxis(JNIEnv *env, jclass clazz, jint p_device, jint p_axis, jfloat p_value) {
- if (step.get() <= 0)
+ if (step.get() <= 0) {
return;
+ }
AndroidInputHandler::JoypadEvent jevent;
jevent.device = p_device;
@@ -332,24 +332,27 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyaxis(JNIEnv *env,
// Called on the UI thread
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyhat(JNIEnv *env, jclass clazz, jint p_device, jint p_hat_x, jint p_hat_y) {
- if (step.get() <= 0)
+ if (step.get() <= 0) {
return;
+ }
AndroidInputHandler::JoypadEvent jevent;
jevent.device = p_device;
jevent.type = AndroidInputHandler::JOY_EVENT_HAT;
- int hat = 0;
+ HatMask hat = HatMask::CENTER;
if (p_hat_x != 0) {
- if (p_hat_x < 0)
- hat |= HatMask::HAT_MASK_LEFT;
- else
- hat |= HatMask::HAT_MASK_RIGHT;
+ if (p_hat_x < 0) {
+ hat |= HatMask::LEFT;
+ } else {
+ hat |= HatMask::RIGHT;
+ }
}
if (p_hat_y != 0) {
- if (p_hat_y < 0)
- hat |= HatMask::HAT_MASK_UP;
- else
- hat |= HatMask::HAT_MASK_DOWN;
+ if (p_hat_y < 0) {
+ hat |= HatMask::UP;
+ } else {
+ hat |= HatMask::DOWN;
+ }
}
jevent.hat = hat;
diff --git a/platform/android/java_godot_lib_jni.h b/platform/android/java_godot_lib_jni.h
index 63e9e6d8e5..7ea74480cb 100644
--- a/platform/android/java_godot_lib_jni.h
+++ b/platform/android/java_godot_lib_jni.h
@@ -41,7 +41,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *en
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ondestroy(JNIEnv *env, jclass clazz);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jclass clazz, jobjectArray p_cmdline);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, jclass clazz, jobject p_surface, jint p_width, jint p_height);
-JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jclass clazz, jobject p_surface, jboolean p_32_bits);
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jclass clazz, jobject p_surface);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, jclass clazz);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_back(JNIEnv *env, jclass clazz);
void touch_preprocessing(JNIEnv *env, jclass clazz, jint input_device, jint ev, jint pointer, jint pointer_count, jfloatArray positions, jint buttons_mask = 0, jfloat vertical_factor = 0, jfloat horizontal_factor = 0);
diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp
index 034885aa32..0e5e10bc0a 100644
--- a/platform/android/os_android.cpp
+++ b/platform/android/os_android.cpp
@@ -261,16 +261,8 @@ Size2i OS_Android::get_display_size() const {
return display_size;
}
-void OS_Android::set_context_is_16_bits(bool p_is_16) {
-#if defined(OPENGL_ENABLED)
- //use_16bits_fbo = p_is_16;
- //if (rasterizer)
- // rasterizer->set_force_16_bits_fbo(p_is_16);
-#endif
-}
-
void OS_Android::set_opengl_extensions(const char *p_gl_extensions) {
-#if defined(OPENGL_ENABLED)
+#if defined(GLES3_ENABLED)
ERR_FAIL_COND(!p_gl_extensions);
gl_extensions = p_gl_extensions;
#endif
@@ -322,10 +314,9 @@ OS_Android::OS_Android(GodotJavaWrapper *p_godot_java, GodotIOJavaWrapper *p_god
main_loop = nullptr;
-#if defined(OPENGL_ENABLED)
+#if defined(GLES3_ENABLED)
gl_extensions = nullptr;
use_gl2 = false;
- use_16bits_fbo = false;
#endif
#if defined(VULKAN_ENABLED)
diff --git a/platform/android/os_android.h b/platform/android/os_android.h
index ce8083388f..a62f79952c 100644
--- a/platform/android/os_android.h
+++ b/platform/android/os_android.h
@@ -47,8 +47,7 @@ private:
bool use_apk_expansion;
-#if defined(OPENGL_ENABLED)
- bool use_16bits_fbo;
+#if defined(GLES3_ENABLED)
const char *gl_extensions;
#endif
@@ -103,7 +102,6 @@ public:
void set_display_size(const Size2i &p_size);
Size2i get_display_size() const;
- void set_context_is_16_bits(bool p_is_16);
void set_opengl_extensions(const char *p_gl_extensions);
void set_native_window(ANativeWindow *p_native_window);
diff --git a/platform/iphone/app_delegate.h b/platform/iphone/app_delegate.h
index d6a2292dd2..76c28b2272 100644
--- a/platform/iphone/app_delegate.h
+++ b/platform/iphone/app_delegate.h
@@ -32,9 +32,9 @@
@class ViewController;
-// FIXME: Add support for both GLES2 and Vulkan when GLES2 is implemented again,
+// FIXME: Add support for both OpenGL and Vulkan when OpenGL is implemented again,
// so it can't be done with compilation time branching.
-//#if defined(OPENGL_ENABLED)
+//#if defined(GLES3_ENABLED)
//@interface AppDelegate : NSObject <UIApplicationDelegate, GLViewDelegate> {
//#endif
//#if defined(VULKAN_ENABLED)
diff --git a/platform/iphone/detect.py b/platform/iphone/detect.py
index 05e24c5003..0d28aa2f06 100644
--- a/platform/iphone/detect.py
+++ b/platform/iphone/detect.py
@@ -53,12 +53,9 @@ def configure(env):
env.Append(CCFLAGS=["-Os", "-ftree-vectorize"])
env.Append(LINKFLAGS=["-Os"])
- if env["target"] == "release_debug":
- env.Append(CPPDEFINES=["DEBUG_ENABLED"])
-
elif env["target"] == "debug":
env.Append(CCFLAGS=["-gdwarf-2", "-O0"])
- env.Append(CPPDEFINES=["_DEBUG", ("DEBUG", 1), "DEBUG_ENABLED"])
+ env.Append(CPPDEFINES=["_DEBUG", ("DEBUG", 1)])
if env["use_lto"]:
env.Append(CCFLAGS=["-flto"])
diff --git a/platform/iphone/display_layer.mm b/platform/iphone/display_layer.mm
index b8df81b89a..afe612e1a5 100644
--- a/platform/iphone/display_layer.mm
+++ b/platform/iphone/display_layer.mm
@@ -89,7 +89,7 @@
// FIXME: Add Vulkan support via MoltenVK. Add fallback code back?
// Create GL ES 2 context
- if (GLOBAL_GET("rendering/driver/driver_name") == "GLES2") {
+ if (GLOBAL_GET("rendering/driver/driver_name") == "opengl3") {
context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
NSLog(@"Setting up an OpenGL ES 2.0 context.");
if (!context) {
diff --git a/platform/iphone/display_server_iphone.mm b/platform/iphone/display_server_iphone.mm
index e18448fb6d..b746c60d4e 100644
--- a/platform/iphone/display_server_iphone.mm
+++ b/platform/iphone/display_server_iphone.mm
@@ -51,8 +51,8 @@ DisplayServerIPhone *DisplayServerIPhone::get_singleton() {
DisplayServerIPhone::DisplayServerIPhone(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
rendering_driver = p_rendering_driver;
-#if defined(OPENGL_ENABLED)
- // FIXME: Add support for both GLES2 and Vulkan when GLES2 is implemented
+#if defined(GLES3_ENABLED)
+ // FIXME: Add support for both OpenGL and Vulkan when OpenGL is implemented
// again,
if (rendering_driver == "opengl_es") {
@@ -60,9 +60,9 @@ DisplayServerIPhone::DisplayServerIPhone(const String &p_rendering_driver, Windo
// FIXME: Add Vulkan support via MoltenVK. Add fallback code back?
- if (RasterizerGLES2::is_viable() == OK) {
- RasterizerGLES2::register_config();
- RasterizerGLES2::make_current();
+ if (RasterizerGLES3::is_viable() == OK) {
+ RasterizerGLES3::register_config();
+ RasterizerGLES3::make_current();
} else {
gl_initialization_error = true;
}
@@ -83,7 +83,7 @@ DisplayServerIPhone::DisplayServerIPhone(const String &p_rendering_driver, Windo
// reset this to what it should be, it will have been set to 0 after
// rendering_server->init() is called
- // RasterizerStorageGLES2::system_fbo = gl_view_base_fb;
+ // RasterizerStorageGLES3system_fbo = gl_view_base_fb;
}
#endif
@@ -157,7 +157,7 @@ Vector<String> DisplayServerIPhone::get_rendering_drivers_func() {
#if defined(VULKAN_ENABLED)
drivers.push_back("vulkan");
#endif
-#if defined(OPENGL_ENABLED)
+#if defined(GLES3_ENABLED)
drivers.push_back("opengl_es");
#endif
@@ -261,7 +261,7 @@ void DisplayServerIPhone::key(Key p_key, bool p_pressed) {
ev->set_pressed(p_pressed);
ev->set_keycode(p_key);
ev->set_physical_keycode(p_key);
- ev->set_unicode(p_key);
+ ev->set_unicode((char32_t)p_key);
perform_event(ev);
};
diff --git a/platform/iphone/export/export_plugin.cpp b/platform/iphone/export/export_plugin.cpp
index 69a8203e9f..0abd255c7c 100644
--- a/platform/iphone/export/export_plugin.cpp
+++ b/platform/iphone/export/export_plugin.cpp
@@ -33,7 +33,7 @@
void EditorExportPlatformIOS::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) {
String driver = ProjectSettings::get_singleton()->get("rendering/driver/driver_name");
r_features->push_back("pvrtc");
- if (driver == "Vulkan") {
+ if (driver == "vulkan") {
// FIXME: Review if this is correct.
r_features->push_back("etc2");
}
@@ -728,10 +728,10 @@ Error EditorExportPlatformIOS::_export_loading_screen_images(const Ref<EditorExp
Error EditorExportPlatformIOS::_walk_dir_recursive(DirAccess *p_da, FileHandler p_handler, void *p_userdata) {
Vector<String> dirs;
- String path;
String current_dir = p_da->get_current_dir();
p_da->list_dir_begin();
- while ((path = p_da->get_next()).length() != 0) {
+ String path = p_da->get_next();
+ while (!path.is_empty()) {
if (p_da->current_is_dir()) {
if (path != "." && path != "..") {
dirs.push_back(path);
@@ -743,6 +743,7 @@ Error EditorExportPlatformIOS::_walk_dir_recursive(DirAccess *p_da, FileHandler
return err;
}
}
+ path = p_da->get_next();
}
p_da->list_dir_end();
@@ -841,7 +842,7 @@ void EditorExportPlatformIOS::_add_assets_to_project(const Ref<EditorExportPrese
String pbx_embeded_frameworks;
const String file_info_format = String("$build_id = {isa = PBXBuildFile; fileRef = $ref_id; };\n") +
- "$ref_id = {isa = PBXFileReference; lastKnownFileType = $file_type; name = \"$name\"; path = \"$file_path\"; sourceTree = \"<group>\"; };\n";
+ "$ref_id = {isa = PBXFileReference; lastKnownFileType = $file_type; name = \"$name\"; path = \"$file_path\"; sourceTree = \"<group>\"; };\n";
for (int i = 0; i < p_additional_assets.size(); ++i) {
String additional_asset_info_format = file_info_format;
@@ -1105,7 +1106,7 @@ Error EditorExportPlatformIOS::_export_additional_assets(const String &p_out_dir
for (int j = 0; j < project_static_libs.size(); j++) {
project_static_libs.write[j] = project_static_libs[j].get_file(); // Only the file name as it's copied to the project
}
- err = _export_additional_assets(p_out_dir, project_static_libs, true, true, r_exported_assets);
+ err = _export_additional_assets(p_out_dir, project_static_libs, true, false, r_exported_assets);
ERR_FAIL_COND_V(err, err);
Vector<String> ios_bundle_files = export_plugins[i]->get_ios_bundle_files();
@@ -1261,8 +1262,8 @@ Error EditorExportPlatformIOS::_export_ios_plugins(const Ref<EditorExportPreset>
String deinitialization_method = plugin.deinitialization_method + "();\n";
plugin_definition_cpp_code += definition_comment +
- "extern void " + initialization_method +
- "extern void " + deinitialization_method + "\n";
+ "extern void " + initialization_method +
+ "extern void " + deinitialization_method + "\n";
plugin_initialization_cpp_code += "\t" + initialization_method;
plugin_deinitialization_cpp_code += "\t" + deinitialization_method;
@@ -1427,7 +1428,6 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
}
bool found_library = false;
- int total_size = 0;
const String project_file = "godot_ios.xcodeproj/project.pbxproj";
Set<String> files_to_parse;
@@ -1523,7 +1523,6 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
file = file.replace("godot_ios", binary_name);
print_line("ADDING: " + file + " size: " + itos(data.size()));
- total_size += data.size();
/* write it into our folder structure */
file = dest_dir + file;
@@ -1687,8 +1686,10 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
archive_args.push_back("archive");
archive_args.push_back("-archivePath");
archive_args.push_back(archive_path);
- err = OS::get_singleton()->execute("xcodebuild", archive_args);
+ String archive_str;
+ 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 (ep.step("Making .ipa", 4)) {
return ERR_SKIP;
@@ -1702,8 +1703,10 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
export_args.push_back("-allowProvisioningUpdates");
export_args.push_back("-exportPath");
export_args.push_back(dest_dir);
- err = OS::get_singleton()->execute("xcodebuild", export_args);
+ 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);
#else
print_line(".ipa can only be built on macOS. Leaving Xcode project without building the package.");
#endif
diff --git a/platform/iphone/joypad_iphone.mm b/platform/iphone/joypad_iphone.mm
index 45842b38aa..1bf5462d91 100644
--- a/platform/iphone/joypad_iphone.mm
+++ b/platform/iphone/joypad_iphone.mm
@@ -259,31 +259,31 @@ void JoypadIPhone::start_processing() {
int joy_id = [self getJoyIdForController:controller];
if (element == gamepad.buttonA) {
- Input::get_singleton()->joy_button(joy_id, JOY_BUTTON_A,
+ Input::get_singleton()->joy_button(joy_id, JoyButton::A,
gamepad.buttonA.isPressed);
} else if (element == gamepad.buttonB) {
- Input::get_singleton()->joy_button(joy_id, JOY_BUTTON_B,
+ Input::get_singleton()->joy_button(joy_id, JoyButton::B,
gamepad.buttonB.isPressed);
} else if (element == gamepad.buttonX) {
- Input::get_singleton()->joy_button(joy_id, JOY_BUTTON_X,
+ Input::get_singleton()->joy_button(joy_id, JoyButton::X,
gamepad.buttonX.isPressed);
} else if (element == gamepad.buttonY) {
- Input::get_singleton()->joy_button(joy_id, JOY_BUTTON_Y,
+ Input::get_singleton()->joy_button(joy_id, JoyButton::Y,
gamepad.buttonY.isPressed);
} else if (element == gamepad.leftShoulder) {
- Input::get_singleton()->joy_button(joy_id, JOY_BUTTON_LEFT_SHOULDER,
+ Input::get_singleton()->joy_button(joy_id, JoyButton::LEFT_SHOULDER,
gamepad.leftShoulder.isPressed);
} else if (element == gamepad.rightShoulder) {
- Input::get_singleton()->joy_button(joy_id, JOY_BUTTON_RIGHT_SHOULDER,
+ Input::get_singleton()->joy_button(joy_id, JoyButton::RIGHT_SHOULDER,
gamepad.rightShoulder.isPressed);
} else if (element == gamepad.dpad) {
- Input::get_singleton()->joy_button(joy_id, JOY_BUTTON_DPAD_UP,
+ Input::get_singleton()->joy_button(joy_id, JoyButton::DPAD_UP,
gamepad.dpad.up.isPressed);
- Input::get_singleton()->joy_button(joy_id, JOY_BUTTON_DPAD_DOWN,
+ Input::get_singleton()->joy_button(joy_id, JoyButton::DPAD_DOWN,
gamepad.dpad.down.isPressed);
- Input::get_singleton()->joy_button(joy_id, JOY_BUTTON_DPAD_LEFT,
+ Input::get_singleton()->joy_button(joy_id, JoyButton::DPAD_LEFT,
gamepad.dpad.left.isPressed);
- Input::get_singleton()->joy_button(joy_id, JOY_BUTTON_DPAD_RIGHT,
+ Input::get_singleton()->joy_button(joy_id, JoyButton::DPAD_RIGHT,
gamepad.dpad.right.isPressed);
};
@@ -291,20 +291,20 @@ void JoypadIPhone::start_processing() {
jx.min = -1;
if (element == gamepad.leftThumbstick) {
jx.value = gamepad.leftThumbstick.xAxis.value;
- Input::get_singleton()->joy_axis(joy_id, JOY_AXIS_LEFT_X, jx);
+ Input::get_singleton()->joy_axis(joy_id, JoyAxis::LEFT_X, jx);
jx.value = -gamepad.leftThumbstick.yAxis.value;
- Input::get_singleton()->joy_axis(joy_id, JOY_AXIS_LEFT_Y, jx);
+ Input::get_singleton()->joy_axis(joy_id, JoyAxis::LEFT_Y, jx);
} else if (element == gamepad.rightThumbstick) {
jx.value = gamepad.rightThumbstick.xAxis.value;
- Input::get_singleton()->joy_axis(joy_id, JOY_AXIS_RIGHT_X, jx);
+ Input::get_singleton()->joy_axis(joy_id, JoyAxis::RIGHT_X, jx);
jx.value = -gamepad.rightThumbstick.yAxis.value;
- Input::get_singleton()->joy_axis(joy_id, JOY_AXIS_RIGHT_Y, jx);
+ Input::get_singleton()->joy_axis(joy_id, JoyAxis::RIGHT_Y, jx);
} else if (element == gamepad.leftTrigger) {
jx.value = gamepad.leftTrigger.value;
- Input::get_singleton()->joy_axis(joy_id, JOY_AXIS_TRIGGER_LEFT, jx);
+ Input::get_singleton()->joy_axis(joy_id, JoyAxis::TRIGGER_LEFT, jx);
} else if (element == gamepad.rightTrigger) {
jx.value = gamepad.rightTrigger.value;
- Input::get_singleton()->joy_axis(joy_id, JOY_AXIS_TRIGGER_RIGHT, jx);
+ Input::get_singleton()->joy_axis(joy_id, JoyAxis::TRIGGER_RIGHT, jx);
};
};
} else if (controller.microGamepad != nil) {
@@ -319,18 +319,18 @@ void JoypadIPhone::start_processing() {
int joy_id = [self getJoyIdForController:controller];
if (element == gamepad.buttonA) {
- Input::get_singleton()->joy_button(joy_id, JOY_BUTTON_A,
+ Input::get_singleton()->joy_button(joy_id, JoyButton::A,
gamepad.buttonA.isPressed);
} else if (element == gamepad.buttonX) {
- Input::get_singleton()->joy_button(joy_id, JOY_BUTTON_X,
+ Input::get_singleton()->joy_button(joy_id, JoyButton::X,
gamepad.buttonX.isPressed);
} else if (element == gamepad.dpad) {
- Input::get_singleton()->joy_button(joy_id, JOY_BUTTON_DPAD_UP,
+ Input::get_singleton()->joy_button(joy_id, JoyButton::DPAD_UP,
gamepad.dpad.up.isPressed);
- Input::get_singleton()->joy_button(joy_id, JOY_BUTTON_DPAD_DOWN,
+ Input::get_singleton()->joy_button(joy_id, JoyButton::DPAD_DOWN,
gamepad.dpad.down.isPressed);
- Input::get_singleton()->joy_button(joy_id, JOY_BUTTON_DPAD_LEFT, gamepad.dpad.left.isPressed);
- Input::get_singleton()->joy_button(joy_id, JOY_BUTTON_DPAD_RIGHT, gamepad.dpad.right.isPressed);
+ Input::get_singleton()->joy_button(joy_id, JoyButton::DPAD_LEFT, gamepad.dpad.left.isPressed);
+ Input::get_singleton()->joy_button(joy_id, JoyButton::DPAD_RIGHT, gamepad.dpad.right.isPressed);
};
};
}
diff --git a/platform/iphone/keyboard_input_view.mm b/platform/iphone/keyboard_input_view.mm
index e2bd0acff4..b11d04181e 100644
--- a/platform/iphone/keyboard_input_view.mm
+++ b/platform/iphone/keyboard_input_view.mm
@@ -115,8 +115,8 @@
- (void)deleteText:(NSInteger)charactersToDelete {
for (int i = 0; i < charactersToDelete; i++) {
- DisplayServerIPhone::get_singleton()->key(KEY_BACKSPACE, true);
- DisplayServerIPhone::get_singleton()->key(KEY_BACKSPACE, false);
+ DisplayServerIPhone::get_singleton()->key(Key::BACKSPACE, true);
+ DisplayServerIPhone::get_singleton()->key(Key::BACKSPACE, false);
}
}
@@ -129,10 +129,10 @@
switch (character) {
case 10:
- character = KEY_ENTER;
+ character = (int)Key::ENTER;
break;
case 8198:
- character = KEY_SPACE;
+ character = (int)Key::SPACE;
break;
default:
break;
diff --git a/platform/iphone/platform_config.h b/platform/iphone/platform_config.h
index 88ad4a3f67..68ef4e31a7 100644
--- a/platform/iphone/platform_config.h
+++ b/platform/iphone/platform_config.h
@@ -30,6 +30,8 @@
#include <alloca.h>
+#define OPENGL_INCLUDE_H <ES3/gl.h>
+
#define PLATFORM_REFCOUNT
#define PTHREAD_RENAME_SELF
diff --git a/platform/javascript/SCsub b/platform/javascript/SCsub
index fa9e6eed15..8d9ba82fd4 100644
--- a/platform/javascript/SCsub
+++ b/platform/javascript/SCsub
@@ -28,11 +28,11 @@ 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])
+ sys_env.Append(LINKFLAGS=["--js-library", lib.abspath])
for js in env["JS_PRE"]:
- sys_env.Append(LINKFLAGS=["--pre-js", env.File(js).path])
+ sys_env.Append(LINKFLAGS=["--pre-js", js.abspath])
for ext in env["JS_EXTERNS"]:
- sys_env["ENV"]["EMCC_CLOSURE_ARGS"] += " --externs " + ext.path
+ sys_env["ENV"]["EMCC_CLOSURE_ARGS"] += " --externs " + ext.abspath
build = []
if env["gdnative_enabled"]:
diff --git a/platform/javascript/detect.py b/platform/javascript/detect.py
index 173b558b6d..b57f3b3f16 100644
--- a/platform/javascript/detect.py
+++ b/platform/javascript/detect.py
@@ -77,11 +77,9 @@ def configure(env):
env.Append(LINKFLAGS=["-Os"])
if env["target"] == "release_debug":
- env.Append(CPPDEFINES=["DEBUG_ENABLED"])
# Retain function names for backtraces at the cost of file size.
env.Append(LINKFLAGS=["--profiling-funcs"])
else: # "debug"
- env.Append(CPPDEFINES=["DEBUG_ENABLED"])
env.Append(CCFLAGS=["-O1", "-g"])
env.Append(LINKFLAGS=["-O1", "-g"])
env["use_assertions"] = True
@@ -182,6 +180,13 @@ def configure(env):
env.Prepend(CPPPATH=["#platform/javascript"])
env.Append(CPPDEFINES=["JAVASCRIPT_ENABLED", "UNIX_ENABLED"])
+ if env["opengl3"]:
+ env.AppendUnique(CPPDEFINES=["GLES3_ENABLED"])
+ # This setting just makes WebGL 2 APIs available, it does NOT disable WebGL 1.
+ env.Append(LINKFLAGS=["-s", "USE_WEBGL2=1"])
+ # Allow use to take control of swapping WebGL buffers.
+ env.Append(LINKFLAGS=["-s", "OFFSCREEN_FRAMEBUFFER=1"])
+
if env["javascript_eval"]:
env.Append(CPPDEFINES=["JAVASCRIPT_EVAL_ENABLED"])
@@ -220,25 +225,11 @@ def configure(env):
# us since we don't know requirements at compile-time.
env.Append(LINKFLAGS=["-s", "ALLOW_MEMORY_GROWTH=1"])
- # This setting just makes WebGL 2 APIs available, it does NOT disable WebGL 1.
- env.Append(LINKFLAGS=["-s", "USE_WEBGL2=1"])
-
# Do not call main immediately when the support code is ready.
env.Append(LINKFLAGS=["-s", "INVOKE_RUN=0"])
- # Allow use to take control of swapping WebGL buffers.
- env.Append(LINKFLAGS=["-s", "OFFSCREEN_FRAMEBUFFER=1"])
-
# callMain for manual start, cwrap for the mono version.
env.Append(LINKFLAGS=["-s", "EXPORTED_RUNTIME_METHODS=['callMain','cwrap']"])
# Add code that allow exiting runtime.
env.Append(LINKFLAGS=["-s", "EXIT_RUNTIME=1"])
-
- # TODO remove once we have GLES support back (temporary fix undefined symbols due to dead code elimination).
- env.Append(
- LINKFLAGS=[
- "-s",
- "EXPORTED_FUNCTIONS=['_main', '_emscripten_webgl_get_current_context']",
- ]
- )
diff --git a/platform/javascript/display_server_javascript.cpp b/platform/javascript/display_server_javascript.cpp
index c2eb826db9..7648ddaf43 100644
--- a/platform/javascript/display_server_javascript.cpp
+++ b/platform/javascript/display_server_javascript.cpp
@@ -30,6 +30,9 @@
#include "platform/javascript/display_server_javascript.h"
+#ifdef GLES3_ENABLED
+#include "drivers/gles3/rasterizer_gles3.h"
+#endif
#include "platform/javascript/os_javascript.h"
#include "servers/rendering/rasterizer_dummy.h"
@@ -50,14 +53,6 @@ DisplayServerJavaScript *DisplayServerJavaScript::get_singleton() {
}
// Window (canvas)
-void DisplayServerJavaScript::focus_canvas() {
- godot_js_display_canvas_focus();
-}
-
-bool DisplayServerJavaScript::is_canvas_focused() {
- return godot_js_display_canvas_is_focused() != 0;
-}
-
bool DisplayServerJavaScript::check_size_force_redraw() {
return godot_js_display_size_update() != 0;
}
@@ -141,29 +136,30 @@ void DisplayServerJavaScript::key_callback(int p_pressed, int p_repeat, int p_mo
int DisplayServerJavaScript::mouse_button_callback(int p_pressed, int p_button, double p_x, double p_y, int p_modifiers) {
DisplayServerJavaScript *ds = get_singleton();
+ Point2 pos(p_x, p_y);
+ Input::get_singleton()->set_mouse_position(pos);
Ref<InputEventMouseButton> ev;
ev.instantiate();
- ev->set_pressed(p_pressed);
- ev->set_position(Point2(p_x, p_y));
- ev->set_global_position(ev->get_position());
+ ev->set_position(pos);
+ ev->set_global_position(pos);
ev->set_pressed(p_pressed);
dom2godot_mod(ev, p_modifiers);
switch (p_button) {
case DOM_BUTTON_LEFT:
- ev->set_button_index(MOUSE_BUTTON_LEFT);
+ ev->set_button_index(MouseButton::LEFT);
break;
case DOM_BUTTON_MIDDLE:
- ev->set_button_index(MOUSE_BUTTON_MIDDLE);
+ ev->set_button_index(MouseButton::MIDDLE);
break;
case DOM_BUTTON_RIGHT:
- ev->set_button_index(MOUSE_BUTTON_RIGHT);
+ ev->set_button_index(MouseButton::RIGHT);
break;
case DOM_BUTTON_XBUTTON1:
- ev->set_button_index(MOUSE_BUTTON_XBUTTON1);
+ ev->set_button_index(MouseButton::MB_XBUTTON1);
break;
case DOM_BUTTON_XBUTTON2:
- ev->set_button_index(MOUSE_BUTTON_XBUTTON2);
+ ev->set_button_index(MouseButton::MB_XBUTTON2);
break;
default:
return false;
@@ -176,7 +172,7 @@ int DisplayServerJavaScript::mouse_button_callback(int p_pressed, int p_button,
if (diff < 400 && Point2(ds->last_click_pos).distance_to(ev->get_position()) < 5) {
ds->last_click_ms = 0;
ds->last_click_pos = Point2(-100, -100);
- ds->last_click_button_index = -1;
+ ds->last_click_button_index = MouseButton::NONE;
ev->set_double_click(true);
}
@@ -190,11 +186,11 @@ int DisplayServerJavaScript::mouse_button_callback(int p_pressed, int p_button,
}
}
- int mask = Input::get_singleton()->get_mouse_button_mask();
- int button_flag = 1 << (ev->get_button_index() - 1);
+ MouseButton mask = Input::get_singleton()->get_mouse_button_mask();
+ MouseButton button_flag = mouse_button_to_mask(ev->get_button_index());
if (ev->is_pressed()) {
mask |= button_flag;
- } else if (mask & button_flag) {
+ } else if ((mask & button_flag) != MouseButton::NONE) {
mask &= ~button_flag;
} else {
// Received release event, but press was outside the canvas, so ignore.
@@ -215,19 +211,22 @@ int DisplayServerJavaScript::mouse_button_callback(int p_pressed, int p_button,
}
void DisplayServerJavaScript::mouse_move_callback(double p_x, double p_y, double p_rel_x, double p_rel_y, int p_modifiers) {
- int input_mask = Input::get_singleton()->get_mouse_button_mask();
+ MouseButton 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 behaviour.
- if (!get_singleton()->cursor_inside_canvas && !input_mask)
+ if (!get_singleton()->cursor_inside_canvas && input_mask == MouseButton::NONE) {
return;
+ }
+ Point2 pos(p_x, p_y);
+ Input::get_singleton()->set_mouse_position(pos);
Ref<InputEventMouseMotion> ev;
ev.instantiate();
dom2godot_mod(ev, p_modifiers);
ev->set_button_mask(input_mask);
- ev->set_position(Point2(p_x, p_y));
- ev->set_global_position(ev->get_position());
+ ev->set_position(pos);
+ ev->set_global_position(pos);
ev->set_relative(Vector2(p_rel_x, p_rel_y));
Input::get_singleton()->set_mouse_position(ev->get_position());
@@ -396,6 +395,10 @@ DisplayServer::MouseMode DisplayServerJavaScript::mouse_get_mode() const {
return MOUSE_MODE_VISIBLE;
}
+Point2i DisplayServerJavaScript::mouse_get_position() const {
+ return Input::get_singleton()->get_mouse_position();
+}
+
// Wheel
int DisplayServerJavaScript::mouse_wheel_callback(double p_delta_x, double p_delta_y) {
if (!godot_js_display_canvas_is_focused()) {
@@ -412,19 +415,19 @@ int DisplayServerJavaScript::mouse_wheel_callback(double p_delta_x, double p_del
ev->set_position(input->get_mouse_position());
ev->set_global_position(ev->get_position());
- ev->set_shift_pressed(input->is_key_pressed(KEY_SHIFT));
- ev->set_alt_pressed(input->is_key_pressed(KEY_ALT));
- ev->set_ctrl_pressed(input->is_key_pressed(KEY_CTRL));
- ev->set_meta_pressed(input->is_key_pressed(KEY_META));
+ ev->set_shift_pressed(input->is_key_pressed(Key::SHIFT));
+ ev->set_alt_pressed(input->is_key_pressed(Key::ALT));
+ ev->set_ctrl_pressed(input->is_key_pressed(Key::CTRL));
+ ev->set_meta_pressed(input->is_key_pressed(Key::META));
if (p_delta_y < 0) {
- ev->set_button_index(MOUSE_BUTTON_WHEEL_UP);
+ ev->set_button_index(MouseButton::WHEEL_UP);
} else if (p_delta_y > 0) {
- ev->set_button_index(MOUSE_BUTTON_WHEEL_DOWN);
+ ev->set_button_index(MouseButton::WHEEL_DOWN);
} else if (p_delta_x > 0) {
- ev->set_button_index(MOUSE_BUTTON_WHEEL_LEFT);
+ ev->set_button_index(MouseButton::WHEEL_LEFT);
} else if (p_delta_x < 0) {
- ev->set_button_index(MOUSE_BUTTON_WHEEL_RIGHT);
+ ev->set_button_index(MouseButton::WHEEL_RIGHT);
} else {
return false;
}
@@ -432,7 +435,7 @@ int DisplayServerJavaScript::mouse_wheel_callback(double p_delta_x, double p_del
// Different browsers give wildly different delta values, and we can't
// interpret deltaMode, so use default value for wheel events' factor.
- int button_flag = 1 << (ev->get_button_index() - 1);
+ MouseButton button_flag = mouse_button_to_mask(ev->get_button_index());
ev->set_pressed(true);
ev->set_button_mask(input->get_mouse_button_mask() | button_flag);
@@ -509,12 +512,12 @@ void DisplayServerJavaScript::vk_input_text_callback(const char *p_text, int p_c
k.instantiate();
k->set_pressed(true);
k->set_echo(false);
- k->set_keycode(KEY_RIGHT);
+ k->set_keycode(Key::RIGHT);
input->parse_input_event(k);
k.instantiate();
k->set_pressed(false);
k->set_echo(false);
- k->set_keycode(KEY_RIGHT);
+ k->set_keycode(Key::RIGHT);
input->parse_input_event(k);
}
}
@@ -557,12 +560,12 @@ void DisplayServerJavaScript::process_joypads() {
for (int b = 0; b < s_btns_num; b++) {
float value = s_btns[b];
// Buttons 6 and 7 in the standard mapping need to be
- // axis to be handled as JOY_AXIS_TRIGGER by Godot.
+ // axis to be handled as JoyAxis::TRIGGER by Godot.
if (s_standard && (b == 6 || b == 7)) {
Input::JoyAxisValue joy_axis;
joy_axis.min = 0;
joy_axis.value = value;
- JoyAxis a = b == 6 ? JOY_AXIS_TRIGGER_LEFT : JOY_AXIS_TRIGGER_RIGHT;
+ JoyAxis a = b == 6 ? JoyAxis::TRIGGER_LEFT : JoyAxis::TRIGGER_RIGHT;
input->joy_axis(idx, a, joy_axis);
} else {
input->joy_button(idx, (JoyButton)b, value);
@@ -579,7 +582,9 @@ void DisplayServerJavaScript::process_joypads() {
Vector<String> DisplayServerJavaScript::get_rendering_drivers_func() {
Vector<String> drivers;
- drivers.push_back("dummy");
+#ifdef GLES3_ENABLED
+ drivers.push_back("opengl3");
+#endif
return drivers;
}
@@ -677,40 +682,34 @@ DisplayServerJavaScript::DisplayServerJavaScript(const String &p_rendering_drive
// Expose method for requesting quit.
godot_js_os_request_quit_cb(request_quit_callback);
- RasterizerDummy::make_current(); // TODO GLES2 in Godot 4.0... or webgpu?
-#if 0
- EmscriptenWebGLContextAttributes attributes;
- emscripten_webgl_init_context_attributes(&attributes);
- attributes.alpha = GLOBAL_GET("display/window/per_pixel_transparency/allowed");
- attributes.antialias = false;
- ERR_FAIL_INDEX_V(p_video_driver, VIDEO_DRIVER_MAX, ERR_INVALID_PARAMETER);
-
- if (p_desired.layered) {
- set_window_per_pixel_transparency_enabled(true);
- }
-
- bool gl_initialization_error = false;
-
- if (RasterizerGLES2::is_viable() == OK) {
- attributes.majorVersion = 1;
- RasterizerGLES2::register_config();
- RasterizerGLES2::make_current();
- } else {
- gl_initialization_error = true;
- }
-
- EMSCRIPTEN_WEBGL_CONTEXT_HANDLE ctx = emscripten_webgl_create_context(canvas_id, &attributes);
- if (emscripten_webgl_make_context_current(ctx) != EMSCRIPTEN_RESULT_SUCCESS) {
- gl_initialization_error = true;
+#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) {
+ EmscriptenWebGLContextAttributes attributes;
+ emscripten_webgl_init_context_attributes(&attributes);
+ //attributes.alpha = GLOBAL_GET("display/window/per_pixel_transparency/allowed");
+ attributes.alpha = true;
+ attributes.antialias = false;
+ attributes.majorVersion = 2;
+
+ 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 {
+ RasterizerGLES3::make_current();
+ }
}
-
- if (gl_initialization_error) {
- OS::get_singleton()->alert("Your browser does not seem to support WebGL. Please update your browser version.",
+ 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");
- return ERR_UNAVAILABLE;
}
-
- video_driver_index = p_video_driver;
+ if (!wants_webgl2 || webgl2_init_failed) {
+ RasterizerDummy::make_current();
+ }
+#else
+ RasterizerDummy::make_current();
#endif
// JS Input interface (js/libs/library_godot_input.js)
@@ -737,8 +736,12 @@ DisplayServerJavaScript::DisplayServerJavaScript(const String &p_rendering_drive
}
DisplayServerJavaScript::~DisplayServerJavaScript() {
- //emscripten_webgl_commit_frame();
- //emscripten_webgl_destroy_context(webgl_ctx);
+#ifdef GLES3_ENABLED
+ if (webgl_ctx) {
+ emscripten_webgl_commit_frame();
+ emscripten_webgl_destroy_context(webgl_ctx);
+ }
+#endif
}
bool DisplayServerJavaScript::has_feature(Feature p_feature) const {
@@ -967,5 +970,9 @@ bool DisplayServerJavaScript::get_swap_cancel_ok() {
}
void DisplayServerJavaScript::swap_buffers() {
- //emscripten_webgl_commit_frame();
+#ifdef GLES3_ENABLED
+ if (webgl_ctx) {
+ emscripten_webgl_commit_frame();
+ }
+#endif
}
diff --git a/platform/javascript/display_server_javascript.h b/platform/javascript/display_server_javascript.h
index 1aa600c421..843bb61984 100644
--- a/platform/javascript/display_server_javascript.h
+++ b/platform/javascript/display_server_javascript.h
@@ -51,6 +51,10 @@ private:
};
JSKeyEvent key_event;
+#ifdef GLES3_ENABLED
+ EMSCRIPTEN_WEBGL_CONTEXT_HANDLE webgl_ctx = 0;
+#endif
+
WindowMode window_mode = WINDOW_MODE_WINDOWED;
ObjectID window_attached_instance_id = {};
@@ -67,13 +71,11 @@ private:
CursorShape cursor_shape = CURSOR_ARROW;
Point2i last_click_pos = Point2(-100, -100); // TODO check this again.
uint64_t last_click_ms = 0;
- int last_click_button_index = -1;
+ MouseButton last_click_button_index = MouseButton::NONE;
bool swap_cancel_ok = false;
// utilities
- static void focus_canvas();
- static bool is_canvas_focused();
static void dom2godot_mod(Ref<InputEventWithModifiers> ev, int p_mod);
static const char *godot2dom_cursor(DisplayServer::CursorShape p_shape);
@@ -121,6 +123,7 @@ public:
// mouse
virtual void mouse_set_mode(MouseMode p_mode) override;
virtual MouseMode mouse_get_mode() const override;
+ virtual Point2i mouse_get_position() const override;
// touch
virtual bool screen_is_touchscreen(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
diff --git a/platform/javascript/dom_keys.inc b/platform/javascript/dom_keys.inc
index 0e62776923..31589f3f40 100644
--- a/platform/javascript/dom_keys.inc
+++ b/platform/javascript/dom_keys.inc
@@ -34,7 +34,7 @@
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; \
+ return Key::p_godot_code; \
}
// Numpad section.
@@ -105,16 +105,16 @@ Key dom_code2godot_scancode(EM_UTF8 const p_code[32], EM_UTF8 const p_key[32], b
DOM2GODOT("BracketLeft", BRACKETLEFT);
DOM2GODOT("BracketRight", BRACKETRIGHT);
DOM2GODOT("Comma", COMMA);
- DOM2GODOT("Digit0", 0);
- DOM2GODOT("Digit1", 1);
- DOM2GODOT("Digit2", 2);
- DOM2GODOT("Digit3", 3);
- DOM2GODOT("Digit4", 4);
- DOM2GODOT("Digit5", 5);
- DOM2GODOT("Digit6", 6);
- DOM2GODOT("Digit7", 7);
- DOM2GODOT("Digit8", 8);
- DOM2GODOT("Digit9", 9);
+ DOM2GODOT("Digit0", KEY_0);
+ DOM2GODOT("Digit1", KEY_1);
+ DOM2GODOT("Digit2", KEY_2);
+ DOM2GODOT("Digit3", KEY_3);
+ DOM2GODOT("Digit4", KEY_4);
+ DOM2GODOT("Digit5", KEY_5);
+ DOM2GODOT("Digit6", KEY_6);
+ DOM2GODOT("Digit7", KEY_7);
+ DOM2GODOT("Digit8", KEY_8);
+ DOM2GODOT("Digit9", KEY_9);
DOM2GODOT("Equal", EQUAL);
DOM2GODOT("IntlBackslash", BACKSLASH);
//DOM2GODOT("IntlRo", UNKNOWN);
@@ -170,7 +170,7 @@ Key dom_code2godot_scancode(EM_UTF8 const p_code[32], EM_UTF8 const p_key[32], b
DOM2GODOT("Tab", TAB);
// ControlPad section.
- DOM2GODOT("Delete", DELETE);
+ DOM2GODOT("Delete", KEY_DELETE);
DOM2GODOT("End", END);
DOM2GODOT("Help", HELP);
DOM2GODOT("Home", HOME);
@@ -227,6 +227,6 @@ 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;
+ return Key::UNKNOWN;
#undef DOM2GODOT
}
diff --git a/platform/javascript/export/export_plugin.cpp b/platform/javascript/export/export_plugin.cpp
index c7bd172751..018dd3b664 100644
--- a/platform/javascript/export/export_plugin.cpp
+++ b/platform/javascript/export/export_plugin.cpp
@@ -140,7 +140,7 @@ void EditorExportPlatformJavaScript::_fix_html(Vector<uint8_t> &p_html, const Re
if (p_preset->get("progressive_web_app/enabled")) {
head_include += "<link rel='manifest' href='" + p_name + ".manifest.json'>\n";
head_include += "<script type='application/javascript'>window.addEventListener('load', () => {if ('serviceWorker' in navigator) {navigator.serviceWorker.register('" +
- p_name + ".service.worker.js');}});</script>\n";
+ p_name + ".service.worker.js');}});</script>\n";
}
// Replaces HTML string
@@ -300,9 +300,9 @@ void EditorExportPlatformJavaScript::get_preset_features(const Ref<EditorExportP
if (p_preset->get("vram_texture_compression/for_mobile")) {
String driver = ProjectSettings::get_singleton()->get("rendering/driver/driver_name");
- if (driver == "GLES2") {
+ if (driver == "opengl3") {
r_features->push_back("etc");
- } else if (driver == "Vulkan") {
+ } else if (driver == "vulkan") {
// FIXME: Review if this is correct.
r_features->push_back("etc2");
}
diff --git a/platform/javascript/js/libs/library_godot_input.js b/platform/javascript/js/libs/library_godot_input.js
index 587c320f35..945dbba902 100644
--- a/platform/javascript/js/libs/library_godot_input.js
+++ b/platform/javascript/js/libs/library_godot_input.js
@@ -104,10 +104,14 @@ const GodotInputGamepads = {
}
}
GodotEventListeners.add(window, 'gamepadconnected', function (evt) {
- add(evt.gamepad);
+ if (evt.gamepad) {
+ add(evt.gamepad);
+ }
}, false);
GodotEventListeners.add(window, 'gamepaddisconnected', function (evt) {
- onchange(evt.gamepad.index, 0);
+ if (evt.gamepad) {
+ onchange(evt.gamepad.index, 0);
+ }
}, false);
},
@@ -389,6 +393,11 @@ const GodotInput = {
const rect = canvas.getBoundingClientRect();
const pos = GodotInput.computePosition(evt, rect);
const modifiers = GodotInput.getModifiers(evt);
+ // Since the event is consumed, focus manually.
+ // NOTE: The iframe container may not have focus yet, so focus even when already active.
+ if (p_pressed) {
+ GodotConfig.canvas.focus();
+ }
if (func(p_pressed, evt.button, pos[0], pos[1], modifiers)) {
evt.preventDefault();
}
@@ -405,14 +414,19 @@ const GodotInput = {
const func = GodotRuntime.get_func(callback);
const canvas = GodotConfig.canvas;
function touch_cb(type, evt) {
+ // Since the event is consumed, focus manually.
+ // NOTE: The iframe container may not have focus yet, so focus even when already active.
+ if (type === 0) {
+ GodotConfig.canvas.focus();
+ }
const rect = canvas.getBoundingClientRect();
const touches = evt.changedTouches;
for (let i = 0; i < touches.length; i++) {
const touch = touches[i];
const pos = GodotInput.computePosition(touch, rect);
- GodotRuntime.setHeapValue(coords + (i * 2), pos[0], 'double');
- GodotRuntime.setHeapValue(coords + (i * 2 + 8), pos[1], 'double');
- GodotRuntime.setHeapValue(ids + i, touch.identifier, 'i32');
+ GodotRuntime.setHeapValue(coords + (i * 2) * 8, pos[0], 'double');
+ GodotRuntime.setHeapValue(coords + (i * 2 + 1) * 8, pos[1], 'double');
+ GodotRuntime.setHeapValue(ids + i * 4, touch.identifier, 'i32');
}
func(type, touches.length);
if (evt.cancelable) {
diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp
index 4431bd5f1b..5da9a96a90 100644
--- a/platform/javascript/os_javascript.cpp
+++ b/platform/javascript/os_javascript.cpp
@@ -36,7 +36,7 @@
#include "main/main.h"
#include "platform/javascript/display_server_javascript.h"
-#include "modules/modules_enabled.gen.h"
+#include "modules/modules_enabled.gen.h" // For websocket.
#ifdef MODULE_WEBSOCKET_ENABLED
#include "modules/websocket/remote_debugger_peer_websocket.h"
#endif
diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h
index d053082d92..fbab95d33b 100644
--- a/platform/javascript/os_javascript.h
+++ b/platform/javascript/os_javascript.h
@@ -75,6 +75,7 @@ public:
Error kill(const ProcessID &p_pid) override;
int get_process_id() const override;
int get_processor_count() const override;
+ int get_default_thread_pool_size() const override { return 1; }
String get_executable_path() const override;
Error shell_open(String p_uri) override;
@@ -89,6 +90,7 @@ public:
String get_user_data_dir() const override;
bool is_userfs_persistent() const override;
+ bool is_single_window() const override { return true; }
void alert(const String &p_alert, const String &p_title = "ALERT!") override;
diff --git a/platform/javascript/package-lock.json b/platform/javascript/package-lock.json
index 8003619576..1bc11c7ccf 100644
--- a/platform/javascript/package-lock.json
+++ b/platform/javascript/package-lock.json
@@ -109,9 +109,9 @@
"dev": true
},
"ansi-regex": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
- "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"dev": true
},
"ansi-styles": {
diff --git a/platform/linuxbsd/SCsub b/platform/linuxbsd/SCsub
index 8aebd57fd2..cec8706fbc 100644
--- a/platform/linuxbsd/SCsub
+++ b/platform/linuxbsd/SCsub
@@ -14,7 +14,7 @@ common_linuxbsd = [
if "x11" in env and env["x11"]:
common_linuxbsd += [
- "context_gl_x11.cpp",
+ "gl_manager_x11.cpp",
"detect_prime_x11.cpp",
"display_server_x11.cpp",
"key_mapping_x11.cpp",
diff --git a/platform/linuxbsd/context_gl_x11.cpp b/platform/linuxbsd/context_gl_x11.cpp
deleted file mode 100644
index 1f92370ab7..0000000000
--- a/platform/linuxbsd/context_gl_x11.cpp
+++ /dev/null
@@ -1,257 +0,0 @@
-/*************************************************************************/
-/* context_gl_x11.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "context_gl_x11.h"
-
-#ifdef X11_ENABLED
-#if defined(OPENGL_ENABLED)
-#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 *);
-
-struct ContextGL_X11_Private {
- ::GLXContext glx_context;
-};
-
-void ContextGL_X11::release_current() {
- glXMakeCurrent(x11_display, None, nullptr);
-}
-
-void ContextGL_X11::make_current() {
- glXMakeCurrent(x11_display, x11_window, p->glx_context);
-}
-
-void ContextGL_X11::swap_buffers() {
- glXSwapBuffers(x11_display, x11_window);
-}
-
-static bool ctxErrorOccurred = false;
-static int ctxErrorHandler(Display *dpy, XErrorEvent *ev) {
- ctxErrorOccurred = true;
- return 0;
-}
-
-static void set_class_hint(Display *p_display, Window p_window) {
- XClassHint *classHint;
-
- /* set the name and class hints for the window manager to use */
- classHint = XAllocClassHint();
- if (classHint) {
- classHint->res_name = (char *)"Godot_Engine";
- classHint->res_class = (char *)"Godot";
- }
- XSetClassHint(p_display, p_window, classHint);
- XFree(classHint);
-}
-
-Error ContextGL_X11::initialize() {
- //const char *extensions = glXQueryExtensionsString(x11_display, DefaultScreen(x11_display));
-
- GLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = (GLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddress((const GLubyte *)"glXCreateContextAttribsARB");
-
- ERR_FAIL_COND_V(!glXCreateContextAttribsARB, ERR_UNCONFIGURED);
-
- static int visual_attribs[] = {
- GLX_RENDER_TYPE, GLX_RGBA_BIT,
- GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
- GLX_DOUBLEBUFFER, true,
- GLX_RED_SIZE, 1,
- GLX_GREEN_SIZE, 1,
- GLX_BLUE_SIZE, 1,
- GLX_DEPTH_SIZE, 24,
- None
- };
-
- static int visual_attribs_layered[] = {
- GLX_RENDER_TYPE, GLX_RGBA_BIT,
- GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
- GLX_DOUBLEBUFFER, true,
- GLX_RED_SIZE, 8,
- GLX_GREEN_SIZE, 8,
- GLX_BLUE_SIZE, 8,
- GLX_ALPHA_SIZE, 8,
- GLX_DEPTH_SIZE, 24,
- None
- };
-
- int fbcount;
- GLXFBConfig fbconfig = 0;
- XVisualInfo *vi = nullptr;
-
- XSetWindowAttributes swa;
- swa.event_mask = StructureNotifyMask;
- swa.border_pixel = 0;
- unsigned long valuemask = CWBorderPixel | CWColormap | CWEventMask;
-
- if (OS::get_singleton()->is_layered_allowed()) {
- GLXFBConfig *fbc = glXChooseFBConfig(x11_display, DefaultScreen(x11_display), visual_attribs_layered, &fbcount);
- ERR_FAIL_COND_V(!fbc, ERR_UNCONFIGURED);
-
- for (int i = 0; i < fbcount; i++) {
- vi = (XVisualInfo *)glXGetVisualFromFBConfig(x11_display, fbc[i]);
- if (!vi)
- continue;
-
- XRenderPictFormat *pict_format = XRenderFindVisualFormat(x11_display, vi->visual);
- if (!pict_format) {
- XFree(vi);
- vi = nullptr;
- continue;
- }
-
- fbconfig = fbc[i];
- if (pict_format->direct.alphaMask > 0) {
- break;
- }
- }
- XFree(fbc);
- ERR_FAIL_COND_V(!fbconfig, ERR_UNCONFIGURED);
-
- swa.background_pixmap = None;
- swa.background_pixel = 0;
- swa.border_pixmap = None;
- valuemask |= CWBackPixel;
-
- } else {
- GLXFBConfig *fbc = glXChooseFBConfig(x11_display, DefaultScreen(x11_display), visual_attribs, &fbcount);
- ERR_FAIL_COND_V(!fbc, ERR_UNCONFIGURED);
-
- vi = glXGetVisualFromFBConfig(x11_display, fbc[0]);
-
- fbconfig = fbc[0];
- XFree(fbc);
- }
-
- int (*oldHandler)(Display *, XErrorEvent *) = XSetErrorHandler(&ctxErrorHandler);
-
- switch (context_type) {
- case GLES_2_0_COMPATIBLE: {
- p->glx_context = glXCreateNewContext(x11_display, fbconfig, GLX_RGBA_TYPE, 0, true);
- ERR_FAIL_COND_V(!p->glx_context, ERR_UNCONFIGURED);
- } break;
- }
-
- swa.colormap = XCreateColormap(x11_display, RootWindow(x11_display, vi->screen), vi->visual, AllocNone);
- x11_window = XCreateWindow(x11_display, RootWindow(x11_display, vi->screen), 0, 0, OS::get_singleton()->get_video_mode().width, OS::get_singleton()->get_video_mode().height, 0, vi->depth, InputOutput, vi->visual, valuemask, &swa);
- XStoreName(x11_display, x11_window, "Godot Engine");
-
- ERR_FAIL_COND_V(!x11_window, ERR_UNCONFIGURED);
- set_class_hint(x11_display, x11_window);
- XMapWindow(x11_display, x11_window);
-
- XSync(x11_display, False);
- XSetErrorHandler(oldHandler);
-
- glXMakeCurrent(x11_display, x11_window, p->glx_context);
-
- XFree(vi);
-
- return OK;
-}
-
-int ContextGL_X11::get_window_width() {
- XWindowAttributes xwa;
- XGetWindowAttributes(x11_display, x11_window, &xwa);
-
- return xwa.width;
-}
-
-int ContextGL_X11::get_window_height() {
- XWindowAttributes xwa;
- XGetWindowAttributes(x11_display, x11_window, &xwa);
-
- return xwa.height;
-}
-
-void ContextGL_X11::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");
- }
- 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;
- use_vsync = p_use;
-}
-
-bool ContextGL_X11::is_using_vsync() const {
- return use_vsync;
-}
-
-ContextGL_X11::ContextGL_X11(::Display *p_x11_display, ::Window &p_x11_window, const OS::VideoMode &p_default_video_mode, ContextType p_context_type) :
- x11_window(p_x11_window) {
- default_video_mode = p_default_video_mode;
- x11_display = p_x11_display;
-
- context_type = p_context_type;
-
- double_buffer = false;
- direct_render = false;
- glx_minor = glx_major = 0;
- p = memnew(ContextGL_X11_Private);
- p->glx_context = 0;
- use_vsync = false;
-}
-
-ContextGL_X11::~ContextGL_X11() {
- release_current();
- glXDestroyContext(x11_display, p->glx_context);
- memdelete(p);
-}
-
-#endif
-#endif
diff --git a/platform/linuxbsd/crash_handler_linuxbsd.cpp b/platform/linuxbsd/crash_handler_linuxbsd.cpp
index 0e98af71fa..9b24b24cb4 100644
--- a/platform/linuxbsd/crash_handler_linuxbsd.cpp
+++ b/platform/linuxbsd/crash_handler_linuxbsd.cpp
@@ -115,7 +115,7 @@ static void handle_crash(int sig) {
int ret;
Error err = OS::get_singleton()->execute(String("addr2line"), args, &output, &ret);
if (err == OK) {
- output.erase(output.length() - 1, 1);
+ output = output.substr(0, output.length() - 1);
}
fprintf(stderr, "[%ld] %s (%s)\n", (long int)i, fname, output.utf8().get_data());
diff --git a/platform/linuxbsd/detect.py b/platform/linuxbsd/detect.py
index 8eb22c1c72..07e16a982b 100644
--- a/platform/linuxbsd/detect.py
+++ b/platform/linuxbsd/detect.py
@@ -105,14 +105,12 @@ def configure(env):
env.Prepend(CCFLAGS=["-O2"])
elif env["optimize"] == "size": # optimize for size
env.Prepend(CCFLAGS=["-Os"])
- env.Prepend(CPPDEFINES=["DEBUG_ENABLED"])
if env["debug_symbols"]:
env.Prepend(CCFLAGS=["-g2"])
elif env["target"] == "debug":
env.Prepend(CCFLAGS=["-g3"])
- env.Prepend(CPPDEFINES=["DEBUG_ENABLED"])
env.Append(LINKFLAGS=["-rdynamic"])
## Architecture
@@ -121,6 +119,21 @@ def configure(env):
if env["bits"] == "default":
env["bits"] = "64" if is64 else "32"
+ machines = {
+ "riscv64": "rv64",
+ "ppc64le": "ppc64",
+ "ppc64": "ppc64",
+ "ppcle": "ppc",
+ "ppc": "ppc",
+ }
+
+ if env["arch"] == "" and platform.machine() in machines:
+ env["arch"] = machines[platform.machine()]
+
+ if env["arch"] == "rv64":
+ # G = General-purpose extensions, C = Compression extension (very common).
+ env.Append(CCFLAGS=["-march=rv64gc"])
+
## Compiler configuration
if "CXX" in env and "clang" in os.path.basename(env["CXX"]):
@@ -290,17 +303,10 @@ def configure(env):
if any(platform.machine() in s for s in list_of_x86):
env["x86_libtheora_opt_gcc"] = True
- if not env["builtin_libvpx"]:
- env.ParseConfig("pkg-config vpx --cflags --libs")
-
if not env["builtin_libvorbis"]:
env["builtin_libogg"] = False # Needed to link against system libvorbis
env.ParseConfig("pkg-config vorbis vorbisfile --cflags --libs")
- if not env["builtin_opus"]:
- env["builtin_libogg"] = False # Needed to link against system opus
- env.ParseConfig("pkg-config opus opusfile --cflags --libs")
-
if not env["builtin_libogg"]:
env.ParseConfig("pkg-config ogg --cflags --libs")
@@ -383,8 +389,8 @@ def configure(env):
# No pkgconfig file for glslang so far
env.Append(LIBS=["glslang", "SPIRV"])
- # env.Append(CPPDEFINES=['OPENGL_ENABLED'])
- env.Append(LIBS=["GL"])
+ env.Append(CPPDEFINES=["GLES3_ENABLED"])
+ env.Append(LIBS=["GL"])
env.Append(LIBS=["pthread"])
diff --git a/platform/linuxbsd/detect_prime_x11.cpp b/platform/linuxbsd/detect_prime_x11.cpp
index da1c95a593..c775546f15 100644
--- a/platform/linuxbsd/detect_prime_x11.cpp
+++ b/platform/linuxbsd/detect_prime_x11.cpp
@@ -29,9 +29,9 @@
/*************************************************************************/
#ifdef X11_ENABLED
-#if defined(OPENGL_ENABLED)
+#if defined(GLES3_ENABLED)
-#include "detect_prime.h"
+#include "detect_prime_x11.h"
#include "core/string/print_string.h"
#include "core/string/ustring.h"
diff --git a/platform/linuxbsd/detect_prime_x11.h b/platform/linuxbsd/detect_prime_x11.h
index 0b548b849e..88d00b3acd 100644
--- a/platform/linuxbsd/detect_prime_x11.h
+++ b/platform/linuxbsd/detect_prime_x11.h
@@ -29,7 +29,7 @@
/*************************************************************************/
#ifdef X11_ENABLED
-#if defined(OPENGL_ENABLED)
+#if defined(GLES3_ENABLED)
int detect_prime();
diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp
index f2cd336b39..74ec8b652f 100644
--- a/platform/linuxbsd/display_server_x11.cpp
+++ b/platform/linuxbsd/display_server_x11.cpp
@@ -34,6 +34,7 @@
#include "core/config/project_settings.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"
@@ -43,6 +44,10 @@
#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
#endif
+#if defined(GLES3_ENABLED)
+#include "drivers/gles3/rasterizer_gles3.h"
+#endif
+
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
@@ -124,6 +129,7 @@ bool DisplayServerX11::has_feature(Feature p_feature) const {
#ifdef DBUS_ENABLED
case FEATURE_KEEP_SCREEN_ON:
#endif
+ case FEATURE_CLIPBOARD_PRIMARY:
return true;
default: {
}
@@ -280,7 +286,7 @@ void DisplayServerX11::_flush_mouse_motion() {
XIDeviceEvent *event_data = (XIDeviceEvent *)event.xcookie.data;
if (event_data->evtype == XI_RawMotion) {
XFreeEventData(x11_display, &event.xcookie);
- polled_events.remove(event_index--);
+ polled_events.remove_at(event_index--);
continue;
}
XFreeEventData(x11_display, &event.xcookie);
@@ -406,6 +412,20 @@ void DisplayServerX11::clipboard_set(const String &p_text) {
XSetSelectionOwner(x11_display, XInternAtom(x11_display, "CLIPBOARD", 0), windows[MAIN_WINDOW_ID].x11_window, CurrentTime);
}
+void DisplayServerX11::clipboard_set_primary(const String &p_text) {
+ _THREAD_SAFE_METHOD_
+ if (!p_text.is_empty()) {
+ {
+ // The clipboard content can be accessed while polling for events.
+ MutexLock mutex_lock(events_mutex);
+ internal_clipboard_primary = p_text;
+ }
+
+ XSetSelectionOwner(x11_display, XA_PRIMARY, windows[MAIN_WINDOW_ID].x11_window, CurrentTime);
+ XSetSelectionOwner(x11_display, XInternAtom(x11_display, "PRIMARY", 0), windows[MAIN_WINDOW_ID].x11_window, CurrentTime);
+ }
+}
+
Bool DisplayServerX11::_predicate_clipboard_selection(Display *display, XEvent *event, XPointer arg) {
if (event->type == SelectionNotify && event->xselection.requestor == *(Window *)arg) {
return True;
@@ -427,7 +447,12 @@ String DisplayServerX11::_clipboard_get_impl(Atom p_source, Window x11_window, A
Window selection_owner = XGetSelectionOwner(x11_display, p_source);
if (selection_owner == x11_window) {
- return internal_clipboard;
+ static const char *target_type = "PRIMARY";
+ if (p_source != None && String(XGetAtomName(x11_display, p_source)) == target_type) {
+ return internal_clipboard_primary;
+ } else {
+ return internal_clipboard;
+ }
}
if (selection_owner != None) {
@@ -580,10 +605,23 @@ String DisplayServerX11::clipboard_get() const {
return ret;
}
+String DisplayServerX11::clipboard_get_primary() const {
+ _THREAD_SAFE_METHOD_
+
+ String ret;
+ ret = _clipboard_get(XInternAtom(x11_display, "PRIMARY", 0), windows[MAIN_WINDOW_ID].x11_window);
+
+ if (ret.is_empty()) {
+ ret = _clipboard_get(XA_PRIMARY, windows[MAIN_WINDOW_ID].x11_window);
+ }
+
+ return ret;
+}
+
Bool DisplayServerX11::_predicate_clipboard_save_targets(Display *display, XEvent *event, XPointer arg) {
if (event->xany.window == *(Window *)arg) {
return (event->type == SelectionRequest) ||
- (event->type == SelectionNotify);
+ (event->type == SelectionNotify);
} else {
return False;
}
@@ -650,35 +688,59 @@ int DisplayServerX11::get_screen_count() const {
return count;
}
-Point2i DisplayServerX11::screen_get_position(int p_screen) const {
- _THREAD_SAFE_METHOD_
+Rect2i DisplayServerX11::_screen_get_rect(int p_screen) const {
+ Rect2i rect(0, 0, 0, 0);
if (p_screen == SCREEN_OF_MAIN_WINDOW) {
p_screen = window_get_current_screen();
}
- // Using Xinerama Extension
+ ERR_FAIL_COND_V(p_screen < 0, rect);
+
+ // Using Xinerama Extension.
int event_base, error_base;
- const Bool ext_okay = XineramaQueryExtension(x11_display, &event_base, &error_base);
- if (!ext_okay) {
- return Point2i(0, 0);
+ if (XineramaQueryExtension(x11_display, &event_base, &error_base)) {
+ int count;
+ XineramaScreenInfo *xsi = XineramaQueryScreens(x11_display, &count);
+
+ // Check if screen is valid.
+ if (p_screen < count) {
+ rect.position.x = xsi[p_screen].x_org;
+ rect.position.y = xsi[p_screen].y_org;
+ rect.size.width = xsi[p_screen].width;
+ rect.size.height = xsi[p_screen].height;
+ } else {
+ ERR_PRINT("Invalid screen index: " + itos(p_screen) + "(count: " + itos(count) + ").");
+ }
+
+ if (xsi) {
+ XFree(xsi);
+ }
}
- int count;
- XineramaScreenInfo *xsi = XineramaQueryScreens(x11_display, &count);
+ return rect;
+}
- // Check if screen is valid
- ERR_FAIL_INDEX_V(p_screen, count, Point2i(0, 0));
+Point2i DisplayServerX11::screen_get_position(int p_screen) const {
+ _THREAD_SAFE_METHOD_
- Point2i position = Point2i(xsi[p_screen].x_org, xsi[p_screen].y_org);
+ return _screen_get_rect(p_screen).position;
+}
- XFree(xsi);
+Size2i DisplayServerX11::screen_get_size(int p_screen) const {
+ _THREAD_SAFE_METHOD_
- return position;
+ return _screen_get_rect(p_screen).size;
}
-Size2i DisplayServerX11::screen_get_size(int p_screen) const {
- return screen_get_usable_rect(p_screen).size;
+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 0;
}
Rect2i DisplayServerX11::screen_get_usable_rect(int p_screen) const {
@@ -688,21 +750,276 @@ Rect2i DisplayServerX11::screen_get_usable_rect(int p_screen) const {
p_screen = window_get_current_screen();
}
- // Using Xinerama Extension
- int event_base, error_base;
- const Bool ext_okay = XineramaQueryExtension(x11_display, &event_base, &error_base);
- if (!ext_okay) {
- return Rect2i(0, 0, 0, 0);
+ int screen_count = get_screen_count();
+
+ // Check if screen is valid.
+ ERR_FAIL_INDEX_V(p_screen, screen_count, Rect2i(0, 0, 0, 0));
+
+ bool is_multiscreen = screen_count > 1;
+
+ // Use full monitor size as fallback.
+ Rect2i rect = _screen_get_rect(p_screen);
+
+ // There's generally only one screen reported by xlib even in multi-screen setup,
+ // in this case it's just one virtual screen composed of all physical monitors.
+ int x11_screen_count = ScreenCount(x11_display);
+ Window x11_window = RootWindow(x11_display, p_screen < x11_screen_count ? p_screen : 0);
+
+ Atom type;
+ int format = 0;
+ unsigned long remaining = 0;
+
+ // Find active desktop for the root window.
+ unsigned int desktop_index = 0;
+ Atom desktop_prop = XInternAtom(x11_display, "_NET_CURRENT_DESKTOP", True);
+ if (desktop_prop != None) {
+ unsigned long desktop_len = 0;
+ unsigned char *desktop_data = nullptr;
+ if (XGetWindowProperty(x11_display, x11_window, desktop_prop, 0, LONG_MAX, False, XA_CARDINAL, &type, &format, &desktop_len, &remaining, &desktop_data) == Success) {
+ if ((format == 32) && (desktop_len > 0) && desktop_data) {
+ desktop_index = (unsigned int)desktop_data[0];
+ }
+ if (desktop_data) {
+ XFree(desktop_data);
+ }
+ }
}
- int count;
- XineramaScreenInfo *xsi = XineramaQueryScreens(x11_display, &count);
+ bool use_simple_method = true;
+
+ // First check for GTK work area, which is more accurate for multi-screen setup.
+ if (is_multiscreen) {
+ // Use already calculated work area when available.
+ Atom gtk_workareas_prop = XInternAtom(x11_display, "_GTK_WORKAREAS", False);
+ if (gtk_workareas_prop != None) {
+ char gtk_workarea_prop_name[32];
+ snprintf(gtk_workarea_prop_name, 32, "_GTK_WORKAREAS_D%d", desktop_index);
+ Atom gtk_workarea_prop = XInternAtom(x11_display, gtk_workarea_prop_name, True);
+ if (gtk_workarea_prop != None) {
+ unsigned long workarea_len = 0;
+ unsigned char *workarea_data = nullptr;
+ if (XGetWindowProperty(x11_display, x11_window, gtk_workarea_prop, 0, LONG_MAX, False, XA_CARDINAL, &type, &format, &workarea_len, &remaining, &workarea_data) == Success) {
+ if ((format == 32) && (workarea_len % 4 == 0) && workarea_data) {
+ long *rect_data = (long *)workarea_data;
+ for (uint32_t data_offset = 0; data_offset < workarea_len; data_offset += 4) {
+ Rect2i workarea_rect;
+ workarea_rect.position.x = rect_data[data_offset];
+ workarea_rect.position.y = rect_data[data_offset + 1];
+ workarea_rect.size.x = rect_data[data_offset + 2];
+ workarea_rect.size.y = rect_data[data_offset + 3];
+
+ // Intersect with actual monitor size to find the correct area,
+ // because areas are not in the same order as screens from Xinerama.
+ if (rect.grow(-1).intersects(workarea_rect)) {
+ rect = rect.intersection(workarea_rect);
+ XFree(workarea_data);
+ return rect;
+ }
+ }
+ }
+ }
+ if (workarea_data) {
+ XFree(workarea_data);
+ }
+ }
+ }
- // Check if screen is valid
- ERR_FAIL_INDEX_V(p_screen, count, Rect2i(0, 0, 0, 0));
+ // Fallback to calculating work area by hand from struts.
+ Atom client_list_prop = XInternAtom(x11_display, "_NET_CLIENT_LIST", True);
+ if (client_list_prop != None) {
+ unsigned long clients_len = 0;
+ unsigned char *clients_data = nullptr;
+ if (XGetWindowProperty(x11_display, x11_window, client_list_prop, 0, LONG_MAX, False, XA_WINDOW, &type, &format, &clients_len, &remaining, &clients_data) == Success) {
+ if ((format == 32) && (clients_len > 0) && clients_data) {
+ Window *windows_data = (Window *)clients_data;
+
+ Rect2i desktop_rect;
+ bool desktop_valid = false;
+
+ // Get full desktop size.
+ {
+ Atom desktop_geometry_prop = XInternAtom(x11_display, "_NET_DESKTOP_GEOMETRY", True);
+ if (desktop_geometry_prop != None) {
+ unsigned long geom_len = 0;
+ unsigned char *geom_data = nullptr;
+ if (XGetWindowProperty(x11_display, x11_window, desktop_geometry_prop, 0, LONG_MAX, False, XA_CARDINAL, &type, &format, &geom_len, &remaining, &geom_data) == Success) {
+ if ((format == 32) && (geom_len >= 2) && geom_data) {
+ desktop_valid = true;
+ long *size_data = (long *)geom_data;
+ desktop_rect.size.x = size_data[0];
+ desktop_rect.size.y = size_data[1];
+ }
+ }
+ if (geom_data) {
+ XFree(geom_data);
+ }
+ }
+ }
+
+ // Get full desktop position.
+ if (desktop_valid) {
+ Atom desktop_viewport_prop = XInternAtom(x11_display, "_NET_DESKTOP_VIEWPORT", True);
+ if (desktop_viewport_prop != None) {
+ unsigned long viewport_len = 0;
+ unsigned char *viewport_data = nullptr;
+ if (XGetWindowProperty(x11_display, x11_window, desktop_viewport_prop, 0, LONG_MAX, False, XA_CARDINAL, &type, &format, &viewport_len, &remaining, &viewport_data) == Success) {
+ if ((format == 32) && (viewport_len >= 2) && viewport_data) {
+ desktop_valid = true;
+ long *pos_data = (long *)viewport_data;
+ desktop_rect.position.x = pos_data[0];
+ desktop_rect.position.y = pos_data[1];
+ }
+ }
+ if (viewport_data) {
+ XFree(viewport_data);
+ }
+ }
+ }
+
+ if (desktop_valid) {
+ use_simple_method = false;
+
+ // Handle bad window errors silently because there's no other way to check
+ // that one of the windows has been destroyed in the meantime.
+ int (*oldHandler)(Display *, XErrorEvent *) = XSetErrorHandler(&bad_window_error_handler);
+
+ for (unsigned long win_index = 0; win_index < clients_len; ++win_index) {
+ g_bad_window = false;
+
+ // Remove strut size from desktop size to get a more accurate result.
+ bool strut_found = false;
+ unsigned long strut_len = 0;
+ unsigned char *strut_data = nullptr;
+ Atom strut_partial_prop = XInternAtom(x11_display, "_NET_WM_STRUT_PARTIAL", True);
+ if (strut_partial_prop != None) {
+ if (XGetWindowProperty(x11_display, windows_data[win_index], strut_partial_prop, 0, LONG_MAX, False, XA_CARDINAL, &type, &format, &strut_len, &remaining, &strut_data) == Success) {
+ strut_found = true;
+ }
+ }
+ // Fallback to older strut property.
+ if (!g_bad_window && !strut_found) {
+ Atom strut_prop = XInternAtom(x11_display, "_NET_WM_STRUT", True);
+ if (strut_prop != None) {
+ if (XGetWindowProperty(x11_display, windows_data[win_index], strut_prop, 0, LONG_MAX, False, XA_CARDINAL, &type, &format, &strut_len, &remaining, &strut_data) == Success) {
+ strut_found = true;
+ }
+ }
+ }
+ if (!g_bad_window && strut_found && (format == 32) && (strut_len >= 4) && strut_data) {
+ long *struts = (long *)strut_data;
+
+ long left = struts[0];
+ long right = struts[1];
+ long top = struts[2];
+ long bottom = struts[3];
+
+ long left_start_y, left_end_y, right_start_y, right_end_y;
+ long top_start_x, top_end_x, bottom_start_x, bottom_end_x;
+
+ if (strut_len >= 12) {
+ left_start_y = struts[4];
+ left_end_y = struts[5];
+ right_start_y = struts[6];
+ right_end_y = struts[7];
+ top_start_x = struts[8];
+ top_end_x = struts[9];
+ bottom_start_x = struts[10];
+ bottom_end_x = struts[11];
+ } else {
+ left_start_y = 0;
+ left_end_y = desktop_rect.size.y;
+ right_start_y = 0;
+ right_end_y = desktop_rect.size.y;
+ top_start_x = 0;
+ top_end_x = desktop_rect.size.x;
+ bottom_start_x = 0;
+ bottom_end_x = desktop_rect.size.x;
+ }
+
+ const Point2i &pos = desktop_rect.position;
+ const Size2i &size = desktop_rect.size;
+
+ Rect2i left_rect(pos.x, pos.y + left_start_y, left, left_end_y - left_start_y);
+ if (left_rect.size.x > 0) {
+ Rect2i intersection = rect.intersection(left_rect);
+ if (!intersection.has_no_area() && intersection.size.x < rect.size.x) {
+ rect.position.x = left_rect.size.x;
+ rect.size.x = rect.size.x - intersection.size.x;
+ }
+ }
+
+ Rect2i right_rect(pos.x + size.x - right, pos.y + right_start_y, right, right_end_y - right_start_y);
+ if (right_rect.size.x > 0) {
+ Rect2i intersection = rect.intersection(right_rect);
+ if (!intersection.has_no_area() && right_rect.size.x < rect.size.x) {
+ rect.size.x = intersection.position.x - rect.position.x;
+ }
+ }
+
+ Rect2i top_rect(pos.x + top_start_x, pos.y, top_end_x - top_start_x, top);
+ if (top_rect.size.y > 0) {
+ Rect2i intersection = rect.intersection(top_rect);
+ if (!intersection.has_no_area() && intersection.size.y < rect.size.y) {
+ rect.position.y = top_rect.size.y;
+ rect.size.y = rect.size.y - intersection.size.y;
+ }
+ }
+
+ Rect2i bottom_rect(pos.x + bottom_start_x, pos.y + size.y - bottom, bottom_end_x - bottom_start_x, bottom);
+ if (bottom_rect.size.y > 0) {
+ Rect2i intersection = rect.intersection(bottom_rect);
+ if (!intersection.has_no_area() && right_rect.size.y < rect.size.y) {
+ rect.size.y = intersection.position.y - rect.position.y;
+ }
+ }
+ }
+ if (strut_data) {
+ XFree(strut_data);
+ }
+ }
+
+ // Restore default error handler.
+ XSetErrorHandler(oldHandler);
+ }
+ }
+ }
+ if (clients_data) {
+ XFree(clients_data);
+ }
+ }
+ }
+
+ // Single screen or fallback for multi screen.
+ if (use_simple_method) {
+ // Get desktop available size from the global work area.
+ Atom workarea_prop = XInternAtom(x11_display, "_NET_WORKAREA", True);
+ if (workarea_prop != None) {
+ unsigned long workarea_len = 0;
+ unsigned char *workarea_data = nullptr;
+ if (XGetWindowProperty(x11_display, x11_window, workarea_prop, 0, LONG_MAX, False, XA_CARDINAL, &type, &format, &workarea_len, &remaining, &workarea_data) == Success) {
+ if ((format == 32) && (workarea_len >= ((desktop_index + 1) * 4)) && workarea_data) {
+ long *rect_data = (long *)workarea_data;
+ int data_offset = desktop_index * 4;
+ Rect2i workarea_rect;
+ workarea_rect.position.x = rect_data[data_offset];
+ workarea_rect.position.y = rect_data[data_offset + 1];
+ workarea_rect.size.x = rect_data[data_offset + 2];
+ workarea_rect.size.y = rect_data[data_offset + 3];
+
+ // Intersect with actual monitor size to get a proper approximation in multi-screen setup.
+ if (!is_multiscreen) {
+ rect = workarea_rect;
+ } else if (rect.intersects(workarea_rect)) {
+ rect = rect.intersection(workarea_rect);
+ }
+ }
+ }
+ if (workarea_data) {
+ XFree(workarea_data);
+ }
+ }
+ }
- Rect2i rect = Rect2i(xsi[p_screen].x_org, xsi[p_screen].y_org, xsi[p_screen].width, xsi[p_screen].height);
- XFree(xsi);
return rect;
}
@@ -837,6 +1154,12 @@ void DisplayServerX11::delete_sub_window(WindowID p_id) {
context_vulkan->window_destroy(p_id);
}
#endif
+#ifdef GLES3_ENABLED
+ if (gl_manager) {
+ gl_manager->window_destroy(p_id);
+ }
+#endif
+
XUnmapWindow(x11_display, wd.x11_window);
XDestroyWindow(x11_display, wd.x11_window);
if (wd.xic) {
@@ -978,22 +1301,38 @@ void DisplayServerX11::window_set_drop_files_callback(const Callable &p_callable
int DisplayServerX11::window_get_current_screen(WindowID p_window) const {
_THREAD_SAFE_METHOD_
- ERR_FAIL_COND_V(!windows.has(p_window), -1);
+ int count = get_screen_count();
+ if (count < 2) {
+ // Early exit with single monitor.
+ return 0;
+ }
+
+ ERR_FAIL_COND_V(!windows.has(p_window), 0);
const WindowData &wd = windows[p_window];
- int x, y;
- Window child;
- XTranslateCoordinates(x11_display, wd.x11_window, DefaultRootWindow(x11_display), 0, 0, &x, &y, &child);
+ const Rect2i window_rect(wd.position, wd.size);
- int count = get_screen_count();
+ // 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++) {
- Point2i pos = screen_get_position(i);
- Size2i size = screen_get_size(i);
- if ((x >= pos.x && x < pos.x + size.width) && (y >= pos.y && y < pos.y + size.height)) {
- return 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 0;
+
+ return screen_index;
+}
+
+void DisplayServerX11::gl_window_make_current(DisplayServer::WindowID p_window_id) {
+#if defined(GLES3_ENABLED)
+ if (gl_manager)
+ gl_manager->window_make_current(p_window_id);
+#endif
}
void DisplayServerX11::window_set_current_screen(int p_screen, WindowID p_window) {
@@ -2069,9 +2408,9 @@ String DisplayServerX11::keyboard_get_layout_name(int p_index) const {
}
Key DisplayServerX11::keyboard_get_keycode_from_physical(Key p_keycode) const {
- unsigned int modifiers = p_keycode & KEY_MODIFIER_MASK;
- unsigned int keycode_no_mod = p_keycode & KEY_CODE_MASK;
- unsigned int xkeycode = KeyMappingX11::get_xlibcode((Key)keycode_no_mod);
+ 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);
if (xkeysym >= 'a' && xkeysym <= 'z') {
xkeysym -= ('a' - 'A');
@@ -2080,7 +2419,7 @@ Key DisplayServerX11::keyboard_get_keycode_from_physical(Key p_keycode) const {
Key key = KeyMappingX11::get_keycode(xkeysym);
// If not found, fallback to QWERTY.
// This should match the behavior of the event pump
- if (key == KEY_NONE) {
+ if (key == Key::NONE) {
return p_keycode;
}
return (Key)(key | modifiers);
@@ -2154,12 +2493,12 @@ void DisplayServerX11::_get_key_modifier_state(unsigned int p_x11_state, Ref<Inp
}
MouseButton DisplayServerX11::_get_mouse_button_state(MouseButton p_x11_button, int p_x11_type) {
- MouseButton mask = MouseButton(1 << (p_x11_button - 1));
+ MouseButton mask = mouse_button_to_mask(p_x11_button);
if (p_x11_type == ButtonPress) {
last_button_state |= mask;
} else {
- last_button_state &= MouseButton(~mask);
+ last_button_state &= ~mask;
}
return last_button_state;
@@ -2226,9 +2565,9 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event,
if (status == XLookupChars) {
bool keypress = xkeyevent->type == KeyPress;
Key keycode = KeyMappingX11::get_keycode(keysym_keycode);
- unsigned int physical_keycode = KeyMappingX11::get_scancode(xkeyevent->keycode);
+ Key physical_keycode = KeyMappingX11::get_scancode(xkeyevent->keycode);
- if (keycode >= 'a' && keycode <= 'z') {
+ if (keycode >= Key::A + 32 && keycode <= Key::Z + 32) {
keycode -= 'a' - 'A';
}
@@ -2237,11 +2576,11 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event,
for (int i = 0; i < tmp.length(); i++) {
Ref<InputEventKey> k;
k.instantiate();
- if (physical_keycode == 0 && keycode == 0 && tmp[i] == 0) {
+ if (physical_keycode == Key::NONE && keycode == Key::NONE && tmp[i] == 0) {
continue;
}
- if (keycode == 0) {
+ if (keycode == Key::NONE) {
keycode = (Key)physical_keycode;
}
@@ -2258,10 +2597,10 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event,
k->set_echo(false);
- if (k->get_keycode() == KEY_BACKTAB) {
+ if (k->get_keycode() == Key::BACKTAB) {
//make it consistent across platforms.
- k->set_keycode(KEY_TAB);
- k->set_physical_keycode(KEY_TAB);
+ k->set_keycode(Key::TAB);
+ k->set_physical_keycode(Key::TAB);
k->set_shift_pressed(true);
}
@@ -2290,7 +2629,7 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event,
// keysym, so it works in all platforms the same.
Key keycode = KeyMappingX11::get_keycode(keysym_keycode);
- unsigned int physical_keycode = KeyMappingX11::get_scancode(xkeyevent->keycode);
+ Key physical_keycode = KeyMappingX11::get_scancode(xkeyevent->keycode);
/* Phase 3, obtain a unicode character from the keysym */
@@ -2310,11 +2649,11 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event,
bool keypress = xkeyevent->type == KeyPress;
- if (physical_keycode == 0 && keycode == KEY_NONE && unicode == 0) {
+ if (physical_keycode == Key::NONE && keycode == Key::NONE && unicode == 0) {
return;
}
- if (keycode == KEY_NONE) {
+ if (keycode == Key::NONE) {
keycode = (Key)physical_keycode;
}
@@ -2377,7 +2716,7 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event,
k->set_pressed(keypress);
- if (keycode >= 'a' && keycode <= 'z') {
+ if (keycode >= Key::A + 32 && keycode <= Key::Z + 32) {
keycode -= int('a' - 'A');
}
@@ -2386,23 +2725,23 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event,
k->set_unicode(unicode);
k->set_echo(p_echo);
- if (k->get_keycode() == KEY_BACKTAB) {
+ if (k->get_keycode() == Key::BACKTAB) {
//make it consistent across platforms.
- k->set_keycode(KEY_TAB);
- k->set_physical_keycode(KEY_TAB);
+ k->set_keycode(Key::TAB);
+ k->set_physical_keycode(Key::TAB);
k->set_shift_pressed(true);
}
//don't set mod state if modifier keys are released by themselves
//else event.is_action() will not work correctly here
if (!k->is_pressed()) {
- if (k->get_keycode() == KEY_SHIFT) {
+ if (k->get_keycode() == Key::SHIFT) {
k->set_shift_pressed(false);
- } else if (k->get_keycode() == KEY_CTRL) {
+ } else if (k->get_keycode() == Key::CTRL) {
k->set_ctrl_pressed(false);
- } else if (k->get_keycode() == KEY_ALT) {
+ } else if (k->get_keycode() == Key::ALT) {
k->set_alt_pressed(false);
- } else if (k->get_keycode() == KEY_META) {
+ } else if (k->get_keycode() == Key::META) {
k->set_meta_pressed(false);
}
}
@@ -2417,7 +2756,7 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event,
Input::get_singleton()->parse_input_event(k);
}
-Atom DisplayServerX11::_process_selection_request_target(Atom p_target, Window p_requestor, Atom p_property) const {
+Atom DisplayServerX11::_process_selection_request_target(Atom p_target, Window p_requestor, Atom p_property, Atom p_selection) const {
if (p_target == XInternAtom(x11_display, "TARGETS", 0)) {
// Request to list all supported targets.
Atom data[9];
@@ -2452,14 +2791,20 @@ Atom DisplayServerX11::_process_selection_request_target(Atom p_target, Window p
0);
return p_property;
} else if (p_target == XInternAtom(x11_display, "UTF8_STRING", 0) ||
- p_target == XInternAtom(x11_display, "COMPOUND_TEXT", 0) ||
- p_target == XInternAtom(x11_display, "TEXT", 0) ||
- p_target == XA_STRING ||
- p_target == XInternAtom(x11_display, "text/plain;charset=utf-8", 0) ||
- p_target == XInternAtom(x11_display, "text/plain", 0)) {
+ p_target == XInternAtom(x11_display, "COMPOUND_TEXT", 0) ||
+ p_target == XInternAtom(x11_display, "TEXT", 0) ||
+ p_target == XA_STRING ||
+ p_target == XInternAtom(x11_display, "text/plain;charset=utf-8", 0) ||
+ p_target == XInternAtom(x11_display, "text/plain", 0)) {
// Directly using internal clipboard because we know our window
// is the owner during a selection request.
- CharString clip = internal_clipboard.utf8();
+ CharString clip;
+ static const char *target_type = "PRIMARY";
+ if (p_selection != None && String(XGetAtomName(x11_display, p_selection)) == target_type) {
+ clip = internal_clipboard_primary.utf8();
+ } else {
+ clip = internal_clipboard.utf8();
+ }
XChangeProperty(x11_display,
p_requestor,
p_property,
@@ -2497,7 +2842,7 @@ void DisplayServerX11::_handle_selection_request_event(XSelectionRequestEvent *p
for (uint64_t i = 0; i < len; i += 2) {
Atom target = targets[i];
Atom &property = targets[i + 1];
- property = _process_selection_request_target(target, p_event->requestor, property);
+ property = _process_selection_request_target(target, p_event->requestor, property, p_event->selection);
}
XChangeProperty(x11_display,
@@ -2515,7 +2860,7 @@ void DisplayServerX11::_handle_selection_request_event(XSelectionRequestEvent *p
}
} else {
// Request for target conversion.
- respond.xselection.property = _process_selection_request_target(p_event->target, p_event->requestor, p_event->property);
+ respond.xselection.property = _process_selection_request_target(p_event->target, p_event->requestor, p_event->property, p_event->selection);
}
respond.xselection.type = SelectionNotify;
@@ -2586,6 +2931,11 @@ void DisplayServerX11::_window_changed(XEvent *event) {
context_vulkan->window_resize(window_id, wd.size.width, wd.size.height);
}
#endif
+#if defined(GLES3_ENABLED)
+ if (gl_manager) {
+ gl_manager->window_resize(window_id, wd.size.width, wd.size.height);
+ }
+#endif
if (!wd.rect_changed_callback.is_null()) {
Rect2i r = new_rect;
@@ -2686,27 +3036,34 @@ void DisplayServerX11::_poll_events() {
{
MutexLock mutex_lock(events_mutex);
- // Non-blocking wait for next event and remove it from the queue.
- XEvent ev;
- while (XCheckIfEvent(x11_display, &ev, _predicate_all_events, nullptr)) {
- // Check if the input manager wants to process the event.
- if (XFilterEvent(&ev, None)) {
- // Event has been filtered by the Input Manager,
- // it has to be ignored and a new one will be received.
- continue;
- }
+ _check_pending_events(polled_events);
+ }
+ }
+}
- // Handle selection request events directly in the event thread, because
- // communication through the x server takes several events sent back and forth
- // and we don't want to block other programs while processing only one each frame.
- if (ev.type == SelectionRequest) {
- _handle_selection_request_event(&(ev.xselectionrequest));
- continue;
- }
+void DisplayServerX11::_check_pending_events(LocalVector<XEvent> &r_events) {
+ // Flush to make sure to gather all pending events.
+ XFlush(x11_display);
- polled_events.push_back(ev);
- }
+ // Non-blocking wait for next event and remove it from the queue.
+ XEvent ev;
+ while (XCheckIfEvent(x11_display, &ev, _predicate_all_events, nullptr)) {
+ // Check if the input manager wants to process the event.
+ if (XFilterEvent(&ev, None)) {
+ // Event has been filtered by the Input Manager,
+ // it has to be ignored and a new one will be received.
+ continue;
+ }
+
+ // Handle selection request events directly in the event thread, because
+ // communication through the x server takes several events sent back and forth
+ // and we don't want to block other programs while processing only one each frame.
+ if (ev.type == SelectionRequest) {
+ _handle_selection_request_event(&(ev.xselectionrequest));
+ continue;
}
+
+ r_events.push_back(ev);
}
}
@@ -2759,6 +3116,9 @@ void DisplayServerX11::process_events() {
MutexLock mutex_lock(events_mutex);
events = polled_events;
polled_events.clear();
+
+ // Check for more pending events to avoid an extra frame delay.
+ _check_pending_events(events);
}
for (uint32_t event_index = 0; event_index < events.size(); ++event_index) {
@@ -2818,7 +3178,7 @@ void DisplayServerX11::process_events() {
if (pen_pressure_range != Vector2()) {
xi.pressure_supported = true;
xi.pressure = (*values - pen_pressure_range[0]) /
- (pen_pressure_range[1] - pen_pressure_range[0]);
+ (pen_pressure_range[1] - pen_pressure_range[0]);
}
}
@@ -2877,10 +3237,7 @@ void DisplayServerX11::process_events() {
xi.last_relative_time = raw_event->time;
} break;
#ifdef TOUCH_ENABLED
- case XI_TouchBegin: // Fall-through
- // Disabled hand-in-hand with the grabbing
- //XIAllowTouchEvents(x11_display, event_data->deviceid, event_data->detail, x11_window, XIAcceptTouch);
-
+ case XI_TouchBegin:
case XI_TouchEnd: {
bool is_begin = event_data->evtype == XI_TouchBegin;
@@ -3112,10 +3469,10 @@ void DisplayServerX11::process_events() {
mb->set_window_id(window_id);
_get_key_modifier_state(event.xbutton.state, mb);
mb->set_button_index((MouseButton)event.xbutton.button);
- if (mb->get_button_index() == MOUSE_BUTTON_RIGHT) {
- mb->set_button_index(MOUSE_BUTTON_MIDDLE);
- } else if (mb->get_button_index() == MOUSE_BUTTON_MIDDLE) {
- mb->set_button_index(MOUSE_BUTTON_RIGHT);
+ if (mb->get_button_index() == MouseButton::RIGHT) {
+ mb->set_button_index(MouseButton::MIDDLE);
+ } else if (mb->get_button_index() == MouseButton::MIDDLE) {
+ mb->set_button_index(MouseButton::RIGHT);
}
mb->set_button_mask(_get_mouse_button_state(mb->get_button_index(), event.xbutton.type));
mb->set_position(Vector2(event.xbutton.x, event.xbutton.y));
@@ -3141,11 +3498,11 @@ void DisplayServerX11::process_events() {
if (diff < 400 && Vector2(last_click_pos).distance_to(Vector2(event.xbutton.x, event.xbutton.y)) < 5) {
last_click_ms = 0;
last_click_pos = Point2i(-100, -100);
- last_click_button_index = -1;
+ last_click_button_index = MouseButton::NONE;
mb->set_double_click(true);
}
- } else if (mb->get_button_index() < 4 || mb->get_button_index() > 7) {
+ } else if (mb->get_button_index() < MouseButton::WHEEL_UP || mb->get_button_index() > MouseButton::WHEEL_RIGHT) {
last_click_button_index = mb->get_button_index();
}
@@ -3278,12 +3635,12 @@ void DisplayServerX11::process_events() {
if (xi.pressure_supported) {
mm->set_pressure(xi.pressure);
} else {
- mm->set_pressure((mouse_get_button_state() & MOUSE_BUTTON_MASK_LEFT) ? 1.0f : 0.0f);
+ mm->set_pressure(bool(mouse_get_button_state() & MouseButton::MASK_LEFT) ? 1.0f : 0.0f);
}
mm->set_tilt(xi.tilt);
_get_key_modifier_state(event.xmotion.state, mm);
- mm->set_button_mask(mouse_get_button_state());
+ mm->set_button_mask((MouseButton)mouse_get_button_state());
mm->set_position(pos);
mm->set_global_position(pos);
Input::get_singleton()->set_mouse_position(pos);
@@ -3328,11 +3685,18 @@ void DisplayServerX11::process_events() {
} break;
case KeyPress:
case KeyRelease: {
+#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);
+ } else {
+ DEBUG_LOG_X11("[%u] KeyRelease window=%lu (%u), keycode=%u, time=%lu \n", frame, event.xkey.window, window_id, event.xkey.keycode, event.xkey.time);
+ }
+#endif
last_timestamp = event.xkey.time;
// key event is a little complex, so
// it will be handled in its own function.
- _handle_key_event(window_id, (XKeyEvent *)&event, events, event_index);
+ _handle_key_event(window_id, &event.xkey, events, event_index);
} break;
case SelectionNotify:
@@ -3455,12 +3819,23 @@ void DisplayServerX11::process_events() {
}
void DisplayServerX11::release_rendering_thread() {
+#if defined(GLES3_ENABLED)
+// gl_manager->release_current();
+#endif
}
void DisplayServerX11::make_rendering_thread() {
+#if defined(GLES3_ENABLED)
+// gl_manager->make_current();
+#endif
}
void DisplayServerX11::swap_buffers() {
+#if defined(GLES3_ENABLED)
+ if (gl_manager) {
+ gl_manager->swap_buffers();
+ }
+#endif
}
void DisplayServerX11::_update_context(WindowData &wd) {
@@ -3602,17 +3977,31 @@ void DisplayServerX11::set_icon(const Ref<Image> &p_icon) {
void DisplayServerX11::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
+
+#if defined(GLES3_ENABLED)
+ if (gl_manager) {
+ gl_manager->set_use_vsync(p_vsync_mode == DisplayServer::VSYNC_ENABLED);
+ }
#endif
}
DisplayServer::VSyncMode DisplayServerX11::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
+#if defined(GLES3_ENABLED)
+ if (gl_manager) {
+ return gl_manager->is_using_vsync() ? DisplayServer::VSYNC_ENABLED : DisplayServer::VSYNC_DISABLED;
+ }
+#endif
+ return DisplayServer::VSYNC_ENABLED;
}
Vector<String> DisplayServerX11::get_rendering_drivers_func() {
@@ -3621,8 +4010,8 @@ Vector<String> DisplayServerX11::get_rendering_drivers_func() {
#ifdef VULKAN_ENABLED
drivers.push_back("vulkan");
#endif
-#ifdef OPENGL_ENABLED
- drivers.push_back("opengl");
+#ifdef GLES3_ENABLED
+ drivers.push_back("opengl3");
#endif
return drivers;
@@ -3631,7 +4020,7 @@ Vector<String> DisplayServerX11::get_rendering_drivers_func() {
DisplayServer *DisplayServerX11::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
DisplayServer *ds = memnew(DisplayServerX11(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error));
if (r_error != OK) {
- OS::get_singleton()->alert("Your video card driver does not support any of the supported Vulkan versions.\n"
+ OS::get_singleton()->alert("Your video card driver does not support any of the supported Vulkan or OpenGL versions.\n"
"Please update your drivers or if you have a very old or integrated GPU, upgrade it.\n"
"If you have updated your graphics drivers recently, try rebooting.",
"Unable to initialize Video driver");
@@ -3707,18 +4096,18 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, V
XSetWindowAttributes new_attr;
new_attr.event_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask |
- ButtonReleaseMask | EnterWindowMask |
- LeaveWindowMask | PointerMotionMask |
- Button1MotionMask |
- Button2MotionMask | Button3MotionMask |
- Button4MotionMask | Button5MotionMask |
- ButtonMotionMask | KeymapStateMask |
- ExposureMask | VisibilityChangeMask |
- StructureNotifyMask |
- SubstructureNotifyMask | SubstructureRedirectMask |
- FocusChangeMask | PropertyChangeMask |
- ColormapChangeMask | OwnerGrabButtonMask |
- im_event_mask;
+ ButtonReleaseMask | EnterWindowMask |
+ LeaveWindowMask | PointerMotionMask |
+ Button1MotionMask |
+ Button2MotionMask | Button3MotionMask |
+ Button4MotionMask | Button5MotionMask |
+ ButtonMotionMask | KeymapStateMask |
+ ExposureMask | VisibilityChangeMask |
+ StructureNotifyMask |
+ SubstructureNotifyMask | SubstructureRedirectMask |
+ FocusChangeMask | PropertyChangeMask |
+ ColormapChangeMask | OwnerGrabButtonMask |
+ im_event_mask;
XChangeWindowAttributes(x11_display, wd.x11_window, CWEventMask, &new_attr);
@@ -3807,6 +4196,12 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, V
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);
+ ERR_FAIL_COND_V_MSG(err != OK, INVALID_WINDOW_ID, "Can't create an OpenGL window");
+ }
+#endif
//set_class_hint(x11_display, wd.x11_window);
XFlush(x11_display);
@@ -3856,7 +4251,7 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
xmbstring = nullptr;
last_click_ms = 0;
- last_click_button_index = -1;
+ last_click_button_index = MouseButton::NONE;
last_click_pos = Point2i(-100, -100);
last_timestamp = 0;
@@ -3988,14 +4383,10 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
xdnd_selection = XInternAtom(x11_display, "XdndSelection", False);
//!!!!!!!!!!!!!!!!!!!!!!!!!!
- //TODO - do Vulkan and GLES2 support checks, driver selection and fallback
+ //TODO - do Vulkan and OpenGL support checks, driver selection and fallback
rendering_driver = p_rendering_driver;
-#ifndef _MSC_VER
-#warning Forcing vulkan rendering driver because OpenGL not implemented yet
-#endif
- rendering_driver = "vulkan";
-
+ bool driver_found = false;
#if defined(VULKAN_ENABLED)
if (rendering_driver == "vulkan") {
context_vulkan = memnew(VulkanContextX11);
@@ -4005,11 +4396,12 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
r_error = ERR_CANT_CREATE;
ERR_FAIL_MSG("Could not initialize Vulkan");
}
+ driver_found = true;
}
#endif
- // Init context and rendering device
-#if defined(OPENGL_ENABLED)
- if (rendering_driver == "opengl_es") {
+ // Initialize context and rendering device.
+#if defined(GLES3_ENABLED)
+ if (rendering_driver == "opengl3") {
if (getenv("DRI_PRIME") == nullptr) {
int use_prime = -1;
@@ -4051,28 +4443,37 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
}
}
- ContextGL_X11::ContextType opengl_api_type = ContextGL_X11::GLES_2_0_COMPATIBLE;
+ GLManager_X11::ContextType opengl_api_type = GLManager_X11::GLES_3_0_COMPATIBLE;
- context_gles2 = memnew(ContextGL_X11(x11_display, x11_window, current_videomode, opengl_api_type));
+ gl_manager = memnew(GLManager_X11(p_resolution, opengl_api_type));
- if (context_gles2->initialize() != OK) {
- memdelete(context_gles2);
- context_gles2 = nullptr;
- ERR_FAIL_V(ERR_UNAVAILABLE);
+ if (gl_manager->initialize() != OK) {
+ memdelete(gl_manager);
+ gl_manager = nullptr;
+ r_error = ERR_UNAVAILABLE;
+ return;
}
+ driver_found = true;
- context_gles2->set_use_vsync(current_videomode.use_vsync);
+ // gl_manager->set_use_vsync(current_videomode.use_vsync);
- if (RasterizerGLES2::is_viable() == OK) {
- RasterizerGLES2::register_config();
- RasterizerGLES2::make_current();
+ if (true) {
+ // if (RasterizerGLES3::is_viable() == OK) {
+ // RasterizerGLES3::register_config();
+ RasterizerGLES3::make_current();
} else {
- memdelete(context_gles2);
- context_gles2 = nullptr;
- ERR_FAIL_V(ERR_UNAVAILABLE);
+ memdelete(gl_manager);
+ gl_manager = nullptr;
+ r_error = ERR_UNAVAILABLE;
+ return;
}
}
#endif
+ if (!driver_found) {
+ r_error = ERR_UNAVAILABLE;
+ 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);
@@ -4088,7 +4489,6 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
}
show_window(main_window);
-//create RenderingDevice if used
#if defined(VULKAN_ENABLED)
if (rendering_driver == "vulkan") {
//temporary
@@ -4099,13 +4499,6 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
}
#endif
- /*
- rendering_server = memnew(RenderingServerDefault);
- if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {
- rendering_server = memnew(RenderingServerWrapMT(rendering_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD));
- }
- */
-
{
//set all event master mask
XIEventMask all_master_event_mask;
@@ -4118,15 +4511,6 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
XISelectEvents(x11_display, DefaultRootWindow(x11_display), &all_master_event_mask, 1);
}
- // Disabled by now since grabbing also blocks mouse events
- // (they are received as extended events instead of standard events)
- /*XIClearMask(xi.touch_event_mask.mask, XI_TouchOwnership);
-
- // Grab touch devices to avoid OS gesture interference
- for (int i = 0; i < xi.touch_devices.size(); ++i) {
- XIGrabDevice(x11_display, xi.touch_devices[i], x11_window, CurrentTime, None, XIGrabModeAsync, XIGrabModeAsync, False, &xi.touch_event_mask);
- }*/
-
cursor_size = XcursorGetDefaultSize(x11_display);
cursor_theme = XcursorGetTheme(x11_display);
@@ -4292,6 +4676,11 @@ DisplayServerX11::~DisplayServerX11() {
context_vulkan->window_destroy(E.key);
}
#endif
+#ifdef GLES3_ENABLED
+ if (rendering_driver == "opengl3") {
+ gl_manager->window_destroy(E.key);
+ }
+#endif
WindowData &wd = E.value;
if (wd.xic) {
@@ -4316,6 +4705,13 @@ DisplayServerX11::~DisplayServerX11() {
}
#endif
+#ifdef GLES3_ENABLED
+ if (gl_manager) {
+ memdelete(gl_manager);
+ gl_manager = nullptr;
+ }
+#endif
+
if (xrandr_handle) {
dlclose(xrandr_handle);
}
diff --git a/platform/linuxbsd/display_server_x11.h b/platform/linuxbsd/display_server_x11.h
index 1887c7105b..3587d587d6 100644
--- a/platform/linuxbsd/display_server_x11.h
+++ b/platform/linuxbsd/display_server_x11.h
@@ -31,6 +31,8 @@
#ifndef DISPLAY_SERVER_X11_H
#define DISPLAY_SERVER_X11_H
+#include "drivers/gles3/rasterizer_platforms.h"
+
#ifdef X11_ENABLED
#include "servers/display_server.h"
@@ -46,8 +48,8 @@
#include "servers/rendering/renderer_compositor.h"
#include "servers/rendering_server.h"
-#if defined(OPENGL_ENABLED)
-#include "context_gl_x11.h"
+#if defined(GLES3_ENABLED)
+#include "gl_manager_x11.h"
#endif
#if defined(VULKAN_ENABLED)
@@ -99,12 +101,12 @@ class DisplayServerX11 : public DisplayServer {
Atom requested;
int xdnd_version;
-#if defined(OPENGL_ENABLED)
- ContextGL_X11 *context_gles2;
+#if defined(GLES3_ENABLED)
+ GLManager_X11 *gl_manager = nullptr;
#endif
#if defined(VULKAN_ENABLED)
- VulkanContextX11 *context_vulkan;
- RenderingDeviceVulkan *rendering_device_vulkan;
+ VulkanContextX11 *context_vulkan = nullptr;
+ RenderingDeviceVulkan *rendering_device_vulkan = nullptr;
#endif
#if defined(DBUS_ENABLED)
@@ -155,6 +157,7 @@ class DisplayServerX11 : public DisplayServer {
WindowID _create_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect);
String internal_clipboard;
+ String internal_clipboard_primary;
Window xdnd_source_window;
::Display *x11_display;
char *xmbstring;
@@ -170,8 +173,8 @@ class DisplayServerX11 : public DisplayServer {
bool last_mouse_pos_valid;
Point2i last_click_pos;
uint64_t last_click_ms;
- int last_click_button_index;
- MouseButton last_button_state = MOUSE_BUTTON_NONE;
+ MouseButton last_click_button_index = MouseButton::NONE;
+ MouseButton last_button_state = MouseButton::NONE;
bool app_focused = false;
uint64_t time_since_no_focus = 0;
@@ -196,6 +199,8 @@ class DisplayServerX11 : public DisplayServer {
bool _refresh_device_info();
+ Rect2i _screen_get_rect(int p_screen) const;
+
MouseButton _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();
@@ -205,7 +210,7 @@ class DisplayServerX11 : public DisplayServer {
void _handle_key_event(WindowID p_window, XKeyEvent *p_event, LocalVector<XEvent> &p_events, uint32_t &p_event_index, bool p_echo = false);
- Atom _process_selection_request_target(Atom p_target, Window p_requestor, Atom p_property) const;
+ 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;
String _clipboard_get_impl(Atom p_source, Window x11_window, Atom target) const;
@@ -267,6 +272,7 @@ class DisplayServerX11 : public DisplayServer {
static void _poll_events_thread(void *ud);
bool _wait_for_events() const;
void _poll_events();
+ void _check_pending_events(LocalVector<XEvent> &r_events);
static Bool _predicate_all_events(Display *display, XEvent *event, XPointer arg);
static Bool _predicate_clipboard_selection(Display *display, XEvent *event, XPointer arg);
@@ -290,6 +296,8 @@ public:
virtual void clipboard_set(const String &p_text) override;
virtual String clipboard_get() const override;
+ virtual void clipboard_set_primary(const String &p_text) override;
+ virtual String clipboard_get_primary() const override;
virtual int get_screen_count() const override;
virtual Point2i screen_get_position(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
@@ -331,6 +339,7 @@ public:
virtual void window_set_max_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID) override;
virtual Size2i window_get_max_size(WindowID p_window = MAIN_WINDOW_ID) const override;
+ virtual void gl_window_make_current(DisplayServer::WindowID p_window_id) override;
virtual void window_set_transient(WindowID p_window, WindowID p_parent) override;
diff --git a/platform/linuxbsd/freedesktop_screensaver.cpp b/platform/linuxbsd/freedesktop_screensaver.cpp
index a6a3b27d76..3973d43d49 100644
--- a/platform/linuxbsd/freedesktop_screensaver.cpp
+++ b/platform/linuxbsd/freedesktop_screensaver.cpp
@@ -50,6 +50,7 @@ void FreeDesktopScreenSaver::inhibit() {
DBusConnection *bus = dbus_bus_get(DBUS_BUS_SESSION, &error);
if (dbus_error_is_set(&error)) {
+ dbus_error_free(&error);
unsupported = true;
return;
}
@@ -72,6 +73,7 @@ void FreeDesktopScreenSaver::inhibit() {
DBusMessage *reply = dbus_connection_send_with_reply_and_block(bus, message, 50, &error);
dbus_message_unref(message);
if (dbus_error_is_set(&error)) {
+ dbus_error_free(&error);
dbus_connection_unref(bus);
unsupported = false;
return;
@@ -96,6 +98,7 @@ void FreeDesktopScreenSaver::uninhibit() {
DBusConnection *bus = dbus_bus_get(DBUS_BUS_SESSION, &error);
if (dbus_error_is_set(&error)) {
+ dbus_error_free(&error);
unsupported = true;
return;
}
@@ -110,6 +113,7 @@ void FreeDesktopScreenSaver::uninhibit() {
DBusMessage *reply = dbus_connection_send_with_reply_and_block(bus, message, 50, &error);
if (dbus_error_is_set(&error)) {
+ dbus_error_free(&error);
dbus_connection_unref(bus);
unsupported = true;
return;
diff --git a/platform/linuxbsd/gl_manager_x11.cpp b/platform/linuxbsd/gl_manager_x11.cpp
new file mode 100644
index 0000000000..e069e92ee6
--- /dev/null
+++ b/platform/linuxbsd/gl_manager_x11.cpp
@@ -0,0 +1,384 @@
+/*************************************************************************/
+/* gl_manager_x11.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "gl_manager_x11.h"
+
+#ifdef X11_ENABLED
+#if defined(GLES3_ENABLED)
+
+#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 *);
+
+struct GLManager_X11_Private {
+ ::GLXContext glx_context;
+};
+
+GLManager_X11::GLDisplay::~GLDisplay() {
+ if (context) {
+ //release_current();
+ glXDestroyContext(x11_display, context->glx_context);
+ memdelete(context);
+ context = nullptr;
+ }
+}
+
+static bool ctxErrorOccurred = false;
+static int ctxErrorHandler(Display *dpy, XErrorEvent *ev) {
+ ctxErrorOccurred = true;
+ return 0;
+}
+
+int GLManager_X11::_find_or_create_display(Display *p_x11_display) {
+ for (unsigned int n = 0; n < _displays.size(); n++) {
+ const GLDisplay &d = _displays[n];
+ if (d.x11_display == p_x11_display)
+ return n;
+ }
+
+ // create
+ GLDisplay d_temp;
+ d_temp.x11_display = p_x11_display;
+ _displays.push_back(d_temp);
+ int new_display_id = _displays.size() - 1;
+
+ // create context
+ GLDisplay &d = _displays[new_display_id];
+
+ d.context = memnew(GLManager_X11_Private);
+ ;
+ d.context->glx_context = 0;
+
+ //Error err = _create_context(d);
+ _create_context(d);
+ return new_display_id;
+}
+
+Error GLManager_X11::_create_context(GLDisplay &gl_display) {
+ // some aliases
+ ::Display *x11_display = gl_display.x11_display;
+
+ //const char *extensions = glXQueryExtensionsString(x11_display, DefaultScreen(x11_display));
+
+ GLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = (GLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddress((const GLubyte *)"glXCreateContextAttribsARB");
+
+ ERR_FAIL_COND_V(!glXCreateContextAttribsARB, ERR_UNCONFIGURED);
+
+ static int visual_attribs[] = {
+ GLX_RENDER_TYPE, GLX_RGBA_BIT,
+ GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
+ GLX_DOUBLEBUFFER, true,
+ GLX_RED_SIZE, 1,
+ GLX_GREEN_SIZE, 1,
+ GLX_BLUE_SIZE, 1,
+ GLX_DEPTH_SIZE, 24,
+ None
+ };
+
+ static int visual_attribs_layered[] = {
+ GLX_RENDER_TYPE, GLX_RGBA_BIT,
+ GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
+ GLX_DOUBLEBUFFER, true,
+ GLX_RED_SIZE, 8,
+ GLX_GREEN_SIZE, 8,
+ GLX_BLUE_SIZE, 8,
+ GLX_ALPHA_SIZE, 8,
+ GLX_DEPTH_SIZE, 24,
+ None
+ };
+
+ int fbcount;
+ GLXFBConfig fbconfig = 0;
+ XVisualInfo *vi = nullptr;
+
+ gl_display.x_swa.event_mask = StructureNotifyMask;
+ gl_display.x_swa.border_pixel = 0;
+ gl_display.x_valuemask = CWBorderPixel | CWColormap | CWEventMask;
+
+ if (OS::get_singleton()->is_layered_allowed()) {
+ GLXFBConfig *fbc = glXChooseFBConfig(x11_display, DefaultScreen(x11_display), visual_attribs_layered, &fbcount);
+ ERR_FAIL_COND_V(!fbc, ERR_UNCONFIGURED);
+
+ for (int i = 0; i < fbcount; i++) {
+ vi = (XVisualInfo *)glXGetVisualFromFBConfig(x11_display, fbc[i]);
+ if (!vi)
+ continue;
+
+ XRenderPictFormat *pict_format = XRenderFindVisualFormat(x11_display, vi->visual);
+ if (!pict_format) {
+ XFree(vi);
+ vi = nullptr;
+ continue;
+ }
+
+ fbconfig = fbc[i];
+ if (pict_format->direct.alphaMask > 0) {
+ break;
+ }
+ }
+ XFree(fbc);
+
+ ERR_FAIL_COND_V(!fbconfig, ERR_UNCONFIGURED);
+
+ gl_display.x_swa.background_pixmap = None;
+ gl_display.x_swa.background_pixel = 0;
+ gl_display.x_swa.border_pixmap = None;
+ gl_display.x_valuemask |= CWBackPixel;
+
+ } else {
+ GLXFBConfig *fbc = glXChooseFBConfig(x11_display, DefaultScreen(x11_display), visual_attribs, &fbcount);
+ ERR_FAIL_COND_V(!fbc, ERR_UNCONFIGURED);
+
+ vi = glXGetVisualFromFBConfig(x11_display, fbc[0]);
+
+ fbconfig = fbc[0];
+ XFree(fbc);
+ }
+
+ int (*oldHandler)(Display *, XErrorEvent *) = XSetErrorHandler(&ctxErrorHandler);
+
+ switch (context_type) {
+ case GLES_3_0_COMPATIBLE: {
+ static int context_attribs[] = {
+ GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
+ GLX_CONTEXT_MINOR_VERSION_ARB, 3,
+ GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
+ GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB /*|GLX_CONTEXT_DEBUG_BIT_ARB*/,
+ None
+ };
+
+ gl_display.context->glx_context = glXCreateContextAttribsARB(x11_display, fbconfig, nullptr, true, context_attribs);
+ ERR_FAIL_COND_V(ctxErrorOccurred || !gl_display.context->glx_context, ERR_UNCONFIGURED);
+ } break;
+ }
+
+ gl_display.x_swa.colormap = XCreateColormap(x11_display, RootWindow(x11_display, vi->screen), vi->visual, AllocNone);
+
+ XSync(x11_display, False);
+ XSetErrorHandler(oldHandler);
+
+ // make our own copy of the vi data
+ // for later creating windows using this display
+ if (vi) {
+ gl_display.x_vi = *vi;
+ }
+
+ XFree(vi);
+
+ return OK;
+}
+
+Error GLManager_X11::window_create(DisplayServer::WindowID p_window_id, ::Window p_window, Display *p_display, int p_width, int p_height) {
+ // make sure vector is big enough...
+ // we can mirror the external vector, it is simpler
+ // to keep the IDs identical for fast lookup
+ if (p_window_id >= (int)_windows.size()) {
+ _windows.resize(p_window_id + 1);
+ }
+
+ GLWindow &win = _windows[p_window_id];
+ win.in_use = true;
+ win.window_id = p_window_id;
+ win.width = p_width;
+ win.height = p_height;
+ win.x11_window = p_window;
+ win.gldisplay_id = _find_or_create_display(p_display);
+
+ // the display could be invalid .. check NYI
+ GLDisplay &gl_display = _displays[win.gldisplay_id];
+ //const XVisualInfo &vi = gl_display.x_vi;
+ //XSetWindowAttributes &swa = gl_display.x_swa;
+ ::Display *x11_display = gl_display.x11_display;
+ ::Window &x11_window = win.x11_window;
+
+ if (!glXMakeCurrent(x11_display, x11_window, gl_display.context->glx_context)) {
+ ERR_PRINT("glXMakeCurrent failed");
+ }
+
+ _internal_set_current_window(&win);
+
+ return OK;
+}
+
+void GLManager_X11::_internal_set_current_window(GLWindow *p_win) {
+ _current_window = p_win;
+
+ // quick access to x info
+ _x_windisp.x11_window = _current_window->x11_window;
+ const GLDisplay &disp = get_current_display();
+ _x_windisp.x11_display = disp.x11_display;
+}
+
+void GLManager_X11::window_resize(DisplayServer::WindowID p_window_id, int p_width, int p_height) {
+ get_window(p_window_id).width = p_width;
+ get_window(p_window_id).height = p_height;
+}
+
+void GLManager_X11::window_destroy(DisplayServer::WindowID p_window_id) {
+ GLWindow &win = get_window(p_window_id);
+ win.in_use = false;
+
+ if (_current_window == &win) {
+ _current_window = nullptr;
+ _x_windisp.x11_display = nullptr;
+ _x_windisp.x11_window = -1;
+ }
+}
+
+void GLManager_X11::release_current() {
+ if (!_current_window)
+ return;
+ glXMakeCurrent(_x_windisp.x11_display, None, nullptr);
+}
+
+void GLManager_X11::window_make_current(DisplayServer::WindowID p_window_id) {
+ if (p_window_id == -1)
+ return;
+
+ GLWindow &win = _windows[p_window_id];
+ if (!win.in_use)
+ return;
+
+ // noop
+ if (&win == _current_window)
+ return;
+
+ const GLDisplay &disp = get_display(win.gldisplay_id);
+
+ glXMakeCurrent(disp.x11_display, win.x11_window, disp.context->glx_context);
+
+ _internal_set_current_window(&win);
+}
+
+void GLManager_X11::make_current() {
+ if (!_current_window)
+ return;
+ if (!_current_window->in_use) {
+ WARN_PRINT("current window not in use!");
+ return;
+ }
+ const GLDisplay &disp = get_current_display();
+ glXMakeCurrent(_x_windisp.x11_display, _x_windisp.x11_window, disp.context->glx_context);
+}
+
+void GLManager_X11::swap_buffers() {
+ // NO NEED TO CALL SWAP BUFFERS for each window...
+ // see https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glXSwapBuffers.xml
+
+ if (!_current_window)
+ return;
+ if (!_current_window->in_use) {
+ WARN_PRINT("current window not in use!");
+ return;
+ }
+
+ // print_line("\tswap_buffers");
+
+ // only for debugging without drawing anything
+ // glClearColor(Math::randf(), 0, 1, 1);
+ //glClear(GL_COLOR_BUFFER_BIT);
+
+ //const GLDisplay &disp = get_current_display();
+ glXSwapBuffers(_x_windisp.x11_display, _x_windisp.x11_window);
+}
+
+Error GLManager_X11::initialize() {
+ 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) {
+ p_use = true;
+ }
+
+ // we need an active window to get a display to set the vsync
+ if (!_current_window)
+ return;
+ 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) {
+ glXSwapIntervalMESA(val);
+ } else if (glXSwapIntervalSGI) {
+ glXSwapIntervalSGI(val);
+ } else if (glXSwapIntervalEXT) {
+ GLXDrawable drawable = glXGetCurrentDrawable();
+ glXSwapIntervalEXT(disp.x11_display, drawable, val);
+ } else
+ return;
+ use_vsync = p_use;
+}
+
+bool GLManager_X11::is_using_vsync() const {
+ return use_vsync;
+}
+
+GLManager_X11::GLManager_X11(const Vector2i &p_size, ContextType p_context_type) {
+ context_type = p_context_type;
+
+ double_buffer = false;
+ direct_render = false;
+ glx_minor = glx_major = 0;
+ use_vsync = false;
+ _current_window = nullptr;
+}
+
+GLManager_X11::~GLManager_X11() {
+ release_current();
+}
+
+#endif
+#endif
diff --git a/platform/linuxbsd/context_gl_x11.h b/platform/linuxbsd/gl_manager_x11.h
index d089886f4d..fa2c8a9c84 100644
--- a/platform/linuxbsd/context_gl_x11.h
+++ b/platform/linuxbsd/gl_manager_x11.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* context_gl_x11.h */
+/* gl_manager_x11.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,53 +28,103 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef CONTEXT_GL_X11_H
-#define CONTEXT_GL_X11_H
+#ifndef GL_MANAGER_X11_H
+#define GL_MANAGER_X11_H
#ifdef X11_ENABLED
-#if defined(OPENGL_ENABLED)
+#include "drivers/gles3/rasterizer_platforms.h"
+
+#ifdef GLES3_ENABLED
#include "core/os/os.h"
+#include "core/templates/local_vector.h"
+#include "servers/display_server.h"
#include <X11/Xlib.h>
#include <X11/extensions/Xrender.h>
-struct ContextGL_X11_Private;
+struct GLManager_X11_Private;
-class ContextGL_X11 {
+class GLManager_X11 {
public:
enum ContextType {
- GLES_2_0_COMPATIBLE,
+ GLES_3_0_COMPATIBLE,
};
private:
- ContextGL_X11_Private *p;
- OS::VideoMode default_video_mode;
- ::Display *x11_display;
- ::Window &x11_window;
+ // any data specific to the window
+ struct GLWindow {
+ GLWindow() { in_use = false; }
+ bool in_use;
+
+ // the external ID .. should match the GL window number .. unused I think
+ DisplayServer::WindowID window_id;
+ int width;
+ int height;
+ ::Window x11_window;
+ int gldisplay_id;
+ };
+
+ struct GLDisplay {
+ GLDisplay() { context = nullptr; }
+ ~GLDisplay();
+ GLManager_X11_Private *context;
+ ::Display *x11_display;
+ XVisualInfo x_vi;
+ XSetWindowAttributes x_swa;
+ unsigned long x_valuemask;
+ };
+
+ // just for convenience, window and display struct
+ struct XWinDisp {
+ ::Window x11_window;
+ ::Display *x11_display;
+ } _x_windisp;
+
+ LocalVector<GLWindow> _windows;
+ LocalVector<GLDisplay> _displays;
+
+ GLWindow *_current_window;
+
+ void _internal_set_current_window(GLWindow *p_win);
+
+ GLWindow &get_window(unsigned int id) { return _windows[id]; }
+ const GLWindow &get_window(unsigned int id) const { return _windows[id]; }
+
+ const GLDisplay &get_current_display() const { return _displays[_current_window->gldisplay_id]; }
+ const GLDisplay &get_display(unsigned int id) { return _displays[id]; }
+
bool double_buffer;
bool direct_render;
int glx_minor, glx_major;
bool use_vsync;
ContextType context_type;
+private:
+ int _find_or_create_display(Display *p_x11_display);
+ Error _create_context(GLDisplay &gl_display);
+
public:
+ 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);
+
void release_current();
void make_current();
void swap_buffers();
- int get_window_width();
- int get_window_height();
+
+ void window_make_current(DisplayServer::WindowID p_window_id);
Error initialize();
void set_use_vsync(bool p_use);
bool is_using_vsync() const;
- ContextGL_X11(::Display *p_x11_display, ::Window &p_x11_window, const OS::VideoMode &p_default_video_mode, ContextType p_context_type);
- ~ContextGL_X11();
+ GLManager_X11(const Vector2i &p_size, ContextType p_context_type);
+ ~GLManager_X11();
};
-#endif
+#endif // GLES3_ENABLED
+#endif // X11_ENABLED
-#endif
-#endif
+#endif // GL_MANAGER_X11_H
diff --git a/platform/linuxbsd/joypad_linux.cpp b/platform/linuxbsd/joypad_linux.cpp
index 8b6dbc4c20..55cc21cc6c 100644
--- a/platform/linuxbsd/joypad_linux.cpp
+++ b/platform/linuxbsd/joypad_linux.cpp
@@ -59,7 +59,7 @@ JoypadLinux::Joypad::~Joypad() {
}
void JoypadLinux::Joypad::reset() {
- dpad = 0;
+ dpad = HatMask::CENTER;
fd = -1;
Input::JoyAxisValue jx;
@@ -253,7 +253,7 @@ void JoypadLinux::close_joypad(int p_id) {
if (joy.fd != -1) {
close(joy.fd);
joy.fd = -1;
- attached_devices.remove(attached_devices.find(joy.devpath));
+ attached_devices.remove_at(attached_devices.find(joy.devpath));
input->joy_connection_changed(p_id, false, "");
};
}
@@ -484,12 +484,12 @@ void JoypadLinux::process_joypads() {
case ABS_HAT0X:
if (ev.value != 0) {
if (ev.value < 0) {
- joy->dpad = (HatMask)((joy->dpad | HatMask::HAT_MASK_LEFT) & ~HatMask::HAT_MASK_RIGHT);
+ joy->dpad = (HatMask)((joy->dpad | HatMask::LEFT) & ~HatMask::RIGHT);
} else {
- joy->dpad = (HatMask)((joy->dpad | HatMask::HAT_MASK_RIGHT) & ~HatMask::HAT_MASK_LEFT);
+ joy->dpad = (HatMask)((joy->dpad | HatMask::RIGHT) & ~HatMask::LEFT);
}
} else {
- joy->dpad &= ~(HatMask::HAT_MASK_LEFT | HatMask::HAT_MASK_RIGHT);
+ joy->dpad &= ~(HatMask::LEFT | HatMask::RIGHT);
}
input->joy_hat(i, (HatMask)joy->dpad);
@@ -498,12 +498,12 @@ void JoypadLinux::process_joypads() {
case ABS_HAT0Y:
if (ev.value != 0) {
if (ev.value < 0) {
- joy->dpad = (HatMask)((joy->dpad | HatMask::HAT_MASK_UP) & ~HatMask::HAT_MASK_DOWN);
+ joy->dpad = (HatMask)((joy->dpad | HatMask::UP) & ~HatMask::DOWN);
} else {
- joy->dpad = (HatMask)((joy->dpad | HatMask::HAT_MASK_DOWN) & ~HatMask::HAT_MASK_UP);
+ joy->dpad = (HatMask)((joy->dpad | HatMask::DOWN) & ~HatMask::UP);
}
} else {
- joy->dpad &= ~(HatMask::HAT_MASK_UP | HatMask::HAT_MASK_DOWN);
+ joy->dpad &= ~(HatMask::UP | HatMask::DOWN);
}
input->joy_hat(i, (HatMask)joy->dpad);
diff --git a/platform/linuxbsd/joypad_linux.h b/platform/linuxbsd/joypad_linux.h
index 177d7a51ce..12b9046d64 100644
--- a/platform/linuxbsd/joypad_linux.h
+++ b/platform/linuxbsd/joypad_linux.h
@@ -56,7 +56,7 @@ private:
Input::JoyAxisValue curr_axis[MAX_ABS];
int key_map[MAX_KEY];
int abs_map[MAX_ABS];
- int dpad = 0;
+ HatMask dpad = HatMask::CENTER;
int fd = -1;
String devpath;
diff --git a/platform/linuxbsd/key_mapping_x11.cpp b/platform/linuxbsd/key_mapping_x11.cpp
index 829feda40a..16c2392859 100644
--- a/platform/linuxbsd/key_mapping_x11.cpp
+++ b/platform/linuxbsd/key_mapping_x11.cpp
@@ -40,266 +40,266 @@ struct _XTranslatePair {
static _XTranslatePair _xkeysym_to_keycode[] = {
// misc keys
- { 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_DELETE },
- { XK_Clear, 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_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 },
+ { 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 but with numlock
- { XK_KP_Insert, KEY_KP_0 },
- { XK_KP_End, KEY_KP_1 },
- { XK_KP_Down, KEY_KP_2 },
- { XK_KP_Page_Down, KEY_KP_3 },
- { XK_KP_Left, KEY_KP_4 },
- { XK_KP_Begin, KEY_KP_5 },
- { XK_KP_Right, KEY_KP_6 },
- { XK_KP_Home, KEY_KP_7 },
- { XK_KP_Up, KEY_KP_8 },
- { XK_KP_Page_Up, KEY_KP_9 },
- { 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_KP_Insert, Key::KP_0 },
+ { XK_KP_End, Key::KP_1 },
+ { XK_KP_Down, Key::KP_2 },
+ { XK_KP_Page_Down, Key::KP_3 },
+ { XK_KP_Left, Key::KP_4 },
+ { XK_KP_Begin, Key::KP_5 },
+ { XK_KP_Right, Key::KP_6 },
+ { XK_KP_Home, Key::KP_7 },
+ { XK_KP_Up, Key::KP_8 },
+ { XK_KP_Page_Up, Key::KP_9 },
+ { 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 },
// 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 },
+ { 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 },
// launch keys
- { XF86XK_Mail, KEY_LAUNCHMAIL },
- { XF86XK_MyComputer, KEY_LAUNCH0 },
- { XF86XK_Calculator, KEY_LAUNCH1 },
- { XF86XK_Standby, KEY_STANDBY },
+ { XF86XK_Mail, Key::LAUNCHMAIL },
+ { XF86XK_MyComputer, Key::LAUNCH0 },
+ { XF86XK_Calculator, Key::LAUNCH1 },
+ { XF86XK_Standby, Key::STANDBY },
- { 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 },
+ { 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 }
+ { 0, Key::NONE }
};
struct _TranslatePair {
- unsigned int keysym;
+ Key keysym;
unsigned int keycode;
};
static _TranslatePair _scancode_to_keycode[] = {
- { KEY_ESCAPE, 0x09 },
- { KEY_1, 0x0A },
- { KEY_2, 0x0B },
- { KEY_3, 0x0C },
- { KEY_4, 0x0D },
- { KEY_5, 0x0E },
- { KEY_6, 0x0F },
- { KEY_7, 0x10 },
- { KEY_8, 0x11 },
- { KEY_9, 0x12 },
- { 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_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_UNKNOWN, 0 }
+ { 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::UNKNOWN, 0 }
};
-unsigned int KeyMappingX11::get_scancode(unsigned int p_code) {
- unsigned int keycode = KEY_UNKNOWN;
- for (int i = 0; _scancode_to_keycode[i].keysym != KEY_UNKNOWN; i++) {
+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;
@@ -309,9 +309,9 @@ unsigned int KeyMappingX11::get_scancode(unsigned int p_code) {
return keycode;
}
-unsigned int KeyMappingX11::get_xlibcode(unsigned int p_keysym) {
+unsigned int KeyMappingX11::get_xlibcode(Key p_keysym) {
unsigned int code = 0;
- for (int i = 0; _scancode_to_keycode[i].keysym != KEY_UNKNOWN; i++) {
+ 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;
@@ -335,13 +335,13 @@ Key KeyMappingX11::get_keycode(KeySym p_keysym) {
}
}
- return KEY_NONE;
+ return Key::NONE;
}
KeySym KeyMappingX11::get_keysym(Key p_code) {
// kinda bruteforce.. could optimize.
- if (p_code < 0x100) { // Latin 1, maps 1-1
+ if (p_code < Key::END_LATIN1) { // Latin 1, maps 1-1
return (KeySym)p_code;
}
@@ -352,7 +352,7 @@ KeySym KeyMappingX11::get_keysym(Key p_code) {
}
}
- return (KeySym)KEY_NONE;
+ return (KeySym)Key::NONE;
}
/***** UNICODE CONVERSION ******/
diff --git a/platform/linuxbsd/key_mapping_x11.h b/platform/linuxbsd/key_mapping_x11.h
index d4f1554671..5f61197abe 100644
--- a/platform/linuxbsd/key_mapping_x11.h
+++ b/platform/linuxbsd/key_mapping_x11.h
@@ -45,11 +45,11 @@ class KeyMappingX11 {
public:
static Key get_keycode(KeySym p_keysym);
- static unsigned int get_xlibcode(unsigned int p_keysym);
- static unsigned int get_scancode(unsigned int p_code);
+ 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);
};
-#endif
+#endif // KEY_MAPPING_X11_H
diff --git a/platform/linuxbsd/platform_config.h b/platform/linuxbsd/platform_config.h
index 3195d08935..aa78b48bb0 100644
--- a/platform/linuxbsd/platform_config.h
+++ b/platform/linuxbsd/platform_config.h
@@ -43,3 +43,5 @@
#define PTHREAD_BSD_SET_NAME
#endif
#endif
+
+#define OPENGL_INCLUDE_H "thirdparty/glad/glad/glad.h"
diff --git a/platform/osx/SCsub b/platform/osx/SCsub
index 46c13d8550..8ba106d1c2 100644
--- a/platform/osx/SCsub
+++ b/platform/osx/SCsub
@@ -13,7 +13,7 @@ files = [
"dir_access_osx.mm",
"joypad_osx.cpp",
"vulkan_context_osx.mm",
- "context_gl_osx.mm",
+ "gl_manager_osx.mm",
]
prog = env.add_program("#bin/godot", files)
diff --git a/platform/osx/context_gl_osx.mm b/platform/osx/context_gl_osx.mm
deleted file mode 100644
index 88db1a296e..0000000000
--- a/platform/osx/context_gl_osx.mm
+++ /dev/null
@@ -1,161 +0,0 @@
-/*************************************************************************/
-/* context_gl_osx.mm */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "context_gl_osx.h"
-
-#if defined(OPENGL_ENABLED) || defined(GLES_ENABLED)
-
-void ContextGL_OSX::release_current() {
- [NSOpenGLContext clearCurrentContext];
-}
-
-void ContextGL_OSX::make_current() {
- [context makeCurrentContext];
-}
-
-void ContextGL_OSX::update() {
- [context update];
-}
-
-void ContextGL_OSX::set_opacity(GLint p_opacity) {
- [context setValues:&p_opacity forParameter:NSOpenGLCPSurfaceOpacity];
-}
-
-int ContextGL_OSX::get_window_width() {
- return OS::get_singleton()->get_video_mode().width;
-}
-
-int ContextGL_OSX::get_window_height() {
- return OS::get_singleton()->get_video_mode().height;
-}
-
-void ContextGL_OSX::swap_buffers() {
- [context flushBuffer];
-}
-
-void ContextGL_OSX::set_use_vsync(bool p_use) {
- CGLContextObj ctx = CGLGetCurrentContext();
- if (ctx) {
- GLint swapInterval = p_use ? 1 : 0;
- CGLSetParameter(ctx, kCGLCPSwapInterval, &swapInterval);
- use_vsync = p_use;
- }
-}
-
-bool ContextGL_OSX::is_using_vsync() const {
- return use_vsync;
-}
-
-Error ContextGL_OSX::initialize() {
- framework = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl"));
- ERR_FAIL_COND_V(!framework, ERR_CANT_CREATE);
-
- unsigned int attributeCount = 0;
-
- // OS X needs non-zero color size, so set reasonable values
- int colorBits = 32;
-
- // Fail if a robustness strategy was requested
-
-#define ADD_ATTR(x) \
- { attributes[attributeCount++] = x; }
-#define ADD_ATTR2(x, y) \
- { \
- ADD_ATTR(x); \
- ADD_ATTR(y); \
- }
-
- // Arbitrary array size here
- NSOpenGLPixelFormatAttribute attributes[40];
-
- ADD_ATTR(NSOpenGLPFADoubleBuffer);
- ADD_ATTR(NSOpenGLPFAClosestPolicy);
-
- if (!opengl_3_context) {
- ADD_ATTR2(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersionLegacy);
- } else {
- //we now need OpenGL 3 or better, maybe even change this to 3_3Core ?
- ADD_ATTR2(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core);
- }
-
- ADD_ATTR2(NSOpenGLPFAColorSize, colorBits);
-
- /*
- if (fbconfig->alphaBits > 0)
- ADD_ATTR2(NSOpenGLPFAAlphaSize, fbconfig->alphaBits);
-*/
-
- ADD_ATTR2(NSOpenGLPFADepthSize, 24);
-
- ADD_ATTR2(NSOpenGLPFAStencilSize, 8);
-
- /*
- if (fbconfig->stereo)
- ADD_ATTR(NSOpenGLPFAStereo);
-*/
-
- /*
- if (fbconfig->samples > 0) {
- ADD_ATTR2(NSOpenGLPFASampleBuffers, 1);
- ADD_ATTR2(NSOpenGLPFASamples, fbconfig->samples);
- }
-*/
-
- // NOTE: All NSOpenGLPixelFormats on the relevant cards support sRGB
- // framebuffer, so there's no need (and no way) to request it
-
- ADD_ATTR(0);
-
-#undef ADD_ATTR
-#undef ADD_ATTR2
-
- pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
- ERR_FAIL_COND_V(pixelFormat == nil, ERR_CANT_CREATE);
-
- context = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil];
-
- ERR_FAIL_COND_V(context == nil, ERR_CANT_CREATE);
-
- [context setView:window_view];
-
- [context makeCurrentContext];
-
- return OK;
-}
-
-ContextGL_OSX::ContextGL_OSX(id p_view, bool p_opengl_3_context) {
- opengl_3_context = p_opengl_3_context;
- window_view = p_view;
- use_vsync = false;
-}
-
-ContextGL_OSX::~ContextGL_OSX() {}
-
-#endif
diff --git a/platform/osx/crash_handler_osx.mm b/platform/osx/crash_handler_osx.mm
index 31228b10b4..57bca7a5b9 100644
--- a/platform/osx/crash_handler_osx.mm
+++ b/platform/osx/crash_handler_osx.mm
@@ -134,8 +134,13 @@ static void handle_crash(int sig) {
args.push_back("-o");
args.push_back(_execpath);
+#if defined(__x86_64) || defined(__x86_64__) || defined(__amd64__)
args.push_back("-arch");
args.push_back("x86_64");
+#elif defined(__aarch64__)
+ args.push_back("-arch");
+ args.push_back("arm64");
+#endif
args.push_back("-l");
snprintf(str, 1024, "%p", load_addr);
args.push_back(str);
@@ -146,7 +151,7 @@ static void handle_crash(int sig) {
String out = "";
Error err = OS::get_singleton()->execute(String("atos"), args, &out, &ret);
if (err == OK && out.substr(0, 2) != "0x") {
- out.erase(out.length() - 1, 1);
+ out = out.substr(0, out.length() - 1);
output = out;
}
}
diff --git a/platform/osx/detect.py b/platform/osx/detect.py
index 6b25daf05d..f5c7731395 100644
--- a/platform/osx/detect.py
+++ b/platform/osx/detect.py
@@ -31,6 +31,7 @@ def get_opts():
BoolVariable("use_ubsan", "Use LLVM/GCC compiler undefined behavior sanitizer (UBSAN)", False),
BoolVariable("use_asan", "Use LLVM/GCC compiler address sanitizer (ASAN)", False),
BoolVariable("use_tsan", "Use LLVM/GCC compiler thread sanitizer (TSAN)", False),
+ BoolVariable("use_coverage", "Use instrumentation codes in the binary (e.g. for code coverage)", False),
]
@@ -57,13 +58,11 @@ def configure(env):
env.Prepend(CCFLAGS=["-O2"])
elif env["optimize"] == "size": # optimize for size
env.Prepend(CCFLAGS=["-Os"])
- env.Prepend(CPPDEFINES=["DEBUG_ENABLED"])
if env["debug_symbols"]:
env.Prepend(CCFLAGS=["-g2"])
elif env["target"] == "debug":
env.Prepend(CCFLAGS=["-g3"])
- env.Prepend(CPPDEFINES=["DEBUG_ENABLED"])
env.Prepend(LINKFLAGS=["-Xlinker", "-no_deduplicate"])
## Architecture
@@ -83,7 +82,7 @@ def configure(env):
env.Append(CCFLAGS=["-arch", "arm64", "-mmacosx-version-min=10.15"])
env.Append(LINKFLAGS=["-arch", "arm64", "-mmacosx-version-min=10.15"])
else:
- print("Building for macOS 10.12+, platform x86-64.")
+ print("Building for macOS 10.12+, platform x86_64.")
env.Append(CCFLAGS=["-arch", "x86_64", "-mmacosx-version-min=10.12"])
env.Append(LINKFLAGS=["-arch", "x86_64", "-mmacosx-version-min=10.12"])
@@ -96,7 +95,6 @@ def configure(env):
env["AR"] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/llvm-ar"
env["RANLIB"] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/llvm-ranlib"
env["AS"] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/llvm-as"
- env.Append(CPPDEFINES=["__MACPORTS__"]) # hack to fix libvpx MM256_BROADCASTSI128_SI256 define
else:
env["CC"] = "clang"
env["CXX"] = "clang++"
@@ -124,7 +122,6 @@ def configure(env):
env["AR"] = basecmd + "ar"
env["RANLIB"] = basecmd + "ranlib"
env["AS"] = basecmd + "as"
- env.Append(CPPDEFINES=["__MACPORTS__"]) # hack to fix libvpx MM256_BROADCASTSI128_SI256 define
if env["use_ubsan"] or env["use_asan"] or env["use_tsan"]:
env.extra_suffix += "s"
@@ -146,6 +143,10 @@ def configure(env):
env.Append(CCFLAGS=["-fsanitize=thread"])
env.Append(LINKFLAGS=["-fsanitize=thread"])
+ if env["use_coverage"]:
+ env.Append(CCFLAGS=["-ftest-coverage", "-fprofile-arcs"])
+ env.Append(LINKFLAGS=["-ftest-coverage", "-fprofile-arcs"])
+
## Dependencies
if env["builtin_libtheora"]:
@@ -182,10 +183,13 @@ def configure(env):
)
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(LINKFLAGS=["-framework", "OpenGL"])
+
if env["vulkan"]:
env.Append(CPPDEFINES=["VULKAN_ENABLED"])
env.Append(LINKFLAGS=["-framework", "Metal", "-framework", "QuartzCore", "-framework", "IOSurface"])
if not env["use_volk"]:
env.Append(LINKFLAGS=["-L$VULKAN_SDK_PATH/MoltenVK/MoltenVK.xcframework/macos-arm64_x86_64/", "-lMoltenVK"])
-
- # env.Append(CPPDEFINES=['GLES_ENABLED', 'OPENGL_ENABLED'])
diff --git a/platform/osx/display_server_osx.h b/platform/osx/display_server_osx.h
index e8f2858489..3cc0b10c5b 100644
--- a/platform/osx/display_server_osx.h
+++ b/platform/osx/display_server_osx.h
@@ -36,9 +36,8 @@
#include "core/input/input.h"
#include "servers/display_server.h"
-#if defined(OPENGL_ENABLED)
-#include "context_gl_osx.h"
-//TODO - reimplement OpenGLES
+#if defined(GLES3_ENABLED)
+#include "gl_manager_osx.h"
#endif
#if defined(VULKAN_ENABLED)
@@ -64,12 +63,12 @@ public:
NSMenu *_get_dock_menu() const;
void _menu_callback(id p_sender);
-#if defined(OPENGL_ENABLED)
- ContextGL_OSX *context_gles2;
+#if defined(GLES3_ENABLED)
+ GLManager_OSX *gl_manager = nullptr;
#endif
#if defined(VULKAN_ENABLED)
- VulkanContextOSX *context_vulkan;
- RenderingDeviceVulkan *rendering_device_vulkan;
+ VulkanContextOSX *context_vulkan = nullptr;
+ RenderingDeviceVulkan *rendering_device_vulkan = nullptr;
#endif
const NSMenu *_get_menu_root(const String &p_menu_root) const;
@@ -85,8 +84,8 @@ public:
bool pressed = false;
bool echo = false;
bool raw = false;
- Key keycode = KEY_NONE;
- uint32_t physical_keycode = 0;
+ Key keycode = Key::NONE;
+ Key physical_keycode = Key::NONE;
uint32_t unicode = 0;
};
@@ -109,9 +108,6 @@ public:
Vector<Vector2> mpath;
-#if defined(OPENGL_ENABLED)
- ContextGL_OSX *context_gles2 = nullptr;
-#endif
Point2i mouse_pos;
Size2i min_size;
@@ -176,7 +172,7 @@ public:
MouseMode mouse_mode;
Point2i last_mouse_pos;
- MouseButton last_button_state = MOUSE_BUTTON_NONE;
+ MouseButton last_button_state = MouseButton::NONE;
bool window_focused;
bool drop_events;
@@ -287,6 +283,7 @@ public:
virtual void window_attach_instance_id(ObjectID p_instance, WindowID p_window = MAIN_WINDOW_ID) override;
virtual ObjectID window_get_attached_instance_id(WindowID p_window = MAIN_WINDOW_ID) const override;
+ virtual void gl_window_make_current(DisplayServer::WindowID p_window_id) 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;
diff --git a/platform/osx/display_server_osx.mm b/platform/osx/display_server_osx.mm
index da6c45793a..fec5c98a99 100644
--- a/platform/osx/display_server_osx.mm
+++ b/platform/osx/display_server_osx.mm
@@ -45,8 +45,8 @@
#include <IOKit/hid/IOHIDKeys.h>
#include <IOKit/hid/IOHIDLib.h>
-#if defined(OPENGL_ENABLED)
-//TODO - reimplement OpenGLES
+#if defined(GLES3_ENABLED)
+#include "drivers/gles3/rasterizer_gles3.h"
#import <AppKit/NSOpenGLView.h>
#endif
@@ -166,9 +166,9 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
[pwd.window_object makeKeyAndOrderFront:nil]; // Move focus back to main window if there is no parent or other windows left.
}
-#if defined(OPENGL_ENABLED)
- if (DS_OSX->rendering_driver == "opengl_es") {
- //TODO - reimplement OpenGLES
+#if defined(GLES3_ENABLED)
+ if (DS_OSX->rendering_driver == "opengl3") {
+ DS_OSX->gl_manager->window_destroy(window_id);
}
#endif
#ifdef VULKAN_ENABLED
@@ -271,9 +271,9 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
layer.contentsScale = scale;
}
-#if defined(OPENGL_ENABLED)
- if (DS_OSX->rendering_driver == "opengl_es") {
- //TODO - reimplement OpenGLES
+#if defined(GLES3_ENABLED)
+ if (DS_OSX->rendering_driver == "opengl3") {
+ DS_OSX->gl_manager->window_resize(window_id, wd.size.width, wd.size.height);
}
#endif
#if defined(VULKAN_ENABLED)
@@ -289,14 +289,6 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
Callable::CallError ce;
wd.rect_changed_callback.call((const Variant **)&sizep, 1, ret, ce);
}
-
- if (OS_OSX::get_singleton()->get_main_loop()) {
- Main::force_redraw();
- //Event retrieval blocks until resize is over. Call Main::iteration() directly.
- if (!Main::is_iterating()) { //avoid cyclic loop
- Main::iteration();
- }
- }
}
- (void)windowDidMove:(NSNotification *)notification {
@@ -377,7 +369,12 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
/* GodotContentView */
/*************************************************************************/
+#if defined(GLES3_ENABLED)
+@interface GodotContentView : NSOpenGLView <NSTextInputClient> {
+#else
@interface GodotContentView : NSView <NSTextInputClient> {
+#endif
+
DisplayServerOSX::WindowID window_id;
NSTrackingArea *trackingArea;
NSMutableAttributedString *markedText;
@@ -405,12 +402,6 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
}
- (CALayer *)makeBackingLayer {
-#if defined(OPENGL_ENABLED)
- if (DS_OSX->rendering_driver == "opengl_es") {
- CALayer *layer = [[NSOpenGLLayer class] layer];
- return layer;
- }
-#endif
#if defined(VULKAN_ENABLED)
if (DS_OSX->rendering_driver == "vulkan") {
CALayer *layer = [[CAMetalLayer class] layer];
@@ -421,10 +412,9 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
}
- (void)updateLayer {
-#if defined(OPENGL_ENABLED)
- if (DS_OSX->rendering_driver == "opengl_es") {
- [super updateLayer];
- //TODO - reimplement OpenGLES
+#if defined(GLES3_ENABLED)
+ if (DS_OSX->rendering_driver == "opengl3") {
+ DS_OSX->gl_manager->window_update(window_id);
}
#endif
#if defined(VULKAN_ENABLED)
@@ -589,8 +579,8 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
ke.pressed = true;
ke.echo = false;
ke.raw = false; // IME input event
- ke.keycode = KEY_NONE;
- ke.physical_keycode = 0;
+ ke.keycode = Key::NONE;
+ ke.physical_keycode = Key::NONE;
ke.unicode = codepoint;
_push_to_key_event_buffer(ke);
@@ -690,7 +680,7 @@ static void _mouseDownEvent(DisplayServer::WindowID window_id, NSEvent *event, M
mb->set_position(pos);
mb->set_global_position(pos);
mb->set_button_mask(DS_OSX->last_button_state);
- if (index == MOUSE_BUTTON_LEFT && pressed) {
+ if (index == MouseButton::LEFT && pressed) {
mb->set_double_click([event clickCount] == 2);
}
@@ -703,10 +693,10 @@ static void _mouseDownEvent(DisplayServer::WindowID window_id, NSEvent *event, M
if (([event modifierFlags] & NSEventModifierFlagControl)) {
wd.mouse_down_control = true;
- _mouseDownEvent(window_id, event, MOUSE_BUTTON_RIGHT, MOUSE_BUTTON_MASK_RIGHT, true);
+ _mouseDownEvent(window_id, event, MouseButton::RIGHT, MouseButton::MASK_RIGHT, true);
} else {
wd.mouse_down_control = false;
- _mouseDownEvent(window_id, event, MOUSE_BUTTON_LEFT, MOUSE_BUTTON_MASK_LEFT, true);
+ _mouseDownEvent(window_id, event, MouseButton::LEFT, MouseButton::MASK_LEFT, true);
}
}
@@ -719,9 +709,9 @@ static void _mouseDownEvent(DisplayServer::WindowID window_id, NSEvent *event, M
DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id];
if (wd.mouse_down_control) {
- _mouseDownEvent(window_id, event, MOUSE_BUTTON_RIGHT, MOUSE_BUTTON_MASK_RIGHT, false);
+ _mouseDownEvent(window_id, event, MouseButton::RIGHT, MouseButton::MASK_RIGHT, false);
} else {
- _mouseDownEvent(window_id, event, MOUSE_BUTTON_LEFT, MOUSE_BUTTON_MASK_LEFT, false);
+ _mouseDownEvent(window_id, event, MouseButton::LEFT, MouseButton::MASK_LEFT, false);
}
}
@@ -807,7 +797,7 @@ static void _mouseDownEvent(DisplayServer::WindowID window_id, NSEvent *event, M
}
- (void)rightMouseDown:(NSEvent *)event {
- _mouseDownEvent(window_id, event, MOUSE_BUTTON_RIGHT, MOUSE_BUTTON_MASK_RIGHT, true);
+ _mouseDownEvent(window_id, event, MouseButton::RIGHT, MouseButton::MASK_RIGHT, true);
}
- (void)rightMouseDragged:(NSEvent *)event {
@@ -815,16 +805,16 @@ static void _mouseDownEvent(DisplayServer::WindowID window_id, NSEvent *event, M
}
- (void)rightMouseUp:(NSEvent *)event {
- _mouseDownEvent(window_id, event, MOUSE_BUTTON_RIGHT, MOUSE_BUTTON_MASK_RIGHT, false);
+ _mouseDownEvent(window_id, event, MouseButton::RIGHT, MouseButton::MASK_RIGHT, false);
}
- (void)otherMouseDown:(NSEvent *)event {
if ((int)[event buttonNumber] == 2) {
- _mouseDownEvent(window_id, event, MOUSE_BUTTON_MIDDLE, MOUSE_BUTTON_MASK_MIDDLE, true);
+ _mouseDownEvent(window_id, event, MouseButton::MIDDLE, MouseButton::MASK_MIDDLE, true);
} else if ((int)[event buttonNumber] == 3) {
- _mouseDownEvent(window_id, event, MOUSE_BUTTON_XBUTTON1, MOUSE_BUTTON_MASK_XBUTTON1, true);
+ _mouseDownEvent(window_id, event, MouseButton::MB_XBUTTON1, MouseButton::MASK_XBUTTON1, true);
} else if ((int)[event buttonNumber] == 4) {
- _mouseDownEvent(window_id, event, MOUSE_BUTTON_XBUTTON2, MOUSE_BUTTON_MASK_XBUTTON2, true);
+ _mouseDownEvent(window_id, event, MouseButton::MB_XBUTTON2, MouseButton::MASK_XBUTTON2, true);
} else {
return;
}
@@ -836,11 +826,11 @@ static void _mouseDownEvent(DisplayServer::WindowID window_id, NSEvent *event, M
- (void)otherMouseUp:(NSEvent *)event {
if ((int)[event buttonNumber] == 2) {
- _mouseDownEvent(window_id, event, MOUSE_BUTTON_MIDDLE, MOUSE_BUTTON_MASK_MIDDLE, false);
+ _mouseDownEvent(window_id, event, MouseButton::MIDDLE, MouseButton::MASK_MIDDLE, false);
} else if ((int)[event buttonNumber] == 3) {
- _mouseDownEvent(window_id, event, MOUSE_BUTTON_XBUTTON1, MOUSE_BUTTON_MASK_XBUTTON1, false);
+ _mouseDownEvent(window_id, event, MouseButton::MB_XBUTTON1, MouseButton::MASK_XBUTTON1, false);
} else if ((int)[event buttonNumber] == 4) {
- _mouseDownEvent(window_id, event, MOUSE_BUTTON_XBUTTON2, MOUSE_BUTTON_MASK_XBUTTON2, false);
+ _mouseDownEvent(window_id, event, MouseButton::MB_XBUTTON2, MouseButton::MASK_XBUTTON2, false);
} else {
return;
}
@@ -932,140 +922,140 @@ static bool isNumpadKey(unsigned int key) {
// Keyboard symbol translation table
static const Key _osx_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_1,
- /* 13 */ KEY_2,
- /* 14 */ KEY_3,
- /* 15 */ KEY_4,
- /* 16 */ KEY_6,
- /* 17 */ KEY_5,
- /* 18 */ KEY_EQUAL,
- /* 19 */ KEY_9,
- /* 1a */ KEY_7,
- /* 1b */ KEY_MINUS,
- /* 1c */ KEY_8,
- /* 1d */ 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_UNKNOWN, /* 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_UNKNOWN, /* F18 */
- /* 50 */ KEY_UNKNOWN, /* 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_UNKNOWN, /* 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_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,
+ /* 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::UNKNOWN, /* 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::UNKNOWN, /* F18 */
+ /* 50 */ Key::UNKNOWN, /* 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::UNKNOWN, /* 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,
};
// Translates a OS X keycode to a Godot keycode
static Key translateKey(unsigned int key) {
if (key >= 128) {
- return KEY_UNKNOWN;
+ return Key::UNKNOWN;
}
return _osx_to_godot_table[key];
@@ -1087,61 +1077,61 @@ struct _KeyCodeMap {
};
static const _KeyCodeMap _keycodes[55] = {
- { '`', KEY_QUOTELEFT },
- { '~', KEY_ASCIITILDE },
- { '0', KEY_0 },
- { '1', KEY_1 },
- { '2', KEY_2 },
- { '3', KEY_3 },
- { '4', KEY_4 },
- { '5', KEY_5 },
- { '6', KEY_6 },
- { '7', KEY_7 },
- { '8', KEY_8 },
- { '9', 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 }
+ { '`', 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 }
};
static Key remapKey(unsigned int key, unsigned int state) {
@@ -1355,7 +1345,7 @@ inline void sendScrollEvent(DisplayServer::WindowID window_id, MouseButton butto
ERR_FAIL_COND(!DS_OSX->windows.has(window_id));
DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id];
- MouseButton mask = MouseButton(1 << (button - 1));
+ MouseButton mask = mouse_button_to_mask(button);
Ref<InputEventMouseButton> sc;
sc.instantiate();
@@ -1428,10 +1418,10 @@ inline void sendPanEvent(DisplayServer::WindowID window_id, double dx, double dy
sendPanEvent(window_id, deltaX, deltaY, [event modifierFlags]);
} else {
if (fabs(deltaX)) {
- sendScrollEvent(window_id, 0 > deltaX ? MOUSE_BUTTON_WHEEL_RIGHT : MOUSE_BUTTON_WHEEL_LEFT, fabs(deltaX * 0.3), [event modifierFlags]);
+ sendScrollEvent(window_id, 0 > deltaX ? MouseButton::WHEEL_RIGHT : MouseButton::WHEEL_LEFT, fabs(deltaX * 0.3), [event modifierFlags]);
}
if (fabs(deltaY)) {
- sendScrollEvent(window_id, 0 < deltaY ? MOUSE_BUTTON_WHEEL_UP : MOUSE_BUTTON_WHEEL_DOWN, fabs(deltaY * 0.3), [event modifierFlags]);
+ sendScrollEvent(window_id, 0 < deltaY ? MouseButton::WHEEL_UP : MouseButton::WHEEL_DOWN, fabs(deltaY * 0.3), [event modifierFlags]);
}
}
}
@@ -1930,6 +1920,7 @@ void DisplayServerOSX::mouse_set_mode(MouseMode p_mode) {
return;
}
+ WindowData &wd = windows[MAIN_WINDOW_ID];
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."
@@ -1938,7 +1929,7 @@ void DisplayServerOSX::mouse_set_mode(MouseMode p_mode) {
CGDisplayHideCursor(kCGDirectMainDisplay);
}
CGAssociateMouseAndMouseCursorPosition(false);
- WindowData &wd = windows[MAIN_WINDOW_ID];
+ [wd.window_object setMovable:NO];
const NSRect contentRect = [wd.window_view frame];
NSRect pointInWindowRect = NSMakeRect(contentRect.size.width / 2, contentRect.size.height / 2, 0, 0);
NSPoint pointOnScreen = [[wd.window_view window] convertRectToScreen:pointInWindowRect].origin;
@@ -1948,17 +1939,21 @@ void DisplayServerOSX::mouse_set_mode(MouseMode p_mode) {
if (mouse_mode == MOUSE_MODE_VISIBLE || mouse_mode == MOUSE_MODE_CONFINED) {
CGDisplayHideCursor(kCGDirectMainDisplay);
}
+ [wd.window_object setMovable:YES];
CGAssociateMouseAndMouseCursorPosition(true);
} else if (p_mode == MOUSE_MODE_CONFINED) {
CGDisplayShowCursor(kCGDirectMainDisplay);
+ [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) {
CGDisplayHideCursor(kCGDirectMainDisplay);
}
+ [wd.window_object setMovable:NO];
CGAssociateMouseAndMouseCursorPosition(false);
} else { // MOUSE_MODE_VISIBLE
CGDisplayShowCursor(kCGDirectMainDisplay);
+ [wd.window_object setMovable:YES];
CGAssociateMouseAndMouseCursorPosition(true);
}
@@ -2586,8 +2581,8 @@ void DisplayServerOSX::_set_window_per_pixel_transparency_enabled(bool p_enabled
//TODO - implement transparency for Vulkan
}
#endif
-#if defined(OPENGL_ENABLED)
- if (rendering_driver == "opengl_es") {
+#if defined(GLES3_ENABLED)
+ if (rendering_driver == "opengl3") {
//TODO - reimplement OpenGLES
}
#endif
@@ -2605,15 +2600,15 @@ void DisplayServerOSX::_set_window_per_pixel_transparency_enabled(bool p_enabled
//TODO - implement transparency for Vulkan
}
#endif
-#if defined(OPENGL_ENABLED)
- if (rendering_driver == "opengl_es") {
+#if defined(GLES3_ENABLED)
+ if (rendering_driver == "opengl3") {
//TODO - reimplement OpenGLES
}
#endif
wd.layered_window = false;
}
-#if defined(OPENGL_ENABLED)
- if (rendering_driver == "opengl_es") {
+#if defined(GLES3_ENABLED)
+ if (rendering_driver == "opengl3") {
//TODO - reimplement OpenGLES
}
#endif
@@ -3014,7 +3009,7 @@ void DisplayServerOSX::cursor_set_custom_image(const RES &p_cursor, CursorShape
ERR_FAIL_COND(!image.is_valid());
NSBitmapImageRep *imgrep = [[NSBitmapImageRep alloc]
- initWithBitmapDataPlanes:NULL
+ initWithBitmapDataPlanes:nullptr
pixelsWide:int(texture_size.width)
pixelsHigh:int(texture_size.height)
bitsPerSample:8
@@ -3210,12 +3205,12 @@ String DisplayServerOSX::keyboard_get_layout_name(int p_index) const {
}
Key DisplayServerOSX::keyboard_get_keycode_from_physical(Key p_keycode) const {
- if (p_keycode == KEY_PAUSE) {
+ if (p_keycode == Key::PAUSE) {
return p_keycode;
}
- unsigned int modifiers = p_keycode & KEY_MODIFIER_MASK;
- unsigned int keycode_no_mod = p_keycode & KEY_CODE_MASK;
+ Key modifiers = p_keycode & KeyModifierMask::MODIFIER_MASK;
+ Key keycode_no_mod = p_keycode & KeyModifierMask::CODE_MASK;
unsigned int osx_keycode = unmapKey((Key)keycode_no_mod);
return (Key)(remapKey(osx_keycode, 0) | modifiers);
}
@@ -3273,8 +3268,8 @@ void DisplayServerOSX::_send_event(NSEvent *p_event) {
_get_key_modifier_state([p_event modifierFlags], k);
k->set_window_id(DisplayServerOSX::INVALID_WINDOW_ID);
k->set_pressed(true);
- k->set_keycode(KEY_PERIOD);
- k->set_physical_keycode(KEY_PERIOD);
+ k->set_keycode(Key::PERIOD);
+ k->set_physical_keycode(Key::PERIOD);
k->set_echo([p_event isARepeat]);
Input::get_singleton()->parse_input_event(k);
@@ -3301,20 +3296,20 @@ void DisplayServerOSX::_process_key_events() {
_push_input(k);
} else {
// IME input
- if ((i == 0 && ke.keycode == 0) || (i > 0 && key_event_buffer[i - 1].keycode == 0)) {
+ if ((i == 0 && ke.keycode == Key::NONE) || (i > 0 && key_event_buffer[i - 1].keycode == Key::NONE)) {
k.instantiate();
k->set_window_id(ke.window_id);
_get_key_modifier_state(ke.osx_state, k);
k->set_pressed(ke.pressed);
k->set_echo(ke.echo);
- k->set_keycode(KEY_NONE);
- k->set_physical_keycode(KEY_NONE);
+ k->set_keycode(Key::NONE);
+ k->set_physical_keycode(Key::NONE);
k->set_unicode(ke.unicode);
_push_input(k);
}
- if (ke.keycode != 0) {
+ if (ke.keycode != Key::NONE) {
k.instantiate();
k->set_window_id(ke.window_id);
@@ -3324,7 +3319,7 @@ void DisplayServerOSX::_process_key_events() {
k->set_keycode(ke.keycode);
k->set_physical_keycode((Key)ke.physical_keycode);
- if (i + 1 < key_event_pos && key_event_buffer[i + 1].keycode == 0) {
+ if (i + 1 < key_event_pos && key_event_buffer[i + 1].keycode == Key::NONE) {
k->set_unicode(key_event_buffer[i + 1].unicode);
}
@@ -3418,7 +3413,7 @@ void DisplayServerOSX::set_icon(const Ref<Image> &p_icon) {
img = img->duplicate();
img->convert(Image::FORMAT_RGBA8);
NSBitmapImageRep *imgrep = [[NSBitmapImageRep alloc]
- initWithBitmapDataPlanes:NULL
+ initWithBitmapDataPlanes:nullptr
pixelsWide:img->get_width()
pixelsHigh:img->get_height()
bitsPerSample:8
@@ -3455,18 +3450,31 @@ void DisplayServerOSX::set_icon(const Ref<Image> &p_icon) {
void DisplayServerOSX::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {
_THREAD_SAFE_METHOD_
+#if defined(GLES3_ENABLED)
+ if (rendering_driver == "opengl3") {
+ gl_manager->swap_buffers();
+ }
+#endif
#if defined(VULKAN_ENABLED)
- context_vulkan->set_vsync_mode(p_window, p_vsync_mode);
+ if (rendering_driver == "vulkan") {
+ context_vulkan->set_vsync_mode(p_window, p_vsync_mode);
+ }
#endif
}
DisplayServer::VSyncMode DisplayServerOSX::window_get_vsync_mode(WindowID p_window) const {
_THREAD_SAFE_METHOD_
+#if defined(GLES3_ENABLED)
+ if (rendering_driver == "opengl3") {
+ return (gl_manager->is_using_vsync() ? DisplayServer::VSyncMode::VSYNC_ENABLED : DisplayServer::VSyncMode::VSYNC_DISABLED);
+ }
+#endif
#if defined(VULKAN_ENABLED)
- return context_vulkan->get_vsync_mode(p_window);
-#else
- return DisplayServer::VSYNC_ENABLED;
+ if (rendering_driver == "vulkan") {
+ return context_vulkan->get_vsync_mode(p_window);
+ }
#endif
+ return DisplayServer::VSYNC_ENABLED;
}
Vector<String> DisplayServerOSX::get_rendering_drivers_func() {
@@ -3475,13 +3483,19 @@ Vector<String> DisplayServerOSX::get_rendering_drivers_func() {
#if defined(VULKAN_ENABLED)
drivers.push_back("vulkan");
#endif
-#if defined(OPENGL_ENABLED)
- drivers.push_back("opengl_es");
+#if defined(GLES3_ENABLED)
+ drivers.push_back("opengl3");
#endif
return drivers;
}
+void DisplayServerOSX::gl_window_make_current(DisplayServer::WindowID p_window_id) {
+#if defined(GLES3_ENABLED)
+ gl_manager->window_make_current(p_window_id);
+#endif
+}
+
Point2i DisplayServerOSX::ime_get_selection() const {
return im_selection;
}
@@ -3522,7 +3536,7 @@ ObjectID DisplayServerOSX::window_get_attached_instance_id(WindowID p_window) co
DisplayServer *DisplayServerOSX::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
DisplayServer *ds = memnew(DisplayServerOSX(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error));
if (r_error != OK) {
- OS::get_singleton()->alert("Your video card driver does not support any of the supported Metal versions.", "Unable to initialize Video driver");
+ OS::get_singleton()->alert("Your video card driver does not support any of the supported Vulkan or OpenGL versions.", "Unable to initialize Video driver");
}
return ds;
}
@@ -3579,9 +3593,12 @@ DisplayServerOSX::WindowID DisplayServerOSX::_create_window(WindowMode p_mode, V
}
}
#endif
-#if defined(OPENGL_ENABLED)
- if (rendering_driver == "opengl_es") {
- //TODO - reimplement OpenGLES
+#if defined(GLES3_ENABLED)
+ if (rendering_driver == "opengl3") {
+ if (gl_manager) {
+ 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");
+ }
}
#endif
id = window_id_counter++;
@@ -3600,9 +3617,9 @@ DisplayServerOSX::WindowID DisplayServerOSX::_create_window(WindowMode p_mode, V
layer.contentsScale = scale;
}
-#if defined(OPENGL_ENABLED)
- if (rendering_driver == "opengl_es") {
- //TODO - reimplement OpenGLES
+#if defined(GLES3_ENABLED)
+ if (rendering_driver == "opengl3") {
+ gl_manager->window_resize(id, wd.size.width, wd.size.height);
}
#endif
#if defined(VULKAN_ENABLED)
@@ -3654,15 +3671,15 @@ void DisplayServerOSX::_dispatch_input_event(const Ref<InputEvent> &p_event) {
}
void DisplayServerOSX::release_rendering_thread() {
- //TODO - reimplement OpenGLES
}
void DisplayServerOSX::make_rendering_thread() {
- //TODO - reimplement OpenGLES
}
void DisplayServerOSX::swap_buffers() {
- //TODO - reimplement OpenGLES
+#if defined(GLES3_ENABLED)
+ gl_manager->swap_buffers();
+#endif
}
void DisplayServerOSX::console_set_visible(bool p_enabled) {
@@ -3750,17 +3767,20 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode
[main_menu setSubmenu:apple_menu forItem:menu_item];
//!!!!!!!!!!!!!!!!!!!!!!!!!!
- //TODO - do Vulkan and GLES2 support checks, driver selection and fallback
+ //TODO - do Vulkan and OpenGL support checks, driver selection and fallback
rendering_driver = p_rendering_driver;
-#ifndef _MSC_VER
-#warning Forcing vulkan rendering driver because OpenGL not implemented yet
-#endif
- rendering_driver = "vulkan";
-
-#if defined(OPENGL_ENABLED)
- if (rendering_driver == "opengl_es") {
- //TODO - reimplement OpenGLES
+#if defined(GLES3_ENABLED)
+ if (rendering_driver == "opengl3") {
+ GLManager_OSX::ContextType opengl_api_type = GLManager_OSX::GLES_3_0_COMPATIBLE;
+ gl_manager = memnew(GLManager_OSX(opengl_api_type));
+ if (gl_manager->initialize() != OK) {
+ memdelete(gl_manager);
+ gl_manager = nullptr;
+ r_error = ERR_UNAVAILABLE;
+ ERR_FAIL_MSG("Could not initialize OpenGL");
+ return;
+ }
}
#endif
#if defined(VULKAN_ENABLED)
@@ -3787,9 +3807,9 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode
}
show_window(MAIN_WINDOW_ID);
-#if defined(OPENGL_ENABLED)
- if (rendering_driver == "opengl_es") {
- //TODO - reimplement OpenGLES
+#if defined(GLES3_ENABLED)
+ if (rendering_driver == "opengl3") {
+ RasterizerGLES3::make_current();
}
#endif
#if defined(VULKAN_ENABLED)
@@ -3820,21 +3840,22 @@ DisplayServerOSX::~DisplayServerOSX() {
}
//destroy drivers
-#if defined(OPENGL_ENABLED)
- if (rendering_driver == "opengl_es") {
- //TODO - reimplement OpenGLES
+#if defined(GLES3_ENABLED)
+ if (gl_manager) {
+ memdelete(gl_manager);
+ gl_manager = nullptr;
}
#endif
#if defined(VULKAN_ENABLED)
- if (rendering_driver == "vulkan") {
- if (rendering_device_vulkan) {
- rendering_device_vulkan->finalize();
- memdelete(rendering_device_vulkan);
- }
+ if (rendering_device_vulkan) {
+ rendering_device_vulkan->finalize();
+ memdelete(rendering_device_vulkan);
+ rendering_device_vulkan = nullptr;
+ }
- if (context_vulkan) {
- memdelete(context_vulkan);
- }
+ if (context_vulkan) {
+ memdelete(context_vulkan);
+ context_vulkan = nullptr;
}
#endif
diff --git a/platform/osx/export/export_plugin.cpp b/platform/osx/export/export_plugin.cpp
index 2404c20153..36a2e5e205 100644
--- a/platform/osx/export/export_plugin.cpp
+++ b/platform/osx/export/export_plugin.cpp
@@ -325,11 +325,11 @@ void EditorExportPlatformOSX::_fix_plist(const Ref<EditorExportPreset> &p_preset
}
/**
- If we're running the OSX version of the Godot editor we'll:
- - export our application bundle to a temporary folder
- - attempt to code sign it
- - and then wrap it up in a DMG
-**/
+ * If we're running the OSX version of the Godot editor we'll:
+ * - export our application bundle to a temporary folder
+ * - attempt to code sign it
+ * - and then wrap it up in a DMG
+ */
Error EditorExportPlatformOSX::_notarize(const Ref<EditorExportPreset> &p_preset, const String &p_path) {
#ifdef OSX_ENABLED
@@ -561,7 +561,6 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
// Now process our template.
bool found_binary = false;
- int total_size = 0;
Vector<String> dylibs_found;
while (ret == UNZ_OK && err == OK) {
@@ -649,7 +648,6 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
}
print_line("ADDING: " + file + " size: " + itos(data.size()));
- total_size += data.size();
// Write it into our application bundle.
file = tmp_app_path_name.plus_file(file);
@@ -962,9 +960,10 @@ void EditorExportPlatformOSX::_zip_folder_recursive(zipFile &p_zip, const String
DirAccessRef da = DirAccess::open(dir);
da->list_dir_begin();
- String f;
- while ((f = da->get_next()) != "") {
+ String f = da->get_next();
+ while (!f.is_empty()) {
if (f == "." || f == "..") {
+ f = da->get_next();
continue;
}
if (da->is_link(f)) {
@@ -1050,10 +1049,24 @@ void EditorExportPlatformOSX::_zip_folder_recursive(zipFile &p_zip, const String
0x0314, // "version made by", 0x03 - Unix, 0x14 - ZIP specification version 2.0, required to store Unix file permissions
0);
- Vector<uint8_t> array = FileAccess::get_file_as_array(dir.plus_file(f));
- zipWriteInFileInZip(p_zip, array.ptr(), array.size());
+ FileAccessRef fa = FileAccess::open(dir.plus_file(f), FileAccess::READ);
+ if (!fa) {
+ ERR_FAIL_MSG("Can't open file to read from path '" + String(dir.plus_file(f)) + "'.");
+ }
+ 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();
}
diff --git a/platform/osx/context_gl_osx.h b/platform/osx/gl_manager_osx.h
index ac45559217..f86bc805c1 100644
--- a/platform/osx/context_gl_osx.h
+++ b/platform/osx/gl_manager_osx.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* context_gl_osx.h */
+/* gl_manager_osx.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,47 +28,79 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef CONTEXT_GL_OSX_H
-#define CONTEXT_GL_OSX_H
+#ifndef GL_MANAGER_OSX_H
+#define GL_MANAGER_OSX_H
-#if defined(OPENGL_ENABLED) || defined(GLES_ENABLED)
+#if defined(OSX_ENABLED) && defined(GLES3_ENABLED)
#include "core/error/error_list.h"
#include "core/os/os.h"
+#include "core/templates/local_vector.h"
+#include "servers/display_server.h"
#include <AppKit/AppKit.h>
#include <ApplicationServices/ApplicationServices.h>
#include <CoreVideo/CoreVideo.h>
-class ContextGL_OSX {
- bool opengl_3_context;
- bool use_vsync;
+class GLManager_OSX {
+public:
+ enum ContextType {
+ GLES_3_0_COMPATIBLE,
+ };
+
+private:
+ struct GLWindow {
+ GLWindow() { in_use = false; }
+ bool in_use;
+
+ DisplayServer::WindowID window_id;
+ int width;
+ int height;
+
+ id window_view;
+ NSOpenGLContext *context;
+ };
+
+ LocalVector<GLWindow> _windows;
+
+ NSOpenGLContext *_shared_context = nullptr;
+ GLWindow *_current_window;
+
+ Error _create_context(GLWindow &win);
+ void _internal_set_current_window(GLWindow *p_win);
- void *framework;
- id window_view;
- NSOpenGLPixelFormat *pixelFormat;
- NSOpenGLContext *context;
+ GLWindow &get_window(unsigned int id) { return _windows[id]; }
+ const GLWindow &get_window(unsigned int id) const { return _windows[id]; }
+
+ bool use_vsync;
+ ContextType context_type;
public:
- void release_current();
+ Error window_create(DisplayServer::WindowID p_window_id, id p_view, 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);
+
+ // get directly from the cached GLWindow
+ int window_get_width(DisplayServer::WindowID p_window_id = 0);
+ int window_get_height(DisplayServer::WindowID p_window_id = 0);
+ void release_current();
void make_current();
- void update();
+ void swap_buffers();
- void set_opacity(GLint p_opacity);
+ void window_make_current(DisplayServer::WindowID p_window_id);
- int get_window_width();
- int get_window_height();
- void swap_buffers();
+ void window_update(DisplayServer::WindowID p_window_id);
Error initialize();
void set_use_vsync(bool p_use);
bool is_using_vsync() const;
- ContextGL_OSX(id p_view, bool p_opengl_3_context);
- ~ContextGL_OSX();
+ GLManager_OSX(ContextType p_context_type);
+ ~GLManager_OSX();
};
-#endif
-#endif
+#endif // defined(OSX_ENABLED) && defined(GLES3_ENABLED)
+
+#endif // GL_MANAGER_OSX_H
diff --git a/platform/osx/gl_manager_osx.mm b/platform/osx/gl_manager_osx.mm
new file mode 100644
index 0000000000..60e0706fc0
--- /dev/null
+++ b/platform/osx/gl_manager_osx.mm
@@ -0,0 +1,233 @@
+/*************************************************************************/
+/* gl_manager_osx.mm */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "gl_manager_osx.h"
+
+#ifdef OSX_ENABLED
+#ifdef GLES3_ENABLED
+
+#include <stdio.h>
+#include <stdlib.h>
+
+Error GLManager_OSX::_create_context(GLWindow &win) {
+ NSOpenGLPixelFormatAttribute attributes[] = {
+ NSOpenGLPFADoubleBuffer,
+ NSOpenGLPFAClosestPolicy,
+ NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,
+ NSOpenGLPFAColorSize, 32,
+ NSOpenGLPFADepthSize, 24,
+ NSOpenGLPFAStencilSize, 8,
+ 0
+ };
+
+ NSOpenGLPixelFormat *pixel_format = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
+ ERR_FAIL_COND_V(pixel_format == nil, ERR_CANT_CREATE);
+
+ win.context = [[NSOpenGLContext alloc] initWithFormat:pixel_format shareContext:_shared_context];
+ ERR_FAIL_COND_V(win.context == nil, ERR_CANT_CREATE);
+ if (_shared_context == nullptr) {
+ _shared_context = win.context;
+ }
+
+ [win.context setView:win.window_view];
+ [win.context makeCurrentContext];
+
+ return OK;
+}
+
+Error GLManager_OSX::window_create(DisplayServer::WindowID p_window_id, id p_view, int p_width, int p_height) {
+ if (p_window_id >= (int)_windows.size()) {
+ _windows.resize(p_window_id + 1);
+ }
+
+ GLWindow &win = _windows[p_window_id];
+ win.in_use = true;
+ win.window_id = p_window_id;
+ win.width = p_width;
+ win.height = p_height;
+ win.window_view = p_view;
+
+ if (_create_context(win) != OK) {
+ _windows.remove_at(_windows.size() - 1);
+ return FAILED;
+ }
+
+ window_make_current(_windows.size() - 1);
+
+ return OK;
+}
+
+void GLManager_OSX::_internal_set_current_window(GLWindow *p_win) {
+ _current_window = p_win;
+}
+
+void GLManager_OSX::window_resize(DisplayServer::WindowID p_window_id, int p_width, int p_height) {
+ if (p_window_id == -1) {
+ return;
+ }
+
+ GLWindow &win = _windows[p_window_id];
+ if (!win.in_use) {
+ return;
+ }
+
+ win.width = p_width;
+ win.height = p_height;
+
+ GLint dim[2];
+ dim[0] = p_width;
+ dim[1] = p_height;
+ CGLSetParameter((CGLContextObj)[win.context CGLContextObj], kCGLCPSurfaceBackingSize, &dim[0]);
+ CGLEnable((CGLContextObj)[win.context CGLContextObj], kCGLCESurfaceBackingSize);
+ if (OS::get_singleton()->is_hidpi_allowed()) {
+ [win.window_view setWantsBestResolutionOpenGLSurface:YES];
+ } else {
+ [win.window_view setWantsBestResolutionOpenGLSurface:NO];
+ }
+
+ [win.context update];
+}
+
+int GLManager_OSX::window_get_width(DisplayServer::WindowID p_window_id) {
+ return get_window(p_window_id).width;
+}
+
+int GLManager_OSX::window_get_height(DisplayServer::WindowID p_window_id) {
+ return get_window(p_window_id).height;
+}
+
+void GLManager_OSX::window_destroy(DisplayServer::WindowID p_window_id) {
+ GLWindow &win = get_window(p_window_id);
+ win.in_use = false;
+
+ if (_current_window == &win) {
+ _current_window = nullptr;
+ }
+}
+
+void GLManager_OSX::release_current() {
+ if (!_current_window) {
+ return;
+ }
+
+ [NSOpenGLContext clearCurrentContext];
+}
+
+void GLManager_OSX::window_make_current(DisplayServer::WindowID p_window_id) {
+ if (p_window_id == -1) {
+ return;
+ }
+
+ GLWindow &win = _windows[p_window_id];
+ if (!win.in_use) {
+ return;
+ }
+
+ if (&win == _current_window) {
+ return;
+ }
+
+ [win.context makeCurrentContext];
+
+ _internal_set_current_window(&win);
+}
+
+void GLManager_OSX::make_current() {
+ if (!_current_window) {
+ return;
+ }
+ if (!_current_window->in_use) {
+ WARN_PRINT("current window not in use!");
+ return;
+ }
+ [_current_window->context makeCurrentContext];
+}
+
+void GLManager_OSX::swap_buffers() {
+ // NO NEED TO CALL SWAP BUFFERS for each window...
+ // see https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glXSwapBuffers.xml
+
+ if (!_current_window) {
+ return;
+ }
+ if (!_current_window->in_use) {
+ WARN_PRINT("current window not in use!");
+ return;
+ }
+ [_current_window->context flushBuffer];
+}
+
+void GLManager_OSX::window_update(DisplayServer::WindowID p_window_id) {
+ if (p_window_id == -1) {
+ return;
+ }
+
+ GLWindow &win = _windows[p_window_id];
+ if (!win.in_use) {
+ return;
+ }
+
+ if (&win == _current_window) {
+ return;
+ }
+
+ [win.context update];
+}
+
+Error GLManager_OSX::initialize() {
+ return OK;
+}
+
+void GLManager_OSX::set_use_vsync(bool p_use) {
+ use_vsync = p_use;
+ CGLContextObj ctx = CGLGetCurrentContext();
+ if (ctx) {
+ GLint swapInterval = p_use ? 1 : 0;
+ CGLSetParameter(ctx, kCGLCPSwapInterval, &swapInterval);
+ use_vsync = p_use;
+ }
+}
+
+bool GLManager_OSX::is_using_vsync() const {
+ return use_vsync;
+}
+
+GLManager_OSX::GLManager_OSX(ContextType p_context_type) {
+ context_type = p_context_type;
+ use_vsync = false;
+ _current_window = nullptr;
+}
+
+GLManager_OSX::~GLManager_OSX() {
+ release_current();
+}
+
+#endif // GLES3_ENABLED
+#endif // OSX
diff --git a/platform/osx/joypad_osx.cpp b/platform/osx/joypad_osx.cpp
index e67d2b0e91..48d165d30b 100644
--- a/platform/osx/joypad_osx.cpp
+++ b/platform/osx/joypad_osx.cpp
@@ -58,6 +58,7 @@ void joypad::free() {
if (ff_device) {
FFDeviceReleaseEffect(ff_device, ff_object);
FFReleaseDevice(ff_device);
+ ff_device = nullptr;
memfree(ff_axes);
memfree(ff_directions);
}
@@ -243,7 +244,7 @@ void JoypadOSX::_device_added(IOReturn p_res, IOHIDDeviceRef p_device) {
if (is_joypad(p_device)) {
configure_joypad(p_device, &new_joypad);
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
- if (IOHIDDeviceGetService != nullptr) {
+ if (IOHIDDeviceGetService) {
#endif
const io_service_t ioservice = IOHIDDeviceGetService(p_device);
if ((ioservice) && (FFIsForceFeedback(ioservice) == FF_OK) && new_joypad.config_force_feedback(ioservice)) {
@@ -263,7 +264,7 @@ void JoypadOSX::_device_removed(IOReturn p_res, IOHIDDeviceRef p_device) {
input->joy_connection_changed(device_list[device].id, false, "");
device_list.write[device].free();
- device_list.remove(device);
+ device_list.remove_at(device);
}
static String _hex_str(uint8_t p_byte) {
@@ -336,10 +337,10 @@ bool JoypadOSX::configure_joypad(IOHIDDeviceRef p_device_ref, joypad *p_joy) {
}
// Xbox controller hat values start at 1 rather than 0.
p_joy->offset_hat = vendor == 0x45e &&
- (product_id == 0x0b05 ||
- product_id == 0x02e0 ||
- product_id == 0x02fd ||
- product_id == 0x0b13);
+ (product_id == 0x0b05 ||
+ product_id == 0x02e0 ||
+ product_id == 0x02fd ||
+ product_id == 0x0b13);
return true;
}
@@ -348,6 +349,7 @@ bool JoypadOSX::configure_joypad(IOHIDDeviceRef p_device_ref, joypad *p_joy) {
{ \
if (ret != FF_OK) { \
FFReleaseDevice(ff_device); \
+ ff_device = nullptr; \
return false; \
} \
}
@@ -367,6 +369,7 @@ bool joypad::config_force_feedback(io_service_t p_service) {
return true;
}
FFReleaseDevice(ff_device);
+ ff_device = nullptr;
return false;
}
#undef FF_ERR
@@ -397,10 +400,10 @@ bool joypad::check_ff_features() {
return false;
}
-static int process_hat_value(int p_min, int p_max, int p_value, bool p_offset_hat) {
+static 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;
- int hat_value = HatMask::HAT_MASK_CENTER;
+ HatMask hat_value = HatMask::CENTER;
if (range == 4) {
value *= 2;
}
@@ -410,31 +413,31 @@ static int process_hat_value(int p_min, int p_max, int p_value, bool p_offset_ha
switch (value) {
case 0:
- hat_value = (HatMask)HatMask::HAT_MASK_UP;
+ hat_value = HatMask::UP;
break;
case 1:
- hat_value = (HatMask)(HatMask::HAT_MASK_UP | HatMask::HAT_MASK_RIGHT);
+ hat_value = (HatMask::UP | HatMask::RIGHT);
break;
case 2:
- hat_value = (HatMask)HatMask::HAT_MASK_RIGHT;
+ hat_value = HatMask::RIGHT;
break;
case 3:
- hat_value = (HatMask)(HatMask::HAT_MASK_DOWN | HatMask::HAT_MASK_RIGHT);
+ hat_value = (HatMask::DOWN | HatMask::RIGHT);
break;
case 4:
- hat_value = (HatMask)HatMask::HAT_MASK_DOWN;
+ hat_value = HatMask::DOWN;
break;
case 5:
- hat_value = (HatMask)(HatMask::HAT_MASK_DOWN | HatMask::HAT_MASK_LEFT);
+ hat_value = (HatMask::DOWN | HatMask::LEFT);
break;
case 6:
- hat_value = (HatMask)HatMask::HAT_MASK_LEFT;
+ hat_value = HatMask::LEFT;
break;
case 7:
- hat_value = (HatMask)(HatMask::HAT_MASK_UP | HatMask::HAT_MASK_LEFT);
+ hat_value = (HatMask::UP | HatMask::LEFT);
break;
default:
- hat_value = (HatMask)HatMask::HAT_MASK_CENTER;
+ hat_value = HatMask::CENTER;
break;
}
return hat_value;
@@ -480,8 +483,8 @@ void JoypadOSX::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);
- int hat_value = process_hat_value(elem.min, elem.max, value, joy.offset_hat);
- input->joy_hat(joy.id, (HatMask)hat_value);
+ HatMask hat_value = process_hat_value(elem.min, elem.max, value, joy.offset_hat);
+ input->joy_hat(joy.id, hat_value);
}
if (joy.ffservice) {
@@ -601,7 +604,7 @@ JoypadOSX::JoypadOSX(Input *in) {
if (array) {
hid_manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
- if (hid_manager != nullptr) {
+ if (hid_manager) {
config_hid_manager(array);
}
CFRelease(array);
diff --git a/platform/osx/joypad_osx.h b/platform/osx/joypad_osx.h
index c060c3d523..2ba7f0d950 100644
--- a/platform/osx/joypad_osx.h
+++ b/platform/osx/joypad_osx.h
@@ -68,8 +68,8 @@ struct joypad {
io_service_t ffservice = 0; /* Interface for force feedback, 0 = no ff */
FFCONSTANTFORCE ff_constant_force;
- FFDeviceObjectReference ff_device;
- FFEffectObjectReference ff_object;
+ FFDeviceObjectReference ff_device = nullptr;
+ FFEffectObjectReference ff_object = nullptr;
uint64_t ff_timestamp = 0;
LONG *ff_directions = nullptr;
FFEFFECT ff_effect;
@@ -106,7 +106,6 @@ private:
int get_joy_ref(IOHIDDeviceRef p_device) const;
void poll_joypads() const;
- void setup_joypad_objects();
void config_hid_manager(CFArrayRef p_matching_array) const;
void joypad_vibration_start(int p_id, float p_magnitude, float p_duration, uint64_t p_timestamp);
diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h
index a52436a70a..7e02f4e154 100644
--- a/platform/osx/os_osx.h
+++ b/platform/osx/os_osx.h
@@ -57,6 +57,8 @@ class OS_OSX : public OS_Unix {
MainLoop *main_loop;
+ static void pre_wait_observer_cb(CFRunLoopObserverRef p_observer, CFRunLoopActivity p_activiy, void *p_context);
+
public:
String open_with_filename;
@@ -92,6 +94,8 @@ public:
String get_locale() 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) override;
+ virtual Error create_instance(const List<String> &p_arguments, ProcessID *r_child_id = nullptr) override;
virtual String get_unique_id() const override; //++
diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm
index e9cb46ed21..39608bdea8 100644
--- a/platform/osx/os_osx.mm
+++ b/platform/osx/os_osx.mm
@@ -178,7 +178,7 @@
class OSXTerminalLogger : public StdLogger {
public:
- virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type = ERR_ERROR) {
+ virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify = false, ErrorType p_type = ERR_ERROR) {
if (!should_log(true)) {
return;
}
@@ -491,14 +491,89 @@ String OS_OSX::get_executable_path() const {
}
}
+Error OS_OSX::create_instance(const List<String> &p_arguments, ProcessID *r_child_id) {
+ // If executable is bundled, always execute editor instances as an app bundle to ensure app window is registered and activated correctly.
+ NSString *nsappname = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"];
+ if (nsappname != nil) {
+ String path;
+ path.parse_utf8([[[NSBundle mainBundle] bundlePath] UTF8String]);
+ return create_process(path, p_arguments, r_child_id);
+ } else {
+ return create_process(get_executable_path(), p_arguments, r_child_id);
+ }
+}
+
+Error OS_OSX::create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id) {
+ if (@available(macOS 10.15, *)) {
+ // Use NSWorkspace if path is an .app bundle.
+ NSURL *url = [NSURL fileURLWithPath:@(p_path.utf8().get_data())];
+ NSBundle *bundle = [NSBundle bundleWithURL:url];
+ if (bundle) {
+ NSMutableArray *arguments = [[NSMutableArray alloc] init];
+ for (const List<String>::Element *E = p_arguments.front(); E; E = E->next()) {
+ [arguments addObject:[NSString stringWithUTF8String:E->get().utf8().get_data()]];
+ }
+ NSWorkspaceOpenConfiguration *configuration = [[NSWorkspaceOpenConfiguration alloc] init];
+ [configuration setArguments:arguments];
+ [configuration setCreatesNewApplicationInstance:YES];
+ __block dispatch_semaphore_t lock = dispatch_semaphore_create(0);
+ __block Error err = ERR_TIMEOUT;
+ __block pid_t pid = 0;
+ [[NSWorkspace sharedWorkspace] openApplicationAtURL:url
+ configuration:configuration
+ completionHandler:^(NSRunningApplication *app, NSError *error) {
+ if (error) {
+ err = ERR_CANT_FORK;
+ NSLog(@"Failed to execute: %@", error.localizedDescription);
+ } else {
+ pid = [app processIdentifier];
+ err = OK;
+ }
+ dispatch_semaphore_signal(lock);
+ }];
+ dispatch_semaphore_wait(lock, dispatch_time(DISPATCH_TIME_NOW, 20000000000)); // 20 sec timeout, wait for app to launch.
+ dispatch_release(lock);
+
+ if (err == OK) {
+ if (r_child_id) {
+ *r_child_id = (ProcessID)pid;
+ }
+ }
+
+ return err;
+ } else {
+ return OS_Unix::create_process(p_path, p_arguments, r_child_id);
+ }
+ } else {
+ return OS_Unix::create_process(p_path, p_arguments, r_child_id);
+ }
+}
+
+void OS_OSX::pre_wait_observer_cb(CFRunLoopObserverRef p_observer, CFRunLoopActivity p_activiy, void *p_context) {
+ // Prevent main loop from sleeping and redraw window during resize / modal popups.
+
+ if (get_singleton()->get_main_loop()) {
+ Main::force_redraw();
+ if (!Main::is_iterating()) { // Avoid cyclic loop.
+ Main::iteration();
+ }
+ }
+
+ CFRunLoopWakeUp(CFRunLoopGetCurrent()); // Prevent main loop from sleeping.
+}
+
void OS_OSX::run() {
force_quit = false;
- if (!main_loop)
+ if (!main_loop) {
return;
+ }
main_loop->initialize();
+ CFRunLoopObserverRef pre_wait_observer = CFRunLoopObserverCreate(kCFAllocatorDefault, kCFRunLoopBeforeWaiting, true, 0, &pre_wait_observer_cb, nullptr);
+ CFRunLoopAddObserver(CFRunLoopGetCurrent(), pre_wait_observer, kCFRunLoopCommonModes);
+
bool quit = false;
while (!force_quit && !quit) {
@try {
@@ -514,6 +589,10 @@ void OS_OSX::run() {
ERR_PRINT("NSException: " + String([exception reason].UTF8String));
}
};
+
+ CFRunLoopRemoveObserver(CFRunLoopGetCurrent(), pre_wait_observer, kCFRunLoopCommonModes);
+ CFRelease(pre_wait_observer);
+
main_loop->finalize();
}
diff --git a/platform/osx/platform_config.h b/platform/osx/platform_config.h
index 2d0fd872dc..7bfa466b97 100644
--- a/platform/osx/platform_config.h
+++ b/platform/osx/platform_config.h
@@ -30,4 +30,5 @@
#include <alloca.h>
+#define OPENGL_INCLUDE_H "thirdparty/glad/glad/glad.h"
#define PTHREAD_RENAME_SELF
diff --git a/platform/uwp/app_uwp.cpp b/platform/uwp/app_uwp.cpp
index 50e33e6c49..9e6ad7a63e 100644
--- a/platform/uwp/app_uwp.cpp
+++ b/platform/uwp/app_uwp.cpp
@@ -121,8 +121,7 @@ void App::SetWindow(CoreWindow ^ p_window) {
window->PointerWheelChanged +=
ref new TypedEventHandler<CoreWindow ^, PointerEventArgs ^>(this, &App::OnPointerWheelChanged);
- mouseChangedNotifier = SignalNotifier::AttachToEvent(L"os_mouse_mode_changed", ref new SignalHandler(
- this, &App::OnMouseModeChanged));
+ mouseChangedNotifier = SignalNotifier::AttachToEvent(L"os_mouse_mode_changed", ref new SignalHandler(this, &App::OnMouseModeChanged));
mouseChangedNotifier->Enable();
diff --git a/platform/uwp/detect.py b/platform/uwp/detect.py
index 28922a4f59..9c91378b22 100644
--- a/platform/uwp/detect.py
+++ b/platform/uwp/detect.py
@@ -64,14 +64,12 @@ def configure(env):
env.Append(CCFLAGS=["/MD"])
env.Append(LINKFLAGS=["/SUBSYSTEM:CONSOLE"])
env.AppendUnique(CPPDEFINES=["WINDOWS_SUBSYSTEM_CONSOLE"])
- env.Append(CPPDEFINES=["DEBUG_ENABLED"])
if env["optimize"] != "none":
env.Append(CCFLAGS=["/O2", "/Zi"])
elif env["target"] == "debug":
env.Append(CCFLAGS=["/Zi"])
env.Append(CCFLAGS=["/MDd"])
- env.Append(CPPDEFINES=["DEBUG_ENABLED"])
env.Append(LINKFLAGS=["/SUBSYSTEM:CONSOLE"])
env.AppendUnique(CPPDEFINES=["WINDOWS_SUBSYSTEM_CONSOLE"])
env.Append(LINKFLAGS=["/DEBUG"])
diff --git a/platform/uwp/export/export_plugin.cpp b/platform/uwp/export/export_plugin.cpp
index a54b85a803..192814efe4 100644
--- a/platform/uwp/export/export_plugin.cpp
+++ b/platform/uwp/export/export_plugin.cpp
@@ -376,7 +376,7 @@ Error EditorExportPlatformUWP::export_project(const Ref<EditorExportPreset> &p_p
Vector<String> cl = ((String)p_preset->get("command_line/extra_args")).strip_edges().split(" ");
for (int i = 0; i < cl.size(); i++) {
if (cl[i].strip_edges().length() == 0) {
- cl.remove(i);
+ cl.remove_at(i);
i--;
}
}
diff --git a/platform/uwp/export/export_plugin.h b/platform/uwp/export/export_plugin.h
index f295789254..acdd85e888 100644
--- a/platform/uwp/export/export_plugin.h
+++ b/platform/uwp/export/export_plugin.h
@@ -367,15 +367,15 @@ class EditorExportPlatformUWP : public EditorExportPlatform {
static bool _should_compress_asset(const String &p_path, const Vector<uint8_t> &p_data) {
/* TODO: This was copied verbatim from Android export. It should be
- * refactored to the parent class and also be used for .zip export.
- */
+ * refactored to the parent class and also be used for .zip export.
+ */
/*
- * By not compressing files with little or not benefit in doing so,
- * a performance gain is expected at runtime. Moreover, if the APK is
- * zip-aligned, assets stored as they are can be efficiently read by
- * Android by memory-mapping them.
- */
+ * By not compressing files with little or not benefit in doing so,
+ * a performance gain is expected at runtime. Moreover, if the APK is
+ * zip-aligned, assets stored as they are can be efficiently read by
+ * Android by memory-mapping them.
+ */
// -- Unconditional uncompress to mimic AAPT plus some other
diff --git a/platform/uwp/joypad_uwp.cpp b/platform/uwp/joypad_uwp.cpp
index b419fb4fae..f8eb4fc96d 100644
--- a/platform/uwp/joypad_uwp.cpp
+++ b/platform/uwp/joypad_uwp.cpp
@@ -58,12 +58,12 @@ void JoypadUWP::process_controllers() {
button_mask *= 2;
}
- input->joy_axis(joy.id, JOY_AXIS_LEFT_X, axis_correct(reading.LeftThumbstickX));
- input->joy_axis(joy.id, JOY_AXIS_LEFT_Y, axis_correct(reading.LeftThumbstickY, true));
- input->joy_axis(joy.id, JOY_AXIS_RIGHT_X, axis_correct(reading.RightThumbstickX));
- input->joy_axis(joy.id, JOY_AXIS_RIGHT_Y, axis_correct(reading.RightThumbstickY, true));
- input->joy_axis(joy.id, JOY_AXIS_TRIGGER_LEFT, axis_correct(reading.LeftTrigger, false, true));
- input->joy_axis(joy.id, JOY_AXIS_TRIGGER_RIGHT, axis_correct(reading.RightTrigger, false, true));
+ input->joy_axis(joy.id, JoyAxis::LEFT_X, axis_correct(reading.LeftThumbstickX));
+ input->joy_axis(joy.id, JoyAxis::LEFT_Y, axis_correct(reading.LeftThumbstickY, true));
+ input->joy_axis(joy.id, JoyAxis::RIGHT_X, axis_correct(reading.RightThumbstickX));
+ input->joy_axis(joy.id, JoyAxis::RIGHT_Y, axis_correct(reading.RightThumbstickY, true));
+ input->joy_axis(joy.id, JoyAxis::TRIGGER_LEFT, axis_correct(reading.LeftTrigger, false, true));
+ input->joy_axis(joy.id, JoyAxis::TRIGGER_RIGHT, axis_correct(reading.RightTrigger, false, true));
uint64_t timestamp = input->get_joy_vibration_timestamp(joy.id);
if (timestamp > joy.ff_timestamp) {
diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp
index daf3c14f3b..1114f5359a 100644
--- a/platform/uwp/os_uwp.cpp
+++ b/platform/uwp/os_uwp.cpp
@@ -161,7 +161,7 @@ Error OS_UWP::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
outside = true;
// FIXME: Hardcoded for now, add Vulkan support.
- p_video_driver = VIDEO_DRIVER_GLES2;
+ p_video_driver = VIDEO_DRIVER_OPENGL;
ContextEGL_UWP::Driver opengl_api_type = ContextEGL_UWP::GLES_2_0;
bool gl_initialization_error = false;
@@ -175,9 +175,9 @@ Error OS_UWP::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
}
if (opengl_api_type == ContextEGL_UWP::GLES_2_0) {
- if (RasterizerGLES2::is_viable() == OK) {
- RasterizerGLES2::register_config();
- RasterizerGLES2::make_current();
+ if (RasterizerGLES3::is_viable() == OK) {
+ RasterizerGLES3::register_config();
+ RasterizerGLES3::make_current();
} else {
gl_initialization_error = true;
}
@@ -319,7 +319,7 @@ void OS_UWP::finalize() {
rendering_server->finish();
memdelete(rendering_server);
-#ifdef OPENGL_ENABLED
+#ifdef GLES3_ENABLED
if (gl_context)
memdelete(gl_context);
#endif
@@ -441,12 +441,13 @@ String OS_UWP::get_name() const {
return "UWP";
}
-OS::Date OS_UWP::get_date(bool utc) const {
+OS::Date OS_UWP::get_date(bool p_utc) const {
SYSTEMTIME systemtime;
- if (utc)
+ if (utc) {
GetSystemTime(&systemtime);
- else
+ } else {
GetLocalTime(&systemtime);
+ }
Date date;
date.day = systemtime.wDay;
@@ -457,7 +458,7 @@ OS::Date OS_UWP::get_date(bool utc) const {
return date;
}
-OS::Time OS_UWP::get_time(bool utc) const {
+OS::Time OS_UWP::get_time(bool p_utc) const {
SYSTEMTIME systemtime;
if (utc)
GetSystemTime(&systemtime);
diff --git a/platform/uwp/os_uwp.h b/platform/uwp/os_uwp.h
index 7945f409a1..0b4d6b73b6 100644
--- a/platform/uwp/os_uwp.h
+++ b/platform/uwp/os_uwp.h
@@ -59,7 +59,7 @@ public:
bool alt = false, shift = false, control = false;
MessageType type = KEY_EVENT_MESSAGE;
bool pressed = false;
- Key keycode = KEY_NONE;
+ Key keycode = Key::NONE;
unsigned int physical_keycode = 0;
unsigned int unicode = 0;
bool echo = false;
@@ -107,7 +107,7 @@ private:
bool control_mem;
bool meta_mem;
bool force_quit;
- MouseButton last_button_state = MOUSE_BUTTON_NONE;
+ MouseButton last_button_state = MouseButton::NONE;
CursorShape cursor_shape;
@@ -117,11 +117,6 @@ private:
Windows::System::Display::DisplayRequest ^ display_request;
- void _post_dpad(DWORD p_dpad, int p_device, bool p_pressed);
-
- void _drag_event(int idx, UINT uMsg, WPARAM wParam, LPARAM lParam);
- void _touch_event(int idx, UINT uMsg, WPARAM wParam, LPARAM lParam);
-
ref class ManagedType {
public:
property bool alert_close_handle;
@@ -190,8 +185,8 @@ public:
virtual String get_name() const;
- virtual Date get_date(bool utc) const;
- virtual Time get_time(bool utc) const;
+ virtual Date get_date(bool p_utc) const;
+ virtual Time get_time(bool p_utc) const;
virtual TimeZoneInfo get_time_zone_info() const;
virtual uint64_t get_unix_time() const;
diff --git a/platform/windows/SCsub b/platform/windows/SCsub
index 47d8e14680..76234c3065 100644
--- a/platform/windows/SCsub
+++ b/platform/windows/SCsub
@@ -15,7 +15,7 @@ common_win = [
"joypad_windows.cpp",
"windows_terminal_logger.cpp",
"vulkan_context_win.cpp",
- "context_gl_windows.cpp",
+ "gl_manager_windows.cpp",
]
res_file = "godot_res.rc"
diff --git a/platform/windows/context_gl_windows.cpp b/platform/windows/context_gl_windows.cpp
deleted file mode 100644
index 74b12cbb3b..0000000000
--- a/platform/windows/context_gl_windows.cpp
+++ /dev/null
@@ -1,186 +0,0 @@
-/*************************************************************************/
-/* context_gl_windows.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#if defined(OPENGL_ENABLED) || defined(GLES_ENABLED)
-
-// Author: Juan Linietsky <reduzio@gmail.com>, (C) 2008
-
-#include "context_gl_windows.h"
-
-#include <dwmapi.h>
-
-#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
-#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
-#define WGL_CONTEXT_FLAGS_ARB 0x2094
-#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
-#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
-#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
-
-#if defined(__GNUC__)
-// Workaround GCC warning from -Wcast-function-type.
-#define wglGetProcAddress (void *)wglGetProcAddress
-#endif
-
-typedef HGLRC(APIENTRY *PFNWGLCREATECONTEXTATTRIBSARBPROC)(HDC, HGLRC, const int *);
-
-void ContextGL_Windows::release_current() {
- wglMakeCurrent(hDC, nullptr);
-}
-
-void ContextGL_Windows::make_current() {
- wglMakeCurrent(hDC, hRC);
-}
-
-int ContextGL_Windows::get_window_width() {
- return OS::get_singleton()->get_video_mode().width;
-}
-
-int ContextGL_Windows::get_window_height() {
- return OS::get_singleton()->get_video_mode().height;
-}
-
-void ContextGL_Windows::swap_buffers() {
- SwapBuffers(hDC);
-}
-
-void ContextGL_Windows::set_use_vsync(bool p_use) {
- if (wglSwapIntervalEXT) {
- int swap_interval = p_use ? 1 : 0;
- wglSwapIntervalEXT(swap_interval);
- }
-
- use_vsync = p_use;
-}
-
-bool ContextGL_Windows::is_using_vsync() const {
- return use_vsync;
-}
-
-#define _WGL_CONTEXT_DEBUG_BIT_ARB 0x0001
-
-Error ContextGL_Windows::initialize() {
- static PIXELFORMATDESCRIPTOR pfd = {
- sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor
- 1,
- PFD_DRAW_TO_WINDOW | // Format Must Support Window
- PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
- PFD_DOUBLEBUFFER,
- (BYTE)PFD_TYPE_RGBA,
- (BYTE)(OS::get_singleton()->is_layered_allowed() ? 32 : 24),
- (BYTE)0, (BYTE)0, (BYTE)0, (BYTE)0, (BYTE)0, (BYTE)0, // Color Bits Ignored
- (BYTE)(OS::get_singleton()->is_layered_allowed() ? 8 : 0), // Alpha Buffer
- (BYTE)0, // Shift Bit Ignored
- (BYTE)0, // No Accumulation Buffer
- (BYTE)0, (BYTE)0, (BYTE)0, (BYTE)0, // Accumulation Bits Ignored
- (BYTE)24, // 24Bit Z-Buffer (Depth Buffer)
- (BYTE)0, // No Stencil Buffer
- (BYTE)0, // No Auxiliary Buffer
- (BYTE)PFD_MAIN_PLANE, // Main Drawing Layer
- (BYTE)0, // Reserved
- 0, 0, 0 // Layer Masks Ignored
- };
-
- hDC = GetDC(hWnd);
- if (!hDC) {
- return ERR_CANT_CREATE; // Return FALSE
- }
-
- pixel_format = ChoosePixelFormat(hDC, &pfd);
- if (!pixel_format) // Did Windows Find A Matching Pixel Format?
- {
- return ERR_CANT_CREATE; // Return FALSE
- }
-
- BOOL ret = SetPixelFormat(hDC, pixel_format, &pfd);
- if (!ret) // Are We Able To Set The Pixel Format?
- {
- return ERR_CANT_CREATE; // Return FALSE
- }
-
- hRC = wglCreateContext(hDC);
- if (!hRC) // Are We Able To Get A Rendering Context?
- {
- return ERR_CANT_CREATE; // Return FALSE
- }
-
- wglMakeCurrent(hDC, hRC);
-
- if (opengl_3_context) {
- int attribs[] = {
- WGL_CONTEXT_MAJOR_VERSION_ARB, 3, //we want a 3.3 context
- WGL_CONTEXT_MINOR_VERSION_ARB, 3,
- //and it shall be forward compatible so that we can only use up to date functionality
- WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
- WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB /*| _WGL_CONTEXT_DEBUG_BIT_ARB*/,
- 0
- }; //zero indicates the end of the array
-
- PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = nullptr; //pointer to the method
- wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB");
-
- if (wglCreateContextAttribsARB == nullptr) //OpenGL 3.0 is not supported
- {
- wglDeleteContext(hRC);
- return ERR_CANT_CREATE;
- }
-
- HGLRC new_hRC = wglCreateContextAttribsARB(hDC, 0, attribs);
- if (!new_hRC) {
- wglDeleteContext(hRC);
- return ERR_CANT_CREATE; // Return false
- }
- wglMakeCurrent(hDC, nullptr);
- wglDeleteContext(hRC);
- hRC = new_hRC;
-
- if (!wglMakeCurrent(hDC, hRC)) // Try To Activate The Rendering Context
- {
- return ERR_CANT_CREATE; // Return FALSE
- }
- }
-
- wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT");
- wglGetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXTPROC)wglGetProcAddress("wglGetSwapIntervalEXT");
- //glWrapperInit(wrapper_get_proc_address);
-
- return OK;
-}
-
-ContextGL_Windows::ContextGL_Windows(HWND hwnd, bool p_opengl_3_context) {
- opengl_3_context = p_opengl_3_context;
- hWnd = hwnd;
- use_vsync = false;
- pixel_format = 0;
-}
-
-ContextGL_Windows::~ContextGL_Windows() {
-}
-
-#endif
diff --git a/platform/windows/detect.py b/platform/windows/detect.py
index 3961480d23..aaaa50e729 100644
--- a/platform/windows/detect.py
+++ b/platform/windows/detect.py
@@ -203,11 +203,11 @@ def configure_msvc(env, manual_msvc_config):
elif env["optimize"] == "size": # optimize for size
env.Append(CCFLAGS=["/O1"])
env.Append(LINKFLAGS=["/OPT:REF"])
- env.AppendUnique(CPPDEFINES=["DEBUG_ENABLED"])
elif env["target"] == "debug":
env.AppendUnique(CCFLAGS=["/Zi", "/FS", "/Od", "/EHsc"])
- env.AppendUnique(CPPDEFINES=["DEBUG_ENABLED"])
+ # Allow big objects. Only needed for debug, see MinGW branch for rationale.
+ env.AppendUnique(CCFLAGS=["/bigobj"])
env.Append(LINKFLAGS=["/DEBUG"])
if env["debug_symbols"]:
@@ -228,9 +228,9 @@ def configure_msvc(env, manual_msvc_config):
env.AppendUnique(CCFLAGS=["/MD"])
env.AppendUnique(CCFLAGS=["/Gd", "/GR", "/nologo"])
- # Force to use Unicode encoding
- env.AppendUnique(CCFLAGS=["/utf-8"])
+ env.AppendUnique(CCFLAGS=["/utf-8"]) # Force to use Unicode encoding.
env.AppendUnique(CXXFLAGS=["/TP"]) # assume all sources are C++
+
if manual_msvc_config: # should be automatic if SCons found it
if os.getenv("WindowsSdkDir") is not None:
env.Prepend(CPPPATH=[os.getenv("WindowsSdkDir") + "/Include"])
@@ -281,7 +281,7 @@ def configure_msvc(env, manual_msvc_config):
if not env["use_volk"]:
LIBS += ["vulkan"]
- # env.AppendUnique(CPPDEFINES = ['OPENGL_ENABLED'])
+ env.AppendUnique(CPPDEFINES=["GLES3_ENABLED"])
LIBS += ["opengl32"]
env.Append(LINKFLAGS=[p + env["LIBSUFFIX"] for p in LIBS])
@@ -351,7 +351,6 @@ def configure_mingw(env):
elif env["target"] == "release_debug":
env.Append(CCFLAGS=["-O2"])
- env.Append(CPPDEFINES=["DEBUG_ENABLED"])
if env["debug_symbols"]:
env.Prepend(CCFLAGS=["-g2"])
if env["optimize"] == "speed": # optimize for speed (default)
@@ -361,7 +360,10 @@ def configure_mingw(env):
elif env["target"] == "debug":
env.Append(CCFLAGS=["-g3"])
- env.Append(CPPDEFINES=["DEBUG_ENABLED"])
+ # Allow big objects. It's supposed not to have drawbacks but seems to break
+ # GCC LTO, so enabling for debug builds only (which are not built with LTO
+ # and are the only ones with too big objects).
+ env.Append(CCFLAGS=["-Wa,-mbig-obj"])
if env["windows_subsystem"] == "gui":
env.Append(LINKFLAGS=["-Wl,--subsystem,windows"])
@@ -457,8 +459,7 @@ def configure_mingw(env):
if not env["use_volk"]:
env.Append(LIBS=["vulkan"])
- ## TODO !!! Re-enable when OpenGLES Rendering Device is implemented !!!
- # env.Append(CPPDEFINES=['OPENGL_ENABLED'])
+ env.Append(CPPDEFINES=["GLES3_ENABLED"])
env.Append(LIBS=["opengl32"])
env.Append(CPPDEFINES=["MINGW_ENABLED", ("MINGW_HAS_SECURE_API", 1)])
diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp
index 905c4142a8..9fe15366f4 100644
--- a/platform/windows/display_server_windows.cpp
+++ b/platform/windows/display_server_windows.cpp
@@ -38,6 +38,15 @@
#include <avrt.h>
+#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
+#endif
+
static String format_error_message(DWORD id) {
LPWSTR messageBuffer = nullptr;
size_t size = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
@@ -533,6 +542,11 @@ void DisplayServerWindows::delete_sub_window(WindowID p_window) {
context_vulkan->window_destroy(p_window);
}
#endif
+#ifdef GLES3_ENABLED
+ if (rendering_driver == "opengl3") {
+ gl_manager->window_destroy(p_window);
+ }
+#endif
if ((tablet_get_current_driver() == "wintab") && wintab_available && windows[p_window].wtctx) {
wintab_WTClose(windows[p_window].wtctx);
@@ -542,6 +556,12 @@ void DisplayServerWindows::delete_sub_window(WindowID p_window) {
windows.erase(p_window);
}
+void DisplayServerWindows::gl_window_make_current(DisplayServer::WindowID p_window_id) {
+#if defined(GLES3_ENABLED)
+ gl_manager->window_make_current(p_window_id);
+#endif
+}
+
void DisplayServerWindows::window_attach_instance_id(ObjectID p_instance, WindowID p_window) {
_THREAD_SAFE_METHOD_
@@ -812,6 +832,11 @@ void DisplayServerWindows::window_set_size(const Size2i p_size, WindowID p_windo
context_vulkan->window_resize(p_window, w, h);
}
#endif
+#if defined(GLES3_ENABLED)
+ if (rendering_driver == "opengl3") {
+ gl_manager->window_resize(p_window, w, h);
+ }
+#endif
if (wd.fullscreen) {
return;
@@ -1475,13 +1500,13 @@ String DisplayServerWindows::keyboard_get_layout_language(int p_index) const {
}
Key DisplayServerWindows::keyboard_get_keycode_from_physical(Key p_keycode) const {
- unsigned int modifiers = p_keycode & KEY_MODIFIER_MASK;
- Key keycode_no_mod = (Key)(p_keycode & KEY_CODE_MASK);
+ Key modifiers = p_keycode & KeyModifierMask::MODIFIER_MASK;
+ Key keycode_no_mod = (Key)(p_keycode & KeyModifierMask::CODE_MASK);
- if (keycode_no_mod == KEY_PRINT ||
- keycode_no_mod == KEY_KP_ADD ||
- keycode_no_mod == KEY_KP_5 ||
- (keycode_no_mod >= KEY_0 && keycode_no_mod <= KEY_9)) {
+ if (keycode_no_mod == Key::PRINT ||
+ keycode_no_mod == Key::KP_ADD ||
+ keycode_no_mod == Key::KP_5 ||
+ (keycode_no_mod >= Key::KEY_0 && keycode_no_mod <= Key::KEY_9)) {
return p_keycode;
}
@@ -1501,10 +1526,10 @@ Key DisplayServerWindows::keyboard_get_keycode_from_physical(Key p_keycode) cons
// we limit these to ASCII to fix some layouts, including Arabic ones
if (char_code >= 32 && char_code <= 127) {
// Godot uses 'braces' instead of 'brackets'
- if (char_code == KEY_BRACKETLEFT || char_code == KEY_BRACKETRIGHT) {
+ if (char_code == (unsigned int)Key::BRACKETLEFT || char_code == (unsigned int)Key::BRACKETRIGHT) {
char_code += 32;
}
- return (Key)(char_code | modifiers);
+ return (Key)(char_code | (unsigned int)modifiers);
}
return (Key)(KeyMappingWindows::get_keysym(vk) | modifiers);
@@ -1591,6 +1616,9 @@ void DisplayServerWindows::make_rendering_thread() {
}
void DisplayServerWindows::swap_buffers() {
+#if defined(GLES3_ENABLED)
+ gl_manager->swap_buffers();
+#endif
}
void DisplayServerWindows::set_native_icon(const String &p_filename) {
@@ -1742,17 +1770,18 @@ void DisplayServerWindows::set_icon(const Ref<Image> &p_icon) {
void DisplayServerWindows::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);
+ // TODO disabling for now
+ //context_vulkan->set_vsync_mode(p_window, p_vsync_mode);
#endif
}
DisplayServer::VSyncMode DisplayServerWindows::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;
+ //TODO disabling for now
+ //return context_vulkan->get_vsync_mode(p_window);
#endif
+ return DisplayServer::VSYNC_ENABLED;
}
void DisplayServerWindows::set_context(Context p_context) {
@@ -2437,41 +2466,41 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
switch (uMsg) {
case WM_LBUTTONDOWN: {
mb->set_pressed(true);
- mb->set_button_index(MOUSE_BUTTON_LEFT);
+ mb->set_button_index(MouseButton::LEFT);
} break;
case WM_LBUTTONUP: {
mb->set_pressed(false);
- mb->set_button_index(MOUSE_BUTTON_LEFT);
+ mb->set_button_index(MouseButton::LEFT);
} break;
case WM_MBUTTONDOWN: {
mb->set_pressed(true);
- mb->set_button_index(MOUSE_BUTTON_MIDDLE);
+ mb->set_button_index(MouseButton::MIDDLE);
} break;
case WM_MBUTTONUP: {
mb->set_pressed(false);
- mb->set_button_index(MOUSE_BUTTON_MIDDLE);
+ mb->set_button_index(MouseButton::MIDDLE);
} break;
case WM_RBUTTONDOWN: {
mb->set_pressed(true);
- mb->set_button_index(MOUSE_BUTTON_RIGHT);
+ mb->set_button_index(MouseButton::RIGHT);
} break;
case WM_RBUTTONUP: {
mb->set_pressed(false);
- mb->set_button_index(MOUSE_BUTTON_RIGHT);
+ mb->set_button_index(MouseButton::RIGHT);
} break;
case WM_LBUTTONDBLCLK: {
mb->set_pressed(true);
- mb->set_button_index(MOUSE_BUTTON_LEFT);
+ mb->set_button_index(MouseButton::LEFT);
mb->set_double_click(true);
} break;
case WM_RBUTTONDBLCLK: {
mb->set_pressed(true);
- mb->set_button_index(MOUSE_BUTTON_RIGHT);
+ mb->set_button_index(MouseButton::RIGHT);
mb->set_double_click(true);
} break;
case WM_MBUTTONDBLCLK: {
mb->set_pressed(true);
- mb->set_button_index(MOUSE_BUTTON_MIDDLE);
+ mb->set_button_index(MouseButton::MIDDLE);
mb->set_double_click(true);
} break;
case WM_MOUSEWHEEL: {
@@ -2482,9 +2511,9 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
}
if (motion > 0) {
- mb->set_button_index(MOUSE_BUTTON_WHEEL_UP);
+ mb->set_button_index(MouseButton::WHEEL_UP);
} else {
- mb->set_button_index(MOUSE_BUTTON_WHEEL_DOWN);
+ mb->set_button_index(MouseButton::WHEEL_DOWN);
}
mb->set_factor(fabs((double)motion / (double)WHEEL_DELTA));
} break;
@@ -2496,34 +2525,34 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
}
if (motion < 0) {
- mb->set_button_index(MOUSE_BUTTON_WHEEL_LEFT);
+ mb->set_button_index(MouseButton::WHEEL_LEFT);
} else {
- mb->set_button_index(MOUSE_BUTTON_WHEEL_RIGHT);
+ mb->set_button_index(MouseButton::WHEEL_RIGHT);
}
mb->set_factor(fabs((double)motion / (double)WHEEL_DELTA));
} break;
case WM_XBUTTONDOWN: {
mb->set_pressed(true);
if (HIWORD(wParam) == XBUTTON1) {
- mb->set_button_index(MOUSE_BUTTON_XBUTTON1);
+ mb->set_button_index(MouseButton::MB_XBUTTON1);
} else {
- mb->set_button_index(MOUSE_BUTTON_XBUTTON2);
+ mb->set_button_index(MouseButton::MB_XBUTTON2);
}
} break;
case WM_XBUTTONUP: {
mb->set_pressed(false);
if (HIWORD(wParam) == XBUTTON1) {
- mb->set_button_index(MOUSE_BUTTON_XBUTTON1);
+ mb->set_button_index(MouseButton::MB_XBUTTON1);
} else {
- mb->set_button_index(MOUSE_BUTTON_XBUTTON2);
+ mb->set_button_index(MouseButton::MB_XBUTTON2);
}
} break;
case WM_XBUTTONDBLCLK: {
mb->set_pressed(true);
if (HIWORD(wParam) == XBUTTON1) {
- mb->set_button_index(MOUSE_BUTTON_XBUTTON1);
+ mb->set_button_index(MouseButton::MB_XBUTTON1);
} else {
- mb->set_button_index(MOUSE_BUTTON_XBUTTON2);
+ mb->set_button_index(MouseButton::MB_XBUTTON2);
}
mb->set_double_click(true);
} break;
@@ -2537,9 +2566,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 |= MouseButton(1 << (mb->get_button_index() - 1));
+ last_button_state |= mouse_button_to_mask(mb->get_button_index());
} else {
- last_button_state &= (MouseButton) ~(1 << (mb->get_button_index() - 1));
+ last_button_state &= ~mouse_button_to_mask(mb->get_button_index());
}
mb->set_button_mask(last_button_state);
@@ -2575,11 +2604,11 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
mb->set_global_position(mb->get_position());
Input::get_singleton()->parse_input_event(mb);
- if (mb->is_pressed() && mb->get_button_index() > 3 && mb->get_button_index() < 8) {
+ if (mb->is_pressed() && mb->get_button_index() >= MouseButton::WHEEL_UP && mb->get_button_index() <= MouseButton::WHEEL_RIGHT) {
// Send release for mouse wheel.
Ref<InputEventMouseButton> mbd = mb->duplicate();
mbd->set_window_id(window_id);
- last_button_state &= (MouseButton) ~(1 << (mbd->get_button_index() - 1));
+ last_button_state &= ~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);
@@ -2929,7 +2958,7 @@ void DisplayServerWindows::_process_key_events() {
if ((ke.lParam & (1 << 24)) && (ke.wParam == VK_RETURN)) {
// Special case for Numpad Enter key.
- k->set_keycode(KEY_KP_ENTER);
+ k->set_keycode(Key::KP_ENTER);
} else {
k->set_keycode((Key)KeyMappingWindows::get_keysym(ke.wParam));
}
@@ -3086,6 +3115,13 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode,
}
#endif
+#ifdef GLES3_ENABLED
+ if (rendering_driver == "opengl3") {
+ Error err = gl_manager->window_create(id, wd.hWnd, hInstance, WindowRect.right - WindowRect.left, WindowRect.bottom - WindowRect.top);
+ ERR_FAIL_COND_V_MSG(err != OK, INVALID_WINDOW_ID, "Failed to create an OpenGL window.");
+ }
+#endif
+
RegisterTouchWindow(wd.hWnd, 0);
TRACKMOUSEEVENT tme;
@@ -3216,6 +3252,8 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
outside = true;
+ rendering_driver = p_rendering_driver;
+
// Note: Wacom WinTab driver API for pen input, for devices incompatible with Windows Ink.
HMODULE wintab_lib = LoadLibraryW(L"wintab32.dll");
if (wintab_lib) {
@@ -3292,8 +3330,6 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
use_raw_input = false;
}
- rendering_driver = "vulkan";
-
#if defined(VULKAN_ENABLED)
if (rendering_driver == "vulkan") {
context_vulkan = memnew(VulkanContextWindows);
@@ -3305,27 +3341,23 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
}
}
#endif
+ // Init context and rendering device
+#if defined(GLES3_ENABLED)
-#if defined(OPENGL_ENABLED)
- if (rendering_driver_index == VIDEO_DRIVER_GLES2) {
- context_gles2 = memnew(ContextGL_Windows(hWnd, false));
+ if (rendering_driver == "opengl3") {
+ GLManager_Windows::ContextType opengl_api_type = GLManager_Windows::GLES_3_0_COMPATIBLE;
- if (context_gles2->initialize() != OK) {
- memdelete(context_gles2);
- context_gles2 = nullptr;
- ERR_FAIL_V(ERR_UNAVAILABLE);
- }
-
- context_gles2->set_use_vsync(video_mode.use_vsync);
+ gl_manager = memnew(GLManager_Windows(opengl_api_type));
- if (RasterizerGLES2::is_viable() == OK) {
- RasterizerGLES2::register_config();
- RasterizerGLES2::make_current();
- } else {
- memdelete(context_gles2);
- context_gles2 = nullptr;
- ERR_FAIL_V(ERR_UNAVAILABLE);
+ if (gl_manager->initialize() != OK) {
+ memdelete(gl_manager);
+ gl_manager = nullptr;
+ r_error = ERR_UNAVAILABLE;
+ return;
}
+
+ // gl_manager->set_use_vsync(current_videomode.use_vsync);
+ RasterizerGLES3::make_current();
}
#endif
@@ -3386,8 +3418,8 @@ Vector<String> DisplayServerWindows::get_rendering_drivers_func() {
#ifdef VULKAN_ENABLED
drivers.push_back("vulkan");
#endif
-#ifdef OPENGL_ENABLED
- drivers.push_back("opengl");
+#ifdef GLES3_ENABLED
+ drivers.push_back("opengl3");
#endif
return drivers;
@@ -3396,7 +3428,7 @@ Vector<String> DisplayServerWindows::get_rendering_drivers_func() {
DisplayServer *DisplayServerWindows::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
DisplayServer *ds = memnew(DisplayServerWindows(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error));
if (r_error != OK) {
- OS::get_singleton()->alert("Your video card driver does not support any of the supported Vulkan versions.\n"
+ OS::get_singleton()->alert("Your video card driver does not support any of the supported Vulkan or OpenGL versions.\n"
"Please update your drivers or if you have a very old or integrated GPU upgrade it.",
"Unable to initialize Video driver");
}
@@ -3417,6 +3449,10 @@ DisplayServerWindows::~DisplayServerWindows() {
SetWindowLongPtr(windows[MAIN_WINDOW_ID].hWnd, GWLP_WNDPROC, (LONG_PTR)user_proc);
};
+#ifdef GLES3_ENABLED
+ // destroy windows .. NYI?
+#endif
+
if (windows.has(MAIN_WINDOW_ID)) {
#ifdef VULKAN_ENABLED
if (rendering_driver == "vulkan") {
@@ -3445,4 +3481,10 @@ DisplayServerWindows::~DisplayServerWindows() {
if (restore_mouse_trails > 1) {
SystemParametersInfoA(SPI_SETMOUSETRAILS, restore_mouse_trails, 0, 0);
}
+#ifdef GLES3_ENABLED
+ if (gl_manager) {
+ memdelete(gl_manager);
+ gl_manager = nullptr;
+ }
+#endif
}
diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h
index 6a90b28579..a59f8ebb44 100644
--- a/platform/windows/display_server_windows.h
+++ b/platform/windows/display_server_windows.h
@@ -51,15 +51,15 @@
#include "drivers/xaudio2/audio_driver_xaudio2.h"
#endif
-#if defined(OPENGL_ENABLED)
-#include "context_gl_windows.h"
-#endif
-
#if defined(VULKAN_ENABLED)
#include "drivers/vulkan/rendering_device_vulkan.h"
#include "platform/windows/vulkan_context_win.h"
#endif
+#if defined(GLES3_ENABLED)
+#include "gl_manager_windows.h"
+#endif
+
#include <fcntl.h>
#include <io.h>
#include <stdio.h>
@@ -304,8 +304,8 @@ class DisplayServerWindows : public DisplayServer {
int old_x, old_y;
Point2i center;
-#if defined(OPENGL_ENABLED)
- ContextGL_Windows *context_gles2;
+#if defined(GLES3_ENABLED)
+ GLManager_Windows *gl_manager;
#endif
#if defined(VULKAN_ENABLED)
@@ -410,7 +410,7 @@ class DisplayServerWindows : public DisplayServer {
bool shift_mem = false;
bool control_mem = false;
bool meta_mem = false;
- MouseButton last_button_state = MOUSE_BUTTON_NONE;
+ MouseButton last_button_state = MouseButton::NONE;
bool use_raw_input = false;
bool drop_events = false;
bool in_dispatch_input_event = false;
@@ -462,7 +462,7 @@ public:
virtual bool screen_is_touchscreen(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
virtual void screen_set_orientation(ScreenOrientation p_orientation, int p_screen = SCREEN_OF_MAIN_WINDOW) override;
- ScreenOrientation screen_get_orientation(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
+ virtual ScreenOrientation screen_get_orientation(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;
@@ -477,6 +477,7 @@ public:
virtual void window_attach_instance_id(ObjectID p_instance, WindowID p_window = MAIN_WINDOW_ID) override;
virtual ObjectID window_get_attached_instance_id(WindowID p_window = MAIN_WINDOW_ID) const override;
+ virtual void gl_window_make_current(DisplayServer::WindowID p_window_id);
virtual void window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override;
diff --git a/platform/windows/gl_manager_windows.cpp b/platform/windows/gl_manager_windows.cpp
new file mode 100644
index 0000000000..fe98f8b0ba
--- /dev/null
+++ b/platform/windows/gl_manager_windows.cpp
@@ -0,0 +1,346 @@
+/*************************************************************************/
+/* gl_manager_windows.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "gl_manager_windows.h"
+
+#ifdef WINDOWS_ENABLED
+#ifdef GLES3_ENABLED
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <dwmapi.h>
+
+#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
+#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
+#define WGL_CONTEXT_FLAGS_ARB 0x2094
+#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
+#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
+#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
+
+#define _WGL_CONTEXT_DEBUG_BIT_ARB 0x0001
+
+#if defined(__GNUC__)
+// Workaround GCC warning from -Wcast-function-type.
+#define wglGetProcAddress (void *)wglGetProcAddress
+#endif
+
+typedef HGLRC(APIENTRY *PFNWGLCREATECONTEXTATTRIBSARBPROC)(HDC, HGLRC, const int *);
+
+int GLManager_Windows::_find_or_create_display(GLWindow &win) {
+ // find display NYI, only 1 supported so far
+ if (_displays.size())
+ return 0;
+
+ // for (unsigned int n = 0; n < _displays.size(); n++) {
+ // const GLDisplay &d = _displays[n];
+ // if (d.x11_display == p_x11_display)
+ // return n;
+ // }
+
+ // create
+ GLDisplay d_temp = {};
+ _displays.push_back(d_temp);
+ int new_display_id = _displays.size() - 1;
+
+ // create context
+ GLDisplay &d = _displays[new_display_id];
+ Error err = _create_context(win, d);
+
+ if (err != OK) {
+ // not good
+ // delete the _display?
+ _displays.remove_at(new_display_id);
+ return -1;
+ }
+
+ return new_display_id;
+}
+
+Error GLManager_Windows::_create_context(GLWindow &win, GLDisplay &gl_display) {
+ static PIXELFORMATDESCRIPTOR pfd = {
+ sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor
+ 1,
+ PFD_DRAW_TO_WINDOW | // Format Must Support Window
+ PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
+ PFD_DOUBLEBUFFER,
+ (BYTE)PFD_TYPE_RGBA,
+ (BYTE)(OS::get_singleton()->is_layered_allowed() ? 32 : 24),
+ (BYTE)0, (BYTE)0, (BYTE)0, (BYTE)0, (BYTE)0, (BYTE)0, // Color Bits Ignored
+ (BYTE)(OS::get_singleton()->is_layered_allowed() ? 8 : 0), // Alpha Buffer
+ (BYTE)0, // Shift Bit Ignored
+ (BYTE)0, // No Accumulation Buffer
+ (BYTE)0, (BYTE)0, (BYTE)0, (BYTE)0, // Accumulation Bits Ignored
+ (BYTE)24, // 24Bit Z-Buffer (Depth Buffer)
+ (BYTE)0, // No Stencil Buffer
+ (BYTE)0, // No Auxiliary Buffer
+ (BYTE)PFD_MAIN_PLANE, // Main Drawing Layer
+ (BYTE)0, // Reserved
+ 0, 0, 0 // Layer Masks Ignored
+ };
+
+ // alias
+ HDC hDC = win.hDC;
+
+ int pixel_format = ChoosePixelFormat(hDC, &pfd);
+ if (!pixel_format) // Did Windows Find A Matching Pixel Format?
+ {
+ return ERR_CANT_CREATE; // Return FALSE
+ }
+
+ BOOL ret = SetPixelFormat(hDC, pixel_format, &pfd);
+ if (!ret) // Are We Able To Set The Pixel Format?
+ {
+ return ERR_CANT_CREATE; // Return FALSE
+ }
+
+ gl_display.hRC = wglCreateContext(hDC);
+ if (!gl_display.hRC) // Are We Able To Get A Rendering Context?
+ {
+ return ERR_CANT_CREATE; // Return FALSE
+ }
+
+ wglMakeCurrent(hDC, gl_display.hRC);
+
+ int attribs[] = {
+ WGL_CONTEXT_MAJOR_VERSION_ARB, 3, //we want a 3.3 context
+ WGL_CONTEXT_MINOR_VERSION_ARB, 3,
+ //and it shall be forward compatible so that we can only use up to date functionality
+ WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
+ WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB /*| _WGL_CONTEXT_DEBUG_BIT_ARB*/,
+ 0
+ }; //zero indicates the end of the array
+
+ PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = nullptr; //pointer to the method
+ wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB");
+
+ if (wglCreateContextAttribsARB == nullptr) //OpenGL 3.0 is not supported
+ {
+ wglDeleteContext(gl_display.hRC);
+ gl_display.hRC = 0;
+ return ERR_CANT_CREATE;
+ }
+
+ HGLRC new_hRC = wglCreateContextAttribsARB(hDC, 0, attribs);
+ if (!new_hRC) {
+ wglDeleteContext(gl_display.hRC);
+ gl_display.hRC = 0;
+ return ERR_CANT_CREATE; // Return false
+ }
+ wglMakeCurrent(hDC, nullptr);
+ wglDeleteContext(gl_display.hRC);
+ gl_display.hRC = new_hRC;
+
+ if (!wglMakeCurrent(hDC, gl_display.hRC)) // Try To Activate The Rendering Context
+ {
+ wglDeleteContext(gl_display.hRC);
+ gl_display.hRC = 0;
+ return ERR_CANT_CREATE; // Return FALSE
+ }
+
+ return OK;
+}
+
+Error GLManager_Windows::window_create(DisplayServer::WindowID p_window_id, HWND p_hwnd, HINSTANCE p_hinstance, int p_width, int p_height) {
+ HDC hdc = GetDC(p_hwnd);
+ if (!hdc) {
+ return ERR_CANT_CREATE; // Return FALSE
+ }
+
+ // make sure vector is big enough...
+ // we can mirror the external vector, it is simpler
+ // to keep the IDs identical for fast lookup
+ if (p_window_id >= (int)_windows.size()) {
+ _windows.resize(p_window_id + 1);
+ }
+
+ GLWindow &win = _windows[p_window_id];
+ win.in_use = true;
+ win.window_id = p_window_id;
+ win.width = p_width;
+ win.height = p_height;
+ win.hwnd = p_hwnd;
+ win.hDC = hdc;
+
+ win.gldisplay_id = _find_or_create_display(win);
+
+ if (win.gldisplay_id == -1) {
+ // release DC?
+ _windows.remove_at(_windows.size() - 1);
+ return FAILED;
+ }
+
+ // make current
+ window_make_current(_windows.size() - 1);
+
+ return OK;
+}
+
+void GLManager_Windows::_internal_set_current_window(GLWindow *p_win) {
+ _current_window = p_win;
+}
+
+void GLManager_Windows::window_resize(DisplayServer::WindowID p_window_id, int p_width, int p_height) {
+ get_window(p_window_id).width = p_width;
+ get_window(p_window_id).height = p_height;
+}
+
+int GLManager_Windows::window_get_width(DisplayServer::WindowID p_window_id) {
+ return get_window(p_window_id).width;
+}
+
+int GLManager_Windows::window_get_height(DisplayServer::WindowID p_window_id) {
+ return get_window(p_window_id).height;
+}
+
+void GLManager_Windows::window_destroy(DisplayServer::WindowID p_window_id) {
+ GLWindow &win = get_window(p_window_id);
+ win.in_use = false;
+
+ if (_current_window == &win) {
+ _current_window = nullptr;
+ }
+}
+
+void GLManager_Windows::release_current() {
+ if (!_current_window)
+ return;
+
+ wglMakeCurrent(_current_window->hDC, nullptr);
+}
+
+void GLManager_Windows::window_make_current(DisplayServer::WindowID p_window_id) {
+ if (p_window_id == -1)
+ return;
+
+ GLWindow &win = _windows[p_window_id];
+ if (!win.in_use)
+ return;
+
+ // noop
+ if (&win == _current_window)
+ return;
+
+ const GLDisplay &disp = get_display(win.gldisplay_id);
+ wglMakeCurrent(win.hDC, disp.hRC);
+
+ _internal_set_current_window(&win);
+}
+
+void GLManager_Windows::make_current() {
+ if (!_current_window)
+ return;
+ if (!_current_window->in_use) {
+ WARN_PRINT("current window not in use!");
+ return;
+ }
+ const GLDisplay &disp = get_current_display();
+ wglMakeCurrent(_current_window->hDC, disp.hRC);
+}
+
+void GLManager_Windows::swap_buffers() {
+ // NO NEED TO CALL SWAP BUFFERS for each window...
+ // see https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glXSwapBuffers.xml
+
+ if (!_current_window)
+ return;
+ if (!_current_window->in_use) {
+ WARN_PRINT("current window not in use!");
+ return;
+ }
+
+ // print_line("\tswap_buffers");
+
+ // only for debugging without drawing anything
+ // glClearColor(Math::randf(), 0, 1, 1);
+ //glClear(GL_COLOR_BUFFER_BIT);
+
+ // const GLDisplay &disp = get_current_display();
+ SwapBuffers(_current_window->hDC);
+}
+
+Error GLManager_Windows::initialize() {
+ wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT");
+ wglGetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXTPROC)wglGetProcAddress("wglGetSwapIntervalEXT");
+ //glWrapperInit(wrapper_get_proc_address);
+
+ 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");
+ }
+ 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;
+ use_vsync = p_use;
+ */
+}
+
+bool GLManager_Windows::is_using_vsync() const {
+ return use_vsync;
+}
+
+GLManager_Windows::GLManager_Windows(ContextType p_context_type) {
+ context_type = p_context_type;
+
+ direct_render = false;
+ glx_minor = glx_major = 0;
+ use_vsync = false;
+ _current_window = nullptr;
+}
+
+GLManager_Windows::~GLManager_Windows() {
+ release_current();
+}
+
+#endif // GLES3_ENABLED
+#endif // WINDOWS
diff --git a/platform/windows/context_gl_windows.h b/platform/windows/gl_manager_windows.h
index feff1d825b..9733a57420 100644
--- a/platform/windows/context_gl_windows.h
+++ b/platform/windows/gl_manager_windows.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* context_gl_windows.h */
+/* gl_manager_windows.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,50 +28,100 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#if defined(OPENGL_ENABLED) || defined(GLES_ENABLED)
+#ifndef GL_MANAGER_WINDOWS_H
+#define GL_MANAGER_WINDOWS_H
-// Author: Juan Linietsky <reduzio@gmail.com>, (C) 2008
-
-#ifndef CONTEXT_GL_WIN_H
-#define CONTEXT_GL_WIN_H
+#if defined(WINDOWS_ENABLED) && defined(GLES3_ENABLED)
#include "core/error/error_list.h"
#include "core/os/os.h"
+#include "core/templates/local_vector.h"
+#include "servers/display_server.h"
-#define WIN32_LEAN_AND_MEAN
#include <windows.h>
typedef bool(APIENTRY *PFNWGLSWAPINTERVALEXTPROC)(int interval);
typedef int(APIENTRY *PFNWGLGETSWAPINTERVALEXTPROC)(void);
-class ContextGL_Windows {
- HDC hDC;
- HGLRC hRC;
- unsigned int pixel_format;
- HWND hWnd;
- bool opengl_3_context;
- bool use_vsync;
+class GLManager_Windows {
+public:
+ enum ContextType {
+ GLES_3_0_COMPATIBLE,
+ };
+
+private:
+ // any data specific to the window
+ struct GLWindow {
+ GLWindow() { in_use = false; }
+ bool in_use;
+
+ // the external ID .. should match the GL window number .. unused I think
+ DisplayServer::WindowID window_id;
+ int width;
+ int height;
+
+ // windows specific
+ HDC hDC;
+ HWND hwnd;
+
+ int gldisplay_id;
+ };
+
+ struct GLDisplay {
+ // windows specific
+ HGLRC hRC;
+ };
+
+ LocalVector<GLWindow> _windows;
+ LocalVector<GLDisplay> _displays;
+
+ GLWindow *_current_window;
PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT;
PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT;
+ // funcs
+ void _internal_set_current_window(GLWindow *p_win);
+
+ GLWindow &get_window(unsigned int id) { return _windows[id]; }
+ const GLWindow &get_window(unsigned int id) const { return _windows[id]; }
+
+ const GLDisplay &get_current_display() const { return _displays[_current_window->gldisplay_id]; }
+ const GLDisplay &get_display(unsigned int id) { return _displays[id]; }
+
+ bool direct_render;
+ int glx_minor, glx_major;
+ bool use_vsync;
+ ContextType context_type;
+
+private:
+ int _find_or_create_display(GLWindow &win);
+ Error _create_context(GLWindow &win, GLDisplay &gl_display);
+
public:
- void release_current();
+ Error window_create(DisplayServer::WindowID p_window_id, HWND p_hwnd, HINSTANCE p_hinstance, 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);
- void make_current();
+ // get directly from the cached GLWindow
+ int window_get_width(DisplayServer::WindowID p_window_id = 0);
+ int window_get_height(DisplayServer::WindowID p_window_id = 0);
- int get_window_width();
- int get_window_height();
+ void release_current();
+ void make_current();
void swap_buffers();
+ void window_make_current(DisplayServer::WindowID p_window_id);
+
Error initialize();
void set_use_vsync(bool p_use);
bool is_using_vsync() const;
- ContextGL_Windows(HWND hwnd, bool p_opengl_3_context);
- ~ContextGL_Windows();
+ GLManager_Windows(ContextType p_context_type);
+ ~GLManager_Windows();
};
-#endif
-#endif
+#endif // defined(WINDOWS_ENABLED) && defined(GLES3_ENABLED)
+
+#endif // GL_MANAGER_WINDOWS_H
diff --git a/platform/windows/joypad_windows.cpp b/platform/windows/joypad_windows.cpp
index 94da63e49d..1d3761ee83 100644
--- a/platform/windows/joypad_windows.cpp
+++ b/platform/windows/joypad_windows.cpp
@@ -334,12 +334,12 @@ void JoypadWindows::process_joypads() {
button_mask = button_mask * 2;
}
- input->joy_axis(joy.id, JOY_AXIS_LEFT_X, axis_correct(joy.state.Gamepad.sThumbLX, true));
- input->joy_axis(joy.id, JOY_AXIS_LEFT_Y, axis_correct(joy.state.Gamepad.sThumbLY, true, false, true));
- input->joy_axis(joy.id, JOY_AXIS_RIGHT_X, axis_correct(joy.state.Gamepad.sThumbRX, true));
- input->joy_axis(joy.id, JOY_AXIS_RIGHT_Y, axis_correct(joy.state.Gamepad.sThumbRY, true, false, true));
- input->joy_axis(joy.id, JOY_AXIS_TRIGGER_LEFT, axis_correct(joy.state.Gamepad.bLeftTrigger, true, true));
- input->joy_axis(joy.id, JOY_AXIS_TRIGGER_RIGHT, axis_correct(joy.state.Gamepad.bRightTrigger, true, true));
+ input->joy_axis(joy.id, JoyAxis::LEFT_X, axis_correct(joy.state.Gamepad.sThumbLX, true));
+ input->joy_axis(joy.id, JoyAxis::LEFT_Y, axis_correct(joy.state.Gamepad.sThumbLY, true, false, true));
+ input->joy_axis(joy.id, JoyAxis::RIGHT_X, axis_correct(joy.state.Gamepad.sThumbRX, true));
+ input->joy_axis(joy.id, JoyAxis::RIGHT_Y, axis_correct(joy.state.Gamepad.sThumbRY, true, false, true));
+ input->joy_axis(joy.id, JoyAxis::TRIGGER_LEFT, axis_correct(joy.state.Gamepad.bLeftTrigger, true, true));
+ input->joy_axis(joy.id, JoyAxis::TRIGGER_RIGHT, axis_correct(joy.state.Gamepad.bRightTrigger, true, true));
joy.last_packet = joy.state.dwPacketNumber;
}
uint64_t timestamp = input->get_joy_vibration_timestamp(joy.id);
@@ -417,31 +417,31 @@ void JoypadWindows::post_hat(int p_device, DWORD p_dpad) {
// 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::HAT_MASK_CENTER;
+ dpad_val = (HatMask)HatMask::CENTER;
}
if (p_dpad == 0) {
- dpad_val = (HatMask)HatMask::HAT_MASK_UP;
+ dpad_val = (HatMask)HatMask::UP;
} else if (p_dpad == 4500) {
- dpad_val = (HatMask)(HatMask::HAT_MASK_UP | HatMask::HAT_MASK_RIGHT);
+ dpad_val = (HatMask)(HatMask::UP | HatMask::RIGHT);
} else if (p_dpad == 9000) {
- dpad_val = (HatMask)HatMask::HAT_MASK_RIGHT;
+ dpad_val = (HatMask)HatMask::RIGHT;
} else if (p_dpad == 13500) {
- dpad_val = (HatMask)(HatMask::HAT_MASK_RIGHT | HatMask::HAT_MASK_DOWN);
+ dpad_val = (HatMask)(HatMask::RIGHT | HatMask::DOWN);
} else if (p_dpad == 18000) {
- dpad_val = (HatMask)HatMask::HAT_MASK_DOWN;
+ dpad_val = (HatMask)HatMask::DOWN;
} else if (p_dpad == 22500) {
- dpad_val = (HatMask)(HatMask::HAT_MASK_DOWN | HatMask::HAT_MASK_LEFT);
+ dpad_val = (HatMask)(HatMask::DOWN | HatMask::LEFT);
} else if (p_dpad == 27000) {
- dpad_val = (HatMask)HatMask::HAT_MASK_LEFT;
+ dpad_val = (HatMask)HatMask::LEFT;
} else if (p_dpad == 31500) {
- dpad_val = (HatMask)(HatMask::HAT_MASK_LEFT | HatMask::HAT_MASK_UP);
+ dpad_val = (HatMask)(HatMask::LEFT | HatMask::UP);
}
input->joy_hat(p_device, dpad_val);
};
diff --git a/platform/windows/key_mapping_windows.cpp b/platform/windows/key_mapping_windows.cpp
index 8016d20470..65ee5dd46b 100644
--- a/platform/windows/key_mapping_windows.cpp
+++ b/platform/windows/key_mapping_windows.cpp
@@ -33,200 +33,200 @@
#include <stdio.h>
struct _WinTranslatePair {
- unsigned int keysym;
+ Key keysym;
unsigned int keycode;
};
static _WinTranslatePair _vk_to_keycode[] = {
- { KEY_BACKSPACE, VK_BACK }, // (0x08) // backspace
- { KEY_TAB, VK_TAB }, //(0x09)
+ { Key::BACKSPACE, VK_BACK }, // (0x08) // backspace
+ { Key::TAB, VK_TAB }, //(0x09)
//VK_CLEAR (0x0C)
- { KEY_ENTER, VK_RETURN }, //(0x0D)
+ { Key::ENTER, VK_RETURN }, //(0x0D)
- { KEY_SHIFT, VK_SHIFT }, //(0x10)
+ { Key::SHIFT, VK_SHIFT }, //(0x10)
- { KEY_CTRL, VK_CONTROL }, //(0x11)
+ { Key::CTRL, VK_CONTROL }, //(0x11)
- { KEY_ALT, VK_MENU }, //(0x12)
+ { Key::ALT, VK_MENU }, //(0x12)
- { KEY_PAUSE, VK_PAUSE }, //(0x13)
+ { Key::PAUSE, VK_PAUSE }, //(0x13)
- { KEY_CAPSLOCK, VK_CAPITAL }, //(0x14)
+ { Key::CAPSLOCK, VK_CAPITAL }, //(0x14)
- { KEY_ESCAPE, VK_ESCAPE }, //(0x1B)
+ { Key::ESCAPE, VK_ESCAPE }, //(0x1B)
- { KEY_SPACE, VK_SPACE }, //(0x20)
+ { Key::SPACE, VK_SPACE }, //(0x20)
- { KEY_PAGEUP, VK_PRIOR }, //(0x21)
+ { Key::PAGEUP, VK_PRIOR }, //(0x21)
- { KEY_PAGEDOWN, VK_NEXT }, //(0x22)
+ { Key::PAGEDOWN, VK_NEXT }, //(0x22)
- { KEY_END, VK_END }, //(0x23)
+ { Key::END, VK_END }, //(0x23)
- { KEY_HOME, VK_HOME }, //(0x24)
+ { Key::HOME, VK_HOME }, //(0x24)
- { KEY_LEFT, VK_LEFT }, //(0x25)
+ { Key::LEFT, VK_LEFT }, //(0x25)
- { KEY_UP, VK_UP }, //(0x26)
+ { Key::UP, VK_UP }, //(0x26)
- { KEY_RIGHT, VK_RIGHT }, //(0x27)
+ { Key::RIGHT, VK_RIGHT }, //(0x27)
- { KEY_DOWN, VK_DOWN }, // (0x28)
+ { Key::DOWN, VK_DOWN }, // (0x28)
//VK_SELECT (0x29)
- { KEY_PRINT, VK_PRINT }, // (0x2A)
+ { Key::PRINT, VK_PRINT }, // (0x2A)
//VK_EXECUTE (0x2B)
- { KEY_PRINT, VK_SNAPSHOT }, // (0x2C)
-
- { KEY_INSERT, VK_INSERT }, // (0x2D)
-
- { KEY_DELETE, VK_DELETE }, // (0x2E)
-
- { KEY_HELP, VK_HELP }, // (0x2F)
-
- { KEY_0, (0x30) }, ////0 key
- { KEY_1, (0x31) }, ////1 key
- { KEY_2, (0x32) }, ////2 key
- { KEY_3, (0x33) }, ////3 key
- { KEY_4, (0x34) }, ////4 key
- { KEY_5, (0x35) }, ////5 key
- { KEY_6, (0x36) }, ////6 key
- { KEY_7, (0x37) }, ////7 key
- { KEY_8, (0x38) }, ////8 key
- { KEY_9, (0x39) }, ////9 key
- { 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_MASK_META, VK_LWIN }, //(0x5B)
- { KEY_MASK_META, VK_RWIN }, //(0x5C)
- { KEY_MENU, VK_APPS }, //(0x5D)
- { 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::PRINT, VK_SNAPSHOT }, // (0x2C)
+
+ { Key::INSERT, VK_INSERT }, // (0x2D)
+
+ { Key::KEY_DELETE, VK_DELETE }, // (0x2E)
+
+ { Key::HELP, VK_HELP }, // (0x2F)
+
+ { 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
+ { 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)
+ { 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)
//VK_SEPARATOR (0x6C)
- { 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_NUMLOCK, VK_NUMLOCK }, // (0x90)
- { KEY_SCROLLLOCK, VK_SCROLL }, // (0x91)
- { 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::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::NUMLOCK, VK_NUMLOCK }, // (0x90)
+ { Key::SCROLLLOCK, VK_SCROLL }, // (0x91)
+ { 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::BACK, VK_BROWSER_BACK }, // (0xA6)
- { KEY_FORWARD, VK_BROWSER_FORWARD }, // (0xA7)
+ { Key::FORWARD, VK_BROWSER_FORWARD }, // (0xA7)
- { KEY_REFRESH, VK_BROWSER_REFRESH }, // (0xA8)
+ { Key::REFRESH, VK_BROWSER_REFRESH }, // (0xA8)
- { KEY_STOP, VK_BROWSER_STOP }, // (0xA9)
+ { Key::STOP, VK_BROWSER_STOP }, // (0xA9)
- { KEY_SEARCH, VK_BROWSER_SEARCH }, // (0xAA)
+ { Key::SEARCH, VK_BROWSER_SEARCH }, // (0xAA)
- { KEY_FAVORITES, VK_BROWSER_FAVORITES }, // (0xAB)
+ { Key::FAVORITES, VK_BROWSER_FAVORITES }, // (0xAB)
- { KEY_HOMEPAGE, VK_BROWSER_HOME }, // (0xAC)
+ { Key::HOMEPAGE, VK_BROWSER_HOME }, // (0xAC)
- { KEY_VOLUMEMUTE, VK_VOLUME_MUTE }, // (0xAD)
+ { Key::VOLUMEMUTE, VK_VOLUME_MUTE }, // (0xAD)
- { KEY_VOLUMEDOWN, VK_VOLUME_DOWN }, // (0xAE)
+ { Key::VOLUMEDOWN, VK_VOLUME_DOWN }, // (0xAE)
- { KEY_VOLUMEUP, VK_VOLUME_UP }, // (0xAF)
+ { Key::VOLUMEUP, VK_VOLUME_UP }, // (0xAF)
- { KEY_MEDIANEXT, VK_MEDIA_NEXT_TRACK }, // (0xB0)
+ { Key::MEDIANEXT, VK_MEDIA_NEXT_TRACK }, // (0xB0)
- { KEY_MEDIAPREVIOUS, VK_MEDIA_PREV_TRACK }, // (0xB1)
+ { Key::MEDIAPREVIOUS, VK_MEDIA_PREV_TRACK }, // (0xB1)
- { KEY_MEDIASTOP, VK_MEDIA_STOP }, // (0xB2)
+ { Key::MEDIASTOP, VK_MEDIA_STOP }, // (0xB2)
//VK_MEDIA_PLAY_PAUSE (0xB3)
- { KEY_LAUNCHMAIL, VK_LAUNCH_MAIL }, // (0xB4)
+ { Key::LAUNCHMAIL, VK_LAUNCH_MAIL }, // (0xB4)
- { KEY_LAUNCHMEDIA, VK_LAUNCH_MEDIA_SELECT }, // (0xB5)
+ { Key::LAUNCHMEDIA, VK_LAUNCH_MEDIA_SELECT }, // (0xB5)
- { KEY_LAUNCH0, VK_LAUNCH_APP1 }, // (0xB6)
+ { Key::LAUNCH0, VK_LAUNCH_APP1 }, // (0xB6)
- { KEY_LAUNCH1, VK_LAUNCH_APP2 }, // (0xB7)
+ { Key::LAUNCH1, VK_LAUNCH_APP2 }, // (0xB7)
- { KEY_SEMICOLON, VK_OEM_1 }, // (0xBA)
+ { Key::SEMICOLON, VK_OEM_1 }, // (0xBA)
- { 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 the US standard keyboard, 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 the US standard keyboard, the '/?' key
- { KEY_QUOTELEFT, VK_OEM_3 }, // (0xC0)
- { KEY_BRACELEFT, VK_OEM_4 }, // (0xDB)
- { KEY_BACKSLASH, VK_OEM_5 }, // (0xDC)
- { KEY_BRACERIGHT, VK_OEM_6 }, // (0xDD)
- { KEY_APOSTROPHE, VK_OEM_7 }, // (0xDE)
+ { Key::QUOTELEFT, VK_OEM_3 }, // (0xC0)
+ { Key::BRACELEFT, VK_OEM_4 }, // (0xDB)
+ { Key::BACKSLASH, VK_OEM_5 }, // (0xDC)
+ { Key::BRACERIGHT, VK_OEM_6 }, // (0xDD)
+ { Key::APOSTROPHE, VK_OEM_7 }, // (0xDE)
/*
{VK_OEM_8 (0xDF)
{VK_OEM_102 (0xE2) // Windows 2000/XP: Either the angle bracket key or the backslash key on the RT 102-key keyboard
*/
- //{ KEY_PLAY, VK_PLAY},// (0xFA)
+ //{ Key::PLAY, VK_PLAY},// (0xFA)
- { KEY_UNKNOWN, 0 }
+ { Key::UNKNOWN, 0 }
};
/*
@@ -237,104 +237,104 @@ VK_OEM_CLEAR (0xFE)
*/
static _WinTranslatePair _scancode_to_keycode[] = {
- { KEY_ESCAPE, 0x01 },
- { KEY_1, 0x02 },
- { KEY_2, 0x03 },
- { KEY_3, 0x04 },
- { KEY_4, 0x05 },
- { KEY_5, 0x06 },
- { KEY_6, 0x07 },
- { KEY_7, 0x08 },
- { KEY_8, 0x09 },
- { KEY_9, 0x0A },
- { 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_DELETE, 0x53 },
- //{ KEY_???, 0x56 }, //NON US BACKSLASH
- { 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_UNKNOWN, 0 }
+ { 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::???, 0x56 }, //NON US BACKSLASH
+ { 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::UNKNOWN, 0 }
};
-unsigned int KeyMappingWindows::get_keysym(unsigned int p_code) {
- for (int i = 0; _vk_to_keycode[i].keysym != KEY_UNKNOWN; i++) {
+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) {
//printf("outcode: %x\n",_vk_to_keycode[i].keysym);
@@ -342,11 +342,11 @@ unsigned int KeyMappingWindows::get_keysym(unsigned int p_code) {
}
}
- return KEY_UNKNOWN;
+ return Key::UNKNOWN;
}
unsigned int KeyMappingWindows::get_scancode(Key p_keycode) {
- for (int i = 0; _scancode_to_keycode[i].keysym != KEY_UNKNOWN; i++) {
+ 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;
}
@@ -355,9 +355,9 @@ unsigned int KeyMappingWindows::get_scancode(Key p_keycode) {
return 0;
}
-unsigned int KeyMappingWindows::get_scansym(unsigned int p_code, bool p_extended) {
- unsigned int keycode = KEY_UNKNOWN;
- for (int i = 0; _scancode_to_keycode[i].keysym != KEY_UNKNOWN; i++) {
+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;
@@ -366,55 +366,55 @@ unsigned int KeyMappingWindows::get_scansym(unsigned int p_code, bool p_extended
if (p_extended) {
switch (keycode) {
- case KEY_ENTER: {
- keycode = KEY_KP_ENTER;
+ case Key::ENTER: {
+ keycode = Key::KP_ENTER;
} break;
- case KEY_SLASH: {
- keycode = KEY_KP_DIVIDE;
+ case Key::SLASH: {
+ keycode = Key::KP_DIVIDE;
} break;
- case KEY_CAPSLOCK: {
- keycode = KEY_KP_ADD;
+ case Key::CAPSLOCK: {
+ keycode = Key::KP_ADD;
} break;
default:
break;
}
} else {
switch (keycode) {
- case KEY_NUMLOCK: {
- keycode = KEY_PAUSE;
+ case Key::NUMLOCK: {
+ keycode = Key::PAUSE;
} break;
- case KEY_HOME: {
- keycode = KEY_KP_7;
+ case Key::HOME: {
+ keycode = Key::KP_7;
} break;
- case KEY_UP: {
- keycode = KEY_KP_8;
+ case Key::UP: {
+ keycode = Key::KP_8;
} break;
- case KEY_PAGEUP: {
- keycode = KEY_KP_9;
+ case Key::PAGEUP: {
+ keycode = Key::KP_9;
} break;
- case KEY_LEFT: {
- keycode = KEY_KP_4;
+ case Key::LEFT: {
+ keycode = Key::KP_4;
} break;
- case KEY_RIGHT: {
- keycode = KEY_KP_6;
+ case Key::RIGHT: {
+ keycode = Key::KP_6;
} break;
- case KEY_END: {
- keycode = KEY_KP_1;
+ case Key::END: {
+ keycode = Key::KP_1;
} break;
- case KEY_DOWN: {
- keycode = KEY_KP_2;
+ case Key::DOWN: {
+ keycode = Key::KP_2;
} break;
- case KEY_PAGEDOWN: {
- keycode = KEY_KP_3;
+ case Key::PAGEDOWN: {
+ keycode = Key::KP_3;
} break;
- case KEY_INSERT: {
- keycode = KEY_KP_0;
+ case Key::INSERT: {
+ keycode = Key::KP_0;
} break;
- case KEY_DELETE: {
- keycode = KEY_KP_PERIOD;
+ case Key::KEY_DELETE: {
+ keycode = Key::KP_PERIOD;
} break;
- case KEY_PRINT: {
- keycode = KEY_KP_MULTIPLY;
+ case Key::PRINT: {
+ keycode = Key::KP_MULTIPLY;
} break;
default:
break;
@@ -426,13 +426,13 @@ unsigned int KeyMappingWindows::get_scansym(unsigned int p_code, bool p_extended
bool KeyMappingWindows::is_extended_key(unsigned int p_code) {
return p_code == VK_INSERT ||
- p_code == VK_DELETE ||
- p_code == VK_HOME ||
- p_code == VK_END ||
- p_code == VK_PRIOR ||
- p_code == VK_NEXT ||
- p_code == VK_LEFT ||
- p_code == VK_UP ||
- p_code == VK_RIGHT ||
- p_code == VK_DOWN;
+ p_code == VK_DELETE ||
+ p_code == VK_HOME ||
+ p_code == VK_END ||
+ p_code == VK_PRIOR ||
+ p_code == VK_NEXT ||
+ p_code == VK_LEFT ||
+ p_code == VK_UP ||
+ p_code == VK_RIGHT ||
+ p_code == VK_DOWN;
}
diff --git a/platform/windows/key_mapping_windows.h b/platform/windows/key_mapping_windows.h
index d056e88f06..0454be7310 100644
--- a/platform/windows/key_mapping_windows.h
+++ b/platform/windows/key_mapping_windows.h
@@ -41,9 +41,9 @@ class KeyMappingWindows {
KeyMappingWindows() {}
public:
- static unsigned int get_keysym(unsigned int p_code);
+ static Key get_keysym(unsigned int p_code);
static unsigned int get_scancode(Key p_keycode);
- static unsigned int get_scansym(unsigned int p_code, bool p_extended);
+ static Key get_scansym(unsigned int p_code, bool p_extended);
static bool is_extended_key(unsigned int p_code);
};
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index 6c02bf1e16..6a0a4790fc 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -290,12 +290,13 @@ String OS_Windows::get_name() const {
return "Windows";
}
-OS::Date OS_Windows::get_date(bool utc) const {
+OS::Date OS_Windows::get_date(bool p_utc) const {
SYSTEMTIME systemtime;
- if (utc)
+ if (p_utc) {
GetSystemTime(&systemtime);
- else
+ } else {
GetLocalTime(&systemtime);
+ }
Date date;
date.day = systemtime.wDay;
@@ -306,12 +307,13 @@ OS::Date OS_Windows::get_date(bool utc) const {
return date;
}
-OS::Time OS_Windows::get_time(bool utc) const {
+OS::Time OS_Windows::get_time(bool p_utc) const {
SYSTEMTIME systemtime;
- if (utc)
+ if (p_utc) {
GetSystemTime(&systemtime);
- else
+ } else {
GetLocalTime(&systemtime);
+ }
Time time;
time.hour = systemtime.wHour;
@@ -445,7 +447,12 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments,
ZeroMemory(&pi.pi, sizeof(pi.pi));
LPSTARTUPINFOW si_w = (LPSTARTUPINFOW)&pi.si;
- int ret = CreateProcessW(nullptr, (LPWSTR)(command.utf16().ptrw()), nullptr, nullptr, false, NORMAL_PRIORITY_CLASS & CREATE_NO_WINDOW, nullptr, nullptr, si_w, &pi.pi);
+ DWORD dwCreationFlags = NORMAL_PRIORITY_CLASS;
+#ifndef DEBUG_ENABLED
+ dwCreationFlags |= CREATE_NO_WINDOW;
+#endif
+
+ int ret = CreateProcessW(nullptr, (LPWSTR)(command.utf16().ptrw()), nullptr, nullptr, false, dwCreationFlags, nullptr, nullptr, si_w, &pi.pi);
ERR_FAIL_COND_V_MSG(ret == 0, ERR_CANT_FORK, "Could not create child process: " + command);
WaitForSingleObject(pi.pi.hProcess, INFINITE);
@@ -473,7 +480,12 @@ Error OS_Windows::create_process(const String &p_path, const List<String> &p_arg
ZeroMemory(&pi.pi, sizeof(pi.pi));
LPSTARTUPINFOW si_w = (LPSTARTUPINFOW)&pi.si;
- int ret = CreateProcessW(nullptr, (LPWSTR)(command.utf16().ptrw()), nullptr, nullptr, false, NORMAL_PRIORITY_CLASS & CREATE_NO_WINDOW, nullptr, nullptr, si_w, &pi.pi);
+ DWORD dwCreationFlags = NORMAL_PRIORITY_CLASS;
+#ifndef DEBUG_ENABLED
+ dwCreationFlags |= CREATE_NO_WINDOW;
+#endif
+
+ int ret = CreateProcessW(nullptr, (LPWSTR)(command.utf16().ptrw()), nullptr, nullptr, false, dwCreationFlags, nullptr, nullptr, si_w, &pi.pi);
ERR_FAIL_COND_V_MSG(ret == 0, ERR_CANT_FORK, "Could not create child process: " + command);
ProcessID pid = pi.pi.dwProcessId;
@@ -758,7 +770,7 @@ String OS_Windows::get_user_data_dir() const {
}
}
- return ProjectSettings::get_singleton()->get_resource_path();
+ return get_data_path().plus_file(get_godot_dir_name()).plus_file("app_userdata").plus_file("[unnamed project]");
}
String OS_Windows::get_unique_id() const {
diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h
index d24afa91eb..1342d95575 100644
--- a/platform/windows/os_windows.h
+++ b/platform/windows/os_windows.h
@@ -46,10 +46,6 @@
#include "drivers/xaudio2/audio_driver_xaudio2.h"
#endif
-#if defined(OPENGL_ENABLED)
-#include "context_gl_windows.h"
-#endif
-
#if defined(VULKAN_ENABLED)
#include "drivers/vulkan/rendering_device_vulkan.h"
#include "platform/windows/vulkan_context_win.h"
@@ -122,8 +118,8 @@ public:
virtual void initialize_joypads() override {}
- virtual Date get_date(bool utc) const override;
- virtual Time get_time(bool utc) const override;
+ virtual Date get_date(bool p_utc) const override;
+ virtual Time get_time(bool p_utc) const override;
virtual TimeZoneInfo get_time_zone_info() const override;
virtual double get_unix_time() const override;
diff --git a/platform/windows/platform_config.h b/platform/windows/platform_config.h
index 481f583f6f..dace0f86af 100644
--- a/platform/windows/platform_config.h
+++ b/platform/windows/platform_config.h
@@ -29,3 +29,5 @@
/*************************************************************************/
#include <malloc.h>
+
+#define OPENGL_INCLUDE_H "thirdparty/glad/glad/glad.h"
diff --git a/platform/windows/windows_terminal_logger.cpp b/platform/windows/windows_terminal_logger.cpp
index e54a61fdfd..d4148630f0 100644
--- a/platform/windows/windows_terminal_logger.cpp
+++ b/platform/windows/windows_terminal_logger.cpp
@@ -71,7 +71,7 @@ void WindowsTerminalLogger::logv(const char *p_format, va_list p_list, bool p_er
#endif
}
-void WindowsTerminalLogger::log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type) {
+void WindowsTerminalLogger::log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify, ErrorType p_type) {
if (!should_log(true)) {
return;
}
diff --git a/platform/windows/windows_terminal_logger.h b/platform/windows/windows_terminal_logger.h
index aacfe5869e..86b65ae30a 100644
--- a/platform/windows/windows_terminal_logger.h
+++ b/platform/windows/windows_terminal_logger.h
@@ -37,8 +37,8 @@
class WindowsTerminalLogger : public StdLogger {
public:
- virtual void logv(const char *p_format, va_list p_list, bool p_err);
- virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type = ERR_ERROR);
+ virtual void logv(const char *p_format, va_list p_list, bool p_err) override;
+ virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify = false, ErrorType p_type = ERR_ERROR) override;
virtual ~WindowsTerminalLogger();
};