wayland_embedder.h 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
  1. /**************************************************************************/
  2. /* wayland_embedder.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. #pragma once
  31. #ifdef WAYLAND_ENABLED
  32. #ifdef TOOLS_ENABLED
  33. #include "core/templates/a_hash_map.h"
  34. #include "core/templates/pooled_list.h"
  35. #ifdef SOWRAP_ENABLED
  36. #include "wayland/dynwrappers/wayland-client-core-so_wrap.h"
  37. #else
  38. #include <wayland-client-core.h>
  39. #endif
  40. #include "protocol/wayland.gen.h"
  41. #include "protocol/linux_dmabuf_v1.gen.h"
  42. #include "protocol/xdg_shell.gen.h"
  43. #include "protocol/commit_timing_v1.gen.h"
  44. #include "protocol/cursor_shape.gen.h"
  45. #include "protocol/fifo_v1.gen.h"
  46. #include "protocol/fractional_scale.gen.h"
  47. #include "protocol/godot_embedding_compositor.gen.h"
  48. #include "protocol/idle_inhibit.gen.h"
  49. #include "protocol/linux_drm_syncobj_v1.gen.h"
  50. #include "protocol/linux_explicit_synchronization_unstable_v1.gen.h"
  51. #include "protocol/pointer_constraints.gen.h"
  52. #include "protocol/pointer_gestures.gen.h"
  53. #include "protocol/primary_selection.gen.h"
  54. #include "protocol/relative_pointer.gen.h"
  55. #include "protocol/tablet.gen.h"
  56. #include "protocol/tearing_control_v1.gen.h"
  57. #include "protocol/text_input.gen.h"
  58. #include "protocol/viewporter.gen.h"
  59. #include "protocol/wayland-drm.gen.h"
  60. #include "protocol/xdg_activation.gen.h"
  61. #include "protocol/xdg_decoration.gen.h"
  62. #include "protocol/xdg_foreign_v1.gen.h"
  63. #include "protocol/xdg_foreign_v2.gen.h"
  64. #include "protocol/xdg_shell.gen.h"
  65. #include "protocol/xdg_system_bell.gen.h"
  66. #include "protocol/xdg_toplevel_icon.gen.h"
  67. #include <errno.h>
  68. #include <stdint.h>
  69. #include <stdio.h>
  70. #include <stdlib.h>
  71. #include <string.h>
  72. #include <sys/socket.h>
  73. #include <sys/un.h>
  74. #include <poll.h>
  75. #include "core/io/dir_access.h"
  76. #include "core/os/thread.h"
  77. // TODO: Consider resizing the ancillary buffer dynamically.
  78. #define EMBED_ANCILLARY_BUF_SIZE 4096
  79. class WaylandEmbedder {
  80. enum class ProxyDirection {
  81. CLIENT,
  82. COMPOSITOR,
  83. };
  84. enum class MessageStatus {
  85. HANDLED,
  86. UNHANDLED,
  87. INVALID,
  88. ERROR,
  89. };
  90. struct msg_info {
  91. uint32_t raw_id = 0;
  92. uint16_t size = 0;
  93. uint16_t opcode = 0;
  94. pid_t pid = 0;
  95. ProxyDirection direction = ProxyDirection::CLIENT;
  96. constexpr size_t words() const { return (size / sizeof(uint32_t)); }
  97. };
  98. struct WaylandObjectData {
  99. virtual ~WaylandObjectData() = default;
  100. };
  101. struct WaylandObject {
  102. const struct wl_interface *interface = nullptr;
  103. int version = 0;
  104. // Inert, awaiting confirmation from server.
  105. bool destroyed = false;
  106. // Other objects might depend on it and must not be destroyed.
  107. bool shared = false;
  108. WaylandObjectData *data = nullptr;
  109. };
  110. struct WaylandDrmGlobalData : WaylandObjectData {
  111. String device;
  112. LocalVector<uint32_t> formats;
  113. bool authenticated;
  114. uint32_t capabilities;
  115. };
  116. struct WaylandShmGlobalData : WaylandObjectData {
  117. LocalVector<uint32_t> formats;
  118. };
  119. struct Client {
  120. struct GlobalIdInfo {
  121. uint32_t id = INVALID_ID;
  122. List<uint32_t>::Element *history_elem = nullptr;
  123. GlobalIdInfo() = default;
  124. GlobalIdInfo(uint32_t p_id, List<uint32_t>::Element *p_history_elem) :
  125. id(p_id), history_elem(p_history_elem) {}
  126. };
  127. WaylandEmbedder *embedder = nullptr;
  128. int socket = -1;
  129. // NOTE: PIDs are not unique per client!
  130. pid_t pid = 0;
  131. // FIXME: Names suck.
  132. AHashMap<uint32_t, HashSet<uint32_t>> registry_globals_instances;
  133. HashSet<uint32_t> wl_registry_instances;
  134. List<uint32_t> global_id_history;
  135. AHashMap<uint32_t, GlobalIdInfo> global_ids;
  136. AHashMap<uint32_t, uint32_t> local_ids;
  137. // Objects with no equivalent on the real compositor.
  138. AHashMap<uint32_t, WaylandObject> fake_objects;
  139. // Objects which mirror events of a global object.
  140. AHashMap<uint32_t, WaylandObject> global_instances;
  141. uint32_t embedded_client_id = INVALID_ID;
  142. uint32_t embedded_window_id = INVALID_ID;
  143. List<int> fds;
  144. // Clients obviously expect properly packed server IDs, so we need to allocate
  145. // them somehow. This approach mimics the one used in PooledList.
  146. uint32_t allocated_server_ids = INVALID_ID;
  147. LocalVector<uint32_t> free_server_ids;
  148. uint32_t get_global_id(uint32_t p_local_id) const { return global_ids.has(p_local_id) ? global_ids[p_local_id].id : INVALID_ID; }
  149. uint32_t get_local_id(uint32_t p_global_id) const { return local_ids.has(p_global_id) ? local_ids[p_global_id] : INVALID_ID; }
  150. uint32_t allocate_server_id();
  151. WaylandObject *get_object(uint32_t p_local_id);
  152. Error delete_object(uint32_t p_local_id);
  153. Error bind_global_id(uint32_t p_global_id, uint32_t p_local_id);
  154. uint32_t new_object(uint32_t p_local_id, const struct wl_interface *p_interface, int p_version = 1, WaylandObjectData *p_data = nullptr);
  155. uint32_t new_server_object(uint32_t p_global_id, const struct wl_interface *p_interface, int p_version = 1, WaylandObjectData *p_data = nullptr);
  156. WaylandObject *new_fake_object(uint32_t p_local_id, const struct wl_interface *p_interface, int p_version = 1, WaylandObjectData *p_data = nullptr);
  157. WaylandObject *new_global_instance(uint32_t p_local_id, uint32_t p_global_id, const struct wl_interface *p_interface, int p_version = 1, WaylandObjectData *p_data = nullptr);
  158. Error send_wl_drm_state(uint32_t p_id, WaylandDrmGlobalData *p_state);
  159. };
  160. // Local IDs are a mess to handle as they strictly depend on their client of
  161. // origin. This wrapper helps with that.
  162. class LocalObjectHandle {
  163. Client *client = nullptr;
  164. uint32_t local_id = INVALID_ID;
  165. public:
  166. constexpr LocalObjectHandle() = default;
  167. constexpr LocalObjectHandle(Client *p_client, uint32_t p_id) :
  168. client(p_client), local_id(p_id) {}
  169. void invalidate() {
  170. client = nullptr;
  171. local_id = INVALID_ID;
  172. }
  173. constexpr bool is_valid() const { return client != nullptr && local_id != INVALID_ID; }
  174. WaylandObject *get() { return is_valid() ? client->get_object(local_id) : nullptr; }
  175. constexpr Client *get_client() const { return client; }
  176. constexpr uint32_t get_local_id() const { return local_id; }
  177. uint32_t get_global_id() const { return (is_valid() && client->global_ids.has(local_id)) ? client->global_ids[local_id].id : INVALID_ID; }
  178. };
  179. struct WaylandSeatInstanceData : WaylandObjectData {
  180. uint32_t wl_keyboard_id = INVALID_ID;
  181. uint32_t wl_pointer_id = INVALID_ID;
  182. };
  183. struct WaylandSeatGlobalData : WaylandObjectData {
  184. uint32_t capabilities = 0;
  185. uint32_t pointed_surface_id = INVALID_ID;
  186. uint32_t focused_surface_id = INVALID_ID;
  187. };
  188. struct WaylandKeyboardData : WaylandObjectData {
  189. uint32_t wl_seat_id = INVALID_ID;
  190. };
  191. struct WaylandPointerData : WaylandObjectData {
  192. uint32_t wl_seat_id = INVALID_ID;
  193. };
  194. struct WaylandSurfaceData : WaylandObjectData {
  195. Client *client = nullptr;
  196. LocalObjectHandle role_object_handle;
  197. };
  198. struct XdgSurfaceData : WaylandObjectData {
  199. uint32_t wl_surface_id = INVALID_ID;
  200. };
  201. struct WaylandSubsurfaceData : WaylandObjectData {
  202. Point2i position;
  203. };
  204. struct XdgToplevelData : WaylandObjectData {
  205. LocalObjectHandle xdg_surface_handle;
  206. LocalObjectHandle parent_handle;
  207. uint32_t wl_subsurface_id = INVALID_ID;
  208. Size2i size;
  209. bool configured = false;
  210. constexpr bool is_embedded() const { return wl_subsurface_id != INVALID_ID; }
  211. };
  212. struct XdgPopupData : WaylandObjectData {
  213. LocalObjectHandle parent_handle;
  214. };
  215. struct XdgPositionerData : WaylandObjectData {
  216. Rect2i anchor_rect;
  217. };
  218. struct EmbeddedClientData : WaylandObjectData {
  219. Client *client = nullptr;
  220. bool disconnected = false;
  221. };
  222. struct RegistryGlobalInfo {
  223. const struct wl_interface *interface = nullptr;
  224. uint32_t version = 0;
  225. uint32_t compositor_name = 0;
  226. // The specs requires for us to ignore requests for destroyed global
  227. // objects until all instances are gone, to avoid races.
  228. bool destroyed = false;
  229. int instance_counter = 0;
  230. // Key is version.
  231. HashMap<uint32_t, uint32_t> reusable_objects;
  232. WaylandObjectData *data = nullptr;
  233. };
  234. // These are the interfaces that the embedder understands and exposes. We do
  235. // not implement handlers for all of them (that's the point), but we need to
  236. // list them anyways to query their signatures at runtime, which include file
  237. // descriptors count. Additionally, even if we could go without specifying
  238. // them, having a "known good" list avoids unpleasant incompatibilities with
  239. // future compositors.
  240. const static constexpr struct wl_interface *interfaces[] = {
  241. // wayland
  242. &wl_buffer_interface,
  243. &wl_callback_interface,
  244. &wl_compositor_interface,
  245. &wl_data_device_interface,
  246. &wl_data_device_manager_interface,
  247. &wl_data_offer_interface,
  248. &wl_data_source_interface,
  249. &wl_display_interface,
  250. &wl_keyboard_interface,
  251. &wl_output_interface,
  252. &wl_pointer_interface,
  253. &wl_region_interface,
  254. &wl_registry_interface,
  255. &wl_seat_interface,
  256. //&wl_shell_interface, // Deprecated.
  257. //&wl_shell_surface_interface, // Deprecated.
  258. &wl_shm_interface,
  259. &wl_shm_pool_interface,
  260. &wl_subcompositor_interface,
  261. &wl_subsurface_interface,
  262. &wl_surface_interface,
  263. //&wl_touch_interface, // Unused (at the moment).
  264. // xdg-shell
  265. &xdg_wm_base_interface,
  266. &xdg_positioner_interface,
  267. &xdg_surface_interface,
  268. &xdg_toplevel_interface,
  269. &xdg_popup_interface,
  270. // linux-dmabuf-v1
  271. &zwp_linux_dmabuf_v1_interface,
  272. &zwp_linux_buffer_params_v1_interface,
  273. &zwp_linux_dmabuf_feedback_v1_interface,
  274. // linux-explicit-synchronization-unstable-v1
  275. &zwp_linux_explicit_synchronization_v1_interface,
  276. &zwp_linux_surface_synchronization_v1_interface,
  277. &zwp_linux_buffer_release_v1_interface,
  278. // fractional-scale
  279. &wp_fractional_scale_manager_v1_interface,
  280. &wp_fractional_scale_v1_interface,
  281. // idle-inhibit
  282. &zwp_idle_inhibit_manager_v1_interface,
  283. &zwp_idle_inhibitor_v1_interface,
  284. // pointer-constraints
  285. &zwp_pointer_constraints_v1_interface,
  286. &zwp_locked_pointer_v1_interface,
  287. &zwp_confined_pointer_v1_interface,
  288. // pointer-gestures
  289. &zwp_pointer_gestures_v1_interface,
  290. &zwp_pointer_gesture_swipe_v1_interface,
  291. &zwp_pointer_gesture_pinch_v1_interface,
  292. &zwp_pointer_gesture_hold_v1_interface,
  293. // primary-selection
  294. &zwp_primary_selection_device_manager_v1_interface,
  295. &zwp_primary_selection_device_v1_interface,
  296. &zwp_primary_selection_offer_v1_interface,
  297. &zwp_primary_selection_source_v1_interface,
  298. // relative-pointer
  299. &zwp_relative_pointer_manager_v1_interface,
  300. &zwp_relative_pointer_v1_interface,
  301. // tablet
  302. // TODO: Needs some extra work
  303. //&zwp_tablet_manager_v2_interface,
  304. //&zwp_tablet_seat_v2_interface,
  305. //&zwp_tablet_tool_v2_interface,
  306. //&zwp_tablet_v2_interface,
  307. //&zwp_tablet_pad_ring_v2_interface,
  308. //&zwp_tablet_pad_strip_v2_interface,
  309. //&zwp_tablet_pad_group_v2_interface,
  310. //&zwp_tablet_pad_v2_interface,
  311. // text-input
  312. &zwp_text_input_v3_interface,
  313. &zwp_text_input_manager_v3_interface,
  314. // viewporter
  315. &wp_viewporter_interface,
  316. &wp_viewport_interface,
  317. // xdg-activation
  318. &xdg_activation_v1_interface,
  319. &xdg_activation_token_v1_interface,
  320. // xdg-decoration
  321. &zxdg_decoration_manager_v1_interface,
  322. &zxdg_toplevel_decoration_v1_interface,
  323. // xdg-foreign
  324. &zxdg_exporter_v1_interface,
  325. &zxdg_importer_v1_interface,
  326. // xdg-foreign-v1
  327. &zxdg_exporter_v1_interface,
  328. &zxdg_importer_v1_interface,
  329. // xdg-foreign-v2
  330. &zxdg_exporter_v2_interface,
  331. &zxdg_importer_v2_interface,
  332. // xdg-shell
  333. &xdg_wm_base_interface,
  334. &xdg_positioner_interface,
  335. &xdg_surface_interface,
  336. &xdg_toplevel_interface,
  337. &xdg_popup_interface,
  338. // xdg-system-bell
  339. &xdg_system_bell_v1_interface,
  340. // xdg-toplevel-icon-v1
  341. &xdg_toplevel_icon_manager_v1_interface,
  342. &xdg_toplevel_icon_v1_interface,
  343. // wp-cursor-shape-v1
  344. &wp_cursor_shape_manager_v1_interface,
  345. // wayland-drm
  346. &wl_drm_interface,
  347. // linux-drm-syncobj-v1
  348. &wp_linux_drm_syncobj_manager_v1_interface,
  349. &wp_linux_drm_syncobj_surface_v1_interface,
  350. &wp_linux_drm_syncobj_timeline_v1_interface,
  351. // fifo-v1
  352. &wp_fifo_manager_v1_interface,
  353. &wp_fifo_v1_interface,
  354. // commit-timing-v1
  355. &wp_commit_timing_manager_v1_interface,
  356. &wp_commit_timer_v1_interface,
  357. // tearing-control-v1
  358. &wp_tearing_control_manager_v1_interface,
  359. &wp_tearing_control_v1_interface,
  360. // Our custom things.
  361. &godot_embedding_compositor_interface,
  362. &godot_embedded_client_interface,
  363. };
  364. // These interfaces will not be reported to embedded clients. This includes
  365. // stuff that interacts with toplevels or other emulated objects that would
  366. // have been filtered out manually anyways.
  367. HashSet<const struct wl_interface *> embedded_interface_deny_list = HashSet({
  368. &zxdg_decoration_manager_v1_interface,
  369. &zxdg_decoration_manager_v1_interface,
  370. &zxdg_exporter_v1_interface,
  371. &zxdg_exporter_v2_interface,
  372. &xdg_toplevel_icon_manager_v1_interface,
  373. &godot_embedding_compositor_interface,
  374. });
  375. static constexpr uint32_t INVALID_ID = 0;
  376. static constexpr uint32_t DISPLAY_ID = 1;
  377. static constexpr uint32_t REGISTRY_ID = 2;
  378. int proxy_socket = -1;
  379. int compositor_socket = -1;
  380. // NOTE: First element must be the listening socket! This allows us to process
  381. // it last, cleaning up closed sockets before it reuses their handles.
  382. LocalVector<struct pollfd> pollfds;
  383. // Key is socket.
  384. AHashMap<int, Client> clients;
  385. Client *main_client = nullptr;
  386. PooledList<WaylandObject> objects;
  387. // Proxies allocated by the compositor. Their ID starts from 0xff000000.
  388. LocalVector<WaylandObject> server_objects;
  389. uint32_t wl_compositor_id = 0;
  390. uint32_t wl_subcompositor_id = 0;
  391. uint32_t main_toplevel_id = 0;
  392. uint32_t xdg_wm_base_id = 0;
  393. // Global id to name
  394. HashMap<uint32_t, uint32_t> registry_globals_names;
  395. HashMap<uint32_t, RegistryGlobalInfo> registry_globals;
  396. uint32_t registry_globals_counter = 0;
  397. uint32_t godot_embedding_compositor_name = 0;
  398. LocalVector<uint32_t> wl_seat_names;
  399. Thread proxy_thread;
  400. List<int> client_fds;
  401. List<int> compositor_fds;
  402. uint32_t serial_counter = 0;
  403. uint32_t configure_serial_counter = 0;
  404. uint32_t sync_callback_id = 0;
  405. Ref<DirAccess> runtime_dir;
  406. int lock_fd = -1;
  407. String socket_path;
  408. String socket_lock_path;
  409. LocalVector<uint32_t> msg_buf;
  410. LocalVector<uint8_t> ancillary_buf;
  411. SafeFlag thread_done;
  412. static size_t wl_array_word_offset(uint32_t p_size);
  413. const static struct wl_interface *wl_interface_from_string(const char *name, size_t size);
  414. static int wl_interface_get_destructor_opcode(const struct wl_interface *p_iface, uint32_t p_version);
  415. static Error send_raw_message(int p_socket, std::initializer_list<struct iovec> p_vecs, const LocalVector<int> &p_fds = LocalVector<int>());
  416. static Error send_wayland_message(int p_socket, uint32_t p_id, uint32_t p_opcode, const uint32_t *p_args, const size_t p_args_words);
  417. static Error send_wayland_message(ProxyDirection p_direction, int p_socket, uint32_t p_id, const struct wl_interface &p_interface, uint32_t p_opcode, const LocalVector<union wl_argument> &p_args);
  418. // Utility aliases.
  419. static Error send_wayland_message(int p_socket, uint32_t p_id, uint32_t p_opcode, std::initializer_list<uint32_t> p_args) {
  420. return send_wayland_message(p_socket, p_id, p_opcode, p_args.begin(), p_args.size());
  421. }
  422. static Error send_wayland_method(int p_socket, uint32_t p_id, const struct wl_interface &p_interface, uint32_t p_opcode, const LocalVector<union wl_argument> &p_args) {
  423. return send_wayland_message(ProxyDirection::COMPOSITOR, p_socket, p_id, p_interface, p_opcode, p_args);
  424. }
  425. static Error send_wayland_event(int p_socket, uint32_t p_id, const struct wl_interface &p_interface, uint32_t p_opcode, const LocalVector<union wl_argument> &p_args) {
  426. return send_wayland_message(ProxyDirection::CLIENT, p_socket, p_id, p_interface, p_opcode, p_args);
  427. }
  428. // Closes the socket.
  429. static void socket_error(int p_socket, uint32_t p_object_id, uint32_t p_code, const String &p_message);
  430. // NOTE: Yes, in our case object arguments are actually uints for now.
  431. // Best way I found to reuse the Wayland stuff. Might need to make our
  432. // own eventually.
  433. static constexpr union wl_argument wl_arg_int(int32_t p_value) {
  434. union wl_argument arg = {};
  435. arg.i = p_value;
  436. return arg;
  437. }
  438. static constexpr union wl_argument wl_arg_uint(uint32_t p_value) {
  439. union wl_argument arg = {};
  440. arg.u = p_value;
  441. return arg;
  442. }
  443. static constexpr union wl_argument wl_arg_fixed(wl_fixed_t p_value) {
  444. union wl_argument arg = {};
  445. arg.f = p_value;
  446. return arg;
  447. }
  448. static constexpr union wl_argument wl_arg_string(const char *p_value) {
  449. union wl_argument arg = {};
  450. arg.s = p_value;
  451. return arg;
  452. }
  453. static constexpr union wl_argument wl_arg_object(uint32_t p_value) {
  454. union wl_argument arg = {};
  455. arg.u = p_value;
  456. return arg;
  457. }
  458. static constexpr union wl_argument wl_arg_new_id(uint32_t p_value) {
  459. union wl_argument arg = {};
  460. arg.n = p_value;
  461. return arg;
  462. }
  463. uint32_t new_object(const struct wl_interface *p_interface, int p_version = 1, WaylandObjectData *p_data = nullptr);
  464. WaylandObject *new_server_object(uint32_t p_global_id, const struct wl_interface *p_interface, int p_version = 1, WaylandObjectData *p_data = nullptr);
  465. void poll_sockets();
  466. int allocate_global_id();
  467. bool global_surface_is_window(uint32_t p_global_surface_id);
  468. WaylandObject *get_object(uint32_t id);
  469. Error delete_object(uint32_t id);
  470. void cleanup_socket(int p_socket);
  471. void sync();
  472. uint32_t wl_registry_bind(uint32_t p_registry_id, uint32_t p_name, int p_version);
  473. void seat_name_enter_surface(uint32_t p_seat_name, uint32_t p_global_surface_id);
  474. void seat_name_leave_surface(uint32_t p_seat_name, uint32_t p_global_surface_id);
  475. MessageStatus handle_request(LocalObjectHandle p_object, uint32_t p_opcode, const uint32_t *msg_data, size_t msg_len);
  476. MessageStatus handle_event(uint32_t p_global_id, LocalObjectHandle p_local_handle, uint32_t p_opcode, const uint32_t *msg_data, size_t msg_len);
  477. void shutdown();
  478. bool handle_generic_msg(Client *client, const WaylandObject *p_object, const struct wl_message *message, const struct msg_info *info, uint32_t *buf, uint32_t instance_id = INVALID_ID);
  479. Error handle_msg_info(Client *client, const struct msg_info *info, uint32_t *buf, int *fds_requested);
  480. Error handle_sock(int p_fd);
  481. void handle_fd(int p_fd, int p_revents);
  482. static void _thread_loop(void *p_data);
  483. public:
  484. // Returns path to socket.
  485. Error init();
  486. String get_socket_path() const { return socket_path; }
  487. ~WaylandEmbedder();
  488. };
  489. #endif // TOOLS_ENABLED
  490. #endif // WAYLAND_ENABLED