summaryrefslogtreecommitdiffstats
path: root/platform/linuxbsd
diff options
context:
space:
mode:
Diffstat (limited to 'platform/linuxbsd')
-rw-r--r--platform/linuxbsd/detect.py2
-rw-r--r--platform/linuxbsd/export/export_plugin.cpp100
-rw-r--r--platform/linuxbsd/export/export_plugin.h2
-rw-r--r--platform/linuxbsd/joypad_linux.cpp6
-rw-r--r--platform/linuxbsd/joypad_linux.h15
-rw-r--r--platform/linuxbsd/wayland/display_server_wayland.cpp2
-rw-r--r--platform/linuxbsd/wayland/rendering_context_driver_vulkan_wayland.cpp2
-rw-r--r--platform/linuxbsd/wayland/wayland_thread.cpp95
-rw-r--r--platform/linuxbsd/wayland/wayland_thread.h10
-rw-r--r--platform/linuxbsd/x11/display_server_x11.cpp37
-rw-r--r--platform/linuxbsd/x11/display_server_x11.h2
-rw-r--r--platform/linuxbsd/x11/rendering_context_driver_vulkan_x11.cpp2
12 files changed, 209 insertions, 66 deletions
diff --git a/platform/linuxbsd/detect.py b/platform/linuxbsd/detect.py
index 303a88ab26..d1de760f34 100644
--- a/platform/linuxbsd/detect.py
+++ b/platform/linuxbsd/detect.py
@@ -179,6 +179,8 @@ def configure(env: "SConsEnvironment"):
env.Append(CCFLAGS=["-fsanitize-recover=memory"])
env.Append(LINKFLAGS=["-fsanitize=memory"])
+ env.Append(CCFLAGS=["-ffp-contract=off"])
+
# LTO
if env["lto"] == "auto": # Full LTO for production.
diff --git a/platform/linuxbsd/export/export_plugin.cpp b/platform/linuxbsd/export/export_plugin.cpp
index 936adddda3..0032b898d2 100644
--- a/platform/linuxbsd/export/export_plugin.cpp
+++ b/platform/linuxbsd/export/export_plugin.cpp
@@ -61,6 +61,20 @@ Error EditorExportPlatformLinuxBSD::_export_debug_script(const Ref<EditorExportP
}
Error EditorExportPlatformLinuxBSD::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) {
+ String custom_debug = p_preset->get("custom_template/debug");
+ String custom_release = p_preset->get("custom_template/release");
+ String arch = p_preset->get("binary_format/architecture");
+
+ String template_path = p_debug ? custom_debug : custom_release;
+ template_path = template_path.strip_edges();
+ if (!template_path.is_empty()) {
+ String exe_arch = _get_exe_arch(template_path);
+ if (arch != exe_arch) {
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Templates"), vformat(TTR("Mismatching custom export template executable architecture, found \"%s\", expected \"%s\"."), exe_arch, arch));
+ return ERR_CANT_CREATE;
+ }
+ }
+
bool export_as_zip = p_path.ends_with("zip");
String pkg_name;
@@ -205,8 +219,76 @@ bool EditorExportPlatformLinuxBSD::is_executable(const String &p_path) const {
return is_elf(p_path) || is_shebang(p_path);
}
+bool EditorExportPlatformLinuxBSD::has_valid_export_configuration(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates, bool p_debug) const {
+ String err;
+ bool valid = EditorExportPlatformPC::has_valid_export_configuration(p_preset, err, r_missing_templates, p_debug);
+
+ String custom_debug = p_preset->get("custom_template/debug").operator String().strip_edges();
+ String custom_release = p_preset->get("custom_template/release").operator String().strip_edges();
+ String arch = p_preset->get("binary_format/architecture");
+
+ if (!custom_debug.is_empty() && FileAccess::exists(custom_debug)) {
+ String exe_arch = _get_exe_arch(custom_debug);
+ if (arch != exe_arch) {
+ err += vformat(TTR("Mismatching custom debug export template executable architecture: found \"%s\", expected \"%s\"."), exe_arch, arch) + "\n";
+ }
+ }
+ if (!custom_release.is_empty() && FileAccess::exists(custom_release)) {
+ String exe_arch = _get_exe_arch(custom_release);
+ if (arch != exe_arch) {
+ err += vformat(TTR("Mismatching custom release export template executable architecture: found \"%s\", expected \"%s\"."), exe_arch, arch) + "\n";
+ }
+ }
+
+ if (!err.is_empty()) {
+ r_error = err;
+ }
+
+ return valid;
+}
+
+String EditorExportPlatformLinuxBSD::_get_exe_arch(const String &p_path) const {
+ Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ);
+ if (f.is_null()) {
+ return "invalid";
+ }
+
+ // Read and check ELF magic number.
+ {
+ uint32_t magic = f->get_32();
+ if (magic != 0x464c457f) { // 0x7F + "ELF"
+ return "invalid";
+ }
+ }
+
+ // Process header.
+ int64_t header_pos = f->get_position();
+ f->seek(header_pos + 14);
+ uint16_t machine = f->get_16();
+ f->close();
+
+ switch (machine) {
+ case 0x0003:
+ return "x86_32";
+ case 0x003e:
+ return "x86_64";
+ case 0x0014:
+ return "ppc32";
+ case 0x0015:
+ return "ppc64";
+ case 0x0028:
+ return "arm32";
+ case 0x00b7:
+ return "arm64";
+ case 0x00f3:
+ return "rv64";
+ default:
+ return "unknown";
+ }
+}
+
Error EditorExportPlatformLinuxBSD::fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size) {
- // Patch the header of the "pck" section in the ELF file so that it corresponds to the embedded data
+ // Patch the header of the "pck" section in the ELF file so that it corresponds to the embedded data.
Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ_WRITE);
if (f.is_null()) {
@@ -214,7 +296,7 @@ Error EditorExportPlatformLinuxBSD::fixup_embedded_pck(const String &p_path, int
return ERR_CANT_OPEN;
}
- // Read and check ELF magic number
+ // Read and check ELF magic number.
{
uint32_t magic = f->get_32();
if (magic != 0x464c457f) { // 0x7F + "ELF"
@@ -223,7 +305,7 @@ Error EditorExportPlatformLinuxBSD::fixup_embedded_pck(const String &p_path, int
}
}
- // Read program architecture bits from class field
+ // Read program architecture bits from class field.
int bits = f->get_8() * 32;
@@ -231,7 +313,7 @@ Error EditorExportPlatformLinuxBSD::fixup_embedded_pck(const String &p_path, int
add_message(EXPORT_MESSAGE_ERROR, TTR("PCK Embedding"), TTR("32-bit executables cannot have embedded data >= 4 GiB."));
}
- // Get info about the section header table
+ // Get info about the section header table.
int64_t section_table_pos;
int64_t section_header_size;
@@ -249,13 +331,13 @@ Error EditorExportPlatformLinuxBSD::fixup_embedded_pck(const String &p_path, int
int num_sections = f->get_16();
int string_section_idx = f->get_16();
- // Load the strings table
+ // Load the strings table.
uint8_t *strings;
{
- // Jump to the strings section header
+ // Jump to the strings section header.
f->seek(section_table_pos + string_section_idx * section_header_size);
- // Read strings data size and offset
+ // Read strings data size and offset.
int64_t string_data_pos;
int64_t string_data_size;
if (bits == 32) {
@@ -268,7 +350,7 @@ Error EditorExportPlatformLinuxBSD::fixup_embedded_pck(const String &p_path, int
string_data_size = f->get_64();
}
- // Read strings data
+ // Read strings data.
f->seek(string_data_pos);
strings = (uint8_t *)memalloc(string_data_size);
if (!strings) {
@@ -277,7 +359,7 @@ Error EditorExportPlatformLinuxBSD::fixup_embedded_pck(const String &p_path, int
f->get_buffer(strings, string_data_size);
}
- // Search for the "pck" section
+ // Search for the "pck" section.
bool found = false;
for (int i = 0; i < num_sections; ++i) {
diff --git a/platform/linuxbsd/export/export_plugin.h b/platform/linuxbsd/export/export_plugin.h
index 21bd81ed2f..bbc55b82ce 100644
--- a/platform/linuxbsd/export/export_plugin.h
+++ b/platform/linuxbsd/export/export_plugin.h
@@ -69,11 +69,13 @@ class EditorExportPlatformLinuxBSD : public EditorExportPlatformPC {
bool is_shebang(const String &p_path) const;
Error _export_debug_script(const Ref<EditorExportPreset> &p_preset, const String &p_app_name, const String &p_pkg_name, const String &p_path);
+ String _get_exe_arch(const String &p_path) const;
public:
virtual void get_export_options(List<ExportOption> *r_options) const override;
virtual List<String> get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const override;
virtual bool get_export_option_visibility(const EditorExportPreset *p_preset, const String &p_option) const override;
+ virtual bool has_valid_export_configuration(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates, bool p_debug = false) const override;
virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0) override;
virtual String get_template_file_name(const String &p_target, const String &p_arch) const override;
virtual Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size) override;
diff --git a/platform/linuxbsd/joypad_linux.cpp b/platform/linuxbsd/joypad_linux.cpp
index 3534c1afee..a67428b9a4 100644
--- a/platform/linuxbsd/joypad_linux.cpp
+++ b/platform/linuxbsd/joypad_linux.cpp
@@ -374,6 +374,12 @@ void JoypadLinux::open_joypad(const char *p_path) {
name = namebuf;
}
+ for (const String &word : name.to_lower().split(" ")) {
+ if (banned_words.has(word)) {
+ return;
+ }
+ }
+
if (ioctl(fd, EVIOCGID, &inpid) < 0) {
close(fd);
return;
diff --git a/platform/linuxbsd/joypad_linux.h b/platform/linuxbsd/joypad_linux.h
index 26a9908d4e..bf24d8e5a5 100644
--- a/platform/linuxbsd/joypad_linux.h
+++ b/platform/linuxbsd/joypad_linux.h
@@ -94,6 +94,21 @@ private:
Vector<String> attached_devices;
+ // List of lowercase words that will prevent the controller from being recognized if its name matches.
+ // This is done to prevent trackpads, graphics tablets and motherboard LED controllers from being
+ // recognized as controllers (and taking up controller ID slots as a result).
+ // Only whole words are matched within the controller name string. The match is case-insensitive.
+ const Vector<String> banned_words = {
+ "touchpad", // Matches e.g. "SynPS/2 Synaptics TouchPad", "Sony Interactive Entertainment DualSense Wireless Controller Touchpad"
+ "trackpad",
+ "clickpad",
+ "keyboard", // Matches e.g. "PG-90215 Keyboard", "Usb Keyboard Usb Keyboard Consumer Control"
+ "mouse", // Matches e.g. "Mouse passthrough"
+ "pen", // Matches e.g. "Wacom One by Wacom S Pen"
+ "finger", // Matches e.g. "Wacom HID 495F Finger"
+ "led", // Matches e.g. "ASRock LED Controller"
+ };
+
static void monitor_joypads_thread_func(void *p_user);
void monitor_joypads_thread_run();
diff --git a/platform/linuxbsd/wayland/display_server_wayland.cpp b/platform/linuxbsd/wayland/display_server_wayland.cpp
index adc9beed66..93096fcdcc 100644
--- a/platform/linuxbsd/wayland/display_server_wayland.cpp
+++ b/platform/linuxbsd/wayland/display_server_wayland.cpp
@@ -1238,7 +1238,7 @@ void DisplayServerWayland::process_events() {
} else {
try_suspend();
}
- } else if (wayland_thread.get_reset_frame()) {
+ } else if (!wayland_thread.is_suspended() || wayland_thread.get_reset_frame()) {
// At last, a sign of life! We're no longer suspended.
suspended = false;
}
diff --git a/platform/linuxbsd/wayland/rendering_context_driver_vulkan_wayland.cpp b/platform/linuxbsd/wayland/rendering_context_driver_vulkan_wayland.cpp
index c874c45a8a..0417ba95eb 100644
--- a/platform/linuxbsd/wayland/rendering_context_driver_vulkan_wayland.cpp
+++ b/platform/linuxbsd/wayland/rendering_context_driver_vulkan_wayland.cpp
@@ -51,7 +51,7 @@ RenderingContextDriver::SurfaceID RenderingContextDriverVulkanWayland::surface_c
create_info.surface = wpd->surface;
VkSurfaceKHR vk_surface = VK_NULL_HANDLE;
- VkResult err = vkCreateWaylandSurfaceKHR(instance_get(), &create_info, nullptr, &vk_surface);
+ VkResult err = vkCreateWaylandSurfaceKHR(instance_get(), &create_info, get_allocation_callbacks(VK_OBJECT_TYPE_SURFACE_KHR), &vk_surface);
ERR_FAIL_COND_V(err != VK_SUCCESS, SurfaceID());
Surface *surface = memnew(Surface);
diff --git a/platform/linuxbsd/wayland/wayland_thread.cpp b/platform/linuxbsd/wayland/wayland_thread.cpp
index 341cc517e3..ab13105d18 100644
--- a/platform/linuxbsd/wayland/wayland_thread.cpp
+++ b/platform/linuxbsd/wayland/wayland_thread.cpp
@@ -1263,23 +1263,25 @@ void WaylandThread::_wl_seat_on_capabilities(void *data, struct wl_seat *wl_seat
// Pointer handling.
if (capabilities & WL_SEAT_CAPABILITY_POINTER) {
- ss->cursor_surface = wl_compositor_create_surface(ss->registry->wl_compositor);
- wl_surface_commit(ss->cursor_surface);
+ if (!ss->wl_pointer) {
+ ss->cursor_surface = wl_compositor_create_surface(ss->registry->wl_compositor);
+ wl_surface_commit(ss->cursor_surface);
- ss->wl_pointer = wl_seat_get_pointer(wl_seat);
- wl_pointer_add_listener(ss->wl_pointer, &wl_pointer_listener, ss);
+ ss->wl_pointer = wl_seat_get_pointer(wl_seat);
+ wl_pointer_add_listener(ss->wl_pointer, &wl_pointer_listener, ss);
- if (ss->registry->wp_relative_pointer_manager) {
- ss->wp_relative_pointer = zwp_relative_pointer_manager_v1_get_relative_pointer(ss->registry->wp_relative_pointer_manager, ss->wl_pointer);
- zwp_relative_pointer_v1_add_listener(ss->wp_relative_pointer, &wp_relative_pointer_listener, ss);
- }
+ if (ss->registry->wp_relative_pointer_manager) {
+ ss->wp_relative_pointer = zwp_relative_pointer_manager_v1_get_relative_pointer(ss->registry->wp_relative_pointer_manager, ss->wl_pointer);
+ zwp_relative_pointer_v1_add_listener(ss->wp_relative_pointer, &wp_relative_pointer_listener, ss);
+ }
- if (ss->registry->wp_pointer_gestures) {
- ss->wp_pointer_gesture_pinch = zwp_pointer_gestures_v1_get_pinch_gesture(ss->registry->wp_pointer_gestures, ss->wl_pointer);
- zwp_pointer_gesture_pinch_v1_add_listener(ss->wp_pointer_gesture_pinch, &wp_pointer_gesture_pinch_listener, ss);
- }
+ if (ss->registry->wp_pointer_gestures) {
+ ss->wp_pointer_gesture_pinch = zwp_pointer_gestures_v1_get_pinch_gesture(ss->registry->wp_pointer_gestures, ss->wl_pointer);
+ zwp_pointer_gesture_pinch_v1_add_listener(ss->wp_pointer_gesture_pinch, &wp_pointer_gesture_pinch_listener, ss);
+ }
- // TODO: Constrain new pointers if the global mouse mode is constrained.
+ // TODO: Constrain new pointers if the global mouse mode is constrained.
+ }
} else {
if (ss->cursor_frame_callback) {
// Just in case. I got bitten by weird race-like conditions already.
@@ -1317,11 +1319,13 @@ void WaylandThread::_wl_seat_on_capabilities(void *data, struct wl_seat *wl_seat
// Keyboard handling.
if (capabilities & WL_SEAT_CAPABILITY_KEYBOARD) {
- ss->xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
- ERR_FAIL_NULL(ss->xkb_context);
+ if (!ss->wl_keyboard) {
+ ss->xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
+ ERR_FAIL_NULL(ss->xkb_context);
- ss->wl_keyboard = wl_seat_get_keyboard(wl_seat);
- wl_keyboard_add_listener(ss->wl_keyboard, &wl_keyboard_listener, ss);
+ ss->wl_keyboard = wl_seat_get_keyboard(wl_seat);
+ wl_keyboard_add_listener(ss->wl_keyboard, &wl_keyboard_listener, ss);
+ }
} else {
if (ss->xkb_context) {
xkb_context_unref(ss->xkb_context);
@@ -1412,10 +1416,10 @@ void WaylandThread::_wl_pointer_on_motion(void *data, struct wl_pointer *wl_poin
PointerData &pd = ss->pointer_data_buffer;
// TODO: Scale only when sending the Wayland message.
- pd.position.x = wl_fixed_to_int(surface_x);
- pd.position.y = wl_fixed_to_int(surface_y);
+ pd.position.x = wl_fixed_to_double(surface_x);
+ pd.position.y = wl_fixed_to_double(surface_y);
- pd.position = scale_vector2i(pd.position, window_state_get_scale_factor(ws));
+ pd.position *= window_state_get_scale_factor(ws);
pd.motion_time = time;
}
@@ -1528,7 +1532,7 @@ void WaylandThread::_wl_pointer_on_frame(void *data, struct wl_pointer *wl_point
mm->set_position(pd.position);
mm->set_global_position(pd.position);
- Vector2i pos_delta = pd.position - old_pd.position;
+ Vector2 pos_delta = pd.position - old_pd.position;
if (old_pd.relative_motion_time != pd.relative_motion_time) {
uint32_t time_delta = pd.relative_motion_time - old_pd.relative_motion_time;
@@ -1645,7 +1649,7 @@ void WaylandThread::_wl_pointer_on_frame(void *data, struct wl_pointer *wl_point
// We have to set the last position pressed here as we can't take for
// granted what the individual events might have seen due to them not having
- // a garaunteed order.
+ // a guaranteed order.
if (mb->is_pressed()) {
pd.last_pressed_position = pd.position;
}
@@ -2047,11 +2051,21 @@ void WaylandThread::_wp_relative_pointer_on_relative_motion(void *data, struct z
SeatState *ss = (SeatState *)data;
ERR_FAIL_NULL(ss);
+ if (!ss->pointed_surface) {
+ // We're probably on a decoration or some other third-party thing.
+ return;
+ }
+
PointerData &pd = ss->pointer_data_buffer;
+ WindowState *ws = wl_surface_get_window_state(ss->pointed_surface);
+ ERR_FAIL_NULL(ws);
+
pd.relative_motion.x = wl_fixed_to_double(dx);
pd.relative_motion.y = wl_fixed_to_double(dy);
+ pd.relative_motion *= window_state_get_scale_factor(ws);
+
pd.relative_motion_time = uptime_lo;
}
@@ -2244,13 +2258,11 @@ void WaylandThread::_wp_tablet_tool_on_done(void *data, struct zwp_tablet_tool_v
void WaylandThread::_wp_tablet_tool_on_removed(void *data, struct zwp_tablet_tool_v2 *wp_tablet_tool_v2) {
TabletToolState *ts = wp_tablet_tool_get_state(wp_tablet_tool_v2);
-
if (!ts) {
return;
}
SeatState *ss = wl_seat_get_seat_state(ts->wl_seat);
-
if (!ss) {
return;
}
@@ -2270,14 +2282,17 @@ void WaylandThread::_wp_tablet_tool_on_removed(void *data, struct zwp_tablet_too
}
void WaylandThread::_wp_tablet_tool_on_proximity_in(void *data, struct zwp_tablet_tool_v2 *wp_tablet_tool_v2, uint32_t serial, struct zwp_tablet_v2 *tablet, struct wl_surface *surface) {
- TabletToolState *ts = wp_tablet_tool_get_state(wp_tablet_tool_v2);
+ if (!surface || !wl_proxy_is_godot((struct wl_proxy *)surface)) {
+ // We're probably on a decoration or something.
+ return;
+ }
+ TabletToolState *ts = wp_tablet_tool_get_state(wp_tablet_tool_v2);
if (!ts) {
return;
}
SeatState *ss = wl_seat_get_seat_state(ts->wl_seat);
-
if (!ss) {
return;
}
@@ -2299,13 +2314,12 @@ void WaylandThread::_wp_tablet_tool_on_proximity_in(void *data, struct zwp_table
void WaylandThread::_wp_tablet_tool_on_proximity_out(void *data, struct zwp_tablet_tool_v2 *wp_tablet_tool_v2) {
TabletToolState *ts = wp_tablet_tool_get_state(wp_tablet_tool_v2);
-
- if (!ts) {
+ if (!ts || !ts->data_pending.proximal_surface) {
+ // Not our stuff, we don't care.
return;
}
SeatState *ss = wl_seat_get_seat_state(ts->wl_seat);
-
if (!ss) {
return;
}
@@ -2326,7 +2340,6 @@ void WaylandThread::_wp_tablet_tool_on_proximity_out(void *data, struct zwp_tabl
void WaylandThread::_wp_tablet_tool_on_down(void *data, struct zwp_tablet_tool_v2 *wp_tablet_tool_v2, uint32_t serial) {
TabletToolState *ts = wp_tablet_tool_get_state(wp_tablet_tool_v2);
-
if (!ts) {
return;
}
@@ -2344,7 +2357,6 @@ void WaylandThread::_wp_tablet_tool_on_down(void *data, struct zwp_tablet_tool_v
void WaylandThread::_wp_tablet_tool_on_up(void *data, struct zwp_tablet_tool_v2 *wp_tablet_tool_v2) {
TabletToolState *ts = wp_tablet_tool_get_state(wp_tablet_tool_v2);
-
if (!ts) {
return;
}
@@ -2360,11 +2372,15 @@ void WaylandThread::_wp_tablet_tool_on_up(void *data, struct zwp_tablet_tool_v2
void WaylandThread::_wp_tablet_tool_on_motion(void *data, struct zwp_tablet_tool_v2 *wp_tablet_tool_v2, wl_fixed_t x, wl_fixed_t y) {
TabletToolState *ts = wp_tablet_tool_get_state(wp_tablet_tool_v2);
-
if (!ts) {
return;
}
+ if (!ts->data_pending.proximal_surface) {
+ // We're probably on a decoration or some other third-party thing.
+ return;
+ }
+
WindowState *ws = wl_surface_get_window_state(ts->data_pending.proximal_surface);
ERR_FAIL_NULL(ws);
@@ -2372,16 +2388,15 @@ void WaylandThread::_wp_tablet_tool_on_motion(void *data, struct zwp_tablet_tool
double scale_factor = window_state_get_scale_factor(ws);
- td.position.x = wl_fixed_to_int(x);
- td.position.y = wl_fixed_to_int(y);
- td.position = scale_vector2i(td.position, scale_factor);
+ td.position.x = wl_fixed_to_double(x);
+ td.position.y = wl_fixed_to_double(y);
+ td.position *= scale_factor;
td.motion_time = OS::get_singleton()->get_ticks_msec();
}
void WaylandThread::_wp_tablet_tool_on_pressure(void *data, struct zwp_tablet_tool_v2 *wp_tablet_tool_v2, uint32_t pressure) {
TabletToolState *ts = wp_tablet_tool_get_state(wp_tablet_tool_v2);
-
if (!ts) {
return;
}
@@ -2395,7 +2410,6 @@ void WaylandThread::_wp_tablet_tool_on_distance(void *data, struct zwp_tablet_to
void WaylandThread::_wp_tablet_tool_on_tilt(void *data, struct zwp_tablet_tool_v2 *wp_tablet_tool_v2, wl_fixed_t tilt_x, wl_fixed_t tilt_y) {
TabletToolState *ts = wp_tablet_tool_get_state(wp_tablet_tool_v2);
-
if (!ts) {
return;
}
@@ -2420,7 +2434,6 @@ void WaylandThread::_wp_tablet_tool_on_wheel(void *data, struct zwp_tablet_tool_
void WaylandThread::_wp_tablet_tool_on_button(void *data, struct zwp_tablet_tool_v2 *wp_tablet_tool_v2, uint32_t serial, uint32_t button, uint32_t state) {
TabletToolState *ts = wp_tablet_tool_get_state(wp_tablet_tool_v2);
-
if (!ts) {
return;
}
@@ -2456,13 +2469,11 @@ void WaylandThread::_wp_tablet_tool_on_button(void *data, struct zwp_tablet_tool
void WaylandThread::_wp_tablet_tool_on_frame(void *data, struct zwp_tablet_tool_v2 *wp_tablet_tool_v2, uint32_t time) {
TabletToolState *ts = wp_tablet_tool_get_state(wp_tablet_tool_v2);
-
if (!ts) {
return;
}
SeatState *ss = wl_seat_get_seat_state(ts->wl_seat);
-
if (!ss) {
return;
}
@@ -2509,7 +2520,7 @@ void WaylandThread::_wp_tablet_tool_on_frame(void *data, struct zwp_tablet_tool_
mm->set_relative(td.position - old_td.position);
mm->set_relative_screen_position(mm->get_relative());
- Vector2i pos_delta = td.position - old_td.position;
+ Vector2 pos_delta = td.position - old_td.position;
uint32_t time_delta = td.motion_time - old_td.motion_time;
mm->set_velocity((Vector2)pos_delta / time_delta);
@@ -3240,6 +3251,8 @@ void WaylandThread::window_create(DisplayServer::WindowID p_window_id, int p_wid
zxdg_exported_v1_add_listener(ws.xdg_exported, &xdg_exported_listener, &ws);
}
+ wl_surface_commit(ws.wl_surface);
+
// Wait for the surface to be configured before continuing.
wl_display_roundtrip(wl_display);
}
diff --git a/platform/linuxbsd/wayland/wayland_thread.h b/platform/linuxbsd/wayland/wayland_thread.h
index 775ca71346..84e9bdc2dc 100644
--- a/platform/linuxbsd/wayland/wayland_thread.h
+++ b/platform/linuxbsd/wayland/wayland_thread.h
@@ -44,7 +44,7 @@
#include <wayland-client-core.h>
#include <wayland-cursor.h>
#ifdef GLES3_ENABLED
-#include <wayland-egl.h>
+#include <wayland-egl-core.h>
#endif
#include <xkbcommon/xkbcommon.h>
#endif // SOWRAP_ENABLED
@@ -295,7 +295,7 @@ public:
};
struct PointerData {
- Point2i position;
+ Point2 position;
uint32_t motion_time = 0;
// Relative motion has its own optional event and so needs its own time.
@@ -305,7 +305,7 @@ public:
BitField<MouseButtonMask> pressed_button_mask;
MouseButton last_button_pressed = MouseButton::NONE;
- Point2i last_pressed_position;
+ Point2 last_pressed_position;
// This is needed to check for a new double click every time.
bool double_click_begun = false;
@@ -325,14 +325,14 @@ public:
};
struct TabletToolData {
- Point2i position;
+ Point2 position;
Vector2 tilt;
uint32_t pressure = 0;
BitField<MouseButtonMask> pressed_button_mask;
MouseButton last_button_pressed = MouseButton::NONE;
- Point2i last_pressed_position;
+ Point2 last_pressed_position;
bool double_click_begun = false;
diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp
index edf3a40ccb..8a2f83be2d 100644
--- a/platform/linuxbsd/x11/display_server_x11.cpp
+++ b/platform/linuxbsd/x11/display_server_x11.cpp
@@ -1519,7 +1519,7 @@ Color DisplayServerX11::screen_get_pixel(const Point2i &p_position) const {
if (image) {
XColor c;
c.pixel = XGetPixel(image, 0, 0);
- XFree(image);
+ XDestroyImage(image);
XQueryColor(x11_display, XDefaultColormap(x11_display, i), &c);
color = Color(float(c.red) / 65535.0, float(c.green) / 65535.0, float(c.blue) / 65535.0, 1.0);
break;
@@ -1637,11 +1637,12 @@ Ref<Image> DisplayServerX11::screen_get_image(int p_screen) const {
}
}
} else {
- XFree(image);
- ERR_FAIL_V_MSG(Ref<Image>(), vformat("XImage with RGB mask %x %x %x and depth %d is not supported.", (uint64_t)image->red_mask, (uint64_t)image->green_mask, (uint64_t)image->blue_mask, (int64_t)image->bits_per_pixel));
+ String msg = vformat("XImage with RGB mask %x %x %x and depth %d is not supported.", (uint64_t)image->red_mask, (uint64_t)image->green_mask, (uint64_t)image->blue_mask, (int64_t)image->bits_per_pixel);
+ XDestroyImage(image);
+ ERR_FAIL_V_MSG(Ref<Image>(), msg);
}
img = Image::create_from_data(width, height, false, Image::FORMAT_RGBA8, img_data);
- XFree(image);
+ XDestroyImage(image);
}
return img;
@@ -1734,7 +1735,7 @@ Vector<DisplayServer::WindowID> DisplayServerX11::get_window_list() const {
return ret;
}
-DisplayServer::WindowID DisplayServerX11::create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect) {
+DisplayServer::WindowID DisplayServerX11::create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect, bool p_exclusive, WindowID p_transient_parent) {
_THREAD_SAFE_METHOD_
WindowID id = _create_window(p_mode, p_vsync_mode, p_flags, p_rect);
@@ -1748,6 +1749,11 @@ DisplayServer::WindowID DisplayServerX11::create_sub_window(WindowMode p_mode, V
rendering_device->screen_create(id);
}
#endif
+
+ if (p_transient_parent != INVALID_WINDOW_ID) {
+ window_set_transient(id, p_transient_parent);
+ }
+
return id;
}
@@ -4964,6 +4970,23 @@ void DisplayServerX11::process_events() {
pos = Point2i(windows[focused_window_id].size.width / 2, windows[focused_window_id].size.height / 2);
}
+ BitField<MouseButtonMask> last_button_state = 0;
+ if (event.xmotion.state & Button1Mask) {
+ last_button_state.set_flag(MouseButtonMask::LEFT);
+ }
+ if (event.xmotion.state & Button2Mask) {
+ last_button_state.set_flag(MouseButtonMask::MIDDLE);
+ }
+ if (event.xmotion.state & Button3Mask) {
+ last_button_state.set_flag(MouseButtonMask::RIGHT);
+ }
+ if (event.xmotion.state & Button4Mask) {
+ last_button_state.set_flag(MouseButtonMask::MB_XBUTTON1);
+ }
+ if (event.xmotion.state & Button5Mask) {
+ last_button_state.set_flag(MouseButtonMask::MB_XBUTTON2);
+ }
+
Ref<InputEventMouseMotion> mm;
mm.instantiate();
@@ -4971,13 +4994,13 @@ void DisplayServerX11::process_events() {
if (xi.pressure_supported) {
mm->set_pressure(xi.pressure);
} else {
- mm->set_pressure(bool(mouse_get_button_state().has_flag(MouseButtonMask::LEFT)) ? 1.0f : 0.0f);
+ mm->set_pressure(bool(last_button_state.has_flag(MouseButtonMask::LEFT)) ? 1.0f : 0.0f);
}
mm->set_tilt(xi.tilt);
mm->set_pen_inverted(xi.pen_inverted);
_get_key_modifier_state(event.xmotion.state, mm);
- mm->set_button_mask(mouse_get_button_state());
+ mm->set_button_mask(last_button_state);
mm->set_position(pos);
mm->set_global_position(pos);
mm->set_velocity(Input::get_singleton()->get_last_mouse_velocity());
diff --git a/platform/linuxbsd/x11/display_server_x11.h b/platform/linuxbsd/x11/display_server_x11.h
index 341ba5f079..0cbfbe51ef 100644
--- a/platform/linuxbsd/x11/display_server_x11.h
+++ b/platform/linuxbsd/x11/display_server_x11.h
@@ -438,7 +438,7 @@ public:
virtual Vector<DisplayServer::WindowID> get_window_list() const override;
- virtual WindowID create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i()) override;
+ virtual WindowID create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i(), bool p_exclusive = false, WindowID p_transient_parent = INVALID_WINDOW_ID) override;
virtual void show_window(WindowID p_id) override;
virtual void delete_sub_window(WindowID p_id) override;
diff --git a/platform/linuxbsd/x11/rendering_context_driver_vulkan_x11.cpp b/platform/linuxbsd/x11/rendering_context_driver_vulkan_x11.cpp
index bf44062266..3f505d000c 100644
--- a/platform/linuxbsd/x11/rendering_context_driver_vulkan_x11.cpp
+++ b/platform/linuxbsd/x11/rendering_context_driver_vulkan_x11.cpp
@@ -51,7 +51,7 @@ RenderingContextDriver::SurfaceID RenderingContextDriverVulkanX11::surface_creat
create_info.window = wpd->window;
VkSurfaceKHR vk_surface = VK_NULL_HANDLE;
- VkResult err = vkCreateXlibSurfaceKHR(instance_get(), &create_info, nullptr, &vk_surface);
+ VkResult err = vkCreateXlibSurfaceKHR(instance_get(), &create_info, get_allocation_callbacks(VK_OBJECT_TYPE_SURFACE_KHR), &vk_surface);
ERR_FAIL_COND_V(err != VK_SUCCESS, SurfaceID());
Surface *surface = memnew(Surface);