summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--SConstruct2
-rw-r--r--core/bind/core_bind.cpp539
-rw-r--r--core/bind/core_bind.h114
-rw-r--r--core/debugger/remote_debugger.cpp3
-rw-r--r--core/input/input.cpp34
-rw-r--r--core/input/input.h14
-rw-r--r--core/os/os.cpp227
-rw-r--r--core/os/os.h244
-rw-r--r--drivers/gl_context/SCsub2
-rw-r--r--drivers/gles2/rasterizer_canvas_gles2.cpp12
-rw-r--r--drivers/gles2/rasterizer_gles2.cpp2
-rw-r--r--drivers/gles2/rasterizer_scene_gles2.cpp2
-rw-r--r--drivers/vulkan/SCsub2
-rw-r--r--editor/debugger/editor_debugger_tree.cpp3
-rw-r--r--editor/debugger/script_editor_debugger.cpp9
-rw-r--r--editor/editor_dir_dialog.cpp3
-rw-r--r--editor/editor_file_dialog.cpp3
-rw-r--r--editor/editor_node.cpp57
-rw-r--r--editor/editor_run.cpp15
-rw-r--r--editor/editor_settings.cpp2
-rw-r--r--editor/filesystem_dock.cpp3
-rw-r--r--editor/plugins/script_editor_plugin.cpp7
-rw-r--r--editor/plugins/shader_editor_plugin.cpp3
-rw-r--r--editor/plugins/spatial_editor_plugin.cpp12
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp3
-rw-r--r--editor/progress_dialog.cpp3
-rw-r--r--editor/project_export.cpp5
-rw-r--r--editor/project_manager.cpp25
-rw-r--r--editor/scene_tree_dock.cpp4
-rw-r--r--main/main.cpp267
-rw-r--r--main/tests/test_physics.cpp3
-rw-r--r--main/tests/test_physics_2d.cpp3
-rw-r--r--main/tests/test_render.cpp3
-rw-r--r--modules/gdnative/nativescript/SCsub2
-rw-r--r--modules/gdscript/language_server/gdscript_text_document.cpp4
-rw-r--r--modules/mobile_vr/mobile_vr_interface.cpp3
-rw-r--r--platform/linuxbsd/SCsub (renamed from platform/x11/SCsub)17
-rw-r--r--platform/linuxbsd/context_gl_x11.cpp (renamed from platform/x11/context_gl_x11.cpp)0
-rw-r--r--platform/linuxbsd/context_gl_x11.h (renamed from platform/x11/context_gl_x11.h)0
-rw-r--r--platform/linuxbsd/crash_handler_linuxbsd.cpp (renamed from platform/x11/crash_handler_x11.cpp)4
-rw-r--r--platform/linuxbsd/crash_handler_linuxbsd.h (renamed from platform/x11/crash_handler_x11.h)2
-rw-r--r--platform/linuxbsd/detect.py (renamed from platform/x11/detect.py)8
-rw-r--r--platform/linuxbsd/detect_prime_x11.cpp (renamed from platform/x11/detect_prime.cpp)2
-rw-r--r--platform/linuxbsd/detect_prime_x11.h (renamed from platform/x11/detect_prime.h)2
-rw-r--r--platform/linuxbsd/display_server_x11.cpp (renamed from platform/x11/display_server_x11.cpp)227
-rw-r--r--platform/linuxbsd/display_server_x11.h (renamed from platform/x11/display_server_x11.h)24
-rw-r--r--platform/linuxbsd/export/export.cpp (renamed from platform/x11/export/export.cpp)6
-rw-r--r--platform/linuxbsd/export/export.h (renamed from platform/x11/export/export.h)8
-rw-r--r--platform/linuxbsd/godot_linuxbsd.cpp (renamed from platform/x11/godot_x11.cpp)6
-rw-r--r--platform/linuxbsd/joypad_linux.cpp (renamed from platform/x11/joypad_linux.cpp)0
-rw-r--r--platform/linuxbsd/joypad_linux.h (renamed from platform/x11/joypad_linux.h)0
-rw-r--r--platform/linuxbsd/key_mapping_x11.cpp (renamed from platform/x11/key_mapping_x11.cpp)0
-rw-r--r--platform/linuxbsd/key_mapping_x11.h (renamed from platform/x11/key_mapping_x11.h)0
-rw-r--r--platform/linuxbsd/logo.png (renamed from platform/x11/logo.png)bin1679 -> 1679 bytes
-rw-r--r--platform/linuxbsd/os_linuxbsd.cpp381
-rw-r--r--platform/linuxbsd/os_linuxbsd.h106
-rw-r--r--platform/linuxbsd/pck_embed.ld (renamed from platform/x11/pck_embed.ld)0
-rw-r--r--platform/linuxbsd/pck_embed.legacy.ld (renamed from platform/x11/pck_embed.legacy.ld)0
-rw-r--r--platform/linuxbsd/platform_config.h (renamed from platform/x11/platform_config.h)0
-rw-r--r--platform/linuxbsd/platform_linuxbsd_builders.py (renamed from platform/x11/platform_x11_builders.py)2
-rw-r--r--platform/linuxbsd/vulkan_context_x11.cpp (renamed from platform/x11/vulkan_context_x11.cpp)0
-rw-r--r--platform/linuxbsd/vulkan_context_x11.h (renamed from platform/x11/vulkan_context_x11.h)0
-rw-r--r--platform/server/os_server.h2
-rw-r--r--platform/x11/os_x11.cpp3568
-rw-r--r--platform/x11/os_x11.h338
-rw-r--r--scene/2d/particles_2d.cpp2
-rw-r--r--scene/2d/touch_screen_button.cpp5
-rw-r--r--scene/3d/gi_probe.cpp2
-rw-r--r--scene/3d/particles.cpp2
-rw-r--r--scene/gui/line_edit.cpp42
-rw-r--r--scene/gui/rich_text_label.cpp3
-rw-r--r--scene/gui/scroll_bar.cpp4
-rw-r--r--scene/gui/scroll_container.cpp4
-rw-r--r--scene/gui/text_edit.cpp34
-rw-r--r--scene/gui/tree.cpp2
-rw-r--r--scene/main/scene_tree.cpp7
-rw-r--r--scene/main/viewport.cpp15
-rw-r--r--scene/main/viewport.h3
-rw-r--r--scene/register_scene_types.cpp2
-rw-r--r--servers/display_server.cpp107
-rw-r--r--servers/display_server.h85
-rw-r--r--servers/visual/visual_server_raster.cpp2
-rw-r--r--servers/visual/visual_server_wrap_mt.cpp7
83 files changed, 1298 insertions, 5372 deletions
diff --git a/SConstruct b/SConstruct
index 84400e800d..ed4b3c6242 100644
--- a/SConstruct
+++ b/SConstruct
@@ -236,7 +236,7 @@ elif env_base['p'] != "":
else:
# Missing `platform` argument, try to detect platform automatically
if sys.platform.startswith('linux'):
- selected_platform = 'x11'
+ selected_platform = 'linuxbsd'
elif sys.platform == 'darwin':
selected_platform = 'osx'
elif sys.platform == 'win32':
diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp
index 62d83b2e04..0236523200 100644
--- a/core/bind/core_bind.cpp
+++ b/core/bind/core_bind.cpp
@@ -194,82 +194,6 @@ _ResourceSaver::_ResourceSaver() {
singleton = this;
}
-/////////////////OS
-
-void _OS::global_menu_add_item(const String &p_menu, const String &p_label, const Variant &p_signal, const Variant &p_meta) {
-
- OS::get_singleton()->global_menu_add_item(p_menu, p_label, p_signal, p_meta);
-}
-
-void _OS::global_menu_add_separator(const String &p_menu) {
-
- OS::get_singleton()->global_menu_add_separator(p_menu);
-}
-
-void _OS::global_menu_remove_item(const String &p_menu, int p_idx) {
-
- OS::get_singleton()->global_menu_remove_item(p_menu, p_idx);
-}
-
-void _OS::global_menu_clear(const String &p_menu) {
-
- OS::get_singleton()->global_menu_clear(p_menu);
-}
-
-Point2 _OS::get_mouse_position() const {
-
- return OS::get_singleton()->get_mouse_position();
-}
-
-void _OS::set_window_title(const String &p_title) {
-
- OS::get_singleton()->set_window_title(p_title);
-}
-
-int _OS::get_mouse_button_state() const {
-
- return OS::get_singleton()->get_mouse_button_state();
-}
-
-String _OS::get_unique_id() const {
- return OS::get_singleton()->get_unique_id();
-}
-
-bool _OS::has_touchscreen_ui_hint() const {
-
- return OS::get_singleton()->has_touchscreen_ui_hint();
-}
-
-void _OS::set_clipboard(const String &p_text) {
-
- OS::get_singleton()->set_clipboard(p_text);
-}
-
-String _OS::get_clipboard() const {
-
- return OS::get_singleton()->get_clipboard();
-}
-
-int _OS::get_video_driver_count() const {
- return OS::get_singleton()->get_video_driver_count();
-}
-
-String _OS::get_video_driver_name(VideoDriver p_driver) const {
- return OS::get_singleton()->get_video_driver_name((int)p_driver);
-}
-
-_OS::VideoDriver _OS::get_current_video_driver() const {
- return (VideoDriver)OS::get_singleton()->get_current_video_driver();
-}
-
-int _OS::get_audio_driver_count() const {
- return OS::get_singleton()->get_audio_driver_count();
-}
-
-String _OS::get_audio_driver_name(int p_driver) const {
- return OS::get_singleton()->get_audio_driver_name(p_driver);
-}
-
PackedStringArray _OS::get_connected_midi_inputs() {
return OS::get_singleton()->get_connected_midi_inputs();
}
@@ -282,198 +206,11 @@ void _OS::close_midi_inputs() {
OS::get_singleton()->close_midi_inputs();
}
-void _OS::set_video_mode(const Size2 &p_size, bool p_fullscreen, bool p_resizeable, int p_screen) {
-
- OS::VideoMode vm;
- vm.width = p_size.width;
- vm.height = p_size.height;
- vm.fullscreen = p_fullscreen;
- vm.resizable = p_resizeable;
- OS::get_singleton()->set_video_mode(vm, p_screen);
-}
-
-Size2 _OS::get_video_mode(int p_screen) const {
-
- OS::VideoMode vm;
- vm = OS::get_singleton()->get_video_mode(p_screen);
- return Size2(vm.width, vm.height);
-}
-
-bool _OS::is_video_mode_fullscreen(int p_screen) const {
-
- OS::VideoMode vm;
- vm = OS::get_singleton()->get_video_mode(p_screen);
- return vm.fullscreen;
-}
-
-int _OS::get_screen_count() const {
- return OS::get_singleton()->get_screen_count();
-}
-
-int _OS::get_current_screen() const {
- return OS::get_singleton()->get_current_screen();
-}
-
-void _OS::set_current_screen(int p_screen) {
- OS::get_singleton()->set_current_screen(p_screen);
-}
-
-Point2 _OS::get_screen_position(int p_screen) const {
- return OS::get_singleton()->get_screen_position(p_screen);
-}
-
-Size2 _OS::get_screen_size(int p_screen) const {
- return OS::get_singleton()->get_screen_size(p_screen);
-}
-
-int _OS::get_screen_dpi(int p_screen) const {
-
- return OS::get_singleton()->get_screen_dpi(p_screen);
-}
-
-Point2 _OS::get_window_position() const {
- return OS::get_singleton()->get_window_position();
-}
-
-void _OS::set_window_position(const Point2 &p_position) {
- OS::get_singleton()->set_window_position(p_position);
-}
-
-Size2 _OS::get_max_window_size() const {
- return OS::get_singleton()->get_max_window_size();
-}
-
-Size2 _OS::get_min_window_size() const {
- return OS::get_singleton()->get_min_window_size();
-}
-
-Size2 _OS::get_window_size() const {
- return OS::get_singleton()->get_window_size();
-}
-
-Size2 _OS::get_real_window_size() const {
- return OS::get_singleton()->get_real_window_size();
-}
-
-void _OS::set_max_window_size(const Size2 &p_size) {
- OS::get_singleton()->set_max_window_size(p_size);
-}
-
-void _OS::set_min_window_size(const Size2 &p_size) {
- OS::get_singleton()->set_min_window_size(p_size);
-}
-
-void _OS::set_window_size(const Size2 &p_size) {
- OS::get_singleton()->set_window_size(p_size);
-}
-
-Rect2 _OS::get_window_safe_area() const {
- return OS::get_singleton()->get_window_safe_area();
-}
-
-void _OS::set_window_fullscreen(bool p_enabled) {
- OS::get_singleton()->set_window_fullscreen(p_enabled);
-}
-
-bool _OS::is_window_fullscreen() const {
- return OS::get_singleton()->is_window_fullscreen();
-}
-
-void _OS::set_window_resizable(bool p_enabled) {
- OS::get_singleton()->set_window_resizable(p_enabled);
-}
-
-bool _OS::is_window_resizable() const {
- return OS::get_singleton()->is_window_resizable();
-}
-
-void _OS::set_window_minimized(bool p_enabled) {
- OS::get_singleton()->set_window_minimized(p_enabled);
-}
-
-bool _OS::is_window_minimized() const {
- return OS::get_singleton()->is_window_minimized();
-}
-
-void _OS::set_window_maximized(bool p_enabled) {
- OS::get_singleton()->set_window_maximized(p_enabled);
-}
-
-bool _OS::is_window_maximized() const {
- return OS::get_singleton()->is_window_maximized();
-}
-
-void _OS::set_window_always_on_top(bool p_enabled) {
- OS::get_singleton()->set_window_always_on_top(p_enabled);
-}
-
-bool _OS::is_window_always_on_top() const {
- return OS::get_singleton()->is_window_always_on_top();
-}
-
-bool _OS::is_window_focused() const {
- return OS::get_singleton()->is_window_focused();
-}
-
-void _OS::set_borderless_window(bool p_borderless) {
- OS::get_singleton()->set_borderless_window(p_borderless);
-}
-
-bool _OS::get_window_per_pixel_transparency_enabled() const {
- return OS::get_singleton()->get_window_per_pixel_transparency_enabled();
-}
-
-void _OS::set_window_per_pixel_transparency_enabled(bool p_enabled) {
- OS::get_singleton()->set_window_per_pixel_transparency_enabled(p_enabled);
-}
-
-bool _OS::get_borderless_window() const {
- return OS::get_singleton()->get_borderless_window();
-}
-
-void _OS::set_ime_active(const bool p_active) {
-
- OS::get_singleton()->set_ime_active(p_active);
-}
-
-void _OS::set_ime_position(const Point2 &p_pos) {
-
- OS::get_singleton()->set_ime_position(p_pos);
-}
-
-Point2 _OS::get_ime_selection() const {
- return OS::get_singleton()->get_ime_selection();
-}
-
-String _OS::get_ime_text() const {
- return OS::get_singleton()->get_ime_text();
-}
-
void _OS::set_use_file_access_save_and_swap(bool p_enable) {
FileAccess::set_backup_save(p_enable);
}
-bool _OS::is_video_mode_resizable(int p_screen) const {
-
- OS::VideoMode vm;
- vm = OS::get_singleton()->get_video_mode(p_screen);
- return vm.resizable;
-}
-
-Array _OS::get_fullscreen_mode_list(int p_screen) const {
-
- List<OS::VideoMode> vmlist;
- OS::get_singleton()->get_fullscreen_mode_list(&vmlist, p_screen);
- Array vmarr;
- for (List<OS::VideoMode>::Element *E = vmlist.front(); E; E = E->next()) {
-
- vmarr.push_back(Size2(E->get().width, E->get().height));
- }
-
- return vmarr;
-}
-
void _OS::set_low_processor_usage_mode(bool p_enabled) {
OS::get_singleton()->set_low_processor_usage_mode(p_enabled);
@@ -562,52 +299,16 @@ String _OS::get_locale() const {
return OS::get_singleton()->get_locale();
}
-String _OS::get_latin_keyboard_variant() const {
- switch (OS::get_singleton()->get_latin_keyboard_variant()) {
- case OS::LATIN_KEYBOARD_QWERTY: return "QWERTY";
- case OS::LATIN_KEYBOARD_QWERTZ: return "QWERTZ";
- case OS::LATIN_KEYBOARD_AZERTY: return "AZERTY";
- case OS::LATIN_KEYBOARD_QZERTY: return "QZERTY";
- case OS::LATIN_KEYBOARD_DVORAK: return "DVORAK";
- case OS::LATIN_KEYBOARD_NEO: return "NEO";
- case OS::LATIN_KEYBOARD_COLEMAK: return "COLEMAK";
- default: return "ERROR";
- }
-}
-
String _OS::get_model_name() const {
return OS::get_singleton()->get_model_name();
}
-bool _OS::is_ok_left_and_cancel_right() const {
-
- return OS::get_singleton()->get_swap_ok_cancel();
-}
-
Error _OS::set_thread_name(const String &p_name) {
return Thread::set_name(p_name);
};
-void _OS::set_use_vsync(bool p_enable) {
- OS::get_singleton()->set_use_vsync(p_enable);
-}
-
-bool _OS::is_vsync_enabled() const {
-
- return OS::get_singleton()->is_vsync_enabled();
-}
-
-void _OS::set_vsync_via_compositor(bool p_enable) {
- OS::get_singleton()->set_vsync_via_compositor(p_enable);
-}
-
-bool _OS::is_vsync_via_compositor_enabled() const {
-
- return OS::get_singleton()->is_vsync_via_compositor_enabled();
-}
-
bool _OS::has_feature(const String &p_feature) const {
return OS::get_singleton()->has_feature(p_feature);
@@ -667,16 +368,6 @@ uint64_t _OS::get_static_memory_peak_usage() const {
return OS::get_singleton()->get_static_memory_peak_usage();
}
-void _OS::set_native_icon(const String &p_filename) {
-
- OS::get_singleton()->set_native_icon(p_filename);
-}
-
-void _OS::set_icon(const Ref<Image> &p_icon) {
-
- OS::get_singleton()->set_icon(p_icon);
-}
-
int _OS::get_exit_code() const {
return OS::get_singleton()->get_exit_code();
@@ -924,11 +615,6 @@ bool _OS::can_use_threads() const {
return OS::get_singleton()->can_use_threads();
}
-bool _OS::can_draw() const {
-
- return OS::get_singleton()->can_draw();
-}
-
bool _OS::is_userfs_persistent() const {
return OS::get_singleton()->is_userfs_persistent();
@@ -1025,22 +711,6 @@ void _OS::print_resources_by_type(const Vector<String> &p_types) {
}
};
-bool _OS::has_virtual_keyboard() const {
- return OS::get_singleton()->has_virtual_keyboard();
-}
-
-void _OS::show_virtual_keyboard(const String &p_existing_text) {
- OS::get_singleton()->show_virtual_keyboard(p_existing_text, Rect2());
-}
-
-void _OS::hide_virtual_keyboard() {
- OS::get_singleton()->hide_virtual_keyboard();
-}
-
-int _OS::get_virtual_keyboard_height() {
- return OS::get_singleton()->get_virtual_keyboard_height();
-}
-
void _OS::print_all_resources(const String &p_to_file) {
OS::get_singleton()->print_all_resources(p_to_file);
@@ -1061,45 +731,6 @@ String _OS::get_user_data_dir() const {
return OS::get_singleton()->get_user_data_dir();
};
-Error _OS::native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track) {
-
- return OS::get_singleton()->native_video_play(p_path, p_volume, p_audio_track, p_subtitle_track);
-};
-
-bool _OS::native_video_is_playing() {
-
- return OS::get_singleton()->native_video_is_playing();
-};
-
-void _OS::native_video_pause() {
-
- OS::get_singleton()->native_video_pause();
-};
-
-void _OS::native_video_unpause() {
- OS::get_singleton()->native_video_unpause();
-};
-
-void _OS::native_video_stop() {
-
- OS::get_singleton()->native_video_stop();
-};
-
-void _OS::request_attention() {
-
- OS::get_singleton()->request_attention();
-}
-
-void _OS::center_window() {
-
- OS::get_singleton()->center_window();
-}
-
-void _OS::move_window_to_foreground() {
-
- OS::get_singleton()->move_window_to_foreground();
-}
-
bool _OS::is_debug_build() const {
#ifdef DEBUG_ENABLED
@@ -1109,26 +740,6 @@ bool _OS::is_debug_build() const {
#endif
}
-void _OS::set_screen_orientation(ScreenOrientation p_orientation) {
-
- OS::get_singleton()->set_screen_orientation(OS::ScreenOrientation(p_orientation));
-}
-
-_OS::ScreenOrientation _OS::get_screen_orientation() const {
-
- return ScreenOrientation(OS::get_singleton()->get_screen_orientation());
-}
-
-void _OS::set_keep_screen_on(bool p_enabled) {
-
- OS::get_singleton()->set_keep_screen_on(p_enabled);
-}
-
-bool _OS::is_keep_screen_on() const {
-
- return OS::get_singleton()->is_keep_screen_on();
-}
-
String _OS::get_system_dir(SystemDir p_dir) const {
return OS::get_singleton()->get_system_dir(OS::SystemDir(p_dir));
@@ -1149,11 +760,6 @@ int _OS::find_keycode_from_string(const String &p_code) const {
return find_keycode(p_code);
}
-void _OS::alert(const String &p_alert, const String &p_title) {
-
- OS::get_singleton()->alert(p_alert, p_title);
-}
-
bool _OS::request_permission(const String &p_name) {
return OS::get_singleton()->request_permission(p_name);
@@ -1169,90 +775,17 @@ Vector<String> _OS::get_granted_permissions() const {
return OS::get_singleton()->get_granted_permissions();
}
+String _OS::get_unique_id() const {
+ return OS::get_singleton()->get_unique_id();
+}
_OS *_OS::singleton = NULL;
void _OS::_bind_methods() {
- //ClassDB::bind_method(D_METHOD("get_mouse_position"),&_OS::get_mouse_position);
- //ClassDB::bind_method(D_METHOD("is_mouse_grab_enabled"),&_OS::is_mouse_grab_enabled);
-
- ClassDB::bind_method(D_METHOD("set_clipboard", "clipboard"), &_OS::set_clipboard);
- ClassDB::bind_method(D_METHOD("get_clipboard"), &_OS::get_clipboard);
-
- //will not delete for now, just unexpose
- //ClassDB::bind_method(D_METHOD("set_video_mode","size","fullscreen","resizable","screen"),&_OS::set_video_mode,DEFVAL(0));
- //ClassDB::bind_method(D_METHOD("get_video_mode_size","screen"),&_OS::get_video_mode,DEFVAL(0));
- //ClassDB::bind_method(D_METHOD("is_video_mode_fullscreen","screen"),&_OS::is_video_mode_fullscreen,DEFVAL(0));
- //ClassDB::bind_method(D_METHOD("is_video_mode_resizable","screen"),&_OS::is_video_mode_resizable,DEFVAL(0));
- //ClassDB::bind_method(D_METHOD("get_fullscreen_mode_list","screen"),&_OS::get_fullscreen_mode_list,DEFVAL(0));
-
- ClassDB::bind_method(D_METHOD("global_menu_add_item", "menu", "label", "id", "meta"), &_OS::global_menu_add_item);
- ClassDB::bind_method(D_METHOD("global_menu_add_separator", "menu"), &_OS::global_menu_add_separator);
- ClassDB::bind_method(D_METHOD("global_menu_remove_item", "menu", "idx"), &_OS::global_menu_remove_item);
- ClassDB::bind_method(D_METHOD("global_menu_clear", "menu"), &_OS::global_menu_clear);
-
- ClassDB::bind_method(D_METHOD("get_video_driver_count"), &_OS::get_video_driver_count);
- ClassDB::bind_method(D_METHOD("get_video_driver_name", "driver"), &_OS::get_video_driver_name);
- ClassDB::bind_method(D_METHOD("get_current_video_driver"), &_OS::get_current_video_driver);
-
- ClassDB::bind_method(D_METHOD("get_audio_driver_count"), &_OS::get_audio_driver_count);
- ClassDB::bind_method(D_METHOD("get_audio_driver_name", "driver"), &_OS::get_audio_driver_name);
ClassDB::bind_method(D_METHOD("get_connected_midi_inputs"), &_OS::get_connected_midi_inputs);
ClassDB::bind_method(D_METHOD("open_midi_inputs"), &_OS::open_midi_inputs);
ClassDB::bind_method(D_METHOD("close_midi_inputs"), &_OS::close_midi_inputs);
- ClassDB::bind_method(D_METHOD("get_screen_count"), &_OS::get_screen_count);
- ClassDB::bind_method(D_METHOD("get_current_screen"), &_OS::get_current_screen);
- ClassDB::bind_method(D_METHOD("set_current_screen", "screen"), &_OS::set_current_screen);
- ClassDB::bind_method(D_METHOD("get_screen_position", "screen"), &_OS::get_screen_position, DEFVAL(-1));
- ClassDB::bind_method(D_METHOD("get_screen_size", "screen"), &_OS::get_screen_size, DEFVAL(-1));
- ClassDB::bind_method(D_METHOD("get_screen_dpi", "screen"), &_OS::get_screen_dpi, DEFVAL(-1));
- ClassDB::bind_method(D_METHOD("get_window_position"), &_OS::get_window_position);
- ClassDB::bind_method(D_METHOD("set_window_position", "position"), &_OS::set_window_position);
- ClassDB::bind_method(D_METHOD("get_window_size"), &_OS::get_window_size);
- ClassDB::bind_method(D_METHOD("get_max_window_size"), &_OS::get_max_window_size);
- ClassDB::bind_method(D_METHOD("get_min_window_size"), &_OS::get_min_window_size);
- ClassDB::bind_method(D_METHOD("set_max_window_size", "size"), &_OS::set_max_window_size);
- ClassDB::bind_method(D_METHOD("set_min_window_size", "size"), &_OS::set_min_window_size);
- ClassDB::bind_method(D_METHOD("set_window_size", "size"), &_OS::set_window_size);
- ClassDB::bind_method(D_METHOD("get_window_safe_area"), &_OS::get_window_safe_area);
- ClassDB::bind_method(D_METHOD("set_window_fullscreen", "enabled"), &_OS::set_window_fullscreen);
- ClassDB::bind_method(D_METHOD("is_window_fullscreen"), &_OS::is_window_fullscreen);
- ClassDB::bind_method(D_METHOD("set_window_resizable", "enabled"), &_OS::set_window_resizable);
- ClassDB::bind_method(D_METHOD("is_window_resizable"), &_OS::is_window_resizable);
- ClassDB::bind_method(D_METHOD("set_window_minimized", "enabled"), &_OS::set_window_minimized);
- ClassDB::bind_method(D_METHOD("is_window_minimized"), &_OS::is_window_minimized);
- ClassDB::bind_method(D_METHOD("set_window_maximized", "enabled"), &_OS::set_window_maximized);
- ClassDB::bind_method(D_METHOD("is_window_maximized"), &_OS::is_window_maximized);
- ClassDB::bind_method(D_METHOD("set_window_always_on_top", "enabled"), &_OS::set_window_always_on_top);
- ClassDB::bind_method(D_METHOD("is_window_always_on_top"), &_OS::is_window_always_on_top);
- ClassDB::bind_method(D_METHOD("is_window_focused"), &_OS::is_window_focused);
- ClassDB::bind_method(D_METHOD("request_attention"), &_OS::request_attention);
- ClassDB::bind_method(D_METHOD("get_real_window_size"), &_OS::get_real_window_size);
- ClassDB::bind_method(D_METHOD("center_window"), &_OS::center_window);
- ClassDB::bind_method(D_METHOD("move_window_to_foreground"), &_OS::move_window_to_foreground);
-
- ClassDB::bind_method(D_METHOD("set_borderless_window", "borderless"), &_OS::set_borderless_window);
- ClassDB::bind_method(D_METHOD("get_borderless_window"), &_OS::get_borderless_window);
-
- ClassDB::bind_method(D_METHOD("get_window_per_pixel_transparency_enabled"), &_OS::get_window_per_pixel_transparency_enabled);
- ClassDB::bind_method(D_METHOD("set_window_per_pixel_transparency_enabled", "enabled"), &_OS::set_window_per_pixel_transparency_enabled);
-
- ClassDB::bind_method(D_METHOD("set_ime_active", "active"), &_OS::set_ime_active);
- ClassDB::bind_method(D_METHOD("set_ime_position", "position"), &_OS::set_ime_position);
- ClassDB::bind_method(D_METHOD("get_ime_selection"), &_OS::get_ime_selection);
- ClassDB::bind_method(D_METHOD("get_ime_text"), &_OS::get_ime_text);
-
- ClassDB::bind_method(D_METHOD("set_screen_orientation", "orientation"), &_OS::set_screen_orientation);
- ClassDB::bind_method(D_METHOD("get_screen_orientation"), &_OS::get_screen_orientation);
-
- ClassDB::bind_method(D_METHOD("set_keep_screen_on", "enabled"), &_OS::set_keep_screen_on);
- ClassDB::bind_method(D_METHOD("is_keep_screen_on"), &_OS::is_keep_screen_on);
-
- ClassDB::bind_method(D_METHOD("has_touchscreen_ui_hint"), &_OS::has_touchscreen_ui_hint);
-
- ClassDB::bind_method(D_METHOD("set_window_title", "title"), &_OS::set_window_title);
-
ClassDB::bind_method(D_METHOD("set_low_processor_usage_mode", "enable"), &_OS::set_low_processor_usage_mode);
ClassDB::bind_method(D_METHOD("is_in_low_processor_usage_mode"), &_OS::is_in_low_processor_usage_mode);
@@ -1283,9 +816,6 @@ void _OS::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_system_time_secs"), &_OS::get_system_time_secs);
ClassDB::bind_method(D_METHOD("get_system_time_msecs"), &_OS::get_system_time_msecs);
- ClassDB::bind_method(D_METHOD("set_native_icon", "filename"), &_OS::set_native_icon);
- ClassDB::bind_method(D_METHOD("set_icon", "icon"), &_OS::set_icon);
-
ClassDB::bind_method(D_METHOD("get_exit_code"), &_OS::get_exit_code);
ClassDB::bind_method(D_METHOD("set_exit_code", "code"), &_OS::set_exit_code);
@@ -1295,10 +825,8 @@ void _OS::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_ticks_usec"), &_OS::get_ticks_usec);
ClassDB::bind_method(D_METHOD("get_splash_tick_msec"), &_OS::get_splash_tick_msec);
ClassDB::bind_method(D_METHOD("get_locale"), &_OS::get_locale);
- ClassDB::bind_method(D_METHOD("get_latin_keyboard_variant"), &_OS::get_latin_keyboard_variant);
ClassDB::bind_method(D_METHOD("get_model_name"), &_OS::get_model_name);
- ClassDB::bind_method(D_METHOD("can_draw"), &_OS::can_draw);
ClassDB::bind_method(D_METHOD("is_userfs_persistent"), &_OS::is_userfs_persistent);
ClassDB::bind_method(D_METHOD("is_stdout_verbose"), &_OS::is_stdout_verbose);
@@ -1310,10 +838,6 @@ void _OS::_bind_methods() {
ClassDB::bind_method(D_METHOD("dump_memory_to_file", "file"), &_OS::dump_memory_to_file);
ClassDB::bind_method(D_METHOD("dump_resources_to_file", "file"), &_OS::dump_resources_to_file);
- ClassDB::bind_method(D_METHOD("has_virtual_keyboard"), &_OS::has_virtual_keyboard);
- ClassDB::bind_method(D_METHOD("show_virtual_keyboard", "existing_text"), &_OS::show_virtual_keyboard, DEFVAL(""));
- ClassDB::bind_method(D_METHOD("hide_virtual_keyboard"), &_OS::hide_virtual_keyboard);
- ClassDB::bind_method(D_METHOD("get_virtual_keyboard_height"), &_OS::get_virtual_keyboard_height);
ClassDB::bind_method(D_METHOD("print_resources_in_use", "short"), &_OS::print_resources_in_use, DEFVAL(false));
ClassDB::bind_method(D_METHOD("print_all_resources", "tofile"), &_OS::print_all_resources, DEFVAL(""));
@@ -1324,81 +848,32 @@ void _OS::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_system_dir", "dir"), &_OS::get_system_dir);
ClassDB::bind_method(D_METHOD("get_unique_id"), &_OS::get_unique_id);
- ClassDB::bind_method(D_METHOD("is_ok_left_and_cancel_right"), &_OS::is_ok_left_and_cancel_right);
-
ClassDB::bind_method(D_METHOD("print_all_textures_by_size"), &_OS::print_all_textures_by_size);
ClassDB::bind_method(D_METHOD("print_resources_by_type", "types"), &_OS::print_resources_by_type);
- ClassDB::bind_method(D_METHOD("native_video_play", "path", "volume", "audio_track", "subtitle_track"), &_OS::native_video_play);
- ClassDB::bind_method(D_METHOD("native_video_is_playing"), &_OS::native_video_is_playing);
- ClassDB::bind_method(D_METHOD("native_video_stop"), &_OS::native_video_stop);
- ClassDB::bind_method(D_METHOD("native_video_pause"), &_OS::native_video_pause);
- ClassDB::bind_method(D_METHOD("native_video_unpause"), &_OS::native_video_unpause);
-
ClassDB::bind_method(D_METHOD("get_keycode_string", "code"), &_OS::get_keycode_string);
ClassDB::bind_method(D_METHOD("is_keycode_unicode", "code"), &_OS::is_keycode_unicode);
ClassDB::bind_method(D_METHOD("find_keycode_from_string", "string"), &_OS::find_keycode_from_string);
ClassDB::bind_method(D_METHOD("set_use_file_access_save_and_swap", "enabled"), &_OS::set_use_file_access_save_and_swap);
- ClassDB::bind_method(D_METHOD("alert", "text", "title"), &_OS::alert, DEFVAL("Alert!"));
-
ClassDB::bind_method(D_METHOD("set_thread_name", "name"), &_OS::set_thread_name);
- ClassDB::bind_method(D_METHOD("set_use_vsync", "enable"), &_OS::set_use_vsync);
- ClassDB::bind_method(D_METHOD("is_vsync_enabled"), &_OS::is_vsync_enabled);
-
- ClassDB::bind_method(D_METHOD("set_vsync_via_compositor", "enable"), &_OS::set_vsync_via_compositor);
- ClassDB::bind_method(D_METHOD("is_vsync_via_compositor_enabled"), &_OS::is_vsync_via_compositor_enabled);
-
ClassDB::bind_method(D_METHOD("has_feature", "tag_name"), &_OS::has_feature);
ClassDB::bind_method(D_METHOD("request_permission", "name"), &_OS::request_permission);
ClassDB::bind_method(D_METHOD("request_permissions"), &_OS::request_permissions);
ClassDB::bind_method(D_METHOD("get_granted_permissions"), &_OS::get_granted_permissions);
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "clipboard"), "set_clipboard", "get_clipboard");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "current_screen"), "set_current_screen", "get_current_screen");
ADD_PROPERTY(PropertyInfo(Variant::INT, "exit_code"), "set_exit_code", "get_exit_code");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "vsync_enabled"), "set_use_vsync", "is_vsync_enabled");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "vsync_via_compositor"), "set_vsync_via_compositor", "is_vsync_via_compositor_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "low_processor_usage_mode"), "set_low_processor_usage_mode", "is_in_low_processor_usage_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "low_processor_usage_mode_sleep_usec"), "set_low_processor_usage_mode_sleep_usec", "get_low_processor_usage_mode_sleep_usec");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "keep_screen_on"), "set_keep_screen_on", "is_keep_screen_on");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "min_window_size"), "set_min_window_size", "get_min_window_size");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "max_window_size"), "set_max_window_size", "get_max_window_size");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "screen_orientation", PROPERTY_HINT_ENUM, "Landscape,Portrait,Reverse Landscape,Reverse Portrait,Sensor Landscape,Sensor Portrait,Sensor"), "set_screen_orientation", "get_screen_orientation");
- ADD_GROUP("Window", "window_");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "window_borderless"), "set_borderless_window", "get_borderless_window");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "window_per_pixel_transparency_enabled"), "set_window_per_pixel_transparency_enabled", "get_window_per_pixel_transparency_enabled");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "window_fullscreen"), "set_window_fullscreen", "is_window_fullscreen");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "window_maximized"), "set_window_maximized", "is_window_maximized");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "window_minimized"), "set_window_minimized", "is_window_minimized");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "window_resizable"), "set_window_resizable", "is_window_resizable");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "window_position"), "set_window_position", "get_window_position");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "window_size"), "set_window_size", "get_window_size");
// Those default values need to be specified for the docs generator,
// to avoid using values from the documentation writer's own OS instance.
- ADD_PROPERTY_DEFAULT("clipboard", "");
- ADD_PROPERTY_DEFAULT("current_screen", 0);
ADD_PROPERTY_DEFAULT("exit_code", 0);
- ADD_PROPERTY_DEFAULT("vsync_enabled", true);
- ADD_PROPERTY_DEFAULT("vsync_via_compositor", false);
ADD_PROPERTY_DEFAULT("low_processor_usage_mode", false);
ADD_PROPERTY_DEFAULT("low_processor_usage_mode_sleep_usec", 6900);
- ADD_PROPERTY_DEFAULT("keep_screen_on", true);
- ADD_PROPERTY_DEFAULT("min_window_size", Vector2());
- ADD_PROPERTY_DEFAULT("max_window_size", Vector2());
- ADD_PROPERTY_DEFAULT("screen_orientation", 0);
- ADD_PROPERTY_DEFAULT("window_borderless", false);
- ADD_PROPERTY_DEFAULT("window_per_pixel_transparency_enabled", false);
- ADD_PROPERTY_DEFAULT("window_fullscreen", false);
- ADD_PROPERTY_DEFAULT("window_maximized", false);
- ADD_PROPERTY_DEFAULT("window_minimized", false);
- ADD_PROPERTY_DEFAULT("window_resizable", true);
- ADD_PROPERTY_DEFAULT("window_position", Vector2());
- ADD_PROPERTY_DEFAULT("window_size", Vector2());
BIND_ENUM_CONSTANT(VIDEO_DRIVER_GLES2);
BIND_ENUM_CONSTANT(VIDEO_DRIVER_VULKAN);
@@ -1424,14 +899,6 @@ void _OS::_bind_methods() {
BIND_ENUM_CONSTANT(MONTH_NOVEMBER);
BIND_ENUM_CONSTANT(MONTH_DECEMBER);
- BIND_ENUM_CONSTANT(SCREEN_ORIENTATION_LANDSCAPE);
- BIND_ENUM_CONSTANT(SCREEN_ORIENTATION_PORTRAIT);
- BIND_ENUM_CONSTANT(SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
- BIND_ENUM_CONSTANT(SCREEN_ORIENTATION_REVERSE_PORTRAIT);
- BIND_ENUM_CONSTANT(SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
- BIND_ENUM_CONSTANT(SCREEN_ORIENTATION_SENSOR_PORTRAIT);
- BIND_ENUM_CONSTANT(SCREEN_ORIENTATION_SENSOR);
-
BIND_ENUM_CONSTANT(SYSTEM_DIR_DESKTOP);
BIND_ENUM_CONSTANT(SYSTEM_DIR_DCIM);
BIND_ENUM_CONSTANT(SYSTEM_DIR_DOCUMENTS);
diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h
index 3a5bd28ce8..510d87844d 100644
--- a/core/bind/core_bind.h
+++ b/core/bind/core_bind.h
@@ -145,83 +145,10 @@ public:
MONTH_DECEMBER
};
- void global_menu_add_item(const String &p_menu, const String &p_label, const Variant &p_signal, const Variant &p_meta);
- void global_menu_add_separator(const String &p_menu);
- void global_menu_remove_item(const String &p_menu, int p_idx);
- void global_menu_clear(const String &p_menu);
-
- Point2 get_mouse_position() const;
- void set_window_title(const String &p_title);
- int get_mouse_button_state() const;
-
- void set_clipboard(const String &p_text);
- String get_clipboard() const;
-
- void set_video_mode(const Size2 &p_size, bool p_fullscreen, bool p_resizeable, int p_screen = 0);
- Size2 get_video_mode(int p_screen = 0) const;
- bool is_video_mode_fullscreen(int p_screen = 0) const;
- bool is_video_mode_resizable(int p_screen = 0) const;
- Array get_fullscreen_mode_list(int p_screen = 0) const;
-
- virtual int get_video_driver_count() const;
- virtual String get_video_driver_name(VideoDriver p_driver) const;
- virtual VideoDriver get_current_video_driver() const;
-
- virtual int get_audio_driver_count() const;
- virtual String get_audio_driver_name(int p_driver) const;
-
virtual PackedStringArray get_connected_midi_inputs();
virtual void open_midi_inputs();
virtual void close_midi_inputs();
- virtual int get_screen_count() const;
- virtual int get_current_screen() const;
- virtual void set_current_screen(int p_screen);
- virtual Point2 get_screen_position(int p_screen = -1) const;
- virtual Size2 get_screen_size(int p_screen = -1) const;
- virtual int get_screen_dpi(int p_screen = -1) const;
- virtual Point2 get_window_position() const;
- virtual void set_window_position(const Point2 &p_position);
- virtual Size2 get_max_window_size() const;
- virtual Size2 get_min_window_size() const;
- virtual Size2 get_window_size() const;
- virtual Size2 get_real_window_size() const;
- virtual Rect2 get_window_safe_area() const;
- virtual void set_max_window_size(const Size2 &p_size);
- virtual void set_min_window_size(const Size2 &p_size);
- virtual void set_window_size(const Size2 &p_size);
- virtual void set_window_fullscreen(bool p_enabled);
- virtual bool is_window_fullscreen() const;
- virtual void set_window_resizable(bool p_enabled);
- virtual bool is_window_resizable() const;
- virtual void set_window_minimized(bool p_enabled);
- virtual bool is_window_minimized() const;
- virtual void set_window_maximized(bool p_enabled);
- virtual bool is_window_maximized() const;
- virtual void set_window_always_on_top(bool p_enabled);
- virtual bool is_window_always_on_top() const;
- virtual bool is_window_focused() const;
- virtual void request_attention();
- virtual void center_window();
- virtual void move_window_to_foreground();
-
- virtual void set_borderless_window(bool p_borderless);
- virtual bool get_borderless_window() const;
-
- virtual bool get_window_per_pixel_transparency_enabled() const;
- virtual void set_window_per_pixel_transparency_enabled(bool p_enabled);
-
- virtual void set_ime_active(const bool p_active);
- virtual void set_ime_position(const Point2 &p_pos);
- virtual Point2 get_ime_selection() const;
- virtual String get_ime_text() const;
-
- Error native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track);
- bool native_video_is_playing();
- void native_video_pause();
- void native_video_unpause();
- void native_video_stop();
-
void set_low_processor_usage_mode(bool p_enabled);
bool is_in_low_processor_usage_mode() const;
@@ -243,25 +170,17 @@ public:
Vector<String> get_cmdline_args();
String get_locale() const;
- String get_latin_keyboard_variant() const;
String get_model_name() const;
void dump_memory_to_file(const String &p_file);
void dump_resources_to_file(const String &p_file);
- bool has_virtual_keyboard() const;
- void show_virtual_keyboard(const String &p_existing_text = "");
- void hide_virtual_keyboard();
- int get_virtual_keyboard_height();
-
void print_resources_in_use(bool p_short = false);
void print_all_resources(const String &p_to_file);
void print_all_textures_by_size();
void print_resources_by_type(const Vector<String> &p_types);
- bool has_touchscreen_ui_hint() const;
-
bool is_debug_build() const;
String get_unique_id() const;
@@ -272,9 +191,6 @@ public:
void set_use_file_access_save_and_swap(bool p_enable);
- void set_native_icon(const String &p_filename);
- void set_icon(const Ref<Image> &p_icon);
-
int get_exit_code() const;
void set_exit_code(int p_code);
Dictionary get_date(bool utc) const;
@@ -298,8 +214,6 @@ public:
bool can_use_threads() const;
- bool can_draw() const;
-
bool is_userfs_persistent() const;
bool is_stdout_verbose() const;
@@ -317,39 +231,12 @@ public:
SYSTEM_DIR_RINGTONES,
};
- enum ScreenOrientation {
-
- SCREEN_ORIENTATION_LANDSCAPE,
- SCREEN_ORIENTATION_PORTRAIT,
- SCREEN_ORIENTATION_REVERSE_LANDSCAPE,
- SCREEN_ORIENTATION_REVERSE_PORTRAIT,
- SCREEN_ORIENTATION_SENSOR_LANDSCAPE,
- SCREEN_ORIENTATION_SENSOR_PORTRAIT,
- SCREEN_ORIENTATION_SENSOR,
- };
-
String get_system_dir(SystemDir p_dir) const;
String get_user_data_dir() const;
- void alert(const String &p_alert, const String &p_title = "ALERT!");
-
- void set_screen_orientation(ScreenOrientation p_orientation);
- ScreenOrientation get_screen_orientation() const;
-
- void set_keep_screen_on(bool p_enabled);
- bool is_keep_screen_on() const;
-
- bool is_ok_left_and_cancel_right() const;
-
Error set_thread_name(const String &p_name);
- void set_use_vsync(bool p_enable);
- bool is_vsync_enabled() const;
-
- void set_vsync_via_compositor(bool p_enable);
- bool is_vsync_via_compositor_enabled() const;
-
bool has_feature(const String &p_feature) const;
bool request_permission(const String &p_name);
@@ -365,7 +252,6 @@ VARIANT_ENUM_CAST(_OS::VideoDriver);
VARIANT_ENUM_CAST(_OS::Weekday);
VARIANT_ENUM_CAST(_OS::Month);
VARIANT_ENUM_CAST(_OS::SystemDir);
-VARIANT_ENUM_CAST(_OS::ScreenOrientation);
class _Geometry : public Object {
diff --git a/core/debugger/remote_debugger.cpp b/core/debugger/remote_debugger.cpp
index 09c60e222c..1cf18239ab 100644
--- a/core/debugger/remote_debugger.cpp
+++ b/core/debugger/remote_debugger.cpp
@@ -38,6 +38,7 @@
#include "core/project_settings.h"
#include "core/script_language.h"
#include "scene/main/node.h"
+#include "servers/display_server.h"
template <typename T>
void RemoteDebugger::_bind_profiler(const String &p_name, T *p_prof) {
@@ -694,7 +695,7 @@ void RemoteDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
} else if (command == "continue") {
script_debugger->set_depth(-1);
script_debugger->set_lines_left(-1);
- OS::get_singleton()->move_window_to_foreground();
+ DisplayServer::get_singleton()->window_move_to_foreground();
break;
} else if (command == "break") {
diff --git a/core/input/input.cpp b/core/input/input.cpp
index 2bede44d19..d40feffe97 100644
--- a/core/input/input.cpp
+++ b/core/input/input.cpp
@@ -41,6 +41,12 @@
Input *Input::singleton = NULL;
+void (*Input::set_mouse_mode_func)(Input::MouseMode) = nullptr;
+Input::MouseMode (*Input::get_mouse_mode_func)() = nullptr;
+void (*Input::warp_mouse_func)(const Vector2 &p_to_pos) = nullptr;
+Input::CursorShape (*Input::get_current_cursor_shape_func)() = nullptr;
+void (*Input::set_custom_mouse_cursor_func)(const RES &, Input::CursorShape, const Vector2 &) = nullptr;
+
Input *Input::get_singleton() {
return singleton;
@@ -48,12 +54,12 @@ Input *Input::get_singleton() {
void Input::set_mouse_mode(MouseMode p_mode) {
ERR_FAIL_INDEX((int)p_mode, 4);
- OS::get_singleton()->set_mouse_mode((OS::MouseMode)p_mode);
+ set_mouse_mode_func(p_mode);
}
Input::MouseMode Input::get_mouse_mode() const {
- return (MouseMode)OS::get_singleton()->get_mouse_mode();
+ return get_mouse_mode_func();
}
void Input::_bind_methods() {
@@ -654,10 +660,8 @@ int Input::get_mouse_button_mask() const {
}
void Input::warp_mouse_position(const Vector2 &p_to) {
-
- OS::get_singleton()->warp_mouse_position(p_to);
+ warp_mouse_func(p_to);
}
-
Point2i Input::warp_mouse_motion(const Ref<InputEventMouseMotion> &p_motion, const Rect2 &p_rect) {
// The relative distance reported for the next event after a warp is in the boundaries of the
@@ -678,7 +682,7 @@ Point2i Input::warp_mouse_motion(const Ref<InputEventMouseMotion> &p_motion, con
const Point2i pos_local = p_motion->get_global_position() - p_rect.position;
const Point2i pos_warped(Math::fposmod(pos_local.x, p_rect.size.x), Math::fposmod(pos_local.y, p_rect.size.y));
if (pos_warped != pos_local) {
- OS::get_singleton()->warp_mouse_position(pos_warped + p_rect.position);
+ warp_mouse_position(pos_warped + p_rect.position);
}
return rel_warped;
@@ -774,14 +778,14 @@ void Input::set_default_cursor_shape(CursorShape p_shape) {
Input::CursorShape Input::get_current_cursor_shape() const {
- return (Input::CursorShape)OS::get_singleton()->get_cursor_shape();
+ return get_current_cursor_shape_func();
}
void Input::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
if (Engine::get_singleton()->is_editor_hint())
return;
- OS::get_singleton()->set_custom_mouse_cursor(p_cursor, (OS::CursorShape)p_shape, p_hotspot);
+ set_custom_mouse_cursor_func(p_cursor, p_shape, p_hotspot);
}
void Input::accumulate_input_event(const Ref<InputEvent> &p_event) {
@@ -1171,23 +1175,13 @@ void Input::set_fallback_mapping(String p_guid) {
}
}
-//Defaults to simple implementation for platforms with a fixed gamepad layout, like consoles.
-bool Input::is_joy_known(int p_device) {
-
- return OS::get_singleton()->is_joy_known(p_device);
-}
-
-String Input::get_joy_guid(int p_device) const {
- return OS::get_singleton()->get_joy_guid(p_device);
-}
-
//platforms that use the remapping system can override and call to these ones
-bool Input::is_joy_mapped(int p_device) {
+bool Input::is_joy_known(int p_device) {
int mapping = joy_names[p_device].mapping;
return mapping != -1 ? (mapping != fallback_mapping) : false;
}
-String Input::get_joy_guid_remapped(int p_device) const {
+String Input::get_joy_guid(int p_device) const {
ERR_FAIL_COND_V(!joy_names.has(p_device), "");
return joy_names[p_device].uid;
}
diff --git a/core/input/input.h b/core/input/input.h
index eb2880e953..6299255a92 100644
--- a/core/input/input.h
+++ b/core/input/input.h
@@ -219,6 +219,14 @@ private:
List<Ref<InputEvent>> accumulated_events;
bool use_accumulated_input;
+ friend class DisplayServer;
+
+ static void (*set_mouse_mode_func)(MouseMode);
+ static MouseMode (*get_mouse_mode_func)();
+ static void (*warp_mouse_func)(const Vector2 &p_to_pos);
+
+ static CursorShape (*get_current_cursor_shape_func)();
+ static void (*set_custom_mouse_cursor_func)(const RES &, CursorShape, const Vector2 &);
protected:
static void _bind_methods();
@@ -300,8 +308,6 @@ public:
void add_joy_mapping(String p_mapping, bool p_update_existing = false);
void remove_joy_mapping(String p_guid);
- bool is_joy_known(int p_device);
- String get_joy_guid(int p_device) const;
String get_joy_button_string(int p_button);
String get_joy_axis_string(int p_axis);
@@ -310,8 +316,8 @@ public:
int get_unused_joy_id();
- bool is_joy_mapped(int p_device);
- String get_joy_guid_remapped(int p_device) const;
+ bool is_joy_known(int p_device);
+ String get_joy_guid(int p_device) const;
void set_fallback_mapping(String p_guid);
void accumulate_input_event(const Ref<InputEvent> &p_event);
diff --git a/core/os/os.cpp b/core/os/os.cpp
index b9c0040627..9dff348b37 100644
--- a/core/os/os.cpp
+++ b/core/os/os.cpp
@@ -139,14 +139,6 @@ void OS::printerr(const char *p_format, ...) {
va_end(argp);
};
-void OS::set_keep_screen_on(bool p_enabled) {
- _keep_screen_on = p_enabled;
-}
-
-bool OS::is_keep_screen_on() const {
- return _keep_screen_on;
-}
-
void OS::set_low_processor_usage_mode(bool p_enabled) {
low_processor_usage_mode = p_enabled;
@@ -167,15 +159,6 @@ int OS::get_low_processor_usage_mode_sleep_usec() const {
return low_processor_usage_mode_sleep_usec;
}
-void OS::set_clipboard(const String &p_text) {
-
- _local_clipboard = p_text;
-}
-String OS::get_clipboard() const {
-
- return _local_clipboard;
-}
-
String OS::get_executable_path() const {
return _execpath;
@@ -216,31 +199,6 @@ static void _OS_printres(Object *p_obj) {
print_line(str);
}
-bool OS::has_virtual_keyboard() const {
-
- return false;
-}
-
-void OS::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect, int p_max_input_length) {
-}
-
-void OS::hide_virtual_keyboard() {
-}
-
-int OS::get_virtual_keyboard_height() const {
- return 0;
-}
-
-void OS::set_cursor_shape(CursorShape p_shape) {
-}
-
-OS::CursorShape OS::get_cursor_shape() const {
- return CURSOR_ARROW;
-}
-
-void OS::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
-}
-
void OS::print_all_resources(String p_to_file) {
ERR_FAIL_COND(p_to_file != "" && _OSPRF);
@@ -372,45 +330,6 @@ Error OS::shell_open(String p_uri) {
};
// implement these with the canvas?
-Error OS::dialog_show(String p_title, String p_description, Vector<String> p_buttons, Object *p_obj, String p_callback) {
-
- while (true) {
-
- print("%ls\n--------\n%ls\n", p_title.c_str(), p_description.c_str());
- for (int i = 0; i < p_buttons.size(); i++) {
- if (i > 0) print(", ");
- print("%i=%ls", i + 1, p_buttons[i].c_str());
- };
- print("\n");
- String res = get_stdin_string().strip_edges();
- if (!res.is_numeric())
- continue;
- int n = res.to_int();
- if (n < 0 || n >= p_buttons.size())
- continue;
- if (p_obj && p_callback != "")
- p_obj->call_deferred(p_callback, n);
- break;
- };
- return OK;
-};
-
-Error OS::dialog_input_text(String p_title, String p_description, String p_partial, Object *p_obj, String p_callback) {
-
- ERR_FAIL_COND_V(!p_obj, FAILED);
- ERR_FAIL_COND_V(p_callback == "", FAILED);
- print("%ls\n---------\n%ls\n[%ls]:\n", p_title.c_str(), p_description.c_str(), p_partial.c_str());
-
- String res = get_stdin_string().strip_edges();
- bool success = true;
- if (res == "") {
- res = p_partial;
- };
-
- p_obj->call_deferred(p_callback, success, res);
-
- return OK;
-};
uint64_t OS::get_static_memory_usage() const {
@@ -427,12 +346,6 @@ Error OS::set_cwd(const String &p_cwd) {
return ERR_CANT_OPEN;
}
-bool OS::has_touchscreen_ui_hint() const {
-
- //return false;
- return Input::get_singleton() && Input::get_singleton()->is_emulating_touch_from_mouse();
-}
-
uint64_t OS::get_free_static_memory() const {
return Memory::get_mem_available();
@@ -441,17 +354,7 @@ uint64_t OS::get_free_static_memory() const {
void OS::yield() {
}
-void OS::set_screen_orientation(ScreenOrientation p_orientation) {
-
- _orientation = p_orientation;
-}
-
-OS::ScreenOrientation OS::get_screen_orientation() const {
-
- return (OS::ScreenOrientation)_orientation;
-}
-
-void OS::_ensure_user_data_dir() {
+void OS::ensure_user_data_dir() {
String dd = get_user_data_dir();
DirAccess *da = DirAccess::open(dd);
@@ -467,12 +370,6 @@ void OS::_ensure_user_data_dir() {
memdelete(da);
}
-void OS::set_native_icon(const String &p_filename) {
-}
-
-void OS::set_icon(const Ref<Image> &p_icon) {
-}
-
String OS::get_model_name() const {
return "GenericDevice";
@@ -484,15 +381,6 @@ void OS::set_cmdline(const char *p_execpath, const List<String> &p_args) {
_cmdline = p_args;
};
-void OS::release_rendering_thread() {
-}
-
-void OS::make_rendering_thread() {
-}
-
-void OS::swap_buffers() {
-}
-
String OS::get_unique_id() const {
ERR_FAIL_V("");
@@ -503,31 +391,6 @@ int OS::get_processor_count() const {
return 1;
}
-Error OS::native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track) {
-
- return FAILED;
-};
-
-bool OS::native_video_is_playing() const {
-
- return false;
-};
-
-void OS::native_video_pause(){
-
-};
-
-void OS::native_video_unpause(){
-
-};
-
-void OS::native_video_stop(){
-
-};
-
-void OS::set_mouse_mode(MouseMode p_mode) {
-}
-
bool OS::can_use_threads() const {
#ifdef NO_THREADS
@@ -537,51 +400,6 @@ bool OS::can_use_threads() const {
#endif
}
-OS::MouseMode OS::get_mouse_mode() const {
-
- return MOUSE_MODE_VISIBLE;
-}
-
-OS::LatinKeyboardVariant OS::get_latin_keyboard_variant() const {
-
- return LATIN_KEYBOARD_QWERTY;
-}
-
-bool OS::is_joy_known(int p_device) {
- return true;
-}
-
-String OS::get_joy_guid(int p_device) const {
- return "Default Joypad";
-}
-
-void OS::set_context(int p_context) {
-}
-
-OS::SwitchVSyncCallbackInThread OS::switch_vsync_function = NULL;
-
-void OS::set_use_vsync(bool p_enable) {
- _use_vsync = p_enable;
- if (switch_vsync_function) { //if a function was set, use function
- switch_vsync_function(p_enable);
- } else { //otherwise just call here
- _set_use_vsync(p_enable);
- }
-}
-
-bool OS::is_vsync_enabled() const {
-
- return _use_vsync;
-}
-
-void OS::set_vsync_via_compositor(bool p_enable) {
- _vsync_via_compositor = p_enable;
-}
-
-bool OS::is_vsync_via_compositor_enabled() const {
- return _vsync_via_compositor;
-}
-
void OS::set_has_server_feature_callback(HasServerFeatureCallback p_callback) {
has_server_feature_callback = p_callback;
@@ -653,48 +471,6 @@ bool OS::has_feature(const String &p_feature) {
return false;
}
-void OS::center_window() {
-
- if (is_window_fullscreen()) return;
-
- Point2 sp = get_screen_position(get_current_screen());
- Size2 scr = get_screen_size(get_current_screen());
- Size2 wnd = get_real_window_size();
-
- int x = sp.width + (scr.width - wnd.width) / 2;
- int y = sp.height + (scr.height - wnd.height) / 2;
-
- set_window_position(Vector2(x, y));
-}
-
-int OS::get_video_driver_count() const {
-
- return 2;
-}
-
-const char *OS::get_video_driver_name(int p_driver) const {
-
- switch (p_driver) {
- case VIDEO_DRIVER_GLES2:
- return "GLES2";
- case VIDEO_DRIVER_VULKAN:
- default:
- return "Vulkan";
- }
-}
-
-int OS::get_audio_driver_count() const {
-
- return AudioDriverManager::get_driver_count();
-}
-
-const char *OS::get_audio_driver_name(int p_driver) const {
-
- AudioDriver *driver = AudioDriverManager::get_driver(p_driver);
- ERR_FAIL_COND_V_MSG(!driver, "", "Cannot get audio driver at index '" + itos(p_driver) + "'.");
- return AudioDriverManager::get_driver(p_driver)->get_name();
-}
-
void OS::set_restart_on_exit(bool p_restart, const List<String> &p_restart_arguments) {
restart_on_exit = p_restart;
restart_commandline = p_restart_arguments;
@@ -740,7 +516,6 @@ OS::OS() {
_verbose_stdout = false;
_no_window = false;
_exit_code = 0;
- _orientation = SCREEN_LANDSCAPE;
_render_thread_mode = RENDER_THREAD_SAFE;
diff --git a/core/os/os.h b/core/os/os.h
index 3e2ee7affd..e15bc90e86 100644
--- a/core/os/os.h
+++ b/core/os/os.h
@@ -82,31 +82,6 @@ public:
RENDER_THREAD_SAFE,
RENDER_SEPARATE_THREAD
};
- struct VideoMode {
-
- int width, height;
- bool fullscreen;
- bool resizable;
- bool borderless_window;
- bool maximized;
- bool always_on_top;
- bool use_vsync;
- bool vsync_via_compositor;
- bool layered;
- float get_aspect() const { return (float)width / (float)height; }
- VideoMode(int p_width = 1024, int p_height = 600, bool p_fullscreen = false, bool p_resizable = true, bool p_borderless_window = false, bool p_maximized = false, bool p_always_on_top = false, bool p_use_vsync = false, bool p_vsync_via_compositor = false) {
- width = p_width;
- height = p_height;
- fullscreen = p_fullscreen;
- resizable = p_resizable;
- borderless_window = p_borderless_window;
- maximized = p_maximized;
- always_on_top = p_always_on_top;
- use_vsync = p_use_vsync;
- vsync_via_compositor = p_vsync_via_compositor;
- layered = false;
- }
- };
protected:
friend class Main;
@@ -117,8 +92,8 @@ protected:
// functions used by main to initialize/deinitialize the OS
void add_logger(Logger *p_logger);
- virtual void initialize_core() = 0;
- virtual Error initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) = 0;
+ virtual void initialize() = 0;
+ virtual void initialize_joypads() = 0;
virtual void set_main_loop(MainLoop *p_main_loop) = 0;
virtual void delete_main_loop() = 0;
@@ -128,7 +103,6 @@ protected:
virtual void set_cmdline(const char *p_execpath, const List<String> &p_args);
- void _ensure_user_data_dir();
virtual bool _check_internal_feature_support(const String &p_feature) = 0;
public:
@@ -136,121 +110,20 @@ public:
static OS *get_singleton();
- virtual void global_menu_add_item(const String &p_menu, const String &p_label, const Variant &p_signal, const Variant &p_meta){};
- virtual void global_menu_add_separator(const String &p_menu){};
- virtual void global_menu_remove_item(const String &p_menu, int p_idx){};
- virtual void global_menu_clear(const String &p_menu){};
-
void print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, Logger::ErrorType p_type = Logger::ERR_ERROR);
void print(const char *p_format, ...) _PRINTF_FORMAT_ATTRIBUTE_2_3;
void printerr(const char *p_format, ...) _PRINTF_FORMAT_ATTRIBUTE_2_3;
- virtual void alert(const String &p_alert, const String &p_title = "ALERT!") = 0;
virtual String get_stdin_string(bool p_block = true) = 0;
- enum MouseMode {
- MOUSE_MODE_VISIBLE,
- MOUSE_MODE_HIDDEN,
- MOUSE_MODE_CAPTURED,
- MOUSE_MODE_CONFINED
- };
-
- virtual void set_mouse_mode(MouseMode p_mode);
- virtual MouseMode get_mouse_mode() const;
-
- virtual void warp_mouse_position(const Point2 &p_to) {}
- virtual Point2 get_mouse_position() const = 0;
- virtual int get_mouse_button_state() const = 0;
- virtual void set_window_title(const String &p_title) = 0;
-
- virtual void set_clipboard(const String &p_text);
- virtual String get_clipboard() const;
-
- virtual void set_video_mode(const VideoMode &p_video_mode, int p_screen = 0) = 0;
- virtual VideoMode get_video_mode(int p_screen = 0) const = 0;
- virtual void get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen = 0) const = 0;
-
- enum VideoDriver {
- VIDEO_DRIVER_VULKAN,
- VIDEO_DRIVER_GLES2,
- VIDEO_DRIVER_MAX,
- };
-
- virtual int get_video_driver_count() const;
- virtual const char *get_video_driver_name(int p_driver) const;
- virtual int get_current_video_driver() const = 0;
-
- virtual int get_audio_driver_count() const;
- virtual const char *get_audio_driver_name(int p_driver) const;
-
virtual PackedStringArray get_connected_midi_inputs();
virtual void open_midi_inputs();
virtual void close_midi_inputs();
- virtual int get_screen_count() const { return 1; }
- virtual int get_current_screen() const { return 0; }
- virtual void set_current_screen(int p_screen) {}
- virtual Point2 get_screen_position(int p_screen = -1) const { return Point2(); }
- virtual Size2 get_screen_size(int p_screen = -1) const { return get_window_size(); }
- virtual int get_screen_dpi(int p_screen = -1) const { return 72; }
- virtual Point2 get_window_position() const { return Vector2(); }
- virtual void set_window_position(const Point2 &p_position) {}
- virtual Size2 get_max_window_size() const { return Size2(); };
- virtual Size2 get_min_window_size() const { return Size2(); };
- virtual Size2 get_window_size() const = 0;
- virtual Size2 get_real_window_size() const { return get_window_size(); }
- virtual void set_min_window_size(const Size2 p_size) {}
- virtual void set_max_window_size(const Size2 p_size) {}
- virtual void set_window_size(const Size2 p_size) {}
- virtual void set_window_fullscreen(bool p_enabled) {}
- virtual bool is_window_fullscreen() const { return true; }
- virtual void set_window_resizable(bool p_enabled) {}
- virtual bool is_window_resizable() const { return false; }
- virtual void set_window_minimized(bool p_enabled) {}
- virtual bool is_window_minimized() const { return false; }
- virtual void set_window_maximized(bool p_enabled) {}
- virtual bool is_window_maximized() const { return true; }
- virtual void set_window_always_on_top(bool p_enabled) {}
- virtual bool is_window_always_on_top() const { return false; }
- virtual bool is_window_focused() const { return true; }
- virtual void set_console_visible(bool p_enabled) {}
- virtual bool is_console_visible() const { return false; }
- virtual void request_attention() {}
- virtual void center_window();
-
- // Returns window area free of hardware controls and other obstacles.
- // The application should use this to determine where to place UI elements.
- //
- // Keep in mind the area returned is in window coordinates rather than
- // viewport coordinates - you should perform the conversion on your own.
- //
- // The maximum size of the area is Rect2(0, 0, window_size.width, window_size.height).
- virtual Rect2 get_window_safe_area() const {
- Size2 window_size = get_window_size();
- return Rect2(0, 0, window_size.width, window_size.height);
- }
-
- virtual void set_borderless_window(bool p_borderless) {}
- virtual bool get_borderless_window() { return 0; }
-
- virtual bool get_window_per_pixel_transparency_enabled() const { return false; }
- virtual void set_window_per_pixel_transparency_enabled(bool p_enabled) {}
-
- virtual uint8_t *get_layered_buffer_data() { return NULL; }
- virtual Size2 get_layered_buffer_size() { return Size2(0, 0); }
- virtual void swap_layered_buffer() {}
-
- virtual void set_ime_active(const bool p_active) {}
- virtual void set_ime_position(const Point2 &p_pos) {}
- virtual Point2 get_ime_selection() const { return Point2(); }
- virtual String get_ime_text() const { return String(); }
-
virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false) { return ERR_UNAVAILABLE; }
virtual Error close_dynamic_library(void *p_library_handle) { return ERR_UNAVAILABLE; }
virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional = false) { return ERR_UNAVAILABLE; }
- virtual void set_keep_screen_on(bool p_enabled);
- virtual bool is_keep_screen_on() const;
virtual void set_low_processor_usage_mode(bool p_enabled);
virtual bool is_in_low_processor_usage_mode() const;
virtual void set_low_processor_usage_mode_sleep_usec(int p_usec);
@@ -273,6 +146,8 @@ public:
virtual List<String> get_cmdline_args() const { return _cmdline; }
virtual String get_model_name() const;
+ void ensure_user_data_dir();
+
virtual MainLoop *get_main_loop() const = 0;
virtual void yield();
@@ -338,8 +213,6 @@ public:
uint32_t get_ticks_msec() const;
uint64_t get_splash_tick_msec() const;
- virtual bool can_draw() const = 0;
-
virtual bool is_userfs_persistent() const { return true; }
bool is_stdout_verbose() const;
@@ -348,39 +221,6 @@ public:
virtual bool is_disable_crash_handler() const { return false; }
virtual void initialize_debugging() {}
- enum CursorShape {
- CURSOR_ARROW,
- CURSOR_IBEAM,
- CURSOR_POINTING_HAND,
- CURSOR_CROSS,
- CURSOR_WAIT,
- CURSOR_BUSY,
- CURSOR_DRAG,
- CURSOR_CAN_DROP,
- CURSOR_FORBIDDEN,
- CURSOR_VSIZE,
- CURSOR_HSIZE,
- CURSOR_BDIAGSIZE,
- CURSOR_FDIAGSIZE,
- CURSOR_MOVE,
- CURSOR_VSPLIT,
- CURSOR_HSPLIT,
- CURSOR_HELP,
- CURSOR_MAX
- };
-
- virtual bool has_virtual_keyboard() const;
- virtual void show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), int p_max_input_length = -1);
- virtual void hide_virtual_keyboard();
-
- // returns height of the currently shown virtual keyboard (0 if keyboard is hidden)
- virtual int get_virtual_keyboard_height() const;
-
- virtual void set_cursor_shape(CursorShape p_shape);
- virtual CursorShape get_cursor_shape() const;
- virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot);
-
- virtual bool get_swap_ok_cancel() { return false; }
virtual void dump_memory_to_file(const char *p_file);
virtual void dump_resources_to_file(const char *p_file);
virtual void print_resources_in_use(bool p_short = false);
@@ -423,34 +263,8 @@ public:
virtual void set_no_window_mode(bool p_enable);
virtual bool is_no_window_mode_enabled() const;
- virtual bool has_touchscreen_ui_hint() const;
-
- enum ScreenOrientation {
-
- SCREEN_LANDSCAPE,
- SCREEN_PORTRAIT,
- SCREEN_REVERSE_LANDSCAPE,
- SCREEN_REVERSE_PORTRAIT,
- SCREEN_SENSOR_LANDSCAPE,
- SCREEN_SENSOR_PORTRAIT,
- SCREEN_SENSOR,
- };
-
- virtual void set_screen_orientation(ScreenOrientation p_orientation);
- ScreenOrientation get_screen_orientation() const;
-
- virtual void enable_for_stealing_focus(ProcessID pid) {}
- virtual void move_window_to_foreground() {}
-
virtual void debug_break();
- virtual void release_rendering_thread();
- virtual void make_rendering_thread();
- virtual void swap_buffers();
-
- virtual void set_native_icon(const String &p_filename);
- virtual void set_icon(const Ref<Image> &p_icon);
-
virtual int get_exit_code() const;
virtual void set_exit_code(int p_code);
@@ -458,62 +272,12 @@ public:
virtual String get_unique_id() const;
- virtual Error native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track);
- virtual bool native_video_is_playing() const;
- virtual void native_video_pause();
- virtual void native_video_unpause();
- virtual void native_video_stop();
-
virtual bool can_use_threads() const;
- virtual Error dialog_show(String p_title, String p_description, Vector<String> p_buttons, Object *p_obj, String p_callback);
- virtual Error dialog_input_text(String p_title, String p_description, String p_partial, Object *p_obj, String p_callback);
-
- enum LatinKeyboardVariant {
- LATIN_KEYBOARD_QWERTY,
- LATIN_KEYBOARD_QWERTZ,
- LATIN_KEYBOARD_AZERTY,
- LATIN_KEYBOARD_QZERTY,
- LATIN_KEYBOARD_DVORAK,
- LATIN_KEYBOARD_NEO,
- LATIN_KEYBOARD_COLEMAK,
- };
-
- virtual LatinKeyboardVariant get_latin_keyboard_variant() const;
-
- virtual bool is_joy_known(int p_device);
- virtual String get_joy_guid(int p_device) const;
-
- enum EngineContext {
- CONTEXT_EDITOR,
- CONTEXT_PROJECTMAN,
- CONTEXT_ENGINE,
- };
-
- virtual void set_context(int p_context);
-
- //amazing hack because OpenGL needs this to be set on a separate thread..
- //also core can't access servers, so a callback must be used
- typedef void (*SwitchVSyncCallbackInThread)(bool);
-
- static SwitchVSyncCallbackInThread switch_vsync_function;
- void set_use_vsync(bool p_enable);
- bool is_vsync_enabled() const;
-
- //real, actual overridable function to switch vsync, which needs to be called from graphics thread if needed
- virtual void _set_use_vsync(bool p_enable) {}
-
- void set_vsync_via_compositor(bool p_enable);
- bool is_vsync_via_compositor_enabled() const;
-
- virtual void force_process_input(){};
bool has_feature(const String &p_feature);
void set_has_server_feature_callback(HasServerFeatureCallback p_callback);
- bool is_layered_allowed() const { return _allow_layered; }
- bool is_hidpi_allowed() const { return _allow_hidpi; }
-
void set_restart_on_exit(bool p_restart, const List<String> &p_restart_arguments);
bool is_restart_on_exit_set() const;
List<String> get_restart_on_exit_arguments() const;
diff --git a/drivers/gl_context/SCsub b/drivers/gl_context/SCsub
index b9f0ea2254..d6945ee2eb 100644
--- a/drivers/gl_context/SCsub
+++ b/drivers/gl_context/SCsub
@@ -2,7 +2,7 @@
Import('env')
-if (env["platform"] in ["haiku", "osx", "windows", "x11"]):
+if (env["platform"] in ["haiku", "osx", "windows", "linuxbsd"]):
# Thirdparty source files
thirdparty_dir = "#thirdparty/glad/"
thirdparty_sources = [
diff --git a/drivers/gles2/rasterizer_canvas_gles2.cpp b/drivers/gles2/rasterizer_canvas_gles2.cpp
index 24927c4bb8..5e8948e9c4 100644
--- a/drivers/gles2/rasterizer_canvas_gles2.cpp
+++ b/drivers/gles2/rasterizer_canvas_gles2.cpp
@@ -124,7 +124,7 @@ void RasterizerCanvasGLES2::canvas_begin() {
viewport_width = storage->frame.current_rt->width;
viewport_height = storage->frame.current_rt->height;
viewport_x = storage->frame.current_rt->x;
- viewport_y = OS::get_singleton()->get_window_size().height - viewport_height - storage->frame.current_rt->y;
+ viewport_y = DisplayServer::get_singleton()->window_get_size().height - viewport_height - storage->frame.current_rt->y;
glScissor(viewport_x, viewport_y, viewport_width, viewport_height);
glViewport(viewport_x, viewport_y, viewport_width, viewport_height);
glEnable(GL_SCISSOR_TEST);
@@ -168,7 +168,7 @@ void RasterizerCanvasGLES2::canvas_begin() {
canvas_transform.translate(-(storage->frame.current_rt->width / 2.0f), -(storage->frame.current_rt->height / 2.0f), 0.0f);
canvas_transform.scale(Vector3(2.0f / storage->frame.current_rt->width, csy * -2.0f / storage->frame.current_rt->height, 1.0f));
} else {
- Vector2 ssize = OS::get_singleton()->get_window_size();
+ Vector2 ssize = DisplayServer::get_singleton()->window_get_size();
canvas_transform.translate(-(ssize.width / 2.0f), -(ssize.height / 2.0f), 0.0f);
canvas_transform.scale(Vector3(2.0f / ssize.width, -2.0f / ssize.height, 1.0f));
}
@@ -194,8 +194,8 @@ void RasterizerCanvasGLES2::canvas_end() {
if (storage->frame.current_rt && storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_DIRECT_TO_SCREEN]) {
//reset viewport to full window size
- int viewport_width = OS::get_singleton()->get_window_size().width;
- int viewport_height = OS::get_singleton()->get_window_size().height;
+ int viewport_width = DisplayServer::get_singleton()->window_get_size().width;
+ int viewport_height = DisplayServer::get_singleton()->window_get_size().height;
glViewport(0, 0, viewport_width, viewport_height);
glScissor(0, 0, viewport_width, viewport_height);
}
@@ -1995,7 +1995,7 @@ void RasterizerCanvasGLES2::draw_lens_distortion_rect(const Rect2 &p_rect, float
if (storage->frame.current_rt) {
half_size = Vector2(storage->frame.current_rt->width, storage->frame.current_rt->height);
} else {
- half_size = OS::get_singleton()->get_window_size();
+ half_size = DisplayServer::get_singleton()->window_get_size();
}
half_size *= 0.5;
Vector2 offset((p_rect.position.x - half_size.x) / half_size.x, (p_rect.position.y - half_size.y) / half_size.y);
@@ -2029,7 +2029,7 @@ void RasterizerCanvasGLES2::draw_lens_distortion_rect(const Rect2 &p_rect, float
void RasterizerCanvasGLES2::draw_window_margins(int *black_margin, RID *black_image) {
- Vector2 window_size = OS::get_singleton()->get_window_size();
+ Vector2 window_size = DisplayServer::get_singleton()->window_get_size();
int window_h = window_size.height;
int window_w = window_size.width;
diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp
index 02b956fd44..f14c5f9406 100644
--- a/drivers/gles2/rasterizer_gles2.cpp
+++ b/drivers/gles2/rasterizer_gles2.cpp
@@ -318,7 +318,7 @@ void RasterizerGLES2::set_current_render_target(RID p_render_target) {
} else {
storage->frame.current_rt = NULL;
storage->frame.clear_request = false;
- glViewport(0, 0, OS::get_singleton()->get_window_size().width, OS::get_singleton()->get_window_size().height);
+ glViewport(0, 0, DisplayServer::get_singleton()->window_get_size().width, DisplayServer::get_singleton()->window_get_size().height);
glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES2::system_fbo);
}
}
diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp
index c433886545..8872dde9fc 100644
--- a/drivers/gles2/rasterizer_scene_gles2.cpp
+++ b/drivers/gles2/rasterizer_scene_gles2.cpp
@@ -3261,7 +3261,7 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
viewport_x = storage->frame.current_rt->x;
if (storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_DIRECT_TO_SCREEN]) {
- viewport_y = OS::get_singleton()->get_window_size().height - viewport_height - storage->frame.current_rt->y;
+ viewport_y = DisplayServer::get_singleton()->window_get_size().height - viewport_height - storage->frame.current_rt->y;
} else {
viewport_y = storage->frame.current_rt->y;
}
diff --git a/drivers/vulkan/SCsub b/drivers/vulkan/SCsub
index 85a5ae8d26..de776b19b2 100644
--- a/drivers/vulkan/SCsub
+++ b/drivers/vulkan/SCsub
@@ -57,7 +57,7 @@ if env['builtin_vulkan']:
'FALLBACK_DATA_DIRS=\\"%s\\"' % '/usr/local/share:/usr/share',
'FALLBACK_CONFIG_DIRS=\\"%s\\"' % '/etc/xdg'
])
- elif env['platform'] == "x11":
+ elif env['platform'] == "linuxbsd":
env_thirdparty.AppendUnique(CPPDEFINES=[
'VK_USE_PLATFORM_XLIB_KHR',
'VULKAN_NON_CMAKE_BUILD',
diff --git a/editor/debugger/editor_debugger_tree.cpp b/editor/debugger/editor_debugger_tree.cpp
index 019a5d0fc3..51242667ac 100644
--- a/editor/debugger/editor_debugger_tree.cpp
+++ b/editor/debugger/editor_debugger_tree.cpp
@@ -33,6 +33,7 @@
#include "editor/editor_node.h"
#include "scene/debugger/scene_debugger.h"
#include "scene/resources/packed_scene.h"
+#include "servers/display_server.h"
EditorDebuggerTree::EditorDebuggerTree() {
set_v_size_flags(SIZE_EXPAND_FILL);
@@ -257,7 +258,7 @@ void EditorDebuggerTree::_item_menu_id_pressed(int p_option) {
text = text.substr(slash + 1);
}
}
- OS::get_singleton()->set_clipboard(text);
+ DisplayServer::get_singleton()->clipboard_set(text);
} break;
}
}
diff --git a/editor/debugger/script_editor_debugger.cpp b/editor/debugger/script_editor_debugger.cpp
index dcb1611f71..9a15902982 100644
--- a/editor/debugger/script_editor_debugger.cpp
+++ b/editor/debugger/script_editor_debugger.cpp
@@ -58,6 +58,7 @@
#include "scene/gui/texture_button.h"
#include "scene/gui/tree.h"
#include "scene/resources/packed_scene.h"
+#include "servers/display_server.h"
using CameraOverride = EditorDebuggerNode::CameraOverride;
@@ -73,7 +74,7 @@ void ScriptEditorDebugger::_put_msg(String p_message, Array p_data) {
void ScriptEditorDebugger::debug_copy() {
String msg = reason->get_text();
if (msg == "") return;
- OS::get_singleton()->set_clipboard(msg);
+ DisplayServer::get_singleton()->clipboard_set(msg);
}
void ScriptEditorDebugger::debug_skip_breakpoints() {
@@ -116,7 +117,7 @@ void ScriptEditorDebugger::debug_continue() {
// Allow focus stealing only if we actually run this client for security.
if (remote_pid && EditorNode::get_singleton()->has_child_process(remote_pid))
- OS::get_singleton()->enable_for_stealing_focus(remote_pid);
+ DisplayServer::get_singleton()->enable_for_stealing_focus(remote_pid);
_clear_execution();
_put_msg("continue", Array());
@@ -253,7 +254,7 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
_update_buttons_state();
_set_reason_text(error, MESSAGE_ERROR);
emit_signal("breaked", true, can_continue);
- OS::get_singleton()->move_window_to_foreground();
+ DisplayServer::get_singleton()->window_move_to_foreground();
if (error != "") {
tabs->set_current_tab(0);
}
@@ -1420,7 +1421,7 @@ void ScriptEditorDebugger::_item_menu_id_pressed(int p_option) {
ci = ci->get_next();
}
- OS::get_singleton()->set_clipboard(text);
+ DisplayServer::get_singleton()->clipboard_set(text);
}
void ScriptEditorDebugger::_tab_changed(int p_tab) {
diff --git a/editor/editor_dir_dialog.cpp b/editor/editor_dir_dialog.cpp
index 20fe349ef6..2e71fdb75e 100644
--- a/editor/editor_dir_dialog.cpp
+++ b/editor/editor_dir_dialog.cpp
@@ -35,6 +35,7 @@
#include "editor/editor_file_system.h"
#include "editor/editor_settings.h"
#include "editor_scale.h"
+#include "servers/display_server.h"
void EditorDirDialog::_update_dir(TreeItem *p_item, EditorFileSystemDirectory *p_dir, const String &p_select_path) {
@@ -188,7 +189,7 @@ EditorDirDialog::EditorDirDialog() {
tree->connect("item_activated", callable_mp(this, &EditorDirDialog::_item_activated));
- makedir = add_button(TTR("Create Folder"), OS::get_singleton()->get_swap_ok_cancel(), "makedir");
+ makedir = add_button(TTR("Create Folder"), DisplayServer::get_singleton()->get_swap_ok_cancel(), "makedir");
makedir->connect("pressed", callable_mp(this, &EditorDirDialog::_make_dir));
makedialog = memnew(ConfirmationDialog);
diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp
index 250fa6b3e0..ff2b8dfd1e 100644
--- a/editor/editor_file_dialog.cpp
+++ b/editor/editor_file_dialog.cpp
@@ -42,6 +42,7 @@
#include "scene/gui/center_container.h"
#include "scene/gui/label.h"
#include "scene/gui/margin_container.h"
+#include "servers/display_server.h"
EditorFileDialog::GetIconFunc EditorFileDialog::get_icon_func = NULL;
EditorFileDialog::GetIconFunc EditorFileDialog::get_large_icon_func = NULL;
@@ -631,7 +632,7 @@ void EditorFileDialog::_item_menu_id_pressed(int p_option) {
case ITEM_MENU_COPY_PATH: {
Dictionary item_meta = item_list->get_item_metadata(item_list->get_current());
- OS::get_singleton()->set_clipboard(item_meta["path"]);
+ DisplayServer::get_singleton()->clipboard_set(item_meta["path"]);
} break;
case ITEM_MENU_DELETE: {
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 3ac383daad..48cd479fcf 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -169,7 +169,7 @@
#include "editor/register_exporters.h"
#include "editor/run_settings_dialog.h"
#include "editor/settings_config_dialog.h"
-
+#include "servers/display_server.h"
#include <stdio.h>
#include <stdlib.h>
@@ -179,7 +179,9 @@ void EditorNode::_update_scene_tabs() {
bool show_rb = EditorSettings::get_singleton()->get("interface/scene_tabs/show_script_button");
- OS::get_singleton()->global_menu_clear("_dock");
+ if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_GLOBAL_MENU)) {
+ DisplayServer::get_singleton()->global_menu_clear("_dock");
+ }
scene_tabs->clear_tabs();
Ref<Texture2D> script_icon = gui_base->get_icon("Script", "EditorIcons");
@@ -195,15 +197,19 @@ void EditorNode::_update_scene_tabs() {
bool unsaved = (i == current) ? saved_version != editor_data.get_undo_redo().get_version() : editor_data.get_scene_version(i) != 0;
scene_tabs->add_tab(editor_data.get_scene_title(i) + (unsaved ? "(*)" : ""), icon);
- OS::get_singleton()->global_menu_add_item("_dock", editor_data.get_scene_title(i) + (unsaved ? "(*)" : ""), GLOBAL_SCENE, i);
+ if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_GLOBAL_MENU)) {
+ DisplayServer::get_singleton()->global_menu_add_item("_dock", editor_data.get_scene_title(i) + (unsaved ? "(*)" : ""), GLOBAL_SCENE, i);
+ }
if (show_rb && editor_data.get_scene_root_script(i).is_valid()) {
scene_tabs->set_tab_right_button(i, script_icon);
}
}
- OS::get_singleton()->global_menu_add_separator("_dock");
- OS::get_singleton()->global_menu_add_item("_dock", TTR("New Window"), GLOBAL_NEW_WINDOW, Variant());
+ if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_GLOBAL_MENU)) {
+ DisplayServer::get_singleton()->global_menu_add_separator("_dock");
+ DisplayServer::get_singleton()->global_menu_add_item("_dock", TTR("New Window"), GLOBAL_NEW_WINDOW, Variant());
+ }
scene_tabs->set_current_tab(editor_data.get_edited_scene());
@@ -252,7 +258,7 @@ void EditorNode::_update_title() {
if (unsaved_cache)
title += " (*)";
- OS::get_singleton()->set_window_title(title);
+ DisplayServer::get_singleton()->window_set_title(title);
}
void EditorNode::_unhandled_input(const Ref<InputEvent> &p_event) {
@@ -2537,7 +2543,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
}
}
- OS::get_singleton()->request_attention();
+ DisplayServer::get_singleton()->window_request_attention();
break;
}
@@ -2585,13 +2591,13 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
} break;
case SETTINGS_TOGGLE_FULLSCREEN: {
- OS::get_singleton()->set_window_fullscreen(!OS::get_singleton()->is_window_fullscreen());
+ DisplayServer::get_singleton()->window_set_mode(DisplayServer::get_singleton()->window_get_mode() == DisplayServer::WINDOW_MODE_FULLSCREEN ? DisplayServer::WINDOW_MODE_WINDOWED : DisplayServer::WINDOW_MODE_FULLSCREEN);
} break;
case SETTINGS_TOGGLE_CONSOLE: {
- bool was_visible = OS::get_singleton()->is_console_visible();
- OS::get_singleton()->set_console_visible(!was_visible);
+ bool was_visible = DisplayServer::get_singleton()->is_console_visible();
+ DisplayServer::get_singleton()->console_set_visible(!was_visible);
EditorSettings::get_singleton()->set_setting("interface/editor/hide_console_window", was_visible);
} break;
case EDITOR_SCREENSHOT: {
@@ -3937,7 +3943,7 @@ void EditorNode::show_warning(const String &p_text, const String &p_title) {
void EditorNode::_copy_warning(const String &p_str) {
- OS::get_singleton()->set_clipboard(warning->get_text());
+ DisplayServer::get_singleton()->clipboard_set(warning->get_text());
}
void EditorNode::_dock_select_input(const Ref<InputEvent> &p_input) {
@@ -5286,7 +5292,7 @@ void EditorNode::_video_driver_selected(int p_which) {
String driver = video_driver->get_item_metadata(p_which);
- String current = OS::get_singleton()->get_video_driver_name(OS::get_singleton()->get_current_video_driver());
+ String current = ""; //OS::get_singleton()->get_video_driver_name(OS::get_singleton()->get_current_video_driver());
if (driver == current) {
return;
@@ -5485,11 +5491,18 @@ EditorNode::EditorNode() {
if (id) {
- if (!OS::get_singleton()->has_touchscreen_ui_hint() && Input::get_singleton()) {
+ bool found_touchscreen = false;
+ for (int i = 0; i < DisplayServer::get_singleton()->get_screen_count(); i++) {
+ if (DisplayServer::get_singleton()->screen_is_touchscreen(i)) {
+ found_touchscreen = true;
+ }
+ }
+
+ if (!found_touchscreen && Input::get_singleton()) {
//only if no touchscreen ui hint, set emulation
id->set_emulate_touch_from_mouse(false); //just disable just in case
}
- id->set_custom_mouse_cursor(RES());
+ DisplayServer::get_singleton()->cursor_set_custom_image(RES());
}
singleton = this;
@@ -5518,8 +5531,8 @@ EditorNode::EditorNode() {
switch (display_scale) {
case 0: {
// Try applying a suitable display scale automatically
- const int screen = OS::get_singleton()->get_current_screen();
- editor_set_scale(OS::get_singleton()->get_screen_dpi(screen) >= 192 && OS::get_singleton()->get_screen_size(screen).x > 2000 ? 2.0 : 1.0);
+ const int screen = DisplayServer::get_singleton()->window_get_current_screen();
+ editor_set_scale(DisplayServer::get_singleton()->screen_get_dpi(screen) >= 192 && DisplayServer::get_singleton()->screen_get_size(screen).x > 2000 ? 2.0 : 1.0);
} break;
case 1: {
@@ -5553,7 +5566,7 @@ EditorNode::EditorNode() {
}
// Define a minimum window size to prevent UI elements from overlapping or being cut off
- OS::get_singleton()->set_min_window_size(Size2(1024, 600) * EDSCALE);
+ DisplayServer::get_singleton()->window_set_min_size(Size2(1024, 600) * EDSCALE);
ResourceLoader::set_abort_on_missing_resources(false);
FileDialog::set_default_show_hidden_files(EditorSettings::get_singleton()->get("filesystem/file_dialog/show_hidden_files"));
@@ -6257,6 +6270,10 @@ EditorNode::EditorNode() {
video_driver->set_disabled(true);
right_menu_hb->add_child(video_driver);
+#ifndef _MSC_VER
+#warning neeeds to be reimplemented
+#endif
+#if 0
String video_drivers = ProjectSettings::get_singleton()->get_custom_property_info()["rendering/quality/driver/driver_name"].hint_string;
String current_video_driver = OS::get_singleton()->get_video_driver_name(OS::get_singleton()->get_current_video_driver());
video_driver_current = 0;
@@ -6272,7 +6289,7 @@ EditorNode::EditorNode() {
}
_update_video_driver_color();
-
+#endif
video_restart_dialog = memnew(ConfirmationDialog);
video_restart_dialog->set_text(TTR("Changing the video driver requires restarting the editor."));
video_restart_dialog->get_ok()->set_text(TTR("Save & Restart"));
@@ -6413,7 +6430,7 @@ EditorNode::EditorNode() {
confirmation->connect("confirmed", callable_mp(this, &EditorNode::_menu_confirm_current));
save_confirmation = memnew(ConfirmationDialog);
- save_confirmation->add_button(TTR("Don't Save"), OS::get_singleton()->get_swap_ok_cancel(), "discard");
+ save_confirmation->add_button(TTR("Don't Save"), DisplayServer::get_singleton()->get_swap_ok_cancel(), "discard");
gui_base->add_child(save_confirmation);
save_confirmation->connect("confirmed", callable_mp(this, &EditorNode::_menu_confirm_current));
save_confirmation->connect("custom_action", callable_mp(this, &EditorNode::_discard_changes));
@@ -6624,7 +6641,7 @@ EditorNode::EditorNode() {
open_imported = memnew(ConfirmationDialog);
open_imported->get_ok()->set_text(TTR("Open Anyway"));
- new_inherited_button = open_imported->add_button(TTR("New Inherited"), !OS::get_singleton()->get_swap_ok_cancel(), "inherit");
+ new_inherited_button = open_imported->add_button(TTR("New Inherited"), !DisplayServer::get_singleton()->get_swap_ok_cancel(), "inherit");
open_imported->connect("confirmed", callable_mp(this, &EditorNode::_open_imported));
open_imported->connect("custom_action", callable_mp(this, &EditorNode::_inherit_imported));
gui_base->add_child(open_imported);
diff --git a/editor/editor_run.cpp b/editor/editor_run.cpp
index 9f0e1f2349..28eff94f36 100644
--- a/editor/editor_run.cpp
+++ b/editor/editor_run.cpp
@@ -32,6 +32,7 @@
#include "core/project_settings.h"
#include "editor_settings.h"
+#include "servers/display_server.h"
EditorRun::Status EditorRun::get_status() const {
@@ -70,19 +71,19 @@ Error EditorRun::run(const String &p_scene, const String &p_custom_args, const L
int screen = EditorSettings::get_singleton()->get("run/window_placement/screen");
if (screen == 0) {
// Same as editor
- screen = OS::get_singleton()->get_current_screen();
+ screen = DisplayServer::get_singleton()->window_get_current_screen();
} else if (screen == 1) {
// Previous monitor (wrap to the other end if needed)
screen = Math::wrapi(
- OS::get_singleton()->get_current_screen() - 1,
+ DisplayServer::get_singleton()->window_get_current_screen() - 1,
0,
- OS::get_singleton()->get_screen_count());
+ DisplayServer::get_singleton()->get_screen_count());
} else if (screen == 2) {
// Next monitor (wrap to the other end if needed)
screen = Math::wrapi(
- OS::get_singleton()->get_current_screen() + 1,
+ DisplayServer::get_singleton()->window_get_current_screen() + 1,
0,
- OS::get_singleton()->get_screen_count());
+ DisplayServer::get_singleton()->get_screen_count());
} else {
// Fixed monitor ID
// There are 3 special options, so decrement the option ID by 3 to get the monitor ID
@@ -94,8 +95,8 @@ Error EditorRun::run(const String &p_scene, const String &p_custom_args, const L
}
Rect2 screen_rect;
- screen_rect.position = OS::get_singleton()->get_screen_position(screen);
- screen_rect.size = OS::get_singleton()->get_screen_size(screen);
+ screen_rect.position = DisplayServer::get_singleton()->screen_get_position(screen);
+ screen_rect.size = DisplayServer::get_singleton()->screen_get_size(screen);
Size2 desired_size;
desired_size.x = ProjectSettings::get_singleton()->get("display/window/size/width");
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index a32b736851..18f0aba030 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -599,7 +599,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
_initial_set("run/window_placement/rect", 1);
hints["run/window_placement/rect"] = PropertyInfo(Variant::INT, "run/window_placement/rect", PROPERTY_HINT_ENUM, "Top Left,Centered,Custom Position,Force Maximized,Force Fullscreen");
String screen_hints = "Same as Editor,Previous Monitor,Next Monitor";
- for (int i = 0; i < OS::get_singleton()->get_screen_count(); i++) {
+ for (int i = 0; i < DisplayServer::get_singleton()->get_screen_count(); i++) {
screen_hints += ",Monitor " + itos(i + 1);
}
_initial_set("run/window_placement/rect_custom_position", Vector2());
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index 962d95736f..171bb4105d 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -44,6 +44,7 @@
#include "import_dock.h"
#include "scene/main/viewport.h"
#include "scene/resources/packed_scene.h"
+#include "servers/display_server.h"
Ref<Texture2D> FileSystemDock::_get_tree_item_icon(EditorFileSystemDirectory *p_dir, int p_idx) {
Ref<Texture2D> file_icon;
@@ -1765,7 +1766,7 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected
case FILE_COPY_PATH: {
if (!p_selected.empty()) {
String fpath = p_selected[0];
- OS::get_singleton()->set_clipboard(fpath);
+ DisplayServer::get_singleton()->clipboard_set(fpath);
}
} break;
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index 2245781703..06d1c664b5 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -48,6 +48,7 @@
#include "scene/main/viewport.h"
#include "scene/scene_string_names.h"
#include "script_text_editor.h"
+#include "servers/display_server.h"
#include "text_editor.h"
/*** SCRIPT EDITOR ****/
@@ -651,7 +652,7 @@ void ScriptEditor::_close_docs_tab() {
void ScriptEditor::_copy_script_path() {
ScriptEditorBase *se = _get_current_editor();
RES script = se->get_edited_resource();
- OS::get_singleton()->set_clipboard(script->get_path());
+ DisplayServer::get_singleton()->clipboard_set(script->get_path());
}
void ScriptEditor::_close_other_tabs() {
@@ -3291,7 +3292,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
erase_tab_confirm = memnew(ConfirmationDialog);
erase_tab_confirm->get_ok()->set_text(TTR("Save"));
- erase_tab_confirm->add_button(TTR("Discard"), OS::get_singleton()->get_swap_ok_cancel(), "discard");
+ erase_tab_confirm->add_button(TTR("Discard"), DisplayServer::get_singleton()->get_swap_ok_cancel(), "discard");
erase_tab_confirm->connect("confirmed", callable_mp(this, &ScriptEditor::_close_current_tab));
erase_tab_confirm->connect("custom_action", callable_mp(this, &ScriptEditor::_close_discard_current_tab));
add_child(erase_tab_confirm);
@@ -3325,7 +3326,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
disk_changed->connect("confirmed", callable_mp(this, &ScriptEditor::_reload_scripts));
disk_changed->get_ok()->set_text(TTR("Reload"));
- disk_changed->add_button(TTR("Resave"), !OS::get_singleton()->get_swap_ok_cancel(), "resave");
+ disk_changed->add_button(TTR("Resave"), !DisplayServer::get_singleton()->get_swap_ok_cancel(), "resave");
disk_changed->connect("custom_action", callable_mp(this, &ScriptEditor::_resave_scripts));
}
diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp
index 01b1e21153..ce8e18b091 100644
--- a/editor/plugins/shader_editor_plugin.cpp
+++ b/editor/plugins/shader_editor_plugin.cpp
@@ -38,6 +38,7 @@
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
#include "editor/property_editor.h"
+#include "servers/display_server.h"
#include "servers/visual/shader_types.h"
/*** SHADER SCRIPT EDITOR ****/
@@ -699,7 +700,7 @@ ShaderEditor::ShaderEditor(EditorNode *p_node) {
disk_changed->connect("confirmed", callable_mp(this, &ShaderEditor::_reload_shader_from_disk));
disk_changed->get_ok()->set_text(TTR("Reload"));
- disk_changed->add_button(TTR("Resave"), !OS::get_singleton()->get_swap_ok_cancel(), "resave");
+ disk_changed->add_button(TTR("Resave"), !DisplayServer::get_singleton()->get_swap_ok_cancel(), "resave");
disk_changed->connect("custom_action", callable_mp(this, &ShaderEditor::save_external_data));
add_child(disk_changed);
diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp
index 0a8c18a7bc..d514b50460 100644
--- a/editor/plugins/spatial_editor_plugin.cpp
+++ b/editor/plugins/spatial_editor_plugin.cpp
@@ -51,6 +51,7 @@
#include "scene/gui/viewport_container.h"
#include "scene/resources/packed_scene.h"
#include "scene/resources/surface_tool.h"
+#include "servers/display_server.h"
#define DISTANCE_DEFAULT 4
@@ -2213,14 +2214,14 @@ void SpatialEditorViewport::set_freelook_active(bool active_now) {
}
// Hide mouse like in an FPS (warping doesn't work)
- OS::get_singleton()->set_mouse_mode(OS::MOUSE_MODE_CAPTURED);
+ DisplayServer::get_singleton()->mouse_set_mode(DisplayServer::MOUSE_MODE_CAPTURED);
} else if (freelook_active && !active_now) {
// Sync camera cursor to cursor to "cut" interpolation jumps due to changing referential
cursor = camera_cursor;
// Restore mouse
- OS::get_singleton()->set_mouse_mode(OS::MOUSE_MODE_VISIBLE);
+ DisplayServer::get_singleton()->mouse_set_mode(DisplayServer::MOUSE_MODE_VISIBLE);
}
freelook_active = active_now;
@@ -3926,8 +3927,11 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed
view_menu->get_popup()->connect("id_pressed", callable_mp(this, &SpatialEditorViewport::_menu_option));
display_submenu->connect("id_pressed", callable_mp(this, &SpatialEditorViewport::_menu_option));
view_menu->set_disable_shortcuts(true);
-
- if (OS::get_singleton()->get_current_video_driver() == OS::VIDEO_DRIVER_GLES2) {
+#ifndef _MSC_VER
+#warning this needs to be fixed
+#endif
+ //if (OS::get_singleton()->get_current_video_driver() == OS::VIDEO_DRIVER_GLES2) {
+ if (false) {
// Alternate display modes only work when using the Vulkan renderer; make this explicit.
const int normal_idx = view_menu->get_popup()->get_item_index(VIEW_DISPLAY_NORMAL);
const int wireframe_idx = view_menu->get_popup()->get_item_index(VIEW_DISPLAY_WIREFRAME);
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index c7c3ba8198..8070e2b4d5 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -44,6 +44,7 @@
#include "scene/gui/panel.h"
#include "scene/main/viewport.h"
#include "scene/resources/visual_shader_nodes.h"
+#include "servers/display_server.h"
#include "servers/visual/shader_types.h"
Control *VisualShaderNodePlugin::create_editor(const Ref<Resource> &p_parent_resource, const Ref<VisualShaderNode> &p_node) {
@@ -1646,7 +1647,7 @@ void VisualShaderEditor::_show_members_dialog(bool at_mouse_pos) {
}
// keep dialog within window bounds
- Size2 window_size = OS::get_singleton()->get_window_size();
+ Size2 window_size = DisplayServer::get_singleton()->window_get_size();
Rect2 dialog_rect = members_dialog->get_global_rect();
if (dialog_rect.position.y + dialog_rect.size.y > window_size.y) {
int difference = dialog_rect.position.y + dialog_rect.size.y - window_size.y;
diff --git a/editor/progress_dialog.cpp b/editor/progress_dialog.cpp
index cdc5255edd..d12fd720a7 100644
--- a/editor/progress_dialog.cpp
+++ b/editor/progress_dialog.cpp
@@ -34,6 +34,7 @@
#include "core/os/os.h"
#include "editor_scale.h"
#include "main/main.h"
+#include "servers/display_server.h"
void BackgroundProgress::_add_task(const String &p_task, const String &p_label, int p_steps) {
@@ -219,7 +220,7 @@ bool ProgressDialog::task_step(const String &p_task, const String &p_state, int
t.state->set_text(p_state);
last_progress_tick = OS::get_singleton()->get_ticks_usec();
if (cancel_hb->is_visible()) {
- OS::get_singleton()->force_process_input();
+ DisplayServer::get_singleton()->process_events();
}
Main::iteration(); // this will not work on a lot of platforms, so it's only meant for the editor
diff --git a/editor/project_export.cpp b/editor/project_export.cpp
index 37b959c78a..95e0bba579 100644
--- a/editor/project_export.cpp
+++ b/editor/project_export.cpp
@@ -46,6 +46,7 @@
#include "scene/gui/margin_container.h"
#include "scene/gui/scroll_container.h"
#include "scene/gui/tab_container.h"
+#include "servers/display_server.h"
void ProjectExportDialog::_notification(int p_what) {
@@ -1250,7 +1251,7 @@ ProjectExportDialog::ProjectExportDialog() {
get_cancel()->set_text(TTR("Close"));
get_ok()->set_text(TTR("Export PCK/Zip"));
- export_button = add_button(TTR("Export Project"), !OS::get_singleton()->get_swap_ok_cancel(), "export");
+ export_button = add_button(TTR("Export Project"), !DisplayServer::get_singleton()->get_swap_ok_cancel(), "export");
export_button->connect("pressed", callable_mp(this, &ProjectExportDialog::_export_project));
// Disable initially before we select a valid preset
export_button->set_disabled(true);
@@ -1265,7 +1266,7 @@ ProjectExportDialog::ProjectExportDialog() {
export_all_dialog->add_button(TTR("Release"), true, "release");
export_all_dialog->connect("custom_action", callable_mp(this, &ProjectExportDialog::_export_all_dialog_action));
- export_all_button = add_button(TTR("Export All"), !OS::get_singleton()->get_swap_ok_cancel(), "export");
+ export_all_button = add_button(TTR("Export All"), !DisplayServer::get_singleton()->get_swap_ok_cancel(), "export");
export_all_button->connect("pressed", callable_mp(this, &ProjectExportDialog::_export_all_dialog));
export_all_button->set_disabled(true);
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index 4e157e927e..0ebfab7ab6 100644
--- a/editor/project_manager.cpp
+++ b/editor/project_manager.cpp
@@ -51,6 +51,7 @@
#include "scene/gui/separator.h"
#include "scene/gui/texture_rect.h"
#include "scene/gui/tool_button.h"
+#include "servers/display_server.h"
static inline String get_project_key_from_path(const String &dir) {
return dir.replace("/", "::");
@@ -1284,7 +1285,11 @@ void ProjectList::load_projects() {
}
void ProjectList::update_dock_menu() {
- OS::get_singleton()->global_menu_clear("_dock");
+
+ if (!DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_GLOBAL_MENU)) {
+ return;
+ }
+ DisplayServer::get_singleton()->global_menu_clear("_dock");
int favs_added = 0;
int total_added = 0;
@@ -1294,18 +1299,18 @@ void ProjectList::update_dock_menu() {
favs_added++;
} else {
if (favs_added != 0) {
- OS::get_singleton()->global_menu_add_separator("_dock");
+ DisplayServer::get_singleton()->global_menu_add_separator("_dock");
}
favs_added = 0;
}
- OS::get_singleton()->global_menu_add_item("_dock", _projects[i].project_name + " ( " + _projects[i].path + " )", GLOBAL_OPEN_PROJECT, Variant(_projects[i].path.plus_file("project.godot")));
+ DisplayServer::get_singleton()->global_menu_add_item("_dock", _projects[i].project_name + " ( " + _projects[i].path + " )", GLOBAL_OPEN_PROJECT, Variant(_projects[i].path.plus_file("project.godot")));
total_added++;
}
}
if (total_added != 0) {
- OS::get_singleton()->global_menu_add_separator("_dock");
+ DisplayServer::get_singleton()->global_menu_add_separator("_dock");
}
- OS::get_singleton()->global_menu_add_item("_dock", TTR("New Window"), GLOBAL_NEW_WINDOW, Variant());
+ DisplayServer::get_singleton()->global_menu_add_item("_dock", TTR("New Window"), GLOBAL_NEW_WINDOW, Variant());
}
void ProjectList::create_project_item_control(int p_index) {
@@ -2413,8 +2418,8 @@ ProjectManager::ProjectManager() {
switch (display_scale) {
case 0: {
// Try applying a suitable display scale automatically
- const int screen = OS::get_singleton()->get_current_screen();
- editor_set_scale(OS::get_singleton()->get_screen_dpi(screen) >= 192 && OS::get_singleton()->get_screen_size(screen).x > 2000 ? 2.0 : 1.0);
+ const int screen = DisplayServer::get_singleton()->window_get_current_screen();
+ editor_set_scale(DisplayServer::get_singleton()->screen_get_dpi(screen) >= 192 && DisplayServer::get_singleton()->screen_get_size(screen).x > 2000 ? 2.0 : 1.0);
} break;
case 1: editor_set_scale(0.75); break;
@@ -2430,12 +2435,12 @@ ProjectManager::ProjectManager() {
}
// Define a minimum window size to prevent UI elements from overlapping or being cut off
- OS::get_singleton()->set_min_window_size(Size2(750, 420) * EDSCALE);
+ DisplayServer::get_singleton()->window_set_min_size(Size2(750, 420) * EDSCALE);
#ifndef OSX_ENABLED
// The macOS platform implementation uses its own hiDPI window resizing code
// TODO: Resize windows on hiDPI displays on Windows and Linux and remove the line below
- OS::get_singleton()->set_window_size(OS::get_singleton()->get_window_size() * MAX(1, EDSCALE));
+ DisplayServer::get_singleton()->window_set_size(DisplayServer::get_singleton()->window_get_size() * MAX(1, EDSCALE));
#endif
}
@@ -2459,7 +2464,7 @@ ProjectManager::ProjectManager() {
String cp;
cp += 0xA9;
- OS::get_singleton()->set_window_title(VERSION_NAME + String(" - ") + TTR("Project Manager") + " - " + cp + " 2007-2020 Juan Linietsky, Ariel Manzur & Godot Contributors");
+ DisplayServer::get_singleton()->window_set_title(VERSION_NAME + String(" - ") + TTR("Project Manager") + " - " + cp + " 2007-2020 Juan Linietsky, Ariel Manzur & Godot Contributors");
Control *center_box = memnew(Control);
center_box->set_v_size_flags(SIZE_EXPAND_FILL);
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index bdc5f0a3e8..4382b63747 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -46,6 +46,8 @@
#include "editor/plugins/spatial_editor_plugin.h"
#include "scene/main/viewport.h"
#include "scene/resources/packed_scene.h"
+#include "servers/display_server.h"
+#include "servers/visual_server.h"
void SceneTreeDock::_nodes_drag_begin() {
@@ -822,7 +824,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
if (node) {
Node *root = EditorNode::get_singleton()->get_edited_scene();
NodePath path = root->get_path().rel_path_to(node->get_path());
- OS::get_singleton()->set_clipboard(path);
+ DisplayServer::get_singleton()->clipboard_set(path);
}
}
} break;
diff --git a/main/main.cpp b/main/main.cpp
index b95ba54576..53bb336b1f 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -64,11 +64,14 @@
#include "servers/arvr_server.h"
#include "servers/audio_server.h"
#include "servers/camera_server.h"
+#include "servers/display_server.h"
#include "servers/navigation_2d_server.h"
#include "servers/navigation_server.h"
#include "servers/physics_2d_server.h"
#include "servers/physics_server.h"
#include "servers/register_server_types.h"
+#include "servers/visual/visual_server_raster.h"
+#include "servers/visual/visual_server_wrap_mt.h"
#ifdef TOOLS_ENABLED
#include "editor/doc_data.h"
@@ -86,6 +89,7 @@
// Initialized in setup()
static Engine *engine = NULL;
static ProjectSettings *globals = NULL;
+static Input *input = NULL;
static InputMap *input_map = NULL;
static TranslationServer *translation_server = NULL;
static Performance *performance = NULL;
@@ -98,6 +102,8 @@ static MessageQueue *message_queue = NULL;
// Initialized in setup2()
static AudioServer *audio_server = NULL;
+static DisplayServer *display_server = NULL;
+static VisualServer *visual_server = NULL;
static CameraServer *camera_server = NULL;
static ARVRServer *arvr_server = NULL;
static PhysicsServer *physics_server = NULL;
@@ -109,7 +115,7 @@ static bool _start_success = false;
// Drivers
-static int video_driver_idx = -1;
+static int display_driver_idx = -1;
static int audio_driver_idx = -1;
// Engine config/tools
@@ -126,7 +132,12 @@ static bool auto_build_solutions = false;
// Display
-static OS::VideoMode video_mode;
+static DisplayServer::WindowMode window_mode = DisplayServer::WINDOW_MODE_WINDOWED;
+static DisplayServer::ScreenOrientation window_orientation = DisplayServer::SCREEN_LANDSCAPE;
+static uint32_t window_flags = 0;
+static Size2i window_size = Size2i(1024, 600);
+static bool window_vsync_via_compositor = false;
+
static int init_screen = -1;
static bool init_fullscreen = false;
static bool init_maximized = false;
@@ -191,6 +202,7 @@ void initialize_physics() {
}
void finalize_physics() {
+
physics_server->finish();
memdelete(physics_server);
@@ -198,6 +210,14 @@ void finalize_physics() {
memdelete(physics_2d_server);
}
+void finalize_display() {
+
+ visual_server->finish();
+ memdelete(visual_server);
+
+ memdelete(display_server);
+}
+
void initialize_navigation_server() {
ERR_FAIL_COND(navigation_server != NULL);
@@ -251,20 +271,25 @@ void Main::print_help(const char *p_binary) {
OS::get_singleton()->print(" --remote-fs <address> Remote filesystem (<host/IP>[:<port>] address).\n");
OS::get_singleton()->print(" --remote-fs-password <password> Password for remote filesystem.\n");
OS::get_singleton()->print(" --audio-driver <driver> Audio driver (");
- for (int i = 0; i < OS::get_singleton()->get_audio_driver_count(); i++) {
+ for (int i = 0; i < AudioDriverManager::get_driver_count(); i++) {
if (i != 0)
OS::get_singleton()->print(", ");
- OS::get_singleton()->print("'%s'", OS::get_singleton()->get_audio_driver_name(i));
+ OS::get_singleton()->print("'%s'", AudioDriverManager::get_driver(i)->get_name());
}
OS::get_singleton()->print(").\n");
- OS::get_singleton()->print(" --video-driver <driver> Video driver (");
- for (int i = 0; i < OS::get_singleton()->get_video_driver_count(); i++) {
- if (i != 0)
- OS::get_singleton()->print(", ");
- OS::get_singleton()->print("'%s'", OS::get_singleton()->get_video_driver_name(i));
+ OS::get_singleton()->print(" --display-driver <driver> Display driver (and rendering driver):\n");
+ for (int i = 0; i < DisplayServer::get_create_function_count(); i++) {
+ OS::get_singleton()->print("\t\t'%s' (", DisplayServer::get_create_function_name(i));
+ Vector<String> rd = DisplayServer::get_create_function_rendering_drivers(i);
+ for (int j = 0; j < rd.size(); j++) {
+ if (j > 0) {
+ OS::get_singleton()->print(", ");
+ }
+ OS::get_singleton()->print("'%s'", rd[j].utf8().get_data());
+ }
+ OS::get_singleton()->print(")\n");
}
- OS::get_singleton()->print(").\n");
- OS::get_singleton()->print("\n");
+ OS::get_singleton()->print(" --rendering-driver <driver> Rendering driver (depends on display driver).\n");
#ifndef SERVER_ENABLED
OS::get_singleton()->print("Display options:\n");
@@ -353,7 +378,7 @@ void Main::print_help(const char *p_binary) {
Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_phase) {
- OS::get_singleton()->initialize_core();
+ OS::get_singleton()->initialize();
engine = memnew(Engine);
@@ -403,7 +428,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
I = args.front();
- String video_driver = "";
+ String display_driver = "";
String audio_driver = "";
String project_path = ".";
bool upwards = false;
@@ -423,6 +448,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
#ifdef TOOLS_ENABLED
bool found_project = false;
#endif
+ bool use_vsync = false;
packed_data = PackedData::get_singleton();
if (!packed_data)
@@ -469,8 +495,8 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
audio_driver = I->next()->get();
bool found = false;
- for (int i = 0; i < OS::get_singleton()->get_audio_driver_count(); i++) {
- if (audio_driver == OS::get_singleton()->get_audio_driver_name(i)) {
+ for (int i = 0; i < AudioDriverManager::get_driver_count(); i++) {
+ if (audio_driver == AudioDriverManager::get_driver(i)->get_name()) {
found = true;
}
}
@@ -478,14 +504,14 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
if (!found) {
OS::get_singleton()->print("Unknown audio driver '%s', aborting.\nValid options are ", audio_driver.utf8().get_data());
- for (int i = 0; i < OS::get_singleton()->get_audio_driver_count(); i++) {
- if (i == OS::get_singleton()->get_audio_driver_count() - 1) {
+ for (int i = 0; i < AudioDriverManager::get_driver_count(); i++) {
+ if (i == AudioDriverManager::get_driver_count() - 1) {
OS::get_singleton()->print(" and ");
} else if (i != 0) {
OS::get_singleton()->print(", ");
}
- OS::get_singleton()->print("'%s'", OS::get_singleton()->get_audio_driver_name(i));
+ OS::get_singleton()->print("'%s'", AudioDriverManager::get_driver(i)->get_name());
}
OS::get_singleton()->print(".\n");
@@ -499,30 +525,30 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
goto error;
}
- } else if (I->get() == "--video-driver") { // force video driver
+ } else if (I->get() == "--display-driver") { // force video driver
if (I->next()) {
- video_driver = I->next()->get();
+ display_driver = I->next()->get();
bool found = false;
- for (int i = 0; i < OS::get_singleton()->get_video_driver_count(); i++) {
- if (video_driver == OS::get_singleton()->get_video_driver_name(i)) {
+ for (int i = 0; i < DisplayServer::get_create_function_count(); i++) {
+ if (display_driver == DisplayServer::get_create_function_name(i)) {
found = true;
}
}
if (!found) {
- OS::get_singleton()->print("Unknown video driver '%s', aborting.\nValid options are ", video_driver.utf8().get_data());
+ OS::get_singleton()->print("Unknown display driver '%s', aborting.\nValid options are ", display_driver.utf8().get_data());
- for (int i = 0; i < OS::get_singleton()->get_video_driver_count(); i++) {
- if (i == OS::get_singleton()->get_video_driver_count() - 1) {
+ for (int i = 0; i < DisplayServer::get_create_function_count(); i++) {
+ if (i == DisplayServer::get_create_function_count() - 1) {
OS::get_singleton()->print(" and ");
} else if (i != 0) {
OS::get_singleton()->print(", ");
}
- OS::get_singleton()->print("'%s'", OS::get_singleton()->get_video_driver_name(i));
+ OS::get_singleton()->print("'%s'", DisplayServer::get_create_function_name(i));
}
OS::get_singleton()->print(".\n");
@@ -542,7 +568,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
} else if (I->get() == "-m" || I->get() == "--maximized") { // force maximized window
init_maximized = true;
- video_mode.maximized = true;
+ window_mode = DisplayServer::WINDOW_MODE_MAXIMIZED;
} else if (I->get() == "-w" || I->get() == "--windowed") { // force windowed window
@@ -574,8 +600,8 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
goto error;
}
- video_mode.width = w;
- video_mode.height = h;
+ window_size.width = w;
+ window_size.height = h;
force_res = true;
N = I->next()->next();
@@ -616,11 +642,11 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
OS::get_singleton()->set_no_window_mode(true);
} else if (I->get() == "--enable-vsync-via-compositor") {
- video_mode.vsync_via_compositor = true;
+ window_vsync_via_compositor = true;
saw_vsync_via_compositor_override = true;
} else if (I->get() == "--disable-vsync-via-compositor") {
- video_mode.vsync_via_compositor = false;
+ window_vsync_via_compositor = false;
saw_vsync_via_compositor_override = true;
#endif
} else if (I->get() == "--profiling") { // enable profiling
@@ -917,7 +943,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
main_args.push_back("--editor");
if (!init_windowed) {
init_maximized = true;
- video_mode.maximized = true;
+ window_mode = DisplayServer::WINDOW_MODE_MAXIMIZED;
}
}
@@ -960,8 +986,8 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
GLOBAL_DEF("rendering/quality/driver/driver_name", "Vulkan");
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/driver/driver_name", PropertyInfo(Variant::STRING, "rendering/quality/driver/driver_name", PROPERTY_HINT_ENUM, "Vulkan,GLES2"));
- if (video_driver == "") {
- video_driver = GLOBAL_GET("rendering/quality/driver/driver_name");
+ if (display_driver == "") {
+ display_driver = GLOBAL_GET("rendering/quality/driver/driver_name");
}
// Assigning here even though it's GLES2-specific, to be sure that it appears in docs
@@ -983,48 +1009,58 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
if (use_custom_res) {
if (!force_res) {
- video_mode.width = GLOBAL_GET("display/window/size/width");
- video_mode.height = GLOBAL_GET("display/window/size/height");
+ window_size.width = GLOBAL_GET("display/window/size/width");
+ window_size.height = GLOBAL_GET("display/window/size/height");
if (globals->has_setting("display/window/size/test_width") && globals->has_setting("display/window/size/test_height")) {
int tw = globals->get("display/window/size/test_width");
if (tw > 0) {
- video_mode.width = tw;
+ window_size.width = tw;
}
int th = globals->get("display/window/size/test_height");
if (th > 0) {
- video_mode.height = th;
+ window_size.height = th;
}
}
}
- video_mode.resizable = GLOBAL_GET("display/window/size/resizable");
- video_mode.borderless_window = GLOBAL_GET("display/window/size/borderless");
- video_mode.fullscreen = GLOBAL_GET("display/window/size/fullscreen");
- video_mode.always_on_top = GLOBAL_GET("display/window/size/always_on_top");
+ if (!bool(GLOBAL_GET("display/window/size/resizable"))) {
+ window_flags |= DisplayServer::WINDOW_FLAG_RESIZE_DISABLED_BIT;
+ }
+ if (bool(GLOBAL_GET("display/window/size/borderless"))) {
+ window_flags |= DisplayServer::WINDOW_FLAG_BORDERLESS_BIT;
+ }
+ if (bool(GLOBAL_GET("display/window/size/fullscreen"))) {
+ window_mode = DisplayServer::WINDOW_MODE_FULLSCREEN;
+ }
+
+ if (bool(GLOBAL_GET("display/window/size/always_on_top"))) {
+ window_flags |= DisplayServer::WINDOW_FLAG_ALWAYS_ON_TOP;
+ }
}
if (!force_lowdpi) {
OS::get_singleton()->_allow_hidpi = GLOBAL_DEF("display/window/dpi/allow_hidpi", false);
}
- video_mode.use_vsync = GLOBAL_DEF_RST("display/window/vsync/use_vsync", true);
- OS::get_singleton()->_use_vsync = video_mode.use_vsync;
+ use_vsync = GLOBAL_DEF_RST("display/window/vsync/use_vsync", true);
+ OS::get_singleton()->_use_vsync = use_vsync;
if (!saw_vsync_via_compositor_override) {
// If one of the command line options to enable/disable vsync via the
// window compositor ("--enable-vsync-via-compositor" or
// "--disable-vsync-via-compositor") was present then it overrides the
// project setting.
- video_mode.vsync_via_compositor = GLOBAL_DEF("display/window/vsync/vsync_via_compositor", false);
+ window_vsync_via_compositor = GLOBAL_DEF("display/window/vsync/vsync_via_compositor", false);
}
- OS::get_singleton()->_vsync_via_compositor = video_mode.vsync_via_compositor;
+ OS::get_singleton()->_vsync_via_compositor = window_vsync_via_compositor;
+ /* todo restore
OS::get_singleton()->_allow_layered = GLOBAL_DEF("display/window/per_pixel_transparency/allowed", false);
video_mode.layered = GLOBAL_DEF("display/window/per_pixel_transparency/enabled", false);
-
+*/
GLOBAL_DEF("rendering/quality/intended_usage/framebuffer_allocation", 2);
GLOBAL_DEF("rendering/quality/intended_usage/framebuffer_allocation.mobile", 3);
@@ -1049,26 +1085,26 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
/* Determine audio and video drivers */
- for (int i = 0; i < OS::get_singleton()->get_video_driver_count(); i++) {
+ for (int i = 0; i < DisplayServer::get_create_function_count(); i++) {
- if (video_driver == OS::get_singleton()->get_video_driver_name(i)) {
+ if (display_driver == DisplayServer::get_create_function_name(i)) {
- video_driver_idx = i;
+ display_driver_idx = i;
break;
}
}
- if (video_driver_idx < 0) {
- video_driver_idx = 0;
+ if (display_driver_idx < 0) {
+ display_driver_idx = 0;
}
if (audio_driver == "") { // specified in project.godot
- audio_driver = GLOBAL_DEF_RST("audio/driver", OS::get_singleton()->get_audio_driver_name(0));
+ audio_driver = GLOBAL_DEF_RST("audio/driver", AudioDriverManager::get_driver(0)->get_name());
}
- for (int i = 0; i < OS::get_singleton()->get_audio_driver_count(); i++) {
+ for (int i = 0; i < AudioDriverManager::get_driver_count(); i++) {
- if (audio_driver == OS::get_singleton()->get_audio_driver_name(i)) {
+ if (audio_driver == AudioDriverManager::get_driver(i)->get_name()) {
audio_driver_idx = i;
break;
@@ -1083,19 +1119,19 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
String orientation = GLOBAL_DEF("display/window/handheld/orientation", "landscape");
if (orientation == "portrait")
- OS::get_singleton()->set_screen_orientation(OS::SCREEN_PORTRAIT);
+ window_orientation = DisplayServer::SCREEN_PORTRAIT;
else if (orientation == "reverse_landscape")
- OS::get_singleton()->set_screen_orientation(OS::SCREEN_REVERSE_LANDSCAPE);
+ window_orientation = DisplayServer::SCREEN_REVERSE_LANDSCAPE;
else if (orientation == "reverse_portrait")
- OS::get_singleton()->set_screen_orientation(OS::SCREEN_REVERSE_PORTRAIT);
+ window_orientation = DisplayServer::SCREEN_REVERSE_PORTRAIT;
else if (orientation == "sensor_landscape")
- OS::get_singleton()->set_screen_orientation(OS::SCREEN_SENSOR_LANDSCAPE);
+ window_orientation = DisplayServer::SCREEN_SENSOR_LANDSCAPE;
else if (orientation == "sensor_portrait")
- OS::get_singleton()->set_screen_orientation(OS::SCREEN_SENSOR_PORTRAIT);
+ window_orientation = DisplayServer::SCREEN_SENSOR_PORTRAIT;
else if (orientation == "sensor")
- OS::get_singleton()->set_screen_orientation(OS::SCREEN_SENSOR);
+ window_orientation = DisplayServer::SCREEN_SENSOR;
else
- OS::get_singleton()->set_screen_orientation(OS::SCREEN_LANDSCAPE);
+ window_orientation = DisplayServer::SCREEN_LANDSCAPE;
}
Engine::get_singleton()->set_iterations_per_second(GLOBAL_DEF("physics/common/physics_fps", 60));
@@ -1131,7 +1167,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
error:
- video_driver = "";
+ display_driver = "";
audio_driver = "";
project_path = "";
@@ -1183,15 +1219,64 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
Thread::_main_thread_id = p_main_tid_override;
}
- Error err = OS::get_singleton()->initialize(video_mode, video_driver_idx, audio_driver_idx);
- if (err != OK) {
- return err;
+ /* Initialize user data dir */
+
+ OS::get_singleton()->ensure_user_data_dir();
+
+ /* Initialize Input */
+
+ input = memnew(Input);
+
+ /* Iniitalize Display Server */
+
+ {
+
+ String rendering_driver; // temp broken
+
+ Error err;
+ display_server = DisplayServer::create(display_driver_idx, rendering_driver, window_mode, window_flags, window_size, err);
+ if (err != OK) {
+ //ok i guess we can't use this display server, try other ones
+ for (int i = 0; i < DisplayServer::get_create_function_count(); i++) {
+ if (i == display_driver_idx) {
+ continue; //don't try the same twice
+ }
+ display_server = DisplayServer::create(display_driver_idx, rendering_driver, window_mode, window_flags, window_size, err);
+ if (err == OK) {
+ break;
+ }
+ }
+ }
+
+ if (!display_server) {
+ ERR_PRINT("Unable to create DisplayServer, all display drivers failed.");
+ return err;
+ }
+ }
+
+ if (display_server->has_feature(DisplayServer::FEATURE_ORIENTATION)) {
+ display_server->screen_set_orientation(window_orientation);
}
+ /* Initialize Visual Server */
+
+ visual_server = memnew(VisualServerRaster);
+ if (OS::get_singleton()->get_render_thread_mode() != OS::RENDER_THREAD_UNSAFE) {
+ visual_server = memnew(VisualServerWrapMT(visual_server, OS::get_singleton()->get_render_thread_mode() == OS::RENDER_SEPARATE_THREAD));
+ }
+
+ visual_server->init();
+
+ OS::get_singleton()->initialize_joypads();
+
+ /* Initialize Audio Driver */
+
+ AudioDriverManager::initialize(audio_driver_idx);
+
print_line(" "); //add a blank line for readability
if (init_use_custom_pos) {
- OS::get_singleton()->set_window_position(init_custom_pos);
+ display_server->window_set_position(init_custom_pos);
}
// right moment to create and initialize the audio server
@@ -1213,21 +1298,21 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
#endif
if (init_screen != -1) {
- OS::get_singleton()->set_current_screen(init_screen);
+ DisplayServer::get_singleton()->window_set_current_screen(init_screen);
}
if (init_windowed) {
//do none..
} else if (init_maximized) {
- OS::get_singleton()->set_window_maximized(true);
+ DisplayServer::get_singleton()->window_set_mode(DisplayServer::WINDOW_MODE_MAXIMIZED);
} else if (init_fullscreen) {
- OS::get_singleton()->set_window_fullscreen(true);
+ DisplayServer::get_singleton()->window_set_mode(DisplayServer::WINDOW_MODE_FULLSCREEN);
}
if (init_always_on_top) {
- OS::get_singleton()->set_window_always_on_top(true);
+ DisplayServer::get_singleton()->window_set_flag(DisplayServer::WINDOW_FLAG_ALWAYS_ON_TOP, true);
}
if (allow_focus_steal_pid) {
- OS::get_singleton()->enable_for_stealing_focus(allow_focus_steal_pid);
+ DisplayServer::get_singleton()->enable_for_stealing_focus(allow_focus_steal_pid);
}
register_server_types();
@@ -1277,7 +1362,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
#ifdef TOOLS_ENABLED
Ref<Image> icon = memnew(Image(app_icon_png));
- OS::get_singleton()->set_icon(icon);
+ DisplayServer::get_singleton()->set_icon(icon);
#endif
}
@@ -1297,7 +1382,14 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
Input *id = Input::get_singleton();
if (id) {
if (bool(GLOBAL_DEF("input_devices/pointing/emulate_touch_from_mouse", false)) && !(editor || project_manager)) {
- if (!OS::get_singleton()->has_touchscreen_ui_hint()) {
+
+ bool found_touchscreen = false;
+ for (int i = 0; i < DisplayServer::get_singleton()->get_screen_count(); i++) {
+ if (DisplayServer::get_singleton()->screen_is_touchscreen(i)) {
+ found_touchscreen = true;
+ }
+ }
+ if (!found_touchscreen) {
//only if no touchscreen ui hint, set emulation
id->set_emulate_touch_from_mouse(true);
}
@@ -1589,7 +1681,7 @@ bool Main::start() {
if (!main_loop) {
if (!ClassDB::class_exists(main_loop_type)) {
- OS::get_singleton()->alert("Error: MainLoop type doesn't exist: " + main_loop_type);
+ DisplayServer::get_singleton()->alert("Error: MainLoop type doesn't exist: " + main_loop_type);
return false;
} else {
@@ -1751,7 +1843,7 @@ bool Main::start() {
sml->set_quit_on_go_back(GLOBAL_DEF("application/config/quit_on_go_back", true));
String appname = ProjectSettings::get_singleton()->get("application/config/name");
appname = TranslationServer::get_singleton()->translate(appname);
- OS::get_singleton()->set_window_title(appname);
+ DisplayServer::get_singleton()->window_set_title(appname);
int shadow_atlas_size = GLOBAL_GET("rendering/quality/shadow_atlas/size");
int shadow_atlas_q0_subdiv = GLOBAL_GET("rendering/quality/shadow_atlas/quadrant_0_subdiv");
@@ -1838,11 +1930,11 @@ bool Main::start() {
if (serr != OK)
ERR_PRINT("Failed to load scene");
}
- OS::get_singleton()->set_context(OS::CONTEXT_EDITOR);
+ DisplayServer::get_singleton()->set_context(DisplayServer::CONTEXT_EDITOR);
}
#endif
if (!editor) {
- OS::get_singleton()->set_context(OS::CONTEXT_ENGINE);
+ DisplayServer::get_singleton()->set_context(DisplayServer::CONTEXT_ENGINE);
}
}
@@ -1881,7 +1973,7 @@ bool Main::start() {
Ref<Image> icon;
icon.instance();
if (ImageLoader::load_image(iconpath, icon) == OK) {
- OS::get_singleton()->set_icon(icon);
+ DisplayServer::get_singleton()->set_icon(icon);
hasicon = true;
}
}
@@ -1896,14 +1988,14 @@ bool Main::start() {
ProgressDialog *progress_dialog = memnew(ProgressDialog);
pmanager->add_child(progress_dialog);
sml->get_root()->add_child(pmanager);
- OS::get_singleton()->set_context(OS::CONTEXT_PROJECTMAN);
+ DisplayServer::get_singleton()->set_context(DisplayServer::CONTEXT_PROJECTMAN);
project_manager = true;
}
if (project_manager || editor) {
// Hide console window if requested (Windows-only).
bool hide_console = EditorSettings::get_singleton()->get_setting("interface/editor/hide_console_window");
- OS::get_singleton()->set_console_visible(!hide_console);
+ DisplayServer::get_singleton()->console_set_visible(!hide_console);
// Load SSL Certificates from Editor Settings (or builtin)
Crypto::load_default_certificates(EditorSettings::get_singleton()->get_setting("network/ssl/editor_ssl_certificates").operator String());
@@ -1913,9 +2005,10 @@ bool Main::start() {
if (!hasicon) {
Ref<Image> icon = memnew(Image(app_icon_png));
- OS::get_singleton()->set_icon(icon);
+ DisplayServer::get_singleton()->set_icon(icon);
}
+ Input::get_singleton()->set_main_loop(main_loop);
OS::get_singleton()->set_main_loop(main_loop);
return true;
@@ -2030,7 +2123,7 @@ bool Main::iteration() {
VisualServer::get_singleton()->sync(); //sync if still drawing from previous frames.
- if (OS::get_singleton()->can_draw() && !disable_render_loop) {
+ if (DisplayServer::get_singleton()->can_any_window_draw() && !disable_render_loop) {
if ((!force_redraw_requested) && OS::get_singleton()->is_in_low_processor_usage_mode()) {
if (VisualServer::get_singleton()->has_changed()) {
@@ -2085,7 +2178,7 @@ bool Main::iteration() {
if (fixed_fps != -1)
return exit;
- if (OS::get_singleton()->is_in_low_processor_usage_mode() || !OS::get_singleton()->can_draw())
+ if (OS::get_singleton()->is_in_low_processor_usage_mode() || !DisplayServer::get_singleton()->can_any_window_draw())
OS::get_singleton()->delay_usec(OS::get_singleton()->get_low_processor_usage_mode_sleep_usec()); //apply some delay to force idle time
else {
uint32_t frame_delay = Engine::get_singleton()->get_frame_delay();
@@ -2182,8 +2275,14 @@ void Main::cleanup() {
}
OS::get_singleton()->finalize();
+
finalize_physics();
finalize_navigation_server();
+ finalize_display();
+
+ if (input) {
+ memdelete(input);
+ }
if (packed_data)
memdelete(packed_data);
diff --git a/main/tests/test_physics.cpp b/main/tests/test_physics.cpp
index 4931d42674..7727af6ad1 100644
--- a/main/tests/test_physics.cpp
+++ b/main/tests/test_physics.cpp
@@ -36,6 +36,7 @@
#include "core/os/main_loop.h"
#include "core/os/os.h"
#include "core/print_string.h"
+#include "servers/display_server.h"
#include "servers/physics_server.h"
#include "servers/visual_server.h"
@@ -313,7 +314,7 @@ public:
camera = vs->camera_create();
RID viewport = vs->viewport_create();
- Size2i screen_size = OS::get_singleton()->get_window_size();
+ Size2i screen_size = DisplayServer::get_singleton()->window_get_size();
vs->viewport_set_size(viewport, screen_size.x, screen_size.y);
vs->viewport_attach_to_screen(viewport, Rect2(Vector2(), screen_size));
vs->viewport_set_active(viewport, true);
diff --git a/main/tests/test_physics_2d.cpp b/main/tests/test_physics_2d.cpp
index 160c25f43a..4403e40b76 100644
--- a/main/tests/test_physics_2d.cpp
+++ b/main/tests/test_physics_2d.cpp
@@ -35,6 +35,7 @@
#include "core/os/os.h"
#include "core/print_string.h"
#include "scene/resources/texture.h"
+#include "servers/display_server.h"
#include "servers/physics_2d_server.h"
#include "servers/visual_server.h"
@@ -354,7 +355,7 @@ public:
RID vp = vs->viewport_create();
canvas = vs->canvas_create();
- Size2i screen_size = OS::get_singleton()->get_window_size();
+ Size2i screen_size = DisplayServer::get_singleton()->window_get_size();
vs->viewport_attach_canvas(vp, canvas);
vs->viewport_set_size(vp, screen_size.x, screen_size.y);
vs->viewport_attach_to_screen(vp, Rect2(Vector2(), screen_size));
diff --git a/main/tests/test_render.cpp b/main/tests/test_render.cpp
index 62239a5cb5..0fbc5ea697 100644
--- a/main/tests/test_render.cpp
+++ b/main/tests/test_render.cpp
@@ -36,6 +36,7 @@
#include "core/os/main_loop.h"
#include "core/os/os.h"
#include "core/print_string.h"
+#include "servers/display_server.h"
#include "servers/visual_server.h"
#define OBJECT_COUNT 50
@@ -163,7 +164,7 @@ public:
// vs->camera_set_perspective( camera, 60.0,0.1, 100.0 );
viewport = vs->viewport_create();
- Size2i screen_size = OS::get_singleton()->get_window_size();
+ Size2i screen_size = DisplayServer::get_singleton()->window_get_size();
vs->viewport_set_size(viewport, screen_size.x, screen_size.y);
vs->viewport_attach_to_screen(viewport, Rect2(Vector2(), screen_size));
vs->viewport_set_active(viewport, true);
diff --git a/modules/gdnative/nativescript/SCsub b/modules/gdnative/nativescript/SCsub
index 92c9d6630d..c28a1c8659 100644
--- a/modules/gdnative/nativescript/SCsub
+++ b/modules/gdnative/nativescript/SCsub
@@ -5,5 +5,5 @@ Import('env_gdnative')
env_gdnative.add_source_files(env.modules_sources, '*.cpp')
-if "platform" in env and env["platform"] in ["x11", "iphone"]:
+if "platform" in env and env["platform"] in ["linuxbsd", "iphone"]:
env.Append(LINKFLAGS=["-rdynamic"])
diff --git a/modules/gdscript/language_server/gdscript_text_document.cpp b/modules/gdscript/language_server/gdscript_text_document.cpp
index d5723fd20f..fbf8ef2f8f 100644
--- a/modules/gdscript/language_server/gdscript_text_document.cpp
+++ b/modules/gdscript/language_server/gdscript_text_document.cpp
@@ -35,6 +35,7 @@
#include "editor/plugins/script_text_editor.h"
#include "gdscript_extend_parser.h"
#include "gdscript_language_protocol.h"
+#include "servers/display_server.h"
void GDScriptTextDocument::_bind_methods() {
ClassDB::bind_method(D_METHOD("didOpen"), &GDScriptTextDocument::didOpen);
@@ -419,7 +420,8 @@ void GDScriptTextDocument::sync_script_content(const String &p_path, const Strin
void GDScriptTextDocument::show_native_symbol_in_editor(const String &p_symbol_id) {
ScriptEditor::get_singleton()->call_deferred("_help_class_goto", p_symbol_id);
- OS::get_singleton()->move_window_to_foreground();
+
+ DisplayServer::get_singleton()->window_move_to_foreground();
}
Array GDScriptTextDocument::find_symbols(const lsp::TextDocumentPositionParams &p_location, List<const lsp::DocumentSymbol *> &r_list) {
diff --git a/modules/mobile_vr/mobile_vr_interface.cpp b/modules/mobile_vr/mobile_vr_interface.cpp
index af429eadd5..2a4b761b73 100644
--- a/modules/mobile_vr/mobile_vr_interface.cpp
+++ b/modules/mobile_vr/mobile_vr_interface.cpp
@@ -31,6 +31,7 @@
#include "mobile_vr_interface.h"
#include "core/input/input.h"
#include "core/os/os.h"
+#include "servers/display_server.h"
#include "servers/visual/visual_server_globals.h"
StringName MobileVRInterface::get_name() const {
@@ -339,7 +340,7 @@ Size2 MobileVRInterface::get_render_targetsize() {
_THREAD_SAFE_METHOD_
// we use half our window size
- Size2 target_size = OS::get_singleton()->get_window_size();
+ Size2 target_size = DisplayServer::get_singleton()->window_get_size();
target_size.x *= 0.5 * oversample;
target_size.y *= oversample;
diff --git a/platform/x11/SCsub b/platform/linuxbsd/SCsub
index ff4e667b87..f3f65e216e 100644
--- a/platform/x11/SCsub
+++ b/platform/linuxbsd/SCsub
@@ -3,20 +3,21 @@
Import('env')
from platform_methods import run_in_subprocess
-import platform_x11_builders
+import platform_linuxbsd_builders
common_x11 = [
+ "crash_handler_linuxbsd.cpp",
+ "os_linuxbsd.cpp",
+ "joypad_linux.cpp",
"context_gl_x11.cpp",
+ "detect_prime_x11.cpp",
+ "display_server_x11.cpp",
"vulkan_context_x11.cpp",
- "crash_handler_x11.cpp",
- "os_x11.cpp",
"key_mapping_x11.cpp",
- "display_server_x11.cpp",
- "joypad_linux.cpp",
- "detect_prime.cpp"
+
]
-prog = env.add_program('#bin/godot', ['godot_x11.cpp'] + common_x11)
+prog = env.add_program('#bin/godot', ['godot_linuxbsd.cpp'] + common_x11)
if (env["debug_symbols"] == "full" or env["debug_symbols"] == "yes") and env["separate_debug_symbols"]:
- env.AddPostAction(prog, run_in_subprocess(platform_x11_builders.make_debug_x11))
+ env.AddPostAction(prog, run_in_subprocess(platform_linuxbsd_builders.make_debug_linuxbsd))
diff --git a/platform/x11/context_gl_x11.cpp b/platform/linuxbsd/context_gl_x11.cpp
index 5442af3bef..5442af3bef 100644
--- a/platform/x11/context_gl_x11.cpp
+++ b/platform/linuxbsd/context_gl_x11.cpp
diff --git a/platform/x11/context_gl_x11.h b/platform/linuxbsd/context_gl_x11.h
index 2c0643c95a..2c0643c95a 100644
--- a/platform/x11/context_gl_x11.h
+++ b/platform/linuxbsd/context_gl_x11.h
diff --git a/platform/x11/crash_handler_x11.cpp b/platform/linuxbsd/crash_handler_linuxbsd.cpp
index 19c8f71d0e..1b3804e3ed 100644
--- a/platform/x11/crash_handler_x11.cpp
+++ b/platform/linuxbsd/crash_handler_linuxbsd.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* crash_handler_x11.cpp */
+/* crash_handler_linuxbsd.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,7 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "crash_handler_x11.h"
+#include "crash_handler_linuxbsd.h"
#include "core/os/os.h"
#include "core/project_settings.h"
diff --git a/platform/x11/crash_handler_x11.h b/platform/linuxbsd/crash_handler_linuxbsd.h
index 98620cc789..94b4649690 100644
--- a/platform/x11/crash_handler_x11.h
+++ b/platform/linuxbsd/crash_handler_linuxbsd.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* crash_handler_x11.h */
+/* crash_handler_linuxbsd.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
diff --git a/platform/x11/detect.py b/platform/linuxbsd/detect.py
index 9a9ab86068..1a395efffe 100644
--- a/platform/x11/detect.py
+++ b/platform/linuxbsd/detect.py
@@ -8,7 +8,7 @@ def is_active():
def get_name():
- return "X11"
+ return "LinuxBSD"
def can_build():
@@ -317,7 +317,7 @@ def configure(env):
if not env['builtin_zlib']:
env.ParseConfig('pkg-config zlib --cflags --libs')
- env.Prepend(CPPPATH=['#platform/x11'])
+ env.Prepend(CPPPATH=['#platform/linuxbsd'])
env.Append(CPPDEFINES=['X11_ENABLED', 'UNIX_ENABLED'])
env.Append(CPPDEFINES=['VULKAN_ENABLED'])
@@ -350,9 +350,9 @@ def configure(env):
print("Warning: Creating template binaries enabled for PCK embedding is currently only supported with GNU ld")
else:
if float(gnu_ld_version.group(1)) >= 2.30:
- env.Append(LINKFLAGS=['-T', 'platform/x11/pck_embed.ld'])
+ env.Append(LINKFLAGS=['-T', 'platform/linuxbsd/pck_embed.ld'])
else:
- env.Append(LINKFLAGS=['-T', 'platform/x11/pck_embed.legacy.ld'])
+ env.Append(LINKFLAGS=['-T', 'platform/linuxbsd/pck_embed.legacy.ld'])
## Cross-compilation
diff --git a/platform/x11/detect_prime.cpp b/platform/linuxbsd/detect_prime_x11.cpp
index d79fd00118..69b0837e6c 100644
--- a/platform/x11/detect_prime.cpp
+++ b/platform/linuxbsd/detect_prime_x11.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* detect_prime.cpp */
+/* detect_prime_x11.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
diff --git a/platform/x11/detect_prime.h b/platform/linuxbsd/detect_prime_x11.h
index df636449f4..039bdee76b 100644
--- a/platform/x11/detect_prime.h
+++ b/platform/linuxbsd/detect_prime_x11.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* detect_prime.h */
+/* detect_prime_x11.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
diff --git a/platform/x11/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp
index b4bd5658b8..ace07a3ac6 100644
--- a/platform/x11/display_server_x11.cpp
+++ b/platform/linuxbsd/display_server_x11.cpp
@@ -32,7 +32,7 @@
#ifdef X11_ENABLED
-#include "detect_prime.h"
+#include "detect_prime_x11.h"
#include "core/os/dir_access.h"
#include "core/print_string.h"
@@ -608,7 +608,8 @@ bool DisplayServerX11::screen_is_touchscreen(int p_screen) const {
#ifndef _MSC_VER
#warning Need to get from proper window
#endif
- return false; //?
+
+ return DisplayServer::screen_is_touchscreen(p_screen);
}
Vector<DisplayServer::WindowID> DisplayServerX11::get_window_list() const {
@@ -638,6 +639,11 @@ void DisplayServerX11::delete_sub_window(WindowID p_id) {
WindowData &wd = windows[p_id];
+#ifdef VULKAN_ENABLED
+ if (rendering_driver == "vulkan") {
+ context_vulkan->window_destroy(wd.vulkan_window);
+ }
+#endif
XUnmapWindow(x11_display, wd.x11_window);
XDestroyWindow(x11_display, wd.x11_window);
if (wd.xic) {
@@ -649,7 +655,7 @@ void DisplayServerX11::delete_sub_window(WindowID p_id) {
void DisplayServerX11::window_set_title(const String &p_title, WindowID p_window) {
- ERR_FAIL_COND(windows.has(p_window));
+ ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
XStoreName(x11_display, wd.x11_window, p_title.utf8().get_data());
@@ -660,7 +666,7 @@ void DisplayServerX11::window_set_title(const String &p_title, WindowID p_window
}
int DisplayServerX11::window_get_current_screen(WindowID p_window) const {
- ERR_FAIL_COND_V(windows.has(p_window), -1);
+ ERR_FAIL_COND_V(!windows.has(p_window), -1);
const WindowData &wd = windows[p_window];
int x, y;
@@ -677,7 +683,7 @@ int DisplayServerX11::window_get_current_screen(WindowID p_window) const {
return 0;
}
void DisplayServerX11::window_set_current_screen(int p_screen, WindowID p_window) {
- ERR_FAIL_COND(windows.has(p_window));
+ ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
int count = get_screen_count();
@@ -697,7 +703,7 @@ void DisplayServerX11::window_set_current_screen(int p_screen, WindowID p_window
}
Point2i DisplayServerX11::window_get_position(WindowID p_window) const {
- ERR_FAIL_COND_V(windows.has(p_window), Point2i());
+ ERR_FAIL_COND_V(!windows.has(p_window), Point2i());
const WindowData &wd = windows[p_window];
int x, y;
Window child;
@@ -705,7 +711,7 @@ Point2i DisplayServerX11::window_get_position(WindowID p_window) const {
return Point2i(x, y);
}
void DisplayServerX11::window_set_position(const Point2i &p_position, WindowID p_window) {
- ERR_FAIL_COND(windows.has(p_window));
+ ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
int x = 0;
@@ -735,7 +741,7 @@ void DisplayServerX11::window_set_position(const Point2i &p_position, WindowID p
}
void DisplayServerX11::window_set_max_size(const Size2i p_size, WindowID p_window) {
- ERR_FAIL_COND(windows.has(p_window));
+ ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
if ((p_size != Size2i()) && ((p_size.x < wd.min_size.x) || (p_size.y < wd.min_size.y))) {
@@ -765,14 +771,14 @@ void DisplayServerX11::window_set_max_size(const Size2i p_size, WindowID p_windo
}
}
Size2i DisplayServerX11::window_get_max_size(WindowID p_window) const {
- ERR_FAIL_COND_V(windows.has(p_window), Size2i());
+ ERR_FAIL_COND_V(!windows.has(p_window), Size2i());
const WindowData &wd = windows[p_window];
return wd.max_size;
}
void DisplayServerX11::window_set_min_size(const Size2i p_size, WindowID p_window) {
- ERR_FAIL_COND(windows.has(p_window));
+ ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
if ((p_size != Size2i()) && (wd.max_size != Size2i()) && ((p_size.x > wd.max_size.x) || (p_size.y > wd.max_size.y))) {
@@ -802,14 +808,14 @@ void DisplayServerX11::window_set_min_size(const Size2i p_size, WindowID p_windo
}
}
Size2i DisplayServerX11::window_get_min_size(WindowID p_window) const {
- ERR_FAIL_COND_V(windows.has(p_window), Size2i());
+ ERR_FAIL_COND_V(!windows.has(p_window), Size2i());
const WindowData &wd = windows[p_window];
return wd.min_size;
}
void DisplayServerX11::window_set_size(const Size2i p_size, WindowID p_window) {
- ERR_FAIL_COND(windows.has(p_window));
+ ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
if (wd.size.width == p_size.width && wd.size.height == p_size.height)
@@ -863,12 +869,12 @@ void DisplayServerX11::window_set_size(const Size2i p_size, WindowID p_window) {
}
}
Size2i DisplayServerX11::window_get_size(WindowID p_window) const {
- ERR_FAIL_COND_V(windows.has(p_window), Size2i());
+ ERR_FAIL_COND_V(!windows.has(p_window), Size2i());
const WindowData &wd = windows[p_window];
return wd.size;
}
Size2i DisplayServerX11::window_get_real_size(WindowID p_window) const {
- ERR_FAIL_COND_V(windows.has(p_window), Size2i());
+ ERR_FAIL_COND_V(!windows.has(p_window), Size2i());
const WindowData &wd = windows[p_window];
XWindowAttributes xwa;
@@ -897,7 +903,7 @@ Size2i DisplayServerX11::window_get_real_size(WindowID p_window) const {
bool DisplayServerX11::window_is_maximize_allowed(WindowID p_window) const {
- ERR_FAIL_COND_V(windows.has(p_window), false);
+ ERR_FAIL_COND_V(!windows.has(p_window), false);
const WindowData &wd = windows[p_window];
Atom property = XInternAtom(x11_display, "_NET_WM_ALLOWED_ACTIONS", False);
@@ -944,7 +950,7 @@ bool DisplayServerX11::window_is_maximize_allowed(WindowID p_window) const {
}
void DisplayServerX11::_set_wm_maximized(WindowID p_window, bool p_enabled) {
- ERR_FAIL_COND(windows.has(p_window));
+ ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
// Using EWMH -- Extended Window Manager Hints
@@ -976,7 +982,7 @@ void DisplayServerX11::_set_wm_maximized(WindowID p_window, bool p_enabled) {
void DisplayServerX11::_set_wm_fullscreen(WindowID p_window, bool p_enabled) {
- ERR_FAIL_COND(windows.has(p_window));
+ ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
if (p_enabled && !window_get_flag(WINDOW_FLAG_BORDERLESS, p_window)) {
@@ -1060,7 +1066,7 @@ void DisplayServerX11::_set_wm_fullscreen(WindowID p_window, bool p_enabled) {
}
void DisplayServerX11::window_set_mode(WindowMode p_mode, WindowID p_window) {
- ERR_FAIL_COND(windows.has(p_window));
+ ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
WindowMode old_mode = window_get_mode(p_window);
@@ -1171,7 +1177,7 @@ void DisplayServerX11::window_set_mode(WindowMode p_mode, WindowID p_window) {
}
DisplayServer::WindowMode DisplayServerX11::window_get_mode(WindowID p_window) const {
- ERR_FAIL_COND_V(windows.has(p_window), WINDOW_MODE_WINDOWED);
+ ERR_FAIL_COND_V(!windows.has(p_window), WINDOW_MODE_WINDOWED);
const WindowData &wd = windows[p_window];
if (wd.fullscreen) { //if fullscreen, it's not in another mode
@@ -1263,7 +1269,7 @@ DisplayServer::WindowMode DisplayServerX11::window_get_mode(WindowID p_window) c
}
void DisplayServerX11::window_set_flag(WindowFlags p_flag, bool p_enabled, WindowID p_window) {
- ERR_FAIL_COND(windows.has(p_window));
+ ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
switch (p_flag) {
@@ -1348,7 +1354,7 @@ void DisplayServerX11::window_set_flag(WindowFlags p_flag, bool p_enabled, Windo
}
}
bool DisplayServerX11::window_get_flag(WindowFlags p_flag, WindowID p_window) const {
- ERR_FAIL_COND_V(windows.has(p_window), false);
+ ERR_FAIL_COND_V(!windows.has(p_window), false);
const WindowData &wd = windows[p_window];
switch (p_flag) {
@@ -1391,7 +1397,7 @@ bool DisplayServerX11::window_get_flag(WindowFlags p_flag, WindowID p_window) co
}
void DisplayServerX11::window_request_attention(WindowID p_window) {
- ERR_FAIL_COND(windows.has(p_window));
+ ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
// Using EWMH -- Extended Window Manager Hints
//
@@ -1415,7 +1421,7 @@ void DisplayServerX11::window_request_attention(WindowID p_window) {
}
void DisplayServerX11::window_move_to_foreground(WindowID p_window) {
- ERR_FAIL_COND(windows.has(p_window));
+ ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
XEvent xev;
@@ -1437,9 +1443,19 @@ bool DisplayServerX11::window_can_draw(WindowID p_window) const {
//this seems to be all that is provided by X11
return window_get_mode(p_window) != WINDOW_MODE_MINIMIZED;
}
+bool DisplayServerX11::can_any_window_draw() const {
+
+ for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) {
+ if (window_get_mode(E->key()) != WINDOW_MODE_MINIMIZED) {
+ return true;
+ }
+ }
+
+ return false;
+}
void DisplayServerX11::window_set_ime_active(const bool p_active, WindowID p_window) {
- ERR_FAIL_COND(windows.has(p_window));
+ ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
wd.im_active = p_active;
@@ -1455,7 +1471,7 @@ void DisplayServerX11::window_set_ime_active(const bool p_active, WindowID p_win
}
}
void DisplayServerX11::window_set_ime_position(const Point2i &p_pos, WindowID p_window) {
- ERR_FAIL_COND(windows.has(p_window));
+ ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
wd.im_position = p_pos;
@@ -2003,7 +2019,7 @@ void DisplayServerX11::_window_changed(XEvent *event) {
wd.size.height = event->xconfigure.height;
#if defined(VULKAN_ENABLED)
- if (video_driver == "vulkan") {
+ if (rendering_driver == "vulkan") {
context_vulkan->window_resize(wd.vulkan_window, wd.size.width, wd.size.height);
}
#endif
@@ -2634,15 +2650,59 @@ void DisplayServerX11::process_events() {
}
void DisplayServerX11::release_rendering_thread() {
- WARN_PRINT("Rendering thread not supported by this display server.");
}
+
void DisplayServerX11::make_rendering_thread() {
- WARN_PRINT("Rendering thread not supported by this display server.");
}
+
void DisplayServerX11::swap_buffers() {
- WARN_PRINT("Swap buffers not supported by this display server.");
}
+void DisplayServerX11::_update_context(WindowData &wd) {
+ XClassHint *classHint = XAllocClassHint();
+
+ if (classHint) {
+
+ CharString name_str;
+ switch (context) {
+ case CONTEXT_EDITOR:
+ name_str = "Godot_Editor";
+ break;
+ case CONTEXT_PROJECTMAN:
+ name_str = "Godot_ProjectList";
+ break;
+ case CONTEXT_ENGINE:
+ name_str = "Godot_Engine";
+ break;
+ }
+
+ CharString class_str;
+ if (context == CONTEXT_ENGINE) {
+ String config_name = GLOBAL_GET("application/config/name");
+ if (config_name.length() == 0) {
+ class_str = "Godot_Engine";
+ } else {
+ class_str = config_name.utf8();
+ }
+ } else {
+ class_str = "Godot";
+ }
+
+ classHint->res_class = class_str.ptrw();
+ classHint->res_name = name_str.ptrw();
+
+ XSetClassHint(x11_display, wd.x11_window, classHint);
+ XFree(classHint);
+ }
+}
+void DisplayServerX11::set_context(Context p_context) {
+
+ context = p_context;
+
+ for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) {
+ _update_context(E->get());
+ }
+}
void DisplayServerX11::set_native_icon(const String &p_filename) {
WARN_PRINT("Native icon not supported by this display server.");
}
@@ -2650,9 +2710,22 @@ void DisplayServerX11::set_icon(const Ref<Image> &p_icon) {
WARN_PRINT("Icon not supported by this display server.");
}
-DisplayServer *DisplayServerX11::create_func(const String &p_video_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
+Vector<String> DisplayServerX11::get_rendering_drivers_func() {
+ Vector<String> drivers;
+
+#ifdef VULKAN_ENABLED
+ drivers.push_back("vulkan");
+#endif
+#ifdef OPENGL_ENABLED
+ drivers.push_back("opengl");
+#endif
+
+ return drivers;
+}
+
+DisplayServer *DisplayServerX11::create_func(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
- return memnew(DisplayServerX11(p_video_driver, p_mode, p_flags, p_resolution, r_error));
+ return memnew(DisplayServerX11(p_rendering_driver, p_mode, p_flags, p_resolution, r_error));
}
DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, const Vector2i &p_resolution) {
@@ -2678,7 +2751,7 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, c
WindowID id;
{
WindowData wd;
- wd.x11_window = XCreateWindow(x11_display, RootWindow(x11_display, visualInfo->screen), 0, 0, OS::get_singleton()->get_video_mode().width, OS::get_singleton()->get_video_mode().height, 0, visualInfo->depth, InputOutput, visualInfo->visual, valuemask, &windowAttributes);
+ wd.x11_window = XCreateWindow(x11_display, RootWindow(x11_display, visualInfo->screen), 0, 0, p_resolution.width, p_resolution.height, 0, visualInfo->depth, InputOutput, visualInfo->visual, valuemask, &windowAttributes);
//set_class_hint(x11_display, wd.x11_window);
XMapWindow(x11_display, wd.x11_window);
@@ -2771,6 +2844,8 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, c
WARN_PRINT("XCreateIC couldn't create wd.xic");
}
+ _update_context(wd);
+
id = window_id_counter++;
windows[id] = wd;
@@ -2788,7 +2863,7 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, c
return id;
}
-DisplayServerX11::DisplayServerX11(const String &p_video_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
+DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
r_error = OK;
@@ -2870,8 +2945,8 @@ DisplayServerX11::DisplayServerX11(const String &p_video_driver, WindowMode p_mo
}
if (!_refresh_device_info()) {
- OS::get_singleton()->alert("Your system does not support XInput 2.\n"
- "Please upgrade your distribution.",
+ alert("Your system does not support XInput 2.\n"
+ "Please upgrade your distribution.",
"Unable to initialize XInput");
r_error = ERR_UNAVAILABLE;
return;
@@ -2930,15 +3005,15 @@ DisplayServerX11::DisplayServerX11(const String &p_video_driver, WindowMode p_mo
//!!!!!!!!!!!!!!!!!!!!!!!!!!
//TODO - do Vulkan and GLES2 support checks, driver selection and fallback
- video_driver = p_video_driver;
+ rendering_driver = p_rendering_driver;
#ifndef _MSC_VER
-#warning Forcing vulkan video driver because OpenGL not implemented yet
+#warning Forcing vulkan rendering driver because OpenGL not implemented yet
#endif
- video_driver = "vulkan";
+ rendering_driver = "vulkan";
#if defined(VULKAN_ENABLED)
- if (video_driver == "vulkan") {
+ if (rendering_driver == "vulkan") {
context_vulkan = memnew(VulkanContextX11);
if (context_vulkan->initialize() != OK) {
@@ -2947,17 +3022,11 @@ DisplayServerX11::DisplayServerX11(const String &p_video_driver, WindowMode p_mo
r_error = ERR_CANT_CREATE;
ERR_FAIL_MSG("Could not initialize Vulkan");
}
-
- //temporary
- rendering_device_vulkan = memnew(RenderingDeviceVulkan);
- rendering_device_vulkan->initialize(context_vulkan);
-
- RasterizerRD::make_current();
}
#endif
// Init context and rendering device
#if defined(OPENGL_ENABLED)
- if (video_driver == "opengl_es") {
+ if (rendering_driver == "opengl_es") {
if (getenv("DRI_PRIME") == NULL) {
int use_prime = -1;
@@ -3028,6 +3097,18 @@ DisplayServerX11::DisplayServerX11(const String &p_video_driver, WindowMode p_mo
}
}
+//create RenderingDevice if used
+#if defined(VULKAN_ENABLED)
+ if (rendering_driver == "vulkan") {
+
+ //temporary
+ rendering_device_vulkan = memnew(RenderingDeviceVulkan);
+ rendering_device_vulkan->initialize(context_vulkan);
+
+ RasterizerRD::make_current();
+ }
+#endif
+
/*
visual_server = memnew(VisualServerRaster);
if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {
@@ -3190,8 +3271,6 @@ DisplayServerX11::DisplayServerX11(const String &p_video_driver, WindowMode p_mo
requested = None;
- visual_server->init();
-
window_has_focus = true; // Set focus to true at init
/*if (p_desired.layered) {
@@ -3211,6 +3290,58 @@ DisplayServerX11::DisplayServerX11(const String &p_video_driver, WindowMode p_mo
r_error = OK;
}
DisplayServerX11::~DisplayServerX11() {
+
+ //destroy all windows
+ for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) {
+#ifdef VULKAN_ENABLED
+ if (rendering_driver == "vulkan") {
+ context_vulkan->window_destroy(E->get().vulkan_window);
+ }
+#endif
+
+ if (E->get().xic) {
+ XDestroyIC(E->get().xic);
+ }
+ XUnmapWindow(x11_display, E->get().x11_window);
+ XDestroyWindow(x11_display, E->get().x11_window);
+ }
+
+ //destroy drivers
+#if defined(VULKAN_ENABLED)
+ if (rendering_driver == "vulkan") {
+
+ if (rendering_device_vulkan) {
+ rendering_device_vulkan->finalize();
+ memdelete(rendering_device_vulkan);
+ }
+
+ if (context_vulkan)
+ memdelete(context_vulkan);
+ }
+#endif
+
+ if (xrandr_handle)
+ dlclose(xrandr_handle);
+
+ for (int i = 0; i < CURSOR_MAX; i++) {
+ if (cursors[i] != None)
+ XFreeCursor(x11_display, cursors[i]);
+ if (img[i] != NULL)
+ XcursorImageDestroy(img[i]);
+ };
+
+ if (xim) {
+ XCloseIM(xim);
+ }
+
+ XCloseDisplay(x11_display);
+ if (xmbstring)
+ memfree(xmbstring);
+}
+
+void DisplayServerX11::register_x11_driver() {
+
+ register_create_function("x11", create_func, get_rendering_drivers_func);
}
#endif // X11 enabled
diff --git a/platform/x11/display_server_x11.h b/platform/linuxbsd/display_server_x11.h
index bc6f1bf2a1..6964447be2 100644
--- a/platform/x11/display_server_x11.h
+++ b/platform/linuxbsd/display_server_x11.h
@@ -36,7 +36,7 @@
#include "servers/display_server.h"
#include "core/input/input.h"
-#include "crash_handler_x11.h"
+
#include "drivers/alsa/audio_driver_alsa.h"
#include "drivers/alsamidi/midi_driver_alsamidi.h"
#include "drivers/pulseaudio/audio_driver_pulseaudio.h"
@@ -52,7 +52,7 @@
#if defined(VULKAN_ENABLED)
#include "drivers/vulkan/rendering_device_vulkan.h"
-#include "platform/x11/vulkan_context_x11.h"
+#include "platform/linuxbsd/vulkan_context_x11.h"
#endif
#include <X11/Xcursor/Xcursor.h>
@@ -110,9 +110,6 @@ class DisplayServerX11 : public DisplayServer {
RenderingDeviceVulkan *rendering_device_vulkan;
#endif
- //Rasterizer *rasterizer;
- VisualServer *visual_server;
-
struct WindowData {
Window x11_window;
::XIC xic;
@@ -200,7 +197,7 @@ class DisplayServerX11 : public DisplayServer {
bool layered_window;
- String video_driver;
+ String rendering_driver;
bool window_focused;
//void set_wm_border(bool p_enabled);
void set_wm_fullscreen(bool p_enabled);
@@ -224,6 +221,10 @@ class DisplayServerX11 : public DisplayServer {
void _set_wm_fullscreen(WindowID p_window, bool p_enabled);
void _set_wm_maximized(WindowID p_window, bool p_enabled);
+ void _update_context(WindowData &wd);
+
+ Context context = CONTEXT_ENGINE;
+
protected:
void _window_changed(XEvent *event);
@@ -286,6 +287,8 @@ public:
virtual bool window_can_draw(WindowID p_window = MAIN_WINDOW_ID) const;
+ virtual bool can_any_window_draw() const;
+
virtual void window_set_ime_active(const bool p_active, WindowID p_window = MAIN_WINDOW_ID);
virtual void window_set_ime_position(const Point2i &p_pos, WindowID p_window = MAIN_WINDOW_ID);
@@ -301,12 +304,17 @@ public:
virtual void make_rendering_thread();
virtual void swap_buffers();
+ virtual void set_context(Context p_context);
+
virtual void set_native_icon(const String &p_filename);
virtual void set_icon(const Ref<Image> &p_icon);
- static DisplayServer *create_func(const String &p_video_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
+ static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
+ static Vector<String> get_rendering_drivers_func();
+
+ static void register_x11_driver();
- DisplayServerX11(const String &p_video_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
+ DisplayServerX11(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
~DisplayServerX11();
};
diff --git a/platform/x11/export/export.cpp b/platform/linuxbsd/export/export.cpp
index 1c0c6ec096..53e3ce8f85 100644
--- a/platform/x11/export/export.cpp
+++ b/platform/linuxbsd/export/export.cpp
@@ -32,17 +32,17 @@
#include "core/os/file_access.h"
#include "editor/editor_export.h"
-#include "platform/x11/logo.gen.h"
+#include "platform/linuxbsd/logo.gen.h"
#include "scene/resources/texture.h"
static Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size);
-void register_x11_exporter() {
+void register_linuxbsd_exporter() {
Ref<EditorExportPlatformPC> platform;
platform.instance();
- Ref<Image> img = memnew(Image(_x11_logo));
+ Ref<Image> img = memnew(Image(_linuxbsd_logo));
Ref<ImageTexture> logo;
logo.instance();
logo->create_from_image(img);
diff --git a/platform/x11/export/export.h b/platform/linuxbsd/export/export.h
index 4049e6a8bf..5ee81f485e 100644
--- a/platform/x11/export/export.h
+++ b/platform/linuxbsd/export/export.h
@@ -28,9 +28,9 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef X11_EXPORT_H
-#define X11_EXPORT_H
+#ifndef LINUXBSD_EXPORT_H
+#define LINUXBSD_EXPORT_H
-void register_x11_exporter();
+void register_linuxbsd_exporter();
-#endif // X11_EXPORT_H
+#endif // LINUXBSD_EXPORT_H
diff --git a/platform/x11/godot_x11.cpp b/platform/linuxbsd/godot_linuxbsd.cpp
index 77b74184ad..710ba3ca40 100644
--- a/platform/x11/godot_x11.cpp
+++ b/platform/linuxbsd/godot_linuxbsd.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* godot_x11.cpp */
+/* godot_linuxbsd.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -34,11 +34,11 @@
#include <unistd.h>
#include "main/main.h"
-#include "os_x11.h"
+#include "os_linuxbsd.h"
int main(int argc, char *argv[]) {
- OS_X11 os;
+ OS_LinuxBSD os;
setlocale(LC_CTYPE, "");
diff --git a/platform/x11/joypad_linux.cpp b/platform/linuxbsd/joypad_linux.cpp
index 7531b1160f..7531b1160f 100644
--- a/platform/x11/joypad_linux.cpp
+++ b/platform/linuxbsd/joypad_linux.cpp
diff --git a/platform/x11/joypad_linux.h b/platform/linuxbsd/joypad_linux.h
index 0d175193a5..0d175193a5 100644
--- a/platform/x11/joypad_linux.h
+++ b/platform/linuxbsd/joypad_linux.h
diff --git a/platform/x11/key_mapping_x11.cpp b/platform/linuxbsd/key_mapping_x11.cpp
index 78bd2b71a0..78bd2b71a0 100644
--- a/platform/x11/key_mapping_x11.cpp
+++ b/platform/linuxbsd/key_mapping_x11.cpp
diff --git a/platform/x11/key_mapping_x11.h b/platform/linuxbsd/key_mapping_x11.h
index 10db43bcc4..10db43bcc4 100644
--- a/platform/x11/key_mapping_x11.h
+++ b/platform/linuxbsd/key_mapping_x11.h
diff --git a/platform/x11/logo.png b/platform/linuxbsd/logo.png
index 078654b757..078654b757 100644
--- a/platform/x11/logo.png
+++ b/platform/linuxbsd/logo.png
Binary files differ
diff --git a/platform/linuxbsd/os_linuxbsd.cpp b/platform/linuxbsd/os_linuxbsd.cpp
new file mode 100644
index 0000000000..2c596b0058
--- /dev/null
+++ b/platform/linuxbsd/os_linuxbsd.cpp
@@ -0,0 +1,381 @@
+/*************************************************************************/
+/* os_linuxbsd.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "os_linuxbsd.h"
+
+#include "core/os/dir_access.h"
+#include "core/print_string.h"
+#include "errno.h"
+
+#ifdef HAVE_MNTENT
+#include <mntent.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <dlfcn.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "main/main.h"
+
+#ifdef X11_ENABLED
+#include "display_server_x11.h"
+#endif
+
+void OS_LinuxBSD::initialize() {
+
+ crash_handler.initialize();
+
+ OS_Unix::initialize_core();
+}
+
+void OS_LinuxBSD::initialize_joypads() {
+
+#ifdef JOYDEV_ENABLED
+ joypad = memnew(JoypadLinux(Input::get_singleton()));
+#endif
+}
+
+String OS_LinuxBSD::get_unique_id() const {
+
+ static String machine_id;
+ if (machine_id.empty()) {
+ if (FileAccess *f = FileAccess::open("/etc/machine-id", FileAccess::READ)) {
+ while (machine_id.empty() && !f->eof_reached()) {
+ machine_id = f->get_line().strip_edges();
+ }
+ f->close();
+ memdelete(f);
+ }
+ }
+ return machine_id;
+}
+
+void OS_LinuxBSD::finalize() {
+
+ if (main_loop)
+ memdelete(main_loop);
+ main_loop = NULL;
+
+#ifdef ALSAMIDI_ENABLED
+ driver_alsamidi.close();
+#endif
+
+#ifdef JOYDEV_ENABLED
+ memdelete(joypad);
+#endif
+}
+
+MainLoop *OS_LinuxBSD::get_main_loop() const {
+
+ return main_loop;
+}
+
+void OS_LinuxBSD::delete_main_loop() {
+
+ if (main_loop)
+ memdelete(main_loop);
+ main_loop = NULL;
+}
+
+void OS_LinuxBSD::set_main_loop(MainLoop *p_main_loop) {
+
+ main_loop = p_main_loop;
+}
+
+String OS_LinuxBSD::get_name() const {
+
+#ifdef __linux__
+ return "Linux";
+#elif defined(__FreeBSD__)
+ return "FreeBSD";
+#elif defined(__NetBSD__)
+ return "NetBSD";
+#else
+ return "BSD";
+#endif
+}
+
+Error OS_LinuxBSD::shell_open(String p_uri) {
+
+ Error ok;
+ List<String> args;
+ args.push_back(p_uri);
+ ok = execute("xdg-open", args, false);
+ if (ok == OK)
+ return OK;
+ ok = execute("gnome-open", args, false);
+ if (ok == OK)
+ return OK;
+ ok = execute("kde-open", args, false);
+ return ok;
+}
+
+bool OS_LinuxBSD::_check_internal_feature_support(const String &p_feature) {
+
+ return p_feature == "pc";
+}
+
+String OS_LinuxBSD::get_config_path() const {
+
+ if (has_environment("XDG_CONFIG_HOME")) {
+ return get_environment("XDG_CONFIG_HOME");
+ } else if (has_environment("HOME")) {
+ return get_environment("HOME").plus_file(".config");
+ } else {
+ return ".";
+ }
+}
+
+String OS_LinuxBSD::get_data_path() const {
+
+ if (has_environment("XDG_DATA_HOME")) {
+ return get_environment("XDG_DATA_HOME");
+ } else if (has_environment("HOME")) {
+ return get_environment("HOME").plus_file(".local/share");
+ } else {
+ return get_config_path();
+ }
+}
+
+String OS_LinuxBSD::get_cache_path() const {
+
+ if (has_environment("XDG_CACHE_HOME")) {
+ return get_environment("XDG_CACHE_HOME");
+ } else if (has_environment("HOME")) {
+ return get_environment("HOME").plus_file(".cache");
+ } else {
+ return get_config_path();
+ }
+}
+
+String OS_LinuxBSD::get_system_dir(SystemDir p_dir) const {
+
+ String xdgparam;
+
+ switch (p_dir) {
+ case SYSTEM_DIR_DESKTOP: {
+
+ xdgparam = "DESKTOP";
+ } break;
+ case SYSTEM_DIR_DCIM: {
+
+ xdgparam = "PICTURES";
+
+ } break;
+ case SYSTEM_DIR_DOCUMENTS: {
+
+ xdgparam = "DOCUMENTS";
+
+ } break;
+ case SYSTEM_DIR_DOWNLOADS: {
+
+ xdgparam = "DOWNLOAD";
+
+ } break;
+ case SYSTEM_DIR_MOVIES: {
+
+ xdgparam = "VIDEOS";
+
+ } break;
+ case SYSTEM_DIR_MUSIC: {
+
+ xdgparam = "MUSIC";
+
+ } break;
+ case SYSTEM_DIR_PICTURES: {
+
+ xdgparam = "PICTURES";
+
+ } break;
+ case SYSTEM_DIR_RINGTONES: {
+
+ xdgparam = "MUSIC";
+
+ } break;
+ }
+
+ String pipe;
+ List<String> arg;
+ arg.push_back(xdgparam);
+ Error err = const_cast<OS_LinuxBSD *>(this)->execute("xdg-user-dir", arg, true, NULL, &pipe);
+ if (err != OK)
+ return ".";
+ return pipe.strip_edges();
+}
+
+void OS_LinuxBSD::run() {
+
+ force_quit = false;
+
+ if (!main_loop)
+ return;
+
+ main_loop->init();
+
+ //uint64_t last_ticks=get_ticks_usec();
+
+ //int frames=0;
+ //uint64_t frame=0;
+
+ while (!force_quit) {
+
+ DisplayServer::get_singleton()->process_events(); // get rid of pending events
+#ifdef JOYDEV_ENABLED
+ joypad->process_joypads();
+#endif
+ if (Main::iteration())
+ break;
+ };
+
+ main_loop->finish();
+}
+
+void OS_LinuxBSD::disable_crash_handler() {
+ crash_handler.disable();
+}
+
+bool OS_LinuxBSD::is_disable_crash_handler() const {
+ return crash_handler.is_disabled();
+}
+
+static String get_mountpoint(const String &p_path) {
+ struct stat s;
+ if (stat(p_path.utf8().get_data(), &s)) {
+ return "";
+ }
+
+#ifdef HAVE_MNTENT
+ dev_t dev = s.st_dev;
+ FILE *fd = setmntent("/proc/mounts", "r");
+ if (!fd) {
+ return "";
+ }
+
+ struct mntent mnt;
+ char buf[1024];
+ size_t buflen = 1024;
+ while (getmntent_r(fd, &mnt, buf, buflen)) {
+ if (!stat(mnt.mnt_dir, &s) && s.st_dev == dev) {
+ endmntent(fd);
+ return String(mnt.mnt_dir);
+ }
+ }
+
+ endmntent(fd);
+#endif
+ return "";
+}
+
+Error OS_LinuxBSD::move_to_trash(const String &p_path) {
+ String trash_can = "";
+ String mnt = get_mountpoint(p_path);
+
+ // If there is a directory "[Mountpoint]/.Trash-[UID]/files", use it as the trash can.
+ if (mnt != "") {
+ String path(mnt + "/.Trash-" + itos(getuid()) + "/files");
+ struct stat s;
+ if (!stat(path.utf8().get_data(), &s)) {
+ trash_can = path;
+ }
+ }
+
+ // Otherwise, if ${XDG_DATA_HOME} is defined, use "${XDG_DATA_HOME}/Trash/files" as the trash can.
+ if (trash_can == "") {
+ char *dhome = getenv("XDG_DATA_HOME");
+ if (dhome) {
+ trash_can = String(dhome) + "/Trash/files";
+ }
+ }
+
+ // Otherwise, if ${HOME} is defined, use "${HOME}/.local/share/Trash/files" as the trash can.
+ if (trash_can == "") {
+ char *home = getenv("HOME");
+ if (home) {
+ trash_can = String(home) + "/.local/share/Trash/files";
+ }
+ }
+
+ // Issue an error if none of the previous locations is appropriate for the trash can.
+ if (trash_can == "") {
+ ERR_PRINT("move_to_trash: Could not determine the trash can location");
+ return FAILED;
+ }
+
+ // Create needed directories for decided trash can location.
+ DirAccess *dir_access = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
+ Error err = dir_access->make_dir_recursive(trash_can);
+ memdelete(dir_access);
+
+ // Issue an error if trash can is not created proprely.
+ if (err != OK) {
+ ERR_PRINT("move_to_trash: Could not create the trash can \"" + trash_can + "\"");
+ return err;
+ }
+
+ // The trash can is successfully created, now move the given resource to it.
+ // Do not use DirAccess:rename() because it can't move files across multiple mountpoints.
+ List<String> mv_args;
+ mv_args.push_back(p_path);
+ mv_args.push_back(trash_can);
+ int retval;
+ err = execute("mv", mv_args, true, NULL, NULL, &retval);
+
+ // Issue an error if "mv" failed to move the given resource to the trash can.
+ if (err != OK || retval != 0) {
+ ERR_PRINT("move_to_trash: Could not move the resource \"" + p_path + "\" to the trash can \"" + trash_can + "\"");
+ return FAILED;
+ }
+
+ return OK;
+}
+
+OS_LinuxBSD::OS_LinuxBSD() {
+
+ main_loop = NULL;
+ force_quit = false;
+
+#ifdef PULSEAUDIO_ENABLED
+ AudioDriverManager::add_driver(&driver_pulseaudio);
+#endif
+
+#ifdef ALSA_ENABLED
+ AudioDriverManager::add_driver(&driver_alsa);
+#endif
+
+#ifdef X11_ENABLED
+ DisplayServerX11::register_x11_driver();
+#endif
+}
diff --git a/platform/linuxbsd/os_linuxbsd.h b/platform/linuxbsd/os_linuxbsd.h
new file mode 100644
index 0000000000..f6586aa45f
--- /dev/null
+++ b/platform/linuxbsd/os_linuxbsd.h
@@ -0,0 +1,106 @@
+/*************************************************************************/
+/* os_linuxbsd.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef OS_LINUXBSD_H
+#define OS_LINUXBSD_H
+
+#include "core/input/input.h"
+#include "crash_handler_linuxbsd.h"
+#include "drivers/alsa/audio_driver_alsa.h"
+#include "drivers/alsamidi/midi_driver_alsamidi.h"
+#include "drivers/pulseaudio/audio_driver_pulseaudio.h"
+#include "drivers/unix/os_unix.h"
+#include "joypad_linux.h"
+#include "servers/audio_server.h"
+#include "servers/visual/rasterizer.h"
+#include "servers/visual_server.h"
+
+class OS_LinuxBSD : public OS_Unix {
+
+ virtual void delete_main_loop();
+
+ bool force_quit;
+
+#ifdef JOYDEV_ENABLED
+ JoypadLinux *joypad;
+#endif
+
+#ifdef ALSA_ENABLED
+ AudioDriverALSA driver_alsa;
+#endif
+
+#ifdef ALSAMIDI_ENABLED
+ MIDIDriverALSAMidi driver_alsamidi;
+#endif
+
+#ifdef PULSEAUDIO_ENABLED
+ AudioDriverPulseAudio driver_pulseaudio;
+#endif
+
+ CrashHandler crash_handler;
+
+ MainLoop *main_loop;
+
+protected:
+ virtual void initialize();
+ virtual void finalize();
+
+ virtual void initialize_joypads();
+
+ virtual void set_main_loop(MainLoop *p_main_loop);
+
+public:
+ virtual String get_name() const;
+
+ virtual MainLoop *get_main_loop() const;
+
+ virtual String get_config_path() const;
+ virtual String get_data_path() const;
+ virtual String get_cache_path() const;
+
+ virtual String get_system_dir(SystemDir p_dir) const;
+
+ virtual Error shell_open(String p_uri);
+
+ virtual String get_unique_id() const;
+
+ virtual bool _check_internal_feature_support(const String &p_feature);
+
+ void run();
+
+ void disable_crash_handler();
+ bool is_disable_crash_handler() const;
+
+ virtual Error move_to_trash(const String &p_path);
+
+ OS_LinuxBSD();
+};
+
+#endif
diff --git a/platform/x11/pck_embed.ld b/platform/linuxbsd/pck_embed.ld
index 57a1994043..57a1994043 100644
--- a/platform/x11/pck_embed.ld
+++ b/platform/linuxbsd/pck_embed.ld
diff --git a/platform/x11/pck_embed.legacy.ld b/platform/linuxbsd/pck_embed.legacy.ld
index a23013ba7a..a23013ba7a 100644
--- a/platform/x11/pck_embed.legacy.ld
+++ b/platform/linuxbsd/pck_embed.legacy.ld
diff --git a/platform/x11/platform_config.h b/platform/linuxbsd/platform_config.h
index ac30519132..ac30519132 100644
--- a/platform/x11/platform_config.h
+++ b/platform/linuxbsd/platform_config.h
diff --git a/platform/x11/platform_x11_builders.py b/platform/linuxbsd/platform_linuxbsd_builders.py
index 5ff0c6fb14..a72306a9c0 100644
--- a/platform/x11/platform_x11_builders.py
+++ b/platform/linuxbsd/platform_linuxbsd_builders.py
@@ -7,7 +7,7 @@ import os
from platform_methods import subprocess_main
-def make_debug_x11(target, source, env):
+def make_debug_linuxbsd(target, source, env):
os.system('objcopy --only-keep-debug {0} {0}.debugsymbols'.format(target[0]))
os.system('strip --strip-debug --strip-unneeded {0}'.format(target[0]))
os.system('objcopy --add-gnu-debuglink={0}.debugsymbols {0}'.format(target[0]))
diff --git a/platform/x11/vulkan_context_x11.cpp b/platform/linuxbsd/vulkan_context_x11.cpp
index 602dbc77a2..602dbc77a2 100644
--- a/platform/x11/vulkan_context_x11.cpp
+++ b/platform/linuxbsd/vulkan_context_x11.cpp
diff --git a/platform/x11/vulkan_context_x11.h b/platform/linuxbsd/vulkan_context_x11.h
index 573f994ea6..573f994ea6 100644
--- a/platform/x11/vulkan_context_x11.h
+++ b/platform/linuxbsd/vulkan_context_x11.h
diff --git a/platform/server/os_server.h b/platform/server/os_server.h
index 63afd68ee8..6bbfe471e0 100644
--- a/platform/server/os_server.h
+++ b/platform/server/os_server.h
@@ -38,7 +38,7 @@
#include "platform/osx/crash_handler_osx.h"
#include "platform/osx/semaphore_osx.h"
#else
-#include "platform/x11/crash_handler_x11.h"
+#include "platform/x11/crash_handler_linuxbsd.h"
#endif
#include "servers/audio_server.h"
#include "servers/visual/rasterizer.h"
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp
deleted file mode 100644
index 8b92af9dda..0000000000
--- a/platform/x11/os_x11.cpp
+++ /dev/null
@@ -1,3568 +0,0 @@
-/*************************************************************************/
-/* os_x11.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "os_x11.h"
-#include "detect_prime.h"
-
-#include "core/os/dir_access.h"
-#include "core/print_string.h"
-#include "errno.h"
-#include "key_mapping_x11.h"
-
-#if defined(OPENGL_ENABLED)
-#include "drivers/gles2/rasterizer_gles2.h"
-#endif
-
-#if defined(VULKAN_ENABLED)
-#include "servers/visual/rasterizer_rd/rasterizer_rd.h"
-#endif
-
-#include "servers/visual/visual_server_raster.h"
-#include "servers/visual/visual_server_wrap_mt.h"
-
-#ifdef HAVE_MNTENT
-#include <mntent.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "X11/Xutil.h"
-
-#include "X11/Xatom.h"
-#include "X11/extensions/Xinerama.h"
-// ICCCM
-#define WM_NormalState 1L // window normal state
-#define WM_IconicState 3L // window minimized
-// EWMH
-#define _NET_WM_STATE_REMOVE 0L // remove/unset property
-#define _NET_WM_STATE_ADD 1L // add/set property
-#define _NET_WM_STATE_TOGGLE 2L // toggle property
-
-#include "main/main.h"
-
-#include <dlfcn.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-//stupid linux.h
-#ifdef KEY_TAB
-#undef KEY_TAB
-#endif
-
-#include <X11/Xatom.h>
-
-#undef CursorShape
-
-#include <X11/XKBlib.h>
-
-// 2.2 is the first release with multitouch
-#define XINPUT_CLIENT_VERSION_MAJOR 2
-#define XINPUT_CLIENT_VERSION_MINOR 2
-
-#define VALUATOR_ABSX 0
-#define VALUATOR_ABSY 1
-#define VALUATOR_PRESSURE 2
-#define VALUATOR_TILTX 3
-#define VALUATOR_TILTY 4
-
-static const double abs_resolution_mult = 10000.0;
-static const double abs_resolution_range_mult = 10.0;
-
-void OS_X11::initialize_core() {
-
- crash_handler.initialize();
-
- OS_Unix::initialize_core();
-}
-
-int OS_X11::get_current_video_driver() const {
- return video_driver_index;
-}
-
-Error OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) {
-
- long im_event_mask = 0;
- last_button_state = 0;
-
- xmbstring = NULL;
- x11_window = 0;
- last_click_ms = 0;
- last_click_button_index = -1;
- last_click_pos = Point2(-100, -100);
- args = OS::get_singleton()->get_cmdline_args();
- current_videomode = p_desired;
- main_loop = NULL;
- last_timestamp = 0;
- last_mouse_pos_valid = false;
- last_keyrelease_time = 0;
- xdnd_version = 0;
-
- if (get_render_thread_mode() == RENDER_SEPARATE_THREAD) {
- XInitThreads();
- }
-
- /** XLIB INITIALIZATION **/
- x11_display = XOpenDisplay(NULL);
-
- if (!x11_display) {
- ERR_PRINT("X11 Display is not available");
- return ERR_UNAVAILABLE;
- }
-
- char *modifiers = NULL;
- Bool xkb_dar = False;
- XAutoRepeatOn(x11_display);
- xkb_dar = XkbSetDetectableAutoRepeat(x11_display, True, NULL);
-
- // Try to support IME if detectable auto-repeat is supported
- if (xkb_dar == True) {
-
-#ifdef X_HAVE_UTF8_STRING
- // Xutf8LookupString will be used later instead of XmbLookupString before
- // the multibyte sequences can be converted to unicode string.
- modifiers = XSetLocaleModifiers("");
-#endif
- }
-
- if (modifiers == NULL) {
- if (is_stdout_verbose()) {
- WARN_PRINT("IME is disabled");
- }
- XSetLocaleModifiers("@im=none");
- WARN_PRINT("Error setting locale modifiers");
- }
-
- const char *err;
- xrr_get_monitors = NULL;
- xrr_free_monitors = NULL;
- int xrandr_major = 0;
- int xrandr_minor = 0;
- int event_base, error_base;
- xrandr_ext_ok = XRRQueryExtension(x11_display, &event_base, &error_base);
- xrandr_handle = dlopen("libXrandr.so.2", RTLD_LAZY);
- if (!xrandr_handle) {
- err = dlerror();
- fprintf(stderr, "could not load libXrandr.so.2, Error: %s\n", err);
- } else {
- XRRQueryVersion(x11_display, &xrandr_major, &xrandr_minor);
- if (((xrandr_major << 8) | xrandr_minor) >= 0x0105) {
- xrr_get_monitors = (xrr_get_monitors_t)dlsym(xrandr_handle, "XRRGetMonitors");
- if (!xrr_get_monitors) {
- err = dlerror();
- fprintf(stderr, "could not find symbol XRRGetMonitors\nError: %s\n", err);
- } else {
- xrr_free_monitors = (xrr_free_monitors_t)dlsym(xrandr_handle, "XRRFreeMonitors");
- if (!xrr_free_monitors) {
- err = dlerror();
- fprintf(stderr, "could not find XRRFreeMonitors\nError: %s\n", err);
- xrr_get_monitors = NULL;
- }
- }
- }
- }
-
- if (!refresh_device_info()) {
- OS::get_singleton()->alert("Your system does not support XInput 2.\n"
- "Please upgrade your distribution.",
- "Unable to initialize XInput");
- return ERR_UNAVAILABLE;
- }
-
- xim = XOpenIM(x11_display, NULL, NULL, NULL);
-
- if (xim == NULL) {
- WARN_PRINT("XOpenIM failed");
- xim_style = 0L;
- } else {
- ::XIMCallback im_destroy_callback;
- im_destroy_callback.client_data = (::XPointer)(this);
- im_destroy_callback.callback = (::XIMProc)(xim_destroy_callback);
- if (XSetIMValues(xim, XNDestroyCallback, &im_destroy_callback,
- NULL) != NULL) {
- WARN_PRINT("Error setting XIM destroy callback");
- }
-
- ::XIMStyles *xim_styles = NULL;
- xim_style = 0L;
- char *imvalret = XGetIMValues(xim, XNQueryInputStyle, &xim_styles, NULL);
- if (imvalret != NULL || xim_styles == NULL) {
- fprintf(stderr, "Input method doesn't support any styles\n");
- }
-
- if (xim_styles) {
- xim_style = 0L;
- for (int i = 0; i < xim_styles->count_styles; i++) {
-
- if (xim_styles->supported_styles[i] ==
- (XIMPreeditNothing | XIMStatusNothing)) {
-
- xim_style = xim_styles->supported_styles[i];
- break;
- }
- }
-
- XFree(xim_styles);
- }
- XFree(imvalret);
- }
-
- //!!!!!!!!!!!!!!!!!!!!!!!!!!
- //TODO - do Vulkan and GLES2 support checks, driver selection and fallback
- video_driver_index = p_video_driver;
-#ifndef _MSC_VER
-#warning Forcing vulkan video driver because OpenGL not implemented yet
-#endif
- video_driver_index = VIDEO_DRIVER_VULKAN;
-
- print_verbose("Driver: " + String(get_video_driver_name(video_driver_index)) + " [" + itos(video_driver_index) + "]");
- //!!!!!!!!!!!!!!!!!!!!!!!!!!
-
- //Create window
-
- long visualMask = VisualScreenMask;
- int numberOfVisuals;
- XVisualInfo vInfoTemplate = {};
- vInfoTemplate.screen = DefaultScreen(x11_display);
- XVisualInfo *visualInfo = XGetVisualInfo(x11_display, visualMask, &vInfoTemplate, &numberOfVisuals);
-
- Colormap colormap = XCreateColormap(x11_display, RootWindow(x11_display, vInfoTemplate.screen), visualInfo->visual, AllocNone);
-
- XSetWindowAttributes windowAttributes = {};
- windowAttributes.colormap = colormap;
- windowAttributes.background_pixel = 0xFFFFFFFF;
- windowAttributes.border_pixel = 0;
- windowAttributes.event_mask = KeyPressMask | KeyReleaseMask | StructureNotifyMask | ExposureMask;
-
- unsigned long valuemask = CWBorderPixel | CWColormap | CWEventMask;
- x11_window = XCreateWindow(x11_display, RootWindow(x11_display, visualInfo->screen), 0, 0, OS::get_singleton()->get_video_mode().width, OS::get_singleton()->get_video_mode().height, 0, visualInfo->depth, InputOutput, visualInfo->visual, valuemask, &windowAttributes);
-
- wm_delete = XInternAtom(x11_display, "WM_DELETE_WINDOW", true);
- XSetWMProtocols(x11_display, x11_window, &wm_delete, 1);
-
- //set_class_hint(x11_display, x11_window);
- XMapWindow(x11_display, x11_window);
- XFlush(x11_display);
-
- XSync(x11_display, False);
- //XSetErrorHandler(oldHandler);
-
- XFree(visualInfo);
-
- // Init context and rendering device
-#if defined(OPENGL_ENABLED)
- if (video_driver_index == VIDEO_DRIVER_GLES2) {
- if (getenv("DRI_PRIME") == NULL) {
- int use_prime = -1;
-
- if (getenv("PRIMUS_DISPLAY") ||
- getenv("PRIMUS_libGLd") ||
- getenv("PRIMUS_libGLa") ||
- getenv("PRIMUS_libGL") ||
- getenv("PRIMUS_LOAD_GLOBAL") ||
- getenv("BUMBLEBEE_SOCKET")) {
-
- print_verbose("Optirun/primusrun detected. Skipping GPU detection");
- use_prime = 0;
- }
-
- if (getenv("LD_LIBRARY_PATH")) {
- String ld_library_path(getenv("LD_LIBRARY_PATH"));
- Vector<String> libraries = ld_library_path.split(":");
-
- for (int i = 0; i < libraries.size(); ++i) {
- if (FileAccess::exists(libraries[i] + "/libGL.so.1") ||
- FileAccess::exists(libraries[i] + "/libGL.so")) {
-
- print_verbose("Custom libGL override detected. Skipping GPU detection");
- use_prime = 0;
- }
- }
- }
-
- if (use_prime == -1) {
- print_verbose("Detecting GPUs, set DRI_PRIME in the environment to override GPU detection logic.");
- use_prime = detect_prime();
- }
-
- if (use_prime) {
- print_line("Found discrete GPU, setting DRI_PRIME=1 to use it.");
- print_line("Note: Set DRI_PRIME=0 in the environment to disable Godot from using the discrete GPU.");
- setenv("DRI_PRIME", "1", 1);
- }
- }
-
- ContextGL_X11::ContextType opengl_api_type = ContextGL_X11::GLES_2_0_COMPATIBLE;
-
- context_gles2 = memnew(ContextGL_X11(x11_display, x11_window, current_videomode, opengl_api_type));
-
- if (context_gles2->initialize() != OK) {
- memdelete(context_gles2);
- context_gles2 = NULL;
- ERR_FAIL_V(ERR_UNAVAILABLE);
- }
-
- context_gles2->set_use_vsync(current_videomode.use_vsync);
-
- if (RasterizerGLES2::is_viable() == OK) {
- RasterizerGLES2::register_config();
- RasterizerGLES2::make_current();
- } else {
- memdelete(context_gles2);
- context_gles2 = NULL;
- ERR_FAIL_V(ERR_UNAVAILABLE);
- }
- }
-#endif
-#if defined(VULKAN_ENABLED)
- if (video_driver_index == VIDEO_DRIVER_VULKAN) {
-
- context_vulkan = memnew(VulkanContextX11);
- if (context_vulkan->initialize() != OK) {
- memdelete(context_vulkan);
- context_vulkan = NULL;
- ERR_FAIL_V(ERR_UNAVAILABLE);
- }
- if (context_vulkan->window_create(x11_window, x11_display, get_video_mode().width, get_video_mode().height) == -1) {
- memdelete(context_vulkan);
- context_vulkan = NULL;
- ERR_FAIL_V(ERR_UNAVAILABLE);
- }
-
- //temporary
- rendering_device_vulkan = memnew(RenderingDeviceVulkan);
- rendering_device_vulkan->initialize(context_vulkan);
-
- RasterizerRD::make_current();
- }
-#endif
-
- visual_server = memnew(VisualServerRaster);
- if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {
- visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD));
- }
-
- if (current_videomode.maximized) {
- current_videomode.maximized = false;
- set_window_maximized(true);
- // borderless fullscreen window mode
- } else if (current_videomode.fullscreen) {
- current_videomode.fullscreen = false;
- set_window_fullscreen(true);
- } else if (current_videomode.borderless_window) {
- Hints hints;
- Atom property;
- hints.flags = 2;
- hints.decorations = 0;
- property = XInternAtom(x11_display, "_MOTIF_WM_HINTS", True);
- XChangeProperty(x11_display, x11_window, property, property, 32, PropModeReplace, (unsigned char *)&hints, 5);
- }
-
- // make PID known to X11
- {
- const long pid = this->get_process_id();
- Atom net_wm_pid = XInternAtom(x11_display, "_NET_WM_PID", False);
- XChangeProperty(x11_display, x11_window, net_wm_pid, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&pid, 1);
- }
-
- // disable resizable window
- if (!current_videomode.resizable && !current_videomode.fullscreen) {
- XSizeHints *xsh;
- xsh = XAllocSizeHints();
- xsh->flags = PMinSize | PMaxSize;
- XWindowAttributes xwa;
- if (current_videomode.fullscreen) {
- XGetWindowAttributes(x11_display, DefaultRootWindow(x11_display), &xwa);
- } else {
- XGetWindowAttributes(x11_display, x11_window, &xwa);
- }
- xsh->min_width = xwa.width;
- xsh->max_width = xwa.width;
- xsh->min_height = xwa.height;
- xsh->max_height = xwa.height;
- XSetWMNormalHints(x11_display, x11_window, xsh);
- XFree(xsh);
- }
-
- if (current_videomode.always_on_top) {
- current_videomode.always_on_top = false;
- set_window_always_on_top(true);
- }
-
- ERR_FAIL_COND_V(!visual_server, ERR_UNAVAILABLE);
- ERR_FAIL_COND_V(x11_window == 0, ERR_UNAVAILABLE);
-
- 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;
-
- XChangeWindowAttributes(x11_display, x11_window, CWEventMask, &new_attr);
-
- static unsigned char all_mask_data[XIMaskLen(XI_LASTEVENT)] = {};
- static unsigned char all_master_mask_data[XIMaskLen(XI_LASTEVENT)] = {};
-
- xi.all_event_mask.deviceid = XIAllDevices;
- xi.all_event_mask.mask_len = sizeof(all_mask_data);
- xi.all_event_mask.mask = all_mask_data;
-
- xi.all_master_event_mask.deviceid = XIAllMasterDevices;
- xi.all_master_event_mask.mask_len = sizeof(all_master_mask_data);
- xi.all_master_event_mask.mask = all_master_mask_data;
-
- XISetMask(xi.all_event_mask.mask, XI_HierarchyChanged);
- XISetMask(xi.all_master_event_mask.mask, XI_DeviceChanged);
- XISetMask(xi.all_master_event_mask.mask, XI_RawMotion);
-
-#ifdef TOUCH_ENABLED
- if (xi.touch_devices.size()) {
- XISetMask(xi.all_event_mask.mask, XI_TouchBegin);
- XISetMask(xi.all_event_mask.mask, XI_TouchUpdate);
- XISetMask(xi.all_event_mask.mask, XI_TouchEnd);
- XISetMask(xi.all_event_mask.mask, XI_TouchOwnership);
- }
-#endif
-
- XISelectEvents(x11_display, x11_window, &xi.all_event_mask, 1);
- XISelectEvents(x11_display, DefaultRootWindow(x11_display), &xi.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);
- }*/
-
- /* set the titlebar name */
- XStoreName(x11_display, x11_window, "Godot");
-
- im_active = false;
- im_position = Vector2();
-
- if (xim && xim_style) {
-
- xic = XCreateIC(xim, XNInputStyle, xim_style, XNClientWindow, x11_window, XNFocusWindow, x11_window, (char *)NULL);
- if (XGetICValues(xic, XNFilterEvents, &im_event_mask, NULL) != NULL) {
- WARN_PRINT("XGetICValues couldn't obtain XNFilterEvents value");
- XDestroyIC(xic);
- xic = NULL;
- }
- if (xic) {
- XUnsetICFocus(xic);
- } else {
- WARN_PRINT("XCreateIC couldn't create xic");
- }
- } else {
-
- xic = NULL;
- WARN_PRINT("XCreateIC couldn't create xic");
- }
-
- cursor_size = XcursorGetDefaultSize(x11_display);
- cursor_theme = XcursorGetTheme(x11_display);
-
- if (!cursor_theme) {
- print_verbose("XcursorGetTheme could not get cursor theme");
- cursor_theme = "default";
- }
-
- for (int i = 0; i < CURSOR_MAX; i++) {
-
- cursors[i] = None;
- img[i] = NULL;
- }
-
- current_cursor = CURSOR_ARROW;
-
- for (int i = 0; i < CURSOR_MAX; i++) {
-
- static const char *cursor_file[] = {
- "left_ptr",
- "xterm",
- "hand2",
- "cross",
- "watch",
- "left_ptr_watch",
- "fleur",
- "dnd-move",
- "crossed_circle",
- "v_double_arrow",
- "h_double_arrow",
- "size_bdiag",
- "size_fdiag",
- "move",
- "row_resize",
- "col_resize",
- "question_arrow"
- };
-
- img[i] = XcursorLibraryLoadImage(cursor_file[i], cursor_theme, cursor_size);
- if (!img[i]) {
- const char *fallback = NULL;
-
- switch (i) {
- case CURSOR_POINTING_HAND:
- fallback = "pointer";
- break;
- case CURSOR_CROSS:
- fallback = "crosshair";
- break;
- case CURSOR_WAIT:
- fallback = "wait";
- break;
- case CURSOR_BUSY:
- fallback = "progress";
- break;
- case CURSOR_DRAG:
- fallback = "grabbing";
- break;
- case CURSOR_CAN_DROP:
- fallback = "hand1";
- break;
- case CURSOR_FORBIDDEN:
- fallback = "forbidden";
- break;
- case CURSOR_VSIZE:
- fallback = "ns-resize";
- break;
- case CURSOR_HSIZE:
- fallback = "ew-resize";
- break;
- case CURSOR_BDIAGSIZE:
- fallback = "fd_double_arrow";
- break;
- case CURSOR_FDIAGSIZE:
- fallback = "bd_double_arrow";
- break;
- case CURSOR_MOVE:
- img[i] = img[CURSOR_DRAG];
- break;
- case CURSOR_VSPLIT:
- fallback = "sb_v_double_arrow";
- break;
- case CURSOR_HSPLIT:
- fallback = "sb_h_double_arrow";
- break;
- case CURSOR_HELP:
- fallback = "help";
- break;
- }
- if (fallback != NULL) {
- img[i] = XcursorLibraryLoadImage(fallback, cursor_theme, cursor_size);
- }
- }
- if (img[i]) {
- cursors[i] = XcursorImageLoadCursor(x11_display, img[i]);
- } else {
- print_verbose("Failed loading custom cursor: " + String(cursor_file[i]));
- }
- }
-
- {
- // Creating an empty/transparent cursor
-
- // Create 1x1 bitmap
- Pixmap cursormask = XCreatePixmap(x11_display,
- RootWindow(x11_display, DefaultScreen(x11_display)), 1, 1, 1);
-
- // Fill with zero
- XGCValues xgc;
- xgc.function = GXclear;
- GC gc = XCreateGC(x11_display, cursormask, GCFunction, &xgc);
- XFillRectangle(x11_display, cursormask, gc, 0, 0, 1, 1);
-
- // Color value doesn't matter. Mask zero means no foreground or background will be drawn
- XColor col = {};
-
- Cursor cursor = XCreatePixmapCursor(x11_display,
- cursormask, // source (using cursor mask as placeholder, since it'll all be ignored)
- cursormask, // mask
- &col, &col, 0, 0);
-
- XFreePixmap(x11_display, cursormask);
- XFreeGC(x11_display, gc);
-
- if (cursor == None) {
- ERR_PRINT("FAILED CREATING CURSOR");
- }
-
- null_cursor = cursor;
- }
- set_cursor_shape(CURSOR_BUSY);
-
- //Set Xdnd (drag & drop) support
- Atom XdndAware = XInternAtom(x11_display, "XdndAware", False);
- Atom version = 5;
- XChangeProperty(x11_display, x11_window, XdndAware, XA_ATOM, 32, PropModeReplace, (unsigned char *)&version, 1);
-
- xdnd_enter = XInternAtom(x11_display, "XdndEnter", False);
- xdnd_position = XInternAtom(x11_display, "XdndPosition", False);
- xdnd_status = XInternAtom(x11_display, "XdndStatus", False);
- xdnd_action_copy = XInternAtom(x11_display, "XdndActionCopy", False);
- xdnd_drop = XInternAtom(x11_display, "XdndDrop", False);
- xdnd_finished = XInternAtom(x11_display, "XdndFinished", False);
- xdnd_selection = XInternAtom(x11_display, "XdndSelection", False);
- requested = None;
-
- visual_server->init();
-
- AudioDriverManager::initialize(p_audio_driver);
-
- input = memnew(Input);
-
- window_has_focus = true; // Set focus to true at init
-#ifdef JOYDEV_ENABLED
- joypad = memnew(JoypadLinux(input));
-#endif
- _ensure_user_data_dir();
-
- if (p_desired.layered) {
- set_window_per_pixel_transparency_enabled(true);
- }
-
- XEvent xevent;
- while (XPending(x11_display) > 0) {
- XNextEvent(x11_display, &xevent);
- if (xevent.type == ConfigureNotify) {
- _window_changed(&xevent);
- }
- }
-
- update_real_mouse_position();
-
- return OK;
-}
-
-bool OS_X11::refresh_device_info() {
- int event_base, error_base;
-
- print_verbose("XInput: Refreshing devices.");
-
- if (!XQueryExtension(x11_display, "XInputExtension", &xi.opcode, &event_base, &error_base)) {
- print_verbose("XInput extension not available. Please upgrade your distribution.");
- return false;
- }
-
- int xi_major_query = XINPUT_CLIENT_VERSION_MAJOR;
- int xi_minor_query = XINPUT_CLIENT_VERSION_MINOR;
-
- if (XIQueryVersion(x11_display, &xi_major_query, &xi_minor_query) != Success) {
- print_verbose(vformat("XInput 2 not available (server supports %d.%d).", xi_major_query, xi_minor_query));
- xi.opcode = 0;
- return false;
- }
-
- if (xi_major_query < XINPUT_CLIENT_VERSION_MAJOR || (xi_major_query == XINPUT_CLIENT_VERSION_MAJOR && xi_minor_query < XINPUT_CLIENT_VERSION_MINOR)) {
- print_verbose(vformat("XInput %d.%d not available (server supports %d.%d). Touch input unavailable.",
- XINPUT_CLIENT_VERSION_MAJOR, XINPUT_CLIENT_VERSION_MINOR, xi_major_query, xi_minor_query));
- }
-
- xi.absolute_devices.clear();
- xi.touch_devices.clear();
-
- int dev_count;
- XIDeviceInfo *info = XIQueryDevice(x11_display, XIAllDevices, &dev_count);
-
- for (int i = 0; i < dev_count; i++) {
- XIDeviceInfo *dev = &info[i];
- if (!dev->enabled)
- continue;
- if (!(dev->use == XIMasterPointer || dev->use == XIFloatingSlave))
- continue;
-
- bool direct_touch = false;
- bool absolute_mode = false;
- int resolution_x = 0;
- int resolution_y = 0;
- int range_min_x = 0;
- int range_min_y = 0;
- int range_max_x = 0;
- int range_max_y = 0;
- int pressure_resolution = 0;
- int tilt_resolution_x = 0;
- int tilt_resolution_y = 0;
- for (int j = 0; j < dev->num_classes; j++) {
-#ifdef TOUCH_ENABLED
- if (dev->classes[j]->type == XITouchClass && ((XITouchClassInfo *)dev->classes[j])->mode == XIDirectTouch) {
- direct_touch = true;
- }
-#endif
- if (dev->classes[j]->type == XIValuatorClass) {
- XIValuatorClassInfo *class_info = (XIValuatorClassInfo *)dev->classes[j];
-
- if (class_info->number == VALUATOR_ABSX && class_info->mode == XIModeAbsolute) {
- resolution_x = class_info->resolution;
- range_min_x = class_info->min;
- range_max_x = class_info->max;
- absolute_mode = true;
- } else if (class_info->number == VALUATOR_ABSY && class_info->mode == XIModeAbsolute) {
- resolution_y = class_info->resolution;
- range_min_y = class_info->min;
- range_max_y = class_info->max;
- absolute_mode = true;
- } else if (class_info->number == VALUATOR_PRESSURE && class_info->mode == XIModeAbsolute) {
- pressure_resolution = (class_info->max - class_info->min);
- if (pressure_resolution == 0) pressure_resolution = 1;
- } else if (class_info->number == VALUATOR_TILTX && class_info->mode == XIModeAbsolute) {
- tilt_resolution_x = (class_info->max - class_info->min);
- if (tilt_resolution_x == 0) tilt_resolution_x = 1;
- } else if (class_info->number == VALUATOR_TILTY && class_info->mode == XIModeAbsolute) {
- tilt_resolution_y = (class_info->max - class_info->min);
- if (tilt_resolution_y == 0) tilt_resolution_y = 1;
- }
- }
- }
- if (direct_touch) {
- xi.touch_devices.push_back(dev->deviceid);
- print_verbose("XInput: Using touch device: " + String(dev->name));
- }
- if (absolute_mode) {
- // If no resolution was reported, use the min/max ranges.
- if (resolution_x <= 0) {
- resolution_x = (range_max_x - range_min_x) * abs_resolution_range_mult;
- }
- if (resolution_y <= 0) {
- resolution_y = (range_max_y - range_min_y) * abs_resolution_range_mult;
- }
-
- xi.absolute_devices[dev->deviceid] = Vector2(abs_resolution_mult / resolution_x, abs_resolution_mult / resolution_y);
- print_verbose("XInput: Absolute pointing device: " + String(dev->name));
- }
-
- xi.pressure = 0;
- xi.pen_devices[dev->deviceid] = Vector3(pressure_resolution, tilt_resolution_x, tilt_resolution_y);
- }
-
- XIFreeDeviceInfo(info);
-#ifdef TOUCH_ENABLED
- if (!xi.touch_devices.size()) {
- print_verbose("XInput: No touch devices found.");
- }
-#endif
-
- return true;
-}
-
-void OS_X11::xim_destroy_callback(::XIM im, ::XPointer client_data,
- ::XPointer call_data) {
-
- WARN_PRINT("Input method stopped");
- OS_X11 *os = reinterpret_cast<OS_X11 *>(client_data);
- os->xim = NULL;
- os->xic = NULL;
-}
-
-void OS_X11::set_ime_active(const bool p_active) {
-
- im_active = p_active;
-
- if (!xic)
- return;
-
- if (p_active) {
- XSetICFocus(xic);
- set_ime_position(im_position);
- } else {
- XUnsetICFocus(xic);
- }
-}
-
-void OS_X11::set_ime_position(const Point2 &p_pos) {
-
- im_position = p_pos;
-
- if (!xic)
- return;
-
- ::XPoint spot;
- spot.x = short(p_pos.x);
- spot.y = short(p_pos.y);
- XVaNestedList preedit_attr = XVaCreateNestedList(0, XNSpotLocation, &spot, NULL);
- XSetICValues(xic, XNPreeditAttributes, preedit_attr, NULL);
- XFree(preedit_attr);
-}
-
-String OS_X11::get_unique_id() const {
-
- static String machine_id;
- if (machine_id.empty()) {
- if (FileAccess *f = FileAccess::open("/etc/machine-id", FileAccess::READ)) {
- while (machine_id.empty() && !f->eof_reached()) {
- machine_id = f->get_line().strip_edges();
- }
- f->close();
- memdelete(f);
- }
- }
- return machine_id;
-}
-
-void OS_X11::finalize() {
-
- if (main_loop)
- memdelete(main_loop);
- main_loop = NULL;
-
- /*
- if (debugger_connection_console) {
- memdelete(debugger_connection_console);
- }
- */
-#ifdef ALSAMIDI_ENABLED
- driver_alsamidi.close();
-#endif
-
-#ifdef JOYDEV_ENABLED
- memdelete(joypad);
-#endif
-
- xi.touch_devices.clear();
- xi.state.clear();
-
- memdelete(input);
-
- cursors_cache.clear();
- visual_server->finish();
- memdelete(visual_server);
-
-#if defined(OPENGL_ENABLED)
- if (video_driver_index == VIDEO_DRIVER_GLES2) {
-
- if (context_gles2)
- memdelete(context_gles2);
- }
-#endif
-#if defined(VULKAN_ENABLED)
- if (video_driver_index == VIDEO_DRIVER_VULKAN) {
-
- if (rendering_device_vulkan) {
- rendering_device_vulkan->finalize();
- memdelete(rendering_device_vulkan);
- }
-
- if (context_vulkan)
- memdelete(context_vulkan);
- }
-#endif
-
- if (xrandr_handle)
- dlclose(xrandr_handle);
-
- XUnmapWindow(x11_display, x11_window);
- XDestroyWindow(x11_display, x11_window);
-
- for (int i = 0; i < CURSOR_MAX; i++) {
- if (cursors[i] != None)
- XFreeCursor(x11_display, cursors[i]);
- if (img[i] != NULL)
- XcursorImageDestroy(img[i]);
- };
-
- if (xic) {
- XDestroyIC(xic);
- }
- if (xim) {
- XCloseIM(xim);
- }
-
- XCloseDisplay(x11_display);
- if (xmbstring)
- memfree(xmbstring);
-
- args.clear();
-}
-
-void OS_X11::set_mouse_mode(MouseMode p_mode) {
-
- if (p_mode == mouse_mode)
- return;
-
- if (mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED)
- XUngrabPointer(x11_display, CurrentTime);
-
- // The only modes that show a cursor are VISIBLE and CONFINED
- bool showCursor = (p_mode == MOUSE_MODE_VISIBLE || p_mode == MOUSE_MODE_CONFINED);
-
- if (showCursor) {
- XDefineCursor(x11_display, x11_window, cursors[current_cursor]); // show cursor
- } else {
- XDefineCursor(x11_display, x11_window, null_cursor); // hide cursor
- }
-
- mouse_mode = p_mode;
-
- if (mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED) {
-
- //flush pending motion events
- flush_mouse_motion();
-
- if (XGrabPointer(
- x11_display, x11_window, True,
- ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
- GrabModeAsync, GrabModeAsync, x11_window, None, CurrentTime) != GrabSuccess) {
- ERR_PRINT("NO GRAB");
- }
-
- if (mouse_mode == MOUSE_MODE_CAPTURED) {
- center.x = current_videomode.width / 2;
- center.y = current_videomode.height / 2;
-
- XWarpPointer(x11_display, None, x11_window,
- 0, 0, 0, 0, (int)center.x, (int)center.y);
-
- input->set_mouse_position(center);
- }
- } else {
- do_mouse_warp = false;
- }
-
- XFlush(x11_display);
-}
-
-void OS_X11::warp_mouse_position(const Point2 &p_to) {
-
- if (mouse_mode == MOUSE_MODE_CAPTURED) {
-
- last_mouse_pos = p_to;
- } else {
-
- /*XWindowAttributes xwa;
- XGetWindowAttributes(x11_display, x11_window, &xwa);
- printf("%d %d\n", xwa.x, xwa.y); needed? */
-
- XWarpPointer(x11_display, None, x11_window,
- 0, 0, 0, 0, (int)p_to.x, (int)p_to.y);
- }
-}
-
-void OS_X11::flush_mouse_motion() {
- while (true) {
- if (XPending(x11_display) > 0) {
- XEvent event;
- XPeekEvent(x11_display, &event);
-
- if (XGetEventData(x11_display, &event.xcookie) && event.xcookie.type == GenericEvent && event.xcookie.extension == xi.opcode) {
- XIDeviceEvent *event_data = (XIDeviceEvent *)event.xcookie.data;
-
- if (event_data->evtype == XI_RawMotion) {
- XNextEvent(x11_display, &event);
- } else {
- break;
- }
- } else {
- break;
- }
- } else {
- break;
- }
- }
-
- xi.relative_motion.x = 0;
- xi.relative_motion.y = 0;
-}
-
-OS::MouseMode OS_X11::get_mouse_mode() const {
- return mouse_mode;
-}
-
-int OS_X11::get_mouse_button_state() const {
- return last_button_state;
-}
-
-Point2 OS_X11::get_mouse_position() const {
- return last_mouse_pos;
-}
-
-bool OS_X11::get_window_per_pixel_transparency_enabled() const {
-
- if (!is_layered_allowed()) return false;
- return layered_window;
-}
-
-void OS_X11::set_window_per_pixel_transparency_enabled(bool p_enabled) {
-
- if (!is_layered_allowed()) return;
- if (layered_window != p_enabled) {
- if (p_enabled) {
- set_borderless_window(true);
- layered_window = true;
- } else {
- layered_window = false;
- }
- }
-}
-
-void OS_X11::set_window_title(const String &p_title) {
- XStoreName(x11_display, x11_window, p_title.utf8().get_data());
-
- Atom _net_wm_name = XInternAtom(x11_display, "_NET_WM_NAME", false);
- Atom utf8_string = XInternAtom(x11_display, "UTF8_STRING", false);
- XChangeProperty(x11_display, x11_window, _net_wm_name, utf8_string, 8, PropModeReplace, (unsigned char *)p_title.utf8().get_data(), p_title.utf8().length());
-}
-
-void OS_X11::set_video_mode(const VideoMode &p_video_mode, int p_screen) {
-}
-
-OS::VideoMode OS_X11::get_video_mode(int p_screen) const {
- return current_videomode;
-}
-
-void OS_X11::get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen) const {
-}
-
-void OS_X11::set_wm_fullscreen(bool p_enabled) {
- if (p_enabled && !get_borderless_window()) {
- // remove decorations if the window is not already borderless
- Hints hints;
- Atom property;
- hints.flags = 2;
- hints.decorations = 0;
- property = XInternAtom(x11_display, "_MOTIF_WM_HINTS", True);
- XChangeProperty(x11_display, x11_window, property, property, 32, PropModeReplace, (unsigned char *)&hints, 5);
- }
-
- if (p_enabled && !is_window_resizable()) {
- // Set the window as resizable to prevent window managers to ignore the fullscreen state flag.
- XSizeHints *xsh;
-
- xsh = XAllocSizeHints();
- xsh->flags = 0L;
- XSetWMNormalHints(x11_display, x11_window, xsh);
- XFree(xsh);
- }
-
- // Using EWMH -- Extended Window Manager Hints
- XEvent xev;
- Atom wm_state = XInternAtom(x11_display, "_NET_WM_STATE", False);
- Atom wm_fullscreen = XInternAtom(x11_display, "_NET_WM_STATE_FULLSCREEN", False);
-
- memset(&xev, 0, sizeof(xev));
- xev.type = ClientMessage;
- xev.xclient.window = x11_window;
- xev.xclient.message_type = wm_state;
- xev.xclient.format = 32;
- xev.xclient.data.l[0] = p_enabled ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
- xev.xclient.data.l[1] = wm_fullscreen;
- xev.xclient.data.l[2] = 0;
-
- XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
-
- // set bypass compositor hint
- Atom bypass_compositor = XInternAtom(x11_display, "_NET_WM_BYPASS_COMPOSITOR", False);
- unsigned long compositing_disable_on = p_enabled ? 1 : 0;
- XChangeProperty(x11_display, x11_window, bypass_compositor, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&compositing_disable_on, 1);
-
- XFlush(x11_display);
-
- if (!p_enabled) {
- // Reset the non-resizable flags if we un-set these before.
- Size2 size = get_window_size();
- XSizeHints *xsh;
- xsh = XAllocSizeHints();
- if (!is_window_resizable()) {
- xsh->flags = PMinSize | PMaxSize;
- xsh->min_width = size.x;
- xsh->max_width = size.x;
- xsh->min_height = size.y;
- xsh->max_height = size.y;
- } else {
- xsh->flags = 0L;
- if (min_size != Size2()) {
- xsh->flags |= PMinSize;
- xsh->min_width = min_size.x;
- xsh->min_height = min_size.y;
- }
- if (max_size != Size2()) {
- xsh->flags |= PMaxSize;
- xsh->max_width = max_size.x;
- xsh->max_height = max_size.y;
- }
- }
- XSetWMNormalHints(x11_display, x11_window, xsh);
- XFree(xsh);
-
- // put back or remove decorations according to the last set borderless state
- Hints hints;
- Atom property;
- hints.flags = 2;
- hints.decorations = current_videomode.borderless_window ? 0 : 1;
- property = XInternAtom(x11_display, "_MOTIF_WM_HINTS", True);
- XChangeProperty(x11_display, x11_window, property, property, 32, PropModeReplace, (unsigned char *)&hints, 5);
- }
-}
-
-void OS_X11::set_wm_above(bool p_enabled) {
- Atom wm_state = XInternAtom(x11_display, "_NET_WM_STATE", False);
- Atom wm_above = XInternAtom(x11_display, "_NET_WM_STATE_ABOVE", False);
-
- XClientMessageEvent xev;
- memset(&xev, 0, sizeof(xev));
- xev.type = ClientMessage;
- xev.window = x11_window;
- xev.message_type = wm_state;
- xev.format = 32;
- xev.data.l[0] = p_enabled ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
- xev.data.l[1] = wm_above;
- xev.data.l[3] = 1;
- XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureRedirectMask | SubstructureNotifyMask, (XEvent *)&xev);
-}
-
-int OS_X11::get_screen_count() const {
- // Using Xinerama Extension
- int event_base, error_base;
- const Bool ext_okay = XineramaQueryExtension(x11_display, &event_base, &error_base);
- if (!ext_okay) return 0;
-
- int count;
- XineramaScreenInfo *xsi = XineramaQueryScreens(x11_display, &count);
- XFree(xsi);
- return count;
-}
-
-int OS_X11::get_current_screen() const {
- int x, y;
- Window child;
- XTranslateCoordinates(x11_display, x11_window, DefaultRootWindow(x11_display), 0, 0, &x, &y, &child);
-
- int count = get_screen_count();
- for (int i = 0; i < count; i++) {
- Point2i pos = get_screen_position(i);
- Size2i size = get_screen_size(i);
- if ((x >= pos.x && x < pos.x + size.width) && (y >= pos.y && y < pos.y + size.height))
- return i;
- }
- return 0;
-}
-
-void OS_X11::set_current_screen(int p_screen) {
- int count = get_screen_count();
- if (p_screen >= count) return;
-
- if (current_videomode.fullscreen) {
- Point2i position = get_screen_position(p_screen);
- Size2i size = get_screen_size(p_screen);
-
- XMoveResizeWindow(x11_display, x11_window, position.x, position.y, size.x, size.y);
- } else {
- if (p_screen != get_current_screen()) {
- Point2i position = get_screen_position(p_screen);
- XMoveWindow(x11_display, x11_window, position.x, position.y);
- }
- }
-}
-
-Point2 OS_X11::get_screen_position(int p_screen) const {
- if (p_screen == -1) {
- p_screen = 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 Point2i(0, 0);
- }
-
- int count;
- XineramaScreenInfo *xsi = XineramaQueryScreens(x11_display, &count);
- if (p_screen >= count) {
- return Point2i(0, 0);
- }
-
- Point2i position = Point2i(xsi[p_screen].x_org, xsi[p_screen].y_org);
-
- XFree(xsi);
-
- return position;
-}
-
-Size2 OS_X11::get_screen_size(int p_screen) const {
- if (p_screen == -1) {
- p_screen = 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 Size2i(0, 0);
-
- int count;
- XineramaScreenInfo *xsi = XineramaQueryScreens(x11_display, &count);
- if (p_screen >= count) return Size2i(0, 0);
-
- Size2i size = Point2i(xsi[p_screen].width, xsi[p_screen].height);
- XFree(xsi);
- return size;
-}
-
-int OS_X11::get_screen_dpi(int p_screen) const {
- if (p_screen == -1) {
- p_screen = get_current_screen();
- }
-
- //invalid screen?
- ERR_FAIL_INDEX_V(p_screen, get_screen_count(), 0);
-
- //Get physical monitor Dimensions through XRandR and calculate dpi
- Size2 sc = get_screen_size(p_screen);
- if (xrandr_ext_ok) {
- int count = 0;
- if (xrr_get_monitors) {
- xrr_monitor_info *monitors = xrr_get_monitors(x11_display, x11_window, true, &count);
- if (p_screen < count) {
- double xdpi = sc.width / (double)monitors[p_screen].mwidth * 25.4;
- double ydpi = sc.height / (double)monitors[p_screen].mheight * 25.4;
- xrr_free_monitors(monitors);
- return (xdpi + ydpi) / 2;
- }
- xrr_free_monitors(monitors);
- } else if (p_screen == 0) {
- XRRScreenSize *sizes = XRRSizes(x11_display, 0, &count);
- if (sizes) {
- double xdpi = sc.width / (double)sizes[0].mwidth * 25.4;
- double ydpi = sc.height / (double)sizes[0].mheight * 25.4;
- return (xdpi + ydpi) / 2;
- }
- }
- }
-
- int width_mm = DisplayWidthMM(x11_display, p_screen);
- int height_mm = DisplayHeightMM(x11_display, p_screen);
- double xdpi = (width_mm ? sc.width / (double)width_mm * 25.4 : 0);
- double ydpi = (height_mm ? sc.height / (double)height_mm * 25.4 : 0);
- if (xdpi || ydpi)
- return (xdpi + ydpi) / (xdpi && ydpi ? 2 : 1);
-
- //could not get dpi
- return 96;
-}
-
-Point2 OS_X11::get_window_position() const {
- int x, y;
- Window child;
- XTranslateCoordinates(x11_display, x11_window, DefaultRootWindow(x11_display), 0, 0, &x, &y, &child);
- return Point2i(x, y);
-}
-
-void OS_X11::set_window_position(const Point2 &p_position) {
- int x = 0;
- int y = 0;
- if (!get_borderless_window()) {
- //exclude window decorations
- XSync(x11_display, False);
- Atom prop = XInternAtom(x11_display, "_NET_FRAME_EXTENTS", True);
- if (prop != None) {
- Atom type;
- int format;
- unsigned long len;
- unsigned long remaining;
- unsigned char *data = NULL;
- if (XGetWindowProperty(x11_display, x11_window, prop, 0, 4, False, AnyPropertyType, &type, &format, &len, &remaining, &data) == Success) {
- if (format == 32 && len == 4) {
- long *extents = (long *)data;
- x = extents[0];
- y = extents[2];
- }
- XFree(data);
- }
- }
- }
- XMoveWindow(x11_display, x11_window, p_position.x - x, p_position.y - y);
- update_real_mouse_position();
-}
-
-Size2 OS_X11::get_window_size() const {
- // Use current_videomode width and height instead of XGetWindowAttributes
- // since right after a XResizeWindow the attributes may not be updated yet
- return Size2i(current_videomode.width, current_videomode.height);
-}
-
-Size2 OS_X11::get_real_window_size() const {
- XWindowAttributes xwa;
- XSync(x11_display, False);
- XGetWindowAttributes(x11_display, x11_window, &xwa);
- int w = xwa.width;
- int h = xwa.height;
- Atom prop = XInternAtom(x11_display, "_NET_FRAME_EXTENTS", True);
- if (prop != None) {
- Atom type;
- int format;
- unsigned long len;
- unsigned long remaining;
- unsigned char *data = NULL;
- if (XGetWindowProperty(x11_display, x11_window, prop, 0, 4, False, AnyPropertyType, &type, &format, &len, &remaining, &data) == Success) {
- if (format == 32 && len == 4) {
- long *extents = (long *)data;
- w += extents[0] + extents[1]; // left, right
- h += extents[2] + extents[3]; // top, bottom
- }
- XFree(data);
- }
- }
- return Size2(w, h);
-}
-
-Size2 OS_X11::get_max_window_size() const {
- return max_size;
-}
-
-Size2 OS_X11::get_min_window_size() const {
- return min_size;
-}
-
-void OS_X11::set_min_window_size(const Size2 p_size) {
-
- if ((p_size != Size2()) && (max_size != Size2()) && ((p_size.x > max_size.x) || (p_size.y > max_size.y))) {
- ERR_PRINT("Minimum window size can't be larger than maximum window size!");
- return;
- }
- min_size = p_size;
-
- if (is_window_resizable()) {
- XSizeHints *xsh;
- xsh = XAllocSizeHints();
- xsh->flags = 0L;
- if (min_size != Size2()) {
- xsh->flags |= PMinSize;
- xsh->min_width = min_size.x;
- xsh->min_height = min_size.y;
- }
- if (max_size != Size2()) {
- xsh->flags |= PMaxSize;
- xsh->max_width = max_size.x;
- xsh->max_height = max_size.y;
- }
- XSetWMNormalHints(x11_display, x11_window, xsh);
- XFree(xsh);
-
- XFlush(x11_display);
- }
-}
-
-void OS_X11::set_max_window_size(const Size2 p_size) {
-
- if ((p_size != Size2()) && ((p_size.x < min_size.x) || (p_size.y < min_size.y))) {
- ERR_PRINT("Maximum window size can't be smaller than minimum window size!");
- return;
- }
- max_size = p_size;
-
- if (is_window_resizable()) {
- XSizeHints *xsh;
- xsh = XAllocSizeHints();
- xsh->flags = 0L;
- if (min_size != Size2()) {
- xsh->flags |= PMinSize;
- xsh->min_width = min_size.x;
- xsh->min_height = min_size.y;
- }
- if (max_size != Size2()) {
- xsh->flags |= PMaxSize;
- xsh->max_width = max_size.x;
- xsh->max_height = max_size.y;
- }
- XSetWMNormalHints(x11_display, x11_window, xsh);
- XFree(xsh);
-
- XFlush(x11_display);
- }
-}
-
-void OS_X11::set_window_size(const Size2 p_size) {
-
- if (current_videomode.width == p_size.width && current_videomode.height == p_size.height)
- return;
-
- XWindowAttributes xwa;
- XSync(x11_display, False);
- XGetWindowAttributes(x11_display, x11_window, &xwa);
- int old_w = xwa.width;
- int old_h = xwa.height;
-
- // If window resizable is disabled we need to update the attributes first
- XSizeHints *xsh;
- xsh = XAllocSizeHints();
- if (!is_window_resizable()) {
- xsh->flags = PMinSize | PMaxSize;
- xsh->min_width = p_size.x;
- xsh->max_width = p_size.x;
- xsh->min_height = p_size.y;
- xsh->max_height = p_size.y;
- } else {
- xsh->flags = 0L;
- if (min_size != Size2()) {
- xsh->flags |= PMinSize;
- xsh->min_width = min_size.x;
- xsh->min_height = min_size.y;
- }
- if (max_size != Size2()) {
- xsh->flags |= PMaxSize;
- xsh->max_width = max_size.x;
- xsh->max_height = max_size.y;
- }
- }
- XSetWMNormalHints(x11_display, x11_window, xsh);
- XFree(xsh);
-
- // Resize the window
- XResizeWindow(x11_display, x11_window, p_size.x, p_size.y);
-
- // Update our videomode width and height
- current_videomode.width = p_size.x;
- current_videomode.height = p_size.y;
-
- for (int timeout = 0; timeout < 50; ++timeout) {
- XSync(x11_display, False);
- XGetWindowAttributes(x11_display, x11_window, &xwa);
-
- if (old_w != xwa.width || old_h != xwa.height)
- break;
-
- usleep(10000);
- }
-}
-
-void OS_X11::set_window_fullscreen(bool p_enabled) {
-
- if (current_videomode.fullscreen == p_enabled)
- return;
-
- if (layered_window)
- set_window_per_pixel_transparency_enabled(false);
-
- if (p_enabled && current_videomode.always_on_top) {
- // Fullscreen + Always-on-top requires a maximized window on some window managers (Metacity)
- set_window_maximized(true);
- }
- set_wm_fullscreen(p_enabled);
- if (!p_enabled && current_videomode.always_on_top) {
- // Restore
- set_window_maximized(false);
- }
- if (!p_enabled) {
- set_window_position(last_position_before_fs);
- } else {
- last_position_before_fs = get_window_position();
- }
- current_videomode.fullscreen = p_enabled;
-}
-
-bool OS_X11::is_window_fullscreen() const {
- return current_videomode.fullscreen;
-}
-
-void OS_X11::set_window_resizable(bool p_enabled) {
-
- XSizeHints *xsh;
- xsh = XAllocSizeHints();
- if (!p_enabled) {
- Size2 size = get_window_size();
-
- xsh->flags = PMinSize | PMaxSize;
- xsh->min_width = size.x;
- xsh->max_width = size.x;
- xsh->min_height = size.y;
- xsh->max_height = size.y;
- } else {
- xsh->flags = 0L;
- if (min_size != Size2()) {
- xsh->flags |= PMinSize;
- xsh->min_width = min_size.x;
- xsh->min_height = min_size.y;
- }
- if (max_size != Size2()) {
- xsh->flags |= PMaxSize;
- xsh->max_width = max_size.x;
- xsh->max_height = max_size.y;
- }
- }
-
- XSetWMNormalHints(x11_display, x11_window, xsh);
- XFree(xsh);
-
- current_videomode.resizable = p_enabled;
-
- XFlush(x11_display);
-}
-
-bool OS_X11::is_window_resizable() const {
- return current_videomode.resizable;
-}
-
-void OS_X11::set_window_minimized(bool p_enabled) {
- // Using ICCCM -- Inter-Client Communication Conventions Manual
- XEvent xev;
- Atom wm_change = XInternAtom(x11_display, "WM_CHANGE_STATE", False);
-
- memset(&xev, 0, sizeof(xev));
- xev.type = ClientMessage;
- xev.xclient.window = x11_window;
- xev.xclient.message_type = wm_change;
- xev.xclient.format = 32;
- xev.xclient.data.l[0] = p_enabled ? WM_IconicState : WM_NormalState;
-
- XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
-
- Atom wm_state = XInternAtom(x11_display, "_NET_WM_STATE", False);
- Atom wm_hidden = XInternAtom(x11_display, "_NET_WM_STATE_HIDDEN", False);
-
- memset(&xev, 0, sizeof(xev));
- xev.type = ClientMessage;
- xev.xclient.window = x11_window;
- xev.xclient.message_type = wm_state;
- xev.xclient.format = 32;
- xev.xclient.data.l[0] = _NET_WM_STATE_ADD;
- xev.xclient.data.l[1] = wm_hidden;
-
- XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
-}
-
-bool OS_X11::is_window_minimized() const {
- // Using ICCCM -- Inter-Client Communication Conventions Manual
- Atom property = XInternAtom(x11_display, "WM_STATE", True);
- Atom type;
- int format;
- unsigned long len;
- unsigned long remaining;
- unsigned char *data = NULL;
-
- int result = XGetWindowProperty(
- x11_display,
- x11_window,
- property,
- 0,
- 32,
- False,
- AnyPropertyType,
- &type,
- &format,
- &len,
- &remaining,
- &data);
-
- if (result == Success) {
- long *state = (long *)data;
- if (state[0] == WM_IconicState)
- return true;
- }
- return false;
-}
-
-void OS_X11::set_window_maximized(bool p_enabled) {
- if (is_window_maximized() == p_enabled)
- return;
-
- // Using EWMH -- Extended Window Manager Hints
- XEvent xev;
- Atom wm_state = XInternAtom(x11_display, "_NET_WM_STATE", False);
- Atom wm_max_horz = XInternAtom(x11_display, "_NET_WM_STATE_MAXIMIZED_HORZ", False);
- Atom wm_max_vert = XInternAtom(x11_display, "_NET_WM_STATE_MAXIMIZED_VERT", False);
-
- memset(&xev, 0, sizeof(xev));
- xev.type = ClientMessage;
- xev.xclient.window = x11_window;
- xev.xclient.message_type = wm_state;
- xev.xclient.format = 32;
- xev.xclient.data.l[0] = p_enabled ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
- xev.xclient.data.l[1] = wm_max_horz;
- xev.xclient.data.l[2] = wm_max_vert;
-
- XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
-
- if (p_enabled && is_window_maximize_allowed()) {
- // Wait for effective resizing (so the GLX context is too).
- // Give up after 0.5s, it's not going to happen on this WM.
- // https://github.com/godotengine/godot/issues/19978
- for (int attempt = 0; !is_window_maximized() && attempt < 50; attempt++) {
- usleep(10000);
- }
- }
-
- maximized = p_enabled;
-}
-
-bool OS_X11::is_window_maximize_allowed() {
- Atom property = XInternAtom(x11_display, "_NET_WM_ALLOWED_ACTIONS", False);
- Atom type;
- int format;
- unsigned long len;
- unsigned long remaining;
- unsigned char *data = NULL;
-
- int result = XGetWindowProperty(
- x11_display,
- x11_window,
- property,
- 0,
- 1024,
- False,
- XA_ATOM,
- &type,
- &format,
- &len,
- &remaining,
- &data);
-
- if (result == Success) {
- Atom *atoms = (Atom *)data;
- Atom wm_act_max_horz = XInternAtom(x11_display, "_NET_WM_ACTION_MAXIMIZE_HORZ", False);
- Atom wm_act_max_vert = XInternAtom(x11_display, "_NET_WM_ACTION_MAXIMIZE_VERT", False);
- bool found_wm_act_max_horz = false;
- bool found_wm_act_max_vert = false;
-
- for (uint64_t i = 0; i < len; i++) {
- if (atoms[i] == wm_act_max_horz)
- found_wm_act_max_horz = true;
- if (atoms[i] == wm_act_max_vert)
- found_wm_act_max_vert = true;
-
- if (found_wm_act_max_horz || found_wm_act_max_vert)
- return true;
- }
- XFree(atoms);
- }
-
- return false;
-}
-
-bool OS_X11::is_window_maximized() const {
- // Using EWMH -- Extended Window Manager Hints
- Atom property = XInternAtom(x11_display, "_NET_WM_STATE", False);
- Atom type;
- int format;
- unsigned long len;
- unsigned long remaining;
- unsigned char *data = NULL;
- bool retval = false;
-
- int result = XGetWindowProperty(
- x11_display,
- x11_window,
- property,
- 0,
- 1024,
- False,
- XA_ATOM,
- &type,
- &format,
- &len,
- &remaining,
- &data);
-
- if (result == Success) {
- Atom *atoms = (Atom *)data;
- Atom wm_max_horz = XInternAtom(x11_display, "_NET_WM_STATE_MAXIMIZED_HORZ", False);
- Atom wm_max_vert = XInternAtom(x11_display, "_NET_WM_STATE_MAXIMIZED_VERT", False);
- bool found_wm_max_horz = false;
- bool found_wm_max_vert = false;
-
- for (uint64_t i = 0; i < len; i++) {
- if (atoms[i] == wm_max_horz)
- found_wm_max_horz = true;
- if (atoms[i] == wm_max_vert)
- found_wm_max_vert = true;
-
- if (found_wm_max_horz && found_wm_max_vert) {
- retval = true;
- break;
- }
- }
- }
-
- XFree(data);
- return retval;
-}
-
-void OS_X11::set_window_always_on_top(bool p_enabled) {
- if (is_window_always_on_top() == p_enabled)
- return;
-
- if (p_enabled && current_videomode.fullscreen) {
- // Fullscreen + Always-on-top requires a maximized window on some window managers (Metacity)
- set_window_maximized(true);
- }
- set_wm_above(p_enabled);
- if (!p_enabled && !current_videomode.fullscreen) {
- // Restore
- set_window_maximized(false);
- }
-
- current_videomode.always_on_top = p_enabled;
-}
-
-bool OS_X11::is_window_always_on_top() const {
- return current_videomode.always_on_top;
-}
-
-bool OS_X11::is_window_focused() const {
- return window_focused;
-}
-
-void OS_X11::set_borderless_window(bool p_borderless) {
-
- if (get_borderless_window() == p_borderless)
- return;
-
- if (!p_borderless && layered_window)
- set_window_per_pixel_transparency_enabled(false);
-
- current_videomode.borderless_window = p_borderless;
-
- Hints hints;
- Atom property;
- hints.flags = 2;
- hints.decorations = current_videomode.borderless_window ? 0 : 1;
- property = XInternAtom(x11_display, "_MOTIF_WM_HINTS", True);
- XChangeProperty(x11_display, x11_window, property, property, 32, PropModeReplace, (unsigned char *)&hints, 5);
-
- // Preserve window size
- set_window_size(Size2(current_videomode.width, current_videomode.height));
-}
-
-bool OS_X11::get_borderless_window() {
-
- bool borderless = current_videomode.borderless_window;
- Atom prop = XInternAtom(x11_display, "_MOTIF_WM_HINTS", True);
- if (prop != None) {
-
- Atom type;
- int format;
- unsigned long len;
- unsigned long remaining;
- unsigned char *data = NULL;
- if (XGetWindowProperty(x11_display, x11_window, prop, 0, sizeof(Hints), False, AnyPropertyType, &type, &format, &len, &remaining, &data) == Success) {
- if (data && (format == 32) && (len >= 5)) {
- borderless = !((Hints *)data)->decorations;
- }
- XFree(data);
- }
- }
- return borderless;
-}
-
-void OS_X11::request_attention() {
- // Using EWMH -- Extended Window Manager Hints
- //
- // Sets the _NET_WM_STATE_DEMANDS_ATTENTION atom for WM_STATE
- // Will be unset by the window manager after user react on the request for attention
-
- XEvent xev;
- Atom wm_state = XInternAtom(x11_display, "_NET_WM_STATE", False);
- Atom wm_attention = XInternAtom(x11_display, "_NET_WM_STATE_DEMANDS_ATTENTION", False);
-
- memset(&xev, 0, sizeof(xev));
- xev.type = ClientMessage;
- xev.xclient.window = x11_window;
- xev.xclient.message_type = wm_state;
- xev.xclient.format = 32;
- xev.xclient.data.l[0] = _NET_WM_STATE_ADD;
- xev.xclient.data.l[1] = wm_attention;
-
- XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
- XFlush(x11_display);
-}
-
-void OS_X11::get_key_modifier_state(unsigned int p_x11_state, Ref<InputEventWithModifiers> state) {
-
- state->set_shift((p_x11_state & ShiftMask));
- state->set_control((p_x11_state & ControlMask));
- state->set_alt((p_x11_state & Mod1Mask /*|| p_x11_state&Mod5Mask*/)); //altgr should not count as alt
- state->set_metakey((p_x11_state & Mod4Mask));
-}
-
-unsigned int OS_X11::get_mouse_button_state(unsigned int p_x11_button, int p_x11_type) {
-
- unsigned int mask = 1 << (p_x11_button - 1);
-
- if (p_x11_type == ButtonPress) {
- last_button_state |= mask;
- } else {
- last_button_state &= ~mask;
- }
-
- return last_button_state;
-}
-
-void OS_X11::handle_key_event(XKeyEvent *p_event, bool p_echo) {
-
- // X11 functions don't know what const is
- XKeyEvent *xkeyevent = p_event;
-
- // This code was pretty difficult to write.
- // The docs stink and every toolkit seems to
- // do it in a different way.
-
- /* Phase 1, obtain a proper keysym */
-
- // This was also very difficult to figure out.
- // You'd expect you could just use Keysym provided by
- // XKeycodeToKeysym to obtain internationalized
- // input.. WRONG!!
- // you must use XLookupString (???) which not only wastes
- // cycles generating an unnecessary string, but also
- // still works in half the cases. (won't handle deadkeys)
- // For more complex input methods (deadkeys and more advanced)
- // you have to use XmbLookupString (??).
- // So.. then you have to chosse which of both results
- // you want to keep.
- // This is a real bizarreness and cpu waster.
-
- KeySym keysym_keycode = 0; // keysym used to find a keycode
- KeySym keysym_unicode = 0; // keysym used to find unicode
-
- // XLookupString returns keysyms usable as nice scancodes/
- char str[256 + 1];
- XKeyEvent xkeyevent_no_mod = *xkeyevent;
- xkeyevent_no_mod.state &= ~ShiftMask;
- xkeyevent_no_mod.state &= ~ControlMask;
- XLookupString(xkeyevent, str, 256, &keysym_unicode, NULL);
- XLookupString(&xkeyevent_no_mod, NULL, 0, &keysym_keycode, NULL);
-
- // Meanwhile, XLookupString returns keysyms useful for unicode.
-
- if (!xmbstring) {
- // keep a temporary buffer for the string
- xmbstring = (char *)memalloc(sizeof(char) * 8);
- xmblen = 8;
- }
-
- if (xkeyevent->type == KeyPress && xic) {
-
- Status status;
-#ifdef X_HAVE_UTF8_STRING
- int utf8len = 8;
- char *utf8string = (char *)memalloc(sizeof(char) * utf8len);
- int utf8bytes = Xutf8LookupString(xic, xkeyevent, utf8string,
- utf8len - 1, &keysym_unicode, &status);
- if (status == XBufferOverflow) {
- utf8len = utf8bytes + 1;
- utf8string = (char *)memrealloc(utf8string, utf8len);
- utf8bytes = Xutf8LookupString(xic, xkeyevent, utf8string,
- utf8len - 1, &keysym_unicode, &status);
- }
- utf8string[utf8bytes] = '\0';
-
- if (status == XLookupChars) {
- bool keypress = xkeyevent->type == KeyPress;
- unsigned int keycode = KeyMappingX11::get_keycode(keysym_keycode);
- unsigned int physical_keycode = KeyMappingX11::get_scancode(xkeyevent->keycode);
-
- if (keycode >= 'a' && keycode <= 'z')
- keycode -= 'a' - 'A';
-
- String tmp;
- tmp.parse_utf8(utf8string, utf8bytes);
- for (int i = 0; i < tmp.length(); i++) {
- Ref<InputEventKey> k;
- k.instance();
- if (physical_keycode == 0 && keycode == 0 && tmp[i] == 0) {
- continue;
- }
-
- if (keycode == 0)
- keycode = physical_keycode;
-
- get_key_modifier_state(xkeyevent->state, k);
-
- k->set_unicode(tmp[i]);
-
- k->set_pressed(keypress);
-
- k->set_keycode(keycode);
-
- k->set_physical_keycode(physical_keycode);
-
- k->set_echo(false);
-
- if (k->get_keycode() == KEY_BACKTAB) {
- //make it consistent across platforms.
- k->set_keycode(KEY_TAB);
- k->set_physical_keycode(KEY_TAB);
- k->set_shift(true);
- }
-
- input->accumulate_input_event(k);
- }
- memfree(utf8string);
- return;
- }
- memfree(utf8string);
-#else
- do {
-
- int mnbytes = XmbLookupString(xic, xkeyevent, xmbstring, xmblen - 1, &keysym_unicode, &status);
- xmbstring[mnbytes] = '\0';
-
- if (status == XBufferOverflow) {
- xmblen = mnbytes + 1;
- xmbstring = (char *)memrealloc(xmbstring, xmblen);
- }
- } while (status == XBufferOverflow);
-#endif
- }
-
- /* Phase 2, obtain a pigui keycode from the keysym */
-
- // KeyMappingX11 just translated the X11 keysym to a PIGUI
- // keysym, so it works in all platforms the same.
-
- unsigned int keycode = KeyMappingX11::get_keycode(keysym_keycode);
- unsigned int physical_keycode = KeyMappingX11::get_scancode(xkeyevent->keycode);
-
- /* Phase 3, obtain a unicode character from the keysym */
-
- // KeyMappingX11 also translates keysym to unicode.
- // It does a binary search on a table to translate
- // most properly.
- unsigned int unicode = keysym_unicode > 0 ? KeyMappingX11::get_unicode_from_keysym(keysym_unicode) : 0;
-
- /* Phase 4, determine if event must be filtered */
-
- // This seems to be a side-effect of using XIM.
- // XEventFilter looks like a core X11 function,
- // but it's actually just used to see if we must
- // ignore a deadkey, or events XIM determines
- // must not reach the actual gui.
- // Guess it was a design problem of the extension
-
- bool keypress = xkeyevent->type == KeyPress;
-
- if (physical_keycode == 0 && keycode == 0 && unicode == 0)
- return;
-
- if (keycode == 0)
- keycode = physical_keycode;
-
- /* Phase 5, determine modifier mask */
-
- // No problems here, except I had no way to
- // know Mod1 was ALT and Mod4 was META (applekey/winkey)
- // just tried Mods until i found them.
-
- //print_verbose("mod1: "+itos(xkeyevent->state&Mod1Mask)+" mod 5: "+itos(xkeyevent->state&Mod5Mask));
-
- Ref<InputEventKey> k;
- k.instance();
-
- get_key_modifier_state(xkeyevent->state, k);
-
- /* Phase 6, determine echo character */
-
- // Echo characters in X11 are a keyrelease and a keypress
- // one after the other with the (almot) same timestamp.
- // To detect them, i use XPeekEvent and check that their
- // difference in time is below a threshold.
-
- if (xkeyevent->type != KeyPress) {
-
- p_echo = false;
-
- // make sure there are events pending,
- // so this call won't block.
- if (XPending(x11_display) > 0) {
- XEvent peek_event;
- XPeekEvent(x11_display, &peek_event);
-
- // I'm using a threshold of 5 msecs,
- // since sometimes there seems to be a little
- // jitter. I'm still not convinced that all this approach
- // is correct, but the xorg developers are
- // not very helpful today.
-
-#define ABSDIFF(x, y) (((x) < (y)) ? ((y) - (x)) : ((x) - (y)))
- ::Time threshold = ABSDIFF(peek_event.xkey.time, xkeyevent->time);
-#undef ABSDIFF
- if (peek_event.type == KeyPress && threshold < 5) {
- KeySym rk;
- XLookupString((XKeyEvent *)&peek_event, str, 256, &rk, NULL);
- if (rk == keysym_keycode) {
- XEvent event;
- XNextEvent(x11_display, &event); //erase next event
- handle_key_event((XKeyEvent *)&event, true);
- return; //ignore current, echo next
- }
- }
-
- // use the time from peek_event so it always works
- }
-
- // save the time to check for echo when keypress happens
- }
-
- /* Phase 7, send event to Window */
-
- k->set_pressed(keypress);
-
- if (keycode >= 'a' && keycode <= 'z')
- keycode -= 'a' - 'A';
-
- k->set_keycode(keycode);
- k->set_physical_keycode(physical_keycode);
- k->set_unicode(unicode);
- k->set_echo(p_echo);
-
- if (k->get_keycode() == KEY_BACKTAB) {
- //make it consistent across platforms.
- k->set_keycode(KEY_TAB);
- k->set_physical_keycode(KEY_TAB);
- k->set_shift(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)
- k->set_shift(false);
- else if (k->get_keycode() == KEY_CONTROL)
- k->set_control(false);
- else if (k->get_keycode() == KEY_ALT)
- k->set_alt(false);
- else if (k->get_keycode() == KEY_META)
- k->set_metakey(false);
- }
-
- bool last_is_pressed = Input::get_singleton()->is_key_pressed(k->get_keycode());
- if (k->is_pressed()) {
- if (last_is_pressed) {
- k->set_echo(true);
- }
- }
-
- //printf("key: %x\n",k->get_keycode());
- input->accumulate_input_event(k);
-}
-
-struct Property {
- unsigned char *data;
- int format, nitems;
- Atom type;
-};
-
-static Property read_property(Display *p_display, Window p_window, Atom p_property) {
-
- Atom actual_type;
- int actual_format;
- unsigned long nitems;
- unsigned long bytes_after;
- unsigned char *ret = 0;
-
- int read_bytes = 1024;
-
- //Keep trying to read the property until there are no
- //bytes unread.
- do {
- if (ret != 0)
- XFree(ret);
-
- XGetWindowProperty(p_display, p_window, p_property, 0, read_bytes, False, AnyPropertyType,
- &actual_type, &actual_format, &nitems, &bytes_after,
- &ret);
-
- read_bytes *= 2;
-
- } while (bytes_after != 0);
-
- Property p = { ret, actual_format, (int)nitems, actual_type };
-
- return p;
-}
-
-static Atom pick_target_from_list(Display *p_display, Atom *p_list, int p_count) {
-
- static const char *target_type = "text/uri-list";
-
- for (int i = 0; i < p_count; i++) {
-
- Atom atom = p_list[i];
-
- if (atom != None && String(XGetAtomName(p_display, atom)) == target_type)
- return atom;
- }
- return None;
-}
-
-static Atom pick_target_from_atoms(Display *p_disp, Atom p_t1, Atom p_t2, Atom p_t3) {
-
- static const char *target_type = "text/uri-list";
- if (p_t1 != None && String(XGetAtomName(p_disp, p_t1)) == target_type)
- return p_t1;
-
- if (p_t2 != None && String(XGetAtomName(p_disp, p_t2)) == target_type)
- return p_t2;
-
- if (p_t3 != None && String(XGetAtomName(p_disp, p_t3)) == target_type)
- return p_t3;
-
- return None;
-}
-
-void OS_X11::_window_changed(XEvent *event) {
-
- if (xic) {
- // Not portable.
- set_ime_position(Point2(0, 1));
- }
- if ((event->xconfigure.width == current_videomode.width) &&
- (event->xconfigure.height == current_videomode.height))
- return;
-
- current_videomode.width = event->xconfigure.width;
- current_videomode.height = event->xconfigure.height;
-
-#if defined(VULKAN_ENABLED)
- if (video_driver_index == VIDEO_DRIVER_VULKAN) {
- context_vulkan->window_resize(0, current_videomode.width, current_videomode.height);
- }
-#endif
-}
-
-void OS_X11::process_xevents() {
-
- //printf("checking events %i\n", XPending(x11_display));
-
- do_mouse_warp = false;
-
- // Is the current mouse mode one where it needs to be grabbed.
- bool mouse_mode_grab = mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED;
-
- while (XPending(x11_display) > 0) {
- XEvent event;
- XNextEvent(x11_display, &event);
-
- if (XFilterEvent(&event, None)) {
- continue;
- }
-
- if (XGetEventData(x11_display, &event.xcookie)) {
-
- if (event.xcookie.type == GenericEvent && event.xcookie.extension == xi.opcode) {
-
- XIDeviceEvent *event_data = (XIDeviceEvent *)event.xcookie.data;
- int index = event_data->detail;
- Vector2 pos = Vector2(event_data->event_x, event_data->event_y);
-
- switch (event_data->evtype) {
- case XI_HierarchyChanged:
- case XI_DeviceChanged: {
- refresh_device_info();
- } break;
- case XI_RawMotion: {
- XIRawEvent *raw_event = (XIRawEvent *)event_data;
- int device_id = raw_event->deviceid;
-
- // Determine the axis used (called valuators in XInput for some forsaken reason)
- // Mask is a bitmask indicating which axes are involved.
- // We are interested in the values of axes 0 and 1.
- if (raw_event->valuators.mask_len <= 0) {
- break;
- }
-
- const double *values = raw_event->raw_values;
-
- double rel_x = 0.0;
- double rel_y = 0.0;
- double pressure = 0.0;
- double tilt_x = 0.0;
- double tilt_y = 0.0;
-
- if (XIMaskIsSet(raw_event->valuators.mask, VALUATOR_ABSX)) {
- rel_x = *values;
- values++;
- }
-
- if (XIMaskIsSet(raw_event->valuators.mask, VALUATOR_ABSY)) {
- rel_y = *values;
- values++;
- }
-
- if (XIMaskIsSet(raw_event->valuators.mask, VALUATOR_PRESSURE)) {
- pressure = *values;
- values++;
- }
-
- if (XIMaskIsSet(raw_event->valuators.mask, VALUATOR_TILTX)) {
- tilt_x = *values;
- values++;
- }
-
- if (XIMaskIsSet(raw_event->valuators.mask, VALUATOR_TILTY)) {
- tilt_y = *values;
- }
-
- Map<int, Vector3>::Element *pen_info = xi.pen_devices.find(device_id);
- if (pen_info) {
- Vector3 mult = pen_info->value();
- if (mult.x != 0.0) xi.pressure = pressure / mult.x;
- if ((mult.y != 0.0) && (mult.z != 0.0)) xi.tilt = Vector2(tilt_x / mult.y, tilt_y / mult.z);
- }
-
- // https://bugs.freedesktop.org/show_bug.cgi?id=71609
- // http://lists.libsdl.org/pipermail/commits-libsdl.org/2015-June/000282.html
- if (raw_event->time == xi.last_relative_time && rel_x == xi.relative_motion.x && rel_y == xi.relative_motion.y) {
- break; // Flush duplicate to avoid overly fast motion
- }
-
- xi.old_raw_pos.x = xi.raw_pos.x;
- xi.old_raw_pos.y = xi.raw_pos.y;
- xi.raw_pos.x = rel_x;
- xi.raw_pos.y = rel_y;
-
- Map<int, Vector2>::Element *abs_info = xi.absolute_devices.find(device_id);
-
- if (abs_info) {
- // Absolute mode device
- Vector2 mult = abs_info->value();
-
- xi.relative_motion.x += (xi.raw_pos.x - xi.old_raw_pos.x) * mult.x;
- xi.relative_motion.y += (xi.raw_pos.y - xi.old_raw_pos.y) * mult.y;
- } else {
- // Relative mode device
- xi.relative_motion.x = xi.raw_pos.x;
- xi.relative_motion.y = xi.raw_pos.y;
- }
-
- 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_TouchEnd: {
-
- bool is_begin = event_data->evtype == XI_TouchBegin;
-
- Ref<InputEventScreenTouch> st;
- st.instance();
- st->set_index(index);
- st->set_position(pos);
- st->set_pressed(is_begin);
-
- if (is_begin) {
- if (xi.state.has(index)) // Defensive
- break;
- xi.state[index] = pos;
- if (xi.state.size() == 1) {
- // X11 may send a motion event when a touch gesture begins, that would result
- // in a spurious mouse motion event being sent to Godot; remember it to be able to filter it out
- xi.mouse_pos_to_filter = pos;
- }
- input->accumulate_input_event(st);
- } else {
- if (!xi.state.has(index)) // Defensive
- break;
- xi.state.erase(index);
- input->accumulate_input_event(st);
- }
- } break;
-
- case XI_TouchUpdate: {
-
- Map<int, Vector2>::Element *curr_pos_elem = xi.state.find(index);
- if (!curr_pos_elem) { // Defensive
- break;
- }
-
- if (curr_pos_elem->value() != pos) {
-
- Ref<InputEventScreenDrag> sd;
- sd.instance();
- sd->set_index(index);
- sd->set_position(pos);
- sd->set_relative(pos - curr_pos_elem->value());
- input->accumulate_input_event(sd);
-
- curr_pos_elem->value() = pos;
- }
- } break;
-#endif
- }
- }
- }
- XFreeEventData(x11_display, &event.xcookie);
-
- switch (event.type) {
- case Expose:
- Main::force_redraw();
- break;
-
- case NoExpose:
- minimized = true;
- break;
-
- case VisibilityNotify: {
- XVisibilityEvent *visibility = (XVisibilityEvent *)&event;
- minimized = (visibility->state == VisibilityFullyObscured);
- } break;
- case LeaveNotify: {
- if (main_loop && !mouse_mode_grab)
- main_loop->notification(MainLoop::NOTIFICATION_WM_MOUSE_EXIT);
-
- } break;
- case EnterNotify: {
- if (main_loop && !mouse_mode_grab)
- main_loop->notification(MainLoop::NOTIFICATION_WM_MOUSE_ENTER);
- } break;
- case FocusIn:
- minimized = false;
- window_has_focus = true;
- main_loop->notification(MainLoop::NOTIFICATION_WM_FOCUS_IN);
- window_focused = true;
-
- if (mouse_mode_grab) {
- // Show and update the cursor if confined and the window regained focus.
- if (mouse_mode == MOUSE_MODE_CONFINED)
- XUndefineCursor(x11_display, x11_window);
- else if (mouse_mode == MOUSE_MODE_CAPTURED) // or re-hide it in captured mode
- XDefineCursor(x11_display, x11_window, null_cursor);
-
- XGrabPointer(
- x11_display, x11_window, True,
- ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
- GrabModeAsync, GrabModeAsync, x11_window, None, CurrentTime);
- }
-#ifdef TOUCH_ENABLED
- // 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);
- }*/
-#endif
- if (xic) {
- XSetICFocus(xic);
- }
- break;
-
- case FocusOut:
- window_has_focus = false;
- input->release_pressed_events();
- main_loop->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT);
- window_focused = false;
-
- if (mouse_mode_grab) {
- //dear X11, I try, I really try, but you never work, you do whathever you want.
- if (mouse_mode == MOUSE_MODE_CAPTURED) {
- // Show the cursor if we're in captured mode so it doesn't look weird.
- XUndefineCursor(x11_display, x11_window);
- }
- XUngrabPointer(x11_display, CurrentTime);
- }
-#ifdef TOUCH_ENABLED
- // Ungrab touch devices so input works as usual while we are unfocused
- /*for (int i = 0; i < xi.touch_devices.size(); ++i) {
- XIUngrabDevice(x11_display, xi.touch_devices[i], CurrentTime);
- }*/
-
- // Release every pointer to avoid sticky points
- for (Map<int, Vector2>::Element *E = xi.state.front(); E; E = E->next()) {
-
- Ref<InputEventScreenTouch> st;
- st.instance();
- st->set_index(E->key());
- st->set_position(E->get());
- input->accumulate_input_event(st);
- }
- xi.state.clear();
-#endif
- if (xic) {
- XUnsetICFocus(xic);
- }
- break;
-
- case ConfigureNotify:
- _window_changed(&event);
- break;
- case ButtonPress:
- case ButtonRelease: {
-
- /* exit in case of a mouse button press */
- last_timestamp = event.xbutton.time;
- if (mouse_mode == MOUSE_MODE_CAPTURED) {
- event.xbutton.x = last_mouse_pos.x;
- event.xbutton.y = last_mouse_pos.y;
- }
-
- Ref<InputEventMouseButton> mb;
- mb.instance();
-
- get_key_modifier_state(event.xbutton.state, mb);
- mb->set_button_index(event.xbutton.button);
- if (mb->get_button_index() == 2)
- mb->set_button_index(3);
- else if (mb->get_button_index() == 3)
- mb->set_button_index(2);
- 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));
- mb->set_global_position(mb->get_position());
-
- mb->set_pressed((event.type == ButtonPress));
-
- if (event.type == ButtonPress) {
-
- uint64_t diff = get_ticks_usec() / 1000 - last_click_ms;
-
- if (mb->get_button_index() == last_click_button_index) {
-
- if (diff < 400 && Point2(last_click_pos).distance_to(Point2(event.xbutton.x, event.xbutton.y)) < 5) {
-
- last_click_ms = 0;
- last_click_pos = Point2(-100, -100);
- last_click_button_index = -1;
- mb->set_doubleclick(true);
- }
-
- } else if (mb->get_button_index() < 4 || mb->get_button_index() > 7) {
- last_click_button_index = mb->get_button_index();
- }
-
- if (!mb->is_doubleclick()) {
- last_click_ms += diff;
- last_click_pos = Point2(event.xbutton.x, event.xbutton.y);
- }
- }
-
- input->accumulate_input_event(mb);
-
- } break;
- case MotionNotify: {
-
- // The X11 API requires filtering one-by-one through the motion
- // notify events, in order to figure out which event is the one
- // generated by warping the mouse pointer.
-
- while (true) {
- if (mouse_mode == MOUSE_MODE_CAPTURED && event.xmotion.x == current_videomode.width / 2 && event.xmotion.y == current_videomode.height / 2) {
- //this is likely the warp event since it was warped here
- center = Vector2(event.xmotion.x, event.xmotion.y);
- break;
- }
-
- if (XPending(x11_display) > 0) {
- XEvent tevent;
- XPeekEvent(x11_display, &tevent);
- if (tevent.type == MotionNotify) {
- XNextEvent(x11_display, &event);
- } else {
- break;
- }
- } else {
- break;
- }
- }
-
- last_timestamp = event.xmotion.time;
-
- // Motion is also simple.
- // A little hack is in order
- // to be able to send relative motion events.
- Point2 pos(event.xmotion.x, event.xmotion.y);
-
- // Avoidance of spurious mouse motion (see handling of touch)
- bool filter = false;
- // Adding some tolerance to match better Point2i to Vector2
- if (xi.state.size() && Vector2(pos).distance_squared_to(xi.mouse_pos_to_filter) < 2) {
- filter = true;
- }
- // Invalidate to avoid filtering a possible legitimate similar event coming later
- xi.mouse_pos_to_filter = Vector2(1e10, 1e10);
- if (filter) {
- break;
- }
-
- if (mouse_mode == MOUSE_MODE_CAPTURED) {
- if (xi.relative_motion.x == 0 && xi.relative_motion.y == 0) {
- break;
- }
-
- Point2i new_center = pos;
- pos = last_mouse_pos + xi.relative_motion;
- center = new_center;
- do_mouse_warp = window_has_focus; // warp the cursor if we're focused in
- }
-
- if (!last_mouse_pos_valid) {
-
- last_mouse_pos = pos;
- last_mouse_pos_valid = true;
- }
-
- // Hackish but relative mouse motion is already handled in the RawMotion event.
- // RawMotion does not provide the absolute mouse position (whereas MotionNotify does).
- // Therefore, RawMotion cannot be the authority on absolute mouse position.
- // RawMotion provides more precision than MotionNotify, which doesn't sense subpixel motion.
- // Therefore, MotionNotify cannot be the authority on relative mouse motion.
- // This means we need to take a combined approach...
- Point2 rel;
-
- // Only use raw input if in capture mode. Otherwise use the classic behavior.
- if (mouse_mode == MOUSE_MODE_CAPTURED) {
- rel = xi.relative_motion;
- } else {
- rel = pos - last_mouse_pos;
- }
-
- // Reset to prevent lingering motion
- xi.relative_motion.x = 0;
- xi.relative_motion.y = 0;
-
- if (mouse_mode == MOUSE_MODE_CAPTURED) {
- pos = Point2i(current_videomode.width / 2, current_videomode.height / 2);
- }
-
- Ref<InputEventMouseMotion> mm;
- mm.instance();
-
- mm->set_pressure(xi.pressure);
- mm->set_tilt(xi.tilt);
-
- // Make the absolute position integral so it doesn't look _too_ weird :)
- Point2i posi(pos);
-
- get_key_modifier_state(event.xmotion.state, mm);
- mm->set_button_mask(get_mouse_button_state());
- mm->set_position(posi);
- mm->set_global_position(posi);
- input->set_mouse_position(posi);
- mm->set_speed(input->get_last_mouse_speed());
-
- mm->set_relative(rel);
-
- last_mouse_pos = pos;
-
- // printf("rel: %d,%d\n", rel.x, rel.y );
- // Don't propagate the motion event unless we have focus
- // this is so that the relative motion doesn't get messed up
- // after we regain focus.
- if (window_has_focus || !mouse_mode_grab)
- input->accumulate_input_event(mm);
-
- } break;
- case KeyPress:
- case KeyRelease: {
-
- last_timestamp = event.xkey.time;
-
- // key event is a little complex, so
- // it will be handled in its own function.
- handle_key_event((XKeyEvent *)&event);
- } break;
- case SelectionRequest: {
-
- XSelectionRequestEvent *req;
- XEvent e, respond;
- e = event;
-
- req = &(e.xselectionrequest);
- if (req->target == XInternAtom(x11_display, "UTF8_STRING", 0) ||
- req->target == XInternAtom(x11_display, "COMPOUND_TEXT", 0) ||
- req->target == XInternAtom(x11_display, "TEXT", 0) ||
- req->target == XA_STRING ||
- req->target == XInternAtom(x11_display, "text/plain;charset=utf-8", 0) ||
- req->target == XInternAtom(x11_display, "text/plain", 0)) {
- CharString clip = OS::get_clipboard().utf8();
- XChangeProperty(x11_display,
- req->requestor,
- req->property,
- req->target,
- 8,
- PropModeReplace,
- (unsigned char *)clip.get_data(),
- clip.length());
- respond.xselection.property = req->property;
- } else if (req->target == XInternAtom(x11_display, "TARGETS", 0)) {
-
- Atom data[7];
- data[0] = XInternAtom(x11_display, "TARGETS", 0);
- data[1] = XInternAtom(x11_display, "UTF8_STRING", 0);
- data[2] = XInternAtom(x11_display, "COMPOUND_TEXT", 0);
- data[3] = XInternAtom(x11_display, "TEXT", 0);
- data[4] = XA_STRING;
- data[5] = XInternAtom(x11_display, "text/plain;charset=utf-8", 0);
- data[6] = XInternAtom(x11_display, "text/plain", 0);
-
- XChangeProperty(x11_display,
- req->requestor,
- req->property,
- XA_ATOM,
- 32,
- PropModeReplace,
- (unsigned char *)&data,
- sizeof(data) / sizeof(data[0]));
- respond.xselection.property = req->property;
-
- } else {
- char *targetname = XGetAtomName(x11_display, req->target);
- printf("No Target '%s'\n", targetname);
- if (targetname)
- XFree(targetname);
- respond.xselection.property = None;
- }
-
- respond.xselection.type = SelectionNotify;
- respond.xselection.display = req->display;
- respond.xselection.requestor = req->requestor;
- respond.xselection.selection = req->selection;
- respond.xselection.target = req->target;
- respond.xselection.time = req->time;
- XSendEvent(x11_display, req->requestor, True, NoEventMask, &respond);
- XFlush(x11_display);
- } break;
-
- case SelectionNotify:
-
- if (event.xselection.target == requested) {
-
- Property p = read_property(x11_display, x11_window, XInternAtom(x11_display, "PRIMARY", 0));
-
- Vector<String> files = String((char *)p.data).split("\n", false);
- for (int i = 0; i < files.size(); i++) {
- files.write[i] = files[i].replace("file://", "").http_unescape().strip_edges();
- }
- main_loop->drop_files(files);
-
- //Reply that all is well.
- XClientMessageEvent m;
- memset(&m, 0, sizeof(m));
- m.type = ClientMessage;
- m.display = x11_display;
- m.window = xdnd_source_window;
- m.message_type = xdnd_finished;
- m.format = 32;
- m.data.l[0] = x11_window;
- m.data.l[1] = 1;
- m.data.l[2] = xdnd_action_copy; //We only ever copy.
-
- XSendEvent(x11_display, xdnd_source_window, False, NoEventMask, (XEvent *)&m);
- }
- break;
-
- case ClientMessage:
-
- if ((unsigned int)event.xclient.data.l[0] == (unsigned int)wm_delete)
- main_loop->notification(MainLoop::NOTIFICATION_WM_QUIT_REQUEST);
-
- else if ((unsigned int)event.xclient.message_type == (unsigned int)xdnd_enter) {
-
- //File(s) have been dragged over the window, check for supported target (text/uri-list)
- xdnd_version = (event.xclient.data.l[1] >> 24);
- Window source = event.xclient.data.l[0];
- bool more_than_3 = event.xclient.data.l[1] & 1;
- if (more_than_3) {
- Property p = read_property(x11_display, source, XInternAtom(x11_display, "XdndTypeList", False));
- requested = pick_target_from_list(x11_display, (Atom *)p.data, p.nitems);
- } else
- requested = pick_target_from_atoms(x11_display, event.xclient.data.l[2], event.xclient.data.l[3], event.xclient.data.l[4]);
- } else if ((unsigned int)event.xclient.message_type == (unsigned int)xdnd_position) {
-
- //xdnd position event, reply with an XDND status message
- //just depending on type of data for now
- XClientMessageEvent m;
- memset(&m, 0, sizeof(m));
- m.type = ClientMessage;
- m.display = event.xclient.display;
- m.window = event.xclient.data.l[0];
- m.message_type = xdnd_status;
- m.format = 32;
- m.data.l[0] = x11_window;
- m.data.l[1] = (requested != None);
- m.data.l[2] = 0; //empty rectangle
- m.data.l[3] = 0;
- m.data.l[4] = xdnd_action_copy;
-
- XSendEvent(x11_display, event.xclient.data.l[0], False, NoEventMask, (XEvent *)&m);
- XFlush(x11_display);
- } else if ((unsigned int)event.xclient.message_type == (unsigned int)xdnd_drop) {
-
- if (requested != None) {
- xdnd_source_window = event.xclient.data.l[0];
- if (xdnd_version >= 1)
- XConvertSelection(x11_display, xdnd_selection, requested, XInternAtom(x11_display, "PRIMARY", 0), x11_window, event.xclient.data.l[2]);
- else
- XConvertSelection(x11_display, xdnd_selection, requested, XInternAtom(x11_display, "PRIMARY", 0), x11_window, CurrentTime);
- } else {
- //Reply that we're not interested.
- XClientMessageEvent m;
- memset(&m, 0, sizeof(m));
- m.type = ClientMessage;
- m.display = event.xclient.display;
- m.window = event.xclient.data.l[0];
- m.message_type = xdnd_finished;
- m.format = 32;
- m.data.l[0] = x11_window;
- m.data.l[1] = 0;
- m.data.l[2] = None; //Failed.
- XSendEvent(x11_display, event.xclient.data.l[0], False, NoEventMask, (XEvent *)&m);
- }
- }
- break;
- default:
- break;
- }
- }
-
- XFlush(x11_display);
-
- if (do_mouse_warp) {
-
- XWarpPointer(x11_display, None, x11_window,
- 0, 0, 0, 0, (int)current_videomode.width / 2, (int)current_videomode.height / 2);
-
- /*
- Window root, child;
- int root_x, root_y;
- int win_x, win_y;
- unsigned int mask;
- XQueryPointer( x11_display, x11_window, &root, &child, &root_x, &root_y, &win_x, &win_y, &mask );
-
- printf("Root: %d,%d\n", root_x, root_y);
- printf("Win: %d,%d\n", win_x, win_y);
- */
- }
-
- input->flush_accumulated_events();
-}
-
-MainLoop *OS_X11::get_main_loop() const {
-
- return main_loop;
-}
-
-void OS_X11::delete_main_loop() {
-
- if (main_loop)
- memdelete(main_loop);
- main_loop = NULL;
-}
-
-void OS_X11::set_main_loop(MainLoop *p_main_loop) {
-
- main_loop = p_main_loop;
- input->set_main_loop(p_main_loop);
-}
-
-bool OS_X11::can_draw() const {
-
- return !minimized;
-};
-
-void OS_X11::set_clipboard(const String &p_text) {
-
- OS::set_clipboard(p_text);
-
- XSetSelectionOwner(x11_display, XA_PRIMARY, x11_window, CurrentTime);
- XSetSelectionOwner(x11_display, XInternAtom(x11_display, "CLIPBOARD", 0), x11_window, CurrentTime);
-};
-
-static String _get_clipboard_impl(Atom p_source, Window x11_window, ::Display *x11_display, String p_internal_clipboard, Atom target) {
-
- String ret;
-
- Atom type;
- Atom selection = XA_PRIMARY;
- int format, result;
- unsigned long len, bytes_left, dummy;
- unsigned char *data;
- Window Sown = XGetSelectionOwner(x11_display, p_source);
-
- if (Sown == x11_window) {
-
- return p_internal_clipboard;
- };
-
- if (Sown != None) {
- XConvertSelection(x11_display, p_source, target, selection,
- x11_window, CurrentTime);
- XFlush(x11_display);
- while (true) {
- XEvent event;
- XNextEvent(x11_display, &event);
- if (event.type == SelectionNotify && event.xselection.requestor == x11_window) {
- break;
- };
- };
-
- //
- // Do not get any data, see how much data is there
- //
- XGetWindowProperty(x11_display, x11_window,
- selection, // Tricky..
- 0, 0, // offset - len
- 0, // Delete 0==FALSE
- AnyPropertyType, //flag
- &type, // return type
- &format, // return format
- &len, &bytes_left, //that
- &data);
- // DATA is There
- if (bytes_left > 0) {
- result = XGetWindowProperty(x11_display, x11_window,
- selection, 0, bytes_left, 0,
- AnyPropertyType, &type, &format,
- &len, &dummy, &data);
- if (result == Success) {
- ret.parse_utf8((const char *)data);
- } else
- printf("FAIL\n");
- XFree(data);
- }
- }
-
- return ret;
-}
-
-static String _get_clipboard(Atom p_source, Window x11_window, ::Display *x11_display, String p_internal_clipboard) {
- String ret;
- Atom utf8_atom = XInternAtom(x11_display, "UTF8_STRING", True);
- if (utf8_atom != None) {
- ret = _get_clipboard_impl(p_source, x11_window, x11_display, p_internal_clipboard, utf8_atom);
- }
- if (ret == "") {
- ret = _get_clipboard_impl(p_source, x11_window, x11_display, p_internal_clipboard, XA_STRING);
- }
- return ret;
-}
-
-String OS_X11::get_clipboard() const {
-
- String ret;
- ret = _get_clipboard(XInternAtom(x11_display, "CLIPBOARD", 0), x11_window, x11_display, OS::get_clipboard());
-
- if (ret == "") {
- ret = _get_clipboard(XA_PRIMARY, x11_window, x11_display, OS::get_clipboard());
- };
-
- return ret;
-}
-
-String OS_X11::get_name() const {
-
- return "X11";
-}
-
-Error OS_X11::shell_open(String p_uri) {
-
- Error ok;
- List<String> args;
- args.push_back(p_uri);
- ok = execute("xdg-open", args, false);
- if (ok == OK)
- return OK;
- ok = execute("gnome-open", args, false);
- if (ok == OK)
- return OK;
- ok = execute("kde-open", args, false);
- return ok;
-}
-
-bool OS_X11::_check_internal_feature_support(const String &p_feature) {
-
- return p_feature == "pc";
-}
-
-String OS_X11::get_config_path() const {
-
- if (has_environment("XDG_CONFIG_HOME")) {
- return get_environment("XDG_CONFIG_HOME");
- } else if (has_environment("HOME")) {
- return get_environment("HOME").plus_file(".config");
- } else {
- return ".";
- }
-}
-
-String OS_X11::get_data_path() const {
-
- if (has_environment("XDG_DATA_HOME")) {
- return get_environment("XDG_DATA_HOME");
- } else if (has_environment("HOME")) {
- return get_environment("HOME").plus_file(".local/share");
- } else {
- return get_config_path();
- }
-}
-
-String OS_X11::get_cache_path() const {
-
- if (has_environment("XDG_CACHE_HOME")) {
- return get_environment("XDG_CACHE_HOME");
- } else if (has_environment("HOME")) {
- return get_environment("HOME").plus_file(".cache");
- } else {
- return get_config_path();
- }
-}
-
-String OS_X11::get_system_dir(SystemDir p_dir) const {
-
- String xdgparam;
-
- switch (p_dir) {
- case SYSTEM_DIR_DESKTOP: {
-
- xdgparam = "DESKTOP";
- } break;
- case SYSTEM_DIR_DCIM: {
-
- xdgparam = "PICTURES";
-
- } break;
- case SYSTEM_DIR_DOCUMENTS: {
-
- xdgparam = "DOCUMENTS";
-
- } break;
- case SYSTEM_DIR_DOWNLOADS: {
-
- xdgparam = "DOWNLOAD";
-
- } break;
- case SYSTEM_DIR_MOVIES: {
-
- xdgparam = "VIDEOS";
-
- } break;
- case SYSTEM_DIR_MUSIC: {
-
- xdgparam = "MUSIC";
-
- } break;
- case SYSTEM_DIR_PICTURES: {
-
- xdgparam = "PICTURES";
-
- } break;
- case SYSTEM_DIR_RINGTONES: {
-
- xdgparam = "MUSIC";
-
- } break;
- }
-
- String pipe;
- List<String> arg;
- arg.push_back(xdgparam);
- Error err = const_cast<OS_X11 *>(this)->execute("xdg-user-dir", arg, true, NULL, &pipe);
- if (err != OK)
- return ".";
- return pipe.strip_edges();
-}
-
-void OS_X11::move_window_to_foreground() {
-
- XEvent xev;
- Atom net_active_window = XInternAtom(x11_display, "_NET_ACTIVE_WINDOW", False);
-
- memset(&xev, 0, sizeof(xev));
- xev.type = ClientMessage;
- xev.xclient.window = x11_window;
- xev.xclient.message_type = net_active_window;
- xev.xclient.format = 32;
- xev.xclient.data.l[0] = 1;
- xev.xclient.data.l[1] = CurrentTime;
-
- XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
- XFlush(x11_display);
-}
-
-void OS_X11::set_cursor_shape(CursorShape p_shape) {
-
- ERR_FAIL_INDEX(p_shape, CURSOR_MAX);
-
- if (p_shape == current_cursor) {
- return;
- }
-
- if (mouse_mode == MOUSE_MODE_VISIBLE || mouse_mode == MOUSE_MODE_CONFINED) {
- if (cursors[p_shape] != None) {
- XDefineCursor(x11_display, x11_window, cursors[p_shape]);
- } else if (cursors[CURSOR_ARROW] != None) {
- XDefineCursor(x11_display, x11_window, cursors[CURSOR_ARROW]);
- }
- }
-
- current_cursor = p_shape;
-}
-
-OS::CursorShape OS_X11::get_cursor_shape() const {
-
- return current_cursor;
-}
-
-void OS_X11::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
-
- if (p_cursor.is_valid()) {
-
- Map<CursorShape, Vector<Variant>>::Element *cursor_c = cursors_cache.find(p_shape);
-
- if (cursor_c) {
- if (cursor_c->get()[0] == p_cursor && cursor_c->get()[1] == p_hotspot) {
- set_cursor_shape(p_shape);
- return;
- }
-
- cursors_cache.erase(p_shape);
- }
-
- Ref<Texture2D> texture = p_cursor;
- Ref<AtlasTexture> atlas_texture = p_cursor;
- Ref<Image> image;
- Size2 texture_size;
- Rect2 atlas_rect;
-
- if (texture.is_valid()) {
- image = texture->get_data();
- }
-
- if (!image.is_valid() && atlas_texture.is_valid()) {
- texture = atlas_texture->get_atlas();
-
- atlas_rect.size.width = texture->get_width();
- atlas_rect.size.height = texture->get_height();
- atlas_rect.position.x = atlas_texture->get_region().position.x;
- atlas_rect.position.y = atlas_texture->get_region().position.y;
-
- texture_size.width = atlas_texture->get_region().size.x;
- texture_size.height = atlas_texture->get_region().size.y;
- } else if (image.is_valid()) {
- texture_size.width = texture->get_width();
- texture_size.height = texture->get_height();
- }
-
- ERR_FAIL_COND(!texture.is_valid());
- ERR_FAIL_COND(p_hotspot.x < 0 || p_hotspot.y < 0);
- ERR_FAIL_COND(texture_size.width > 256 || texture_size.height > 256);
- ERR_FAIL_COND(p_hotspot.x > texture_size.width || p_hotspot.y > texture_size.height);
-
- image = texture->get_data();
-
- ERR_FAIL_COND(!image.is_valid());
-
- // Create the cursor structure
- XcursorImage *cursor_image = XcursorImageCreate(texture_size.width, texture_size.height);
- XcursorUInt image_size = texture_size.width * texture_size.height;
- XcursorDim size = sizeof(XcursorPixel) * image_size;
-
- cursor_image->version = 1;
- cursor_image->size = size;
- cursor_image->xhot = p_hotspot.x;
- cursor_image->yhot = p_hotspot.y;
-
- // allocate memory to contain the whole file
- cursor_image->pixels = (XcursorPixel *)memalloc(size);
-
- for (XcursorPixel index = 0; index < image_size; index++) {
- int row_index = floor(index / texture_size.width) + atlas_rect.position.y;
- int column_index = (index % int(texture_size.width)) + atlas_rect.position.x;
-
- if (atlas_texture.is_valid()) {
- column_index = MIN(column_index, atlas_rect.size.width - 1);
- row_index = MIN(row_index, atlas_rect.size.height - 1);
- }
-
- *(cursor_image->pixels + index) = image->get_pixel(column_index, row_index).to_argb32();
- }
-
- ERR_FAIL_COND(cursor_image->pixels == NULL);
-
- // Save it for a further usage
- cursors[p_shape] = XcursorImageLoadCursor(x11_display, cursor_image);
-
- Vector<Variant> params;
- params.push_back(p_cursor);
- params.push_back(p_hotspot);
- cursors_cache.insert(p_shape, params);
-
- if (p_shape == current_cursor) {
- if (mouse_mode == MOUSE_MODE_VISIBLE || mouse_mode == MOUSE_MODE_CONFINED) {
- XDefineCursor(x11_display, x11_window, cursors[p_shape]);
- }
- }
-
- memfree(cursor_image->pixels);
- XcursorImageDestroy(cursor_image);
- } else {
- // Reset to default system cursor
- if (img[p_shape]) {
- cursors[p_shape] = XcursorImageLoadCursor(x11_display, img[p_shape]);
- }
-
- CursorShape c = current_cursor;
- current_cursor = CURSOR_MAX;
- set_cursor_shape(c);
-
- cursors_cache.erase(p_shape);
- }
-}
-
-void OS_X11::release_rendering_thread() {
-#if defined(OPENGL_ENABLED)
- if (video_driver_index == VIDEO_DRIVER_GLES2) {
- context_gles2->release_current();
- }
-#endif
-}
-
-void OS_X11::make_rendering_thread() {
-#if defined(OPENGL_ENABLED)
- if (video_driver_index == VIDEO_DRIVER_GLES2) {
- context_gles2->make_current();
- }
-#endif
-}
-
-void OS_X11::swap_buffers() {
-#if defined(OPENGL_ENABLED)
- if (video_driver_index == VIDEO_DRIVER_GLES2) {
- context_gles2->swap_buffers();
- }
-#endif
- /* not needed for now
-#if defined(VULKAN_ENABLED)
- if (video_driver_index == VIDEO_DRIVER_VULKAN) {
- context_vulkan->swap_buffers();
- }
-#endif*/
-}
-
-void OS_X11::alert(const String &p_alert, const String &p_title) {
- const char *message_programs[] = { "zenity", "kdialog", "Xdialog", "xmessage" };
-
- String path = get_environment("PATH");
- Vector<String> path_elems = path.split(":", false);
- String program;
-
- for (int i = 0; i < path_elems.size(); i++) {
- for (uint64_t k = 0; k < sizeof(message_programs) / sizeof(char *); k++) {
- String tested_path = path_elems[i].plus_file(message_programs[k]);
-
- if (FileAccess::exists(tested_path)) {
- program = tested_path;
- break;
- }
- }
-
- if (program.length())
- break;
- }
-
- List<String> args;
-
- if (program.ends_with("zenity")) {
- args.push_back("--error");
- args.push_back("--width");
- args.push_back("500");
- args.push_back("--title");
- args.push_back(p_title);
- args.push_back("--text");
- args.push_back(p_alert);
- }
-
- if (program.ends_with("kdialog")) {
- args.push_back("--error");
- args.push_back(p_alert);
- args.push_back("--title");
- args.push_back(p_title);
- }
-
- if (program.ends_with("Xdialog")) {
- args.push_back("--title");
- args.push_back(p_title);
- args.push_back("--msgbox");
- args.push_back(p_alert);
- args.push_back("0");
- args.push_back("0");
- }
-
- if (program.ends_with("xmessage")) {
- args.push_back("-center");
- args.push_back("-title");
- args.push_back(p_title);
- args.push_back(p_alert);
- }
-
- if (program.length()) {
- execute(program, args, true);
- } else {
- print_line(p_alert);
- }
-}
-
-bool g_set_icon_error = false;
-int set_icon_errorhandler(Display *dpy, XErrorEvent *ev) {
- g_set_icon_error = true;
- return 0;
-}
-
-void OS_X11::set_icon(const Ref<Image> &p_icon) {
- int (*oldHandler)(Display *, XErrorEvent *) = XSetErrorHandler(&set_icon_errorhandler);
-
- Atom net_wm_icon = XInternAtom(x11_display, "_NET_WM_ICON", False);
-
- if (p_icon.is_valid()) {
- Ref<Image> img = p_icon->duplicate();
- img->convert(Image::FORMAT_RGBA8);
-
- while (true) {
- int w = img->get_width();
- int h = img->get_height();
-
- if (g_set_icon_error) {
- g_set_icon_error = false;
-
- WARN_PRINT("Icon too large, attempting to resize icon.");
-
- int new_width, new_height;
- if (w > h) {
- new_width = w / 2;
- new_height = h * new_width / w;
- } else {
- new_height = h / 2;
- new_width = w * new_height / h;
- }
-
- w = new_width;
- h = new_height;
-
- if (!w || !h) {
- WARN_PRINT("Unable to set icon.");
- break;
- }
-
- img->resize(w, h, Image::INTERPOLATE_CUBIC);
- }
-
- // We're using long to have wordsize (32Bit build -> 32 Bits, 64 Bit build -> 64 Bits
- Vector<long> pd;
-
- pd.resize(2 + w * h);
-
- pd.write[0] = w;
- pd.write[1] = h;
-
- const uint8_t *r = img->get_data().ptr();
-
- long *wr = &pd.write[2];
- uint8_t const *pr = r;
-
- for (int i = 0; i < w * h; i++) {
- long v = 0;
- // A R G B
- v |= pr[3] << 24 | pr[0] << 16 | pr[1] << 8 | pr[2];
- *wr++ = v;
- pr += 4;
- }
-
- XChangeProperty(x11_display, x11_window, net_wm_icon, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)pd.ptr(), pd.size());
-
- if (!g_set_icon_error)
- break;
- }
- } else {
- XDeleteProperty(x11_display, x11_window, net_wm_icon);
- }
-
- XFlush(x11_display);
- XSetErrorHandler(oldHandler);
-}
-
-void OS_X11::force_process_input() {
- process_xevents(); // get rid of pending events
-#ifdef JOYDEV_ENABLED
- joypad->process_joypads();
-#endif
-}
-
-void OS_X11::run() {
-
- force_quit = false;
-
- if (!main_loop)
- return;
-
- main_loop->init();
-
- //uint64_t last_ticks=get_ticks_usec();
-
- //int frames=0;
- //uint64_t frame=0;
-
- while (!force_quit) {
-
- process_xevents(); // get rid of pending events
-#ifdef JOYDEV_ENABLED
- joypad->process_joypads();
-#endif
- if (Main::iteration())
- break;
- };
-
- main_loop->finish();
-}
-
-bool OS_X11::is_joy_known(int p_device) {
- return input->is_joy_mapped(p_device);
-}
-
-String OS_X11::get_joy_guid(int p_device) const {
- return input->get_joy_guid_remapped(p_device);
-}
-
-void OS_X11::_set_use_vsync(bool p_enable) {
-#if defined(OPENGL_ENABLED)
- if (video_driver_index == VIDEO_DRIVER_GLES2) {
- if (context_gles2)
- context_gles2->set_use_vsync(p_enable);
- }
-#endif
-}
-
-void OS_X11::set_context(int p_context) {
-
- XClassHint *classHint = XAllocClassHint();
-
- if (classHint) {
-
- CharString name_str;
- switch (p_context) {
- case CONTEXT_EDITOR:
- name_str = "Godot_Editor";
- break;
- case CONTEXT_PROJECTMAN:
- name_str = "Godot_ProjectList";
- break;
- case CONTEXT_ENGINE:
- name_str = "Godot_Engine";
- break;
- }
-
- CharString class_str;
- if (p_context == CONTEXT_ENGINE) {
- String config_name = GLOBAL_GET("application/config/name");
- if (config_name.length() == 0) {
- class_str = "Godot_Engine";
- } else {
- class_str = config_name.utf8();
- }
- } else {
- class_str = "Godot";
- }
-
- classHint->res_class = class_str.ptrw();
- classHint->res_name = name_str.ptrw();
-
- XSetClassHint(x11_display, x11_window, classHint);
- XFree(classHint);
- }
-}
-
-void OS_X11::disable_crash_handler() {
- crash_handler.disable();
-}
-
-bool OS_X11::is_disable_crash_handler() const {
- return crash_handler.is_disabled();
-}
-
-static String get_mountpoint(const String &p_path) {
- struct stat s;
- if (stat(p_path.utf8().get_data(), &s)) {
- return "";
- }
-
-#ifdef HAVE_MNTENT
- dev_t dev = s.st_dev;
- FILE *fd = setmntent("/proc/mounts", "r");
- if (!fd) {
- return "";
- }
-
- struct mntent mnt;
- char buf[1024];
- size_t buflen = 1024;
- while (getmntent_r(fd, &mnt, buf, buflen)) {
- if (!stat(mnt.mnt_dir, &s) && s.st_dev == dev) {
- endmntent(fd);
- return String(mnt.mnt_dir);
- }
- }
-
- endmntent(fd);
-#endif
- return "";
-}
-
-Error OS_X11::move_to_trash(const String &p_path) {
- String trash_can = "";
- String mnt = get_mountpoint(p_path);
-
- // If there is a directory "[Mountpoint]/.Trash-[UID]/files", use it as the trash can.
- if (mnt != "") {
- String path(mnt + "/.Trash-" + itos(getuid()) + "/files");
- struct stat s;
- if (!stat(path.utf8().get_data(), &s)) {
- trash_can = path;
- }
- }
-
- // Otherwise, if ${XDG_DATA_HOME} is defined, use "${XDG_DATA_HOME}/Trash/files" as the trash can.
- if (trash_can == "") {
- char *dhome = getenv("XDG_DATA_HOME");
- if (dhome) {
- trash_can = String(dhome) + "/Trash/files";
- }
- }
-
- // Otherwise, if ${HOME} is defined, use "${HOME}/.local/share/Trash/files" as the trash can.
- if (trash_can == "") {
- char *home = getenv("HOME");
- if (home) {
- trash_can = String(home) + "/.local/share/Trash/files";
- }
- }
-
- // Issue an error if none of the previous locations is appropriate for the trash can.
- if (trash_can == "") {
- ERR_PRINT("move_to_trash: Could not determine the trash can location");
- return FAILED;
- }
-
- // Create needed directories for decided trash can location.
- DirAccess *dir_access = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
- Error err = dir_access->make_dir_recursive(trash_can);
- memdelete(dir_access);
-
- // Issue an error if trash can is not created proprely.
- if (err != OK) {
- ERR_PRINT("move_to_trash: Could not create the trash can \"" + trash_can + "\"");
- return err;
- }
-
- // The trash can is successfully created, now move the given resource to it.
- // Do not use DirAccess:rename() because it can't move files across multiple mountpoints.
- List<String> mv_args;
- mv_args.push_back(p_path);
- mv_args.push_back(trash_can);
- int retval;
- err = execute("mv", mv_args, true, NULL, NULL, &retval);
-
- // Issue an error if "mv" failed to move the given resource to the trash can.
- if (err != OK || retval != 0) {
- ERR_PRINT("move_to_trash: Could not move the resource \"" + p_path + "\" to the trash can \"" + trash_can + "\"");
- return FAILED;
- }
-
- return OK;
-}
-
-OS::LatinKeyboardVariant OS_X11::get_latin_keyboard_variant() const {
-
- XkbDescRec *xkbdesc = XkbAllocKeyboard();
- ERR_FAIL_COND_V(!xkbdesc, LATIN_KEYBOARD_QWERTY);
-
- XkbGetNames(x11_display, XkbSymbolsNameMask, xkbdesc);
- ERR_FAIL_COND_V(!xkbdesc->names, LATIN_KEYBOARD_QWERTY);
- ERR_FAIL_COND_V(!xkbdesc->names->symbols, LATIN_KEYBOARD_QWERTY);
-
- char *layout = XGetAtomName(x11_display, xkbdesc->names->symbols);
- ERR_FAIL_COND_V(!layout, LATIN_KEYBOARD_QWERTY);
-
- Vector<String> info = String(layout).split("+");
- ERR_FAIL_INDEX_V(1, info.size(), LATIN_KEYBOARD_QWERTY);
-
- if (info[1].find("colemak") != -1) {
- return LATIN_KEYBOARD_COLEMAK;
- } else if (info[1].find("qwertz") != -1) {
- return LATIN_KEYBOARD_QWERTZ;
- } else if (info[1].find("azerty") != -1) {
- return LATIN_KEYBOARD_AZERTY;
- } else if (info[1].find("qzerty") != -1) {
- return LATIN_KEYBOARD_QZERTY;
- } else if (info[1].find("dvorak") != -1) {
- return LATIN_KEYBOARD_DVORAK;
- } else if (info[1].find("neo") != -1) {
- return LATIN_KEYBOARD_NEO;
- }
-
- return LATIN_KEYBOARD_QWERTY;
-}
-
-void OS_X11::update_real_mouse_position() {
- Window root_return, child_return;
- int root_x, root_y, win_x, win_y;
- unsigned int mask_return;
-
- Bool xquerypointer_result = XQueryPointer(x11_display, x11_window, &root_return, &child_return, &root_x, &root_y,
- &win_x, &win_y, &mask_return);
-
- if (xquerypointer_result) {
- if (win_x > 0 && win_y > 0 && win_x <= current_videomode.width && win_y <= current_videomode.height) {
-
- last_mouse_pos.x = win_x;
- last_mouse_pos.y = win_y;
- last_mouse_pos_valid = true;
- input->set_mouse_position(last_mouse_pos);
- }
- }
-}
-
-OS_X11::OS_X11() {
-
-#ifdef PULSEAUDIO_ENABLED
- AudioDriverManager::add_driver(&driver_pulseaudio);
-#endif
-
-#ifdef ALSA_ENABLED
- AudioDriverManager::add_driver(&driver_alsa);
-#endif
-
- xi.opcode = 0;
- xi.last_relative_time = 0;
- layered_window = false;
- minimized = false;
- window_focused = true;
- xim_style = 0L;
- mouse_mode = MOUSE_MODE_VISIBLE;
- last_position_before_fs = Vector2();
-}
diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h
deleted file mode 100644
index 4cdf5445ce..0000000000
--- a/platform/x11/os_x11.h
+++ /dev/null
@@ -1,338 +0,0 @@
-/*************************************************************************/
-/* os_x11.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#ifndef OS_X11_H
-#define OS_X11_H
-
-#include "core/input/input.h"
-#include "crash_handler_x11.h"
-#include "drivers/alsa/audio_driver_alsa.h"
-#include "drivers/alsamidi/midi_driver_alsamidi.h"
-#include "drivers/pulseaudio/audio_driver_pulseaudio.h"
-#include "drivers/unix/os_unix.h"
-#include "joypad_linux.h"
-#include "servers/audio_server.h"
-#include "servers/visual/rasterizer.h"
-#include "servers/visual_server.h"
-
-#if defined(OPENGL_ENABLED)
-#include "context_gl_x11.h"
-#endif
-
-#if defined(VULKAN_ENABLED)
-#include "drivers/vulkan/rendering_device_vulkan.h"
-#include "platform/x11/vulkan_context_x11.h"
-#endif
-
-#include <X11/Xcursor/Xcursor.h>
-#include <X11/Xlib.h>
-#include <X11/extensions/XInput2.h>
-#include <X11/extensions/Xrandr.h>
-#include <X11/keysym.h>
-
-// Hints for X11 fullscreen
-typedef struct {
- unsigned long flags;
- unsigned long functions;
- unsigned long decorations;
- long inputMode;
- unsigned long status;
-} Hints;
-
-typedef struct _xrr_monitor_info {
- Atom name;
- Bool primary;
- Bool automatic;
- int noutput;
- int x;
- int y;
- int width;
- int height;
- int mwidth;
- int mheight;
- RROutput *outputs;
-} xrr_monitor_info;
-
-#undef CursorShape
-
-class OS_X11 : public OS_Unix {
-
- Atom wm_delete;
- Atom xdnd_enter;
- Atom xdnd_position;
- Atom xdnd_status;
- Atom xdnd_action_copy;
- Atom xdnd_drop;
- Atom xdnd_finished;
- Atom xdnd_selection;
- Atom requested;
-
- int xdnd_version;
-
-#if defined(OPENGL_ENABLED)
- ContextGL_X11 *context_gles2;
-#endif
-#if defined(VULKAN_ENABLED)
- VulkanContextX11 *context_vulkan;
- RenderingDeviceVulkan *rendering_device_vulkan;
-#endif
-
- //Rasterizer *rasterizer;
- VisualServer *visual_server;
- VideoMode current_videomode;
- List<String> args;
- Window x11_window;
- Window xdnd_source_window;
- MainLoop *main_loop;
- ::Display *x11_display;
- char *xmbstring;
- int xmblen;
- unsigned long last_timestamp;
- ::Time last_keyrelease_time;
- ::XIC xic;
- ::XIM xim;
- ::XIMStyle xim_style;
- static void xim_destroy_callback(::XIM im, ::XPointer client_data,
- ::XPointer call_data);
-
- // IME
- bool im_active;
- Vector2 im_position;
- Vector2 last_position_before_fs;
-
- Size2 min_size;
- Size2 max_size;
-
- Point2 last_mouse_pos;
- bool last_mouse_pos_valid;
- Point2i last_click_pos;
- uint64_t last_click_ms;
- int last_click_button_index;
- uint32_t last_button_state;
-
- struct {
- int opcode;
- Vector<int> touch_devices;
- Map<int, Vector2> absolute_devices;
- Map<int, Vector3> pen_devices;
- XIEventMask all_event_mask;
- XIEventMask all_master_event_mask;
- Map<int, Vector2> state;
- double pressure;
- Vector2 tilt;
- Vector2 mouse_pos_to_filter;
- Vector2 relative_motion;
- Vector2 raw_pos;
- Vector2 old_raw_pos;
- ::Time last_relative_time;
- } xi;
-
- bool refresh_device_info();
-
- unsigned int get_mouse_button_state(unsigned int p_x11_button, int p_x11_type);
- void get_key_modifier_state(unsigned int p_x11_state, Ref<InputEventWithModifiers> state);
- void flush_mouse_motion();
-
- MouseMode mouse_mode;
- Point2i center;
-
- void handle_key_event(XKeyEvent *p_event, bool p_echo = false);
- void process_xevents();
- virtual void delete_main_loop();
-
- bool force_quit;
- bool minimized;
- bool window_has_focus;
- bool do_mouse_warp;
-
- const char *cursor_theme;
- int cursor_size;
- XcursorImage *img[CURSOR_MAX];
- Cursor cursors[CURSOR_MAX];
- Cursor null_cursor;
- CursorShape current_cursor;
- Map<CursorShape, Vector<Variant>> cursors_cache;
-
- Input *input;
-
-#ifdef JOYDEV_ENABLED
- JoypadLinux *joypad;
-#endif
-
-#ifdef ALSA_ENABLED
- AudioDriverALSA driver_alsa;
-#endif
-
-#ifdef ALSAMIDI_ENABLED
- MIDIDriverALSAMidi driver_alsamidi;
-#endif
-
-#ifdef PULSEAUDIO_ENABLED
- AudioDriverPulseAudio driver_pulseaudio;
-#endif
-
- bool layered_window;
-
- CrashHandler crash_handler;
-
- int video_driver_index;
- bool maximized;
- bool window_focused;
- //void set_wm_border(bool p_enabled);
- void set_wm_fullscreen(bool p_enabled);
- void set_wm_above(bool p_enabled);
-
- typedef xrr_monitor_info *(*xrr_get_monitors_t)(Display *dpy, Window window, Bool get_active, int *nmonitors);
- typedef void (*xrr_free_monitors_t)(xrr_monitor_info *monitors);
- xrr_get_monitors_t xrr_get_monitors;
- xrr_free_monitors_t xrr_free_monitors;
- void *xrandr_handle;
- Bool xrandr_ext_ok;
-
-protected:
- virtual int get_current_video_driver() const;
-
- virtual void initialize_core();
- virtual Error initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
- virtual void finalize();
-
- virtual void set_main_loop(MainLoop *p_main_loop);
-
- void _window_changed(XEvent *event);
-
- bool is_window_maximize_allowed();
-
-public:
- virtual String get_name() const;
-
- virtual void set_cursor_shape(CursorShape p_shape);
- virtual CursorShape get_cursor_shape() const;
- virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot);
-
- void set_mouse_mode(MouseMode p_mode);
- MouseMode get_mouse_mode() const;
-
- virtual void warp_mouse_position(const Point2 &p_to);
- virtual Point2 get_mouse_position() const;
- virtual int get_mouse_button_state() const;
- virtual void set_window_title(const String &p_title);
-
- virtual void set_icon(const Ref<Image> &p_icon);
-
- virtual MainLoop *get_main_loop() const;
-
- virtual bool can_draw() const;
-
- virtual void set_clipboard(const String &p_text);
- virtual String get_clipboard() const;
-
- virtual void release_rendering_thread();
- virtual void make_rendering_thread();
- virtual void swap_buffers();
-
- virtual String get_config_path() const;
- virtual String get_data_path() const;
- virtual String get_cache_path() const;
-
- virtual String get_system_dir(SystemDir p_dir) const;
-
- virtual Error shell_open(String p_uri);
-
- virtual void set_video_mode(const VideoMode &p_video_mode, int p_screen = 0);
- virtual VideoMode get_video_mode(int p_screen = 0) const;
- virtual void get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen = 0) const;
-
- virtual int get_screen_count() const;
- virtual int get_current_screen() const;
- virtual void set_current_screen(int p_screen);
- virtual Point2 get_screen_position(int p_screen = -1) const;
- virtual Size2 get_screen_size(int p_screen = -1) const;
- virtual int get_screen_dpi(int p_screen = -1) const;
- virtual Point2 get_window_position() const;
- virtual void set_window_position(const Point2 &p_position);
- virtual Size2 get_window_size() const;
- virtual Size2 get_real_window_size() const;
- virtual Size2 get_max_window_size() const;
- virtual Size2 get_min_window_size() const;
- virtual void set_min_window_size(const Size2 p_size);
- virtual void set_max_window_size(const Size2 p_size);
- virtual void set_window_size(const Size2 p_size);
- virtual void set_window_fullscreen(bool p_enabled);
- virtual bool is_window_fullscreen() const;
- virtual void set_window_resizable(bool p_enabled);
- virtual bool is_window_resizable() const;
- virtual void set_window_minimized(bool p_enabled);
- virtual bool is_window_minimized() const;
- virtual void set_window_maximized(bool p_enabled);
- virtual bool is_window_maximized() const;
- virtual void set_window_always_on_top(bool p_enabled);
- virtual bool is_window_always_on_top() const;
- virtual bool is_window_focused() const;
- virtual void request_attention();
-
- virtual void set_borderless_window(bool p_borderless);
- virtual bool get_borderless_window();
-
- virtual bool get_window_per_pixel_transparency_enabled() const;
- virtual void set_window_per_pixel_transparency_enabled(bool p_enabled);
-
- virtual void set_ime_active(const bool p_active);
- virtual void set_ime_position(const Point2 &p_pos);
-
- virtual String get_unique_id() const;
-
- virtual void move_window_to_foreground();
- virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
-
- virtual bool is_joy_known(int p_device);
- virtual String get_joy_guid(int p_device) const;
-
- virtual void set_context(int p_context);
-
- virtual void _set_use_vsync(bool p_enable);
- //virtual bool is_vsync_enabled() const;
-
- virtual bool _check_internal_feature_support(const String &p_feature);
-
- virtual void force_process_input();
- void run();
-
- void disable_crash_handler();
- bool is_disable_crash_handler() const;
-
- virtual Error move_to_trash(const String &p_path);
-
- virtual LatinKeyboardVariant get_latin_keyboard_variant() const;
-
- void update_real_mouse_position();
- OS_X11();
-};
-
-#endif
diff --git a/scene/2d/particles_2d.cpp b/scene/2d/particles_2d.cpp
index 2ba2fd8f79..e5c17fe9a4 100644
--- a/scene/2d/particles_2d.cpp
+++ b/scene/2d/particles_2d.cpp
@@ -228,7 +228,7 @@ bool Particles2D::get_fractional_delta() const {
String Particles2D::get_configuration_warning() const {
- if (OS::get_singleton()->get_current_video_driver() == OS::VIDEO_DRIVER_GLES2) {
+ if (VisualServer::get_singleton()->is_low_end()) {
return TTR("GPU-based particles are not supported by the GLES2 video driver.\nUse the CPUParticles2D node instead. You can use the \"Convert to CPUParticles\" option for this purpose.");
}
diff --git a/scene/2d/touch_screen_button.cpp b/scene/2d/touch_screen_button.cpp
index 20d73113dc..0f79e12275 100644
--- a/scene/2d/touch_screen_button.cpp
+++ b/scene/2d/touch_screen_button.cpp
@@ -33,6 +33,7 @@
#include "core/input/input.h"
#include "core/input/input_map.h"
#include "core/os/os.h"
+#include "scene/main/viewport.h"
void TouchScreenButton::set_texture(const Ref<Texture2D> &p_texture) {
@@ -114,7 +115,7 @@ void TouchScreenButton::_notification(int p_what) {
if (!is_inside_tree())
return;
- if (!Engine::get_singleton()->is_editor_hint() && !OS::get_singleton()->has_touchscreen_ui_hint() && visibility == VISIBILITY_TOUCHSCREEN_ONLY)
+ if (!Engine::get_singleton()->is_editor_hint() && !!DisplayServer::get_singleton()->screen_is_touchscreen(DisplayServer::get_singleton()->window_get_current_screen(get_viewport()->get_window_id())) && visibility == VISIBILITY_TOUCHSCREEN_ONLY)
return;
if (finger_pressed != -1) {
@@ -145,7 +146,7 @@ void TouchScreenButton::_notification(int p_what) {
} break;
case NOTIFICATION_ENTER_TREE: {
- if (!Engine::get_singleton()->is_editor_hint() && !OS::get_singleton()->has_touchscreen_ui_hint() && visibility == VISIBILITY_TOUCHSCREEN_ONLY)
+ if (!Engine::get_singleton()->is_editor_hint() && !!DisplayServer::get_singleton()->screen_is_touchscreen(DisplayServer::get_singleton()->window_get_current_screen(get_viewport()->get_window_id())) && visibility == VISIBILITY_TOUCHSCREEN_ONLY)
return;
update();
diff --git a/scene/3d/gi_probe.cpp b/scene/3d/gi_probe.cpp
index c3f039ae85..76549f7e51 100644
--- a/scene/3d/gi_probe.cpp
+++ b/scene/3d/gi_probe.cpp
@@ -526,7 +526,7 @@ Vector<Face3> GIProbe::get_faces(uint32_t p_usage_flags) const {
String GIProbe::get_configuration_warning() const {
- if (OS::get_singleton()->get_current_video_driver() == OS::VIDEO_DRIVER_GLES2) {
+ if (VisualServer::get_singleton()->is_low_end()) {
return TTR("GIProbes are not supported by the GLES2 video driver.\nUse a BakedLightmap instead.");
}
return String();
diff --git a/scene/3d/particles.cpp b/scene/3d/particles.cpp
index e502b0c037..7a1eeb105a 100644
--- a/scene/3d/particles.cpp
+++ b/scene/3d/particles.cpp
@@ -240,7 +240,7 @@ bool Particles::get_fractional_delta() const {
String Particles::get_configuration_warning() const {
- if (OS::get_singleton()->get_current_video_driver() == OS::VIDEO_DRIVER_GLES2) {
+ if (VisualServer::get_singleton()->is_low_end()) {
return TTR("GPU-based particles are not supported by the GLES2 video driver.\nUse the CPUParticles node instead. You can use the \"Convert to CPUParticles\" option for this purpose.");
}
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index 7ee4dab3c9..8466612c85 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -36,12 +36,12 @@
#include "core/print_string.h"
#include "core/translation.h"
#include "label.h"
-
+#include "servers/display_server.h"
#ifdef TOOLS_ENABLED
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
#endif
-
+#include "scene/main/viewport.h"
static bool _is_text_char(CharType c) {
return !is_symbol(c);
@@ -127,8 +127,8 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
selection.creating = false;
selection.doubleclick = false;
- if (OS::get_singleton()->has_virtual_keyboard())
- OS::get_singleton()->show_virtual_keyboard(text, get_global_rect(), max_length);
+ if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD))
+ DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), max_length);
}
update();
@@ -304,8 +304,8 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
case KEY_ENTER: {
emit_signal("text_entered", text);
- if (OS::get_singleton()->has_virtual_keyboard())
- OS::get_singleton()->hide_virtual_keyboard();
+ if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD))
+ DisplayServer::get_singleton()->virtual_keyboard_hide();
} break;
@@ -914,8 +914,8 @@ void LineEdit::_notification(int p_what) {
if (has_focus()) {
- OS::get_singleton()->set_ime_active(true);
- OS::get_singleton()->set_ime_position(get_global_position() + Point2(using_placeholder ? 0 : x_ofs, y_ofs + caret_height));
+ DisplayServer::get_singleton()->window_set_ime_active(true, get_viewport()->get_window_id());
+ DisplayServer::get_singleton()->window_set_ime_position(get_global_position() + Point2(using_placeholder ? 0 : x_ofs, y_ofs + caret_height), get_viewport()->get_window_id());
}
} break;
case NOTIFICATION_FOCUS_ENTER: {
@@ -926,12 +926,12 @@ void LineEdit::_notification(int p_what) {
draw_caret = true;
}
- OS::get_singleton()->set_ime_active(true);
+ DisplayServer::get_singleton()->window_set_ime_active(true, get_viewport()->get_window_id());
Point2 cursor_pos = Point2(get_cursor_position(), 1) * get_minimum_size().height;
- OS::get_singleton()->set_ime_position(get_global_position() + cursor_pos);
+ DisplayServer::get_singleton()->window_set_ime_position(get_global_position() + cursor_pos, get_viewport()->get_window_id());
- if (OS::get_singleton()->has_virtual_keyboard())
- OS::get_singleton()->show_virtual_keyboard(text, get_global_rect(), max_length);
+ if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD))
+ DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), max_length);
} break;
case NOTIFICATION_FOCUS_EXIT: {
@@ -940,20 +940,20 @@ void LineEdit::_notification(int p_what) {
caret_blink_timer->stop();
}
- OS::get_singleton()->set_ime_position(Point2());
- OS::get_singleton()->set_ime_active(false);
+ DisplayServer::get_singleton()->window_set_ime_position(Point2(), get_viewport()->get_window_id());
+ DisplayServer::get_singleton()->window_set_ime_active(false, get_viewport()->get_window_id());
ime_text = "";
ime_selection = Point2();
- if (OS::get_singleton()->has_virtual_keyboard())
- OS::get_singleton()->hide_virtual_keyboard();
+ if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD))
+ DisplayServer::get_singleton()->virtual_keyboard_hide();
} break;
case MainLoop::NOTIFICATION_OS_IME_UPDATE: {
if (has_focus()) {
- ime_text = OS::get_singleton()->get_ime_text();
- ime_selection = OS::get_singleton()->get_ime_selection();
+ ime_text = DisplayServer::get_singleton()->ime_get_text();
+ ime_selection = DisplayServer::get_singleton()->ime_get_selection();
update();
}
} break;
@@ -963,14 +963,14 @@ void LineEdit::_notification(int p_what) {
void LineEdit::copy_text() {
if (selection.enabled && !pass) {
- OS::get_singleton()->set_clipboard(text.substr(selection.begin, selection.end - selection.begin));
+ DisplayServer::get_singleton()->clipboard_set(text.substr(selection.begin, selection.end - selection.begin));
}
}
void LineEdit::cut_text() {
if (selection.enabled && !pass) {
- OS::get_singleton()->set_clipboard(text.substr(selection.begin, selection.end - selection.begin));
+ DisplayServer::get_singleton()->clipboard_set(text.substr(selection.begin, selection.end - selection.begin));
selection_delete();
}
}
@@ -978,7 +978,7 @@ void LineEdit::cut_text() {
void LineEdit::paste_text() {
// Strip escape characters like \n and \t as they can't be displayed on LineEdit.
- String paste_buffer = OS::get_singleton()->get_clipboard().strip_escapes();
+ String paste_buffer = DisplayServer::get_singleton()->clipboard_get().strip_escapes();
if (paste_buffer != "") {
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index e4651ef473..2a21df002c 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -34,6 +34,7 @@
#include "core/os/keyboard.h"
#include "core/os/os.h"
#include "scene/scene_string_names.h"
+#include "servers/display_server.h"
#include "modules/modules_enabled.gen.h"
#ifdef MODULE_REGEX_ENABLED
@@ -2584,7 +2585,7 @@ void RichTextLabel::selection_copy() {
}
if (text != "") {
- OS::get_singleton()->set_clipboard(text);
+ DisplayServer::get_singleton()->clipboard_set(text);
}
}
diff --git a/scene/gui/scroll_bar.cpp b/scene/gui/scroll_bar.cpp
index fef5e00984..4750853c3b 100644
--- a/scene/gui/scroll_bar.cpp
+++ b/scene/gui/scroll_bar.cpp
@@ -33,6 +33,7 @@
#include "core/os/keyboard.h"
#include "core/os/os.h"
#include "core/print_string.h"
+#include "scene/main/viewport.h"
bool ScrollBar::focus_by_default = false;
@@ -559,8 +560,7 @@ void ScrollBar::_drag_node_input(const Ref<InputEvent> &p_input) {
drag_node_accum = Vector2();
last_drag_node_accum = Vector2();
drag_node_from = Vector2(orientation == HORIZONTAL ? get_value() : 0, orientation == VERTICAL ? get_value() : 0);
-
- drag_node_touching = OS::get_singleton()->has_touchscreen_ui_hint();
+ drag_node_touching = !DisplayServer::get_singleton()->screen_is_touchscreen(DisplayServer::get_singleton()->window_get_current_screen(get_viewport()->get_window_id()));
drag_node_touching_deaccel = false;
time_since_motion = 0;
diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp
index c25a6d5a0c..8bd741f4d8 100644
--- a/scene/gui/scroll_container.cpp
+++ b/scene/gui/scroll_container.cpp
@@ -129,7 +129,7 @@ void ScrollContainer::_gui_input(const Ref<InputEvent> &p_gui_input) {
if (v_scroll->get_value() != prev_v_scroll || h_scroll->get_value() != prev_h_scroll)
accept_event(); //accept event if scroll changed
- if (!OS::get_singleton()->has_touchscreen_ui_hint())
+ if (!DisplayServer::get_singleton()->screen_is_touchscreen(DisplayServer::get_singleton()->window_get_current_screen(get_viewport()->get_window_id())))
return;
if (mb->get_button_index() != BUTTON_LEFT)
@@ -145,7 +145,7 @@ void ScrollContainer::_gui_input(const Ref<InputEvent> &p_gui_input) {
drag_accum = Vector2();
last_drag_accum = Vector2();
drag_from = Vector2(h_scroll->get_value(), v_scroll->get_value());
- drag_touching = OS::get_singleton()->has_touchscreen_ui_hint();
+ drag_touching = !DisplayServer::get_singleton()->screen_is_touchscreen(DisplayServer::get_singleton()->window_get_current_screen(get_viewport()->get_window_id()));
drag_touching_deaccel = false;
beyond_deadzone = false;
time_since_motion = 0;
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 46f6d002cd..dd535ba76f 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -1754,8 +1754,8 @@ void TextEdit::_notification(int p_what) {
}
if (has_focus()) {
- OS::get_singleton()->set_ime_active(true);
- OS::get_singleton()->set_ime_position(get_global_position() + cursor_pos + Point2(0, get_row_height()));
+ DisplayServer::get_singleton()->window_set_ime_active(true);
+ DisplayServer::get_singleton()->window_set_ime_position(get_global_position() + cursor_pos + Point2(0, get_row_height()));
}
} break;
case NOTIFICATION_FOCUS_ENTER: {
@@ -1766,12 +1766,12 @@ void TextEdit::_notification(int p_what) {
draw_caret = true;
}
- OS::get_singleton()->set_ime_active(true);
+ DisplayServer::get_singleton()->window_set_ime_active(true);
Point2 cursor_pos = Point2(cursor_get_column(), cursor_get_line()) * get_row_height();
- OS::get_singleton()->set_ime_position(get_global_position() + cursor_pos);
+ DisplayServer::get_singleton()->window_set_ime_position(get_global_position() + cursor_pos);
- if (OS::get_singleton()->has_virtual_keyboard())
- OS::get_singleton()->show_virtual_keyboard(get_text(), get_global_rect());
+ if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD))
+ DisplayServer::get_singleton()->virtual_keyboard_show(get_text(), get_global_rect());
} break;
case NOTIFICATION_FOCUS_EXIT: {
@@ -1779,19 +1779,19 @@ void TextEdit::_notification(int p_what) {
caret_blink_timer->stop();
}
- OS::get_singleton()->set_ime_position(Point2());
- OS::get_singleton()->set_ime_active(false);
+ DisplayServer::get_singleton()->window_set_ime_position(Point2());
+ DisplayServer::get_singleton()->window_set_ime_active(false);
ime_text = "";
ime_selection = Point2();
- if (OS::get_singleton()->has_virtual_keyboard())
- OS::get_singleton()->hide_virtual_keyboard();
+ if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD))
+ DisplayServer::get_singleton()->virtual_keyboard_hide();
} break;
case MainLoop::NOTIFICATION_OS_IME_UPDATE: {
if (has_focus()) {
- ime_text = OS::get_singleton()->get_ime_text();
- ime_selection = OS::get_singleton()->get_ime_selection();
+ ime_text = DisplayServer::get_singleton()->ime_get_text();
+ ime_selection = DisplayServer::get_singleton()->ime_get_selection();
update();
}
} break;
@@ -5226,7 +5226,7 @@ void TextEdit::cut() {
if (!selection.active) {
String clipboard = text[cursor.line];
- OS::get_singleton()->set_clipboard(clipboard);
+ DisplayServer::get_singleton()->clipboard_set(clipboard);
cursor_set_line(cursor.line);
cursor_set_column(0);
@@ -5244,7 +5244,7 @@ void TextEdit::cut() {
} else {
String clipboard = _base_get_text(selection.from_line, selection.from_column, selection.to_line, selection.to_column);
- OS::get_singleton()->set_clipboard(clipboard);
+ DisplayServer::get_singleton()->clipboard_set(clipboard);
_remove_text(selection.from_line, selection.from_column, selection.to_line, selection.to_column);
cursor_set_line(selection.from_line); // Set afterwards else it causes the view to be offset.
@@ -5264,19 +5264,19 @@ void TextEdit::copy() {
if (text[cursor.line].length() != 0) {
String clipboard = _base_get_text(cursor.line, 0, cursor.line, text[cursor.line].length());
- OS::get_singleton()->set_clipboard(clipboard);
+ DisplayServer::get_singleton()->clipboard_set(clipboard);
cut_copy_line = clipboard;
}
} else {
String clipboard = _base_get_text(selection.from_line, selection.from_column, selection.to_line, selection.to_column);
- OS::get_singleton()->set_clipboard(clipboard);
+ DisplayServer::get_singleton()->clipboard_set(clipboard);
cut_copy_line = "";
}
}
void TextEdit::paste() {
- String clipboard = OS::get_singleton()->get_clipboard();
+ String clipboard = DisplayServer::get_singleton()->clipboard_get();
begin_complex_operation();
if (selection.active) {
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index d9bfffffe9..cecfb07edb 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -2703,7 +2703,7 @@ void Tree::_gui_input(Ref<InputEvent> p_event) {
drag_accum = 0;
//last_drag_accum=0;
drag_from = v_scroll->get_value();
- drag_touching = OS::get_singleton()->has_touchscreen_ui_hint();
+ drag_touching = !DisplayServer::get_singleton()->screen_is_touchscreen(DisplayServer::get_singleton()->window_get_current_screen(get_viewport()->get_window_id()));
drag_touching_deaccel = false;
if (drag_touching) {
set_physics_process_internal(true);
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp
index b7b2f190b3..b0708b70b8 100644
--- a/scene/main/scene_tree.cpp
+++ b/scene/main/scene_tree.cpp
@@ -47,6 +47,7 @@
#include "scene/resources/mesh.h"
#include "scene/resources/packed_scene.h"
#include "scene/scene_string_names.h"
+#include "servers/display_server.h"
#include "servers/navigation_server.h"
#include "servers/physics_2d_server.h"
#include "servers/physics_server.h"
@@ -526,7 +527,7 @@ bool SceneTree::idle(float p_time) {
_notify_group_pause("idle_process_internal", Node::NOTIFICATION_INTERNAL_PROCESS);
_notify_group_pause("idle_process", Node::NOTIFICATION_PROCESS);
- Size2 win_size = Size2(OS::get_singleton()->get_window_size().width, OS::get_singleton()->get_window_size().height);
+ Size2 win_size = Size2(DisplayServer::get_singleton()->window_get_size().width, DisplayServer::get_singleton()->window_get_size().height);
if (win_size != last_screen_size) {
@@ -1143,7 +1144,7 @@ void SceneTree::_update_root_rect() {
}
//actual screen video mode
- Size2 video_mode = Size2(OS::get_singleton()->get_window_size().width, OS::get_singleton()->get_window_size().height);
+ Size2 video_mode = Size2(DisplayServer::get_singleton()->window_get_size().width, DisplayServer::get_singleton()->window_get_size().height);
Size2 desired_res = stretch_min;
Size2 viewport_size;
@@ -1734,7 +1735,7 @@ SceneTree::SceneTree() {
stretch_aspect = STRETCH_ASPECT_IGNORE;
stretch_shrink = 1;
- last_screen_size = Size2(OS::get_singleton()->get_window_size().width, OS::get_singleton()->get_window_size().height);
+ last_screen_size = Size2(DisplayServer::get_singleton()->window_get_size().width, DisplayServer::get_singleton()->window_get_size().height);
_update_root_rect();
root->set_physics_object_picking(GLOBAL_DEF("physics/common/enable_object_picking", true));
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index adfcc8153b..20587f49b9 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -51,6 +51,7 @@
#include "scene/main/timer.h"
#include "scene/resources/mesh.h"
#include "scene/scene_string_names.h"
+#include "servers/display_server.h"
#include "servers/physics_2d_server.h"
void ViewportTexture::setup_local_to_scene() {
@@ -732,7 +733,7 @@ Rect2 Viewport::get_visible_rect() const {
Rect2 r;
if (size == Size2()) {
- r = Rect2(Point2(), OS::get_singleton()->get_window_size());
+ r = Rect2(Point2(), DisplayServer::get_singleton()->window_get_size());
} else {
r = Rect2(Point2(), size);
}
@@ -2172,7 +2173,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
}
if (!over) {
- OS::get_singleton()->set_cursor_shape((OS::CursorShape)Input::get_singleton()->get_default_cursor_shape());
+ DisplayServer::get_singleton()->cursor_set_shape((DisplayServer::CursorShape)Input::get_singleton()->get_default_cursor_shape());
return;
}
@@ -2245,7 +2246,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
}
}
- OS::get_singleton()->set_cursor_shape((OS::CursorShape)cursor_shape);
+ DisplayServer::get_singleton()->cursor_set_shape((DisplayServer::CursorShape)cursor_shape);
if (over && over->can_process()) {
_gui_call_input(over, mm);
@@ -2258,9 +2259,9 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
bool can_drop = _gui_drop(over, pos, true);
if (!can_drop) {
- OS::get_singleton()->set_cursor_shape(OS::CURSOR_FORBIDDEN);
+ DisplayServer::get_singleton()->cursor_set_shape(DisplayServer::CURSOR_FORBIDDEN);
} else {
- OS::get_singleton()->set_cursor_shape(OS::CURSOR_CAN_DROP);
+ DisplayServer::get_singleton()->cursor_set_shape(DisplayServer::CURSOR_CAN_DROP);
}
//change mouse accordingly i guess
}
@@ -3086,6 +3087,10 @@ void Viewport::_propagate_update_default_repeat(Node *p_node) {
}
}
+DisplayServer::WindowID Viewport::get_window_id() const {
+ return DisplayServer::MAIN_WINDOW_ID;
+}
+
void Viewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_use_arvr", "use"), &Viewport::set_use_arvr);
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index e511ce1b17..b2a25fe0e9 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -35,6 +35,7 @@
#include "scene/main/node.h"
#include "scene/resources/texture.h"
#include "scene/resources/world_2d.h"
+#include "servers/display_server.h"
#include "servers/visual_server.h"
class Camera;
@@ -560,6 +561,8 @@ public:
void set_default_canvas_item_texture_repeat(DefaultCanvasItemTextureRepeat p_repeat);
DefaultCanvasItemTextureRepeat get_default_canvas_item_texture_repeat() const;
+ DisplayServer::WindowID get_window_id() const;
+
Viewport();
~Viewport();
};
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index f15911b0e2..5b33277fa0 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -480,7 +480,7 @@ void register_scene_types() {
#endif
ClassDB::register_class<NavigationMesh>();
- AcceptDialog::set_swap_ok_cancel(GLOBAL_DEF("gui/common/swap_ok_cancel", bool(OS::get_singleton()->get_swap_ok_cancel())));
+ AcceptDialog::set_swap_ok_cancel(GLOBAL_DEF("gui/common/swap_ok_cancel", bool(DisplayServer::get_singleton()->get_swap_ok_cancel())));
ClassDB::register_class<Shader>();
ClassDB::register_class<VisualShader>();
diff --git a/servers/display_server.cpp b/servers/display_server.cpp
index c3ecf302c3..b1ace561df 100644
--- a/servers/display_server.cpp
+++ b/servers/display_server.cpp
@@ -29,8 +29,13 @@
/*************************************************************************/
#include "display_server.h"
+#include "core/input/input.h"
DisplayServer *DisplayServer::singleton = nullptr;
+DisplayServer::SwitchVSyncCallbackInThread DisplayServer::switch_vsync_function = nullptr;
+
+DisplayServer::DisplayServerCreate DisplayServer::server_create_functions[DisplayServer::MAX_SERVERS];
+int DisplayServer::server_create_count = 0;
void DisplayServer::global_menu_add_item(const String &p_menu, const String &p_label, const Variant &p_signal, const Variant &p_meta) {
WARN_PRINT("Global menus not supported by this display server.");
@@ -76,6 +81,18 @@ DisplayServer::ScreenOrientation DisplayServer::screen_get_orientation(int p_scr
return SCREEN_LANDSCAPE;
}
+bool DisplayServer::screen_is_touchscreen(int p_screen) const {
+ //return false;
+ return Input::get_singleton() && Input::get_singleton()->is_emulating_touch_from_mouse();
+}
+
+void DisplayServer::screen_set_keep_on(bool p_enable) {
+ WARN_PRINT("Keeping screen on not supported by this display server.");
+}
+bool DisplayServer::screen_is_kept_on() const {
+ return false;
+}
+
DisplayServer::WindowID DisplayServer::create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i) {
ERR_FAIL_V_MSG(INVALID_WINDOW_ID, "Sub-windows not supported by this display server.");
}
@@ -104,7 +121,7 @@ bool DisplayServer::is_console_visible() const {
return false;
}
-void DisplayServer::virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect) {
+void DisplayServer::virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect, int p_max_legth) {
WARN_PRINT("Virtual keyboard not supported by this display server.");
}
void DisplayServer::virtual_keyboard_hide() {
@@ -180,7 +197,32 @@ void DisplayServer::set_native_icon(const String &p_filename) {
WARN_PRINT("Native icon not supported by this display server.");
}
void DisplayServer::set_icon(const Ref<Image> &p_icon) {
- WARN_PRINT("Iconnot supported by this display server.");
+ WARN_PRINT("Icon not supported by this display server.");
+}
+
+void DisplayServer::_set_use_vsync(bool p_enable) {
+ WARN_PRINT("VSync not supported by this display server.");
+}
+void DisplayServer::vsync_set_enabled(bool p_enable) {
+ vsync_enabled = p_enable;
+ if (switch_vsync_function) { //if a function was set, use function
+ switch_vsync_function(p_enable);
+ } else { //otherwise just call here
+ _set_use_vsync(p_enable);
+ }
+}
+bool DisplayServer::vsync_is_enabled() const {
+ return vsync_enabled;
+}
+
+void DisplayServer::vsync_set_use_via_compositor(bool p_enable) {
+ WARN_PRINT("VSync via compositor not supported by this display server.");
+}
+bool DisplayServer::vsync_is_using_via_compositor() const {
+ return false;
+}
+
+void DisplayServer::set_context(Context p_context) {
}
void DisplayServer::_bind_methods() {
@@ -214,6 +256,9 @@ void DisplayServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("screen_set_orientation", "orientation", "screen"), &DisplayServer::screen_set_orientation, DEFVAL(SCREEN_OF_MAIN_WINDOW));
ClassDB::bind_method(D_METHOD("screen_get_orientation", "screen"), &DisplayServer::screen_get_orientation, DEFVAL(SCREEN_OF_MAIN_WINDOW));
+ ClassDB::bind_method(D_METHOD("screen_set_keep_on", "enable"), &DisplayServer::screen_set_keep_on);
+ ClassDB::bind_method(D_METHOD("screen_is_kept_on"), &DisplayServer::screen_is_kept_on);
+
ClassDB::bind_method(D_METHOD("get_window_list"), &DisplayServer::get_window_list);
ClassDB::bind_method(D_METHOD("create_sub_window", "mode", "rect"), &DisplayServer::create_sub_window, DEFVAL(Rect2i()));
@@ -258,14 +303,14 @@ void DisplayServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("console_set_visible", "console_visible"), &DisplayServer::console_set_visible);
ClassDB::bind_method(D_METHOD("is_console_visible"), &DisplayServer::is_console_visible);
- ClassDB::bind_method(D_METHOD("virtual_keyboard_show", "existing_text", "position"), &DisplayServer::virtual_keyboard_show, DEFVAL(Rect2i()));
+ ClassDB::bind_method(D_METHOD("virtual_keyboard_show", "existing_text", "position", "max_length"), &DisplayServer::virtual_keyboard_show, DEFVAL(Rect2i()), DEFVAL(-1));
ClassDB::bind_method(D_METHOD("virtual_keyboard_hide"), &DisplayServer::virtual_keyboard_hide);
ClassDB::bind_method(D_METHOD("virtual_keyboard_get_height"), &DisplayServer::virtual_keyboard_get_height);
ClassDB::bind_method(D_METHOD("cursor_set_shape", "shape"), &DisplayServer::cursor_set_shape);
ClassDB::bind_method(D_METHOD("cursor_get_shape"), &DisplayServer::cursor_get_shape);
- ClassDB::bind_method(D_METHOD("cursor_set_custom_image", "cursor", "shape", "hotspot"), &DisplayServer::cursor_set_custom_image);
+ ClassDB::bind_method(D_METHOD("cursor_set_custom_image", "cursor", "shape", "hotspot"), &DisplayServer::cursor_set_custom_image, DEFVAL(CURSOR_ARROW), DEFVAL(Vector2()));
ClassDB::bind_method(D_METHOD("get_swap_ok_cancel"), &DisplayServer::get_swap_ok_cancel);
@@ -285,6 +330,12 @@ void DisplayServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("process_events"), &DisplayServer::process_events);
ClassDB::bind_method(D_METHOD("force_process_and_drop_events"), &DisplayServer::force_process_and_drop_events);
+ ClassDB::bind_method(D_METHOD("vsync_set_enabled", "enabled"), &DisplayServer::vsync_set_enabled);
+ ClassDB::bind_method(D_METHOD("vsync_is_enabled"), &DisplayServer::vsync_is_enabled);
+
+ ClassDB::bind_method(D_METHOD("vsync_set_use_via_compositor", "enabled"), &DisplayServer::vsync_set_use_via_compositor);
+ ClassDB::bind_method(D_METHOD("vsync_is_using_via_compositor"), &DisplayServer::vsync_is_using_via_compositor);
+
ClassDB::bind_method(D_METHOD("set_native_icon", "filename"), &DisplayServer::set_native_icon);
ClassDB::bind_method(D_METHOD("set_icon", "image"), &DisplayServer::set_icon);
@@ -367,8 +418,56 @@ void DisplayServer::_bind_methods() {
BIND_ENUM_CONSTANT(LATIN_KEYBOARD_NEO);
BIND_ENUM_CONSTANT(LATIN_KEYBOARD_COLEMAK);
}
+
+void DisplayServer::register_create_function(const char *p_name, CreateFunction p_function, GetVideoDriversFunction p_get_drivers) {
+ ERR_FAIL_COND(server_create_count == MAX_SERVERS);
+ server_create_functions[server_create_count].create_function = p_function;
+ server_create_functions[server_create_count].name = p_name;
+ server_create_count++;
+}
+int DisplayServer::get_create_function_count() {
+ return server_create_count;
+}
+const char *DisplayServer::get_create_function_name(int p_index) {
+ ERR_FAIL_INDEX_V(p_index, server_create_count, nullptr);
+ return server_create_functions[p_index].name;
+}
+
+Vector<String> DisplayServer::get_create_function_rendering_drivers(int p_index) {
+ ERR_FAIL_INDEX_V(p_index, server_create_count, Vector<String>());
+ return server_create_functions[p_index].get_rendering_drivers_function();
+}
+
+DisplayServer *DisplayServer::create(int p_index, const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
+ ERR_FAIL_INDEX_V(p_index, server_create_count, nullptr);
+ return server_create_functions[p_index].create_function(p_rendering_driver, p_mode, p_flags, p_resolution, r_error);
+}
+
+void DisplayServer::_input_set_mouse_mode(Input::MouseMode p_mode) {
+ singleton->mouse_set_mode(MouseMode(p_mode));
+}
+Input::MouseMode DisplayServer::_input_get_mouse_mode() {
+ return Input::MouseMode(singleton->mouse_get_mode());
+}
+
+void DisplayServer::_input_warp(const Vector2 &p_to_pos) {
+ singleton->mouse_warp_to_position(p_to_pos);
+}
+
+Input::CursorShape DisplayServer::_input_get_current_cursor_shape() {
+ return (Input::CursorShape)singleton->cursor_get_shape();
+}
+void DisplayServer::_input_set_custom_mouse_cursor_func(const RES &p_image, Input::CursorShape p_shape, const Vector2 &p_hostspot) {
+ singleton->cursor_set_custom_image(p_image, (CursorShape)p_shape, p_hostspot);
+}
+
DisplayServer::DisplayServer() {
singleton = this;
+ Input::set_mouse_mode_func = _input_set_mouse_mode;
+ Input::get_mouse_mode_func = _input_get_mouse_mode;
+ Input::warp_mouse_func = _input_warp;
+ Input::get_current_cursor_shape_func = _input_get_current_cursor_shape;
+ Input::set_custom_mouse_cursor_func = _input_set_custom_mouse_cursor_func;
}
DisplayServer::~DisplayServer() {
}
diff --git a/servers/display_server.h b/servers/display_server.h
index c05a7fadbd..94848153ce 100644
--- a/servers/display_server.h
+++ b/servers/display_server.h
@@ -31,6 +31,7 @@
#ifndef DISPLAY_SERVER_H
#define DISPLAY_SERVER_H
+#include "core/input/input.h"
#include "core/os/os.h"
#include "core/resource.h"
@@ -38,9 +39,45 @@ class DisplayServer : public Object {
GDCLASS(DisplayServer, Object)
static DisplayServer *singleton;
+ bool vsync_enabled = true;
+
+public:
+ _FORCE_INLINE_ static DisplayServer *get_singleton() {
+ return singleton;
+ }
+ enum WindowMode {
+ WINDOW_MODE_WINDOWED,
+ WINDOW_MODE_MINIMIZED,
+ WINDOW_MODE_MAXIMIZED,
+ WINDOW_MODE_FULLSCREEN
+ };
+
+ typedef DisplayServer *(*CreateFunction)(const String &, WindowMode, uint32_t, const Size2i &, Error &r_error); //video driver, window mode, resolution
+ typedef Vector<String> (*GetVideoDriversFunction)(); //video driver, window mode, resolution
+private:
+ static void _input_set_mouse_mode(Input::MouseMode p_mode);
+ static Input::MouseMode _input_get_mouse_mode();
+ static void _input_warp(const Vector2 &p_to_pos);
+ static Input::CursorShape _input_get_current_cursor_shape();
+ static void _input_set_custom_mouse_cursor_func(const RES &, Input::CursorShape, const Vector2 &p_hostspot);
protected:
static void _bind_methods();
+ enum {
+ MAX_SERVERS = 64
+ };
+
+ struct DisplayServerCreate {
+ const char *name;
+ GetVideoDriversFunction get_rendering_drivers_function;
+ CreateFunction create_function;
+ };
+
+ static DisplayServerCreate server_create_functions[MAX_SERVERS];
+ static int server_create_count;
+
+ friend class VisualServerRaster;
+ virtual void _set_use_vsync(bool p_enable);
public:
enum Feature {
@@ -62,7 +99,8 @@ public:
FEATURE_ICON,
FEATURE_NATIVE_ICON,
FEATURE_ORIENTATION,
- FEATURE_SWAP_BUFFERS
+ FEATURE_SWAP_BUFFERS,
+ FEATURE_KEEP_SCREEN_ON,
};
@@ -101,8 +139,7 @@ public:
virtual Point2i screen_get_position(int p_screen = SCREEN_OF_MAIN_WINDOW) const = 0;
virtual Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const = 0;
virtual int screen_get_dpi(int p_screen = SCREEN_OF_MAIN_WINDOW) const = 0;
- virtual bool screen_is_touchscreen(int p_screen = SCREEN_OF_MAIN_WINDOW) const = 0;
-
+ virtual bool screen_is_touchscreen(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
enum ScreenOrientation {
SCREEN_LANDSCAPE,
@@ -117,6 +154,8 @@ public:
virtual void screen_set_orientation(ScreenOrientation p_orientation, int p_screen = SCREEN_OF_MAIN_WINDOW);
ScreenOrientation screen_get_orientation(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
+ virtual void screen_set_keep_on(bool p_enable); //disable screensaver
+ virtual bool screen_is_kept_on() const;
enum {
MAIN_WINDOW_ID = 0,
INVALID_WINDOW_ID = -1
@@ -126,13 +165,6 @@ public:
virtual Vector<int> get_window_list() const = 0;
- enum WindowMode {
- WINDOW_MODE_WINDOWED,
- WINDOW_MODE_MINIMIZED,
- WINDOW_MODE_MAXIMIZED,
- WINDOW_MODE_FULLSCREEN
- };
-
enum WindowFlags {
WINDOW_FLAG_RESIZE_DISABLED,
WINDOW_FLAG_BORDERLESS,
@@ -179,6 +211,8 @@ public:
virtual bool window_can_draw(WindowID p_window = MAIN_WINDOW_ID) const = 0;
+ virtual bool can_any_window_draw() const = 0;
+
virtual void window_set_ime_active(const bool p_active, WindowID p_window = MAIN_WINDOW_ID);
virtual void window_set_ime_position(const Point2i &p_pos, WindowID p_window = MAIN_WINDOW_ID);
@@ -188,7 +222,7 @@ public:
virtual void console_set_visible(bool p_enabled);
virtual bool is_console_visible() const;
- virtual void virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2());
+ virtual void virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), int p_max_legth = -1);
virtual void virtual_keyboard_hide();
// returns height of the currently shown virtual keyboard (0 if keyboard is hidden)
@@ -216,7 +250,7 @@ public:
};
virtual void cursor_set_shape(CursorShape p_shape);
virtual CursorShape cursor_get_shape() const;
- virtual void cursor_set_custom_image(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot);
+ virtual void cursor_set_custom_image(const RES &p_cursor, CursorShape p_shape = CURSOR_ARROW, const Vector2 &p_hotspot = Vector2());
virtual bool get_swap_ok_cancel();
@@ -255,8 +289,31 @@ public:
virtual void set_native_icon(const String &p_filename);
virtual void set_icon(const Ref<Image> &p_icon);
- typedef Vector<String> *(*GetSupportedVideoDriversFunction)();
- typedef DisplayServer *(*CreateFunction)(const String &, WindowMode, uint32_t, const Size2i &, Error &r_error); //video driver, window mode, resolution
+ typedef void (*SwitchVSyncCallbackInThread)(bool);
+
+ static SwitchVSyncCallbackInThread switch_vsync_function;
+
+ void vsync_set_enabled(bool p_enable);
+ bool vsync_is_enabled() const;
+
+ virtual void vsync_set_use_via_compositor(bool p_enable);
+ virtual bool vsync_is_using_via_compositor() const;
+
+ //real, actual overridable function to switch vsync, which needs to be called from graphics thread if needed
+
+ enum Context {
+ CONTEXT_EDITOR,
+ CONTEXT_PROJECTMAN,
+ CONTEXT_ENGINE,
+ };
+
+ virtual void set_context(Context p_context);
+
+ static void register_create_function(const char *p_name, CreateFunction p_function, GetVideoDriversFunction p_get_drivers);
+ static int get_create_function_count();
+ static const char *get_create_function_name(int p_index);
+ static Vector<String> get_create_function_rendering_drivers(int p_index);
+ static DisplayServer *create(int p_index, const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
DisplayServer();
~DisplayServer();
diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp
index 35ec52a5c0..1026972a62 100644
--- a/servers/visual/visual_server_raster.cpp
+++ b/servers/visual/visual_server_raster.cpp
@@ -234,7 +234,7 @@ void VisualServerRaster::set_debug_generate_wireframes(bool p_generate) {
}
void VisualServerRaster::call_set_use_vsync(bool p_enable) {
- OS::get_singleton()->_set_use_vsync(p_enable);
+ DisplayServer::get_singleton()->_set_use_vsync(p_enable);
}
bool VisualServerRaster::is_low_end() const {
diff --git a/servers/visual/visual_server_wrap_mt.cpp b/servers/visual/visual_server_wrap_mt.cpp
index 90d301c0cd..4169144fc9 100644
--- a/servers/visual/visual_server_wrap_mt.cpp
+++ b/servers/visual/visual_server_wrap_mt.cpp
@@ -31,6 +31,7 @@
#include "visual_server_wrap_mt.h"
#include "core/os/os.h"
#include "core/project_settings.h"
+#include "servers/display_server.h"
void VisualServerWrapMT::thread_exit() {
@@ -61,7 +62,7 @@ void VisualServerWrapMT::thread_loop() {
server_thread = Thread::get_caller_id();
- OS::get_singleton()->make_rendering_thread();
+ DisplayServer::get_singleton()->make_rendering_thread();
visual_server->init();
@@ -108,7 +109,7 @@ void VisualServerWrapMT::init() {
if (create_thread) {
print_verbose("VisualServerWrapMT: Creating render thread");
- OS::get_singleton()->release_rendering_thread();
+ DisplayServer::get_singleton()->release_rendering_thread();
if (create_thread) {
thread = Thread::create(_thread_callback, this);
print_verbose("VisualServerWrapMT: Starting render thread");
@@ -173,7 +174,7 @@ VisualServerWrapMT::VisualServerWrapMT(VisualServer *p_contained, bool p_create_
command_queue(p_create_thread) {
singleton_mt = this;
- OS::switch_vsync_function = set_use_vsync_callback; //as this goes to another thread, make sure it goes properly
+ DisplayServer::switch_vsync_function = set_use_vsync_callback; //as this goes to another thread, make sure it goes properly
visual_server = p_contained;
create_thread = p_create_thread;