diff options
Diffstat (limited to 'platform/linuxbsd')
-rw-r--r-- | platform/linuxbsd/detect.py | 24 | ||||
-rw-r--r-- | platform/linuxbsd/godot_linuxbsd.cpp | 12 | ||||
-rw-r--r-- | platform/linuxbsd/pck_embed.ld | 10 | ||||
-rw-r--r-- | platform/linuxbsd/pck_embed.legacy.ld | 10 | ||||
-rw-r--r-- | platform/linuxbsd/wayland/SCsub | 15 | ||||
-rw-r--r-- | platform/linuxbsd/wayland/display_server_wayland.cpp | 53 | ||||
-rw-r--r-- | platform/linuxbsd/wayland/display_server_wayland.h | 5 | ||||
-rw-r--r-- | platform/linuxbsd/wayland/wayland_thread.cpp | 45 | ||||
-rw-r--r-- | platform/linuxbsd/wayland/wayland_thread.h | 19 | ||||
-rw-r--r-- | platform/linuxbsd/x11/display_server_x11.cpp | 3 |
10 files changed, 151 insertions, 45 deletions
diff --git a/platform/linuxbsd/detect.py b/platform/linuxbsd/detect.py index e6a47f556d..94784f2da9 100644 --- a/platform/linuxbsd/detect.py +++ b/platform/linuxbsd/detect.py @@ -207,9 +207,9 @@ def configure(env: "Environment"): env.Append(CPPDEFINES=["SOWRAP_ENABLED"]) if env["wayland"]: - if os.system("wayland-scanner -v") != 0: - print("wayland-scanner not found. Aborting.") - sys.exit(255) + if os.system("wayland-scanner -v 2>/dev/null") != 0: + print("wayland-scanner not found. Disabling Wayland support.") + env["wayland"] = False if env["touch"]: env.Append(CPPDEFINES=["TOUCH_ENABLED"]) @@ -496,24 +496,6 @@ def configure(env: "Environment"): if env["execinfo"]: env.Append(LIBS=["execinfo"]) - if not env.editor_build: - import subprocess - import re - - linker_version_str = subprocess.check_output( - [env.subst(env["LINK"]), "-Wl,--version"] + env.subst(env["LINKFLAGS"]) - ).decode("utf-8") - gnu_ld_version = re.search(r"^GNU ld [^$]*(\d+\.\d+)$", linker_version_str, re.MULTILINE) - if not gnu_ld_version: - print( - "Warning: Creating export template binaries enabled for PCK embedding is currently only supported with GNU ld, not gold, LLD or mold." - ) - else: - if float(gnu_ld_version.group(1)) >= 2.30: - env.Append(LINKFLAGS=["-T", "platform/linuxbsd/pck_embed.ld"]) - else: - env.Append(LINKFLAGS=["-T", "platform/linuxbsd/pck_embed.legacy.ld"]) - if platform.system() == "FreeBSD": env.Append(LINKFLAGS=["-lkvm"]) diff --git a/platform/linuxbsd/godot_linuxbsd.cpp b/platform/linuxbsd/godot_linuxbsd.cpp index efad9c8594..a2b6fbeb25 100644 --- a/platform/linuxbsd/godot_linuxbsd.cpp +++ b/platform/linuxbsd/godot_linuxbsd.cpp @@ -41,6 +41,18 @@ #include <sys/resource.h> #endif +// For export templates, add a section; the exporter will patch it to enclose +// the data appended to the executable (bundled PCK). +#if !defined(TOOLS_ENABLED) && defined(__GNUC__) +static const char dummy[8] __attribute__((section("pck"), used)) = { 0 }; + +// Dummy function to prevent LTO from discarding "pck" section. +extern "C" const char *pck_section_dummy_call() __attribute__((used)); +extern "C" const char *pck_section_dummy_call() { + return &dummy[0]; +} +#endif + int main(int argc, char *argv[]) { #if defined(SANITIZERS_ENABLED) // Note: Set stack size to be at least 30 MB (vs 8 MB default) to avoid overflow, address sanitizer can increase stack usage up to 3 times. diff --git a/platform/linuxbsd/pck_embed.ld b/platform/linuxbsd/pck_embed.ld deleted file mode 100644 index 57a1994043..0000000000 --- a/platform/linuxbsd/pck_embed.ld +++ /dev/null @@ -1,10 +0,0 @@ -SECTIONS -{ - /* Add a zero-sized section; the exporter will patch it to enclose the data appended to the executable (embedded PCK) */ - pck 0 (INFO) : - { - /* binutils >= 2.30 allow it being zero-sized, but needs something between the braces to keep the section */ - . = ALIGN(8); - } -} -INSERT AFTER .rodata; diff --git a/platform/linuxbsd/pck_embed.legacy.ld b/platform/linuxbsd/pck_embed.legacy.ld deleted file mode 100644 index a23013ba7a..0000000000 --- a/platform/linuxbsd/pck_embed.legacy.ld +++ /dev/null @@ -1,10 +0,0 @@ -SECTIONS -{ - /* The exporter will patch this section to enclose the data appended to the executable (embedded PCK) */ - pck 0 (INFO) : AT ( ADDR (.rodata) + SIZEOF (.rodata) ) - { - /* binutils < 2.30 need some actual content for the linker not to discard the section */ - BYTE(0); - } -} -INSERT AFTER .rodata; diff --git a/platform/linuxbsd/wayland/SCsub b/platform/linuxbsd/wayland/SCsub index dbb3c02690..99b7349dbe 100644 --- a/platform/linuxbsd/wayland/SCsub +++ b/platform/linuxbsd/wayland/SCsub @@ -19,7 +19,7 @@ if env["use_sowrap"]: "WAYLAND_API_CODE": Builder( action=Action( "wayland-scanner -c private-code < ${SOURCE} | sed 's:wayland-util\.h:../dynwrappers/wayland-client-core-so_wrap\.h:' > ${TARGET}", - 'Generating Wayland protocol marshalling code: "${TARGET}"', + 'Generating Wayland protocol marshaling code: "${TARGET}"', ), single_source=True, ), @@ -37,7 +37,7 @@ else: "WAYLAND_API_CODE": Builder( action=Action( "wayland-scanner -c private-code < ${SOURCE} > ${TARGET}", - 'Generating Wayland protocol marshalling code: "${TARGET}"', + 'Generating Wayland protocol marshaling code: "${TARGET}"', ), single_source=True, ), @@ -151,11 +151,22 @@ env.WAYLAND_API_CODE( source="#thirdparty/wayland-protocols/unstable/tablet/tablet-unstable-v2.xml", ) +env.WAYLAND_API_HEADER( + target="protocol/xdg_foreign.gen.h", + source="#thirdparty/wayland-protocols/unstable/xdg-foreign/xdg-foreign-unstable-v1.xml", +) + +env.WAYLAND_API_CODE( + target="protocol/xdg_foreign.gen.c", + source="#thirdparty/wayland-protocols/unstable/xdg-foreign/xdg-foreign-unstable-v1.xml", +) + source_files = [ "protocol/wayland.gen.c", "protocol/viewporter.gen.c", "protocol/fractional_scale.gen.c", "protocol/xdg_shell.gen.c", + "protocol/xdg_foreign.gen.c", "protocol/xdg_decoration.gen.c", "protocol/xdg_activation.gen.c", "protocol/relative_pointer.gen.c", diff --git a/platform/linuxbsd/wayland/display_server_wayland.cpp b/platform/linuxbsd/wayland/display_server_wayland.cpp index e22eddd08e..02b715056a 100644 --- a/platform/linuxbsd/wayland/display_server_wayland.cpp +++ b/platform/linuxbsd/wayland/display_server_wayland.cpp @@ -196,6 +196,9 @@ bool DisplayServerWayland::has_feature(Feature p_feature) const { case FEATURE_SWAP_BUFFERS: case FEATURE_KEEP_SCREEN_ON: case FEATURE_CLIPBOARD_PRIMARY: +#ifdef DBUS_ENABLED + case FEATURE_NATIVE_DIALOG: +#endif case FEATURE_HIDPI: { return true; } break; @@ -269,6 +272,22 @@ bool DisplayServerWayland::is_dark_mode() const { } } +Error DisplayServerWayland::file_dialog_show(const String &p_title, const String &p_current_directory, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector<String> &p_filters, const Callable &p_callback) { + WindowID window_id = MAIN_WINDOW_ID; + // TODO: Use window IDs for multiwindow support. + + WaylandThread::WindowState *ws = wayland_thread.wl_surface_get_window_state(wayland_thread.window_get_wl_surface(window_id)); + return portal_desktop->file_dialog_show(window_id, (ws ? ws->exported_handle : String()), p_title, p_current_directory, String(), p_filename, p_mode, p_filters, TypedArray<Dictionary>(), p_callback, false); +} + +Error DisplayServerWayland::file_dialog_with_options_show(const String &p_title, const String &p_current_directory, const String &p_root, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector<String> &p_filters, const TypedArray<Dictionary> &p_options, const Callable &p_callback) { + WindowID window_id = MAIN_WINDOW_ID; + // TODO: Use window IDs for multiwindow support. + + WaylandThread::WindowState *ws = wayland_thread.wl_surface_get_window_state(wayland_thread.window_get_wl_surface(window_id)); + return portal_desktop->file_dialog_show(window_id, (ws ? ws->exported_handle : String()), p_title, p_current_directory, p_root, p_filename, p_mode, p_filters, p_options, p_callback, true); +} + #endif void DisplayServerWayland::mouse_set_mode(MouseMode p_mode) { @@ -557,6 +576,37 @@ Vector<DisplayServer::WindowID> DisplayServerWayland::get_window_list() const { return ret; } +int64_t DisplayServerWayland::window_get_native_handle(HandleType p_handle_type, WindowID p_window) const { + MutexLock mutex_lock(wayland_thread.mutex); + + switch (p_handle_type) { + case DISPLAY_HANDLE: { + return (int64_t)wayland_thread.get_wl_display(); + } break; + + case WINDOW_HANDLE: { + return (int64_t)wayland_thread.window_get_wl_surface(p_window); + } break; + + case WINDOW_VIEW: { + return 0; // Not supported. + } break; + +#ifdef GLES3_ENABLED + case OPENGL_CONTEXT: { + if (egl_manager) { + return (int64_t)egl_manager->get_context(p_window); + } + return 0; + } break; +#endif // GLES3_ENABLED + + default: { + return 0; + } break; + } +} + DisplayServer::WindowID DisplayServerWayland::get_window_at_screen_position(const Point2i &p_position) const { // Standard Wayland APIs don't support this. return MAIN_WINDOW_ID; @@ -1192,10 +1242,11 @@ DisplayServerWayland::DisplayServerWayland(const String &p_rendering_driver, Win if (context_rd) { if (context_rd->initialize() != OK) { + ERR_PRINT(vformat("Could not initialize %s", context_rd->get_api_name())); memdelete(context_rd); context_rd = nullptr; r_error = ERR_CANT_CREATE; - ERR_FAIL_MSG(vformat("Could not initialize %s", context_rd->get_api_name())); + return; } } #endif diff --git a/platform/linuxbsd/wayland/display_server_wayland.h b/platform/linuxbsd/wayland/display_server_wayland.h index f0aabb8c52..3e7f3c4cb4 100644 --- a/platform/linuxbsd/wayland/display_server_wayland.h +++ b/platform/linuxbsd/wayland/display_server_wayland.h @@ -171,6 +171,9 @@ public: #ifdef DBUS_ENABLED virtual bool is_dark_mode_supported() const override; virtual bool is_dark_mode() const override; + + virtual Error file_dialog_show(const String &p_title, const String &p_current_directory, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector<String> &p_filters, const Callable &p_callback) override; + virtual Error file_dialog_with_options_show(const String &p_title, const String &p_current_directory, const String &p_root, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector<String> &p_filters, const TypedArray<Dictionary> &p_options, const Callable &p_callback) override; #endif virtual void mouse_set_mode(MouseMode p_mode) override; @@ -200,6 +203,8 @@ public: virtual Vector<DisplayServer::WindowID> get_window_list() const override; + virtual int64_t window_get_native_handle(HandleType p_handle_type, WindowID p_window = MAIN_WINDOW_ID) const override; + virtual WindowID get_window_at_screen_position(const Point2i &p_position) const override; virtual void window_attach_instance_id(ObjectID p_instance, WindowID p_window_id = MAIN_WINDOW_ID) override; diff --git a/platform/linuxbsd/wayland/wayland_thread.cpp b/platform/linuxbsd/wayland/wayland_thread.cpp index 9410e4653d..0e9c3fb776 100644 --- a/platform/linuxbsd/wayland/wayland_thread.cpp +++ b/platform/linuxbsd/wayland/wayland_thread.cpp @@ -370,6 +370,12 @@ void WaylandThread::_wl_registry_on_global(void *data, struct wl_registry *wl_re return; } + if (strcmp(interface, zxdg_exporter_v1_interface.name) == 0) { + registry->wl_exporter = (struct zxdg_exporter_v1 *)wl_registry_bind(wl_registry, name, &zxdg_exporter_v1_interface, 1); + registry->wl_exporter_name = name; + return; + } + if (strcmp(interface, wl_compositor_interface.name) == 0) { registry->wl_compositor = (struct wl_compositor *)wl_registry_bind(wl_registry, name, &wl_compositor_interface, 4); registry->wl_compositor_name = name; @@ -570,6 +576,17 @@ void WaylandThread::_wl_registry_on_global_remove(void *data, struct wl_registry return; } + if (name == registry->wl_exporter_name) { + if (registry->wl_exporter) { + zxdg_exporter_v1_destroy(registry->wl_exporter); + registry->wl_exporter = nullptr; + } + + registry->wl_exporter_name = 0; + + return; + } + if (name == registry->wl_compositor_name) { if (registry->wl_compositor) { wl_compositor_destroy(registry->wl_compositor); @@ -969,6 +986,14 @@ void WaylandThread::_wl_surface_on_leave(void *data, struct wl_surface *wl_surfa DEBUG_LOG_WAYLAND_THREAD(vformat("Window left output %x.\n", (size_t)wl_output)); } +// TODO: Add support to this event. +void WaylandThread::_wl_surface_on_preferred_buffer_scale(void *data, struct wl_surface *wl_surface, int32_t factor) { +} + +// TODO: Add support to this event. +void WaylandThread::_wl_surface_on_preferred_buffer_transform(void *data, struct wl_surface *wl_surface, uint32_t transform) { +} + void WaylandThread::_wl_output_on_geometry(void *data, struct wl_output *wl_output, int32_t x, int32_t y, int32_t physical_width, int32_t physical_height, int32_t subpixel, const char *make, const char *model, int32_t transform) { ScreenState *ss = (ScreenState *)data; ERR_FAIL_NULL(ss); @@ -1107,6 +1132,13 @@ void WaylandThread::_xdg_toplevel_on_wm_capabilities(void *data, struct xdg_topl } } +void WaylandThread::_xdg_exported_on_exported(void *data, zxdg_exported_v1 *exported, const char *handle) { + WindowState *ws = (WindowState *)data; + ERR_FAIL_NULL(ws); + + ws->exported_handle = vformat("wayland:%s", String::utf8(handle)); +} + void WaylandThread::_xdg_toplevel_decoration_on_configure(void *data, struct zxdg_toplevel_decoration_v1 *xdg_toplevel_decoration, uint32_t mode) { if (mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE) { #ifdef LIBDECOR_ENABLED @@ -1675,6 +1707,10 @@ void WaylandThread::_wl_pointer_on_axis_discrete(void *data, struct wl_pointer * void WaylandThread::_wl_pointer_on_axis_value120(void *data, struct wl_pointer *wl_pointer, uint32_t axis, int32_t value120) { } +// TODO: Add support to this event. +void WaylandThread::_wl_pointer_on_axis_relative_direction(void *data, struct wl_pointer *wl_pointer, uint32_t axis, uint32_t direction) { +} + void WaylandThread::_wl_keyboard_on_keymap(void *data, struct wl_keyboard *wl_keyboard, uint32_t format, int32_t fd, uint32_t size) { ERR_FAIL_COND_MSG(format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, "Unsupported keymap format announced from the Wayland compositor."); @@ -2975,6 +3011,11 @@ void WaylandThread::window_create(DisplayServer::WindowID p_window_id, int p_wid // "loop". wl_surface_commit(ws.wl_surface); + if (registry.wl_exporter) { + ws.xdg_exported = zxdg_exporter_v1_export(registry.wl_exporter, ws.wl_surface); + zxdg_exported_v1_add_listener(ws.xdg_exported, &xdg_exported_listener, &ws); + } + // Wait for the surface to be configured before continuing. wl_display_roundtrip(wl_display); } @@ -3980,6 +4021,10 @@ void WaylandThread::destroy() { xdg_wm_base_destroy(registry.xdg_wm_base); } + if (registry.wl_exporter) { + zxdg_exporter_v1_destroy(registry.wl_exporter); + } + if (registry.wl_shm) { wl_shm_destroy(registry.wl_shm); } diff --git a/platform/linuxbsd/wayland/wayland_thread.h b/platform/linuxbsd/wayland/wayland_thread.h index 8591db4306..86033c1a09 100644 --- a/platform/linuxbsd/wayland/wayland_thread.h +++ b/platform/linuxbsd/wayland/wayland_thread.h @@ -63,6 +63,7 @@ #include "wayland/protocol/wayland.gen.h" #include "wayland/protocol/xdg_activation.gen.h" #include "wayland/protocol/xdg_decoration.gen.h" +#include "wayland/protocol/xdg_foreign.gen.h" #include "wayland/protocol/xdg_shell.gen.h" #ifdef LIBDECOR_ENABLED @@ -132,6 +133,9 @@ public: struct xdg_wm_base *xdg_wm_base = nullptr; uint32_t xdg_wm_base_name = 0; + struct zxdg_exporter_v1 *wl_exporter = nullptr; + uint32_t wl_exporter_name = 0; + // wayland-protocols globals. struct wp_viewporter *wp_viewporter = nullptr; @@ -197,6 +201,9 @@ public: struct wp_viewport *wp_viewport = nullptr; struct wp_fractional_scale_v1 *wp_fractional_scale = nullptr; + struct zxdg_exported_v1 *xdg_exported = nullptr; + + String exported_handle; // Currently applied buffer scale. int buffer_scale = 1; @@ -495,6 +502,8 @@ private: static void _wl_surface_on_enter(void *data, struct wl_surface *wl_surface, struct wl_output *wl_output); static void _wl_surface_on_leave(void *data, struct wl_surface *wl_surface, struct wl_output *wl_output); + static void _wl_surface_on_preferred_buffer_scale(void *data, struct wl_surface *wl_surface, int32_t factor); + static void _wl_surface_on_preferred_buffer_transform(void *data, struct wl_surface *wl_surface, uint32_t transform); static void _frame_wl_callback_on_done(void *data, struct wl_callback *wl_callback, uint32_t callback_data); @@ -520,6 +529,7 @@ private: static void _wl_pointer_on_axis_stop(void *data, struct wl_pointer *wl_pointer, uint32_t time, uint32_t axis); static void _wl_pointer_on_axis_discrete(void *data, struct wl_pointer *wl_pointer, uint32_t axis, int32_t discrete); static void _wl_pointer_on_axis_value120(void *data, struct wl_pointer *wl_pointer, uint32_t axis, int32_t value120); + static void _wl_pointer_on_axis_relative_direction(void *data, struct wl_pointer *wl_pointer, uint32_t axis, uint32_t direction); static void _wl_keyboard_on_keymap(void *data, struct wl_keyboard *wl_keyboard, uint32_t format, int32_t fd, uint32_t size); static void _wl_keyboard_on_enter(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, struct wl_surface *surface, struct wl_array *keys); @@ -599,6 +609,8 @@ private: static void _xdg_toplevel_decoration_on_configure(void *data, struct zxdg_toplevel_decoration_v1 *xdg_toplevel_decoration, uint32_t mode); + static void _xdg_exported_on_exported(void *data, zxdg_exported_v1 *exported, const char *handle); + static void _xdg_activation_token_on_done(void *data, struct xdg_activation_token_v1 *xdg_activation_token, const char *token); // Core Wayland event listeners. @@ -610,6 +622,8 @@ private: static constexpr struct wl_surface_listener wl_surface_listener = { .enter = _wl_surface_on_enter, .leave = _wl_surface_on_leave, + .preferred_buffer_scale = _wl_surface_on_preferred_buffer_scale, + .preferred_buffer_transform = _wl_surface_on_preferred_buffer_transform, }; static constexpr struct wl_callback_listener frame_wl_callback_listener { @@ -645,6 +659,7 @@ private: .axis_stop = _wl_pointer_on_axis_stop, .axis_discrete = _wl_pointer_on_axis_discrete, .axis_value120 = _wl_pointer_on_axis_value120, + .axis_relative_direction = _wl_pointer_on_axis_relative_direction, }; static constexpr struct wl_keyboard_listener wl_keyboard_listener = { @@ -753,6 +768,10 @@ private: .frame = _wp_tablet_tool_on_frame, }; + static constexpr struct zxdg_exported_v1_listener xdg_exported_listener = { + .handle = _xdg_exported_on_exported + }; + static constexpr struct zxdg_toplevel_decoration_v1_listener xdg_toplevel_decoration_listener = { .configure = _xdg_toplevel_decoration_on_configure, }; diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp index 20e2e897f2..93d528bab6 100644 --- a/platform/linuxbsd/x11/display_server_x11.cpp +++ b/platform/linuxbsd/x11/display_server_x11.cpp @@ -6080,10 +6080,11 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode if (context_rd) { if (context_rd->initialize() != OK) { + ERR_PRINT(vformat("Could not initialize %s", context_rd->get_api_name())); memdelete(context_rd); context_rd = nullptr; r_error = ERR_CANT_CREATE; - ERR_FAIL_MSG(vformat("Could not initialize %s", context_rd->get_api_name())); + return; } driver_found = true; } |