Path: blob/master/platform/linuxbsd/wayland/wayland_thread.h
11353 views
/**************************************************************************/1/* wayland_thread.h */2/**************************************************************************/3/* This file is part of: */4/* GODOT ENGINE */5/* https://godotengine.org */6/**************************************************************************/7/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */8/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */9/* */10/* Permission is hereby granted, free of charge, to any person obtaining */11/* a copy of this software and associated documentation files (the */12/* "Software"), to deal in the Software without restriction, including */13/* without limitation the rights to use, copy, modify, merge, publish, */14/* distribute, sublicense, and/or sell copies of the Software, and to */15/* permit persons to whom the Software is furnished to do so, subject to */16/* the following conditions: */17/* */18/* The above copyright notice and this permission notice shall be */19/* included in all copies or substantial portions of the Software. */20/* */21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */23/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */24/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */25/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */26/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */27/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */28/**************************************************************************/2930#pragma once3132#ifdef WAYLAND_ENABLED3334#include "key_mapping_xkb.h"3536#ifdef SOWRAP_ENABLED37#include "wayland/dynwrappers/wayland-client-core-so_wrap.h"38#include "wayland/dynwrappers/wayland-cursor-so_wrap.h"39#include "wayland/dynwrappers/wayland-egl-core-so_wrap.h"40#include "xkbcommon-so_wrap.h"41#else42#include <wayland-client-core.h>43#include <wayland-cursor.h>44#ifdef GLES3_ENABLED45#include <wayland-egl-core.h>46#endif47#include <xkbcommon/xkbcommon.h>48#endif // SOWRAP_ENABLED4950// These must go after the Wayland client include to work properly.51#include "wayland/protocol/idle_inhibit.gen.h"52#include "wayland/protocol/primary_selection.gen.h"53// These four protocol headers name wl_pointer method arguments as `pointer`,54// which is the same name as X11's pointer typedef. This trips some very55// annoying shadowing warnings. A `#define` works around this issue.56#define pointer wl_pointer57#include "wayland/protocol/cursor_shape.gen.h"58#include "wayland/protocol/pointer_constraints.gen.h"59#include "wayland/protocol/pointer_gestures.gen.h"60#include "wayland/protocol/relative_pointer.gen.h"61#undef pointer62#include "wayland/protocol/fractional_scale.gen.h"63#include "wayland/protocol/tablet.gen.h"64#include "wayland/protocol/text_input.gen.h"65#include "wayland/protocol/viewporter.gen.h"66#include "wayland/protocol/wayland.gen.h"67#include "wayland/protocol/xdg_activation.gen.h"68#include "wayland/protocol/xdg_decoration.gen.h"69#include "wayland/protocol/xdg_foreign_v2.gen.h"70#include "wayland/protocol/xdg_shell.gen.h"71#include "wayland/protocol/xdg_system_bell.gen.h"72#include "wayland/protocol/xdg_toplevel_icon.gen.h"7374// NOTE: Deprecated.75#include "wayland/protocol/xdg_foreign_v1.gen.h"7677#ifdef LIBDECOR_ENABLED78#ifdef SOWRAP_ENABLED79#include "dynwrappers/libdecor-so_wrap.h"80#else81#include <libdecor.h>82#endif // SOWRAP_ENABLED83#endif // LIBDECOR_ENABLED8485#include "core/os/thread.h"86#include "servers/display/display_server.h"8788class WaylandThread {89public:90// Messages used for exchanging information between Godot's and Wayland's thread.91class Message : public RefCounted {92GDSOFTCLASS(Message, RefCounted);9394public:95Message() {}96virtual ~Message() = default;97};9899class WindowMessage : public Message {100GDSOFTCLASS(WindowMessage, Message);101102public:103DisplayServer::WindowID id = DisplayServer::INVALID_WINDOW_ID;104};105106// Message data for window rect changes.107class WindowRectMessage : public WindowMessage {108GDSOFTCLASS(WindowRectMessage, WindowMessage);109110public:111// NOTE: This is in "scaled" terms. For example, if there's a 1920x1080 rect112// with a scale factor of 2, the actual value of `rect` will be 3840x2160.113Rect2i rect;114};115116class WindowEventMessage : public WindowMessage {117GDSOFTCLASS(WindowEventMessage, WindowMessage);118119public:120DisplayServer::WindowEvent event;121};122123class InputEventMessage : public Message {124GDSOFTCLASS(InputEventMessage, Message);125126public:127Ref<InputEvent> event;128};129130class DropFilesEventMessage : public WindowMessage {131GDSOFTCLASS(DropFilesEventMessage, WindowMessage);132133public:134Vector<String> files;135};136137class IMEUpdateEventMessage : public WindowMessage {138GDSOFTCLASS(IMEUpdateEventMessage, WindowMessage);139140public:141String text;142Vector2i selection;143};144145class IMECommitEventMessage : public WindowMessage {146GDSOFTCLASS(IMECommitEventMessage, WindowMessage);147148public:149String text;150};151152struct RegistryState {153WaylandThread *wayland_thread;154155// Core Wayland globals.156struct wl_shm *wl_shm = nullptr;157uint32_t wl_shm_name = 0;158159struct wl_compositor *wl_compositor = nullptr;160uint32_t wl_compositor_name = 0;161162struct wl_subcompositor *wl_subcompositor = nullptr;163uint32_t wl_subcompositor_name = 0;164165struct wl_data_device_manager *wl_data_device_manager = nullptr;166uint32_t wl_data_device_manager_name = 0;167168List<struct wl_output *> wl_outputs;169List<struct wl_seat *> wl_seats;170171// xdg-shell globals.172173struct xdg_wm_base *xdg_wm_base = nullptr;174uint32_t xdg_wm_base_name = 0;175176// NOTE: Deprecated.177struct zxdg_exporter_v1 *xdg_exporter_v1 = nullptr;178uint32_t xdg_exporter_v1_name = 0;179180uint32_t xdg_exporter_v2_name = 0;181struct zxdg_exporter_v2 *xdg_exporter_v2 = nullptr;182183// wayland-protocols globals.184185struct wp_viewporter *wp_viewporter = nullptr;186uint32_t wp_viewporter_name = 0;187188struct wp_fractional_scale_manager_v1 *wp_fractional_scale_manager = nullptr;189uint32_t wp_fractional_scale_manager_name = 0;190191struct wp_cursor_shape_manager_v1 *wp_cursor_shape_manager = nullptr;192uint32_t wp_cursor_shape_manager_name = 0;193194struct zxdg_decoration_manager_v1 *xdg_decoration_manager = nullptr;195uint32_t xdg_decoration_manager_name = 0;196197struct xdg_system_bell_v1 *xdg_system_bell = nullptr;198uint32_t xdg_system_bell_name = 0;199200struct xdg_toplevel_icon_manager_v1 *xdg_toplevel_icon_manager = nullptr;201uint32_t xdg_toplevel_icon_manager_name = 0;202203struct xdg_activation_v1 *xdg_activation = nullptr;204uint32_t xdg_activation_name = 0;205206struct zwp_primary_selection_device_manager_v1 *wp_primary_selection_device_manager = nullptr;207uint32_t wp_primary_selection_device_manager_name = 0;208209struct zwp_relative_pointer_manager_v1 *wp_relative_pointer_manager = nullptr;210uint32_t wp_relative_pointer_manager_name = 0;211212struct zwp_pointer_constraints_v1 *wp_pointer_constraints = nullptr;213uint32_t wp_pointer_constraints_name = 0;214215struct zwp_pointer_gestures_v1 *wp_pointer_gestures = nullptr;216uint32_t wp_pointer_gestures_name = 0;217218struct zwp_idle_inhibit_manager_v1 *wp_idle_inhibit_manager = nullptr;219uint32_t wp_idle_inhibit_manager_name = 0;220221struct zwp_tablet_manager_v2 *wp_tablet_manager = nullptr;222uint32_t wp_tablet_manager_name = 0;223224struct zwp_text_input_manager_v3 *wp_text_input_manager = nullptr;225uint32_t wp_text_input_manager_name = 0;226227// We're really not meant to use this one directly but we still need to know228// whether it's available.229uint32_t wp_fifo_manager_name = 0;230};231232// General Wayland-specific states. Shouldn't be accessed directly.233// TODO: Make private?234235struct WindowState {236DisplayServer::WindowID id = DisplayServer::INVALID_WINDOW_ID;237DisplayServer::WindowID parent_id = DisplayServer::INVALID_WINDOW_ID;238239Rect2i rect;240DisplayServer::WindowMode mode = DisplayServer::WINDOW_MODE_WINDOWED;241bool suspended = false;242243// These are true by default as it isn't guaranteed that we'll find an244// xdg-shell implementation with wm_capabilities available. If and once we245// receive a wm_capabilities event these will get reset and updated with246// whatever the compositor says.247bool can_minimize = false;248bool can_maximize = false;249bool can_fullscreen = false;250251HashSet<struct wl_output *> wl_outputs;252253// NOTE: If for whatever reason this callback is destroyed _while_ the event254// thread is still running, it might be a good idea to set its user data to255// `nullptr`. From some initial testing of mine, it looks like it might still256// be called even after being destroyed, pointing to probably invalid window257// data by then and segfaulting hard.258struct wl_callback *frame_callback = nullptr;259uint64_t last_frame_time = 0;260261struct wl_surface *wl_surface = nullptr;262struct xdg_surface *xdg_surface = nullptr;263struct xdg_toplevel *xdg_toplevel = nullptr;264265struct wp_viewport *wp_viewport = nullptr;266struct wp_fractional_scale_v1 *wp_fractional_scale = nullptr;267268// NOTE: Deprecated.269struct zxdg_exported_v1 *xdg_exported_v1 = nullptr;270271struct zxdg_exported_v2 *xdg_exported_v2 = nullptr;272273struct xdg_popup *xdg_popup = nullptr;274275String exported_handle;276277// Currently applied buffer scale.278int buffer_scale = 1;279280// Buffer scale must be applied right before rendering but _after_ committing281// everything else or otherwise we might have an inconsistent state (e.g.282// double scale and odd resolution). This flag assists with that; when set,283// on the next frame, we'll commit whatever is set in `buffer_scale`.284bool buffer_scale_changed = false;285286// NOTE: The preferred buffer scale is currently only dynamically calculated.287// It can be accessed by calling `window_state_get_preferred_buffer_scale`.288289// Override used by the fractional scale add-on object. If less or equal to 0290// (default) then the normal output-based scale is used instead.291double fractional_scale = 0;292293// What the compositor is recommending us.294double preferred_fractional_scale = 0;295296struct zxdg_toplevel_decoration_v1 *xdg_toplevel_decoration = nullptr;297298struct zwp_idle_inhibitor_v1 *wp_idle_inhibitor = nullptr;299300#ifdef LIBDECOR_ENABLED301// If this is null the xdg_* variables must be set and vice-versa. This way we302// can handle this mess gracefully enough to hopefully being able of getting303// rid of this cleanly once we have our own CSDs.304struct libdecor_frame *libdecor_frame = nullptr;305struct libdecor_configuration *pending_libdecor_configuration = nullptr;306#endif307308RegistryState *registry;309WaylandThread *wayland_thread;310};311312// "High level" Godot-side screen data.313struct ScreenData {314// Geometry data.315Point2i position;316317String make;318String model;319320Size2i size;321Size2i physical_size;322323float refresh_rate = -1;324int scale = 1;325};326327struct ScreenState {328uint32_t wl_output_name = 0;329330ScreenData pending_data;331ScreenData data;332333WaylandThread *wayland_thread;334};335336enum class Gesture {337NONE,338MAGNIFY,339};340341enum class PointerConstraint {342NONE,343LOCKED,344CONFINED,345};346347struct PointerData {348Point2 position;349uint32_t motion_time = 0;350351// Relative motion has its own optional event and so needs its own time.352Vector2 relative_motion;353uint32_t relative_motion_time = 0;354355BitField<MouseButtonMask> pressed_button_mask = MouseButtonMask::NONE;356357MouseButton last_button_pressed = MouseButton::NONE;358Point2 last_pressed_position;359360DisplayServer::WindowID pointed_id = DisplayServer::INVALID_WINDOW_ID;361DisplayServer::WindowID last_pointed_id = DisplayServer::INVALID_WINDOW_ID;362363// This is needed to check for a new double click every time.364bool double_click_begun = false;365366uint32_t button_time = 0;367uint32_t button_serial = 0;368369uint32_t scroll_type = WL_POINTER_AXIS_SOURCE_WHEEL;370371// The amount "scrolled" in pixels, in each direction.372Vector2 scroll_vector;373374// The amount of scroll "clicks" in each direction, in fractions of 120.375Vector2i discrete_scroll_vector_120;376377uint32_t pinch_scale = 1;378};379380struct TabletToolData {381Point2 position;382Vector2 tilt;383uint32_t pressure = 0;384385BitField<MouseButtonMask> pressed_button_mask = MouseButtonMask::NONE;386387MouseButton last_button_pressed = MouseButton::NONE;388Point2 last_pressed_position;389390bool double_click_begun = false;391392uint64_t button_time = 0;393uint64_t motion_time = 0;394395DisplayServer::WindowID proximal_id = DisplayServer::INVALID_WINDOW_ID;396DisplayServer::WindowID last_proximal_id = DisplayServer::INVALID_WINDOW_ID;397uint32_t proximity_serial = 0;398};399400struct TabletToolState {401struct wl_seat *wl_seat = nullptr;402403bool is_eraser = false;404405TabletToolData data_pending;406TabletToolData data;407};408409struct OfferState {410HashSet<String> mime_types;411};412413struct SeatState {414RegistryState *registry = nullptr;415416WaylandThread *wayland_thread = nullptr;417418struct wl_seat *wl_seat = nullptr;419uint32_t wl_seat_name = 0;420421// Pointer.422struct wl_pointer *wl_pointer = nullptr;423424uint32_t pointer_enter_serial = 0;425426struct wp_cursor_shape_device_v1 *wp_cursor_shape_device = nullptr;427428struct zwp_relative_pointer_v1 *wp_relative_pointer = nullptr;429struct zwp_locked_pointer_v1 *wp_locked_pointer = nullptr;430struct zwp_confined_pointer_v1 *wp_confined_pointer = nullptr;431432struct zwp_pointer_gesture_pinch_v1 *wp_pointer_gesture_pinch = nullptr;433434// NOTE: According to the wp_pointer_gestures protocol specification, there435// can be only one active gesture at a time.436Gesture active_gesture = Gesture::NONE;437438// Used for delta calculations.439// NOTE: The wp_pointer_gestures protocol keeps track of the total scale of440// the pinch gesture, while godot instead wants its delta.441wl_fixed_t old_pinch_scale = 0;442443struct wl_surface *cursor_surface = nullptr;444struct wl_callback *cursor_frame_callback = nullptr;445uint32_t cursor_time_ms = 0;446447// This variable is needed to buffer all pointer changes until a448// wl_pointer.frame event, as per Wayland's specification. Everything is449// first set in `data_buffer` and then `data` is set with its contents on450// an input frame event. All methods should generally read from451// `pointer_data` and write to `data_buffer`.452PointerData pointer_data_buffer;453PointerData pointer_data;454455// Keyboard.456struct wl_keyboard *wl_keyboard = nullptr;457458// For key events.459DisplayServer::WindowID focused_id = DisplayServer::INVALID_WINDOW_ID;460461struct xkb_context *xkb_context = nullptr;462struct xkb_keymap *xkb_keymap = nullptr;463struct xkb_state *xkb_state = nullptr;464465const char *keymap_buffer = nullptr;466uint32_t keymap_buffer_size = 0;467468HashMap<xkb_keycode_t, Key> pressed_keycodes;469470xkb_layout_index_t current_layout_index = 0;471472int32_t repeat_key_delay_msec = 0;473int32_t repeat_start_delay_msec = 0;474475xkb_keycode_t repeating_keycode = XKB_KEYCODE_INVALID;476uint64_t last_repeat_start_msec = 0;477uint64_t last_repeat_msec = 0;478479bool shift_pressed = false;480bool ctrl_pressed = false;481bool alt_pressed = false;482bool meta_pressed = false;483484uint32_t last_key_pressed_serial = 0;485486struct wl_data_device *wl_data_device = nullptr;487488// Drag and drop.489DisplayServer::WindowID dnd_id = DisplayServer::INVALID_WINDOW_ID;490struct wl_data_offer *wl_data_offer_dnd = nullptr;491uint32_t dnd_enter_serial = 0;492493// Clipboard.494struct wl_data_source *wl_data_source_selection = nullptr;495Vector<uint8_t> selection_data;496497struct wl_data_offer *wl_data_offer_selection = nullptr;498499// Primary selection.500struct zwp_primary_selection_device_v1 *wp_primary_selection_device = nullptr;501502struct zwp_primary_selection_source_v1 *wp_primary_selection_source = nullptr;503Vector<uint8_t> primary_data;504505struct zwp_primary_selection_offer_v1 *wp_primary_selection_offer = nullptr;506507// Tablet.508struct zwp_tablet_seat_v2 *wp_tablet_seat = nullptr;509510List<struct zwp_tablet_tool_v2 *> tablet_tools;511512// IME.513struct zwp_text_input_v3 *wp_text_input = nullptr;514DisplayServer::WindowID ime_window_id = DisplayServer::INVALID_WINDOW_ID;515bool ime_enabled = false;516bool ime_active = false;517String ime_text;518String ime_text_commit;519Vector2i ime_cursor;520Rect2i ime_rect;521};522523struct CustomCursor {524struct wl_buffer *wl_buffer = nullptr;525uint32_t *buffer_data = nullptr;526uint32_t buffer_data_size = 0;527528Point2i hotspot;529};530531private:532struct ThreadData {533SafeFlag thread_done;534Mutex mutex;535536struct wl_display *wl_display = nullptr;537};538539// FIXME: Is this the right thing to do?540inline static const char *proxy_tag = "godot";541542Thread events_thread;543ThreadData thread_data;544545HashMap<DisplayServer::WindowID, WindowState> windows;546547List<Ref<Message>> messages;548549xdg_toplevel_icon_v1 *xdg_icon = nullptr;550wl_buffer *icon_buffer = nullptr;551552String cursor_theme_name;553int unscaled_cursor_size = 24;554555// NOTE: Regarding screen scale handling, the cursor cache is currently556// "static", by which I mean that we try to change it as little as possible and557// thus will be as big as the largest screen. This is mainly due to the fact558// that doing it dynamically doesn't look like it's worth it to me currently,559// especially as usually screen scales don't change continuously.560int cursor_scale = 1;561562// Use cursor-shape-v1 protocol if the compositor supports it.563wp_cursor_shape_device_v1_shape standard_cursors[DisplayServer::CURSOR_MAX] = {564wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_DEFAULT, //CURSOR_ARROW565wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_TEXT, //CURSOR_IBEAM566wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_POINTER, //CURSOR_POINTING_HAND567wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_CROSSHAIR, //CURSOR_CROSS568wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_WAIT, //CURSOR_WAIT569wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_PROGRESS, //CURSOR_BUSY570wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_GRAB, //CURSOR_DRAG571wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_GRABBING, //CURSOR_CAN_DROP572wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NO_DROP, //CURSOR_FORBIDDEN573wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NS_RESIZE, //CURSOR_VSIZE574wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_EW_RESIZE, //CURSOR_HSIZE575wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NESW_RESIZE, //CURSOR_BDIAGSIZE576wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NWSE_RESIZE, //CURSOR_FDIAGSIZE577wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_MOVE, //CURSOR_MOVE578wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_ROW_RESIZE, //CURSOR_VSPLIT579wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_COL_RESIZE, //CURSOR_HSPLIT580wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_HELP, //CURSOR_HELP581};582583// Fallback to reading $XCURSOR and system themes if the compositor does not.584struct wl_cursor_theme *wl_cursor_theme = nullptr;585struct wl_cursor *wl_cursors[DisplayServer::CURSOR_MAX] = {};586587// User-defined cursor overrides. Take precedence over standard and wl cursors.588HashMap<DisplayServer::CursorShape, CustomCursor> custom_cursors;589590DisplayServer::CursorShape cursor_shape = DisplayServer::CURSOR_ARROW;591bool cursor_visible = true;592593PointerConstraint pointer_constraint = PointerConstraint::NONE;594595struct wl_display *wl_display = nullptr;596struct wl_registry *wl_registry = nullptr;597598struct wl_seat *wl_seat_current = nullptr;599600bool frame = true;601602RegistryState registry;603604bool initialized = false;605606#ifdef LIBDECOR_ENABLED607struct libdecor *libdecor_context = nullptr;608#endif // LIBDECOR_ENABLED609610// Main polling method.611static void _poll_events_thread(void *p_data);612613// Core Wayland event handlers.614static void _wl_registry_on_global(void *data, struct wl_registry *wl_registry, uint32_t name, const char *interface, uint32_t version);615static void _wl_registry_on_global_remove(void *data, struct wl_registry *wl_registry, uint32_t name);616617static void _wl_surface_on_enter(void *data, struct wl_surface *wl_surface, struct wl_output *wl_output);618static void _wl_surface_on_leave(void *data, struct wl_surface *wl_surface, struct wl_output *wl_output);619static void _wl_surface_on_preferred_buffer_scale(void *data, struct wl_surface *wl_surface, int32_t factor);620static void _wl_surface_on_preferred_buffer_transform(void *data, struct wl_surface *wl_surface, uint32_t transform);621622static void _frame_wl_callback_on_done(void *data, struct wl_callback *wl_callback, uint32_t callback_data);623624static void _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);625static void _wl_output_on_mode(void *data, struct wl_output *wl_output, uint32_t flags, int32_t width, int32_t height, int32_t refresh);626static void _wl_output_on_done(void *data, struct wl_output *wl_output);627static void _wl_output_on_scale(void *data, struct wl_output *wl_output, int32_t factor);628static void _wl_output_on_name(void *data, struct wl_output *wl_output, const char *name);629static void _wl_output_on_description(void *data, struct wl_output *wl_output, const char *description);630631static void _wl_seat_on_capabilities(void *data, struct wl_seat *wl_seat, uint32_t capabilities);632static void _wl_seat_on_name(void *data, struct wl_seat *wl_seat, const char *name);633634static void _cursor_frame_callback_on_done(void *data, struct wl_callback *wl_callback, uint32_t time_ms);635636static void _wl_pointer_on_enter(void *data, struct wl_pointer *wl_pointer, uint32_t serial, struct wl_surface *surface, wl_fixed_t surface_x, wl_fixed_t surface_y);637static void _wl_pointer_on_leave(void *data, struct wl_pointer *wl_pointer, uint32_t serial, struct wl_surface *surface);638static void _wl_pointer_on_motion(void *data, struct wl_pointer *wl_pointer, uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y);639static void _wl_pointer_on_button(void *data, struct wl_pointer *wl_pointer, uint32_t serial, uint32_t time, uint32_t button, uint32_t state);640static void _wl_pointer_on_axis(void *data, struct wl_pointer *wl_pointer, uint32_t time, uint32_t axis, wl_fixed_t value);641static void _wl_pointer_on_frame(void *data, struct wl_pointer *wl_pointer);642static void _wl_pointer_on_axis_source(void *data, struct wl_pointer *wl_pointer, uint32_t axis_source);643static void _wl_pointer_on_axis_stop(void *data, struct wl_pointer *wl_pointer, uint32_t time, uint32_t axis);644static void _wl_pointer_on_axis_discrete(void *data, struct wl_pointer *wl_pointer, uint32_t axis, int32_t discrete);645static void _wl_pointer_on_axis_value120(void *data, struct wl_pointer *wl_pointer, uint32_t axis, int32_t value120);646static void _wl_pointer_on_axis_relative_direction(void *data, struct wl_pointer *wl_pointer, uint32_t axis, uint32_t direction);647648static void _wl_keyboard_on_keymap(void *data, struct wl_keyboard *wl_keyboard, uint32_t format, int32_t fd, uint32_t size);649static void _wl_keyboard_on_enter(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, struct wl_surface *surface, struct wl_array *keys);650static void _wl_keyboard_on_leave(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, struct wl_surface *surface);651static void _wl_keyboard_on_key(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t state);652static void _wl_keyboard_on_modifiers(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group);653static void _wl_keyboard_on_repeat_info(void *data, struct wl_keyboard *wl_keyboard, int32_t rate, int32_t delay);654655static void _wl_data_device_on_data_offer(void *data, struct wl_data_device *wl_data_device, struct wl_data_offer *id);656static void _wl_data_device_on_enter(void *data, struct wl_data_device *wl_data_device, uint32_t serial, struct wl_surface *surface, wl_fixed_t x, wl_fixed_t y, struct wl_data_offer *id);657static void _wl_data_device_on_leave(void *data, struct wl_data_device *wl_data_device);658static void _wl_data_device_on_motion(void *data, struct wl_data_device *wl_data_device, uint32_t time, wl_fixed_t x, wl_fixed_t y);659static void _wl_data_device_on_drop(void *data, struct wl_data_device *wl_data_device);660static void _wl_data_device_on_selection(void *data, struct wl_data_device *wl_data_device, struct wl_data_offer *id);661662static void _wl_data_offer_on_offer(void *data, struct wl_data_offer *wl_data_offer, const char *mime_type);663static void _wl_data_offer_on_source_actions(void *data, struct wl_data_offer *wl_data_offer, uint32_t source_actions);664static void _wl_data_offer_on_action(void *data, struct wl_data_offer *wl_data_offer, uint32_t dnd_action);665666static void _wl_data_source_on_target(void *data, struct wl_data_source *wl_data_source, const char *mime_type);667static void _wl_data_source_on_send(void *data, struct wl_data_source *wl_data_source, const char *mime_type, int32_t fd);668static void _wl_data_source_on_cancelled(void *data, struct wl_data_source *wl_data_source);669static void _wl_data_source_on_dnd_drop_performed(void *data, struct wl_data_source *wl_data_source);670static void _wl_data_source_on_dnd_finished(void *data, struct wl_data_source *wl_data_source);671static void _wl_data_source_on_action(void *data, struct wl_data_source *wl_data_source, uint32_t dnd_action);672673// xdg-shell event handlers.674static void _xdg_wm_base_on_ping(void *data, struct xdg_wm_base *xdg_wm_base, uint32_t serial);675676static void _xdg_surface_on_configure(void *data, struct xdg_surface *xdg_surface, uint32_t serial);677678static void _xdg_toplevel_on_configure(void *data, struct xdg_toplevel *xdg_toplevel, int32_t width, int32_t height, struct wl_array *states);679static void _xdg_toplevel_on_close(void *data, struct xdg_toplevel *xdg_toplevel);680static void _xdg_toplevel_on_configure_bounds(void *data, struct xdg_toplevel *xdg_toplevel, int32_t width, int32_t height);681static void _xdg_toplevel_on_wm_capabilities(void *data, struct xdg_toplevel *xdg_toplevel, struct wl_array *capabilities);682683static void _xdg_popup_on_configure(void *data, struct xdg_popup *xdg_popup, int32_t x, int32_t y, int32_t width, int32_t height);684static void _xdg_popup_on_popup_done(void *data, struct xdg_popup *xdg_popup);685static void _xdg_popup_on_repositioned(void *data, struct xdg_popup *xdg_popup, uint32_t token);686687// wayland-protocols event handlers.688static void _wp_fractional_scale_on_preferred_scale(void *data, struct wp_fractional_scale_v1 *wp_fractional_scale_v1, uint32_t scale);689690static void _wp_relative_pointer_on_relative_motion(void *data, struct zwp_relative_pointer_v1 *wp_relative_pointer_v1, uint32_t uptime_hi, uint32_t uptime_lo, wl_fixed_t dx, wl_fixed_t dy, wl_fixed_t dx_unaccel, wl_fixed_t dy_unaccel);691692static void _wp_pointer_gesture_pinch_on_begin(void *data, struct zwp_pointer_gesture_pinch_v1 *wp_pointer_gesture_pinch_v1, uint32_t serial, uint32_t time, struct wl_surface *surface, uint32_t fingers);693static void _wp_pointer_gesture_pinch_on_update(void *data, struct zwp_pointer_gesture_pinch_v1 *wp_pointer_gesture_pinch_v1, uint32_t time, wl_fixed_t dx, wl_fixed_t dy, wl_fixed_t scale, wl_fixed_t rotation);694static void _wp_pointer_gesture_pinch_on_end(void *data, struct zwp_pointer_gesture_pinch_v1 *zp_pointer_gesture_pinch_v1, uint32_t serial, uint32_t time, int32_t cancelled);695696static void _wp_primary_selection_device_on_data_offer(void *data, struct zwp_primary_selection_device_v1 *wp_primary_selection_device_v1, struct zwp_primary_selection_offer_v1 *offer);697static void _wp_primary_selection_device_on_selection(void *data, struct zwp_primary_selection_device_v1 *wp_primary_selection_device_v1, struct zwp_primary_selection_offer_v1 *id);698699static void _wp_primary_selection_offer_on_offer(void *data, struct zwp_primary_selection_offer_v1 *wp_primary_selection_offer_v1, const char *mime_type);700701static void _wp_primary_selection_source_on_send(void *data, struct zwp_primary_selection_source_v1 *wp_primary_selection_source_v1, const char *mime_type, int32_t fd);702static void _wp_primary_selection_source_on_cancelled(void *data, struct zwp_primary_selection_source_v1 *wp_primary_selection_source_v1);703704static void _wp_tablet_seat_on_tablet_added(void *data, struct zwp_tablet_seat_v2 *wp_tablet_seat_v2, struct zwp_tablet_v2 *id);705static void _wp_tablet_seat_on_tool_added(void *data, struct zwp_tablet_seat_v2 *wp_tablet_seat_v2, struct zwp_tablet_tool_v2 *id);706static void _wp_tablet_seat_on_pad_added(void *data, struct zwp_tablet_seat_v2 *wp_tablet_seat_v2, struct zwp_tablet_pad_v2 *id);707708static void _wp_tablet_tool_on_type(void *data, struct zwp_tablet_tool_v2 *wp_tablet_tool_v2, uint32_t tool_type);709static void _wp_tablet_tool_on_hardware_serial(void *data, struct zwp_tablet_tool_v2 *wp_tablet_tool_v2, uint32_t hardware_serial_hi, uint32_t hardware_serial_lo);710static void _wp_tablet_tool_on_hardware_id_wacom(void *data, struct zwp_tablet_tool_v2 *wp_tablet_tool_v2, uint32_t hardware_id_hi, uint32_t hardware_id_lo);711static void _wp_tablet_tool_on_capability(void *data, struct zwp_tablet_tool_v2 *wp_tablet_tool_v2, uint32_t capability);712static void _wp_tablet_tool_on_done(void *data, struct zwp_tablet_tool_v2 *wp_tablet_tool_v2);713static void _wp_tablet_tool_on_removed(void *data, struct zwp_tablet_tool_v2 *wp_tablet_tool_v2);714static void _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);715static void _wp_tablet_tool_on_proximity_out(void *data, struct zwp_tablet_tool_v2 *wp_tablet_tool_v2);716static void _wp_tablet_tool_on_down(void *data, struct zwp_tablet_tool_v2 *wp_tablet_tool_v2, uint32_t serial);717static void _wp_tablet_tool_on_up(void *data, struct zwp_tablet_tool_v2 *wp_tablet_tool_v2);718static void _wp_tablet_tool_on_motion(void *data, struct zwp_tablet_tool_v2 *wp_tablet_tool_v2, wl_fixed_t x, wl_fixed_t y);719static void _wp_tablet_tool_on_pressure(void *data, struct zwp_tablet_tool_v2 *wp_tablet_tool_v2, uint32_t pressure);720static void _wp_tablet_tool_on_distance(void *data, struct zwp_tablet_tool_v2 *wp_tablet_tool_v2, uint32_t distance);721static void _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);722static void _wp_tablet_tool_on_rotation(void *data, struct zwp_tablet_tool_v2 *wp_tablet_tool_v2, wl_fixed_t degrees);723static void _wp_tablet_tool_on_slider(void *data, struct zwp_tablet_tool_v2 *wp_tablet_tool_v2, int32_t position);724static void _wp_tablet_tool_on_wheel(void *data, struct zwp_tablet_tool_v2 *wp_tablet_tool_v2, wl_fixed_t degrees, int32_t clicks);725static void _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);726static void _wp_tablet_tool_on_frame(void *data, struct zwp_tablet_tool_v2 *wp_tablet_tool_v2, uint32_t time);727728static void _wp_text_input_on_enter(void *data, struct zwp_text_input_v3 *wp_text_input_v3, struct wl_surface *surface);729static void _wp_text_input_on_leave(void *data, struct zwp_text_input_v3 *wp_text_input_v3, struct wl_surface *surface);730static void _wp_text_input_on_preedit_string(void *data, struct zwp_text_input_v3 *wp_text_input_v3, const char *text, int32_t cursor_begin, int32_t cursor_end);731static void _wp_text_input_on_commit_string(void *data, struct zwp_text_input_v3 *wp_text_input_v3, const char *text);732static void _wp_text_input_on_delete_surrounding_text(void *data, struct zwp_text_input_v3 *wp_text_input_v3, uint32_t before_length, uint32_t after_length);733static void _wp_text_input_on_done(void *data, struct zwp_text_input_v3 *wp_text_input_v3, uint32_t serial);734735static void _xdg_toplevel_decoration_on_configure(void *data, struct zxdg_toplevel_decoration_v1 *xdg_toplevel_decoration, uint32_t mode);736737// NOTE: Deprecated.738static void _xdg_exported_v1_on_handle(void *data, zxdg_exported_v1 *exported, const char *handle);739740static void _xdg_exported_v2_on_handle(void *data, zxdg_exported_v2 *exported, const char *handle);741742static void _xdg_activation_token_on_done(void *data, struct xdg_activation_token_v1 *xdg_activation_token, const char *token);743744// Core Wayland event listeners.745static constexpr struct wl_registry_listener wl_registry_listener = {746.global = _wl_registry_on_global,747.global_remove = _wl_registry_on_global_remove,748};749750static constexpr struct wl_surface_listener wl_surface_listener = {751.enter = _wl_surface_on_enter,752.leave = _wl_surface_on_leave,753.preferred_buffer_scale = _wl_surface_on_preferred_buffer_scale,754.preferred_buffer_transform = _wl_surface_on_preferred_buffer_transform,755};756757static constexpr struct wl_callback_listener frame_wl_callback_listener = {758.done = _frame_wl_callback_on_done,759};760761static constexpr struct wl_output_listener wl_output_listener = {762.geometry = _wl_output_on_geometry,763.mode = _wl_output_on_mode,764.done = _wl_output_on_done,765.scale = _wl_output_on_scale,766.name = _wl_output_on_name,767.description = _wl_output_on_description,768};769770static constexpr struct wl_seat_listener wl_seat_listener = {771.capabilities = _wl_seat_on_capabilities,772.name = _wl_seat_on_name,773};774775static constexpr struct wl_callback_listener cursor_frame_callback_listener = {776.done = _cursor_frame_callback_on_done,777};778779static constexpr struct wl_pointer_listener wl_pointer_listener = {780.enter = _wl_pointer_on_enter,781.leave = _wl_pointer_on_leave,782.motion = _wl_pointer_on_motion,783.button = _wl_pointer_on_button,784.axis = _wl_pointer_on_axis,785.frame = _wl_pointer_on_frame,786.axis_source = _wl_pointer_on_axis_source,787.axis_stop = _wl_pointer_on_axis_stop,788.axis_discrete = _wl_pointer_on_axis_discrete,789.axis_value120 = _wl_pointer_on_axis_value120,790.axis_relative_direction = _wl_pointer_on_axis_relative_direction,791};792793static constexpr struct wl_keyboard_listener wl_keyboard_listener = {794.keymap = _wl_keyboard_on_keymap,795.enter = _wl_keyboard_on_enter,796.leave = _wl_keyboard_on_leave,797.key = _wl_keyboard_on_key,798.modifiers = _wl_keyboard_on_modifiers,799.repeat_info = _wl_keyboard_on_repeat_info,800};801802static constexpr struct wl_data_device_listener wl_data_device_listener = {803.data_offer = _wl_data_device_on_data_offer,804.enter = _wl_data_device_on_enter,805.leave = _wl_data_device_on_leave,806.motion = _wl_data_device_on_motion,807.drop = _wl_data_device_on_drop,808.selection = _wl_data_device_on_selection,809};810811static constexpr struct wl_data_offer_listener wl_data_offer_listener = {812.offer = _wl_data_offer_on_offer,813.source_actions = _wl_data_offer_on_source_actions,814.action = _wl_data_offer_on_action,815};816817static constexpr struct wl_data_source_listener wl_data_source_listener = {818.target = _wl_data_source_on_target,819.send = _wl_data_source_on_send,820.cancelled = _wl_data_source_on_cancelled,821.dnd_drop_performed = _wl_data_source_on_dnd_drop_performed,822.dnd_finished = _wl_data_source_on_dnd_finished,823.action = _wl_data_source_on_action,824};825826// xdg-shell event listeners.827static constexpr struct xdg_wm_base_listener xdg_wm_base_listener = {828.ping = _xdg_wm_base_on_ping,829};830831static constexpr struct xdg_surface_listener xdg_surface_listener = {832.configure = _xdg_surface_on_configure,833};834835static constexpr struct xdg_toplevel_listener xdg_toplevel_listener = {836.configure = _xdg_toplevel_on_configure,837.close = _xdg_toplevel_on_close,838.configure_bounds = _xdg_toplevel_on_configure_bounds,839.wm_capabilities = _xdg_toplevel_on_wm_capabilities,840};841842static constexpr struct xdg_popup_listener xdg_popup_listener = {843.configure = _xdg_popup_on_configure,844.popup_done = _xdg_popup_on_popup_done,845.repositioned = _xdg_popup_on_repositioned,846};847848// wayland-protocols event listeners.849static constexpr struct wp_fractional_scale_v1_listener wp_fractional_scale_listener = {850.preferred_scale = _wp_fractional_scale_on_preferred_scale,851};852853static constexpr struct zwp_relative_pointer_v1_listener wp_relative_pointer_listener = {854.relative_motion = _wp_relative_pointer_on_relative_motion,855};856857static constexpr struct zwp_pointer_gesture_pinch_v1_listener wp_pointer_gesture_pinch_listener = {858.begin = _wp_pointer_gesture_pinch_on_begin,859.update = _wp_pointer_gesture_pinch_on_update,860.end = _wp_pointer_gesture_pinch_on_end,861};862863static constexpr struct zwp_primary_selection_device_v1_listener wp_primary_selection_device_listener = {864.data_offer = _wp_primary_selection_device_on_data_offer,865.selection = _wp_primary_selection_device_on_selection,866};867868static constexpr struct zwp_primary_selection_offer_v1_listener wp_primary_selection_offer_listener = {869.offer = _wp_primary_selection_offer_on_offer,870};871872static constexpr struct zwp_primary_selection_source_v1_listener wp_primary_selection_source_listener = {873.send = _wp_primary_selection_source_on_send,874.cancelled = _wp_primary_selection_source_on_cancelled,875};876877static constexpr struct zwp_tablet_seat_v2_listener wp_tablet_seat_listener = {878.tablet_added = _wp_tablet_seat_on_tablet_added,879.tool_added = _wp_tablet_seat_on_tool_added,880.pad_added = _wp_tablet_seat_on_pad_added,881};882883static constexpr struct zwp_tablet_tool_v2_listener wp_tablet_tool_listener = {884.type = _wp_tablet_tool_on_type,885.hardware_serial = _wp_tablet_tool_on_hardware_serial,886.hardware_id_wacom = _wp_tablet_tool_on_hardware_id_wacom,887.capability = _wp_tablet_tool_on_capability,888.done = _wp_tablet_tool_on_done,889.removed = _wp_tablet_tool_on_removed,890.proximity_in = _wp_tablet_tool_on_proximity_in,891.proximity_out = _wp_tablet_tool_on_proximity_out,892.down = _wp_tablet_tool_on_down,893.up = _wp_tablet_tool_on_up,894.motion = _wp_tablet_tool_on_motion,895.pressure = _wp_tablet_tool_on_pressure,896.distance = _wp_tablet_tool_on_distance,897.tilt = _wp_tablet_tool_on_tilt,898.rotation = _wp_tablet_tool_on_rotation,899.slider = _wp_tablet_tool_on_slider,900.wheel = _wp_tablet_tool_on_wheel,901.button = _wp_tablet_tool_on_button,902.frame = _wp_tablet_tool_on_frame,903};904905static constexpr struct zwp_text_input_v3_listener wp_text_input_listener = {906.enter = _wp_text_input_on_enter,907.leave = _wp_text_input_on_leave,908.preedit_string = _wp_text_input_on_preedit_string,909.commit_string = _wp_text_input_on_commit_string,910.delete_surrounding_text = _wp_text_input_on_delete_surrounding_text,911.done = _wp_text_input_on_done,912};913914// NOTE: Deprecated.915static constexpr struct zxdg_exported_v1_listener xdg_exported_v1_listener = {916.handle = _xdg_exported_v1_on_handle,917};918919static constexpr struct zxdg_exported_v2_listener xdg_exported_v2_listener = {920.handle = _xdg_exported_v2_on_handle,921};922923static constexpr struct zxdg_toplevel_decoration_v1_listener xdg_toplevel_decoration_listener = {924.configure = _xdg_toplevel_decoration_on_configure,925};926927static constexpr struct xdg_activation_token_v1_listener xdg_activation_token_listener = {928.done = _xdg_activation_token_on_done,929};930931#ifdef LIBDECOR_ENABLED932// libdecor event handlers.933static void libdecor_on_error(struct libdecor *context, enum libdecor_error error, const char *message);934935static void libdecor_frame_on_configure(struct libdecor_frame *frame, struct libdecor_configuration *configuration, void *user_data);936937static void libdecor_frame_on_close(struct libdecor_frame *frame, void *user_data);938939static void libdecor_frame_on_commit(struct libdecor_frame *frame, void *user_data);940941static void libdecor_frame_on_dismiss_popup(struct libdecor_frame *frame, const char *seat_name, void *user_data);942943// libdecor event listeners.944static constexpr struct libdecor_interface libdecor_interface = {945.error = libdecor_on_error,946.reserved0 = nullptr,947.reserved1 = nullptr,948.reserved2 = nullptr,949.reserved3 = nullptr,950.reserved4 = nullptr,951.reserved5 = nullptr,952.reserved6 = nullptr,953.reserved7 = nullptr,954.reserved8 = nullptr,955.reserved9 = nullptr,956};957958static constexpr struct libdecor_frame_interface libdecor_frame_interface = {959.configure = libdecor_frame_on_configure,960.close = libdecor_frame_on_close,961.commit = libdecor_frame_on_commit,962.dismiss_popup = libdecor_frame_on_dismiss_popup,963.reserved0 = nullptr,964.reserved1 = nullptr,965.reserved2 = nullptr,966.reserved3 = nullptr,967.reserved4 = nullptr,968.reserved5 = nullptr,969.reserved6 = nullptr,970.reserved7 = nullptr,971.reserved8 = nullptr,972.reserved9 = nullptr,973};974#endif // LIBDECOR_ENABLED975976static Vector<uint8_t> _read_fd(int fd);977static int _allocate_shm_file(size_t size);978979static Vector<uint8_t> _wl_data_offer_read(struct wl_display *wl_display, const char *p_mime, struct wl_data_offer *wl_data_offer);980static Vector<uint8_t> _wp_primary_selection_offer_read(struct wl_display *wl_display, const char *p_mime, struct zwp_primary_selection_offer_v1 *wp_primary_selection_offer);981982static void _seat_state_set_current(WaylandThread::SeatState &p_ss);983static Ref<InputEventKey> _seat_state_get_key_event(SeatState *p_ss, xkb_keycode_t p_keycode, bool p_pressed);984static Ref<InputEventKey> _seat_state_get_unstuck_key_event(SeatState *p_ss, xkb_keycode_t p_keycode, bool p_pressed, Key p_key);985986static void _wayland_state_update_cursor();987988void _set_current_seat(struct wl_seat *p_seat);989990bool _load_cursor_theme(int p_cursor_size);991992void _update_scale(int p_scale);993994public:995Mutex &mutex = thread_data.mutex;996997struct wl_display *get_wl_display() const;998999// Core Wayland utilities for integrating with our own data structures.1000static bool wl_proxy_is_godot(struct wl_proxy *p_proxy);1001static void wl_proxy_tag_godot(struct wl_proxy *p_proxy);10021003static WindowState *wl_surface_get_window_state(struct wl_surface *p_surface);1004static ScreenState *wl_output_get_screen_state(struct wl_output *p_output);1005static SeatState *wl_seat_get_seat_state(struct wl_seat *p_seat);1006static TabletToolState *wp_tablet_tool_get_state(struct zwp_tablet_tool_v2 *p_tool);1007static OfferState *wl_data_offer_get_offer_state(struct wl_data_offer *p_offer);10081009static OfferState *wp_primary_selection_offer_get_offer_state(struct zwp_primary_selection_offer_v1 *p_offer);10101011void seat_state_unlock_pointer(SeatState *p_ss);1012void seat_state_lock_pointer(SeatState *p_ss);1013void seat_state_set_hint(SeatState *p_ss, int p_x, int p_y);1014void seat_state_confine_pointer(SeatState *p_ss);10151016static void seat_state_update_cursor(SeatState *p_ss);10171018void seat_state_echo_keys(SeatState *p_ss);10191020static int window_state_get_preferred_buffer_scale(WindowState *p_ws);1021static double window_state_get_scale_factor(WindowState *p_ws);1022static void window_state_update_size(WindowState *p_ws, int p_width, int p_height);10231024static Vector2i scale_vector2i(const Vector2i &p_vector, double p_amount);10251026void push_message(Ref<Message> message);1027bool has_message();1028Ref<Message> pop_message();10291030void beep() const;10311032void set_icon(const Ref<Image> &p_icon);10331034void window_create(DisplayServer::WindowID p_window_id, int p_width, int p_height);1035void window_create_popup(DisplayServer::WindowID p_window_id, DisplayServer::WindowID p_parent_id, Rect2i p_rect);1036void window_destroy(DisplayServer::WindowID p_window_Id);10371038void window_set_parent(DisplayServer::WindowID p_window_id, DisplayServer::WindowID p_parent_id);10391040struct wl_surface *window_get_wl_surface(DisplayServer::WindowID p_window_id) const;1041WindowState *window_get_state(DisplayServer::WindowID p_window_id);10421043void window_start_resize(DisplayServer::WindowResizeEdge p_edge, DisplayServer::WindowID p_window);10441045void window_set_max_size(DisplayServer::WindowID p_window_id, const Size2i &p_size);1046void window_set_min_size(DisplayServer::WindowID p_window_id, const Size2i &p_size);10471048bool window_can_set_mode(DisplayServer::WindowID p_window_id, DisplayServer::WindowMode p_window_mode) const;1049void window_try_set_mode(DisplayServer::WindowID p_window_id, DisplayServer::WindowMode p_window_mode);1050DisplayServer::WindowMode window_get_mode(DisplayServer::WindowID p_window_id) const;10511052void window_set_borderless(DisplayServer::WindowID p_window_id, bool p_borderless);1053void window_set_title(DisplayServer::WindowID p_window_id, const String &p_title);1054void window_set_app_id(DisplayServer::WindowID p_window_id, const String &p_app_id);10551056bool window_is_focused(DisplayServer::WindowID p_window_id);10571058// Optional - requires xdg_activation_v11059void window_request_attention(DisplayServer::WindowID p_window_id);10601061void window_start_drag(DisplayServer::WindowID p_window_id);10621063// Optional - require idle_inhibit_unstable_v11064void window_set_idle_inhibition(DisplayServer::WindowID p_window_id, bool p_enable);1065bool window_get_idle_inhibition(DisplayServer::WindowID p_window_id) const;10661067ScreenData screen_get_data(int p_screen) const;1068int get_screen_count() const;10691070void pointer_set_constraint(PointerConstraint p_constraint);1071void pointer_set_hint(const Point2i &p_hint);1072PointerConstraint pointer_get_constraint() const;1073DisplayServer::WindowID pointer_get_pointed_window_id() const;1074DisplayServer::WindowID pointer_get_last_pointed_window_id() const;1075BitField<MouseButtonMask> pointer_get_button_mask() const;10761077void cursor_set_visible(bool p_visible);1078void cursor_set_shape(DisplayServer::CursorShape p_cursor_shape);10791080void cursor_set_custom_shape(DisplayServer::CursorShape p_cursor_shape);1081void cursor_shape_set_custom_image(DisplayServer::CursorShape p_cursor_shape, Ref<Image> p_image, const Point2i &p_hotspot);1082void cursor_shape_clear_custom_image(DisplayServer::CursorShape p_cursor_shape);10831084void window_set_ime_active(const bool p_active, DisplayServer::WindowID p_window_id);1085void window_set_ime_position(const Point2i &p_pos, DisplayServer::WindowID p_window_id);10861087int keyboard_get_layout_count() const;1088int keyboard_get_current_layout_index() const;1089void keyboard_set_current_layout_index(int p_index);1090String keyboard_get_layout_name(int p_index) const;10911092Key keyboard_get_key_from_physical(Key p_key) const;10931094void keyboard_echo_keys();10951096bool selection_has_mime(const String &p_mime) const;1097Vector<uint8_t> selection_get_mime(const String &p_mime) const;10981099void selection_set_text(const String &p_text);11001101// Optional primary support - requires wp_primary_selection_unstable_v11102bool primary_has_mime(const String &p_mime) const;1103Vector<uint8_t> primary_get_mime(const String &p_mime) const;11041105void primary_set_text(const String &p_text);11061107void commit_surfaces();11081109void set_frame();1110bool get_reset_frame();1111bool wait_frame_suspend_ms(int p_timeout);1112bool is_fifo_available() const;11131114uint64_t window_get_last_frame_time(DisplayServer::WindowID p_window_id) const;1115bool window_is_suspended(DisplayServer::WindowID p_window_id) const;1116bool is_suspended() const;11171118Error init();1119void destroy();1120};11211122#endif // WAYLAND_ENABLED112311241125