wayland_thread.h 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930
  1. /**************************************************************************/
  2. /* wayland_thread.h */
  3. /**************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /**************************************************************************/
  8. /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
  9. /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
  10. /* */
  11. /* Permission is hereby granted, free of charge, to any person obtaining */
  12. /* a copy of this software and associated documentation files (the */
  13. /* "Software"), to deal in the Software without restriction, including */
  14. /* without limitation the rights to use, copy, modify, merge, publish, */
  15. /* distribute, sublicense, and/or sell copies of the Software, and to */
  16. /* permit persons to whom the Software is furnished to do so, subject to */
  17. /* the following conditions: */
  18. /* */
  19. /* The above copyright notice and this permission notice shall be */
  20. /* included in all copies or substantial portions of the Software. */
  21. /* */
  22. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  23. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  24. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
  25. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  26. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  27. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  28. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  29. /**************************************************************************/
  30. #ifndef WAYLAND_THREAD_H
  31. #define WAYLAND_THREAD_H
  32. #ifdef WAYLAND_ENABLED
  33. #include "key_mapping_xkb.h"
  34. #ifdef SOWRAP_ENABLED
  35. #include "wayland/dynwrappers/wayland-client-core-so_wrap.h"
  36. #include "wayland/dynwrappers/wayland-cursor-so_wrap.h"
  37. #include "wayland/dynwrappers/wayland-egl-core-so_wrap.h"
  38. #include "xkbcommon-so_wrap.h"
  39. #else
  40. #include <wayland-client-core.h>
  41. #include <wayland-cursor.h>
  42. #include <xkbcommon/xkbcommon.h>
  43. #endif // SOWRAP_ENABLED
  44. // These must go after the Wayland client include to work properly.
  45. #include "wayland/protocol/idle_inhibit.gen.h"
  46. #include "wayland/protocol/primary_selection.gen.h"
  47. // These three protocol headers name wl_pointer method arguments as `pointer`,
  48. // which is the same name as X11's pointer typedef. This trips some very
  49. // annoying shadowing warnings. A `#define` works around this issue.
  50. #define pointer wl_pointer
  51. #include "wayland/protocol/pointer_constraints.gen.h"
  52. #include "wayland/protocol/pointer_gestures.gen.h"
  53. #include "wayland/protocol/relative_pointer.gen.h"
  54. #undef pointer
  55. #include "wayland/protocol/fractional_scale.gen.h"
  56. #include "wayland/protocol/tablet.gen.h"
  57. #include "wayland/protocol/viewporter.gen.h"
  58. #include "wayland/protocol/wayland.gen.h"
  59. #include "wayland/protocol/xdg_activation.gen.h"
  60. #include "wayland/protocol/xdg_decoration.gen.h"
  61. #include "wayland/protocol/xdg_shell.gen.h"
  62. #ifdef LIBDECOR_ENABLED
  63. #ifdef SOWRAP_ENABLED
  64. #include "dynwrappers/libdecor-so_wrap.h"
  65. #else
  66. #include <libdecor-0/libdecor.h>
  67. #endif // SOWRAP_ENABLED
  68. #endif // LIBDECOR_ENABLED
  69. #include "core/os/thread.h"
  70. #include "servers/display_server.h"
  71. class WaylandThread {
  72. public:
  73. // Messages used for exchanging information between Godot's and Wayland's thread.
  74. class Message : public RefCounted {
  75. public:
  76. Message() {}
  77. virtual ~Message() = default;
  78. };
  79. // Message data for window rect changes.
  80. class WindowRectMessage : public Message {
  81. public:
  82. // NOTE: This is in "scaled" terms. For example, if there's a 1920x1080 rect
  83. // with a scale factor of 2, the actual value of `rect` will be 3840x2160.
  84. Rect2i rect;
  85. };
  86. class WindowEventMessage : public Message {
  87. public:
  88. DisplayServer::WindowEvent event;
  89. };
  90. class InputEventMessage : public Message {
  91. public:
  92. Ref<InputEvent> event;
  93. };
  94. class DropFilesEventMessage : public Message {
  95. public:
  96. Vector<String> files;
  97. };
  98. struct RegistryState {
  99. WaylandThread *wayland_thread;
  100. // Core Wayland globals.
  101. struct wl_shm *wl_shm = nullptr;
  102. uint32_t wl_shm_name = 0;
  103. struct wl_compositor *wl_compositor = nullptr;
  104. uint32_t wl_compositor_name = 0;
  105. struct wl_subcompositor *wl_subcompositor = nullptr;
  106. uint32_t wl_subcompositor_name = 0;
  107. struct wl_data_device_manager *wl_data_device_manager = nullptr;
  108. uint32_t wl_data_device_manager_name = 0;
  109. List<struct wl_output *> wl_outputs;
  110. List<struct wl_seat *> wl_seats;
  111. // xdg-shell globals.
  112. struct xdg_wm_base *xdg_wm_base = nullptr;
  113. uint32_t xdg_wm_base_name = 0;
  114. // wayland-protocols globals.
  115. struct wp_viewporter *wp_viewporter = nullptr;
  116. uint32_t wp_viewporter_name = 0;
  117. struct wp_fractional_scale_manager_v1 *wp_fractional_scale_manager = nullptr;
  118. uint32_t wp_fractional_scale_manager_name = 0;
  119. struct zxdg_decoration_manager_v1 *xdg_decoration_manager = nullptr;
  120. uint32_t xdg_decoration_manager_name = 0;
  121. struct xdg_activation_v1 *xdg_activation = nullptr;
  122. uint32_t xdg_activation_name = 0;
  123. struct zwp_primary_selection_device_manager_v1 *wp_primary_selection_device_manager = nullptr;
  124. uint32_t wp_primary_selection_device_manager_name = 0;
  125. struct zwp_relative_pointer_manager_v1 *wp_relative_pointer_manager = nullptr;
  126. uint32_t wp_relative_pointer_manager_name = 0;
  127. struct zwp_pointer_constraints_v1 *wp_pointer_constraints = nullptr;
  128. uint32_t wp_pointer_constraints_name = 0;
  129. struct zwp_pointer_gestures_v1 *wp_pointer_gestures = nullptr;
  130. uint32_t wp_pointer_gestures_name = 0;
  131. struct zwp_idle_inhibit_manager_v1 *wp_idle_inhibit_manager = nullptr;
  132. uint32_t wp_idle_inhibit_manager_name = 0;
  133. struct zwp_tablet_manager_v2 *wp_tablet_manager = nullptr;
  134. uint32_t wp_tablet_manager_name = 0;
  135. };
  136. // General Wayland-specific states. Shouldn't be accessed directly.
  137. // TODO: Make private?
  138. struct WindowState {
  139. DisplayServer::WindowID id;
  140. Rect2i rect;
  141. DisplayServer::WindowMode mode = DisplayServer::WINDOW_MODE_WINDOWED;
  142. // These are true by default as it isn't guaranteed that we'll find an
  143. // xdg-shell implementation with wm_capabilities available. If and once we
  144. // receive a wm_capabilities event these will get reset and updated with
  145. // whatever the compositor says.
  146. bool can_minimize = false;
  147. bool can_maximize = false;
  148. bool can_fullscreen = false;
  149. HashSet<struct wl_output *> wl_outputs;
  150. // NOTE: If for whatever reason this callback is destroyed _while_ the event
  151. // thread is still running, it might be a good idea to set its user data to
  152. // `nullptr`. From some initial testing of mine, it looks like it might still
  153. // be called even after being destroyed, pointing to probably invalid window
  154. // data by then and segfaulting hard.
  155. struct wl_callback *frame_callback = nullptr;
  156. struct wl_surface *wl_surface = nullptr;
  157. struct xdg_surface *xdg_surface = nullptr;
  158. struct xdg_toplevel *xdg_toplevel = nullptr;
  159. struct wp_viewport *wp_viewport = nullptr;
  160. struct wp_fractional_scale_v1 *wp_fractional_scale = nullptr;
  161. // Currently applied buffer scale.
  162. int buffer_scale = 1;
  163. // Buffer scale must be applied right before rendering but _after_ committing
  164. // everything else or otherwise we might have an inconsistent state (e.g.
  165. // double scale and odd resolution). This flag assists with that; when set,
  166. // on the next frame, we'll commit whatever is set in `buffer_scale`.
  167. bool buffer_scale_changed = false;
  168. // NOTE: The preferred buffer scale is currently only dynamically calculated.
  169. // It can be accessed by calling `window_state_get_preferred_buffer_scale`.
  170. // Override used by the fractional scale add-on object. If less or equal to 0
  171. // (default) then the normal output-based scale is used instead.
  172. double fractional_scale = 0;
  173. // What the compositor is recommending us.
  174. double preferred_fractional_scale = 0;
  175. struct zxdg_toplevel_decoration_v1 *xdg_toplevel_decoration = nullptr;
  176. struct zwp_idle_inhibitor_v1 *wp_idle_inhibitor = nullptr;
  177. #ifdef LIBDECOR_ENABLED
  178. // If this is null the xdg_* variables must be set and vice-versa. This way we
  179. // can handle this mess gracefully enough to hopefully being able of getting
  180. // rid of this cleanly once we have our own CSDs.
  181. struct libdecor_frame *libdecor_frame = nullptr;
  182. struct libdecor_configuration *pending_libdecor_configuration = nullptr;
  183. #endif
  184. RegistryState *registry;
  185. WaylandThread *wayland_thread;
  186. };
  187. // "High level" Godot-side screen data.
  188. struct ScreenData {
  189. // Geometry data.
  190. Point2i position;
  191. String make;
  192. String model;
  193. Size2i size;
  194. Size2i physical_size;
  195. float refresh_rate = -1;
  196. int scale = 1;
  197. };
  198. struct ScreenState {
  199. uint32_t wl_output_name = 0;
  200. ScreenData pending_data;
  201. ScreenData data;
  202. WaylandThread *wayland_thread;
  203. };
  204. enum class Gesture {
  205. NONE,
  206. MAGNIFY,
  207. };
  208. enum class PointerConstraint {
  209. NONE,
  210. LOCKED,
  211. CONFINED,
  212. };
  213. struct PointerData {
  214. Point2i position;
  215. uint32_t motion_time = 0;
  216. // Relative motion has its own optional event and so needs its own time.
  217. Vector2 relative_motion;
  218. uint32_t relative_motion_time = 0;
  219. BitField<MouseButtonMask> pressed_button_mask;
  220. MouseButton last_button_pressed = MouseButton::NONE;
  221. Point2i last_pressed_position;
  222. // This is needed to check for a new double click every time.
  223. bool double_click_begun = false;
  224. uint32_t button_time = 0;
  225. uint32_t button_serial = 0;
  226. uint32_t scroll_type = WL_POINTER_AXIS_SOURCE_WHEEL;
  227. // The amount "scrolled" in pixels, in each direction.
  228. Vector2 scroll_vector;
  229. // The amount of scroll "clicks" in each direction.
  230. Vector2i discrete_scroll_vector;
  231. uint32_t pinch_scale = 1;
  232. };
  233. struct TabletToolData {
  234. Point2i position;
  235. Vector2i tilt;
  236. uint32_t pressure = 0;
  237. BitField<MouseButtonMask> pressed_button_mask;
  238. MouseButton last_button_pressed = MouseButton::NONE;
  239. Point2i last_pressed_position;
  240. bool double_click_begun = false;
  241. // Note: the protocol doesn't have it (I guess that this isn't really meant to
  242. // be used as a mouse...), but we'll hack one in with the current ticks.
  243. uint64_t button_time = 0;
  244. bool is_eraser = false;
  245. bool in_proximity = false;
  246. bool touching = false;
  247. };
  248. struct OfferState {
  249. HashSet<String> mime_types;
  250. };
  251. struct SeatState {
  252. RegistryState *registry = nullptr;
  253. WaylandThread *wayland_thread = nullptr;
  254. struct wl_seat *wl_seat = nullptr;
  255. uint32_t wl_seat_name = 0;
  256. // Pointer.
  257. struct wl_pointer *wl_pointer = nullptr;
  258. uint32_t pointer_enter_serial = 0;
  259. struct wl_surface *pointed_surface = nullptr;
  260. struct wl_surface *last_pointed_surface = nullptr;
  261. struct zwp_relative_pointer_v1 *wp_relative_pointer = nullptr;
  262. struct zwp_locked_pointer_v1 *wp_locked_pointer = nullptr;
  263. struct zwp_confined_pointer_v1 *wp_confined_pointer = nullptr;
  264. struct zwp_pointer_gesture_pinch_v1 *wp_pointer_gesture_pinch = nullptr;
  265. // NOTE: According to the wp_pointer_gestures protocol specification, there
  266. // can be only one active gesture at a time.
  267. Gesture active_gesture = Gesture::NONE;
  268. // Used for delta calculations.
  269. // NOTE: The wp_pointer_gestures protocol keeps track of the total scale of
  270. // the pinch gesture, while godot instead wants its delta.
  271. wl_fixed_t old_pinch_scale = 0;
  272. struct wl_surface *cursor_surface = nullptr;
  273. struct wl_callback *cursor_frame_callback = nullptr;
  274. uint32_t cursor_time_ms = 0;
  275. // This variable is needed to buffer all pointer changes until a
  276. // wl_pointer.frame event, as per Wayland's specification. Everything is
  277. // first set in `data_buffer` and then `data` is set with its contents on
  278. // an input frame event. All methods should generally read from
  279. // `pointer_data` and write to `data_buffer`.
  280. PointerData pointer_data_buffer;
  281. PointerData pointer_data;
  282. // Keyboard.
  283. struct wl_keyboard *wl_keyboard = nullptr;
  284. struct xkb_context *xkb_context = nullptr;
  285. struct xkb_keymap *xkb_keymap = nullptr;
  286. struct xkb_state *xkb_state = nullptr;
  287. const char *keymap_buffer = nullptr;
  288. uint32_t keymap_buffer_size = 0;
  289. xkb_layout_index_t current_layout_index = 0;
  290. int32_t repeat_key_delay_msec = 0;
  291. int32_t repeat_start_delay_msec = 0;
  292. xkb_keycode_t repeating_keycode = XKB_KEYCODE_INVALID;
  293. uint64_t last_repeat_start_msec = 0;
  294. uint64_t last_repeat_msec = 0;
  295. bool shift_pressed = false;
  296. bool ctrl_pressed = false;
  297. bool alt_pressed = false;
  298. bool meta_pressed = false;
  299. uint32_t last_key_pressed_serial = 0;
  300. struct wl_data_device *wl_data_device = nullptr;
  301. // Drag and drop.
  302. struct wl_data_offer *wl_data_offer_dnd = nullptr;
  303. uint32_t dnd_enter_serial = 0;
  304. // Clipboard.
  305. struct wl_data_source *wl_data_source_selection = nullptr;
  306. Vector<uint8_t> selection_data;
  307. struct wl_data_offer *wl_data_offer_selection = nullptr;
  308. // Primary selection.
  309. struct zwp_primary_selection_device_v1 *wp_primary_selection_device = nullptr;
  310. struct zwp_primary_selection_source_v1 *wp_primary_selection_source = nullptr;
  311. Vector<uint8_t> primary_data;
  312. struct zwp_primary_selection_offer_v1 *wp_primary_selection_offer = nullptr;
  313. // Tablet.
  314. struct zwp_tablet_seat_v2 *wp_tablet_seat = nullptr;
  315. List<struct zwp_tablet_tool_v2 *> tablet_tools;
  316. TabletToolData tablet_tool_data_buffer;
  317. TabletToolData tablet_tool_data;
  318. };
  319. struct CustomCursor {
  320. struct wl_buffer *wl_buffer = nullptr;
  321. uint32_t *buffer_data = nullptr;
  322. uint32_t buffer_data_size = 0;
  323. RID rid;
  324. Point2i hotspot;
  325. };
  326. private:
  327. struct ThreadData {
  328. SafeFlag thread_done;
  329. Mutex mutex;
  330. struct wl_display *wl_display = nullptr;
  331. };
  332. // FIXME: Is this the right thing to do?
  333. inline static const char *proxy_tag = "godot";
  334. Thread events_thread;
  335. ThreadData thread_data;
  336. WindowState main_window;
  337. List<Ref<Message>> messages;
  338. String cursor_theme_name;
  339. int unscaled_cursor_size = 24;
  340. // NOTE: Regarding screen scale handling, the cursor cache is currently
  341. // "static", by which I mean that we try to change it as little as possible and
  342. // thus will be as big as the largest screen. This is mainly due to the fact
  343. // that doing it dynamically doesn't look like it's worth it to me currently,
  344. // especially as usually screen scales don't change continuously.
  345. int cursor_scale = 1;
  346. struct wl_cursor_theme *wl_cursor_theme = nullptr;
  347. struct wl_cursor *wl_cursors[DisplayServer::CURSOR_MAX] = {};
  348. HashMap<DisplayServer::CursorShape, CustomCursor> custom_cursors;
  349. struct wl_cursor *current_wl_cursor = nullptr;
  350. struct CustomCursor *current_custom_cursor = nullptr;
  351. DisplayServer::CursorShape last_cursor_shape = DisplayServer::CURSOR_ARROW;
  352. PointerConstraint pointer_constraint = PointerConstraint::NONE;
  353. struct wl_display *wl_display = nullptr;
  354. struct wl_registry *wl_registry = nullptr;
  355. struct wl_seat *wl_seat_current = nullptr;
  356. bool frame = true;
  357. RegistryState registry;
  358. bool initialized = false;
  359. #ifdef LIBDECOR_ENABLED
  360. struct libdecor *libdecor_context = nullptr;
  361. #endif // LIBDECOR_ENABLED
  362. // Main polling method.
  363. static void _poll_events_thread(void *p_data);
  364. // Core Wayland event handlers.
  365. static void _wl_registry_on_global(void *data, struct wl_registry *wl_registry, uint32_t name, const char *interface, uint32_t version);
  366. static void _wl_registry_on_global_remove(void *data, struct wl_registry *wl_registry, uint32_t name);
  367. static void _wl_surface_on_enter(void *data, struct wl_surface *wl_surface, struct wl_output *wl_output);
  368. static void _wl_surface_on_leave(void *data, struct wl_surface *wl_surface, struct wl_output *wl_output);
  369. static void _frame_wl_callback_on_done(void *data, struct wl_callback *wl_callback, uint32_t callback_data);
  370. static 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);
  371. static void _wl_output_on_mode(void *data, struct wl_output *wl_output, uint32_t flags, int32_t width, int32_t height, int32_t refresh);
  372. static void _wl_output_on_done(void *data, struct wl_output *wl_output);
  373. static void _wl_output_on_scale(void *data, struct wl_output *wl_output, int32_t factor);
  374. static void _wl_output_on_name(void *data, struct wl_output *wl_output, const char *name);
  375. static void _wl_output_on_description(void *data, struct wl_output *wl_output, const char *description);
  376. static void _wl_seat_on_capabilities(void *data, struct wl_seat *wl_seat, uint32_t capabilities);
  377. static void _wl_seat_on_name(void *data, struct wl_seat *wl_seat, const char *name);
  378. static void _cursor_frame_callback_on_done(void *data, struct wl_callback *wl_callback, uint32_t time_ms);
  379. static 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);
  380. static void _wl_pointer_on_leave(void *data, struct wl_pointer *wl_pointer, uint32_t serial, struct wl_surface *surface);
  381. static 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);
  382. static void _wl_pointer_on_button(void *data, struct wl_pointer *wl_pointer, uint32_t serial, uint32_t time, uint32_t button, uint32_t state);
  383. static void _wl_pointer_on_axis(void *data, struct wl_pointer *wl_pointer, uint32_t time, uint32_t axis, wl_fixed_t value);
  384. static void _wl_pointer_on_frame(void *data, struct wl_pointer *wl_pointer);
  385. static void _wl_pointer_on_axis_source(void *data, struct wl_pointer *wl_pointer, uint32_t axis_source);
  386. static void _wl_pointer_on_axis_stop(void *data, struct wl_pointer *wl_pointer, uint32_t time, uint32_t axis);
  387. static void _wl_pointer_on_axis_discrete(void *data, struct wl_pointer *wl_pointer, uint32_t axis, int32_t discrete);
  388. static void _wl_pointer_on_axis_value120(void *data, struct wl_pointer *wl_pointer, uint32_t axis, int32_t value120);
  389. static void _wl_keyboard_on_keymap(void *data, struct wl_keyboard *wl_keyboard, uint32_t format, int32_t fd, uint32_t size);
  390. static void _wl_keyboard_on_enter(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, struct wl_surface *surface, struct wl_array *keys);
  391. static void _wl_keyboard_on_leave(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, struct wl_surface *surface);
  392. static void _wl_keyboard_on_key(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t state);
  393. static 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);
  394. static void _wl_keyboard_on_repeat_info(void *data, struct wl_keyboard *wl_keyboard, int32_t rate, int32_t delay);
  395. static void _wl_data_device_on_data_offer(void *data, struct wl_data_device *wl_data_device, struct wl_data_offer *id);
  396. static 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);
  397. static void _wl_data_device_on_leave(void *data, struct wl_data_device *wl_data_device);
  398. static 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);
  399. static void _wl_data_device_on_drop(void *data, struct wl_data_device *wl_data_device);
  400. static void _wl_data_device_on_selection(void *data, struct wl_data_device *wl_data_device, struct wl_data_offer *id);
  401. static void _wl_data_offer_on_offer(void *data, struct wl_data_offer *wl_data_offer, const char *mime_type);
  402. static void _wl_data_offer_on_source_actions(void *data, struct wl_data_offer *wl_data_offer, uint32_t source_actions);
  403. static void _wl_data_offer_on_action(void *data, struct wl_data_offer *wl_data_offer, uint32_t dnd_action);
  404. static void _wl_data_source_on_target(void *data, struct wl_data_source *wl_data_source, const char *mime_type);
  405. static void _wl_data_source_on_send(void *data, struct wl_data_source *wl_data_source, const char *mime_type, int32_t fd);
  406. static void _wl_data_source_on_cancelled(void *data, struct wl_data_source *wl_data_source);
  407. static void _wl_data_source_on_dnd_drop_performed(void *data, struct wl_data_source *wl_data_source);
  408. static void _wl_data_source_on_dnd_finished(void *data, struct wl_data_source *wl_data_source);
  409. static void _wl_data_source_on_action(void *data, struct wl_data_source *wl_data_source, uint32_t dnd_action);
  410. // xdg-shell event handlers.
  411. static void _xdg_wm_base_on_ping(void *data, struct xdg_wm_base *xdg_wm_base, uint32_t serial);
  412. static void _xdg_surface_on_configure(void *data, struct xdg_surface *xdg_surface, uint32_t serial);
  413. static void _xdg_toplevel_on_configure(void *data, struct xdg_toplevel *xdg_toplevel, int32_t width, int32_t height, struct wl_array *states);
  414. static void _xdg_toplevel_on_close(void *data, struct xdg_toplevel *xdg_toplevel);
  415. static void _xdg_toplevel_on_configure_bounds(void *data, struct xdg_toplevel *xdg_toplevel, int32_t width, int32_t height);
  416. static void _xdg_toplevel_on_wm_capabilities(void *data, struct xdg_toplevel *xdg_toplevel, struct wl_array *capabilities);
  417. // wayland-protocols event handlers.
  418. static void _wp_fractional_scale_on_preferred_scale(void *data, struct wp_fractional_scale_v1 *wp_fractional_scale_v1, uint32_t scale);
  419. static 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);
  420. static void _wp_pointer_gesture_pinch_on_begin(void *data, struct zwp_pointer_gesture_pinch_v1 *zwp_pointer_gesture_pinch_v1, uint32_t serial, uint32_t time, struct wl_surface *surface, uint32_t fingers);
  421. static void _wp_pointer_gesture_pinch_on_update(void *data, struct zwp_pointer_gesture_pinch_v1 *zwp_pointer_gesture_pinch_v1, uint32_t time, wl_fixed_t dx, wl_fixed_t dy, wl_fixed_t scale, wl_fixed_t rotation);
  422. static void _wp_pointer_gesture_pinch_on_end(void *data, struct zwp_pointer_gesture_pinch_v1 *zwp_pointer_gesture_pinch_v1, uint32_t serial, uint32_t time, int32_t cancelled);
  423. static 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);
  424. static 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);
  425. static void _wp_primary_selection_offer_on_offer(void *data, struct zwp_primary_selection_offer_v1 *zwp_primary_selection_offer_v1, const char *mime_type);
  426. static 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);
  427. static void _wp_primary_selection_source_on_cancelled(void *data, struct zwp_primary_selection_source_v1 *wp_primary_selection_source_v1);
  428. static void _wp_tablet_seat_on_tablet_added(void *data, struct zwp_tablet_seat_v2 *zwp_tablet_seat_v2, struct zwp_tablet_v2 *id);
  429. static void _wp_tablet_seat_on_tool_added(void *data, struct zwp_tablet_seat_v2 *zwp_tablet_seat_v2, struct zwp_tablet_tool_v2 *id);
  430. static void _wp_tablet_seat_on_pad_added(void *data, struct zwp_tablet_seat_v2 *zwp_tablet_seat_v2, struct zwp_tablet_pad_v2 *id);
  431. static void _wp_tablet_tool_on_type(void *data, struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2, uint32_t tool_type);
  432. static void _wp_tablet_tool_on_hardware_serial(void *data, struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2, uint32_t hardware_serial_hi, uint32_t hardware_serial_lo);
  433. static void _wp_tablet_tool_on_hardware_id_wacom(void *data, struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2, uint32_t hardware_id_hi, uint32_t hardware_id_lo);
  434. static void _wp_tablet_tool_on_capability(void *data, struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2, uint32_t capability);
  435. static void _wp_tablet_tool_on_done(void *data, struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2);
  436. static void _wp_tablet_tool_on_removed(void *data, struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2);
  437. static void _wp_tablet_tool_on_proximity_in(void *data, struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2, uint32_t serial, struct zwp_tablet_v2 *tablet, struct wl_surface *surface);
  438. static void _wp_tablet_tool_on_proximity_out(void *data, struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2);
  439. static void _wp_tablet_tool_on_down(void *data, struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2, uint32_t serial);
  440. static void _wp_tablet_tool_on_up(void *data, struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2);
  441. static void _wp_tablet_tool_on_motion(void *data, struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2, wl_fixed_t x, wl_fixed_t y);
  442. static void _wp_tablet_tool_on_pressure(void *data, struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2, uint32_t pressure);
  443. static void _wp_tablet_tool_on_distance(void *data, struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2, uint32_t distance);
  444. static void _wp_tablet_tool_on_tilt(void *data, struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2, wl_fixed_t tilt_x, wl_fixed_t tilt_y);
  445. static void _wp_tablet_tool_on_rotation(void *data, struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2, wl_fixed_t degrees);
  446. static void _wp_tablet_tool_on_slider(void *data, struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2, int32_t position);
  447. static void _wp_tablet_tool_on_wheel(void *data, struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2, wl_fixed_t degrees, int32_t clicks);
  448. static void _wp_tablet_tool_on_button(void *data, struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2, uint32_t serial, uint32_t button, uint32_t state);
  449. static void _wp_tablet_tool_on_frame(void *data, struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2, uint32_t time);
  450. static void _xdg_toplevel_decoration_on_configure(void *data, struct zxdg_toplevel_decoration_v1 *xdg_toplevel_decoration, uint32_t mode);
  451. static void _xdg_activation_token_on_done(void *data, struct xdg_activation_token_v1 *xdg_activation_token, const char *token);
  452. // Core Wayland event listeners.
  453. static constexpr struct wl_registry_listener wl_registry_listener = {
  454. .global = _wl_registry_on_global,
  455. .global_remove = _wl_registry_on_global_remove,
  456. };
  457. static constexpr struct wl_surface_listener wl_surface_listener = {
  458. .enter = _wl_surface_on_enter,
  459. .leave = _wl_surface_on_leave,
  460. };
  461. static constexpr struct wl_callback_listener frame_wl_callback_listener {
  462. .done = _frame_wl_callback_on_done,
  463. };
  464. static constexpr struct wl_output_listener wl_output_listener = {
  465. .geometry = _wl_output_on_geometry,
  466. .mode = _wl_output_on_mode,
  467. .done = _wl_output_on_done,
  468. .scale = _wl_output_on_scale,
  469. .name = _wl_output_on_name,
  470. .description = _wl_output_on_description,
  471. };
  472. static constexpr struct wl_seat_listener wl_seat_listener = {
  473. .capabilities = _wl_seat_on_capabilities,
  474. .name = _wl_seat_on_name,
  475. };
  476. static constexpr struct wl_callback_listener cursor_frame_callback_listener {
  477. .done = _cursor_frame_callback_on_done,
  478. };
  479. static constexpr struct wl_pointer_listener wl_pointer_listener = {
  480. .enter = _wl_pointer_on_enter,
  481. .leave = _wl_pointer_on_leave,
  482. .motion = _wl_pointer_on_motion,
  483. .button = _wl_pointer_on_button,
  484. .axis = _wl_pointer_on_axis,
  485. .frame = _wl_pointer_on_frame,
  486. .axis_source = _wl_pointer_on_axis_source,
  487. .axis_stop = _wl_pointer_on_axis_stop,
  488. .axis_discrete = _wl_pointer_on_axis_discrete,
  489. .axis_value120 = _wl_pointer_on_axis_value120,
  490. };
  491. static constexpr struct wl_keyboard_listener wl_keyboard_listener = {
  492. .keymap = _wl_keyboard_on_keymap,
  493. .enter = _wl_keyboard_on_enter,
  494. .leave = _wl_keyboard_on_leave,
  495. .key = _wl_keyboard_on_key,
  496. .modifiers = _wl_keyboard_on_modifiers,
  497. .repeat_info = _wl_keyboard_on_repeat_info,
  498. };
  499. static constexpr struct wl_data_device_listener wl_data_device_listener = {
  500. .data_offer = _wl_data_device_on_data_offer,
  501. .enter = _wl_data_device_on_enter,
  502. .leave = _wl_data_device_on_leave,
  503. .motion = _wl_data_device_on_motion,
  504. .drop = _wl_data_device_on_drop,
  505. .selection = _wl_data_device_on_selection,
  506. };
  507. static constexpr struct wl_data_offer_listener wl_data_offer_listener = {
  508. .offer = _wl_data_offer_on_offer,
  509. .source_actions = _wl_data_offer_on_source_actions,
  510. .action = _wl_data_offer_on_action,
  511. };
  512. static constexpr struct wl_data_source_listener wl_data_source_listener = {
  513. .target = _wl_data_source_on_target,
  514. .send = _wl_data_source_on_send,
  515. .cancelled = _wl_data_source_on_cancelled,
  516. .dnd_drop_performed = _wl_data_source_on_dnd_drop_performed,
  517. .dnd_finished = _wl_data_source_on_dnd_finished,
  518. .action = _wl_data_source_on_action,
  519. };
  520. // xdg-shell event listeners.
  521. static constexpr struct xdg_wm_base_listener xdg_wm_base_listener = {
  522. .ping = _xdg_wm_base_on_ping,
  523. };
  524. static constexpr struct xdg_surface_listener xdg_surface_listener = {
  525. .configure = _xdg_surface_on_configure,
  526. };
  527. static constexpr struct xdg_toplevel_listener xdg_toplevel_listener = {
  528. .configure = _xdg_toplevel_on_configure,
  529. .close = _xdg_toplevel_on_close,
  530. .configure_bounds = _xdg_toplevel_on_configure_bounds,
  531. .wm_capabilities = _xdg_toplevel_on_wm_capabilities,
  532. };
  533. // wayland-protocols event listeners.
  534. static constexpr struct wp_fractional_scale_v1_listener wp_fractional_scale_listener = {
  535. .preferred_scale = _wp_fractional_scale_on_preferred_scale,
  536. };
  537. static constexpr struct zwp_relative_pointer_v1_listener wp_relative_pointer_listener = {
  538. .relative_motion = _wp_relative_pointer_on_relative_motion,
  539. };
  540. static constexpr struct zwp_pointer_gesture_pinch_v1_listener wp_pointer_gesture_pinch_listener = {
  541. .begin = _wp_pointer_gesture_pinch_on_begin,
  542. .update = _wp_pointer_gesture_pinch_on_update,
  543. .end = _wp_pointer_gesture_pinch_on_end,
  544. };
  545. static constexpr struct zwp_primary_selection_device_v1_listener wp_primary_selection_device_listener = {
  546. .data_offer = _wp_primary_selection_device_on_data_offer,
  547. .selection = _wp_primary_selection_device_on_selection,
  548. };
  549. static constexpr struct zwp_primary_selection_offer_v1_listener wp_primary_selection_offer_listener = {
  550. .offer = _wp_primary_selection_offer_on_offer,
  551. };
  552. static constexpr struct zwp_primary_selection_source_v1_listener wp_primary_selection_source_listener = {
  553. .send = _wp_primary_selection_source_on_send,
  554. .cancelled = _wp_primary_selection_source_on_cancelled,
  555. };
  556. static constexpr struct zwp_tablet_seat_v2_listener wp_tablet_seat_listener = {
  557. .tablet_added = _wp_tablet_seat_on_tablet_added,
  558. .tool_added = _wp_tablet_seat_on_tool_added,
  559. .pad_added = _wp_tablet_seat_on_pad_added,
  560. };
  561. static constexpr struct zwp_tablet_tool_v2_listener wp_tablet_tool_listener = {
  562. .type = _wp_tablet_tool_on_type,
  563. .hardware_serial = _wp_tablet_tool_on_hardware_serial,
  564. .hardware_id_wacom = _wp_tablet_tool_on_hardware_id_wacom,
  565. .capability = _wp_tablet_tool_on_capability,
  566. .done = _wp_tablet_tool_on_done,
  567. .removed = _wp_tablet_tool_on_removed,
  568. .proximity_in = _wp_tablet_tool_on_proximity_in,
  569. .proximity_out = _wp_tablet_tool_on_proximity_out,
  570. .down = _wp_tablet_tool_on_down,
  571. .up = _wp_tablet_tool_on_up,
  572. .motion = _wp_tablet_tool_on_motion,
  573. .pressure = _wp_tablet_tool_on_pressure,
  574. .distance = _wp_tablet_tool_on_distance,
  575. .tilt = _wp_tablet_tool_on_tilt,
  576. .rotation = _wp_tablet_tool_on_rotation,
  577. .slider = _wp_tablet_tool_on_slider,
  578. .wheel = _wp_tablet_tool_on_wheel,
  579. .button = _wp_tablet_tool_on_button,
  580. .frame = _wp_tablet_tool_on_frame,
  581. };
  582. static constexpr struct zxdg_toplevel_decoration_v1_listener xdg_toplevel_decoration_listener = {
  583. .configure = _xdg_toplevel_decoration_on_configure,
  584. };
  585. static constexpr struct xdg_activation_token_v1_listener xdg_activation_token_listener = {
  586. .done = _xdg_activation_token_on_done,
  587. };
  588. #ifdef LIBDECOR_ENABLED
  589. // libdecor event handlers.
  590. static void libdecor_on_error(struct libdecor *context, enum libdecor_error error, const char *message);
  591. static void libdecor_frame_on_configure(struct libdecor_frame *frame, struct libdecor_configuration *configuration, void *user_data);
  592. static void libdecor_frame_on_close(struct libdecor_frame *frame, void *user_data);
  593. static void libdecor_frame_on_commit(struct libdecor_frame *frame, void *user_data);
  594. static void libdecor_frame_on_dismiss_popup(struct libdecor_frame *frame, const char *seat_name, void *user_data);
  595. // libdecor event listeners.
  596. static constexpr struct libdecor_interface libdecor_interface = {
  597. .error = libdecor_on_error,
  598. .reserved0 = nullptr,
  599. .reserved1 = nullptr,
  600. .reserved2 = nullptr,
  601. .reserved3 = nullptr,
  602. .reserved4 = nullptr,
  603. .reserved5 = nullptr,
  604. .reserved6 = nullptr,
  605. .reserved7 = nullptr,
  606. .reserved8 = nullptr,
  607. .reserved9 = nullptr,
  608. };
  609. static constexpr struct libdecor_frame_interface libdecor_frame_interface = {
  610. .configure = libdecor_frame_on_configure,
  611. .close = libdecor_frame_on_close,
  612. .commit = libdecor_frame_on_commit,
  613. .dismiss_popup = libdecor_frame_on_dismiss_popup,
  614. .reserved0 = nullptr,
  615. .reserved1 = nullptr,
  616. .reserved2 = nullptr,
  617. .reserved3 = nullptr,
  618. .reserved4 = nullptr,
  619. .reserved5 = nullptr,
  620. .reserved6 = nullptr,
  621. .reserved7 = nullptr,
  622. .reserved8 = nullptr,
  623. .reserved9 = nullptr,
  624. };
  625. #endif // LIBDECOR_ENABLED
  626. static Vector<uint8_t> _read_fd(int fd);
  627. static int _allocate_shm_file(size_t size);
  628. static Vector<uint8_t> _wl_data_offer_read(struct wl_display *wl_display, const char *p_mime, struct wl_data_offer *wl_data_offer);
  629. static 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);
  630. static void _seat_state_set_current(WaylandThread::SeatState &p_ss);
  631. static bool _seat_state_configure_key_event(WaylandThread::SeatState &p_seat, Ref<InputEventKey> p_event, xkb_keycode_t p_keycode, bool p_pressed);
  632. static void _wayland_state_update_cursor();
  633. void _set_current_seat(struct wl_seat *p_seat);
  634. bool _load_cursor_theme(int p_cursor_size);
  635. void _update_scale(int p_scale);
  636. public:
  637. Mutex &mutex = thread_data.mutex;
  638. struct wl_display *get_wl_display() const;
  639. // Core Wayland utilities for integrating with our own data structures.
  640. static bool wl_proxy_is_godot(struct wl_proxy *p_proxy);
  641. static void wl_proxy_tag_godot(struct wl_proxy *p_proxy);
  642. static WindowState *wl_surface_get_window_state(struct wl_surface *p_surface);
  643. static ScreenState *wl_output_get_screen_state(struct wl_output *p_output);
  644. static SeatState *wl_seat_get_seat_state(struct wl_seat *p_seat);
  645. static OfferState *wl_data_offer_get_offer_state(struct wl_data_offer *p_offer);
  646. static OfferState *wp_primary_selection_offer_get_offer_state(struct zwp_primary_selection_offer_v1 *p_offer);
  647. void seat_state_unlock_pointer(SeatState *p_ss);
  648. void seat_state_lock_pointer(SeatState *p_ss);
  649. void seat_state_set_hint(SeatState *p_ss, int p_x, int p_y);
  650. void seat_state_confine_pointer(SeatState *p_ss);
  651. static void seat_state_update_cursor(SeatState *p_ss);
  652. void seat_state_echo_keys(SeatState *p_ss);
  653. static int window_state_get_preferred_buffer_scale(WindowState *p_ws);
  654. static double window_state_get_scale_factor(WindowState *p_ws);
  655. static void window_state_update_size(WindowState *p_ws, int p_width, int p_height);
  656. static Vector2i scale_vector2i(const Vector2i &p_vector, double p_amount);
  657. void push_message(Ref<Message> message);
  658. bool has_message();
  659. Ref<Message> pop_message();
  660. void window_create(DisplayServer::WindowID p_window_id, int p_width, int p_height);
  661. struct wl_surface *window_get_wl_surface(DisplayServer::WindowID p_window_id) const;
  662. void window_set_max_size(DisplayServer::WindowID p_window_id, const Size2i &p_size);
  663. void window_set_min_size(DisplayServer::WindowID p_window_id, const Size2i &p_size);
  664. bool window_can_set_mode(DisplayServer::WindowID p_window_id, DisplayServer::WindowMode p_window_mode) const;
  665. void window_try_set_mode(DisplayServer::WindowID p_window_id, DisplayServer::WindowMode p_window_mode);
  666. DisplayServer::WindowMode window_get_mode(DisplayServer::WindowID p_window_id) const;
  667. void window_set_borderless(DisplayServer::WindowID p_window_id, bool p_borderless);
  668. void window_set_title(DisplayServer::WindowID p_window_id, const String &p_title);
  669. void window_set_app_id(DisplayServer::WindowID p_window_id, const String &p_app_id);
  670. bool window_is_focused(DisplayServer::WindowID p_window_id);
  671. // Optional - requires xdg_activation_v1
  672. void window_request_attention(DisplayServer::WindowID p_window_id);
  673. // Optional - require idle_inhibit_unstable_v1
  674. void window_set_idle_inhibition(DisplayServer::WindowID p_window_id, bool p_enable);
  675. bool window_get_idle_inhibition(DisplayServer::WindowID p_window_id) const;
  676. ScreenData screen_get_data(int p_screen) const;
  677. int get_screen_count() const;
  678. void pointer_set_constraint(PointerConstraint p_constraint);
  679. void pointer_set_hint(const Point2i &p_hint);
  680. PointerConstraint pointer_get_constraint() const;
  681. DisplayServer::WindowID pointer_get_pointed_window_id() const;
  682. BitField<MouseButtonMask> pointer_get_button_mask() const;
  683. void cursor_hide();
  684. void cursor_set_shape(DisplayServer::CursorShape p_cursor_shape);
  685. void cursor_set_custom_shape(DisplayServer::CursorShape p_cursor_shape);
  686. void cursor_shape_set_custom_image(DisplayServer::CursorShape p_cursor_shape, Ref<Image> p_image, const Point2i &p_hotspot);
  687. void cursor_shape_clear_custom_image(DisplayServer::CursorShape p_cursor_shape);
  688. int keyboard_get_layout_count() const;
  689. int keyboard_get_current_layout_index() const;
  690. void keyboard_set_current_layout_index(int p_index);
  691. String keyboard_get_layout_name(int p_index) const;
  692. Key keyboard_get_key_from_physical(Key p_key) const;
  693. void keyboard_echo_keys();
  694. bool selection_has_mime(const String &p_mime) const;
  695. Vector<uint8_t> selection_get_mime(const String &p_mime) const;
  696. void selection_set_text(const String &p_text);
  697. // Optional primary support - requires wp_primary_selection_unstable_v1
  698. bool primary_has_mime(const String &p_mime) const;
  699. Vector<uint8_t> primary_get_mime(const String &p_mime) const;
  700. void primary_set_text(const String &p_text);
  701. void set_frame();
  702. bool get_reset_frame();
  703. Error init();
  704. void destroy();
  705. };
  706. #endif // WAYLAND_ENABLED
  707. #endif // WAYLAND_THREAD_H