summaryrefslogtreecommitdiffstats
path: root/platform/linuxbsd
diff options
context:
space:
mode:
Diffstat (limited to 'platform/linuxbsd')
-rw-r--r--platform/linuxbsd/detect.py24
-rw-r--r--platform/linuxbsd/godot_linuxbsd.cpp12
-rw-r--r--platform/linuxbsd/pck_embed.ld10
-rw-r--r--platform/linuxbsd/pck_embed.legacy.ld10
-rw-r--r--platform/linuxbsd/wayland/SCsub15
-rw-r--r--platform/linuxbsd/wayland/display_server_wayland.cpp53
-rw-r--r--platform/linuxbsd/wayland/display_server_wayland.h5
-rw-r--r--platform/linuxbsd/wayland/wayland_thread.cpp45
-rw-r--r--platform/linuxbsd/wayland/wayland_thread.h19
-rw-r--r--platform/linuxbsd/x11/display_server_x11.cpp3
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;
}