wayland_embedder.cpp 101 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971
  1. /**************************************************************************/
  2. /* wayland_embedder.cpp */
  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. #include "wayland_embedder.h"
  31. #ifdef WAYLAND_ENABLED
  32. #ifdef TOOLS_ENABLED
  33. #include <sys/stat.h>
  34. #ifdef __FreeBSD__
  35. #include <dev/evdev/input-event-codes.h>
  36. #else
  37. // Assume Linux.
  38. #include <linux/input-event-codes.h>
  39. #endif
  40. #include "core/os/os.h"
  41. #include <fcntl.h>
  42. #include <sys/file.h>
  43. #include <unistd.h>
  44. #define WAYLAND_EMBED_ID_MAX 1000
  45. //#define WAYLAND_EMBED_DEBUG_LOGS_ENABLED
  46. #ifdef WAYLAND_EMBED_DEBUG_LOGS_ENABLED
  47. // Gotta flush as we're doing this mess from a thread without any
  48. // synchronization. It's awful, I know, but the `print_*` utilities hang for
  49. // some reason during editor startup and I need some quick and dirty debugging.
  50. #define DEBUG_LOG_WAYLAND_EMBED(...) \
  51. if (1) { \
  52. printf("[PROXY] %s\n", vformat(__VA_ARGS__).utf8().ptr()); \
  53. fflush(stdout); \
  54. } else \
  55. ((void)0)
  56. #else
  57. #define DEBUG_LOG_WAYLAND_EMBED(...)
  58. #endif
  59. // Wayland messages are structured with 32-bit words.
  60. #define WL_WORD_SIZE (sizeof(uint32_t))
  61. // Event opcodes. Request opcodes are defined in the generated client headers.
  62. // We could generate server headers but they would clash (without modifications)
  63. // and we use just a few constants anyways.
  64. #define WL_DISPLAY_ERROR 0
  65. #define WL_DISPLAY_DELETE_ID 1
  66. #define WL_REGISTRY_GLOBAL 0
  67. #define WL_REGISTRY_GLOBAL_REMOVE 1
  68. #define WL_CALLBACK_DONE 0
  69. #define WL_KEYBOARD_ENTER 1
  70. #define WL_KEYBOARD_LEAVE 2
  71. #define WL_KEYBOARD_KEY 3
  72. #define WL_POINTER_ENTER 0
  73. #define WL_POINTER_LEAVE 1
  74. #define WL_POINTER_BUTTON 3
  75. #define WL_SHM_FORMAT 0
  76. #define WL_DRM_DEVICE 0
  77. #define WL_DRM_FORMAT 1
  78. #define WL_DRM_AUTHENTICATED 2
  79. #define WL_DRM_CAPABILITIES 3
  80. #define XDG_POPUP_CONFIGURE 0
  81. size_t WaylandEmbedder::wl_array_word_offset(uint32_t p_size) {
  82. uint32_t pad = (WL_WORD_SIZE - (p_size % WL_WORD_SIZE)) % WL_WORD_SIZE;
  83. return (p_size + pad) / WL_WORD_SIZE;
  84. }
  85. const struct wl_interface *WaylandEmbedder::wl_interface_from_string(const char *name, size_t size) {
  86. for (size_t i = 0; i < (sizeof interfaces / sizeof *interfaces); ++i) {
  87. if (strncmp(name, interfaces[i]->name, size) == 0) {
  88. return interfaces[i];
  89. }
  90. }
  91. return nullptr;
  92. }
  93. int WaylandEmbedder::wl_interface_get_destructor_opcode(const struct wl_interface *p_iface, uint32_t version) {
  94. ERR_FAIL_NULL_V(p_iface, -1);
  95. // FIXME: Figure out how to extract the destructor from the XML files. This
  96. // value is not currently exposed by wayland-scanner.
  97. for (int i = 0; i < p_iface->method_count; ++i) {
  98. const struct wl_message &m = p_iface->methods[i];
  99. uint32_t destructor_version = String::to_int(m.signature);
  100. if (destructor_version <= version && (strcmp(m.name, "destroy") == 0 || strcmp(m.name, "release") == 0)) {
  101. return i;
  102. }
  103. }
  104. return -1;
  105. }
  106. struct WaylandEmbedder::WaylandObject *WaylandEmbedder::get_object(uint32_t p_global_id) {
  107. if (p_global_id == 0) {
  108. return nullptr;
  109. }
  110. // Server-allocated stuff starts at 0xff000000.
  111. bool is_server = p_global_id & 0xff000000;
  112. if (is_server) {
  113. p_global_id &= ~(0xff000000);
  114. }
  115. #ifdef DEV_ENABLED
  116. if (p_global_id >= WAYLAND_EMBED_ID_MAX) {
  117. // Oh no. Time for debug info!
  118. #ifdef WAYLAND_EMBED_DEBUG_LOGS_ENABLED
  119. for (uint32_t id = 1; id < objects.reserved_size(); ++id) {
  120. WaylandObject &object = objects[id];
  121. DEBUG_LOG_WAYLAND_EMBED(vformat(" - g0x%x (#%d): %s version %d, data 0x%x", id, id, object.interface->name, object.version, (uintptr_t)object.data));
  122. }
  123. #endif // WAYLAND_EMBED_DEBUG_LOGS_ENABLED
  124. CRASH_NOW_MSG(vformat("Tried to access ID bigger than debug cap (%d > %d).", p_global_id, WAYLAND_EMBED_ID_MAX));
  125. }
  126. #endif // DEV_ENABLED
  127. if (is_server) {
  128. if (server_objects.size() <= p_global_id) {
  129. return nullptr;
  130. }
  131. return &server_objects[p_global_id];
  132. } else {
  133. if (objects.reserved_size() <= p_global_id) {
  134. return nullptr;
  135. }
  136. return &objects[p_global_id];
  137. }
  138. }
  139. Error WaylandEmbedder::delete_object(uint32_t p_global_id) {
  140. WaylandObject *object = get_object(p_global_id);
  141. ERR_FAIL_NULL_V(object, ERR_DOES_NOT_EXIST);
  142. if (object->shared) {
  143. ERR_FAIL_V_MSG(FAILED, vformat("Tried to delete shared object g0x%x.", p_global_id));
  144. }
  145. DEBUG_LOG_WAYLAND_EMBED(vformat("Deleting object %s g0x%x", object->interface ? object->interface->name : "UNKNOWN", p_global_id));
  146. if (object->data) {
  147. memdelete(object->data);
  148. object->data = nullptr;
  149. }
  150. bool is_server = p_global_id & 0xff000000;
  151. if (is_server) {
  152. server_objects[p_global_id & ~(0xff000000)] = WaylandObject();
  153. } else {
  154. objects.free(p_global_id);
  155. }
  156. registry_globals_names.erase(p_global_id);
  157. return OK;
  158. }
  159. uint32_t WaylandEmbedder::Client::allocate_server_id() {
  160. uint32_t new_id = INVALID_ID;
  161. if (free_server_ids.size() > 0) {
  162. int new_size = free_server_ids.size() - 1;
  163. new_id = free_server_ids[new_size] | 0xff000000;
  164. free_server_ids.resize_uninitialized(new_size);
  165. } else {
  166. new_id = allocated_server_ids | 0xff000000;
  167. ++allocated_server_ids;
  168. #ifdef DEV_ENABLED
  169. CRASH_COND_MSG(allocated_server_ids > WAYLAND_EMBED_ID_MAX, "Max server ID reached. This might indicate a leak.");
  170. #endif // DEV_ENABLED
  171. }
  172. DEBUG_LOG_WAYLAND_EMBED(vformat("Allocated server-side id 0x%x.", new_id));
  173. return new_id;
  174. }
  175. struct WaylandEmbedder::WaylandObject *WaylandEmbedder::Client::get_object(uint32_t p_local_id) {
  176. if (p_local_id == INVALID_ID) {
  177. return nullptr;
  178. }
  179. if (global_instances.has(p_local_id)) {
  180. return &global_instances[p_local_id];
  181. }
  182. if (fake_objects.has(p_local_id)) {
  183. return &fake_objects[p_local_id];
  184. }
  185. if (!global_ids.has(p_local_id)) {
  186. return nullptr;
  187. }
  188. ERR_FAIL_NULL_V(embedder, nullptr);
  189. return embedder->get_object(get_global_id(p_local_id));
  190. }
  191. Error WaylandEmbedder::Client::bind_global_id(uint32_t p_global_id, uint32_t p_local_id) {
  192. ERR_FAIL_COND_V(local_ids.has(p_global_id), ERR_ALREADY_EXISTS);
  193. ERR_FAIL_COND_V(global_ids.has(p_local_id), ERR_ALREADY_EXISTS);
  194. GlobalIdInfo gid_info;
  195. gid_info.id = p_global_id;
  196. DEBUG_LOG_WAYLAND_EMBED(vformat("Pushing g0x%x in the global id history", p_global_id));
  197. gid_info.history_elem = global_id_history.push_back(p_global_id);
  198. global_ids[p_local_id] = gid_info;
  199. local_ids[p_global_id] = p_local_id;
  200. return OK;
  201. }
  202. Error WaylandEmbedder::Client::delete_object(uint32_t p_local_id) {
  203. if (fake_objects.has(p_local_id)) {
  204. #ifdef WAYLAND_EMBED_DEBUG_LOGS_ENABLED
  205. WaylandObject *object = &fake_objects[p_local_id];
  206. DEBUG_LOG_WAYLAND_EMBED(vformat("Deleting fake object %s l0x%x", object->interface ? object->interface->name : "UNKNOWN", p_local_id));
  207. #endif
  208. if (!(p_local_id & 0xff000000)) {
  209. // wl_display::delete_id
  210. send_wayland_message(socket, DISPLAY_ID, 1, { p_local_id });
  211. }
  212. fake_objects.erase(p_local_id);
  213. // We can skip everything else below, as fake objects don't have a global id.
  214. return OK;
  215. }
  216. ERR_FAIL_COND_V(!global_ids.has(p_local_id), ERR_DOES_NOT_EXIST);
  217. GlobalIdInfo gid_info = global_ids[p_local_id];
  218. uint32_t global_id = gid_info.id;
  219. DEBUG_LOG_WAYLAND_EMBED(vformat("Erasing g0x%x from the global id history", global_id));
  220. global_id_history.erase(gid_info.history_elem);
  221. if (global_instances.has(p_local_id)) {
  222. #ifdef WAYLAND_EMBED_DEBUG_LOGS_ENABLED
  223. WaylandObject *object = &global_instances[p_local_id];
  224. DEBUG_LOG_WAYLAND_EMBED(vformat("Deleting global instance %s l0x%x", object->interface ? object->interface->name : "UNKNOWN", p_local_id));
  225. #endif
  226. // wl_display::delete_id
  227. send_wayland_message(socket, DISPLAY_ID, 1, { p_local_id });
  228. // We don't want to delete the global object tied to this instance, so we'll only get rid of the local stuff.
  229. global_instances.erase(p_local_id);
  230. global_ids.erase(p_local_id);
  231. if (global_id != INVALID_ID) {
  232. local_ids.erase(global_id);
  233. }
  234. // We're done here.
  235. return OK;
  236. }
  237. if (wl_registry_instances.has(p_local_id)) {
  238. wl_registry_instances.erase(p_local_id);
  239. }
  240. WaylandObject *object = embedder->get_object(global_id);
  241. ERR_FAIL_NULL_V(object, ERR_DOES_NOT_EXIST);
  242. ERR_FAIL_COND_V_MSG(object->shared, ERR_INVALID_PARAMETER, vformat("Tried to delete shared object g0x%x.", global_id));
  243. global_ids.erase(p_local_id);
  244. local_ids.erase(global_id);
  245. if (p_local_id & 0xff000000) {
  246. free_server_ids.push_back(p_local_id & ~(0xff000000));
  247. }
  248. uint32_t *global_name = embedder->registry_globals_names.getptr(global_id);
  249. if (global_name) {
  250. {
  251. RegistryGlobalInfo &info = embedder->registry_globals[*global_name];
  252. ERR_FAIL_COND_V_MSG(info.instance_counter == 0, ERR_BUG, "Instance counter inconsistency.");
  253. --info.instance_counter;
  254. if (info.destroyed && info.instance_counter == 0) {
  255. embedder->registry_globals.erase(*global_name);
  256. }
  257. }
  258. registry_globals_instances[*global_name].erase(p_local_id);
  259. }
  260. return embedder->delete_object(global_id);
  261. }
  262. // Returns INVALID_ID if the creation fails. In that case, the user can assume
  263. // that the client got kicked out.
  264. uint32_t WaylandEmbedder::Client::new_object(uint32_t p_local_id, const struct wl_interface *p_interface, int p_version, WaylandObjectData *p_data) {
  265. if (embedder == nullptr) {
  266. socket_error(socket, p_local_id, WL_DISPLAY_ERROR_IMPLEMENTATION, "No embedder set.");
  267. ERR_FAIL_V(INVALID_ID);
  268. }
  269. if (get_object(p_local_id) != nullptr) {
  270. socket_error(socket, p_local_id, WL_DISPLAY_ERROR_IMPLEMENTATION, vformat("Tried to create %s l0x%x but it already exists as %s", p_interface->name, p_local_id, get_object(p_local_id)->interface->name));
  271. ERR_FAIL_V(INVALID_ID);
  272. }
  273. uint32_t new_global_id = embedder->new_object(p_interface, p_version, p_data);
  274. bind_global_id(new_global_id, p_local_id);
  275. return new_global_id;
  276. }
  277. uint32_t WaylandEmbedder::Client::new_server_object(uint32_t p_global_id, const struct wl_interface *p_interface, int p_version, WaylandObjectData *p_data) {
  278. if (embedder == nullptr) {
  279. socket_error(socket, get_local_id(p_global_id), WL_DISPLAY_ERROR_IMPLEMENTATION, "No embedder set.");
  280. ERR_FAIL_V(INVALID_ID);
  281. }
  282. uint32_t new_local_id = allocate_server_id();
  283. embedder->new_server_object(p_global_id, p_interface, p_version, p_data);
  284. bind_global_id(p_global_id, new_local_id);
  285. return new_local_id;
  286. }
  287. WaylandEmbedder::WaylandObject *WaylandEmbedder::Client::new_fake_object(uint32_t p_local_id, const struct wl_interface *p_interface, int p_version, WaylandObjectData *p_data) {
  288. if (embedder == nullptr) {
  289. socket_error(socket, p_local_id, WL_DISPLAY_ERROR_IMPLEMENTATION, "No embedder set.");
  290. ERR_FAIL_V(nullptr);
  291. }
  292. if (get_object(p_local_id) != nullptr) {
  293. socket_error(socket, p_local_id, WL_DISPLAY_ERROR_IMPLEMENTATION, vformat("Object l0x%x already exists", p_local_id));
  294. ERR_FAIL_V(nullptr);
  295. }
  296. WaylandObject &new_object = fake_objects[p_local_id];
  297. new_object.interface = p_interface;
  298. new_object.version = p_version;
  299. new_object.data = p_data;
  300. return &new_object;
  301. }
  302. WaylandEmbedder::WaylandObject *WaylandEmbedder::Client::new_global_instance(uint32_t p_local_id, uint32_t p_global_id, const struct wl_interface *p_interface, int p_version, WaylandObjectData *p_data) {
  303. if (embedder == nullptr) {
  304. socket_error(socket, p_local_id, WL_DISPLAY_ERROR_IMPLEMENTATION, "No embedder set.");
  305. ERR_FAIL_V(nullptr);
  306. }
  307. if (get_object(p_local_id) != nullptr) {
  308. socket_error(socket, p_local_id, WL_DISPLAY_ERROR_IMPLEMENTATION, vformat("Object l0x%x already exists", p_local_id));
  309. ERR_FAIL_V(nullptr);
  310. }
  311. WaylandObject &new_object = global_instances[p_local_id];
  312. new_object.interface = p_interface;
  313. new_object.version = p_version;
  314. new_object.data = p_data;
  315. // FIXME: Track each instance properly. Global instances (the compatibility
  316. // mechanism) are particular as they're the only case where a global ID might
  317. // map to multiple local objects. In that case we need to mirror each event
  318. // which passes a registry object as an argument for each instance.
  319. GlobalIdInfo gid_info;
  320. gid_info.id = p_global_id;
  321. gid_info.history_elem = global_id_history.push_back(p_global_id);
  322. global_ids[p_local_id] = gid_info;
  323. // NOTE: Normally, for each client, there's a single local object per global
  324. // object, but global instances break this expectation. This is technically
  325. // wrong but should work fine, as we have special logic whenever needed.
  326. //
  327. // TODO: it might be nice to enforce that this table is never looked up for
  328. // global instances or even just log attempts.
  329. local_ids[p_global_id] = p_local_id;
  330. return &new_object;
  331. }
  332. Error WaylandEmbedder::Client::send_wl_drm_state(uint32_t p_id, WaylandDrmGlobalData *p_state) {
  333. ERR_FAIL_NULL_V(p_state, ERR_INVALID_PARAMETER);
  334. if (p_state->device.is_empty()) {
  335. // Not yet initialized.
  336. return OK;
  337. }
  338. LocalVector<union wl_argument> args;
  339. args.push_back(wl_arg_string(p_state->device.utf8().get_data()));
  340. send_wayland_event(socket, p_id, wl_drm_interface, WL_DRM_DEVICE, args);
  341. for (uint32_t format : p_state->formats) {
  342. Error err = send_wayland_message(socket, p_id, WL_DRM_FORMAT, { format });
  343. ERR_FAIL_COND_V(err != OK, err);
  344. }
  345. if (p_state->authenticated) {
  346. Error err = send_wayland_message(socket, p_id, WL_DRM_AUTHENTICATED, {});
  347. ERR_FAIL_COND_V(err != OK, err);
  348. }
  349. Error err = send_wayland_message(socket, p_id, WL_DRM_CAPABILITIES, { p_state->capabilities });
  350. ERR_FAIL_COND_V(err != OK, err);
  351. return OK;
  352. }
  353. void WaylandEmbedder::cleanup_socket(int p_socket) {
  354. DEBUG_LOG_WAYLAND_EMBED(vformat("Cleaning up socket %d.", p_socket));
  355. close(p_socket);
  356. for (size_t i = 0; i < pollfds.size(); ++i) {
  357. if (pollfds[i].fd == p_socket) {
  358. pollfds.remove_at_unordered(i);
  359. break;
  360. }
  361. }
  362. ERR_FAIL_COND(!clients.has(p_socket));
  363. Client &client = clients[p_socket];
  364. for (KeyValue<uint32_t, WaylandObject> &pair : client.fake_objects) {
  365. WaylandObject &object = pair.value;
  366. if (object.interface == &xdg_toplevel_interface) {
  367. XdgToplevelData *data = (XdgToplevelData *)object.data;
  368. CRASH_COND(data == nullptr);
  369. if (data->wl_subsurface_id != INVALID_ID) {
  370. // wl_subsurface::destroy() - xdg_toplevels are mapped to subsurfaces.
  371. send_wayland_message(compositor_socket, data->wl_subsurface_id, 0, {});
  372. }
  373. if (!data->xdg_surface_handle.get()) {
  374. continue;
  375. }
  376. XdgSurfaceData *xdg_surf_data = (XdgSurfaceData *)data->xdg_surface_handle.get()->data;
  377. if (xdg_surf_data == nullptr) {
  378. continue;
  379. }
  380. if (!data->parent_handle.get()) {
  381. continue;
  382. }
  383. XdgToplevelData *parent_data = (XdgToplevelData *)data->parent_handle.get()->data;
  384. if (parent_data == nullptr) {
  385. continue;
  386. }
  387. if (!parent_data->xdg_surface_handle.get()) {
  388. continue;
  389. }
  390. XdgSurfaceData *parent_xdg_surf_data = (XdgSurfaceData *)parent_data->xdg_surface_handle.get()->data;
  391. if (parent_xdg_surf_data == nullptr) {
  392. continue;
  393. }
  394. for (uint32_t wl_seat_name : wl_seat_names) {
  395. WaylandSeatGlobalData *global_seat_data = (WaylandSeatGlobalData *)registry_globals[wl_seat_name].data;
  396. if (global_seat_data == nullptr) {
  397. continue;
  398. }
  399. if (global_seat_data->focused_surface_id == xdg_surf_data->wl_surface_id) {
  400. seat_name_leave_surface(wl_seat_name, xdg_surf_data->wl_surface_id);
  401. seat_name_enter_surface(wl_seat_name, parent_xdg_surf_data->wl_surface_id);
  402. }
  403. }
  404. }
  405. }
  406. for (List<uint32_t>::Element *E = client.global_id_history.back(); E;) {
  407. uint32_t global_id = E->get();
  408. E = E->prev();
  409. WaylandObject *object = get_object(global_id);
  410. if (object == nullptr) {
  411. DEBUG_LOG_WAYLAND_EMBED(vformat("Skipping deletability check of object g0x%x as it's null.", global_id));
  412. continue;
  413. }
  414. if (object->interface == nullptr) {
  415. DEBUG_LOG_WAYLAND_EMBED(vformat("Skipping deletability check of object g0x%x as it's invalid.", global_id));
  416. continue;
  417. }
  418. DEBUG_LOG_WAYLAND_EMBED(vformat("Checking deletability of %s#g0x%x version %s", object->interface->name, global_id, object->version));
  419. if (object->shared) {
  420. DEBUG_LOG_WAYLAND_EMBED("Shared, skipping.");
  421. continue;
  422. }
  423. if (object->interface == &wl_callback_interface) {
  424. // Those things self-destruct.
  425. DEBUG_LOG_WAYLAND_EMBED("wl_callback self destructs.");
  426. continue;
  427. }
  428. if (object->destroyed) {
  429. DEBUG_LOG_WAYLAND_EMBED("Already destroyed, skipping.");
  430. continue;
  431. }
  432. int destructor = wl_interface_get_destructor_opcode(object->interface, object->version);
  433. if (destructor >= 0) {
  434. DEBUG_LOG_WAYLAND_EMBED(vformat("Destroying %s#g0x%x", object->interface->name, global_id));
  435. if (object->interface == &wl_surface_interface) {
  436. for (uint32_t wl_seat_name : wl_seat_names) {
  437. WaylandSeatGlobalData *global_seat_data = (WaylandSeatGlobalData *)registry_globals[wl_seat_name].data;
  438. if (global_seat_data) {
  439. if (global_seat_data->pointed_surface_id == global_id) {
  440. global_seat_data->pointed_surface_id = INVALID_ID;
  441. }
  442. if (global_seat_data->focused_surface_id == global_id) {
  443. global_seat_data->focused_surface_id = INVALID_ID;
  444. }
  445. }
  446. }
  447. }
  448. send_wayland_message(compositor_socket, global_id, destructor, {});
  449. object->destroyed = true;
  450. if (global_id & 0xff000000) {
  451. delete_object(global_id);
  452. object = nullptr;
  453. }
  454. }
  455. if (object && !object->destroyed) {
  456. ERR_PRINT(vformat("Unreferenced object %s g0x%x (leak!)", object->interface->name, global_id));
  457. }
  458. }
  459. uint32_t eclient_id = client.embedded_client_id;
  460. clients.erase(client.socket);
  461. WaylandObject *eclient = main_client->get_object(eclient_id);
  462. if (eclient) {
  463. EmbeddedClientData *eclient_data = (EmbeddedClientData *)eclient->data;
  464. ERR_FAIL_NULL(eclient_data);
  465. if (!eclient_data->disconnected) {
  466. // godot_embedded_client::disconnected
  467. send_wayland_message(main_client->socket, eclient_id, 0, {});
  468. }
  469. eclient_data->disconnected = true;
  470. }
  471. }
  472. void WaylandEmbedder::socket_error(int p_socket, uint32_t p_object_id, uint32_t p_code, const String &p_message) {
  473. const char *err_name = "unknown";
  474. switch (p_code) {
  475. case WL_DISPLAY_ERROR_INVALID_OBJECT: {
  476. err_name = "invalid_object";
  477. } break;
  478. case WL_DISPLAY_ERROR_INVALID_METHOD: {
  479. err_name = "invalid_method";
  480. } break;
  481. case WL_DISPLAY_ERROR_NO_MEMORY: {
  482. err_name = "no_memory";
  483. } break;
  484. case WL_DISPLAY_ERROR_IMPLEMENTATION: {
  485. err_name = "implementation";
  486. } break;
  487. }
  488. ERR_PRINT(vformat("Socket %d %s error: %s", p_socket, err_name, p_message));
  489. LocalVector<union wl_argument> args;
  490. args.push_back(wl_arg_object(p_object_id));
  491. args.push_back(wl_arg_uint(p_code));
  492. args.push_back(wl_arg_string(vformat("[Godot Embedder] %s", p_message).utf8().get_data()));
  493. send_wayland_event(p_socket, DISPLAY_ID, wl_display_interface, WL_DISPLAY_ERROR, args);
  494. // So, here's the deal: from some extensive research I did, there are
  495. // absolutely zero safeguards for ensuring that the error message ends to the
  496. // client. It's absolutely tiny and takes _nothing_ to get there (less than
  497. // 4µs with a debug build on my machine), but still enough to get truncated in
  498. // the distance between `send_wayland_event` and `close`.
  499. //
  500. // Because of this we're going to give the client some slack: we're going to
  501. // wait for its socket to close (or whatever) or 1s, whichever happens first.
  502. //
  503. // Hopefully it's good enough for <1000 bytes :P
  504. struct pollfd pollfd = {};
  505. pollfd.fd = p_socket;
  506. int ret = poll(&pollfd, 1, 1'000);
  507. if (ret == 0) {
  508. ERR_PRINT("Client timeout while disconnecting.");
  509. }
  510. if (ret < 0) {
  511. ERR_PRINT(vformat("Client error while disconnecting: %s", strerror(errno)));
  512. }
  513. close(p_socket);
  514. }
  515. void WaylandEmbedder::poll_sockets() {
  516. if (poll(pollfds.ptr(), pollfds.size(), -1) == -1) {
  517. CRASH_NOW_MSG(vformat("poll() failed, errno %d.", errno));
  518. }
  519. // First handle everything but the listening socket (which is always the first
  520. // element), so that we can cleanup closed sockets before accidentally reusing
  521. // them (and breaking everything).
  522. for (size_t i = 1; i < pollfds.size(); ++i) {
  523. handle_fd(pollfds[i].fd, pollfds[i].revents);
  524. }
  525. handle_fd(pollfds[0].fd, pollfds[0].revents);
  526. }
  527. Error WaylandEmbedder::send_raw_message(int p_socket, std::initializer_list<struct iovec> p_vecs, const LocalVector<int> &p_fds) {
  528. struct msghdr msg = {};
  529. msg.msg_iov = (struct iovec *)p_vecs.begin();
  530. msg.msg_iovlen = p_vecs.size();
  531. if (!p_fds.is_empty()) {
  532. size_t data_size = p_fds.size() * sizeof(int);
  533. msg.msg_control = Memory::alloc_aligned_static(CMSG_SPACE(data_size), CMSG_ALIGN(1));
  534. msg.msg_controllen = CMSG_SPACE(data_size);
  535. struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
  536. cmsg->cmsg_level = SOL_SOCKET;
  537. cmsg->cmsg_type = SCM_RIGHTS;
  538. cmsg->cmsg_len = CMSG_LEN(data_size);
  539. // NOTE: According to the linux man page cmsg(5), we shall not access the
  540. // pointer returned CMSG_DATA directly, due to alignment concerns. We should
  541. // copy data from a suitably aligned object instead.
  542. memcpy(CMSG_DATA(cmsg), p_fds.ptr(), data_size);
  543. }
  544. #ifdef WAYLAND_EMBED_DEBUG_LOGS_ENABLED
  545. printf("[PROXY] Sending: ");
  546. for (const struct iovec &vec : p_vecs) {
  547. for (size_t i = 0; i < vec.iov_len; ++i) {
  548. printf("%.2x", ((const uint8_t *)vec.iov_base)[i]);
  549. }
  550. }
  551. printf("\n");
  552. #endif
  553. sendmsg(p_socket, &msg, MSG_NOSIGNAL);
  554. if (msg.msg_control) {
  555. Memory::free_aligned_static(msg.msg_control);
  556. }
  557. return OK;
  558. }
  559. Error WaylandEmbedder::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) {
  560. ERR_FAIL_COND_V(p_socket < 0, ERR_INVALID_PARAMETER);
  561. ERR_FAIL_COND_V(p_id == INVALID_ID, ERR_INVALID_PARAMETER);
  562. uint32_t args_size = p_args_words * sizeof *p_args;
  563. // Header is always 8 bytes long.
  564. uint32_t total_size = 8 + (args_size);
  565. uint32_t header[2] = { p_id, (total_size << 16) + p_opcode };
  566. struct iovec vecs[2] = {
  567. { header, 8 },
  568. // According to the sendmsg manual, these buffers should never be written to,
  569. // so this cast should be safe.
  570. { (void *)p_args, args_size },
  571. };
  572. struct msghdr msg = {};
  573. msg.msg_iov = vecs;
  574. msg.msg_iovlen = std_size(vecs);
  575. #ifdef WAYLAND_EMBED_DEBUG_LOGS_ENABLED
  576. printf("[PROXY] Sending: ");
  577. for (struct iovec &vec : vecs) {
  578. for (size_t i = 0; i < vec.iov_len; ++i) {
  579. printf("%.2x", ((const uint8_t *)vec.iov_base)[i]);
  580. }
  581. }
  582. printf("\n");
  583. #endif
  584. if (sendmsg(p_socket, &msg, MSG_NOSIGNAL) < 0) {
  585. return FAILED;
  586. }
  587. return OK;
  588. }
  589. Error WaylandEmbedder::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) {
  590. ERR_FAIL_COND_V(p_direction == ProxyDirection::CLIENT && p_opcode >= (uint32_t)p_interface.event_count, ERR_INVALID_PARAMETER);
  591. ERR_FAIL_COND_V(p_direction == ProxyDirection::COMPOSITOR && p_opcode >= (uint32_t)p_interface.method_count, ERR_INVALID_PARAMETER);
  592. const struct wl_message &msg = p_direction == ProxyDirection::CLIENT ? p_interface.events[p_opcode] : p_interface.methods[p_opcode];
  593. LocalVector<uint32_t> arg_buf;
  594. size_t arg_idx = 0;
  595. for (size_t sig_idx = 0; sig_idx < strlen(msg.signature); ++sig_idx) {
  596. if (arg_idx >= p_args.size()) {
  597. String err_msg = vformat("Not enough arguments for r0x%d %s.%s(%s) (only got %d)", p_id, p_interface.name, msg.name, msg.signature, p_args.size());
  598. ERR_FAIL_COND_V_MSG(arg_idx >= p_args.size(), ERR_INVALID_PARAMETER, err_msg);
  599. }
  600. char sym = msg.signature[sig_idx];
  601. if (sym >= '0' && sym <= '?') {
  602. // We don't care about version notices and nullability symbols. We can skip
  603. // those.
  604. continue;
  605. }
  606. const union wl_argument &arg = p_args[arg_idx];
  607. switch (sym) {
  608. case 'i': {
  609. arg_buf.push_back((uint32_t)arg.i);
  610. } break;
  611. case 'u': {
  612. arg_buf.push_back(arg.u);
  613. } break;
  614. case 'f': {
  615. arg_buf.push_back((uint32_t)arg.f);
  616. } break;
  617. case 'o': {
  618. // We're encoding object arguments as uints because I don't think we can
  619. // reuse the whole opaque struct thing.
  620. arg_buf.push_back(arg.u);
  621. } break;
  622. case 'n': {
  623. arg_buf.push_back(arg.n);
  624. } break;
  625. case 's': {
  626. const char *str = p_args[arg_idx].s;
  627. // Wayland requires the string length to include the null terminator.
  628. uint32_t str_len = strlen(str) + 1;
  629. arg_buf.push_back(str_len);
  630. size_t data_begin_idx = arg_buf.size();
  631. uint32_t str_words = wl_array_word_offset(str_len);
  632. arg_buf.resize(arg_buf.size() + str_words);
  633. strcpy((char *)(arg_buf.ptr() + data_begin_idx), str);
  634. } break;
  635. case 'a': {
  636. const wl_array *arr = p_args[arg_idx].a;
  637. arg_buf.push_back(arr->size);
  638. size_t data_begin_idx = arg_buf.size();
  639. uint32_t words = wl_array_word_offset(arr->size);
  640. arg_buf.resize(arg_buf.size() + words);
  641. memcpy(arg_buf.ptr() + data_begin_idx, arr->data, arr->size);
  642. } break;
  643. // FDs (h) are encoded out-of-band.
  644. }
  645. ++arg_idx;
  646. }
  647. send_wayland_message(p_socket, p_id, p_opcode, arg_buf.ptr(), arg_buf.size());
  648. return OK;
  649. }
  650. uint32_t WaylandEmbedder::new_object(const struct wl_interface *p_interface, int p_version, WaylandObjectData *p_data) {
  651. uint32_t new_global_id = allocate_global_id();
  652. DEBUG_LOG_WAYLAND_EMBED(vformat("New object g0x%x %s", new_global_id, p_interface->name));
  653. WaylandObject *new_object = get_object(new_global_id);
  654. new_object->interface = p_interface;
  655. new_object->version = p_version;
  656. new_object->data = p_data;
  657. return new_global_id;
  658. }
  659. WaylandEmbedder::WaylandObject *WaylandEmbedder::new_server_object(uint32_t p_global_id, const struct wl_interface *p_interface, int p_version, WaylandObjectData *p_data) {
  660. // The max ID will never increment more than one at a time, due to the
  661. // packed nature of IDs. libwayland already does similar assertions so it
  662. // just makes sense to double-check to avoid messing memory up or
  663. // allocating a huge buffer for nothing.
  664. uint32_t stripped_id = p_global_id & ~(0xff000000);
  665. ERR_FAIL_COND_V_MSG(stripped_id > server_objects.size(), nullptr, "Invalid new server id requested.");
  666. ERR_FAIL_COND_V_MSG(get_object(p_global_id) && get_object(p_global_id)->interface, nullptr, vformat("Tried to create %s g0x%x but it already exists as %s.", p_interface->name, p_global_id, get_object(p_global_id)->interface->name));
  667. if (stripped_id == server_objects.size()) {
  668. server_objects.resize(server_objects.size() + 1);
  669. }
  670. DEBUG_LOG_WAYLAND_EMBED(vformat("New server object %s g0x%x", p_interface->name, p_global_id));
  671. WaylandObject *new_object = get_object(p_global_id);
  672. new_object->interface = p_interface;
  673. new_object->version = p_version;
  674. new_object->data = p_data;
  675. return new_object;
  676. }
  677. void WaylandEmbedder::sync() {
  678. CRASH_COND_MSG(sync_callback_id, "Sync already in progress.");
  679. sync_callback_id = allocate_global_id();
  680. get_object(sync_callback_id)->interface = &wl_callback_interface;
  681. get_object(sync_callback_id)->version = 1;
  682. send_wayland_message(compositor_socket, DISPLAY_ID, 0, { sync_callback_id });
  683. DEBUG_LOG_WAYLAND_EMBED("Synchronizing");
  684. while (true) {
  685. poll_sockets();
  686. if (!sync_callback_id) {
  687. // Obj got deleted - sync is done.
  688. return;
  689. }
  690. }
  691. }
  692. // Returns the gid for the newly bound object, or an existing shared object if
  693. // necessary.
  694. uint32_t WaylandEmbedder::wl_registry_bind(uint32_t p_registry_id, uint32_t p_name, int p_version) {
  695. RegistryGlobalInfo &info = registry_globals[p_name];
  696. uint32_t id = INVALID_ID;
  697. if (wl_interface_get_destructor_opcode(info.interface, p_version) < 0) {
  698. DEBUG_LOG_WAYLAND_EMBED(vformat("Binding instanced global %s %d", info.interface->name, p_version));
  699. // Reusable object.
  700. if (info.reusable_objects.has(p_version) && info.reusable_objects[p_version] != INVALID_ID) {
  701. DEBUG_LOG_WAYLAND_EMBED("Already bound.");
  702. return info.reusable_objects[p_version];
  703. }
  704. id = new_object(info.interface, p_version);
  705. ERR_FAIL_COND_V(id == INVALID_ID, INVALID_ID);
  706. info.reusable_objects[p_version] = id;
  707. get_object(id)->shared = true;
  708. } else {
  709. DEBUG_LOG_WAYLAND_EMBED(vformat("Binding global %s as g0x%x version %d", info.interface->name, id, p_version));
  710. id = new_object(info.interface, p_version);
  711. }
  712. ERR_FAIL_COND_V(id == INVALID_ID, INVALID_ID);
  713. registry_globals_names[id] = p_name;
  714. LocalVector<union wl_argument> args;
  715. args.push_back(wl_arg_uint(info.compositor_name));
  716. args.push_back(wl_arg_string(info.interface->name));
  717. args.push_back(wl_arg_int(p_version));
  718. args.push_back(wl_arg_new_id(id));
  719. Error err = send_wayland_method(compositor_socket, p_registry_id, wl_registry_interface, WL_REGISTRY_BIND, args);
  720. ERR_FAIL_COND_V_MSG(err != OK, INVALID_ID, "Error while sending bind request.");
  721. return id;
  722. }
  723. void WaylandEmbedder::seat_name_enter_surface(uint32_t p_seat_name, uint32_t p_wl_surface_id) {
  724. WaylandSurfaceData *surf_data = (WaylandSurfaceData *)get_object(p_wl_surface_id)->data;
  725. CRASH_COND(surf_data == nullptr);
  726. Client *client = surf_data->client;
  727. CRASH_COND(client == nullptr);
  728. if (!client->local_ids.has(p_wl_surface_id)) {
  729. DEBUG_LOG_WAYLAND_EMBED("Called seat_name_enter_surface with an unknown surface");
  730. return;
  731. }
  732. uint32_t local_surface_id = client->get_local_id(p_wl_surface_id);
  733. DEBUG_LOG_WAYLAND_EMBED(vformat("KB: Entering surface g0x%x", p_wl_surface_id));
  734. for (uint32_t local_seat_id : client->registry_globals_instances[p_seat_name]) {
  735. WaylandSeatInstanceData *seat_data = (WaylandSeatInstanceData *)client->get_object(local_seat_id)->data;
  736. CRASH_COND(seat_data == nullptr);
  737. uint32_t local_keyboard_id = client->get_local_id(seat_data->wl_keyboard_id);
  738. if (local_keyboard_id != INVALID_ID) {
  739. // TODO: track keys. Not super important at the time of writing, since we
  740. // don't use that in the engine, although we should.
  741. // wl_keyboard::enter(serial, surface, keys) - keys will be empty for now
  742. send_wayland_message(client->socket, local_keyboard_id, 1, { serial_counter++, local_surface_id, 0 });
  743. }
  744. }
  745. if (client->socket != main_client->socket) {
  746. // godot_embedded_client::window_focus_in
  747. send_wayland_message(main_client->socket, client->embedded_client_id, 2, {});
  748. }
  749. }
  750. void WaylandEmbedder::seat_name_leave_surface(uint32_t p_seat_name, uint32_t p_wl_surface_id) {
  751. WaylandSurfaceData *surf_data = (WaylandSurfaceData *)get_object(p_wl_surface_id)->data;
  752. CRASH_COND(surf_data == nullptr);
  753. Client *client = surf_data->client;
  754. CRASH_COND(client == nullptr);
  755. if (!client->local_ids.has(p_wl_surface_id)) {
  756. DEBUG_LOG_WAYLAND_EMBED("Called seat_name_leave_surface with an unknown surface!");
  757. return;
  758. }
  759. uint32_t local_surface_id = client->get_local_id(p_wl_surface_id);
  760. DEBUG_LOG_WAYLAND_EMBED(vformat("KB: Leaving surface g0x%x", p_wl_surface_id));
  761. for (uint32_t local_seat_id : client->registry_globals_instances[p_seat_name]) {
  762. WaylandSeatInstanceData *seat_data = (WaylandSeatInstanceData *)client->get_object(local_seat_id)->data;
  763. CRASH_COND(seat_data == nullptr);
  764. uint32_t local_keyboard_id = client->get_local_id(seat_data->wl_keyboard_id);
  765. if (local_keyboard_id != INVALID_ID) {
  766. // wl_keyboard::enter(serial, surface, keys) - keys will be empty for now
  767. send_wayland_message(client->socket, local_keyboard_id, 2, { serial_counter++, local_surface_id });
  768. }
  769. }
  770. if (client != main_client) {
  771. // godot_embedded_client::window_focus_out
  772. send_wayland_message(main_client->socket, client->embedded_client_id, 3, {});
  773. }
  774. }
  775. int WaylandEmbedder::allocate_global_id() {
  776. uint32_t id = INVALID_ID;
  777. objects.request(id);
  778. objects[id] = WaylandObject();
  779. DEBUG_LOG_WAYLAND_EMBED(vformat("Allocated new global id g0x%x", id));
  780. #ifdef DEV_ENABLED
  781. if (id > WAYLAND_EMBED_ID_MAX) {
  782. // Oh no. Time for debug info!
  783. #ifdef WAYLAND_EMBED_DEBUG_LOGS_ENABLED
  784. for (uint32_t i = 1; i < objects.reserved_size(); ++i) {
  785. WaylandObject &object = objects[id];
  786. DEBUG_LOG_WAYLAND_EMBED(vformat(" - g0x%x (#%d): %s version %d, data 0x%x", i, i, object.interface->name, object.version, (uintptr_t)object.data));
  787. }
  788. #endif // WAYLAND_EMBED_DEBUG_LOGS_ENABLED
  789. CRASH_NOW_MSG("Max ID reached. This might indicate a leak.");
  790. }
  791. #endif // DEV_ENABLED
  792. return id;
  793. }
  794. bool WaylandEmbedder::global_surface_is_window(uint32_t p_wl_surface_id) {
  795. WaylandObject *surface_object = get_object(p_wl_surface_id);
  796. ERR_FAIL_NULL_V(surface_object, false);
  797. if (surface_object->interface != &wl_surface_interface || surface_object->data == nullptr) {
  798. return false;
  799. }
  800. WaylandSurfaceData *surface_data = (WaylandSurfaceData *)surface_object->data;
  801. if (!surface_data->role_object_handle.get()) {
  802. return false;
  803. }
  804. WaylandObject *role_object = surface_data->role_object_handle.get();
  805. return (role_object && role_object->interface == &xdg_toplevel_interface);
  806. }
  807. bool WaylandEmbedder::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) {
  808. // We allow client-less events.
  809. CRASH_COND(client == nullptr && info->direction == ProxyDirection::COMPOSITOR);
  810. ERR_FAIL_NULL_V(p_object, false);
  811. bool valid = true;
  812. // Let's strip the header.
  813. uint32_t *body = buf + 2;
  814. size_t arg_idx = 0;
  815. size_t buf_idx = 0;
  816. size_t last_str_buf_idx = -1;
  817. uint32_t last_str_len = 0;
  818. for (size_t i = 0; i < strlen(message->signature); ++i) {
  819. ERR_FAIL_COND_V(buf_idx > (info->size / sizeof *body), false);
  820. char sym = message->signature[i];
  821. if (sym >= '0' && sym <= '?') {
  822. // We don't care about version notices and nullability symbols. We can skip
  823. // those.
  824. continue;
  825. }
  826. switch (sym) {
  827. case 'a': {
  828. uint32_t array_len = body[buf_idx];
  829. // We can't obviously go forward by just one byte. Let's skip to the end of
  830. // the array.
  831. buf_idx += wl_array_word_offset(array_len);
  832. } break;
  833. case 's': {
  834. uint32_t string_len = body[buf_idx];
  835. last_str_buf_idx = buf_idx;
  836. last_str_len = string_len;
  837. // Same as the array.
  838. buf_idx += wl_array_word_offset(string_len);
  839. } break;
  840. case 'n': {
  841. uint32_t arg = body[buf_idx];
  842. const struct wl_interface *new_interface = message->types[arg_idx];
  843. uint32_t new_version = p_object->version;
  844. if (!new_interface && last_str_len != 0) {
  845. // When the protocol definition does not define an interface it reports a
  846. // string and an unsigned integer representing the interface and the
  847. // version requested.
  848. new_interface = wl_interface_from_string((char *)(body + last_str_buf_idx + 1), last_str_len);
  849. new_version = body[arg_idx - 1];
  850. }
  851. if (new_interface == nullptr) {
  852. if (last_str_len > 0) {
  853. DEBUG_LOG_WAYLAND_EMBED(vformat("Unknown interface %s, marking packet as invalid.", (char *)(body + last_str_buf_idx + 1)));
  854. } else {
  855. DEBUG_LOG_WAYLAND_EMBED("Unknown interface, marking packet as invalid.");
  856. }
  857. valid = false;
  858. break;
  859. }
  860. if (info->direction == ProxyDirection::COMPOSITOR) {
  861. // FIXME: Create objects only if the packet is valid.
  862. uint32_t new_local_id = arg;
  863. body[buf_idx] = client->new_object(new_local_id, new_interface, new_version);
  864. if (body[buf_idx] == INVALID_ID) {
  865. valid = false;
  866. break;
  867. }
  868. } else if (info->direction == ProxyDirection::CLIENT) {
  869. uint32_t new_global_id = arg;
  870. if (client) {
  871. body[buf_idx] = client->new_server_object(new_global_id, new_interface, new_version);
  872. } else {
  873. new_server_object(new_global_id, new_interface, new_version);
  874. }
  875. if (body[buf_idx] == INVALID_ID) {
  876. valid = false;
  877. break;
  878. }
  879. }
  880. } break;
  881. case 'o': {
  882. if (!client) {
  883. break;
  884. }
  885. uint32_t obj_id = body[buf_idx];
  886. if (obj_id == 0) {
  887. // Object arguments can be nil.
  888. break;
  889. }
  890. if (info->direction == ProxyDirection::CLIENT) {
  891. if (!client->local_ids.has(obj_id)) {
  892. DEBUG_LOG_WAYLAND_EMBED(vformat("Object argument g0x%x not found, marking packet as invalid.", obj_id));
  893. valid = false;
  894. break;
  895. }
  896. body[buf_idx] = instance_id != INVALID_ID ? instance_id : client->get_local_id(obj_id);
  897. } else if (info->direction == ProxyDirection::COMPOSITOR) {
  898. if (!client->global_ids.has(obj_id)) {
  899. DEBUG_LOG_WAYLAND_EMBED(vformat("Object argument l0x%x not found, marking packet as invalid.", obj_id));
  900. valid = false;
  901. break;
  902. }
  903. body[buf_idx] = client->get_global_id(obj_id);
  904. }
  905. } break;
  906. }
  907. ++arg_idx;
  908. ++buf_idx;
  909. }
  910. return valid;
  911. }
  912. WaylandEmbedder::MessageStatus WaylandEmbedder::handle_request(LocalObjectHandle p_object, uint32_t p_opcode, const uint32_t *msg_data, size_t msg_len) {
  913. ERR_FAIL_COND_V(!p_object.is_valid(), MessageStatus::HANDLED);
  914. WaylandObject *object = p_object.get();
  915. Client *client = p_object.get_client();
  916. ERR_FAIL_NULL_V(object, MessageStatus::HANDLED);
  917. // NOTE: Global ID may be null.
  918. uint32_t global_id = p_object.get_global_id();
  919. uint32_t local_id = p_object.get_local_id();
  920. ERR_FAIL_NULL_V(object->interface, MessageStatus::ERROR);
  921. const struct wl_interface *interface = object->interface;
  922. ERR_FAIL_COND_V((int)p_opcode >= interface->method_count, MessageStatus::ERROR);
  923. const struct wl_message message = interface->methods[p_opcode];
  924. DEBUG_LOG_WAYLAND_EMBED(vformat("Client #%d -> %s::%s(%s) l0x%x g0x%x", client->socket, interface->name, message.name, message.signature, local_id, global_id));
  925. const uint32_t *body = msg_data + 2;
  926. if (registry_globals_names.has(global_id)) {
  927. int global_name = registry_globals_names[global_id];
  928. ERR_FAIL_COND_V(!registry_globals.has(global_name), MessageStatus::ERROR);
  929. RegistryGlobalInfo &global_info = registry_globals[global_name];
  930. if (global_info.destroyed) {
  931. DEBUG_LOG_WAYLAND_EMBED("Skipping request for destroyed global object");
  932. return MessageStatus::HANDLED;
  933. }
  934. }
  935. if (object->interface == &wl_display_interface && p_opcode == WL_DISPLAY_GET_REGISTRY) {
  936. // The gist of this is that the registry is a global and the compositor can
  937. // quite simply take for granted that a single client can access any global
  938. // bound from any registry. Let's remove all doubts by using a single
  939. // registry (also for efficiency) and doing fancy remaps.
  940. uint32_t local_registry_id = body[0];
  941. // Note that the registry has already been allocated in the initialization
  942. // routine.
  943. for (KeyValue<uint32_t, RegistryGlobalInfo> &pair : registry_globals) {
  944. uint32_t global_name = pair.key;
  945. RegistryGlobalInfo &global_info = pair.value;
  946. if (global_info.destroyed) {
  947. continue;
  948. }
  949. const struct wl_interface *global_interface = global_info.interface;
  950. if (client != main_client && embedded_interface_deny_list.has(global_interface)) {
  951. DEBUG_LOG_WAYLAND_EMBED(vformat("Skipped global announcement %s for embedded client.", global_interface->name));
  952. continue;
  953. }
  954. LocalVector<union wl_argument> args;
  955. args.push_back(wl_arg_uint(global_name));
  956. args.push_back(wl_arg_string(global_interface->name));
  957. args.push_back(wl_arg_uint(global_info.version));
  958. send_wayland_event(client->socket, local_registry_id, wl_registry_interface, WL_REGISTRY_GLOBAL, args);
  959. }
  960. client->wl_registry_instances.insert(local_registry_id);
  961. client->new_global_instance(local_registry_id, REGISTRY_ID, &wl_registry_interface, 1);
  962. return MessageStatus::HANDLED;
  963. }
  964. if (object->interface == &wl_registry_interface) {
  965. if (p_opcode == WL_REGISTRY_BIND) {
  966. // [Request] wl_registry::bind(usun)
  967. uint32_t global_name = body[0];
  968. uint32_t interface_name_len = body[1];
  969. //const char *interface_name = (const char *)(body + 2);
  970. uint32_t version = body[2 + wl_array_word_offset(interface_name_len)];
  971. uint32_t new_local_id_idx = 2 + wl_array_word_offset(interface_name_len) + 1;
  972. uint32_t new_local_id = body[new_local_id_idx];
  973. if (!registry_globals.has(global_name)) {
  974. socket_error(client->socket, local_id, WL_DISPLAY_ERROR_INVALID_METHOD, vformat("Invalid global object #%d", global_name));
  975. return MessageStatus::HANDLED;
  976. }
  977. RegistryGlobalInfo &global_info = registry_globals[global_name];
  978. ERR_FAIL_NULL_V(global_info.interface, MessageStatus::ERROR);
  979. version = MIN(global_info.version, version);
  980. if (global_info.interface == &godot_embedding_compositor_interface) {
  981. if (!client->registry_globals_instances.has(global_name)) {
  982. client->registry_globals_instances[global_name] = {};
  983. }
  984. client->registry_globals_instances[global_name].insert(new_local_id);
  985. ++global_info.instance_counter;
  986. DEBUG_LOG_WAYLAND_EMBED("Bound embedded compositor interface.");
  987. client->new_fake_object(new_local_id, &godot_embedding_compositor_interface, 1);
  988. return MessageStatus::HANDLED;
  989. }
  990. WaylandObject *instance = nullptr;
  991. client->registry_globals_instances[global_name].insert(new_local_id);
  992. ++global_info.instance_counter;
  993. if (!client->registry_globals_instances.has(global_name)) {
  994. client->registry_globals_instances[global_name] = {};
  995. }
  996. uint32_t bind_gid = wl_registry_bind(REGISTRY_ID, global_name, version);
  997. if (bind_gid == INVALID_ID) {
  998. socket_error(client->socket, local_id, WL_DISPLAY_ERROR_IMPLEMENTATION, "Bind failed.");
  999. return MessageStatus::HANDLED;
  1000. }
  1001. WaylandObject *bind_obj = get_object(bind_gid);
  1002. if (bind_obj == nullptr) {
  1003. socket_error(client->socket, local_id, WL_DISPLAY_ERROR_IMPLEMENTATION, "Bind failed.");
  1004. return MessageStatus::HANDLED;
  1005. }
  1006. if (!bind_obj->shared) {
  1007. client->bind_global_id(bind_gid, new_local_id);
  1008. instance = bind_obj;
  1009. } else {
  1010. instance = client->new_global_instance(new_local_id, global_info.reusable_objects[version], global_info.interface, version);
  1011. DEBUG_LOG_WAYLAND_EMBED(vformat("Instancing global #%d iface %s ver %d new id l0x%x g0x%x", global_name, global_info.interface->name, version, new_local_id, global_info.reusable_objects[version]));
  1012. // Some interfaces report their state as soon as they're bound. Since
  1013. // instances are handled by us, we need to track and report the relevant
  1014. // data ourselves.
  1015. if (global_info.interface == &wl_drm_interface) {
  1016. Error err = client->send_wl_drm_state(new_local_id, (WaylandDrmGlobalData *)global_info.data);
  1017. if (err != OK) {
  1018. return MessageStatus::ERROR;
  1019. }
  1020. } else if (global_info.interface == &wl_shm_interface) {
  1021. WaylandShmGlobalData *global_data = (WaylandShmGlobalData *)global_info.data;
  1022. ERR_FAIL_NULL_V(global_data, MessageStatus::ERROR);
  1023. for (uint32_t format : global_data->formats) {
  1024. send_wayland_message(client->socket, new_local_id, WL_SHM_FORMAT, { format });
  1025. }
  1026. }
  1027. }
  1028. ERR_FAIL_NULL_V(instance, MessageStatus::UNHANDLED);
  1029. if (global_info.interface == &wl_seat_interface) {
  1030. WaylandSeatInstanceData *new_data = memnew(WaylandSeatInstanceData);
  1031. instance->data = new_data;
  1032. }
  1033. return MessageStatus::HANDLED;
  1034. }
  1035. }
  1036. if (object->interface == &wl_compositor_interface && p_opcode == WL_COMPOSITOR_CREATE_SURFACE) {
  1037. uint32_t new_local_id = body[0];
  1038. WaylandSurfaceData *data = memnew(WaylandSurfaceData);
  1039. data->client = client;
  1040. uint32_t new_global_id = client->new_object(new_local_id, &wl_surface_interface, object->version, data);
  1041. ERR_FAIL_COND_V(new_global_id == INVALID_ID, MessageStatus::HANDLED);
  1042. DEBUG_LOG_WAYLAND_EMBED(vformat("Keeping track of surface l0x%x g0x%x.", new_local_id, new_global_id));
  1043. send_wayland_message(compositor_socket, global_id, p_opcode, { new_global_id });
  1044. return MessageStatus::HANDLED;
  1045. }
  1046. if (object->interface == &wl_surface_interface) {
  1047. WaylandSurfaceData *surface_data = (WaylandSurfaceData *)object->data;
  1048. ERR_FAIL_NULL_V(surface_data, MessageStatus::ERROR);
  1049. if (p_opcode == WL_SURFACE_DESTROY) {
  1050. for (uint32_t wl_seat_name : wl_seat_names) {
  1051. WaylandSeatGlobalData *global_seat_data = (WaylandSeatGlobalData *)registry_globals[wl_seat_name].data;
  1052. ERR_FAIL_NULL_V(global_seat_data, MessageStatus::ERROR);
  1053. if (global_seat_data->pointed_surface_id == global_id) {
  1054. global_seat_data->pointed_surface_id = INVALID_ID;
  1055. }
  1056. if (global_seat_data->focused_surface_id == global_id) {
  1057. global_seat_data->focused_surface_id = INVALID_ID;
  1058. }
  1059. }
  1060. } else if (p_opcode == WL_SURFACE_COMMIT) {
  1061. if (surface_data->role_object_handle.is_valid()) {
  1062. WaylandObject *role_object = surface_data->role_object_handle.get();
  1063. if (role_object && role_object->interface) {
  1064. DEBUG_LOG_WAYLAND_EMBED(vformat("!!!!! Committed surface g0x%x with role object %s id l0x%x", global_id, role_object->interface->name, surface_data->role_object_handle.get_local_id()));
  1065. }
  1066. if (role_object && role_object->interface == &xdg_toplevel_interface) {
  1067. XdgToplevelData *toplevel_data = (XdgToplevelData *)role_object->data;
  1068. ERR_FAIL_NULL_V(toplevel_data, MessageStatus::ERROR);
  1069. // xdg shell spec requires clients to first send data and then commit the
  1070. // surface.
  1071. if (toplevel_data->is_embedded() && !toplevel_data->configured) {
  1072. toplevel_data->configured = true;
  1073. // xdg_surface::configure
  1074. send_wayland_message(client->socket, toplevel_data->xdg_surface_handle.get_local_id(), 0, { serial_counter++ });
  1075. }
  1076. }
  1077. }
  1078. send_wayland_message(compositor_socket, global_id, p_opcode, {});
  1079. return MessageStatus::HANDLED;
  1080. }
  1081. }
  1082. if (object->interface == &wl_seat_interface) {
  1083. uint32_t global_seat_name = registry_globals_names[global_id];
  1084. RegistryGlobalInfo &seat_global_info = registry_globals[global_seat_name];
  1085. WaylandSeatGlobalData *global_data = (WaylandSeatGlobalData *)seat_global_info.data;
  1086. ERR_FAIL_NULL_V(global_data, MessageStatus::ERROR);
  1087. WaylandSeatInstanceData *instance_data = (WaylandSeatInstanceData *)object->data;
  1088. ERR_FAIL_NULL_V(instance_data, MessageStatus::ERROR);
  1089. if (p_opcode == WL_SEAT_GET_POINTER) {
  1090. ERR_FAIL_COND_V(global_id == INVALID_ID, MessageStatus::ERROR);
  1091. // [Request] wl_seat::get_pointer(n);
  1092. uint32_t new_local_id = body[0];
  1093. WaylandPointerData *new_data = memnew(WaylandPointerData);
  1094. new_data->wl_seat_id = global_id;
  1095. uint32_t new_global_id = client->new_object(new_local_id, &wl_pointer_interface, object->version, new_data);
  1096. ERR_FAIL_COND_V(new_global_id == INVALID_ID, MessageStatus::HANDLED);
  1097. instance_data->wl_pointer_id = new_global_id;
  1098. send_wayland_message(compositor_socket, global_id, p_opcode, { new_global_id });
  1099. return MessageStatus::HANDLED;
  1100. }
  1101. if (p_opcode == WL_SEAT_GET_KEYBOARD) {
  1102. ERR_FAIL_COND_V(global_id == INVALID_ID, MessageStatus::ERROR);
  1103. // [Request] wl_seat::get_pointer(n);
  1104. uint32_t new_local_id = body[0];
  1105. WaylandKeyboardData *new_data = memnew(WaylandKeyboardData);
  1106. new_data->wl_seat_id = global_id;
  1107. uint32_t new_global_id = client->new_object(new_local_id, &wl_keyboard_interface, object->version, new_data);
  1108. ERR_FAIL_COND_V(new_global_id == INVALID_ID, MessageStatus::HANDLED);
  1109. instance_data->wl_keyboard_id = new_global_id;
  1110. send_wayland_message(compositor_socket, global_id, p_opcode, { new_global_id });
  1111. return MessageStatus::HANDLED;
  1112. }
  1113. }
  1114. if (object->interface == &xdg_wm_base_interface) {
  1115. if (p_opcode == XDG_WM_BASE_CREATE_POSITIONER) {
  1116. uint32_t new_local_id = body[0];
  1117. uint32_t new_global_id = client->new_object(new_local_id, &xdg_positioner_interface, object->version, memnew(XdgPositionerData));
  1118. ERR_FAIL_COND_V(new_global_id == INVALID_ID, MessageStatus::HANDLED);
  1119. send_wayland_message(compositor_socket, global_id, p_opcode, { new_global_id });
  1120. return MessageStatus::HANDLED;
  1121. }
  1122. if (p_opcode == XDG_WM_BASE_GET_XDG_SURFACE) {
  1123. // [Request] xdg_wm_base::get_xdg_surface(no).
  1124. uint32_t new_local_id = body[0];
  1125. uint32_t surface_id = body[1];
  1126. uint32_t global_surface_id = client->get_global_id(surface_id);
  1127. bool fake = (client != main_client);
  1128. XdgSurfaceData *data = memnew(XdgSurfaceData);
  1129. data->wl_surface_id = global_surface_id;
  1130. if (fake) {
  1131. client->new_fake_object(new_local_id, &xdg_surface_interface, object->version, data);
  1132. DEBUG_LOG_WAYLAND_EMBED(vformat("Created fake xdg_surface l0x%x for surface l0x%x", new_local_id, surface_id));
  1133. } else {
  1134. uint32_t new_global_id = client->new_object(new_local_id, &xdg_surface_interface, object->version, data);
  1135. ERR_FAIL_COND_V(new_global_id == INVALID_ID, MessageStatus::HANDLED);
  1136. DEBUG_LOG_WAYLAND_EMBED(vformat("Created real xdg_surface l0x%x g0x%x for surface l0x%x", new_local_id, new_global_id, surface_id));
  1137. send_wayland_message(compositor_socket, global_id, p_opcode, { new_global_id, global_surface_id });
  1138. }
  1139. return MessageStatus::HANDLED;
  1140. }
  1141. }
  1142. if (object->interface == &xdg_surface_interface) {
  1143. XdgSurfaceData *xdg_surf_data = (XdgSurfaceData *)object->data;
  1144. ERR_FAIL_NULL_V(xdg_surf_data, MessageStatus::ERROR);
  1145. WaylandSurfaceData *surface_data = (WaylandSurfaceData *)get_object(xdg_surf_data->wl_surface_id)->data;
  1146. ERR_FAIL_NULL_V(surface_data, MessageStatus::ERROR);
  1147. bool is_embedded = client->fake_objects.has(local_id);
  1148. if (p_opcode == XDG_SURFACE_GET_POPUP) {
  1149. // [Request] xdg_surface::get_popup(no?o).
  1150. uint32_t new_local_id = body[0];
  1151. uint32_t local_parent_id = body[1];
  1152. uint32_t local_positioner_id = body[2];
  1153. surface_data->role_object_handle = LocalObjectHandle(client, new_local_id);
  1154. XdgPopupData *popup_data = memnew(XdgPopupData);
  1155. popup_data->parent_handle = LocalObjectHandle(client, local_parent_id);
  1156. if (!is_embedded) {
  1157. uint32_t new_global_id = client->new_object(new_local_id, &xdg_popup_interface, object->version, popup_data);
  1158. ERR_FAIL_COND_V(new_global_id == INVALID_ID, MessageStatus::HANDLED);
  1159. uint32_t global_parent_id = client->get_global_id(local_parent_id);
  1160. uint32_t global_positioner_id = client->get_global_id(local_positioner_id);
  1161. send_wayland_message(compositor_socket, global_id, p_opcode, { new_global_id, global_parent_id, global_positioner_id });
  1162. return MessageStatus::HANDLED;
  1163. }
  1164. {
  1165. // Popups are real, time to actually instantiate an xdg_surface.
  1166. WaylandObject copy = *object;
  1167. client->fake_objects.erase(local_id);
  1168. global_id = client->new_object(local_id, copy.interface, copy.version, copy.data);
  1169. ERR_FAIL_COND_V(global_id == INVALID_ID, MessageStatus::HANDLED);
  1170. object = get_object(global_id);
  1171. // xdg_wm_base::get_xdg_surface(no);
  1172. send_wayland_message(compositor_socket, xdg_wm_base_id, 2, { global_id, xdg_surf_data->wl_surface_id });
  1173. }
  1174. uint32_t new_global_id = client->new_object(new_local_id, &xdg_popup_interface, object->version, popup_data);
  1175. ERR_FAIL_COND_V(new_global_id == INVALID_ID, MessageStatus::HANDLED);
  1176. uint32_t global_parent_id = INVALID_ID;
  1177. if (local_parent_id != INVALID_ID) {
  1178. XdgSurfaceData *parent_xdg_surf_data = (XdgSurfaceData *)client->get_object(local_parent_id)->data;
  1179. ERR_FAIL_NULL_V(parent_xdg_surf_data, MessageStatus::ERROR);
  1180. WaylandSurfaceData *parent_surface_data = (WaylandSurfaceData *)get_object(parent_xdg_surf_data->wl_surface_id)->data;
  1181. ERR_FAIL_NULL_V(parent_surface_data, MessageStatus::ERROR);
  1182. WaylandObject *parent_role_obj = parent_surface_data->role_object_handle.get();
  1183. ERR_FAIL_NULL_V(parent_role_obj, MessageStatus::ERROR);
  1184. XdgPositionerData *pos_data = (XdgPositionerData *)client->get_object(local_positioner_id)->data;
  1185. ERR_FAIL_NULL_V(pos_data, MessageStatus::ERROR);
  1186. if (parent_role_obj->interface == &xdg_toplevel_interface) {
  1187. XdgToplevelData *parent_toplevel_data = (XdgToplevelData *)parent_role_obj->data;
  1188. ERR_FAIL_NULL_V(parent_toplevel_data, MessageStatus::ERROR);
  1189. if (parent_toplevel_data->is_embedded()) {
  1190. // Embedded windows are subsurfaces of a parent window. We need to
  1191. // "redirect" the popup request on the parent window and adjust the
  1192. // positioner properly if needed.
  1193. XdgToplevelData *main_parent_toplevel_data = (XdgToplevelData *)parent_toplevel_data->parent_handle.get()->data;
  1194. ERR_FAIL_NULL_V(main_parent_toplevel_data, MessageStatus::ERROR);
  1195. global_parent_id = main_parent_toplevel_data->xdg_surface_handle.get_global_id();
  1196. WaylandSubsurfaceData *subsurf_data = (WaylandSubsurfaceData *)get_object(parent_toplevel_data->wl_subsurface_id)->data;
  1197. ERR_FAIL_NULL_V(subsurf_data, MessageStatus::ERROR);
  1198. Point2i adj_pos = subsurf_data->position + pos_data->anchor_rect.position;
  1199. // xdg_positioner::set_anchor_rect
  1200. send_wayland_message(compositor_socket, client->get_global_id(local_positioner_id), 2, { (uint32_t)adj_pos.x, (uint32_t)adj_pos.y, (uint32_t)pos_data->anchor_rect.size.width, (uint32_t)pos_data->anchor_rect.size.height });
  1201. }
  1202. } else {
  1203. global_parent_id = client->get_global_id(local_parent_id);
  1204. }
  1205. }
  1206. send_wayland_message(compositor_socket, global_id, p_opcode, { new_global_id, global_parent_id, client->get_global_id(local_positioner_id) });
  1207. return MessageStatus::HANDLED;
  1208. }
  1209. if (p_opcode == XDG_SURFACE_GET_TOPLEVEL) {
  1210. // [Request] xdg_surface::get_toplevel(n).
  1211. uint32_t new_local_id = body[0];
  1212. surface_data->role_object_handle = LocalObjectHandle(client, new_local_id);
  1213. XdgToplevelData *data = memnew(XdgToplevelData);
  1214. data->xdg_surface_handle = LocalObjectHandle(client, local_id);
  1215. if (is_embedded) {
  1216. client->new_fake_object(new_local_id, &xdg_toplevel_interface, object->version, data);
  1217. client->embedded_window_id = new_local_id;
  1218. // godot_embedded_client::window_embedded()
  1219. send_wayland_message(main_client->socket, client->embedded_client_id, 1, {});
  1220. } else {
  1221. uint32_t new_global_id = client->new_object(new_local_id, &xdg_toplevel_interface, object->version, data);
  1222. ERR_FAIL_COND_V(new_global_id == INVALID_ID, MessageStatus::HANDLED);
  1223. if (main_toplevel_id == 0) {
  1224. main_toplevel_id = new_global_id;
  1225. DEBUG_LOG_WAYLAND_EMBED(vformat("main toplevel set to gx0%x.", main_toplevel_id));
  1226. }
  1227. send_wayland_message(compositor_socket, global_id, p_opcode, { new_global_id });
  1228. }
  1229. return MessageStatus::HANDLED;
  1230. }
  1231. }
  1232. if (object->interface == &xdg_positioner_interface) {
  1233. XdgPositionerData *pos_data = (XdgPositionerData *)object->data;
  1234. ERR_FAIL_NULL_V(pos_data, MessageStatus::ERROR);
  1235. if (p_opcode == XDG_POSITIONER_SET_ANCHOR_RECT) {
  1236. // Args: int x, int y, int width, int height.
  1237. pos_data->anchor_rect = Rect2i(body[0], body[1], body[2], body[3]);
  1238. send_wayland_message(compositor_socket, global_id, p_opcode, { body[0], body[1], body[2], body[3] });
  1239. return MessageStatus::HANDLED;
  1240. }
  1241. }
  1242. if (object->interface == &xdg_toplevel_interface && p_opcode == XDG_TOPLEVEL_DESTROY) {
  1243. if (client->fake_objects.has(local_id)) {
  1244. XdgToplevelData *data = (XdgToplevelData *)object->data;
  1245. ERR_FAIL_NULL_V(data, MessageStatus::ERROR);
  1246. XdgSurfaceData *xdg_surf_data = nullptr;
  1247. if (data->xdg_surface_handle.is_valid()) {
  1248. xdg_surf_data = (XdgSurfaceData *)data->xdg_surface_handle.get()->data;
  1249. ERR_FAIL_NULL_V(xdg_surf_data, MessageStatus::ERROR);
  1250. }
  1251. ERR_FAIL_NULL_V(xdg_surf_data, MessageStatus::ERROR);
  1252. XdgSurfaceData *parent_xdg_surf_data = nullptr;
  1253. {
  1254. XdgToplevelData *parent_data = nullptr;
  1255. if (data->parent_handle.get()) {
  1256. parent_data = (XdgToplevelData *)data->parent_handle.get()->data;
  1257. ERR_FAIL_NULL_V(parent_data, MessageStatus::ERROR);
  1258. }
  1259. if (parent_data && parent_data->xdg_surface_handle.get()) {
  1260. parent_xdg_surf_data = (XdgSurfaceData *)parent_data->xdg_surface_handle.get()->data;
  1261. ERR_FAIL_NULL_V(parent_xdg_surf_data, MessageStatus::ERROR);
  1262. }
  1263. }
  1264. for (uint32_t wl_seat_name : wl_seat_names) {
  1265. WaylandSeatGlobalData *global_seat_data = (WaylandSeatGlobalData *)registry_globals[wl_seat_name].data;
  1266. ERR_FAIL_NULL_V(global_seat_data, MessageStatus::ERROR);
  1267. if (global_seat_data->focused_surface_id == xdg_surf_data->wl_surface_id) {
  1268. if (xdg_surf_data) {
  1269. seat_name_leave_surface(wl_seat_name, xdg_surf_data->wl_surface_id);
  1270. }
  1271. if (parent_xdg_surf_data) {
  1272. seat_name_enter_surface(wl_seat_name, parent_xdg_surf_data->wl_surface_id);
  1273. }
  1274. }
  1275. }
  1276. // wl_display::delete_id
  1277. send_wayland_message(client->socket, local_id, p_opcode, {});
  1278. if (local_id == client->embedded_window_id) {
  1279. client->embedded_window_id = 0;
  1280. }
  1281. if (data->wl_subsurface_id != INVALID_ID) {
  1282. send_wayland_message(compositor_socket, data->wl_subsurface_id, WL_SUBSURFACE_DESTROY, {});
  1283. }
  1284. client->delete_object(local_id);
  1285. return MessageStatus::HANDLED;
  1286. }
  1287. }
  1288. if (interface == &zwp_pointer_constraints_v1_interface) {
  1289. // FIXME: This implementation leaves no way of unlocking the pointer when
  1290. // embedded into the main window. We might need to be a bit more invasive.
  1291. if (p_opcode == ZWP_POINTER_CONSTRAINTS_V1_LOCK_POINTER) {
  1292. // [Request] zwp_pointer_constraints_v1::lock_pointer(nooou).
  1293. uint32_t new_local_id = body[0];
  1294. uint32_t local_surface_id = body[1];
  1295. uint32_t local_pointer_id = body[2];
  1296. uint32_t lifetime = body[4];
  1297. WaylandSurfaceData *surf_data = (WaylandSurfaceData *)client->get_object(local_surface_id)->data;
  1298. ERR_FAIL_NULL_V(surf_data, MessageStatus::ERROR);
  1299. WaylandObject *role_obj = surf_data->role_object_handle.get();
  1300. ERR_FAIL_NULL_V(role_obj, MessageStatus::ERROR);
  1301. if (role_obj->interface == &xdg_toplevel_interface) {
  1302. XdgToplevelData *toplevel_data = (XdgToplevelData *)role_obj->data;
  1303. ERR_FAIL_NULL_V(toplevel_data, MessageStatus::ERROR);
  1304. if (!toplevel_data->is_embedded()) {
  1305. // Passthrough.
  1306. return MessageStatus::UNHANDLED;
  1307. }
  1308. // Subsurfaces don't normally work, at least on sway, as the locking
  1309. // condition might rely on focus, which they don't get. We can remap them to
  1310. // the parent surface and set a region though.
  1311. XdgToplevelData *parent_data = (XdgToplevelData *)toplevel_data->parent_handle.get()->data;
  1312. ERR_FAIL_NULL_V(parent_data, MessageStatus::ERROR);
  1313. XdgSurfaceData *parent_xdg_surf_data = (XdgSurfaceData *)parent_data->xdg_surface_handle.get()->data;
  1314. ERR_FAIL_NULL_V(parent_xdg_surf_data, MessageStatus::ERROR);
  1315. WaylandSubsurfaceData *subsurf_data = (WaylandSubsurfaceData *)get_object(toplevel_data->wl_subsurface_id)->data;
  1316. ERR_FAIL_NULL_V(subsurf_data, MessageStatus::ERROR);
  1317. uint32_t new_global_id = client->new_object(new_local_id, &zwp_locked_pointer_v1_interface, object->version);
  1318. ERR_FAIL_COND_V(new_global_id == INVALID_ID, MessageStatus::HANDLED);
  1319. uint32_t x = subsurf_data->position.x;
  1320. uint32_t y = subsurf_data->position.y;
  1321. uint32_t width = toplevel_data->size.width;
  1322. uint32_t height = toplevel_data->size.height;
  1323. // NOTE: At least on sway I can't seem to be able to get this region
  1324. // working but the calls check out.
  1325. DEBUG_LOG_WAYLAND_EMBED(vformat("Creating custom region x%d y%d w%d h%d", x, y, width, height));
  1326. uint32_t new_region_id = allocate_global_id();
  1327. get_object(new_region_id)->interface = &wl_region_interface;
  1328. get_object(new_region_id)->version = get_object(wl_compositor_id)->version;
  1329. // wl_compostor::create_region(n).
  1330. send_wayland_message(compositor_socket, wl_compositor_id, 1, { new_region_id });
  1331. // wl_region::add(iiii).
  1332. send_wayland_message(compositor_socket, new_region_id, 1, { x, y, width, height });
  1333. send_wayland_message(compositor_socket, global_id, p_opcode, { new_global_id, parent_xdg_surf_data->wl_surface_id, client->get_global_id(local_pointer_id), new_region_id, lifetime });
  1334. // wl_region::destroy().
  1335. send_wayland_message(compositor_socket, new_region_id, 0, {});
  1336. return MessageStatus::HANDLED;
  1337. }
  1338. }
  1339. }
  1340. if (interface == &godot_embedded_client_interface) {
  1341. EmbeddedClientData *eclient_data = (EmbeddedClientData *)object->data;
  1342. ERR_FAIL_NULL_V(eclient_data, MessageStatus::ERROR);
  1343. Client *eclient = eclient_data->client;
  1344. ERR_FAIL_NULL_V(eclient, MessageStatus::ERROR);
  1345. if (p_opcode == GODOT_EMBEDDED_CLIENT_DESTROY) {
  1346. if (!eclient_data->disconnected) {
  1347. close(eclient->socket);
  1348. }
  1349. client->delete_object(local_id);
  1350. return MessageStatus::HANDLED;
  1351. }
  1352. if (eclient_data->disconnected) {
  1353. // Object is inert.
  1354. return MessageStatus::HANDLED;
  1355. }
  1356. ERR_FAIL_COND_V(eclient->embedded_window_id == 0, MessageStatus::ERROR);
  1357. XdgToplevelData *toplevel_data = (XdgToplevelData *)eclient->get_object(eclient->embedded_window_id)->data;
  1358. ERR_FAIL_NULL_V(toplevel_data, MessageStatus::ERROR);
  1359. if (p_opcode == GODOT_EMBEDDED_CLIENT_SET_EMBEDDED_WINDOW_RECT && toplevel_data->wl_subsurface_id != INVALID_ID) {
  1360. uint32_t x = body[0];
  1361. uint32_t y = body[1];
  1362. uint32_t width = body[2];
  1363. uint32_t height = body[3];
  1364. WaylandSubsurfaceData *subsurf_data = (WaylandSubsurfaceData *)get_object(toplevel_data->wl_subsurface_id)->data;
  1365. ERR_FAIL_NULL_V(subsurf_data, MessageStatus::ERROR);
  1366. toplevel_data->size.width = width;
  1367. toplevel_data->size.height = height;
  1368. subsurf_data->position.x = x;
  1369. subsurf_data->position.y = y;
  1370. // wl_subsurface::set_position
  1371. send_wayland_message(compositor_socket, toplevel_data->wl_subsurface_id, 1, { x, y });
  1372. // xdg_toplevel::configure
  1373. send_wayland_message(eclient->socket, eclient->embedded_window_id, 0, { width, height, 0 });
  1374. // xdg_surface::configure
  1375. send_wayland_message(eclient->socket, toplevel_data->xdg_surface_handle.get_local_id(), 0, { configure_serial_counter++ });
  1376. return MessageStatus::HANDLED;
  1377. } else if (p_opcode == GODOT_EMBEDDED_CLIENT_SET_EMBEDDED_WINDOW_PARENT) {
  1378. uint32_t main_client_parent_id = body[0];
  1379. if (toplevel_data->parent_handle.get_local_id() == main_client_parent_id) {
  1380. return MessageStatus::HANDLED;
  1381. }
  1382. if (main_client_parent_id == INVALID_ID && toplevel_data->wl_subsurface_id != INVALID_ID) {
  1383. // Window hiding logic.
  1384. // wl_subsurface::destroy()
  1385. send_wayland_message(compositor_socket, toplevel_data->wl_subsurface_id, 0, {});
  1386. toplevel_data->parent_handle.invalidate();
  1387. toplevel_data->wl_subsurface_id = INVALID_ID;
  1388. return MessageStatus::HANDLED;
  1389. }
  1390. XdgToplevelData *parent_toplevel_data = (XdgToplevelData *)client->get_object(main_client_parent_id)->data;
  1391. ERR_FAIL_NULL_V(parent_toplevel_data, MessageStatus::ERROR);
  1392. XdgSurfaceData *parent_xdg_surf_data = (XdgSurfaceData *)parent_toplevel_data->xdg_surface_handle.get()->data;
  1393. ERR_FAIL_NULL_V(parent_xdg_surf_data, MessageStatus::ERROR);
  1394. XdgSurfaceData *xdg_surf_data = (XdgSurfaceData *)toplevel_data->xdg_surface_handle.get()->data;
  1395. ERR_FAIL_NULL_V(xdg_surf_data, MessageStatus::ERROR);
  1396. if (toplevel_data->wl_subsurface_id != INVALID_ID) {
  1397. // wl_subsurface::destroy()
  1398. send_wayland_message(compositor_socket, toplevel_data->wl_subsurface_id, 0, {});
  1399. }
  1400. uint32_t new_sub_id = allocate_global_id();
  1401. WaylandObject *new_sub_object = get_object(new_sub_id);
  1402. new_sub_object->interface = &wl_subsurface_interface;
  1403. new_sub_object->data = memnew(WaylandSubsurfaceData);
  1404. new_sub_object->version = get_object(wl_subcompositor_id)->version;
  1405. toplevel_data->wl_subsurface_id = new_sub_id;
  1406. toplevel_data->parent_handle = LocalObjectHandle(main_client, main_client_parent_id);
  1407. DEBUG_LOG_WAYLAND_EMBED(vformat("Binding subsurface g0x%x.", new_sub_id));
  1408. // wl_subcompositor::get_subsurface
  1409. send_wayland_message(compositor_socket, wl_subcompositor_id, 1, { new_sub_id, xdg_surf_data->wl_surface_id, parent_xdg_surf_data->wl_surface_id });
  1410. // wl_subsurface::set_desync
  1411. send_wayland_message(compositor_socket, new_sub_id, 5, {});
  1412. return MessageStatus::HANDLED;
  1413. } else if (p_opcode == GODOT_EMBEDDED_CLIENT_FOCUS_WINDOW) {
  1414. XdgSurfaceData *xdg_surf_data = (XdgSurfaceData *)toplevel_data->xdg_surface_handle.get()->data;
  1415. ERR_FAIL_NULL_V(xdg_surf_data, MessageStatus::ERROR);
  1416. for (uint32_t wl_seat_name : wl_seat_names) {
  1417. RegistryGlobalInfo &global_seat_info = registry_globals[wl_seat_name];
  1418. WaylandSeatGlobalData *global_seat_data = (WaylandSeatGlobalData *)global_seat_info.data;
  1419. if (global_seat_data->focused_surface_id != INVALID_ID) {
  1420. seat_name_leave_surface(wl_seat_name, global_seat_data->focused_surface_id);
  1421. }
  1422. global_seat_data->focused_surface_id = xdg_surf_data->wl_surface_id;
  1423. seat_name_enter_surface(wl_seat_name, xdg_surf_data->wl_surface_id);
  1424. }
  1425. } else if (p_opcode == GODOT_EMBEDDED_CLIENT_EMBEDDED_WINDOW_REQUEST_CLOSE) {
  1426. // xdg_toplevel::close
  1427. send_wayland_message(eclient->socket, eclient->embedded_window_id, 1, {});
  1428. return MessageStatus::HANDLED;
  1429. }
  1430. }
  1431. // Server-allocated objects are a bit annoying to handle for us. Right now we
  1432. // use a heuristic. See: https://ppaalanen.blogspot.com/2014/07/wayland-protocol-design-object-lifespan.html
  1433. if (strcmp(message.name, "destroy") == 0 || strcmp(message.name, "release") == 0) {
  1434. if (object->shared) {
  1435. // We must not delete shared objects.
  1436. client->delete_object(local_id);
  1437. return MessageStatus::HANDLED;
  1438. }
  1439. if (global_id != INVALID_ID) {
  1440. send_wayland_message(compositor_socket, global_id, p_opcode, {});
  1441. object->destroyed = true;
  1442. }
  1443. if (local_id & 0xff000000) {
  1444. DEBUG_LOG_WAYLAND_EMBED(vformat("!!!!!! Deallocating server object l0x%x", local_id));
  1445. client->delete_object(local_id);
  1446. }
  1447. return MessageStatus::HANDLED;
  1448. }
  1449. if (client->fake_objects.has(local_id)) {
  1450. // Object is fake, we're done.
  1451. DEBUG_LOG_WAYLAND_EMBED("Dropping unhandled request for fake object.");
  1452. return MessageStatus::HANDLED;
  1453. }
  1454. if (global_id == INVALID_ID) {
  1455. DEBUG_LOG_WAYLAND_EMBED("Dropping request with invalid global object id");
  1456. return MessageStatus::HANDLED;
  1457. }
  1458. return MessageStatus::UNHANDLED;
  1459. }
  1460. WaylandEmbedder::MessageStatus WaylandEmbedder::handle_event(uint32_t p_global_id, LocalObjectHandle p_local_handle, uint32_t p_opcode, const uint32_t *msg_data, size_t msg_len) {
  1461. WaylandObject *global_object = get_object(p_global_id);
  1462. ERR_FAIL_NULL_V_MSG(global_object, MessageStatus::ERROR, "Compositor messages must always have a global object.");
  1463. #ifdef WAYLAND_EMBED_DEBUG_LOGS_ENABLED
  1464. ERR_FAIL_NULL_V(global_object->interface, MessageStatus::ERROR);
  1465. const struct wl_interface *interface = global_object->interface;
  1466. ERR_FAIL_COND_V((int)p_opcode >= interface->event_count, MessageStatus::ERROR);
  1467. const struct wl_message message = interface->events[p_opcode];
  1468. if (p_local_handle.is_valid()) {
  1469. int socket = p_local_handle.get_client()->socket;
  1470. DEBUG_LOG_WAYLAND_EMBED(vformat("Client #%d <- %s::%s(%s) g0x%x", socket, interface->name, message.name, message.signature, p_global_id));
  1471. } else {
  1472. DEBUG_LOG_WAYLAND_EMBED(vformat("Client N/A <- %s::%s(%s) g0x%x", interface->name, message.name, message.signature, p_global_id));
  1473. }
  1474. #endif //WAYLAND_EMBED_DEBUG_LOGS_ENABLED
  1475. const uint32_t *body = msg_data + 2;
  1476. //size_t body_len = msg_len - (WL_WORD_SIZE * 2);
  1477. // FIXME: Make sure that it makes sense to track this protocol. Not only is it
  1478. // old and getting deprecated, but I can't even get this code branch to hit
  1479. // probably because, at the time of writing, we only get the "main" display
  1480. // through the proxy.
  1481. if (global_object->interface == &wl_drm_interface) {
  1482. // wl_drm can't ever be destroyed, so we need to track its state as it's going
  1483. // to be instanced at least few times.
  1484. uint32_t global_name = registry_globals_names[p_global_id];
  1485. WaylandDrmGlobalData *global_data = (WaylandDrmGlobalData *)registry_globals[global_name].data;
  1486. ERR_FAIL_NULL_V(global_data, MessageStatus::ERROR);
  1487. if (p_opcode == WL_DRM_DEVICE) {
  1488. // signature: s
  1489. uint32_t name_len = body[0];
  1490. uint8_t *name = (uint8_t *)(body + 1);
  1491. global_data->device = String::utf8((const char *)name, name_len);
  1492. return MessageStatus::UNHANDLED;
  1493. }
  1494. if (p_opcode == WL_DRM_FORMAT) {
  1495. // signature: u
  1496. uint32_t format = body[0];
  1497. global_data->formats.push_back(format);
  1498. return MessageStatus::UNHANDLED;
  1499. }
  1500. if (p_opcode == WL_DRM_AUTHENTICATED) {
  1501. // signature: N/A
  1502. global_data->authenticated = true;
  1503. return MessageStatus::UNHANDLED;
  1504. }
  1505. if (p_opcode == WL_DRM_CAPABILITIES) {
  1506. // signature: u
  1507. uint32_t capabilities = body[0];
  1508. global_data->capabilities = capabilities;
  1509. }
  1510. return MessageStatus::UNHANDLED;
  1511. }
  1512. if (global_object->interface == &wl_shm_interface) {
  1513. uint32_t global_name = registry_globals_names[p_global_id];
  1514. WaylandShmGlobalData *global_data = (WaylandShmGlobalData *)registry_globals[global_name].data;
  1515. ERR_FAIL_NULL_V(global_data, MessageStatus::ERROR);
  1516. if (p_opcode == WL_SHM_FORMAT) {
  1517. // Signature: u
  1518. uint32_t format = body[0];
  1519. global_data->formats.push_back(format);
  1520. }
  1521. }
  1522. if (!p_local_handle.is_valid()) {
  1523. // Some requests might not have a valid local object handle for various
  1524. // reasons, such as when certain events are directed to this proxy or when the
  1525. // destination client of a message disconnected in the meantime.
  1526. if (global_object->interface == &wl_display_interface) {
  1527. if (p_opcode == WL_DISPLAY_DELETE_ID) {
  1528. // [Event] wl_display::delete_id(u)
  1529. uint32_t global_delete_id = body[0];
  1530. DEBUG_LOG_WAYLAND_EMBED(vformat("Compositor requested deletion of g0x%x (no client)", global_delete_id));
  1531. delete_object(global_delete_id);
  1532. return MessageStatus::HANDLED;
  1533. } else if (p_opcode == WL_DISPLAY_ERROR) {
  1534. // [Event] wl_display::error(ous)
  1535. uint32_t obj_id = body[0];
  1536. uint32_t err_code = body[1];
  1537. CRASH_NOW_MSG(vformat("Error obj g0x%x code %d: %s", obj_id, err_code, (const char *)(body + 3)));
  1538. }
  1539. }
  1540. if (global_object->interface == &wl_callback_interface && p_opcode == WL_CALLBACK_DONE) {
  1541. if (sync_callback_id != INVALID_ID && p_global_id == sync_callback_id) {
  1542. sync_callback_id = 0;
  1543. DEBUG_LOG_WAYLAND_EMBED("Sync response received");
  1544. return MessageStatus::HANDLED;
  1545. }
  1546. }
  1547. if (global_object->interface == &wl_registry_interface) {
  1548. if (p_opcode == WL_REGISTRY_GLOBAL) {
  1549. // [Event] wl_registry::global(usu).
  1550. uint32_t global_name = body[0];
  1551. uint32_t interface_name_len = body[1];
  1552. const char *interface_name = (const char *)(body + 2);
  1553. uint32_t global_version = body[2 + wl_array_word_offset(interface_name_len)];
  1554. DEBUG_LOG_WAYLAND_EMBED("Global c#%d %s %d", global_name, interface_name, global_version);
  1555. const struct wl_interface *global_interface = wl_interface_from_string(interface_name, interface_name_len);
  1556. if (global_interface) {
  1557. RegistryGlobalInfo global_info = {};
  1558. global_info.interface = global_interface;
  1559. global_info.version = MIN(global_version, (uint32_t)global_interface->version);
  1560. DEBUG_LOG_WAYLAND_EMBED("Clamped global %s to version %d.", interface_name, global_info.version);
  1561. global_info.compositor_name = global_name;
  1562. int new_global_name = registry_globals_counter++;
  1563. if (global_info.interface == &wl_shm_interface) {
  1564. DEBUG_LOG_WAYLAND_EMBED("Allocating global wl_shm data.");
  1565. global_info.data = memnew(WaylandShmGlobalData);
  1566. }
  1567. if (global_info.interface == &wl_seat_interface) {
  1568. DEBUG_LOG_WAYLAND_EMBED("Allocating global wl_seat data.");
  1569. global_info.data = memnew(WaylandSeatGlobalData);
  1570. wl_seat_names.push_back(new_global_name);
  1571. }
  1572. if (global_info.interface == &wl_drm_interface) {
  1573. DEBUG_LOG_WAYLAND_EMBED("Allocating global wl_drm data.");
  1574. global_info.data = memnew(WaylandDrmGlobalData);
  1575. }
  1576. registry_globals[new_global_name] = global_info;
  1577. // We need some interfaces directly. It's better to bind a "copy" ourselves
  1578. // than to wait for the client to ask one.
  1579. if (global_interface == &xdg_wm_base_interface && xdg_wm_base_id == 0) {
  1580. xdg_wm_base_id = wl_registry_bind(p_global_id, new_global_name, global_info.version);
  1581. ERR_FAIL_COND_V(xdg_wm_base_id == INVALID_ID, MessageStatus::ERROR);
  1582. } else if (global_interface == &wl_compositor_interface && wl_compositor_id == 0) {
  1583. wl_compositor_id = wl_registry_bind(p_global_id, new_global_name, global_info.version);
  1584. ERR_FAIL_COND_V(wl_compositor_id == INVALID_ID, MessageStatus::ERROR);
  1585. } else if (global_interface == &wl_subcompositor_interface && wl_subcompositor_id == 0) {
  1586. wl_subcompositor_id = wl_registry_bind(p_global_id, new_global_name, global_info.version);
  1587. ERR_FAIL_COND_V(wl_subcompositor_id == INVALID_ID, MessageStatus::ERROR);
  1588. }
  1589. DEBUG_LOG_WAYLAND_EMBED(vformat("Local registry object name: l#%d", new_global_name));
  1590. if (clients.is_empty()) {
  1591. // Let's not waste time.
  1592. return MessageStatus::HANDLED;
  1593. }
  1594. // Notify all clients.
  1595. LocalVector<wl_argument> args;
  1596. args.push_back(wl_arg_uint(new_global_name));
  1597. args.push_back(wl_arg_string(interface_name));
  1598. args.push_back(wl_arg_uint(global_info.version));
  1599. for (KeyValue<int, Client> &pair : clients) {
  1600. Client &client = pair.value;
  1601. for (uint32_t local_registry_id : client.wl_registry_instances) {
  1602. send_wayland_event(client.socket, local_registry_id, wl_registry_interface, WL_REGISTRY_GLOBAL, args);
  1603. }
  1604. }
  1605. return MessageStatus::HANDLED;
  1606. } else {
  1607. DEBUG_LOG_WAYLAND_EMBED("Skipping unknown global %s version %d.", interface_name, global_version);
  1608. return MessageStatus::HANDLED;
  1609. }
  1610. } else if (p_opcode == WL_REGISTRY_GLOBAL_REMOVE) {
  1611. uint32_t compositor_name = body[0];
  1612. uint32_t local_name = 0;
  1613. RegistryGlobalInfo *global_info = nullptr;
  1614. // FIXME: Use a map or something.
  1615. for (KeyValue<uint32_t, RegistryGlobalInfo> &pair : registry_globals) {
  1616. uint32_t name = pair.key;
  1617. RegistryGlobalInfo &info = pair.value;
  1618. if (info.compositor_name == compositor_name) {
  1619. local_name = name;
  1620. global_info = &info;
  1621. break;
  1622. }
  1623. }
  1624. ERR_FAIL_NULL_V(global_info, MessageStatus::ERROR);
  1625. if (global_info->instance_counter == 0) {
  1626. memdelete(global_info->data);
  1627. registry_globals.erase(local_name);
  1628. } else {
  1629. global_info->destroyed = true;
  1630. }
  1631. // Notify all clients.
  1632. LocalVector<wl_argument> args;
  1633. args.push_back(wl_arg_uint(local_name));
  1634. for (KeyValue<int, Client> &pair : clients) {
  1635. Client &client = pair.value;
  1636. for (uint32_t local_registry_id : client.wl_registry_instances) {
  1637. send_wayland_event(client.socket, local_registry_id, wl_registry_interface, WL_REGISTRY_GLOBAL_REMOVE, args);
  1638. }
  1639. }
  1640. return MessageStatus::HANDLED;
  1641. }
  1642. }
  1643. DEBUG_LOG_WAYLAND_EMBED("No valid local object handle, falling back to generic handler.");
  1644. return MessageStatus::UNHANDLED;
  1645. }
  1646. Client *client = p_local_handle.get_client();
  1647. ERR_FAIL_NULL_V(client, MessageStatus::ERROR);
  1648. WaylandObject *object = p_local_handle.get();
  1649. uint32_t local_id = p_local_handle.get_local_id();
  1650. if (global_object->interface == &wl_display_interface) {
  1651. if (p_opcode == WL_DISPLAY_DELETE_ID) {
  1652. // [Event] wl_display::delete_id(u)
  1653. uint32_t global_delete_id = body[0];
  1654. uint32_t local_delete_id = client->get_local_id(global_delete_id);
  1655. DEBUG_LOG_WAYLAND_EMBED(vformat("Compositor requested delete of g0x%x l0x%x", global_delete_id, local_delete_id));
  1656. if (local_delete_id == INVALID_ID) {
  1657. // No idea what this object is, might be of the other client. This
  1658. // definitely does not make sense to us, so we're done.
  1659. return MessageStatus::INVALID;
  1660. }
  1661. client->delete_object(local_delete_id);
  1662. send_wayland_message(client->socket, DISPLAY_ID, WL_DISPLAY_DELETE_ID, { local_delete_id });
  1663. return MessageStatus::HANDLED;
  1664. }
  1665. return MessageStatus::UNHANDLED;
  1666. }
  1667. if (object->interface == &wl_keyboard_interface) {
  1668. WaylandKeyboardData *data = (WaylandKeyboardData *)object->data;
  1669. ERR_FAIL_NULL_V(data, MessageStatus::ERROR);
  1670. uint32_t global_seat_name = registry_globals_names[data->wl_seat_id];
  1671. RegistryGlobalInfo &global_seat_info = registry_globals[global_seat_name];
  1672. WaylandSeatGlobalData *global_seat_data = (WaylandSeatGlobalData *)global_seat_info.data;
  1673. ERR_FAIL_NULL_V(global_seat_data, MessageStatus::ERROR);
  1674. if (p_opcode == WL_KEYBOARD_ENTER) {
  1675. // [Event] wl_keyboard::enter(uoa)
  1676. uint32_t surface = body[1];
  1677. if (global_seat_data->focused_surface_id != surface) {
  1678. DEBUG_LOG_WAYLAND_EMBED(vformat("Focused g0x%x", surface));
  1679. global_seat_data->focused_surface_id = surface;
  1680. }
  1681. } else if (p_opcode == WL_KEYBOARD_LEAVE) {
  1682. // [Event] wl_keyboard::leave(uo)
  1683. uint32_t surface = body[1];
  1684. if (global_seat_data->focused_surface_id == surface) {
  1685. global_seat_data->focused_surface_id = INVALID_ID;
  1686. }
  1687. } else if (p_opcode == WL_KEYBOARD_KEY) {
  1688. // NOTE: modifiers event can be sent even without focus, according to the
  1689. // spec, so there's no need to skip it.
  1690. if (global_seat_data->focused_surface_id != INVALID_ID && !client->local_ids.has(global_seat_data->focused_surface_id)) {
  1691. DEBUG_LOG_WAYLAND_EMBED(vformat("Skipped wl_keyboard event due to unfocused surface 0x%x", global_seat_data->focused_surface_id));
  1692. return MessageStatus::HANDLED;
  1693. }
  1694. }
  1695. return MessageStatus::UNHANDLED;
  1696. }
  1697. if (object->interface == &wl_pointer_interface) {
  1698. WaylandPointerData *data = (WaylandPointerData *)object->data;
  1699. ERR_FAIL_NULL_V(data, MessageStatus::ERROR);
  1700. uint32_t global_seat_name = registry_globals_names[data->wl_seat_id];
  1701. RegistryGlobalInfo &global_seat_info = registry_globals[global_seat_name];
  1702. WaylandSeatGlobalData *global_seat_data = (WaylandSeatGlobalData *)global_seat_info.data;
  1703. ERR_FAIL_NULL_V(global_seat_data, MessageStatus::ERROR);
  1704. WaylandSeatInstanceData *seat_data = (WaylandSeatInstanceData *)object->data;
  1705. ERR_FAIL_NULL_V(seat_data, MessageStatus::ERROR);
  1706. if (p_opcode == WL_POINTER_BUTTON && global_seat_data->pointed_surface_id != INVALID_ID) {
  1707. // [Event] wl_pointer::button(uuuu);
  1708. uint32_t button = body[2];
  1709. uint32_t state = body[3];
  1710. DEBUG_LOG_WAYLAND_EMBED(vformat("Button %d state %d on surface g0x%x (focused g0x%x)", button, state, global_seat_data->pointed_surface_id, global_seat_data->focused_surface_id));
  1711. bool client_pointed = client->local_ids.has(global_seat_data->pointed_surface_id);
  1712. if (button != BTN_LEFT || state != WL_POINTER_BUTTON_STATE_RELEASED) {
  1713. return client_pointed ? MessageStatus::UNHANDLED : MessageStatus::HANDLED;
  1714. }
  1715. if (global_seat_data->focused_surface_id == global_seat_data->pointed_surface_id) {
  1716. return client_pointed ? MessageStatus::UNHANDLED : MessageStatus::HANDLED;
  1717. }
  1718. if (!global_surface_is_window(global_seat_data->pointed_surface_id)) {
  1719. return client_pointed ? MessageStatus::UNHANDLED : MessageStatus::HANDLED;
  1720. }
  1721. if (global_seat_data->focused_surface_id != INVALID_ID) {
  1722. seat_name_leave_surface(global_seat_name, global_seat_data->focused_surface_id);
  1723. }
  1724. global_seat_data->focused_surface_id = global_seat_data->pointed_surface_id;
  1725. seat_name_enter_surface(global_seat_name, global_seat_data->focused_surface_id);
  1726. } else if (p_opcode == WL_POINTER_ENTER) {
  1727. // [Event] wl_pointer::enter(uoff).
  1728. uint32_t surface = body[1];
  1729. WaylandSurfaceData *surface_data = (WaylandSurfaceData *)get_object(surface)->data;
  1730. ERR_FAIL_NULL_V(surface_data, MessageStatus::ERROR);
  1731. if (global_seat_data->pointed_surface_id != surface) {
  1732. DEBUG_LOG_WAYLAND_EMBED(vformat("Pointer (g0x%x seat g0x%x): pointed surface old g0x%x new g0x%x", p_global_id, data->wl_seat_id, global_seat_data->pointed_surface_id, surface));
  1733. global_seat_data->pointed_surface_id = surface;
  1734. }
  1735. } else if (p_opcode == WL_POINTER_LEAVE) {
  1736. // [Event] wl_pointer::leave(uo).
  1737. uint32_t surface = body[1];
  1738. WaylandSurfaceData *surface_data = (WaylandSurfaceData *)get_object(surface)->data;
  1739. ERR_FAIL_NULL_V(surface_data, MessageStatus::ERROR);
  1740. if (global_seat_data->pointed_surface_id == surface) {
  1741. DEBUG_LOG_WAYLAND_EMBED(vformat("Pointer (g0x%x seat g0x%x): g0x%x -> g0x%x", p_global_id, data->wl_seat_id, global_seat_data->pointed_surface_id, INVALID_ID));
  1742. global_seat_data->pointed_surface_id = INVALID_ID;
  1743. }
  1744. }
  1745. return MessageStatus::UNHANDLED;
  1746. }
  1747. if (object->interface == &xdg_popup_interface) {
  1748. if (p_opcode == XDG_POPUP_CONFIGURE) {
  1749. // [Event] xdg_popup::configure(iiii);
  1750. int32_t x = body[0];
  1751. int32_t y = body[1];
  1752. int32_t width = body[2];
  1753. int32_t height = body[3];
  1754. XdgPopupData *data = (XdgPopupData *)object->data;
  1755. ERR_FAIL_NULL_V(data, MessageStatus::ERROR);
  1756. XdgSurfaceData *parent_xdg_surf_data = (XdgSurfaceData *)data->parent_handle.get()->data;
  1757. ERR_FAIL_NULL_V(parent_xdg_surf_data, MessageStatus::ERROR);
  1758. WaylandSurfaceData *parent_surface_data = (WaylandSurfaceData *)get_object(parent_xdg_surf_data->wl_surface_id)->data;
  1759. ERR_FAIL_NULL_V(parent_surface_data, MessageStatus::ERROR);
  1760. WaylandObject *parent_role_obj = parent_surface_data->role_object_handle.get();
  1761. ERR_FAIL_NULL_V(parent_role_obj, MessageStatus::ERROR);
  1762. if (parent_role_obj->interface == &xdg_toplevel_interface) {
  1763. XdgToplevelData *parent_toplevel_data = (XdgToplevelData *)parent_role_obj->data;
  1764. ERR_FAIL_NULL_V(parent_toplevel_data, MessageStatus::ERROR);
  1765. if (parent_toplevel_data->is_embedded()) {
  1766. WaylandSubsurfaceData *subsurf_data = (WaylandSubsurfaceData *)get_object(parent_toplevel_data->wl_subsurface_id)->data;
  1767. ERR_FAIL_NULL_V(subsurf_data, MessageStatus::ERROR);
  1768. // The coordinates passed will be shifted by the embedded window position,
  1769. // so we need to fix them back.
  1770. Point2i fixed_position = Point2i(x, y) - subsurf_data->position;
  1771. DEBUG_LOG_WAYLAND_EMBED(vformat("Correcting popup configure position to %s", fixed_position));
  1772. send_wayland_message(client->socket, local_id, p_opcode, { (uint32_t)fixed_position.x, (uint32_t)fixed_position.y, (uint32_t)width, (uint32_t)height });
  1773. return MessageStatus::HANDLED;
  1774. }
  1775. }
  1776. }
  1777. }
  1778. return MessageStatus::UNHANDLED;
  1779. }
  1780. void WaylandEmbedder::shutdown() {
  1781. thread_done.set();
  1782. {
  1783. // First making a list of all clients so that we can iteratively delete them.
  1784. LocalVector<int> sockets;
  1785. for (KeyValue<int, Client> &pair : clients) {
  1786. sockets.push_back(pair.key);
  1787. }
  1788. for (int socket : sockets) {
  1789. cleanup_socket(socket);
  1790. }
  1791. }
  1792. close(compositor_socket);
  1793. compositor_socket = -1;
  1794. for (KeyValue<uint32_t, RegistryGlobalInfo> &pair : registry_globals) {
  1795. RegistryGlobalInfo &info = pair.value;
  1796. if (info.data) {
  1797. memdelete(info.data);
  1798. info.data = nullptr;
  1799. }
  1800. }
  1801. }
  1802. Error WaylandEmbedder::handle_msg_info(Client *client, const struct msg_info *info, uint32_t *buf, int *fds_requested) {
  1803. ERR_FAIL_NULL_V(info, ERR_BUG);
  1804. ERR_FAIL_NULL_V(fds_requested, ERR_BUG);
  1805. ERR_FAIL_NULL_V_MSG(info->direction == ProxyDirection::COMPOSITOR && client, ERR_BUG, "Wait, where did this message come from?");
  1806. *fds_requested = 0;
  1807. WaylandObject *object = nullptr;
  1808. uint32_t global_id = INVALID_ID;
  1809. if (info->direction == ProxyDirection::CLIENT) {
  1810. global_id = info->raw_id;
  1811. } else if (info->direction == ProxyDirection::COMPOSITOR) {
  1812. global_id = client->get_global_id(info->raw_id);
  1813. }
  1814. if (global_id != INVALID_ID) {
  1815. object = get_object(global_id);
  1816. } else if (client) {
  1817. object = client->get_object(info->raw_id);
  1818. }
  1819. if (object == nullptr) {
  1820. if (info->direction == ProxyDirection::COMPOSITOR) {
  1821. uint32_t local_id = info->raw_id;
  1822. ERR_PRINT(vformat("Couldn't find requested object l0x%x for client %d, disconnecting.", local_id, client->socket));
  1823. socket_error(client->socket, local_id, WL_DISPLAY_ERROR_INVALID_OBJECT, vformat("Object l0x%x not found.", local_id));
  1824. return OK;
  1825. } else {
  1826. CRASH_NOW_MSG(vformat("No object found for r0x%x", info->raw_id));
  1827. }
  1828. }
  1829. const struct wl_interface *interface = nullptr;
  1830. interface = object->interface;
  1831. if (interface == nullptr && info->raw_id & 0xff000000) {
  1832. // Regular clients have no confirmation about deleted server objects (why
  1833. // should they?) but since we share connections there's the risk of receiving
  1834. // messages about deleted server objects. The simplest solution is to ignore
  1835. // unknown server-side objects. Not the safest thing, I know, but it should do
  1836. // the job.
  1837. DEBUG_LOG_WAYLAND_EMBED(vformat("Ignoring unknown server-side object r0x%x", info->raw_id));
  1838. return OK;
  1839. }
  1840. ERR_FAIL_NULL_V_MSG(interface, ERR_BUG, vformat("Object r0x%x has no interface", info->raw_id));
  1841. const struct wl_message *message = nullptr;
  1842. if (info->direction == ProxyDirection::CLIENT) {
  1843. ERR_FAIL_COND_V(info->opcode >= interface->event_count, ERR_BUG);
  1844. message = &interface->events[info->opcode];
  1845. } else {
  1846. ERR_FAIL_COND_V(info->opcode >= interface->method_count, ERR_BUG);
  1847. message = &interface->methods[info->opcode];
  1848. }
  1849. ERR_FAIL_NULL_V(message, ERR_BUG);
  1850. *fds_requested = String(message->signature).count("h");
  1851. LocalVector<int> sent_fds;
  1852. if (*fds_requested > 0) {
  1853. DEBUG_LOG_WAYLAND_EMBED(vformat("Requested %d FDs.", *fds_requested));
  1854. List<int> &fd_queue = info->direction == ProxyDirection::COMPOSITOR ? client->fds : compositor_fds;
  1855. for (int i = 0; i < *fds_requested; ++i) {
  1856. ERR_FAIL_COND_V_MSG(fd_queue.is_empty(), ERR_BUG, "Out of FDs.");
  1857. DEBUG_LOG_WAYLAND_EMBED(vformat("Fetching FD %d.", fd_queue.front()->get()));
  1858. sent_fds.push_back(fd_queue.front()->get());
  1859. fd_queue.pop_front();
  1860. }
  1861. DEBUG_LOG_WAYLAND_EMBED(vformat("Remaining FDs: %d.", fd_queue.size()));
  1862. }
  1863. if (object->destroyed) {
  1864. DEBUG_LOG_WAYLAND_EMBED("Ignoring message for inert object.");
  1865. // Inert object.
  1866. return OK;
  1867. }
  1868. if (info->direction == ProxyDirection::COMPOSITOR) {
  1869. MessageStatus request_status = handle_request(LocalObjectHandle(client, info->raw_id), info->opcode, buf, info->size);
  1870. if (request_status == MessageStatus::ERROR) {
  1871. return ERR_BUG;
  1872. }
  1873. if (request_status == MessageStatus::HANDLED) {
  1874. DEBUG_LOG_WAYLAND_EMBED("Custom handler success.");
  1875. return OK;
  1876. }
  1877. if (global_id != INVALID_ID) {
  1878. buf[0] = global_id;
  1879. }
  1880. DEBUG_LOG_WAYLAND_EMBED("Falling back to generic handler.");
  1881. if (handle_generic_msg(client, object, message, info, buf)) {
  1882. send_raw_message(compositor_socket, { { buf, info->size } }, sent_fds);
  1883. }
  1884. } else {
  1885. uint32_t global_name = 0;
  1886. bool is_global = false;
  1887. if (registry_globals_names.has(global_id)) {
  1888. global_name = registry_globals_names[global_id];
  1889. is_global = true;
  1890. }
  1891. // FIXME: For compatibility, mirror events with instanced registry globals as
  1892. // object arguments. For example, `wl_surface.enter` returns a `wl_output`. If
  1893. // said `wl_output` has been instanced multiple times, we need to resend the
  1894. // same event with each instance as the argument, or the client might miss the
  1895. // event by looking for the "wrong" instance.
  1896. //
  1897. // Note that this missing behavior is exclusively a compatibility mechanism
  1898. // for old compositors which only implement undestroyable globals. We
  1899. // otherwise passthrough every bind request and then the compositor takes care
  1900. // of everything.
  1901. // See: https://lore.freedesktop.org/wayland-devel/[email protected]/
  1902. if (object->shared) {
  1903. bool handled = false;
  1904. for (KeyValue<int, Client> &pair : clients) {
  1905. Client &c = pair.value;
  1906. if (c.socket < 0) {
  1907. continue;
  1908. }
  1909. if (!c.local_ids.has(global_id)) {
  1910. DEBUG_LOG_WAYLAND_EMBED("!!!!!!!!!!! Instance missing?");
  1911. continue;
  1912. }
  1913. if (is_global) {
  1914. if (!c.registry_globals_instances.has(global_name)) {
  1915. continue;
  1916. }
  1917. DEBUG_LOG_WAYLAND_EMBED(vformat("Broadcasting to all global instances for client %d (socket %d)", c.pid, c.socket));
  1918. for (uint32_t instance_id : c.registry_globals_instances[global_name]) {
  1919. DEBUG_LOG_WAYLAND_EMBED(vformat("Global instance l0x%x", instance_id));
  1920. LocalObjectHandle local_obj = LocalObjectHandle(&c, instance_id);
  1921. if (!local_obj.is_valid()) {
  1922. continue;
  1923. }
  1924. MessageStatus event_status = handle_event(global_id, local_obj, info->opcode, buf, info->size);
  1925. if (event_status == MessageStatus::ERROR) {
  1926. return ERR_BUG;
  1927. }
  1928. if (event_status == MessageStatus::HANDLED) {
  1929. DEBUG_LOG_WAYLAND_EMBED("Custom handler success.");
  1930. handled = true;
  1931. continue;
  1932. }
  1933. if (event_status == MessageStatus::INVALID) {
  1934. continue;
  1935. }
  1936. DEBUG_LOG_WAYLAND_EMBED("Falling back to generic handler.");
  1937. buf[0] = instance_id;
  1938. if (handle_generic_msg(&c, local_obj.get(), message, info, buf, instance_id)) {
  1939. send_raw_message(c.socket, { { buf, info->size } }, sent_fds);
  1940. }
  1941. handled = true;
  1942. }
  1943. } else if (interface == &wl_display_interface) {
  1944. // NOTE: The only shared non-global objects are `wl_display` and
  1945. // `wl_registry`, both of which require custom handlers. Additionally, of
  1946. // those only `wl_display` has client-specific handlers, which is what this
  1947. // branch manages.
  1948. LocalObjectHandle local_obj = LocalObjectHandle(&c, c.get_local_id(global_id));
  1949. if (!local_obj.is_valid()) {
  1950. continue;
  1951. }
  1952. DEBUG_LOG_WAYLAND_EMBED(vformat("Shared non-global l0x%x g0x%x", c.get_local_id(global_id), global_id));
  1953. MessageStatus event_status = handle_event(global_id, local_obj, info->opcode, buf, info->size);
  1954. if (event_status == MessageStatus::ERROR) {
  1955. return ERR_BUG;
  1956. }
  1957. if (event_status == MessageStatus::HANDLED) {
  1958. DEBUG_LOG_WAYLAND_EMBED("Custom handler success.");
  1959. handled = true;
  1960. continue;
  1961. }
  1962. if (event_status == MessageStatus::INVALID) {
  1963. continue;
  1964. }
  1965. DEBUG_LOG_WAYLAND_EMBED("Falling back to generic handler.");
  1966. if (handle_generic_msg(&c, local_obj.get(), message, info, buf)) {
  1967. send_raw_message(c.socket, { { buf, info->size } }, sent_fds);
  1968. }
  1969. handled = true;
  1970. }
  1971. }
  1972. if (!handled) {
  1973. // No client handled this, it's going to be handled as a client-less event.
  1974. // We do this only at the end to avoid handling certain events (e.g.
  1975. // deletion) twice.
  1976. handle_event(global_id, LocalObjectHandle(nullptr, INVALID_ID), info->opcode, buf, info->size);
  1977. }
  1978. } else {
  1979. LocalObjectHandle local_obj = LocalObjectHandle(client, client ? client->get_local_id(global_id) : INVALID_ID);
  1980. MessageStatus event_status = handle_event(global_id, local_obj, info->opcode, buf, info->size);
  1981. if (event_status == MessageStatus::ERROR) {
  1982. return ERR_BUG;
  1983. }
  1984. if (event_status == MessageStatus::HANDLED || event_status == MessageStatus::INVALID) {
  1985. // We're done.
  1986. return OK;
  1987. }
  1988. // Generic passthrough.
  1989. if (client) {
  1990. uint32_t local_id = client->get_local_id(global_id);
  1991. ERR_FAIL_COND_V(local_id == INVALID_ID, OK);
  1992. DEBUG_LOG_WAYLAND_EMBED(vformat("%s::%s(%s) g0x%x -> l0x%x", interface->name, message->name, message->signature, global_id, local_id));
  1993. buf[0] = local_id;
  1994. if (handle_generic_msg(client, local_obj.get(), message, info, buf)) {
  1995. send_raw_message(client->socket, { { buf, info->size } }, sent_fds);
  1996. }
  1997. } else {
  1998. WARN_PRINT_ONCE(vformat("[Wayland Embedder] Unexpected client-less event from %s#g0x%x. Object has probably leaked.", object->interface->name, global_id));
  1999. handle_generic_msg(nullptr, object, message, info, buf);
  2000. }
  2001. }
  2002. }
  2003. for (int fd : sent_fds) {
  2004. DEBUG_LOG_WAYLAND_EMBED(vformat("Closing fd %d.", fd));
  2005. close(fd);
  2006. }
  2007. return OK;
  2008. }
  2009. Error WaylandEmbedder::handle_sock(int p_fd) {
  2010. ERR_FAIL_COND_V(p_fd < 0, ERR_INVALID_PARAMETER);
  2011. struct msg_info info = {};
  2012. {
  2013. struct msghdr head_msg = {};
  2014. uint32_t header[2];
  2015. struct iovec vec = { header, sizeof header };
  2016. head_msg.msg_iov = &vec;
  2017. head_msg.msg_iovlen = 1;
  2018. ssize_t head_rec = recvmsg(p_fd, &head_msg, MSG_PEEK);
  2019. if (head_rec == 0) {
  2020. // Client disconnected.
  2021. return ERR_CONNECTION_ERROR;
  2022. }
  2023. if (head_rec == -1) {
  2024. if (errno == ECONNRESET) {
  2025. // No need to print the error, the client forcefully disconnected, that's
  2026. // fine.
  2027. return ERR_CONNECTION_ERROR;
  2028. }
  2029. ERR_FAIL_V_MSG(FAILED, vformat("Can't read message header: %s", strerror(errno)));
  2030. }
  2031. ERR_FAIL_COND_V_MSG(((size_t)head_rec) != vec.iov_len, ERR_CONNECTION_ERROR, vformat("Should've received %d bytes, instead got %d bytes", vec.iov_len, head_rec));
  2032. // Header is two 32-bit words: first is ID, second has size in most significant
  2033. // half and opcode in the other half.
  2034. info.raw_id = header[0];
  2035. info.size = header[1] >> 16;
  2036. info.opcode = header[1] & 0xFFFF;
  2037. info.direction = p_fd != compositor_socket ? ProxyDirection::COMPOSITOR : ProxyDirection::CLIENT;
  2038. }
  2039. if (msg_buf.size() < info.words()) {
  2040. msg_buf.resize(info.words());
  2041. }
  2042. ERR_FAIL_COND_V_MSG(info.size % WL_WORD_SIZE != 0, ERR_CONNECTION_ERROR, "Invalid message length.");
  2043. struct msghdr full_msg = {};
  2044. struct iovec vec = { msg_buf.ptr(), info.size };
  2045. {
  2046. full_msg.msg_iov = &vec;
  2047. full_msg.msg_iovlen = 1;
  2048. full_msg.msg_control = ancillary_buf.ptr();
  2049. full_msg.msg_controllen = ancillary_buf.size();
  2050. ssize_t full_rec = recvmsg(p_fd, &full_msg, 0);
  2051. if (full_rec == -1) {
  2052. if (errno == ECONNRESET) {
  2053. // No need to print the error, the client forcefully disconnected, that's
  2054. // fine.
  2055. return ERR_CONNECTION_ERROR;
  2056. }
  2057. ERR_FAIL_V_MSG(FAILED, vformat("Can't read message: %s", strerror(errno)));
  2058. }
  2059. ERR_FAIL_COND_V_MSG(((size_t)full_rec) != info.size, ERR_CONNECTION_ERROR, "Invalid message length.");
  2060. DEBUG_LOG_WAYLAND_EMBED(" === START PACKET === ");
  2061. #ifdef WAYLAND_EMBED_DEBUG_LOGS_ENABLED
  2062. printf("[PROXY] Received bytes: ");
  2063. for (ssize_t i = 0; i < full_rec; ++i) {
  2064. printf("%.2x", ((const uint8_t *)msg_buf.ptr())[i]);
  2065. }
  2066. printf("\n");
  2067. #endif
  2068. }
  2069. if (full_msg.msg_controllen > 0) {
  2070. struct cmsghdr *cmsg = CMSG_FIRSTHDR(&full_msg);
  2071. while (cmsg) {
  2072. // TODO: Check for validity of message fields.
  2073. size_t data_len = cmsg->cmsg_len - sizeof *cmsg;
  2074. if (cmsg->cmsg_type == SCM_RIGHTS) {
  2075. // NOTE: Linux docs say that we can't just cast data to pointer type because
  2076. // of alignment concerns. So we have to memcpy into a new buffer.
  2077. int *cmsg_fds = (int *)malloc(data_len);
  2078. memcpy(cmsg_fds, CMSG_DATA(cmsg), data_len);
  2079. size_t cmsg_fds_count = data_len / sizeof *cmsg_fds;
  2080. for (size_t i = 0; i < cmsg_fds_count; ++i) {
  2081. int fd = cmsg_fds[i];
  2082. if (info.direction == ProxyDirection::COMPOSITOR) {
  2083. clients[p_fd].fds.push_back(fd);
  2084. } else {
  2085. compositor_fds.push_back(fd);
  2086. }
  2087. }
  2088. #ifdef WAYLAND_EMBED_DEBUG_LOGS_ENABLED
  2089. printf("[PROXY] Received %ld file descriptors: ", cmsg_fds_count);
  2090. for (size_t i = 0; i < cmsg_fds_count; ++i) {
  2091. printf("%d ", cmsg_fds[i]);
  2092. }
  2093. printf("\n");
  2094. #endif
  2095. free(cmsg_fds);
  2096. }
  2097. cmsg = CMSG_NXTHDR(&full_msg, cmsg);
  2098. }
  2099. }
  2100. full_msg.msg_control = nullptr;
  2101. full_msg.msg_controllen = 0;
  2102. int fds_requested = 0;
  2103. Client *client = nullptr;
  2104. if (p_fd == compositor_socket) {
  2105. // Let's figure out the recipient of the message.
  2106. for (KeyValue<int, Client> &pair : clients) {
  2107. Client &c = pair.value;
  2108. if (c.local_ids.has(info.raw_id)) {
  2109. client = &c;
  2110. }
  2111. }
  2112. } else {
  2113. CRASH_COND(!clients.has(p_fd));
  2114. client = &clients[p_fd];
  2115. }
  2116. if (handle_msg_info(client, &info, msg_buf.ptr(), &fds_requested) != OK) {
  2117. return ERR_BUG;
  2118. }
  2119. DEBUG_LOG_WAYLAND_EMBED(" === END PACKET === ");
  2120. return OK;
  2121. }
  2122. void WaylandEmbedder::_thread_loop(void *p_data) {
  2123. Thread::set_name("Wayland Embed");
  2124. ERR_FAIL_NULL(p_data);
  2125. WaylandEmbedder *proxy = (WaylandEmbedder *)p_data;
  2126. DEBUG_LOG_WAYLAND_EMBED("Proxy thread started");
  2127. while (!proxy->thread_done.is_set()) {
  2128. proxy->poll_sockets();
  2129. }
  2130. }
  2131. Error WaylandEmbedder::init() {
  2132. ancillary_buf.resize(EMBED_ANCILLARY_BUF_SIZE);
  2133. proxy_socket = socket(AF_UNIX, SOCK_STREAM, 0);
  2134. struct sockaddr_un addr = {};
  2135. addr.sun_family = AF_UNIX;
  2136. String runtime_dir_path = OS::get_singleton()->get_environment("XDG_RUNTIME_DIR");
  2137. ERR_FAIL_COND_V_MSG(runtime_dir_path.is_empty(), ERR_DOES_NOT_EXIST, "XDG_RUNTIME_DIR is not set or empty.");
  2138. runtime_dir = DirAccess::create_for_path(runtime_dir_path);
  2139. ERR_FAIL_COND_V(!runtime_dir.is_valid(), ERR_BUG);
  2140. ERR_FAIL_COND_V_MSG(!runtime_dir->is_writable(runtime_dir_path), ERR_FILE_CANT_WRITE, "XDG_RUNTIME_DIR points to an invalid directory.");
  2141. int socket_id = 0;
  2142. while (socket_path.is_empty()) {
  2143. String test_socket_path = runtime_dir_path + "/godot-wayland-" + itos(socket_id);
  2144. String test_socket_lock_path = test_socket_path + ".lock";
  2145. print_verbose(vformat("Trying to get socket %s", test_socket_path));
  2146. print_verbose(vformat("Opening lock %s", test_socket_lock_path));
  2147. int test_lock_fd = open(test_socket_lock_path.utf8().get_data(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
  2148. if (flock(test_lock_fd, LOCK_EX | LOCK_NB) == -1) {
  2149. print_verbose(vformat("Can't lock %s", test_socket_lock_path));
  2150. close(test_lock_fd);
  2151. ++socket_id;
  2152. continue;
  2153. } else {
  2154. lock_fd = test_lock_fd;
  2155. socket_path = test_socket_path;
  2156. socket_lock_path = test_socket_lock_path;
  2157. break;
  2158. }
  2159. }
  2160. DirAccess::remove_absolute(socket_path);
  2161. strncpy(addr.sun_path, socket_path.utf8().get_data(), sizeof(addr.sun_path) - 1);
  2162. if (bind(proxy_socket, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
  2163. ERR_FAIL_V_MSG(ERR_CANT_CREATE, "Can't bind embedding socket.");
  2164. }
  2165. if (listen(proxy_socket, 1) == -1) {
  2166. ERR_FAIL_V_MSG(ERR_CANT_OPEN, "Can't listen embedding socket.");
  2167. }
  2168. struct wl_display *display = wl_display_connect(nullptr);
  2169. ERR_FAIL_NULL_V(display, ERR_CANT_OPEN);
  2170. compositor_socket = wl_display_get_fd(display);
  2171. pollfds.push_back({ proxy_socket, POLLIN, 0 });
  2172. pollfds.push_back({ compositor_socket, POLLIN, 0 });
  2173. RegistryGlobalInfo control_global_info = {};
  2174. control_global_info.interface = &godot_embedding_compositor_interface;
  2175. control_global_info.version = godot_embedding_compositor_interface.version;
  2176. godot_embedding_compositor_name = registry_globals_counter++;
  2177. registry_globals[godot_embedding_compositor_name] = control_global_info;
  2178. {
  2179. uint32_t invalid_id = INVALID_ID;
  2180. objects.request(invalid_id);
  2181. CRASH_COND(invalid_id != INVALID_ID);
  2182. }
  2183. {
  2184. uint32_t display_id = new_object(&wl_display_interface);
  2185. CRASH_COND(display_id != DISPLAY_ID);
  2186. get_object(DISPLAY_ID)->shared = true;
  2187. }
  2188. {
  2189. uint32_t registry_id = new_object(&wl_registry_interface);
  2190. CRASH_COND(registry_id != REGISTRY_ID);
  2191. get_object(REGISTRY_ID)->shared = true;
  2192. }
  2193. // wl_display::get_registry(n)
  2194. send_wayland_message(compositor_socket, DISPLAY_ID, 1, { REGISTRY_ID });
  2195. sync();
  2196. proxy_thread.start(_thread_loop, this);
  2197. return OK;
  2198. }
  2199. void WaylandEmbedder::handle_fd(int p_fd, int p_revents) {
  2200. if (p_fd == proxy_socket && p_revents & POLLIN) {
  2201. // Client init.
  2202. int new_fd = accept(proxy_socket, nullptr, nullptr);
  2203. ERR_FAIL_COND_MSG(new_fd == -1, "Failed to accept client.");
  2204. struct ucred cred = {};
  2205. socklen_t cred_size = sizeof cred;
  2206. getsockopt(new_fd, SOL_SOCKET, SO_PEERCRED, &cred, &cred_size);
  2207. Client &client = clients.insert_new(new_fd, {})->value;
  2208. client.embedder = this;
  2209. client.socket = new_fd;
  2210. client.pid = cred.pid;
  2211. client.global_ids[DISPLAY_ID] = Client::GlobalIdInfo(DISPLAY_ID, nullptr);
  2212. client.local_ids[DISPLAY_ID] = DISPLAY_ID;
  2213. pollfds.push_back({ new_fd, POLLIN, 0 });
  2214. if (main_client == nullptr) {
  2215. main_client = &client;
  2216. }
  2217. if (new_fd != main_client->socket && main_client->registry_globals_instances.has(godot_embedding_compositor_name)) {
  2218. uint32_t new_local_id = main_client->allocate_server_id();
  2219. client.embedded_client_id = new_local_id;
  2220. for (uint32_t local_id : main_client->registry_globals_instances[godot_embedding_compositor_name]) {
  2221. EmbeddedClientData *eclient_data = memnew(EmbeddedClientData);
  2222. eclient_data->client = &client;
  2223. main_client->new_fake_object(new_local_id, &godot_embedded_client_interface, 1, eclient_data);
  2224. // godot_embedding_compositor::client(nu)
  2225. send_wayland_message(main_client->socket, local_id, 0, { new_local_id, (uint32_t)cred.pid });
  2226. }
  2227. }
  2228. DEBUG_LOG_WAYLAND_EMBED(vformat("New client %d (pid %d) initialized.", client.socket, cred.pid));
  2229. return;
  2230. }
  2231. if (p_fd == compositor_socket && p_revents & POLLIN) {
  2232. Error err = handle_sock(p_fd);
  2233. if (err == ERR_BUG) {
  2234. ERR_PRINT("Unexpected error while handling socket, shutting down.");
  2235. shutdown();
  2236. return;
  2237. }
  2238. return;
  2239. }
  2240. const Client *client = clients.getptr(p_fd);
  2241. if (client) {
  2242. if (main_client && client == main_client && p_revents & (POLLHUP | POLLERR)) {
  2243. DEBUG_LOG_WAYLAND_EMBED("Main client disconnected, shutting down.");
  2244. shutdown();
  2245. return;
  2246. }
  2247. if (p_revents & POLLIN) {
  2248. Error err = handle_sock(p_fd);
  2249. if (err == ERR_BUG) {
  2250. ERR_PRINT("Unexpected error while handling socket, shutting down.");
  2251. shutdown();
  2252. return;
  2253. }
  2254. if (err != OK) {
  2255. DEBUG_LOG_WAYLAND_EMBED("disconnecting");
  2256. cleanup_socket(p_fd);
  2257. return;
  2258. }
  2259. return;
  2260. } else if (p_revents & (POLLHUP | POLLERR | POLLNVAL)) {
  2261. if (p_revents & POLLHUP) {
  2262. DEBUG_LOG_WAYLAND_EMBED(vformat("Socket %d hangup.", p_fd));
  2263. }
  2264. if (p_revents & POLLERR) {
  2265. DEBUG_LOG_WAYLAND_EMBED(vformat("Socket %d error.", p_fd));
  2266. }
  2267. if (p_revents & POLLNVAL) {
  2268. DEBUG_LOG_WAYLAND_EMBED(vformat("Socket %d invalid FD.", p_fd));
  2269. }
  2270. cleanup_socket(p_fd);
  2271. return;
  2272. }
  2273. }
  2274. }
  2275. WaylandEmbedder::~WaylandEmbedder() {
  2276. shutdown();
  2277. if (proxy_thread.is_started()) {
  2278. proxy_thread.wait_to_finish();
  2279. }
  2280. }
  2281. #endif // TOOLS_ENABLED
  2282. #endif // WAYLAND_ENABLED