[
  {
    "path": ".github/FUNDING.yml",
    "content": "# These are supported funding model platforms\n\ngithub: [mmulet]\n"
  },
  {
    "path": ".gitignore",
    "content": "deps\nc_interop/*.o\nc_interop/*.so\nshaders/spirv\nc_interop/out\n.task\nc_interop/build\nnode_modules\nsrc/protocols\nbin\npkg\n.DS_Store\nTaskfile.yml\ntaskfile.yml\nTaskfile.yaml\ntaskfile.yaml\nAppdir\ndist\nresources/npm_licenses.txt\n.podman\n.podman-run\nthird_party/chafa_source/build\ndebug.log\n\nresources/out/bunterm\n__debug_bin*\nterm.everything\nterm.everything❗mmulet.com-dont_forget_to_chmod_+x_this_file\n"
  },
  {
    "path": ".vscode/extensions.json",
    "content": "{\n  \"recommendations\": [\n    \"ms-vscode.cpptools-extension-pack\",\n    \"golang.go\",\n    \"ms-vscode.makefile-tools\"\n  ]\n}\n"
  },
  {
    "path": ".vscode/launch.json",
    "content": "{\n  // Use IntelliSense to learn about possible attributes.\n  // Hover to view descriptions of existing attributes.\n  // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387\n  \"version\": \"0.2.0\",\n  \"configurations\": [\n    {\n      \"name\": \"Gen protocols\",\n      \"type\": \"go\",\n      \"request\": \"launch\",\n      \"mode\": \"auto\",\n      \"program\": \"${workspaceFolder}/cmd/protocols\"\n    },\n    {\n      \"name\": \"Launch term.everything\",\n      \"type\": \"go\",\n      \"request\": \"launch\",\n      \"mode\": \"auto\",\n      \"program\": \"${workspaceFolder}\",\n      \"console\": \"externalTerminal\",\n      \"args\": [\n        \"alacritty\"\n        // \"firefox\"\n      ],\n      // \"buildFlags\": [\"-tags=debug\"],\n    }\n   \n  ]\n}\n"
  },
  {
    "path": ".vscode/settings.json",
    "content": "{\n  \"files.exclude\": {\n    \"**/.git\": true,\n    \"**/.svn\": true,\n    \"**/.hg\": true,\n    \"**/CVS\": true,\n    \"**/.DS_Store\": true,\n    \"**/Thumbs.db\": true,\n    \"third_party\": false,\n    \".task\": false,\n    \"deps\": false,\n    \"scripts\": false,\n    \".vscode\": false,\n    \"bun.lock\": false,\n    \"package.json\": false,\n    \"tsconfig.json\": false,\n    \".gitmodules\": false,\n    \".gitignore\": false,\n    \"node_modules\": false,\n    \"c_interop/build\": false,\n    \"shaders/spirv\": false,\n    \"bin\": false,\n    \"pkg\": false,\n    \"**/Taskfile.dist.yml\": false,\n    \"tests\": false,\n    \"Appdir\": false,\n    \"*.AppImage\": false,\n    \"dist\": false,\n    \"patches\": false,\n    \"LICENSE.txt\": false\n  },\n  \"files.associations\": {\n    \"*.glsl\": \"glsl\",\n    \"*.scene\": \"json\",\n    \"socket.h\": \"c\",\n    \"*.tcc\": \"cpp\",\n    \"string\": \"cpp\",\n    \"iostream\": \"cpp\",\n    \"cctype\": \"cpp\",\n    \"clocale\": \"cpp\",\n    \"cmath\": \"cpp\",\n    \"cstdarg\": \"cpp\",\n    \"cstddef\": \"cpp\",\n    \"cstdio\": \"cpp\",\n    \"cstdlib\": \"cpp\",\n    \"cstring\": \"cpp\",\n    \"ctime\": \"cpp\",\n    \"cwchar\": \"cpp\",\n    \"cwctype\": \"cpp\",\n    \"array\": \"cpp\",\n    \"atomic\": \"cpp\",\n    \"strstream\": \"cpp\",\n    \"bit\": \"cpp\",\n    \"bitset\": \"cpp\",\n    \"chrono\": \"cpp\",\n    \"compare\": \"cpp\",\n    \"complex\": \"cpp\",\n    \"concepts\": \"cpp\",\n    \"condition_variable\": \"cpp\",\n    \"cstdint\": \"cpp\",\n    \"deque\": \"cpp\",\n    \"list\": \"cpp\",\n    \"map\": \"cpp\",\n    \"set\": \"cpp\",\n    \"unordered_map\": \"cpp\",\n    \"unordered_set\": \"cpp\",\n    \"vector\": \"cpp\",\n    \"exception\": \"cpp\",\n    \"algorithm\": \"cpp\",\n    \"functional\": \"cpp\",\n    \"iterator\": \"cpp\",\n    \"memory\": \"cpp\",\n    \"memory_resource\": \"cpp\",\n    \"numeric\": \"cpp\",\n    \"optional\": \"cpp\",\n    \"random\": \"cpp\",\n    \"ratio\": \"cpp\",\n    \"string_view\": \"cpp\",\n    \"system_error\": \"cpp\",\n    \"tuple\": \"cpp\",\n    \"type_traits\": \"cpp\",\n    \"utility\": \"cpp\",\n    \"fstream\": \"cpp\",\n    \"initializer_list\": \"cpp\",\n    \"iomanip\": \"cpp\",\n    \"iosfwd\": \"cpp\",\n    \"istream\": \"cpp\",\n    \"limits\": \"cpp\",\n    \"mutex\": \"cpp\",\n    \"new\": \"cpp\",\n    \"numbers\": \"cpp\",\n    \"ostream\": \"cpp\",\n    \"ranges\": \"cpp\",\n    \"shared_mutex\": \"cpp\",\n    \"sstream\": \"cpp\",\n    \"stdexcept\": \"cpp\",\n    \"stop_token\": \"cpp\",\n    \"streambuf\": \"cpp\",\n    \"thread\": \"cpp\",\n    \"cfenv\": \"cpp\",\n    \"cinttypes\": \"cpp\",\n    \"typeindex\": \"cpp\",\n    \"typeinfo\": \"cpp\",\n    \"variant\": \"cpp\",\n    \"semaphore\": \"cpp\",\n    \"csignal\": \"cpp\",\n    \"future\": \"cpp\",\n    \"span\": \"cpp\",\n    \"valarray\": \"cpp\",\n    \"*.ipp\": \"cpp\",\n    \"csetjmp\": \"cpp\"\n  },\n  \"terminal.integrated.enableImages\": true,\n  \"typescript.preferences.importModuleSpecifierEnding\": \"js\",\n  \"javascript.preferences.importModuleSpecifierEnding\": \"js\",\n  \"C_Cpp.default.compilerPath\": \"/usr/bin/gcc\",\n  \"C_Cpp.default.includePath\": [\n    \"/usr/include/\",\n    \"/usr/local/include\",\n    \"/usr/include/chafa\",\n    \"/usr/lib/x86_64-linux-gnu/chafa/include\",\n    \"/usr/include/glib-2.0\",\n    \"/usr/lib/x86_64-linux-gnu/glib-2.0/include\",\n    \"${workspaceFolder}/c_interop/include\",\n    \"${workspaceFolder}/deps/**/*\",\n    \"${workspaceFolder}/third_party/node-v22.14.0-linux-x64/include/node\",\n    \"${workspaceFolder}/third_party/node-addon-api-8.3.1\"\n  ],\n  \"mesonbuild.selectRootDir\": false,\n  \"cSpell.words\": [\n    \"Appdir\",\n    \"appimage\",\n    \"chafa\",\n    \"Gwern\",\n    \"LEFTBRACE\",\n    \"libinterop\",\n    \"linuxdeploy\",\n    \"memcopy\",\n    \"mmaped\",\n    \"RIGHTBRACE\",\n    \"subcompositor\",\n    \"Xwayland\"\n  ],\n  \"mesonbuild.configureOnOpen\": false,\n  \"editor.wordWrap\": \"off\",\n  \"editor.rulers\": [\n    80\n  ]\n}"
  },
  {
    "path": "ChangeLog.md",
    "content": "# 0.7.8\n- Added support for mouse when really zoomed out by\n    - Adding SGR 1006 support for mouse reporting in terminals that support it.\n# 0.7.7\n- Fixed a bug where the terminal would not output SIXELS even when the override was set.\n# 0.7.6\n- Now it only redraws the screen when there are changes (like frame draw requests from wayland, mouse movement, etc), reducing CPU usage, and network bandwidth for remote sessions.\n- Moved profiling code behind a build tag to reduce binary size for normal users.\n# 0.7.5\n- Converted code to entriely go (with a tiny bit of c). THis simplifies the build process and reduces dependencies. This lets us easily port to new platforms like arm64.\n\n# 0.5.4\n- Added environment variables to pass through chafa options.\n- Added environment variable `TERM_EVERYTHING_PIXEL_TYPE` to workaround certain cases where there is a bgr/rgb swap.\n- Added `--max-frame-rate` option to ...set the maximum frame rate.\n- Fixed a build bug with node_canvas's included version of libstdc++.so\n# 0.5.3\nfixed right mouse click and sub menus\nSet XDG_SESSION_TYPE to wayland so app that have\na wayland support will use it.\n# 0.5.2\nfixed scrolling inversion https://github.com/mmulet/term.everything/issues/4\n# 0.5.0\nFirst Beta release\n"
  },
  {
    "path": "Contributing.md",
    "content": "\n# Easy Distribute and hacking.\n\nWant to change just a couple lines?\n\nThe only dependency you need is `podman\n- [podman https://podman.io/docs/installation](https://podman.io/docs/installation) On ubuntu just use`sudo apt install podman`\n\nand run the distribute script\n```sh\n./distribute.sh\n```\nThat will use a podman container to build the entire app and it will put the output\nin `./dist`.\n\nChange the `PLATFORM` environment variable to build for different platforms.\nFor example to build for linux aarch64:\n```sh\nPLATFORM=linux/aarch64 ./distribute.sh\n```\n\n# Development\n\nBelow are all the dependencies this app needs.\n\n## Deps:\n\n- Download the following dependecies from your system's package manager. On ubuntu use: `sudo apt install pkg-config libchafa-dev build-essential libglib2.0-dev`\n- Optional: [vscode](https://code.visualstudio.com/) with these recommended extensions:\n    - \"ms-vscode.cpptools-extension-pack\",\n    - \"golang.go\",\n    - \"ms-vscode.makefile-tools\"\n\n### Version map\nThese are the versions of the tools used to build and run the project:\n- chafa 1.16.0\n\n# Running and building\n\n\n## run\n\nYou can just run make\n```sh\nmake\n```\nThis will build the app.\n\nOr\nGenerate the needed code with\n```sh\ngo generate\n```\n\nand run with go run.\n\n```sh\ngo run . firefox\n```\ne, good for local testing or sending to friends\n## clean-all\nRemove all build artifacts.\n```sh\nmake clean\n```\n\n\n## Distribute\nThe distribute script creates an statically linked binary in a alpine linux podman container.\n"
  },
  {
    "path": "LICENSE.txt",
    "content": "\nGNU AFFERO GENERAL PUBLIC LICENSE\n\nVersion 3, 19 November 2007\n\nCopyright © 2007 Free Software Foundation, Inc. <https://fsf.org/>\nEveryone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.\nPreamble\n\nThe GNU Affero General Public License is a free, copyleft license for software and other kinds of works, specifically designed to ensure cooperation with the community in the case of network server software.\n\nThe licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, our General Public Licenses are intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users.\n\nWhen we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.\n\nDevelopers that use our General Public Licenses protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License which gives you legal permission to copy, distribute and/or modify the software.\n\nA secondary benefit of defending all users' freedom is that improvements made in alternate versions of the program, if they receive widespread use, become available for other developers to incorporate. Many developers of free software are heartened and encouraged by the resulting cooperation. However, in the case of software used on network servers, this result may fail to come about. The GNU General Public License permits making a modified version and letting the public access it on a server without ever releasing its source code to the public.\n\nThe GNU Affero General Public License is designed specifically to ensure that, in such cases, the modified source code becomes available to the community. It requires the operator of a network server to provide the source code of the modified version running there to the users of that server. Therefore, public use of a modified version, on a publicly accessible server, gives the public access to the source code of the modified version.\n\nAn older license, called the Affero General Public License and published by Affero, was designed to accomplish similar goals. This is a different license, not a version of the Affero GPL, but Affero has released a new version of the Affero GPL which permits relicensing under this license.\n\nThe precise terms and conditions for copying, distribution and modification follow.\nTERMS AND CONDITIONS\n0. Definitions.\n\n\"This License\" refers to version 3 of the GNU Affero General Public License.\n\n\"Copyright\" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.\n\n\"The Program\" refers to any copyrightable work licensed under this License. Each licensee is addressed as \"you\". \"Licensees\" and \"recipients\" may be individuals or organizations.\n\nTo \"modify\" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a \"modified version\" of the earlier work or a work \"based on\" the earlier work.\n\nA \"covered work\" means either the unmodified Program or a work based on the Program.\n\nTo \"propagate\" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.\n\nTo \"convey\" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.\n\nAn interactive user interface displays \"Appropriate Legal Notices\" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.\n1. Source Code.\n\nThe \"source code\" for a work means the preferred form of the work for making modifications to it. \"Object code\" means any non-source form of a work.\n\nA \"Standard Interface\" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.\n\nThe \"System Libraries\" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A \"Major Component\", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.\n\nThe \"Corresponding Source\" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.\n\nThe Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.\n\nThe Corresponding Source for a work in source code form is that same work.\n2. Basic Permissions.\n\nAll rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.\n\nYou may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.\n\nConveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.\n3. Protecting Users' Legal Rights From Anti-Circumvention Law.\n\nNo covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.\n\nWhen you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.\n4. Conveying Verbatim Copies.\n\nYou may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.\n\nYou may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.\n5. Conveying Modified Source Versions.\n\nYou may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:\n\n    a) The work must carry prominent notices stating that you modified it, and giving a relevant date.\n    b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to \"keep intact all notices\".\n    c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.\n    d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.\n\nA compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an \"aggregate\" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.\n6. Conveying Non-Source Forms.\n\nYou may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:\n\n    a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.\n    b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.\n    c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.\n    d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.\n    e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.\n\nA separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.\n\nA \"User Product\" is either (1) a \"consumer product\", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, \"normally used\" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.\n\n\"Installation Information\" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.\n\nIf you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).\n\nThe requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.\n\nCorresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.\n7. Additional Terms.\n\n\"Additional permissions\" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.\n\nWhen you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.\n\nNotwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:\n\n    a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or\n    b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or\n    c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or\n    d) Limiting the use for publicity purposes of names of licensors or authors of the material; or\n    e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or\n    f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.\n\nAll other non-permissive additional terms are considered \"further restrictions\" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.\n\nIf you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.\n\nAdditional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.\n8. Termination.\n\nYou may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).\n\nHowever, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.\n\nMoreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.\n\nTermination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.\n9. Acceptance Not Required for Having Copies.\n\nYou are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.\n10. Automatic Licensing of Downstream Recipients.\n\nEach time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.\n\nAn \"entity transaction\" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.\n\nYou may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.\n11. Patents.\n\nA \"contributor\" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's \"contributor version\".\n\nA contributor's \"essential patent claims\" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, \"control\" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.\n\nEach contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.\n\nIn the following three paragraphs, a \"patent license\" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To \"grant\" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.\n\nIf you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. \"Knowingly relying\" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.\n\nIf, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.\n\nA patent license is \"discriminatory\" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.\n\nNothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.\n12. No Surrender of Others' Freedom.\n\nIf conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.\n13. Remote Network Interaction; Use with the GNU General Public License.\n\nNotwithstanding any other provision of this License, if you modify the Program, your modified version must prominently offer all users interacting with it remotely through a computer network (if your version supports such interaction) an opportunity to receive the Corresponding Source of your version by providing access to the Corresponding Source from a network server at no charge, through some standard or customary means of facilitating copying of software. This Corresponding Source shall include the Corresponding Source for any work covered by version 3 of the GNU General Public License that is incorporated pursuant to the following paragraph.\n\nNotwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the work with which it is combined will remain governed by version 3 of the GNU General Public License.\n14. Revised Versions of this License.\n\nThe Free Software Foundation may publish revised and/or new versions of the GNU Affero General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.\n\nEach version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU Affero General Public License \"or any later version\" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU Affero General Public License, you may choose any version ever published by the Free Software Foundation.\n\nIf the Program specifies that a proxy can decide which future versions of the GNU Affero General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.\n\nLater license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.\n15. Disclaimer of Warranty.\n\nTHERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n16. Limitation of Liability.\n\nIN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.\n17. Interpretation of Sections 15 and 16.\n\nIf the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.\n\nEND OF TERMS AND CONDITIONS\nHow to Apply These Terms to Your New Programs\n\nIf you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.\n\nTo do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU Affero General Public License as\n    published by the Free Software Foundation, either version 3 of the\n    License, or (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU Affero General Public License for more details.\n\n    You should have received a copy of the GNU Affero General Public License\n    along with this program.  If not, see <https://www.gnu.org/licenses/>.\n\nAlso add information on how to contact you by electronic and paper mail.\n\nIf your software can interact with users remotely through a computer network, you should also make sure that it provides a way for users to get its source. For example, if your program is a web application, its interface could display a \"Source\" link that leads users to an archive of the code. There are many ways you could offer source, and different solutions will be better for different programs; see section 13 for the specific requirements.\n\nYou should also get your employer (if you work as a programmer) or school, if any, to sign a \"copyright disclaimer\" for the program, if necessary. For more information on this, and how to apply and follow the GNU AGPL, see <https://www.gnu.org/licenses/>.\n"
  },
  {
    "path": "Makefile",
    "content": ".PHONY: all clean build\n\n.DELETE_ON_ERROR:\n\nbin_name :=  dist/$(if $(PLATFORM),$(PLATFORM)/,)$(if $(STATIC_BUILD),static,)/$(ARCH_PREFIX)term.everything❗mmulet.com-dont_forget_to_chmod_+x_this_file\n\nprotocols_files := $(shell find ./wayland/generate)\n\nxml_protocols := $(shell find ./wayland/generate -name \"*.xml\")\n\ngenerated_protocols := $(patsubst ./wayland/generate/resources/%,./wayland/protocols/%.go,$(xml_protocols))\n\ngenerated_helpers := $(patsubst ./wayland/generate/resources/%,./wayland/%.helper.go,$(xml_protocols))\n\nbuild: $(generated_protocols) $(generated_helpers) $(bin_name)\n\n# grouped target to generate all protocols and helpers in one go\n# the & is what does this\n$(generated_protocols) $(generated_helpers)&: $(protocols_files) ./wayland/generate.go\n\tgo generate ./wayland\n\nSTATIC_FLAGS := $(if $(STATIC_BUILD),-ldflags '-extldflags \"-static\"',)\n\n$(bin_name): go.mod main.go $(shell find ./wayland) $(shell find ./termeverything) Makefile $(shell find ./framebuffertoansi) $(shell find ./escapecodes) $(generated_protocols) $(generated_helpers)\n\tgo build $(STATIC_FLAGS) -o $(bin_name) .\n\nclean:\n\t@echo cleaning\n\trm __debug_bin* 2>/dev/null || true\n\tif [ -z \"$$MULTI_PLATFORM\" ]; then rm -rf ./dist 2>/dev/null || true; fi\n\trm ./wayland/protocols/*.xml.go 2>/dev/null || true\n\trm ./wayland/*.helper.go 2>/dev/null || true"
  },
  {
    "path": "Readme.md",
    "content": "\n\n\n<table>\n  <tr>\n    <td valign=\"middle\">\n      <img width=\"128\" height=\"128\" alt=\"icon2\" src=\"./termeverything/resources/icon.png\" />\n    </td>\n    <td><h1>Term.Everything❗</h1></td>\n    <td><a href=\"https://github.com/mmulet/term.everything/releases\">Download the beta test now!</a></td>\n    <td><a href=\"./resources/HowIDidIt.md\">HowIDidIt.md</a></td>\n  </tr>\n  <tr>\n    <td></td>\n    <td>Works on both x11 and Wayland host systems.</td>\n    <td>Now written in go!</td>\n    <td><a href=\"https://github.com/mmulet/term.everything/tree/typescript\">Typescript version here</a> </td>\n  </tr>\n</table>\n\n## Run every GUI app in the terminal!\n\n![warp_into_terminal0001-0195](./resources/graphics/warp_in_2.gif)\n\n## Even over ssh!\nBehold as I play a [video game in a font](https://github.com/mmulet/font-game-engine) in a web browser in a terminal transmitted over ssh (with one hand tied behind my back)!\n\n![ssh_example](./resources/graphics/ssh_example.gif)\n\n### Read about how it works!\nCheck out [HowIDidIt.md](./resources/HowIDidIt.md)\n\n## More Examples\nThe quality of the window is limited to the number of rows and columns in your\nterminal. If you increase the resolution (ctrl - in alacritty, check your\nterminal) the quality will go up, (but performance may go down).\n\nHere I open up the Wing It! movie, and increase the quality until I get both\na good frame rate and resolution:\n\n![increase resolution](./resources/graphics/show_increase_res.gif)\n\n----------------\n\nIf your terminal supports images (like [kitty](https://sw.kovidgoyal.net/kitty/)\nor [iterm2](https://iterm2.com/)) you can render windows at full resolution\n(performance may degrade).\n\nIn this example, on my mac, I open iTerm2 ssh into ubuntu and open firefox\nat full resolution:\n\n![full_resultion](resources/graphics/full_resultion.gif)\n\n------------\n\nI feel like every single day I hear about another terminal file viewer. I say, stop making terminal file viewers because you can just use the file viewer you already have! In your terminal!\n\n![file_manager](./resources/graphics/file_manager.gif)\n\n-------------\n\nTerminal in a terminal in a terminal in a terminal in a terminal.... it's terminals all the way down.\n![terminal_in_terminal](./resources/graphics/terminal_in_terminal.gif)\n\n-------------\nWith only a small amount hacking, it can run Doom (shareware episode)!\n\n![Doom](./resources/graphics/doom.gif)\n------\nRun an entire Desktop in your terminal!\n[@ismail-yilmaz](https://github.com/ismail-yilmaz) is running Firefox, on [KDE Neon](https://neon.kde.org) in a [VM](https://gitlab.gnome.org/GNOME/gnome-boxes) on [Bobcat](https://github.com/ismail-yilmaz/Bobcat)\n![Desktop in VM](./resources/graphics/desktop_in_vm.gif)\n\nAnd this isn't even full resolution! Checkout the [full vid in in the discussions](https://github.com/mmulet/term.everything/discussions/16#discussioncomment-14390137)\n\n## About\n`term.everything❗` is a Linux CLI program to run GUI windows in your terminal. Specifically, `term.everything❗` is a built-from-scratch [Wayland](https://wiki.archlinux.org/title/Wayland) compositor that outputs to a terminal rather than your monitor.\n\n>Don't know what Wayland is or just want to know more about how this works? Then, head over to [HowIDidIt.md](./resources/HowIDidIt.md) where I will explain how everything works in detail.\n\n## Try it out!\n[Download the beta test now!](https://github.com/mmulet/term.everything/releases)\n\n## Roadmap\n1. [x] Term some things <--- This is where we are at\n  - Some apps or (even most apps) may fail to launch or even crash! Please create [an issue]( https://github.com/mmulet/term.everything/issues) if you have problems.\n2. [ ] Term most things\n3. [ ] Term everything❗\n\n## Help and Usage\nCheck out the [help file here](./resources/help.md) for a usage guide on how to use `term.everything❗`\n\n## Contributing\nterm.everything❗ is written in developer friendly [Go](https://go.dev/), with a just a smidge of C.\nSee [./Contributing.md](./Contributing.md).\n\n## Legal:\n\nterm.everything❗ copyright 2025 Late for Dinner Studios, LLC\n---\nFontemon copyright 2021 Late for Dinner Studios, LLC\n---\nWing It! movie is licensed under the Creative Commons Attribution 4.0 license\n[Wing it licensing page](https://studio.blender.org/projects/wing-it/pages/licensing/)\nAttribution:\n(CC) Blender Foundation | studio.blender.org\n---\nDoom shareware episode is copyright 1993 id Software\n---\n\n## Bonus:\nThis is Gwerm the Term Worm.\n\n![this is gwern](./resources/graphics/this_is_gwern.gif)\n\nHe is doing okay. Thanks for asking.\n"
  },
  {
    "path": "distribute.sh",
    "content": "#!/bin/bash\n\n# This script builds a distributable AppImage\n# of the term.everything application using Podman.\n\nPODMAN=\"podman \"\nAPP_NAME=\"term.everything❗mmulet.com-dont_forget_to_chmod_+x_this_file\"\n\n\nget_distro() {\n    if [ -f /etc/os-release ]; then\n        . /etc/os-release\n    else\n        echo \"unknown\"\n        return\n    fi\n\n    # Check ID first, then fall back to ID_LIKE\n    for id in $ID $ID_LIKE; do\n        case $id in\n            ubuntu|debian|linuxmint|pop)\n                echo \"sudo apt install -y\"\n                return\n                ;;\n            fedora)\n                echo \"sudo dnf install -y\"\n                return\n                ;;\n            centos|rhel|rocky|almalinux)\n                echo \"sudo yum install -y\"\n                return\n                ;;\n            arch|manjaro|cachyos|endeavouros|garuda)\n                echo \"sudo pacman -S\"\n                return\n                ;;\n            opensuse*|suse)\n                echo \"sudo zypper install\"\n                return\n                ;;\n            alpine)\n                echo \"sudo apk add\"\n                return\n                ;;\n            void)\n                echo \"sudo xbps-install -S\"\n                return\n                ;;\n            gentoo)\n                echo \"sudo emerge\"\n                return\n                ;;\n            nixos)\n                echo \"nix-env -iA nixpkgs.\"\n                return\n                ;;\n        esac\n    done\n\n    echo \"unknown\"\n}\n\nif ! command -v podman >/dev/null 2>&1; then\n    if command -v docker >/dev/null 2>&1; then\n        PODMAN=\"docker \"\n    else\n        INSTALL_CMD=$(get_distro)\n        echo \"Warning: podman is not installed or not in PATH.\"\n        echo \"To install on your system, try: $INSTALL_CMD podman\"\n        echo \"Please install podman to proceed, it's literally all you need. Don't even need attention. Just podman. Just get podman. What are you waiting for? Stop reading this and install podman.\"\n        exit 1\n    fi\n  \nfi\n\nif [ -z \"${PLATFORM+x}\" ]; then\n    PLATFORM_ARG=\"\"\nelse\n    PLATFORM_ARG=\"--platform $PLATFORM -e PLATFORM=$PLATFORM -e MULTI_PLATFORM=1 -e ARCH_PREFIX=$ARCH_PREFIX\"\nfi\n\n$PODMAN run \\\n    $PLATFORM_ARG \\\n    -it \\\n    --volume .:/home/mount \\\n    --rm alpine:latest /bin/sh /home/mount/resources/alpineCompile.sh && \\\necho \"Output is ./dist/$PLATFORM/static/$APP_NAME\"\n\n"
  },
  {
    "path": "escapecodes/AsiEscapeCodes.go",
    "content": "package escapecodes\n\nconst (\n\tDisableAlternativeScreenBuffer = \"\\x1b[?1049l\"\n\tEnableAlternativeScreenBuffer  = \"\\x1b[?1049h\"\n\tEnableSGR                      = \"\\x1b[?1006h\"\n\tEnableMouseTracking            = \"\\x1b[?1003h\"\n\tDisableMouseTracking           = \"\\x1b[?1003l\"\n\tDisableNormalMouseTracking     = \"\\x1b[?1000l\"\n\n\tHideCursor = \"\\x1b[?25l\"\n\tShowCursor = \"\\x1b[?25h\"\n\tReset      = \"\\x1b[0m\"\n\tFgBlack    = \"\\x1b[30m\"\n\tBgWhite    = \"\\x1b[47m\"\n\tFgWhite    = \"\\x1b[37m\"\n\tBgBlack    = \"\\x1b[40m\"\n\tFgRed      = \"\\x1b[31m\"\n\tBgRed      = \"\\x1b[41m\"\n\tFgGreen    = \"\\x1b[32m\"\n\tBgGreen    = \"\\x1b[42m\"\n\tFgYellow   = \"\\x1b[33m\"\n\tBgYellow   = \"\\x1b[43m\"\n\tFgBlue     = \"\\x1b[34m\"\n\tBgBlue     = \"\\x1b[44m\"\n\tFgMagenta  = \"\\x1b[35m\"\n\tBgMagenta  = \"\\x1b[45m\"\n\tFgCyan     = \"\\x1b[36m\"\n\tBgCyan     = \"\\x1b[46m\"\n\n\tBold          = \"\\x1b[1m\"\n\tDim           = \"\\x1b[2m\"\n\tItalic        = \"\\x1b[3m\"\n\tUnderline     = \"\\x1b[4m\"\n\tInverse       = \"\\x1b[7m\"\n\tHidden        = \"\\x1b[8m\"\n\tStrikethrough = \"\\x1b[9m\"\n\n\tMoveCursorToHome     = \"\\x1b[H\"\n\tClearScreen          = \"\\x1b[2J\"\n\tClearLine            = \"\\x1b[2K\"\n\tClearLineAfterCursor = \"\\x1b[0K\"\n)\n"
  },
  {
    "path": "framebuffertoansi/ChafaInfo.go",
    "content": "package framebuffertoansi\n\n// #cgo pkg-config: chafa glib-2.0\n// #include \"chafa.h\"\n// #include <glib.h>\n//\n// // Small helpers to safely access GString from Go.\n// static const char* gstring_str(const GString* s) { return s->str; }\n// static gsize gstring_len(const GString* s) { return s->len; }\n//\n// // Feature test for OCTANT availability to mimic the original #ifdef.\n// #ifdef CHAFA_VERSION_1_16\n// #define HAVE_CHAFA_OCTANT 1\n// static ChafaSymbolTags octant_symbol() { return CHAFA_SYMBOL_TAG_OCTANT; }\n// #else\n// #define HAVE_CHAFA_OCTANT 0\n// static ChafaSymbolTags octant_symbol() { return 0; }\n// #endif\n// static int chafa_have_octant() { return HAVE_CHAFA_OCTANT; }\n//\nimport \"C\"\nimport (\n\t\"os\"\n\t\"runtime\"\n\t\"unsafe\"\n)\n\ntype ChafaInfo struct {\n\tTermInfo  *C.ChafaTermInfo\n\tMode      C.ChafaCanvasMode\n\tPixelMode C.ChafaPixelMode\n\tSymbolMap *C.ChafaSymbolMap\n\tConfig    *C.ChafaCanvasConfig\n\tCanvas    *C.ChafaCanvas\n\n\tWidthCells            int\n\tHeightCells           int\n\tWidthOfACellInPixels  int\n\tHeightOfACellInPixels int\n\tSessionTypeIsX11      bool\n\tPixelTypeOverride     C.ChafaPixelType\n}\n\nfunc (ci *ChafaInfo) ConvertImage(texturePixels []byte, textureWidth, textureHeight, textureStride uint32) string {\n\tif len(texturePixels) == 0 {\n\t\treturn \"\"\n\t}\n\n\tpixelsPtr := (*C.guint8)(unsafe.Pointer(&texturePixels[0]))\n\n\tC.chafa_canvas_draw_all_pixels(\n\t\tci.Canvas,\n\t\tci.getPixelType(),\n\t\tpixelsPtr,\n\t\tC.int(textureWidth),\n\t\tC.int(textureHeight),\n\t\tC.int(textureStride),\n\t)\n\truntime.KeepAlive(texturePixels)\n\n\tgstr := C.chafa_canvas_print(ci.Canvas, ci.TermInfo)\n\tif gstr == nil {\n\t\treturn \"\"\n\t}\n\tdefer C.g_string_free(gstr, C.gboolean(1))\n\n\tptrStr := C.gstring_str(gstr)\n\tlength := C.gstring_len(gstr)\n\tif ptrStr == nil || length == 0 {\n\t\treturn \"\"\n\t}\n\treturn C.GoStringN((*C.char)(unsafe.Pointer(ptrStr)), C.int(length))\n}\n\nfunc MakeChafaInfo(widthCells, heightCells, widthOfACellInPixels, heightOfACellInPixels int, sessionTypeIsX11 bool) *ChafaInfo {\n\ttermInfo, mode, pixelMode := DetectTerminal()\n\n\tci := &ChafaInfo{\n\t\tTermInfo:              termInfo,\n\t\tMode:                  mode,\n\t\tPixelMode:             pixelMode,\n\t\tWidthCells:            widthCells,\n\t\tHeightCells:           heightCells,\n\t\tWidthOfACellInPixels:  widthOfACellInPixels,\n\t\tHeightOfACellInPixels: heightOfACellInPixels,\n\t\tSessionTypeIsX11:      sessionTypeIsX11,\n\t}\n\n\t// Symbol map from env override (or default)\n\tci.SymbolMap = C.chafa_symbol_map_new()\n\tC.chafa_symbol_map_add_by_tags(ci.SymbolMap, getChafaSymbolTags())\n\n\t// Canvas config\n\tci.Config = C.chafa_canvas_config_new()\n\tC.chafa_canvas_config_set_canvas_mode(ci.Config, ci.Mode)\n\tC.chafa_canvas_config_set_pixel_mode(ci.Config, ci.PixelMode)\n\tC.chafa_canvas_config_set_geometry(ci.Config, C.int(widthCells), C.int(heightCells))\n\tC.chafa_canvas_config_set_symbol_map(ci.Config, ci.SymbolMap)\n\t// chafa_canvas_config_set_optimizations(config, TRUE);\n\tC.chafa_canvas_config_set_work_factor(ci.Config, C.gfloat(0.0))\n\t// C.chafa_canvas_config_set_preprocessing_enabled(ci.Config, C.gboolean(0))\n\t// C.chafa_canvas_config_set_dither_intensity(ci.Config, C.CHAFA_DITHER_MODE_DIFFUSION)\n\n\tif widthOfACellInPixels > 0 && heightOfACellInPixels > 0 {\n\t\t/* We know the pixel dimensions of each cell. Store it in the config. */\n\n\t\tC.chafa_canvas_config_set_cell_geometry(ci.Config, C.int(widthOfACellInPixels), C.int(heightOfACellInPixels))\n\t}\n\n\tci.Canvas = C.chafa_canvas_new(ci.Config)\n\n\tci.PixelTypeOverride = getChafaPixelType()\n\n\treturn ci\n}\n\nfunc (ci *ChafaInfo) getPixelType() C.ChafaPixelType {\n\tif ci.PixelTypeOverride != C.CHAFA_PIXEL_MAX {\n\t\treturn ci.PixelTypeOverride\n\t}\n\tif ci.PixelMode == C.CHAFA_PIXEL_MODE_KITTY && !ci.SessionTypeIsX11 {\n\t\treturn C.CHAFA_PIXEL_RGBA8_UNASSOCIATED\n\t}\n\treturn C.CHAFA_PIXEL_BGRA8_UNASSOCIATED\n}\n\nfunc getChafaPixelType() C.ChafaPixelType {\n\tswitch os.Getenv(\"TERM_EVERYTHING_PIXEL_TYPE\") {\n\tcase \"\":\n\t\treturn C.CHAFA_PIXEL_MAX // No override\n\tcase \"RGBA8\":\n\t\treturn C.CHAFA_PIXEL_RGBA8_UNASSOCIATED\n\tcase \"BGRA8\":\n\t\treturn C.CHAFA_PIXEL_BGRA8_UNASSOCIATED\n\tcase \"ARGB8\":\n\t\treturn C.CHAFA_PIXEL_ARGB8_UNASSOCIATED\n\tcase \"ABGR8\":\n\t\treturn C.CHAFA_PIXEL_ABGR8_UNASSOCIATED\n\tcase \"RGBA8_PREMULTIPLIED\":\n\t\treturn C.CHAFA_PIXEL_RGBA8_PREMULTIPLIED\n\tcase \"BGRA8_PREMULTIPLIED\":\n\t\treturn C.CHAFA_PIXEL_BGRA8_PREMULTIPLIED\n\tcase \"ARGB8_PREMULTIPLIED\":\n\t\treturn C.CHAFA_PIXEL_ARGB8_PREMULTIPLIED\n\tcase \"ABGR8_PREMULTIPLIED\":\n\t\treturn C.CHAFA_PIXEL_ABGR8_PREMULTIPLIED\n\tdefault:\n\t\treturn C.CHAFA_PIXEL_MAX\n\t}\n}\n\nvar defaultSymbolTags = C.ChafaSymbolTags(C.CHAFA_SYMBOL_TAG_ALL)\n\nfunc getChafaSymbolTags() C.ChafaSymbolTags {\n\tswitch os.Getenv(\"TERM_EVERYTHING_SYMBOLS\") {\n\tcase \"\":\n\t\treturn defaultSymbolTags\n\tcase \"NONE\":\n\t\treturn C.CHAFA_SYMBOL_TAG_NONE\n\tcase \"SPACE\":\n\t\treturn C.CHAFA_SYMBOL_TAG_SPACE\n\tcase \"SOLID\":\n\t\treturn C.CHAFA_SYMBOL_TAG_SOLID\n\tcase \"STIPPLE\":\n\t\treturn C.CHAFA_SYMBOL_TAG_STIPPLE\n\tcase \"BLOCK\":\n\t\treturn C.CHAFA_SYMBOL_TAG_BLOCK\n\tcase \"BORDER\":\n\t\treturn C.CHAFA_SYMBOL_TAG_BORDER\n\tcase \"DIAGONAL\":\n\t\treturn C.CHAFA_SYMBOL_TAG_DIAGONAL\n\tcase \"DOT\":\n\t\treturn C.CHAFA_SYMBOL_TAG_DOT\n\tcase \"QUAD\":\n\t\treturn C.CHAFA_SYMBOL_TAG_QUAD\n\tcase \"HHALF\":\n\t\treturn C.CHAFA_SYMBOL_TAG_HHALF\n\tcase \"VHALF\":\n\t\treturn C.CHAFA_SYMBOL_TAG_VHALF\n\tcase \"HALF\":\n\t\treturn C.CHAFA_SYMBOL_TAG_HALF\n\tcase \"INVERTED\":\n\t\treturn C.CHAFA_SYMBOL_TAG_INVERTED\n\tcase \"BRAILLE\":\n\t\treturn C.CHAFA_SYMBOL_TAG_BRAILLE\n\tcase \"TECHNICAL\":\n\t\treturn C.CHAFA_SYMBOL_TAG_TECHNICAL\n\tcase \"GEOMETRIC\":\n\t\treturn C.CHAFA_SYMBOL_TAG_GEOMETRIC\n\tcase \"ASCII\":\n\t\treturn C.CHAFA_SYMBOL_TAG_ASCII\n\tcase \"ALPHA\":\n\t\treturn C.CHAFA_SYMBOL_TAG_ALPHA\n\tcase \"DIGIT\":\n\t\treturn C.CHAFA_SYMBOL_TAG_DIGIT\n\tcase \"ALNUM\":\n\t\treturn C.CHAFA_SYMBOL_TAG_ALNUM\n\tcase \"NARROW\":\n\t\treturn C.CHAFA_SYMBOL_TAG_NARROW\n\tcase \"WIDE\":\n\t\treturn C.CHAFA_SYMBOL_TAG_WIDE\n\tcase \"AMBIGUOUS\":\n\t\treturn C.CHAFA_SYMBOL_TAG_AMBIGUOUS\n\tcase \"UGLY\":\n\t\treturn C.CHAFA_SYMBOL_TAG_UGLY\n\tcase \"LEGACY\":\n\t\treturn C.CHAFA_SYMBOL_TAG_LEGACY\n\tcase \"SEXTANT\":\n\t\treturn C.CHAFA_SYMBOL_TAG_SEXTANT\n\tcase \"WEDGE\":\n\t\treturn C.CHAFA_SYMBOL_TAG_WEDGE\n\tcase \"LATIN\":\n\t\treturn C.CHAFA_SYMBOL_TAG_LATIN\n\tcase \"IMPORTED\":\n\t\treturn C.CHAFA_SYMBOL_TAG_IMPORTED\n\tcase \"OCTANT\":\n\t\tif C.chafa_have_octant() != 0 {\n\t\t\treturn C.ChafaSymbolTags(C.chafa_have_octant())\n\t\t}\n\t\treturn defaultSymbolTags\n\tcase \"ALL\":\n\t\treturn C.CHAFA_SYMBOL_TAG_ALL\n\tdefault:\n\t\treturn defaultSymbolTags\n\t}\n}\n\nfunc (ci *ChafaInfo) Destroy() {\n\tif ci == nil {\n\t\treturn\n\t}\n\tif ci.Canvas != nil {\n\t\tC.chafa_canvas_unref(ci.Canvas)\n\t\tci.Canvas = nil\n\t}\n\tif ci.Config != nil {\n\t\tC.chafa_canvas_config_unref(ci.Config)\n\t\tci.Config = nil\n\t}\n\tif ci.SymbolMap != nil {\n\t\tC.chafa_symbol_map_unref(ci.SymbolMap)\n\t\tci.SymbolMap = nil\n\t}\n\tif ci.TermInfo != nil {\n\t\tC.chafa_term_info_unref(ci.TermInfo)\n\t\tci.TermInfo = nil\n\t}\n}\n"
  },
  {
    "path": "framebuffertoansi/DetectTerminal.go",
    "content": "package framebuffertoansi\n\n// #cgo pkg-config: chafa glib-2.0\n// #include \"chafa.h\"\n// #include <glib.h>\n//\n// static ChafaTermInfo* detect_term_info_from_env() {\n//     gchar **envp = g_get_environ();\n//     ChafaTermInfo *term_info = chafa_term_db_detect(chafa_term_db_get_default(), envp);\n//     g_strfreev(envp);\n//     return term_info;\n// }\nimport \"C\"\nimport \"os\"\n\nfunc getDefaultPixelMode(termInfo *C.ChafaTermInfo) C.ChafaPixelMode {\n\tif C.chafa_term_info_have_seq(termInfo, C.CHAFA_TERM_SEQ_BEGIN_ITERM2_IMAGE) != 0 {\n\t\treturn C.CHAFA_PIXEL_MODE_ITERM2\n\t} else if C.chafa_term_info_have_seq(termInfo, C.CHAFA_TERM_SEQ_BEGIN_KITTY_IMMEDIATE_IMAGE_V1) != 0 {\n\t\treturn C.CHAFA_PIXEL_MODE_KITTY\n\t} else if C.chafa_term_info_have_seq(termInfo, C.CHAFA_TERM_SEQ_BEGIN_SIXELS) != 0 {\n\t\treturn C.CHAFA_PIXEL_MODE_SIXELS\n\t} else {\n\t\treturn C.CHAFA_PIXEL_MODE_SYMBOLS\n\t}\n}\n\nfunc getPixelModeOverride() string {\n\treturn os.Getenv(\"TERM_EVERYTHING_PIXEL_MODE\")\n}\n\nfunc getCanvasModeOverride() string {\n\treturn os.Getenv(\"TERM_EVERYTHING_CANVAS_MODE\")\n}\n\nfunc getPixelMode(termInfo *C.ChafaTermInfo) C.ChafaPixelMode {\n\toverride := getPixelModeOverride()\n\tif override == \"\" {\n\t\treturn getDefaultPixelMode(termInfo)\n\t}\n\tswitch override {\n\tcase \"SYMBOLS\":\n\t\treturn C.CHAFA_PIXEL_MODE_SYMBOLS\n\tcase \"SIXELS\":\n\t\treturn C.CHAFA_PIXEL_MODE_SIXELS\n\tcase \"KITTY\":\n\t\treturn C.CHAFA_PIXEL_MODE_KITTY\n\tcase \"ITERM2\":\n\t\treturn C.CHAFA_PIXEL_MODE_ITERM2\n\tdefault:\n\t\treturn getDefaultPixelMode(termInfo)\n\t}\n}\n\nfunc getDefaultCanvasMode(termInfo *C.ChafaTermInfo, pixelMode C.ChafaPixelMode) C.ChafaCanvasMode {\n\tswitch pixelMode {\n\tcase C.CHAFA_PIXEL_MODE_ITERM2, C.CHAFA_PIXEL_MODE_SIXELS, C.CHAFA_PIXEL_MODE_KITTY:\n\t\treturn C.CHAFA_CANVAS_MODE_TRUECOLOR\n\tcase C.CHAFA_PIXEL_MODE_SYMBOLS:\n\t\tfallthrough\n\tdefault:\n\t\tif C.chafa_term_info_have_seq(termInfo, C.CHAFA_TERM_SEQ_SET_COLOR_FGBG_DIRECT) != 0 &&\n\t\t\tC.chafa_term_info_have_seq(termInfo, C.CHAFA_TERM_SEQ_SET_COLOR_FG_DIRECT) != 0 &&\n\t\t\tC.chafa_term_info_have_seq(termInfo, C.CHAFA_TERM_SEQ_SET_COLOR_BG_DIRECT) != 0 {\n\t\t\treturn C.CHAFA_CANVAS_MODE_TRUECOLOR\n\t\t} else if C.chafa_term_info_have_seq(termInfo, C.CHAFA_TERM_SEQ_SET_COLOR_FGBG_256) != 0 &&\n\t\t\tC.chafa_term_info_have_seq(termInfo, C.CHAFA_TERM_SEQ_SET_COLOR_FG_256) != 0 &&\n\t\t\tC.chafa_term_info_have_seq(termInfo, C.CHAFA_TERM_SEQ_SET_COLOR_BG_256) != 0 {\n\t\t\treturn C.CHAFA_CANVAS_MODE_INDEXED_240\n\t\t} else if C.chafa_term_info_have_seq(termInfo, C.CHAFA_TERM_SEQ_SET_COLOR_FGBG_16) != 0 &&\n\t\t\tC.chafa_term_info_have_seq(termInfo, C.CHAFA_TERM_SEQ_SET_COLOR_FG_16) != 0 &&\n\t\t\tC.chafa_term_info_have_seq(termInfo, C.CHAFA_TERM_SEQ_SET_COLOR_BG_16) != 0 {\n\t\t\treturn C.CHAFA_CANVAS_MODE_INDEXED_16\n\t\t} else if C.chafa_term_info_have_seq(termInfo, C.CHAFA_TERM_SEQ_INVERT_COLORS) != 0 &&\n\t\t\tC.chafa_term_info_have_seq(termInfo, C.CHAFA_TERM_SEQ_RESET_ATTRIBUTES) != 0 {\n\t\t\treturn C.CHAFA_CANVAS_MODE_FGBG_BGFG\n\t\t} else {\n\t\t\treturn C.CHAFA_CANVAS_MODE_FGBG\n\t\t}\n\t}\n}\n\nfunc getCanvasMode(termInfo *C.ChafaTermInfo, pixelMode C.ChafaPixelMode) C.ChafaCanvasMode {\n\toverride := getCanvasModeOverride()\n\tif override == \"\" {\n\t\treturn getDefaultCanvasMode(termInfo, pixelMode)\n\t}\n\tswitch override {\n\tcase \"TRUECOLOR\":\n\t\treturn C.CHAFA_CANVAS_MODE_TRUECOLOR\n\tcase \"INDEXED_256\":\n\t\treturn C.CHAFA_CANVAS_MODE_INDEXED_256\n\tcase \"INDEXED_240\":\n\t\treturn C.CHAFA_CANVAS_MODE_INDEXED_240\n\tcase \"INDEXED_16\":\n\t\treturn C.CHAFA_CANVAS_MODE_INDEXED_16\n\tcase \"FGBG_BGFG\":\n\t\treturn C.CHAFA_CANVAS_MODE_FGBG_BGFG\n\tcase \"FGBG\":\n\t\treturn C.CHAFA_CANVAS_MODE_FGBG\n\tcase \"INDEXED_8\":\n\t\treturn C.CHAFA_CANVAS_MODE_INDEXED_8\n\tcase \"INDEXED_16_8\":\n\t\treturn C.CHAFA_CANVAS_MODE_INDEXED_16_8\n\tdefault:\n\t\treturn getDefaultCanvasMode(termInfo, pixelMode)\n\t}\n}\n\nfunc DetectTerminal() (termInfo *C.ChafaTermInfo, mode C.ChafaCanvasMode, pixelMode C.ChafaPixelMode) {\n\ttermInfo = C.detect_term_info_from_env()\n\tif getPixelModeOverride() != \"\" ||\n\t\tgetCanvasModeOverride() != \"\" {\n\t\t/* Make sure we have fallback sequences in case the user forces\n\t\t * a mode that's technically unsupported by the terminal. */\n\t\tfallback_info := C.chafa_term_db_get_fallback_info(C.chafa_term_db_get_default())\n\t\tC.chafa_term_info_supplement(termInfo, fallback_info)\n\t\tC.chafa_term_info_unref(fallback_info)\n\t}\n\n\tpixelMode = getPixelMode(termInfo)\n\tmode = getCanvasMode(termInfo, pixelMode)\n\treturn\n}\n"
  },
  {
    "path": "framebuffertoansi/DrawState.go",
    "content": "package framebuffertoansi\n\n// #cgo pkg-config: chafa glib-2.0\n// #include \"chafa.h\"\nimport \"C\"\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\t\"unsafe\"\n\n\t\"github.com/mmulet/term.everything/escapecodes\"\n)\n\ntype DrawState struct {\n\tSessionTypeIsX11 bool\n\tChafaInfo        *ChafaInfo\n}\n\nfunc MakeDrawState(sessionTypeIsX11 bool) *DrawState {\n\treturn &DrawState{\n\t\tSessionTypeIsX11: sessionTypeIsX11,\n\t}\n}\n\nfunc (ds *DrawState) ResizeChafaInfoIfNeeded(WidthCells int, HeightCells int, termSize TermSize) {\n\n\tif ds.ChafaInfo != nil && !(ds.ChafaInfo.WidthCells == WidthCells &&\n\t\tds.ChafaInfo.HeightCells == HeightCells &&\n\t\tds.ChafaInfo.WidthOfACellInPixels == termSize.WidthOfACellInPixels &&\n\t\tds.ChafaInfo.HeightOfACellInPixels == termSize.HeightOfACellInPixels) {\n\t\tds.ChafaInfo.Destroy()\n\t\tds.ChafaInfo = nil\n\t}\n\tif ds.ChafaInfo != nil {\n\t\treturn\n\t}\n\n\tds.ChafaInfo = MakeChafaInfo(WidthCells,\n\t\tHeightCells,\n\t\ttermSize.WidthOfACellInPixels,\n\t\ttermSize.HeightOfACellInPixels,\n\t\tds.SessionTypeIsX11)\n}\n\nfunc (ds *DrawState) Destroy() {\n\tif ds.ChafaInfo != nil {\n\t\tds.ChafaInfo.Destroy()\n\t\tds.ChafaInfo = nil\n\t}\n}\n\nfunc (ds *DrawState) DrawDesktop(texturePixels []byte, width, height uint32, statusLine *string) (int, int) {\n\thaveStatusLine := statusLine != nil && len(*statusLine) > 0\n\ttermSize := MakeTermSize()\n\n\twidthCells := termSize.WidthCells\n\n\tstatusLineHeight := 0\n\tif haveStatusLine {\n\t\tstatusLineHeight = 1\n\t}\n\n\theightCells := termSize.HeightCells - statusLineHeight\n\n\t// Adjust geometry preserving aspect ratio.\n\tC.chafa_calc_canvas_geometry(\n\t\tC.int(width),\n\t\tC.int(height),\n\t\t(*C.int)(unsafe.Pointer(&widthCells)),\n\t\t(*C.int)(unsafe.Pointer(&heightCells)),\n\t\tC.gfloat(termSize.FontRatio),\n\t\tC.gboolean(1), // preserve aspect\n\t\tC.gboolean(0), // do not upscale\n\t)\n\n\tds.ResizeChafaInfoIfNeeded(widthCells, heightCells, termSize)\n\n\tprintable := ds.ChafaInfo.ConvertImage(texturePixels, width, height, width*4)\n\n\tvar sb strings.Builder\n\tif haveStatusLine {\n\t\tsb.WriteString(escapecodes.MoveCursorToHome)\n\t\tsb.WriteString(*statusLine)\n\t\tsb.WriteString(escapecodes.ClearLineAfterCursor)\n\t\tsb.WriteString(\"\\n\")\n\n\t}\n\tsb.WriteString(printable)\n\n\tfmt.Fprint(os.Stdout, sb.String())\n\t_ = os.Stdout.Sync()\n\n\treturn widthCells, heightCells\n}\n"
  },
  {
    "path": "framebuffertoansi/Readme.md",
    "content": "Convert a framebuffer (bytes) with pixel data into ANSI escape codes for terminal display.\n\n## Usage\n\n```go\ndrawState := framebuffertoansi.MakeDrawState(true)\nvar grid []byte = ...\nwidth := 80\nheight := 24\ndrawState.DrawDesktop(grid, uint32(width), uint32(height), \"Hello, world!\")\n```"
  },
  {
    "path": "framebuffertoansi/TermSize.go",
    "content": "package framebuffertoansi\n\nimport (\n\t\"os\"\n\t\"syscall\"\n\t\"unsafe\"\n)\n\ntype TermSize struct {\n\tWidthCells  int\n\tHeightCells int\n\n\tWidthPixels  int\n\tHeightPixels int\n\n\tFontRatio float64\n\n\tWidthOfACellInPixels  int\n\tHeightOfACellInPixels int\n}\ntype WinSize struct {\n\tRow    uint16\n\tCol    uint16\n\tXpixel uint16\n\tYpixel uint16\n}\n\nfunc MakeTermSize() TermSize {\n\tts := TermSize{\n\t\tWidthCells:            -1,\n\t\tHeightCells:           -1,\n\t\tWidthPixels:           -1,\n\t\tHeightPixels:          -1,\n\t\tWidthOfACellInPixels:  -1,\n\t\tHeightOfACellInPixels: -1,\n\t\tFontRatio:             0.5,\n\t}\n\n\ttryFDs := []uintptr{os.Stdout.Fd(), os.Stderr.Fd(), os.Stdin.Fd()}\n\tfor _, fd := range tryFDs {\n\t\tif ws, err := GetWinsize(fd); err == nil {\n\t\t\tts.WidthCells = int(ws.Col)\n\t\t\tts.HeightCells = int(ws.Row)\n\t\t\tts.WidthPixels = int(ws.Xpixel)\n\t\t\tts.HeightPixels = int(ws.Ypixel)\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif ts.WidthCells <= 0 {\n\t\tts.WidthCells = -1\n\t}\n\tif ts.HeightCells <= 2 {\n\t\tts.HeightCells = -1\n\t}\n\n\tif ts.WidthPixels <= 0 || ts.HeightPixels <= 0 {\n\t\tts.WidthPixels = -1\n\t\tts.HeightPixels = -1\n\t}\n\n\tif ts.WidthCells > 0 && ts.HeightCells > 0 && ts.WidthPixels > 0 && ts.HeightPixels > 0 {\n\t\tts.WidthOfACellInPixels = ts.WidthPixels / ts.WidthCells\n\t\tts.HeightOfACellInPixels = ts.HeightPixels / ts.HeightCells\n\t\tif ts.HeightOfACellInPixels > 0 {\n\t\t\tts.FontRatio = float64(ts.WidthOfACellInPixels) / float64(ts.HeightOfACellInPixels)\n\t\t}\n\t} else {\n\t\tts.WidthOfACellInPixels = -1\n\t\tts.HeightOfACellInPixels = -1\n\t\tts.FontRatio = 0.5\n\t}\n\n\treturn ts\n}\n\nfunc GetWinsize(fd uintptr) (WinSize, error) {\n\tvar ws WinSize\n\t_, _, errno := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(&ws)))\n\tif errno != 0 {\n\t\treturn ws, errno\n\t}\n\treturn ws, nil\n}\n"
  },
  {
    "path": "go.mod",
    "content": "module github.com/mmulet/term.everything\n\ngo 1.25.2\n"
  },
  {
    "path": "main.go",
    "content": "package main\n\nimport (\n\t\"github.com/mmulet/term.everything/termeverything\"\n)\n\n//go:generate go generate ./wayland\n\nfunc main() {\n\ttermeverything.MainLoop()\n}\n"
  },
  {
    "path": "resources/HowIDidIt.md",
    "content": "# How I Did It!\n\nA long long time ago, when a program wanted to draw something to the screen, it\ncould just write to a certain spot in RAM. The screen was a wild west and anyone\ncould draw anywhere anytime.\n\nNowadays, display access is coordinated by a special program called the\n[Display Server](https://en.wikipedia.org/wiki/Windowing_system#Display_server),\nwhich \"coordinates the input and output of its clients to and from the rest of\nthe operating system, the hardware and each other\". With input being mouse/keyboard/etc\nand output being graphics, images, anything you see in a \"window\".\n\nOn modern linux, for display servers most systems use either the [Wayland (protocol)](https://en.wikipedia.org/wiki/Wayland_(protocol)) or [x11](https://en.wikipedia.org/wiki/X_Window_System).\nWe're going to focus on Wayland, mostly because it's newer and there are systems in place\nto run older x11 apps in wayland for backwards compatibility.\n\n## Wayland (protocol)\nNotice that it's Wayland *protocol* not wayland display-server. That's because\nWayland is not a display server. It's a [protocol](https://en.wikipedia.org/wiki/Communication_protocol); it'a a way for programs to communicate\nto a hypothetical display server. When people say that their system is running \nWayland, what they really mean is that their system is running a display server\nthat speaks the wayland protocol.\n\nWhat's even better\nis that Wayland does not have a set [Rendering Model](https://en.wikipedia.org/wiki/Wayland_(protocol)#Rendering_model), the programs decide entirely on their own how they\nwill draw their \"windows\" or other graphics, then they just hand it over to the\ndisplay server.\n\n## How to draw\nThe wayland protocol actually has no opinion on what you do with the graphics the\nprograms give you. Sure, they probably expect that you will use [Kernel Mode Setting](https://en.wikipedia.org/wiki/Mode_setting), but really if you wanted to, you could print\nout the graphics and give them to a league of crochet grandmas to individually\ntie together every single pixel into the afghan of legend! The programs would never be the wiser.\n\nAgain, the main benefit of wayland is that the programs don't care\nhow they get input as long as it *gets input*, and it doesn't care what happens to\nits output.\n\nSo, this means we can do anything we want, so let's output to the terminal!\n\nI take the output given to us by the client and convert the images to terminal\noutput, the utf8 characters with ansi escape codes via the [chafa library](https://github.com/hpjansson/chafa/). For input, I take the keyboard and mouse (yes terminals support mice)\nfrom the stdin. And that's it! Of course, there are about 10K lines of code needed to actually do this in practice, but if you're interested in that I invite you to [check out the source code](../termeverything/).\n\n## What else can you do with wayland\nI have many other crazy ideas of what else to do custom wayland display server, so stay tuned.\n"
  },
  {
    "path": "resources/alpineCompile.sh",
    "content": "#!/bin/sh\n\ncat > /etc/apk/repositories << EOF\nhttps://dl-cdn.alpinelinux.org/alpine/edge/main\nhttps://dl-cdn.alpinelinux.org/alpine/edge/community\nEOF\n\napk update\napk add chafa-dev go glib-static pcre2-static make\n# Because I'm paranoid, remove the shared libs\n# just not to tempt the linker\nrm /usr/lib/libchafa.so*\n\ncd /home/mount\nmake clean\nSTATIC_BUILD=1 make"
  },
  {
    "path": "resources/multiplatform.sh",
    "content": "#!/bin/bash\n\n\nPLATFORM=linux/aarch64 ARCH_PREFIX=ARM- ./distribute.sh\nPLATFORM=linux/amd64 ARCH_PREFIX= ./distribute.sh"
  },
  {
    "path": "termeverything/ConvertKeycodeToXbdCode.go",
    "content": "package termeverything\n\n// /**\n//   - According to sleuthing here are the mod makes\n//   - 1 << 0 Shift\n//   - 1 << 1 Lock\n//   - 1 << 2 Control\n//   - 1 << 3 Alt\n//   - 1 << 4 Mod2\n//   - 1 << 5 Mod3\n//   - 1 << 6 Mod4\n//   - 1 << 7 Mod5\n//   - 1 << 8 Button1\n//   - 1 << 9 Button2\n//   - 1 << 10 Button3\n//   - 1 << 11 Button4\n//   - 1 << 12 Button5\nconst (\n\tModShift   = 1 << 0\n\tModLock    = 1 << 1\n\tModControl = 1 << 2\n\tModAlt     = 1 << 3\n)\n\n// numericKeys and alphaKeys exported here for KeycodeSingleCodes.go\nvar numericKeys = []Linux_Event_Codes{\n\tKEY_0,\n\tKEY_1,\n\tKEY_2,\n\tKEY_3,\n\tKEY_4,\n\tKEY_5,\n\tKEY_6,\n\tKEY_7,\n\tKEY_8,\n\tKEY_9,\n}\n\nvar alphaKeys = []Linux_Event_Codes{\n\tKEY_A,\n\tKEY_B,\n\tKEY_C,\n\tKEY_D,\n\tKEY_E,\n\tKEY_F,\n\tKEY_G,\n\tKEY_H,\n\tKEY_I,\n\tKEY_J,\n\tKEY_K,\n\tKEY_L,\n\tKEY_M,\n\tKEY_N,\n\tKEY_O,\n\tKEY_P,\n\tKEY_Q,\n\tKEY_R,\n\tKEY_S,\n\tKEY_T,\n\tKEY_U,\n\tKEY_V,\n\tKEY_W,\n\tKEY_X,\n\tKEY_Y,\n\tKEY_Z,\n}\n\ntype XkbdCode interface {\n\tisXkbdCode()\n\tOrModifiers(int)\n\tGetModifiers() int\n}\n\nfunc (*KeyCode) isXkbdCode() {}\n\ntype KeyCode struct {\n\tKeyCode   Linux_Event_Codes\n\tModifiers int\n}\n\nfunc (k *KeyCode) OrModifiers(modifiers int) {\n\tk.Modifiers |= modifiers\n}\n\nfunc (k *KeyCode) GetModifiers() int {\n\treturn k.Modifiers\n}\n\nfunc ConvertKeycodeToXbdCode(data []byte) []XkbdCode {\n\tif len(data) == 1 {\n\t\tif out := KeycodeSingleCodes(int(data[0])); out != nil {\n\t\t\treturn []XkbdCode{out}\n\t\t}\n\t\treturn nil\n\t}\n\tif len(data) == 2 {\n\t\treturn parse_length_2(data)\n\t}\n\tif len(data) == 3 {\n\t\treturn parse_length_3(data)\n\t}\n\tif data[0] == 27 && data[1] == 91 && data[2] == 60 {\n\t\treturn ParseSGRMouseSequences(data)\n\t}\n\n\tif len(data) == 4 {\n\t\treturn parse_length_4(data)\n\t}\n\tif len(data) == 5 {\n\t\tif data[0] == 27 && data[1] == 91 && data[4] == 126 {\n\t\t\tif data[2] == 49 {\n\t\t\t\tif keyCode, ok := f5_through_8_codes[data[3]]; ok {\n\t\t\t\t\treturn []XkbdCode{&KeyCode{KeyCode: keyCode, Modifiers: 0}}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif data[2] == 50 {\n\t\t\t\tif keyCode, ok := f9_through_12_codes[data[3]]; ok {\n\t\t\t\t\treturn []XkbdCode{&KeyCode{KeyCode: keyCode, Modifiers: 0}}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif len(data)%6 == 0 {\n\t\tout := make([]XkbdCode, 0)\n\t\tnumEvents := len(data) / 6\n\t\tfor i := range numEvents {\n\t\t\tslice := data[i*6 : (i+1)*6]\n\t\t\tif slice[0] == 27 && slice[1] == 91 && slice[3] == 59 {\n\t\t\t\tswitch slice[2] {\n\t\t\t\tcase 49: // '1'\n\t\t\t\t\tif modifiers := modifiers_for_arrow_and_page_up_etc(slice[4]); modifiers > 0 {\n\t\t\t\t\t\teventOut := parse_length_3([]byte{27, 91, slice[5]})\n\t\t\t\t\t\tif len(eventOut) > 0 {\n\t\t\t\t\t\t\tfor _, e := range eventOut {\n\t\t\t\t\t\t\t\te.OrModifiers(modifiers)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tout = append(out, eventOut...)\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\tcase 50, 51, 52, 53, 54: // '2'..'6'\n\t\t\t\t\tif modifiers := modifiers_for_arrow_and_page_up_etc(slice[4]); slice[5] == 126 && modifiers > 0 {\n\t\t\t\t\t\teventOut := parse_length_4([]byte{27, 91, slice[2], 126})\n\t\t\t\t\t\tif len(eventOut) > 0 {\n\t\t\t\t\t\t\tfor _, e := range eventOut {\n\t\t\t\t\t\t\t\te.OrModifiers(modifiers)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tout = append(out, eventOut...)\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// if value := PointerCode(slice); value != nil {\n\t\t\t// \tout = append(out, value)\n\t\t\t// }\n\t\t}\n\t\treturn out\n\t}\n\n\tif len(data) == 7 {\n\t\tif data[0] == 27 && data[1] == 91 && data[4] == 59 && data[6] == 126 {\n\t\t\tif modifiers := modifiers_for_arrow_and_page_up_etc(data[5]); modifiers > 0 {\n\t\t\t\tif data[2] == 49 {\n\t\t\t\t\tif keyCode, ok := f5_through_8_codes[data[3]]; ok {\n\t\t\t\t\t\treturn []XkbdCode{&KeyCode{KeyCode: keyCode, Modifiers: modifiers}}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif data[2] == 50 {\n\t\t\t\t\tif keyCode, ok := f9_through_12_codes[data[3]]; ok {\n\t\t\t\t\t\treturn []XkbdCode{&KeyCode{KeyCode: keyCode, Modifiers: modifiers}}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Unrecognized\n\t// TODO maybe return error here?\n\treturn nil\n}\n\nfunc parse_length_2(data []byte) []XkbdCode {\n\tif len(data) < 2 {\n\t\treturn nil\n\t}\n\tif data[0] == 27 {\n\t\tout := KeycodeSingleCodes(int(data[1]))\n\t\tif out == nil {\n\t\t\treturn nil\n\t\t}\n\t\tout.Modifiers |= ModAlt\n\t\treturn []XkbdCode{out}\n\t}\n\tout := make([]XkbdCode, 0, 2)\n\tif out1 := KeycodeSingleCodes(int(data[0])); out1 != nil {\n\t\tout = append(out, out1)\n\t}\n\tif out2 := KeycodeSingleCodes(int(data[1])); out2 != nil {\n\t\tout = append(out, out2)\n\t}\n\treturn out\n}\n\nfunc parse_length_3(data []byte) []XkbdCode {\n\tif len(data) < 3 {\n\t\treturn nil\n\t}\n\tif data[0] != 27 {\n\t\ta := KeycodeSingleCodes(int(data[0]))\n\t\tb := parse_length_2(data[1:])\n\t\tif a != nil {\n\t\t\treturn append([]XkbdCode{a}, b...)\n\t\t}\n\t\treturn b\n\t}\n\tif data[1] == 79 { // 'O'\n\t\tswitch data[2] {\n\t\tcase 80: // 'P'\n\t\t\treturn []XkbdCode{&KeyCode{KeyCode: KEY_F1, Modifiers: 0}}\n\t\tcase 81: // 'Q'\n\t\t\treturn []XkbdCode{&KeyCode{KeyCode: KEY_F2, Modifiers: 0}}\n\t\tcase 82: // 'R'\n\t\t\treturn []XkbdCode{&KeyCode{KeyCode: KEY_F3, Modifiers: 0}}\n\t\tcase 83: // 'S'\n\t\t\treturn []XkbdCode{&KeyCode{KeyCode: KEY_F4, Modifiers: 0}}\n\t\t}\n\t}\n\tif data[1] == 91 { // '['\n\t\tswitch data[2] {\n\t\tcase 65: // 'A'\n\t\t\treturn []XkbdCode{&KeyCode{KeyCode: KEY_UP, Modifiers: 0}}\n\t\tcase 66: // 'B'\n\t\t\treturn []XkbdCode{&KeyCode{KeyCode: KEY_DOWN, Modifiers: 0}}\n\t\tcase 67: // 'C'\n\t\t\treturn []XkbdCode{&KeyCode{KeyCode: KEY_RIGHT, Modifiers: 0}}\n\t\tcase 68: // 'D'\n\t\t\treturn []XkbdCode{&KeyCode{KeyCode: KEY_LEFT, Modifiers: 0}}\n\t\tcase 70: // 'F'\n\t\t\treturn []XkbdCode{&KeyCode{KeyCode: KEY_END, Modifiers: 0}}\n\t\tcase 72: // 'H'\n\t\t\treturn []XkbdCode{&KeyCode{KeyCode: KEY_HOME, Modifiers: 0}}\n\t\tcase 90: // 'Z' => Shift+Tab\n\t\t\treturn []XkbdCode{&KeyCode{KeyCode: KEY_TAB, Modifiers: ModShift}}\n\t\t// These work for alt+F1, shift+F2, etc in some terminals\n\t\tcase 80: // 'P'\n\t\t\treturn []XkbdCode{&KeyCode{KeyCode: KEY_F1, Modifiers: 0}}\n\t\tcase 81: // 'Q'\n\t\t\treturn []XkbdCode{&KeyCode{KeyCode: KEY_F2, Modifiers: 0}}\n\t\tcase 82: // 'R'\n\t\t\treturn []XkbdCode{&KeyCode{KeyCode: KEY_F3, Modifiers: 0}}\n\t\tcase 83: // 'S'\n\t\t\treturn []XkbdCode{&KeyCode{KeyCode: KEY_F4, Modifiers: 0}}\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc modifiers_for_arrow_and_page_up_etc(slice4 byte) int {\n\tswitch slice4 {\n\tcase 50: // '2'\n\t\treturn ModShift\n\tcase 51: // '3'\n\t\treturn ModAlt\n\tcase 52: // '4'\n\t\treturn ModShift | ModAlt\n\tcase 53: // '5'\n\t\treturn ModControl\n\tcase 54: // '6'\n\t\treturn ModControl | ModShift\n\tdefault:\n\t\treturn -1\n\t}\n}\n\nfunc parse_length_4(data []byte) []XkbdCode {\n\tif len(data) < 4 {\n\t\treturn nil\n\t}\n\tif data[0] != 27 {\n\t\ta := KeycodeSingleCodes(int(data[0]))\n\t\tb := parse_length_3(data[1:])\n\t\tif a != nil {\n\t\t\treturn append([]XkbdCode{a}, b...)\n\t\t}\n\t\treturn b\n\t}\n\tif data[1] == 91 { // '['\n\t\tif data[2] == 50 && data[3] == 126 { // \"2~\"\n\t\t\treturn []XkbdCode{&KeyCode{KeyCode: KEY_INSERT, Modifiers: 0}}\n\t\t}\n\t\tif data[2] == 51 && data[3] == 126 { // \"3~\"\n\t\t\treturn []XkbdCode{&KeyCode{KeyCode: KEY_DELETE, Modifiers: 0}}\n\t\t}\n\t\tif data[2] == 53 && data[3] == 126 { // \"5~\"\n\t\t\treturn []XkbdCode{&KeyCode{KeyCode: KEY_PAGEUP, Modifiers: 0}}\n\t\t}\n\t\tif data[2] == 54 && data[3] == 126 { // \"6~\"\n\t\t\treturn []XkbdCode{&KeyCode{KeyCode: KEY_PAGEDOWN, Modifiers: 0}}\n\t\t}\n\t}\n\treturn nil\n}\n\nvar f5_through_8_codes = map[byte]Linux_Event_Codes{\n\t53: KEY_F5, // '5'\n\t55: KEY_F6, // '7'\n\t56: KEY_F7, // '8'\n\t57: KEY_F8, // '9'\n}\n\nvar f9_through_12_codes = map[byte]Linux_Event_Codes{\n\t48: KEY_F9,  // '0'\n\t49: KEY_F10, // '1'\n\t51: KEY_F11, // '3'\n\t52: KEY_F12, // '4'\n}\n"
  },
  {
    "path": "termeverything/DisplayServerType.go",
    "content": "package termeverything\n\nimport \"os\"\n\ntype DisplayServerTypeEnum int\n\nconst (\n\tDisplayServerTypeUnknown DisplayServerTypeEnum = iota\n\tDisplayServerTypeX11\n\tDisplayServerTypeWayland\n)\n\nfunc DisplayServerType() DisplayServerTypeEnum {\n\n\tif displayType, ok := os.LookupEnv(\"XDG_SESSION_TYPE\"); ok {\n\n\t\tswitch displayType {\n\t\tcase \"x11\":\n\t\t\treturn DisplayServerTypeX11\n\t\tcase \"wayland\":\n\t\t\treturn DisplayServerTypeWayland\n\t\t}\n\t}\n\treturn DisplayServerTypeUnknown\n}\n"
  },
  {
    "path": "termeverything/KeycodeSingleCodes.go",
    "content": "package termeverything\n\nimport \"fmt\"\n\nfunc KeycodeSingleCodes(d int) *KeyCode {\n\tif d >= 1 && d <= 26 {\n\t\t/**\n\t\t * @TODO not sure what to do about the\n\t\t * ctrl+keys that are shadowed\n\t\t * by these keys\n\t\t */\n\t\tswitch d {\n\t\tcase 3, 9, 13:\n\t\t\t// skip (handled below)\n\t\tdefault:\n\t\t\treturn &KeyCode{\n\t\t\t\tKeyCode:   alphaKeys[d-1],\n\t\t\t\tModifiers: ModControl,\n\t\t\t}\n\t\t}\n\t}\n\n\tif d >= 48 && d <= 57 {\n\t\treturn &KeyCode{\n\t\t\tKeyCode:   numericKeys[d-48],\n\t\t\tModifiers: 0,\n\t\t}\n\t}\n\n\tif d >= 65 && d <= 90 {\n\t\treturn &KeyCode{\n\t\t\tKeyCode:   alphaKeys[d-65],\n\t\t\tModifiers: ModShift,\n\t\t}\n\t}\n\n\tif d >= 97 && d <= 122 {\n\t\treturn &KeyCode{\n\t\t\tKeyCode:   alphaKeys[d-97],\n\t\t\tModifiers: 0,\n\t\t}\n\t}\n\n\tswitch d {\n\tcase 33: // !\n\t\treturn &KeyCode{KeyCode: KEY_1, Modifiers: ModShift}\n\tcase 64: // @\n\t\treturn &KeyCode{KeyCode: KEY_2, Modifiers: ModShift}\n\tcase 35: // #\n\t\treturn &KeyCode{KeyCode: KEY_3, Modifiers: ModShift}\n\tcase 36: // $\n\t\treturn &KeyCode{KeyCode: KEY_4, Modifiers: ModShift}\n\tcase 37: // %\n\t\treturn &KeyCode{KeyCode: KEY_5, Modifiers: ModShift}\n\tcase 34: // \"\n\t\treturn &KeyCode{KeyCode: KEY_APOSTROPHE, Modifiers: ModShift}\n\tcase 39: // '\n\t\treturn &KeyCode{KeyCode: KEY_APOSTROPHE, Modifiers: 0}\n\tcase 94: // ^\n\t\treturn &KeyCode{KeyCode: KEY_6, Modifiers: ModShift}\n\tcase 38: // &\n\t\treturn &KeyCode{KeyCode: KEY_7, Modifiers: ModShift}\n\tcase 42: // *\n\t\treturn &KeyCode{KeyCode: KEY_8, Modifiers: ModShift}\n\tcase 40: // (\n\t\treturn &KeyCode{KeyCode: KEY_9, Modifiers: ModShift}\n\tcase 41: // )\n\t\treturn &KeyCode{KeyCode: KEY_0, Modifiers: ModShift}\n\n\tcase 3: // escape (as per original TS)\n\t\treturn &KeyCode{KeyCode: KEY_ESC, Modifiers: 0}\n\tcase 27: // escape (shift)\n\t\treturn &KeyCode{KeyCode: KEY_ESC, Modifiers: ModShift}\n\n\tcase 96: // `\n\t\treturn &KeyCode{KeyCode: KEY_GRAVE, Modifiers: 0}\n\tcase 126: // ~\n\t\treturn &KeyCode{KeyCode: KEY_GRAVE, Modifiers: ModShift}\n\n\tcase 45: // -\n\t\treturn &KeyCode{KeyCode: KEY_MINUS, Modifiers: 0}\n\tcase 95: // _\n\t\treturn &KeyCode{KeyCode: KEY_MINUS, Modifiers: ModShift}\n\n\tcase 61: // =\n\t\treturn &KeyCode{KeyCode: KEY_EQUAL, Modifiers: 0}\n\tcase 43: // +\n\t\treturn &KeyCode{KeyCode: KEY_EQUAL, Modifiers: ModShift}\n\n\tcase 8: // CTRL+backspace (overshadowed by CTRL+H)\n\t\treturn &KeyCode{KeyCode: KEY_BACKSPACE, Modifiers: ModControl}\n\tcase 127: // backspace\n\t\treturn &KeyCode{KeyCode: KEY_BACKSPACE, Modifiers: 0}\n\n\tcase 9: // tab\n\t\treturn &KeyCode{KeyCode: KEY_TAB, Modifiers: 0}\n\tcase 13: // enter\n\t\treturn &KeyCode{KeyCode: KEY_ENTER, Modifiers: 0}\n\n\tcase 32: // space\n\t\treturn &KeyCode{KeyCode: KEY_SPACE, Modifiers: 0}\n\tcase 0: // ctrl + space\n\t\treturn &KeyCode{KeyCode: KEY_SPACE, Modifiers: ModControl}\n\n\tcase 59: // ;\n\t\treturn &KeyCode{KeyCode: KEY_SEMICOLON, Modifiers: 0}\n\tcase 58: // :\n\t\treturn &KeyCode{KeyCode: KEY_SEMICOLON, Modifiers: ModShift}\n\n\tcase 91: // [\n\t\treturn &KeyCode{KeyCode: KEY_LEFTBRACE, Modifiers: 0}\n\tcase 123: // {\n\t\treturn &KeyCode{KeyCode: KEY_LEFTBRACE, Modifiers: ModShift}\n\n\tcase 93: // ]\n\t\treturn &KeyCode{KeyCode: KEY_RIGHTBRACE, Modifiers: 0}\n\tcase 125: // }\n\t\treturn &KeyCode{KeyCode: KEY_RIGHTBRACE, Modifiers: ModShift}\n\tcase 129: // ctrl+]\n\t\treturn &KeyCode{KeyCode: KEY_RIGHTBRACE, Modifiers: ModControl}\n\n\tcase 92: // \\\n\t\treturn &KeyCode{KeyCode: KEY_BACKSLASH, Modifiers: 0}\n\tcase 124: // |\n\t\treturn &KeyCode{KeyCode: KEY_BACKSLASH, Modifiers: ModShift}\n\n\tcase 44: // ,\n\t\treturn &KeyCode{KeyCode: KEY_COMMA, Modifiers: 0}\n\tcase 60: // <\n\t\treturn &KeyCode{KeyCode: KEY_COMMA, Modifiers: ModShift}\n\n\tcase 46: // .\n\t\treturn &KeyCode{KeyCode: KEY_DOT, Modifiers: 0}\n\tcase 62: // >\n\t\treturn &KeyCode{KeyCode: KEY_DOT, Modifiers: ModShift}\n\n\tcase 47: // /\n\t\treturn &KeyCode{KeyCode: KEY_SLASH, Modifiers: 0}\n\tcase 63: // ?\n\t\treturn &KeyCode{KeyCode: KEY_SLASH, Modifiers: ModShift}\n\tcase 31: // ctrl+/\n\t\treturn &KeyCode{KeyCode: KEY_SLASH, Modifiers: ModControl}\n\t}\n\n\tfmt.Printf(\"Unrecognized key code: %d\\n\", d)\n\treturn nil\n}\n"
  },
  {
    "path": "termeverything/LinuxEventCodes.go",
    "content": "package termeverything\n\n/**\n * @see [input-event-codes.h](https://github.com/torvalds/linux/blob/master/include/uapi/linux/input-event-codes.h)\n */\ntype Linux_Event_Codes int\n\nconst (\n\tKEY_RESERVED   Linux_Event_Codes = 0\n\tKEY_ESC        Linux_Event_Codes = 1\n\tKEY_1          Linux_Event_Codes = 2\n\tKEY_2          Linux_Event_Codes = 3\n\tKEY_3          Linux_Event_Codes = 4\n\tKEY_4          Linux_Event_Codes = 5\n\tKEY_5          Linux_Event_Codes = 6\n\tKEY_6          Linux_Event_Codes = 7\n\tKEY_7          Linux_Event_Codes = 8\n\tKEY_8          Linux_Event_Codes = 9\n\tKEY_9          Linux_Event_Codes = 10\n\tKEY_0          Linux_Event_Codes = 11\n\tKEY_MINUS      Linux_Event_Codes = 12\n\tKEY_EQUAL      Linux_Event_Codes = 13\n\tKEY_BACKSPACE  Linux_Event_Codes = 14\n\tKEY_TAB        Linux_Event_Codes = 15\n\tKEY_Q          Linux_Event_Codes = 16\n\tKEY_W          Linux_Event_Codes = 17\n\tKEY_E          Linux_Event_Codes = 18\n\tKEY_R          Linux_Event_Codes = 19\n\tKEY_T          Linux_Event_Codes = 20\n\tKEY_Y          Linux_Event_Codes = 21\n\tKEY_U          Linux_Event_Codes = 22\n\tKEY_I          Linux_Event_Codes = 23\n\tKEY_O          Linux_Event_Codes = 24\n\tKEY_P          Linux_Event_Codes = 25\n\tKEY_LEFTBRACE  Linux_Event_Codes = 26\n\tKEY_RIGHTBRACE Linux_Event_Codes = 27\n\tKEY_ENTER      Linux_Event_Codes = 28\n\tKEY_LEFTCTRL   Linux_Event_Codes = 29\n\tKEY_A          Linux_Event_Codes = 30\n\tKEY_S          Linux_Event_Codes = 31\n\tKEY_D          Linux_Event_Codes = 32\n\tKEY_F          Linux_Event_Codes = 33\n\tKEY_G          Linux_Event_Codes = 34\n\tKEY_H          Linux_Event_Codes = 35\n\tKEY_J          Linux_Event_Codes = 36\n\tKEY_K          Linux_Event_Codes = 37\n\tKEY_L          Linux_Event_Codes = 38\n\tKEY_SEMICOLON  Linux_Event_Codes = 39\n\tKEY_APOSTROPHE Linux_Event_Codes = 40\n\tKEY_GRAVE      Linux_Event_Codes = 41\n\tKEY_LEFTSHIFT  Linux_Event_Codes = 42\n\tKEY_BACKSLASH  Linux_Event_Codes = 43\n\tKEY_Z          Linux_Event_Codes = 44\n\tKEY_X          Linux_Event_Codes = 45\n\tKEY_C          Linux_Event_Codes = 46\n\tKEY_V          Linux_Event_Codes = 47\n\tKEY_B          Linux_Event_Codes = 48\n\tKEY_N          Linux_Event_Codes = 49\n\tKEY_M          Linux_Event_Codes = 50\n\tKEY_COMMA      Linux_Event_Codes = 51\n\tKEY_DOT        Linux_Event_Codes = 52\n\tKEY_SLASH      Linux_Event_Codes = 53\n\tKEY_RIGHTSHIFT Linux_Event_Codes = 54\n\tKEY_KPASTERISK Linux_Event_Codes = 55\n\tKEY_LEFTALT    Linux_Event_Codes = 56\n\tKEY_SPACE      Linux_Event_Codes = 57\n\tKEY_CAPSLOCK   Linux_Event_Codes = 58\n\tKEY_F1         Linux_Event_Codes = 59\n\tKEY_F2         Linux_Event_Codes = 60\n\tKEY_F3         Linux_Event_Codes = 61\n\tKEY_F4         Linux_Event_Codes = 62\n\tKEY_F5         Linux_Event_Codes = 63\n\tKEY_F6         Linux_Event_Codes = 64\n\tKEY_F7         Linux_Event_Codes = 65\n\tKEY_F8         Linux_Event_Codes = 66\n\tKEY_F9         Linux_Event_Codes = 67\n\tKEY_F10        Linux_Event_Codes = 68\n\tKEY_NUMLOCK    Linux_Event_Codes = 69\n\tKEY_SCROLLLOCK Linux_Event_Codes = 70\n\tKEY_KP7        Linux_Event_Codes = 71\n\tKEY_KP8        Linux_Event_Codes = 72\n\tKEY_KP9        Linux_Event_Codes = 73\n\tKEY_KPMINUS    Linux_Event_Codes = 74\n\tKEY_KP4        Linux_Event_Codes = 75\n\tKEY_KP5        Linux_Event_Codes = 76\n\tKEY_KP6        Linux_Event_Codes = 77\n\tKEY_KPPLUS     Linux_Event_Codes = 78\n\tKEY_KP1        Linux_Event_Codes = 79\n\tKEY_KP2        Linux_Event_Codes = 80\n\tKEY_KP3        Linux_Event_Codes = 81\n\tKEY_KP0        Linux_Event_Codes = 82\n\tKEY_KPDOT      Linux_Event_Codes = 83\n\n\tKEY_ZENKAKUHANKAKU   Linux_Event_Codes = 85\n\tKEY_102ND            Linux_Event_Codes = 86\n\tKEY_F11              Linux_Event_Codes = 87\n\tKEY_F12              Linux_Event_Codes = 88\n\tKEY_RO               Linux_Event_Codes = 89\n\tKEY_KATAKANA         Linux_Event_Codes = 90\n\tKEY_HIRAGANA         Linux_Event_Codes = 91\n\tKEY_HENKAN           Linux_Event_Codes = 92\n\tKEY_KATAKANAHIRAGANA Linux_Event_Codes = 93\n\tKEY_MUHENKAN         Linux_Event_Codes = 94\n\tKEY_KPJPCOMMA        Linux_Event_Codes = 95\n\tKEY_KPENTER          Linux_Event_Codes = 96\n\tKEY_RIGHTCTRL        Linux_Event_Codes = 97\n\tKEY_KPSLASH          Linux_Event_Codes = 98\n\tKEY_SYSRQ            Linux_Event_Codes = 99\n\tKEY_RIGHTALT         Linux_Event_Codes = 100\n\tKEY_LINEFEED         Linux_Event_Codes = 101\n\tKEY_HOME             Linux_Event_Codes = 102\n\tKEY_UP               Linux_Event_Codes = 103\n\tKEY_PAGEUP           Linux_Event_Codes = 104\n\tKEY_LEFT             Linux_Event_Codes = 105\n\tKEY_RIGHT            Linux_Event_Codes = 106\n\tKEY_END              Linux_Event_Codes = 107\n\tKEY_DOWN             Linux_Event_Codes = 108\n\tKEY_PAGEDOWN         Linux_Event_Codes = 109\n\tKEY_INSERT           Linux_Event_Codes = 110\n\tKEY_DELETE           Linux_Event_Codes = 111\n\tKEY_MACRO            Linux_Event_Codes = 112\n\tKEY_MUTE             Linux_Event_Codes = 113\n\tKEY_VOLUMEDOWN       Linux_Event_Codes = 114\n\tKEY_VOLUMEUP         Linux_Event_Codes = 115\n\tKEY_POWER            Linux_Event_Codes = 116 /* SC System Power Down */\n\tKEY_KPEQUAL          Linux_Event_Codes = 117\n\tKEY_KPPLUSMINUS      Linux_Event_Codes = 118\n\tKEY_PAUSE            Linux_Event_Codes = 119\n\tKEY_SCALE            Linux_Event_Codes = 120 /* AL Compiz Scale (Expose) */\n\n\tKEY_KPCOMMA Linux_Event_Codes = 121\n\tKEY_HANGEUL Linux_Event_Codes = 122\n\t// KEY_HANGUEL same as KEY_HANGEUL\n\tKEY_HANJA      Linux_Event_Codes = 123\n\tKEY_YEN        Linux_Event_Codes = 124\n\tKEY_LEFTMETA   Linux_Event_Codes = 125\n\tKEY_RIGHTMETA  Linux_Event_Codes = 126\n\tKEY_COMPOSE    Linux_Event_Codes = 127\n\tKEY_STOP       Linux_Event_Codes = 128 /* AC Stop */\n\tKEY_AGAIN      Linux_Event_Codes = 129\n\tKEY_PROPS      Linux_Event_Codes = 130 /* AC Properties */\n\tKEY_UNDO       Linux_Event_Codes = 131 /* AC Undo */\n\tKEY_FRONT      Linux_Event_Codes = 132\n\tKEY_COPY       Linux_Event_Codes = 133 /* AC Copy */\n\tKEY_OPEN       Linux_Event_Codes = 134 /* AC Open */\n\tKEY_PASTE      Linux_Event_Codes = 135 /* AC Paste */\n\tKEY_FIND       Linux_Event_Codes = 136 /* AC Search */\n\tKEY_CUT        Linux_Event_Codes = 137 /* AC Cut */\n\tKEY_HELP       Linux_Event_Codes = 138 /* AL Integrated Help Center */\n\tKEY_MENU       Linux_Event_Codes = 139 /* Menu (show menu) */\n\tKEY_CALC       Linux_Event_Codes = 140 /* AL Calculator */\n\tKEY_SETUP      Linux_Event_Codes = 141\n\tKEY_SLEEP      Linux_Event_Codes = 142 /* SC System Sleep */\n\tKEY_WAKEUP     Linux_Event_Codes = 143 /* System Wake Up */\n\tKEY_FILE       Linux_Event_Codes = 144 /* AL Local Machine Browser */\n\tKEY_SENDFILE   Linux_Event_Codes = 145\n\tKEY_DELETEFILE Linux_Event_Codes = 146\n\tKEY_XFER       Linux_Event_Codes = 147\n\tKEY_PROG1      Linux_Event_Codes = 148\n\tKEY_PROG2      Linux_Event_Codes = 149\n\tKEY_WWW        Linux_Event_Codes = 150 /* AL Internet Browser */\n\tKEY_MSDOS      Linux_Event_Codes = 151\n\tKEY_COFFEE     Linux_Event_Codes = 152 /* AL Terminal Lock/Screensaver */\n\t// KEY_SCREENLOCK same as KEY_COFFEE\n\tKEY_ROTATE_DISPLAY Linux_Event_Codes = 153 /* Display orientation */\n\t// KEY_DIRECTION same as KEY_ROTATE_DISPLAY\n\tKEY_CYCLEWINDOWS Linux_Event_Codes = 154\n\tKEY_MAIL         Linux_Event_Codes = 155\n\tKEY_BOOKMARKS    Linux_Event_Codes = 156 /* AC Bookmarks */\n\tKEY_COMPUTER     Linux_Event_Codes = 157\n\tKEY_BACK         Linux_Event_Codes = 158 /* AC Back */\n\tKEY_FORWARD      Linux_Event_Codes = 159 /* AC Forward */\n\tKEY_CLOSECD      Linux_Event_Codes = 160\n\tKEY_EJECTCD      Linux_Event_Codes = 161\n\tKEY_EJECTCLOSECD Linux_Event_Codes = 162\n\tKEY_NEXTSONG     Linux_Event_Codes = 163\n\tKEY_PLAYPAUSE    Linux_Event_Codes = 164\n\tKEY_PREVIOUSSONG Linux_Event_Codes = 165\n\tKEY_STOPCD       Linux_Event_Codes = 166\n\tKEY_RECORD       Linux_Event_Codes = 167\n\tKEY_REWIND       Linux_Event_Codes = 168\n\tKEY_PHONE        Linux_Event_Codes = 169 /* Media Select Telephone */\n\tKEY_ISO          Linux_Event_Codes = 170\n\tKEY_CONFIG       Linux_Event_Codes = 171 /* AL Consumer Control Configuration */\n\tKEY_HOMEPAGE     Linux_Event_Codes = 172 /* AC Home */\n\tKEY_REFRESH      Linux_Event_Codes = 173 /* AC Refresh */\n\tKEY_EXIT         Linux_Event_Codes = 174 /* AC Exit */\n\tKEY_MOVE         Linux_Event_Codes = 175\n\tKEY_EDIT         Linux_Event_Codes = 176\n\tKEY_SCROLLUP     Linux_Event_Codes = 177\n\tKEY_SCROLLDOWN   Linux_Event_Codes = 178\n\tKEY_KPLEFTPAREN  Linux_Event_Codes = 179\n\tKEY_KPRIGHTPAREN Linux_Event_Codes = 180\n\tKEY_NEW          Linux_Event_Codes = 181 /* AC New */\n\tKEY_REDO         Linux_Event_Codes = 182 /* AC Redo/Repeat */\n\n\tKEY_F13 Linux_Event_Codes = 183\n\tKEY_F14 Linux_Event_Codes = 184\n\tKEY_F15 Linux_Event_Codes = 185\n\tKEY_F16 Linux_Event_Codes = 186\n\tKEY_F17 Linux_Event_Codes = 187\n\tKEY_F18 Linux_Event_Codes = 188\n\tKEY_F19 Linux_Event_Codes = 189\n\tKEY_F20 Linux_Event_Codes = 190\n\tKEY_F21 Linux_Event_Codes = 191\n\tKEY_F22 Linux_Event_Codes = 192\n\tKEY_F23 Linux_Event_Codes = 193\n\tKEY_F24 Linux_Event_Codes = 194\n\n\tKEY_PLAYCD           Linux_Event_Codes = 200\n\tKEY_PAUSECD          Linux_Event_Codes = 201\n\tKEY_PROG3            Linux_Event_Codes = 202\n\tKEY_PROG4            Linux_Event_Codes = 203\n\tKEY_ALL_APPLICATIONS Linux_Event_Codes = 204 /* AC Desktop Show All Applications */\n\t// KEY_DASHBOARD same as KEY_ALL_APPLICATIONS\n\tKEY_SUSPEND        Linux_Event_Codes = 205\n\tKEY_CLOSE          Linux_Event_Codes = 206 /* AC Close */\n\tKEY_PLAY           Linux_Event_Codes = 207\n\tKEY_FASTFORWARD    Linux_Event_Codes = 208\n\tKEY_BASSBOOST      Linux_Event_Codes = 209\n\tKEY_PRINT          Linux_Event_Codes = 210 /* AC Print */\n\tKEY_HP             Linux_Event_Codes = 211\n\tKEY_CAMERA         Linux_Event_Codes = 212\n\tKEY_SOUND          Linux_Event_Codes = 213\n\tKEY_QUESTION       Linux_Event_Codes = 214\n\tKEY_EMAIL          Linux_Event_Codes = 215\n\tKEY_CHAT           Linux_Event_Codes = 216\n\tKEY_SEARCH         Linux_Event_Codes = 217\n\tKEY_CONNECT        Linux_Event_Codes = 218\n\tKEY_FINANCE        Linux_Event_Codes = 219 /* AL Checkbook/Finance */\n\tKEY_SPORT          Linux_Event_Codes = 220\n\tKEY_SHOP           Linux_Event_Codes = 221\n\tKEY_ALTERASE       Linux_Event_Codes = 222\n\tKEY_CANCEL         Linux_Event_Codes = 223 /* AC Cancel */\n\tKEY_BRIGHTNESSDOWN Linux_Event_Codes = 224\n\tKEY_BRIGHTNESSUP   Linux_Event_Codes = 225\n\tKEY_MEDIA          Linux_Event_Codes = 226\n\n\tKEY_SWITCHVIDEOMODE Linux_Event_Codes = 227 /* Cycle video outputs */\n\tKEY_KBDILLUMTOGGLE  Linux_Event_Codes = 228\n\tKEY_KBDILLUMDOWN    Linux_Event_Codes = 229\n\tKEY_KBDILLUMUP      Linux_Event_Codes = 230\n\n\tKEY_SEND             Linux_Event_Codes = 231 /* AC Send */\n\tKEY_REPLY            Linux_Event_Codes = 232 /* AC Reply */\n\tKEY_FORWARDMAIL      Linux_Event_Codes = 233 /* AC Forward Msg */\n\tKEY_SAVE             Linux_Event_Codes = 234 /* AC Save */\n\tKEY_DOCUMENTS        Linux_Event_Codes = 235\n\tKEY_BATTERY          Linux_Event_Codes = 236\n\tKEY_BLUETOOTH        Linux_Event_Codes = 237\n\tKEY_WLAN             Linux_Event_Codes = 238\n\tKEY_UWB              Linux_Event_Codes = 239\n\tKEY_UNKNOWN          Linux_Event_Codes = 240\n\tKEY_VIDEO_NEXT       Linux_Event_Codes = 241\n\tKEY_VIDEO_PREV       Linux_Event_Codes = 242\n\tKEY_BRIGHTNESS_CYCLE Linux_Event_Codes = 243\n\tKEY_BRIGHTNESS_AUTO  Linux_Event_Codes = 244\n\t// KEY_BRIGHTNESS_ZERO same as KEY_BRIGHTNESS_AUTO\n\tKEY_DISPLAY_OFF Linux_Event_Codes = 245\n\tKEY_WWAN        Linux_Event_Codes = 246\n\t// KEY_WIMAX same as KEY_WWAN\n\tKEY_RFKILL  Linux_Event_Codes = 247\n\tKEY_MICMUTE Linux_Event_Codes = 248\n)\n\n// LINUX_BUTTON_CODES corresponds to Linux button codes.\n// @see input-event-codes.h\ntype LINUX_BUTTON_CODES int\n\nconst (\n\tBTN_MISC LINUX_BUTTON_CODES = 0x100\n\tBTN_0    LINUX_BUTTON_CODES = 0x100\n\tBTN_1    LINUX_BUTTON_CODES = 0x101\n\tBTN_2    LINUX_BUTTON_CODES = 0x102\n\tBTN_3    LINUX_BUTTON_CODES = 0x103\n\tBTN_4    LINUX_BUTTON_CODES = 0x104\n\tBTN_5    LINUX_BUTTON_CODES = 0x105\n\tBTN_6    LINUX_BUTTON_CODES = 0x106\n\tBTN_7    LINUX_BUTTON_CODES = 0x107\n\tBTN_8    LINUX_BUTTON_CODES = 0x108\n\tBTN_9    LINUX_BUTTON_CODES = 0x109\n\n\tBTN_MOUSE   LINUX_BUTTON_CODES = 0x110\n\tBTN_LEFT    LINUX_BUTTON_CODES = 0x110\n\tBTN_RIGHT   LINUX_BUTTON_CODES = 0x111\n\tBTN_MIDDLE  LINUX_BUTTON_CODES = 0x112\n\tBTN_SIDE    LINUX_BUTTON_CODES = 0x113\n\tBTN_EXTRA   LINUX_BUTTON_CODES = 0x114\n\tBTN_FORWARD LINUX_BUTTON_CODES = 0x115\n\tBTN_BACK    LINUX_BUTTON_CODES = 0x116\n\tBTN_TASK    LINUX_BUTTON_CODES = 0x117\n\n\tBTN_JOYSTICK LINUX_BUTTON_CODES = 0x120\n\tBTN_TRIGGER  LINUX_BUTTON_CODES = 0x120\n\tBTN_THUMB    LINUX_BUTTON_CODES = 0x121\n\tBTN_THUMB2   LINUX_BUTTON_CODES = 0x122\n\tBTN_TOP      LINUX_BUTTON_CODES = 0x123\n\tBTN_TOP2     LINUX_BUTTON_CODES = 0x124\n\tBTN_PINKIE   LINUX_BUTTON_CODES = 0x125\n\tBTN_BASE     LINUX_BUTTON_CODES = 0x126\n\tBTN_BASE2    LINUX_BUTTON_CODES = 0x127\n\tBTN_BASE3    LINUX_BUTTON_CODES = 0x128\n\tBTN_BASE4    LINUX_BUTTON_CODES = 0x129\n\tBTN_BASE5    LINUX_BUTTON_CODES = 0x12a\n\tBTN_BASE6    LINUX_BUTTON_CODES = 0x12b\n\tBTN_DEAD     LINUX_BUTTON_CODES = 0x12f\n\n\tBTN_GAMEPAD LINUX_BUTTON_CODES = 0x130\n\tBTN_SOUTH   LINUX_BUTTON_CODES = 0x130\n\tBTN_A       LINUX_BUTTON_CODES = BTN_SOUTH\n\tBTN_EAST    LINUX_BUTTON_CODES = 0x131\n\tBTN_B       LINUX_BUTTON_CODES = BTN_EAST\n\tBTN_C       LINUX_BUTTON_CODES = 0x132\n\tBTN_NORTH   LINUX_BUTTON_CODES = 0x133\n\tBTN_X       LINUX_BUTTON_CODES = BTN_NORTH\n\tBTN_WEST    LINUX_BUTTON_CODES = 0x134\n\tBTN_Y       LINUX_BUTTON_CODES = BTN_WEST\n\tBTN_Z       LINUX_BUTTON_CODES = 0x135\n\tBTN_TL      LINUX_BUTTON_CODES = 0x136\n\tBTN_TR      LINUX_BUTTON_CODES = 0x137\n\tBTN_TL2     LINUX_BUTTON_CODES = 0x138\n\tBTN_TR2     LINUX_BUTTON_CODES = 0x139\n\tBTN_SELECT  LINUX_BUTTON_CODES = 0x13a\n\tBTN_START   LINUX_BUTTON_CODES = 0x13b\n\tBTN_MODE    LINUX_BUTTON_CODES = 0x13c\n\tBTN_THUMBL  LINUX_BUTTON_CODES = 0x13d\n\tBTN_THUMBR  LINUX_BUTTON_CODES = 0x13e\n\n\tBTN_DIGI           LINUX_BUTTON_CODES = 0x140\n\tBTN_TOOL_PEN       LINUX_BUTTON_CODES = 0x140\n\tBTN_TOOL_RUBBER    LINUX_BUTTON_CODES = 0x141\n\tBTN_TOOL_BRUSH     LINUX_BUTTON_CODES = 0x142\n\tBTN_TOOL_PENCIL    LINUX_BUTTON_CODES = 0x143\n\tBTN_TOOL_AIRBRUSH  LINUX_BUTTON_CODES = 0x144\n\tBTN_TOOL_FINGER    LINUX_BUTTON_CODES = 0x145\n\tBTN_TOOL_MOUSE     LINUX_BUTTON_CODES = 0x146\n\tBTN_TOOL_LENS      LINUX_BUTTON_CODES = 0x147\n\tBTN_TOOL_QUINTTAP  LINUX_BUTTON_CODES = 0x148 /* Five fingers on trackpad */\n\tBTN_STYLUS3        LINUX_BUTTON_CODES = 0x149\n\tBTN_TOUCH          LINUX_BUTTON_CODES = 0x14a\n\tBTN_STYLUS         LINUX_BUTTON_CODES = 0x14b\n\tBTN_STYLUS2        LINUX_BUTTON_CODES = 0x14c\n\tBTN_TOOL_DOUBLETAP LINUX_BUTTON_CODES = 0x14d\n\tBTN_TOOL_TRIPLETAP LINUX_BUTTON_CODES = 0x14e\n\tBTN_TOOL_QUADTAP   LINUX_BUTTON_CODES = 0x14f /* Four fingers on trackpad */\n\n\tBTN_WHEEL     LINUX_BUTTON_CODES = 0x150\n\tBTN_GEAR_DOWN LINUX_BUTTON_CODES = 0x150\n\tBTN_GEAR_UP   LINUX_BUTTON_CODES = 0x151\n)\n"
  },
  {
    "path": "termeverything/MainLoop.go",
    "content": "package termeverything\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"os/exec\"\n\t\"strings\"\n\n\t\"github.com/mmulet/term.everything/wayland\"\n)\n\nfunc MainLoop() {\n\targs := ParseArgs()\n\tSetVirtualMonitorSize(args.VirtualMonitorSize)\n\tlistener, err := wayland.MakeSocketListener(&args)\n\tif err != nil {\n\t\tfmt.Fprintf(os.Stderr, \"Failed to create socket listener: %v\\n\", err)\n\t\tos.Exit(1)\n\t}\n\n\tdisplaySize := wayland.Size{\n\t\tWidth:  uint32(wayland.VirtualMonitorSize.Width),\n\t\tHeight: uint32(wayland.VirtualMonitorSize.Height),\n\t}\n\n\tterminalWindow := MakeTerminalWindow(listener,\n\t\tdisplaySize,\n\t\t&args,\n\t)\n\n\tterminanDrawLoop := MakeTerminalDrawLoop(\n\t\tdisplaySize,\n\t\targs.HideStatusBar,\n\t\tlen(args.Positionals) > 0,\n\t\tterminalWindow.SharedRenderedScreenSize,\n\t\tterminalWindow.FrameEvents,\n\t\t&args,\n\t)\n\n\tgo listener.MainLoopThenClose()\n\tgo terminalWindow.InputLoop()\n\tgo terminanDrawLoop.MainLoop()\n\n\tdone := make(chan struct{})\n\tgo func() {\n\t\tfor {\n\t\t\tconn := <-listener.OnConnection\n\t\t\tclient := wayland.MakeClient(conn)\n\t\t\tterminalWindow.GetClients <- client\n\t\t\tterminanDrawLoop.GetClients <- client\n\t\t\tgo client.MainLoop()\n\t\t}\n\t}()\n\n\tif len(args.Positionals) > 0 {\n\t\tcmdStr := strings.Join(args.Positionals, \" \")\n\t\tshell := args.Shell\n\t\tcmd := exec.Command(shell, \"-c\", cmdStr)\n\n\t\tbaseEnv := os.Environ()\n\t\tfiltered := make([]string, 0, len(baseEnv))\n\t\tfor _, e := range baseEnv {\n\t\t\tif strings.HasPrefix(e, \"DISPLAY=\") {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif !args.SupportOldApps && strings.HasPrefix(e, \"XDG_SESSION_TYPE=\") {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tfiltered = append(filtered, e)\n\t\t}\n\t\tfiltered = append(filtered, fmt.Sprintf(\"WAYLAND_DISPLAY=%s\", listener.WaylandDisplayName))\n\t\tif !args.SupportOldApps {\n\t\t\tfiltered = append(filtered, \"XDG_SESSION_TYPE=wayland\")\n\t\t}\n\n\t\tcmd.Env = filtered\n\t\t// cmd.Stdout = os.Stdout\n\t\t// cmd.Stderr = os.Stderr\n\t\t// cmd.Stdin = os.Stdin\n\n\t\tif err := cmd.Start(); err != nil {\n\t\t\tfmt.Fprintf(os.Stderr, \"Failed to start command: %v\\n\", err)\n\t\t} else {\n\t\t\tgo func() {\n\t\t\t\t_ = cmd.Wait()\n\t\t\t}()\n\t\t}\n\t}\n\n\t<-done\n\n\t//TODO start xwaylnd_if_neccessary\n\n\t// // Wait for SigInt, TODO something different\n\t// sig := make(chan os.Signal, 1)\n\t// signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)\n\t// <-sig\n\t// _ = listener.Close()\n\t// fmt.Println(\"Shutdown complete\")\n}\n"
  },
  {
    "path": "termeverything/ParseArgs.go",
    "content": "package termeverything\n\nimport (\n\t\"flag\"\n\t\"fmt\"\n\t\"os\"\n\n\t_ \"embed\"\n)\n\n//go:embed resources/help.md\nvar helpFile string\n\n//go:embed resources/LICENSES.txt\nvar licensesFile string\n\nconst version = \"0.7.6\"\n\ntype CommandLineArgs struct {\n\tWaylandDisplayNameArg string\n\tSupportOldApps        bool\n\tXwayland              string\n\tXwaylandWM            string\n\tShell                 string\n\tHideStatusBar         bool\n\tVirtualMonitorSize    string\n\tDebugLog              bool\n\tReverseScroll         bool\n\tMaxFrameRate          string\n\tPositionals           []string\n}\n\nfunc (args *CommandLineArgs) WaylandDisplayName() string {\n\treturn args.WaylandDisplayNameArg\n}\n\nfunc ParseArgs() CommandLineArgs {\n\tvar args CommandLineArgs\n\n\tflag.StringVar(&args.WaylandDisplayNameArg, \"wayland-display-name\", \"\", \"\")\n\tflag.BoolVar(&args.SupportOldApps, \"support-old-apps\", false, \"\")\n\tflag.StringVar(&args.Xwayland, \"xwayland\", \"\", \"\")\n\tflag.StringVar(&args.XwaylandWM, \"xwayland-wm\", \"\", \"\")\n\tflag.StringVar(&args.Shell, \"shell\", \"/bin/bash\", \"\")\n\tflag.BoolVar(&args.HideStatusBar, \"hide-status-bar\", false, \"\")\n\tflag.StringVar(&args.VirtualMonitorSize, \"virtual-monitor-size\", \"\", \"\")\n\tversionFlag := flag.Bool(\"version\", false, \"\")\n\tflag.BoolVar(&args.DebugLog, \"debug-log\", false, \"\")\n\thelpFlag := flag.Bool(\"help\", false, \"\")\n\thFlag := flag.Bool(\"h\", false, \"help\") // short option for help\n\tlicensesFlag := flag.Bool(\"licenses\", false, \"\")\n\tflag.BoolVar(&args.ReverseScroll, \"reverse-scroll\", false, \"\")\n\tflag.StringVar(&args.MaxFrameRate, \"max-frame-rate\", \"\", \"\")\n\n\tflag.Parse()\n\n\tif *versionFlag {\n\t\tfmt.Println(version)\n\t\tos.Exit(0)\n\t}\n\tif *helpFlag || *hFlag {\n\t\tfmt.Println(RenderMarkdownToTerminal(helpFile))\n\t\tos.Exit(0)\n\t}\n\tif *licensesFlag {\n\t\tfmt.Println(licensesFile)\n\t\tos.Exit(0)\n\t}\n\n\targs.Positionals = flag.Args()\n\treturn args\n}\n"
  },
  {
    "path": "termeverything/PointerCode.go",
    "content": "package termeverything\n\nimport (\n\t\"strconv\"\n\t\"strings\"\n)\n\ntype PointerEvent interface {\n\tisPointerEvent()\n\tisXkbdCode()\n\tOrModifiers(int)\n\tGetModifiers() int\n}\n\ntype PointerMove struct {\n\tRow       int\n\tCol       int\n\tModifiers int\n}\n\nfunc (*PointerMove) isPointerEvent() {}\nfunc (*PointerMove) isXkbdCode()     {}\nfunc (p *PointerMove) OrModifiers(modifiers int) {\n\tp.Modifiers |= modifiers\n}\n\nfunc (p *PointerMove) GetModifiers() int {\n\treturn p.Modifiers\n}\n\ntype PointerButtonPress struct {\n\tModifiers                 int\n\tNeedToReleaseOtherButtons bool\n\tButton                    LINUX_BUTTON_CODES\n}\n\nfunc (*PointerButtonPress) isPointerEvent() {}\nfunc (*PointerButtonPress) isXkbdCode()     {}\nfunc (p *PointerButtonPress) OrModifiers(modifiers int) {\n\tp.Modifiers |= modifiers\n}\n\nfunc (p *PointerButtonPress) GetModifiers() int {\n\treturn p.Modifiers\n}\n\n/**\n * Pointer button release is special\n * because we can't be sure of which\n * button is being released\n */\ntype PointerButtonRelease struct {\n\tButton              LINUX_BUTTON_CODES\n\tNeedsButtonGuessing bool\n\tModifiers           int\n}\n\nfunc (*PointerButtonRelease) isPointerEvent() {}\nfunc (*PointerButtonRelease) isXkbdCode()     {}\nfunc (p *PointerButtonRelease) OrModifiers(modifiers int) {\n\tp.Modifiers |= modifiers\n}\n\nfunc (p *PointerButtonRelease) GetModifiers() int {\n\treturn p.Modifiers\n}\n\ntype PointerWheel struct {\n\tUp        bool\n\tModifiers int\n}\n\nfunc (*PointerWheel) isPointerEvent() {}\nfunc (*PointerWheel) isXkbdCode()     {}\nfunc (p *PointerWheel) OrModifiers(modifiers int) {\n\tp.Modifiers |= modifiers\n}\n\nfunc (p *PointerWheel) GetModifiers() int {\n\treturn p.Modifiers\n}\n\nfunc MouseModifiers(code, base int) int {\n\tmodeType := code - base\n\tmodifiers := 0\n\tif (modeType & 0b1000) != 0 {\n\t\tmodifiers |= ModControl\n\t}\n\tif (modeType & 0b1_0000) != 0 {\n\t\tmodifiers |= ModAlt\n\t}\n\treturn modifiers\n}\n\nfunc ParseMouseCode(code string) XkbdCode {\n\tparts := strings.Split(code, \";\")\n\tif len(parts) != 3 {\n\t\treturn nil\n\t}\n\tbuttonPart := parts[0]\n\tcolPart := parts[1]\n\trowAndTermPart := parts[2]\n\tpressRelease := rowAndTermPart[len(rowAndTermPart)-1]\n\trowPart := rowAndTermPart[:len(rowAndTermPart)-1]\n\n\tbutton, err := strconv.Atoi(buttonPart)\n\tif err != nil {\n\t\treturn nil\n\t}\n\tcol, err := strconv.Atoi(colPart)\n\tif err != nil {\n\t\treturn nil\n\t}\n\tcol = col - 1\n\trow, err := strconv.Atoi(rowPart)\n\tif err != nil {\n\t\treturn nil\n\t}\n\trow = row - 1\n\tpress := false\n\tswitch pressRelease {\n\tcase 'M':\n\t\tpress = true\n\tcase 'm':\n\t\tpress = false\n\tdefault:\n\t\treturn nil\n\t}\n\n\td := button + 32\n\t/**\n\t* Mouse time!\n\t */\n\tswitch d {\n\n\tcase 67, 75, 83, 91:\n\t\tmodifiers := MouseModifiers(d, 67)\n\t\treturn &PointerMove{\n\t\t\tRow:       row,\n\t\t\tCol:       col,\n\t\t\tModifiers: modifiers,\n\t\t}\n\tcase 64, 72, 80, 88:\n\t\t/**\n\t\t* This is pointer moving while\n\t\t* holding left mouse button down\n\t\t*\n\t\t* so far it has always followed\n\t\t* a button down event,\n\t\t* so I'm just sending a pointer move\n\t\t* rather than a button followed by a move\n\t\t */\n\t\tmodifiers := MouseModifiers(d, 64)\n\t\treturn &PointerMove{\n\t\t\tRow:       row,\n\t\t\tCol:       col,\n\t\t\tModifiers: modifiers,\n\t\t}\n\tcase 65, 73, 81, 89:\n\t\t/**\n\t\t * Move while holding middle mouse button down\n\t\t */\n\t\tmodifiers := MouseModifiers(d, 65)\n\t\treturn &PointerMove{\n\t\t\tRow:       row,\n\t\t\tCol:       col,\n\t\t\tModifiers: modifiers,\n\t\t}\n\tcase 66, 74, 82, 90:\n\t\t/**\n\t\t * Move while holding right mouse button down\n\t\t */\n\t\tmodifiers := MouseModifiers(d, 66)\n\t\treturn &PointerMove{\n\t\t\tRow:       row,\n\t\t\tCol:       col,\n\t\t\tModifiers: modifiers,\n\t\t}\n\n\t// Mouse button left down\n\tcase 32, 40, 48, 56:\n\t\tif press {\n\t\t\treturn &PointerButtonPress{\n\t\t\t\tButton:                    BTN_LEFT,\n\t\t\t\tNeedToReleaseOtherButtons: false,\n\t\t\t\tModifiers:                 MouseModifiers(d, 32),\n\t\t\t}\n\t\t}\n\t\treturn &PointerButtonRelease{\n\t\t\tButton:    BTN_LEFT,\n\t\t\tModifiers: MouseModifiers(d, 32),\n\t\t}\n\t// Mouse button middle down\n\tcase 33, 41, 49, 57:\n\t\tif press {\n\t\t\treturn &PointerButtonPress{\n\t\t\t\tButton:                    BTN_MIDDLE,\n\t\t\t\tNeedToReleaseOtherButtons: false,\n\t\t\t\tModifiers:                 MouseModifiers(d, 33),\n\t\t\t}\n\t\t}\n\t\treturn &PointerButtonRelease{\n\t\t\tButton:    BTN_MIDDLE,\n\t\t\tModifiers: MouseModifiers(d, 33),\n\t\t}\n\t// Mouse button right down\n\tcase 34, 42, 50, 58:\n\t\tif press {\n\t\t\treturn &PointerButtonPress{\n\t\t\t\tButton:                    BTN_RIGHT,\n\t\t\t\tNeedToReleaseOtherButtons: false,\n\t\t\t\tModifiers:                 MouseModifiers(d, 34),\n\t\t\t}\n\t\t}\n\t\treturn &PointerButtonRelease{\n\t\t\tButton:    BTN_RIGHT,\n\t\t\tModifiers: MouseModifiers(d, 34),\n\t\t}\n\t// Mouse wheel up\n\tcase 96, 104, 112, 120:\n\t\treturn &PointerWheel{\n\t\t\tUp:        true,\n\t\t\tModifiers: MouseModifiers(d, 96),\n\t\t}\n\t// Mouse wheel down\n\tcase 97, 105, 113, 121:\n\t\treturn &PointerWheel{\n\t\t\tUp:        false,\n\t\t\tModifiers: MouseModifiers(d, 97),\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc ParseSGRMouseSequences(data []byte) []XkbdCode {\n\tcodes := strings.Split(string(data), \"\\x1b[<\")\n\tif len(codes) < 2 {\n\t\treturn nil\n\t}\n\tcodes = codes[1:] // First split is empty string before first ESC[<\n\tout := make([]XkbdCode, 0)\n\tfor _, code := range codes {\n\n\t\tbuttonCode := ParseMouseCode(code)\n\t\tif buttonCode == nil {\n\t\t\tcontinue\n\t\t}\n\t\tout = append(out, buttonCode)\n\t}\n\treturn out\n}\n\nfunc PointerCode(data []byte) PointerEvent {\n\tif !(len(data) >= 3 && data[0] == 27 && data[1] == 91 && data[2] == 77) {\n\t\treturn nil\n\t}\n\n\td := int(data[3])\n\n\t/**\n\t * Mouse time!\n\t */\n\tswitch d {\n\n\tcase 67, 75, 83, 91:\n\t\t// @TODO why 33\n\t\tif len(data) < 6 {\n\t\t\treturn nil\n\t\t}\n\t\tcol := int(data[4]) - 33\n\t\trow := int(data[5]) - 33\n\t\tmodifiers := MouseModifiers(d, 67)\n\t\treturn &PointerMove{\n\t\t\tRow:       row,\n\t\t\tCol:       col,\n\t\t\tModifiers: modifiers,\n\t\t}\n\tcase 64, 72, 80, 88:\n\t\t// @again why 33\n\t\tif len(data) < 6 {\n\t\t\treturn nil\n\t\t}\n\t\tcol := int(data[4]) - 33\n\t\trow := int(data[5]) - 33\n\t\t/**\n\t\t * This is pointer moving while\n\t\t * holding a button down\n\t\t *\n\t\t * so far it has always followed\n\t\t * a button down event,\n\t\t * so I'm just sending a pointer move\n\t\t * rather than a button followed by a move\n\t\t */\n\t\tmodifiers := MouseModifiers(d, 64)\n\t\treturn &PointerMove{\n\t\t\tRow:       row,\n\t\t\tCol:       col,\n\t\t\tModifiers: modifiers,\n\t\t}\n\n\t// Mouse button left down\n\tcase 32, 40, 48, 56:\n\t\treturn &PointerButtonPress{\n\t\t\tButton:                    BTN_LEFT,\n\t\t\tNeedToReleaseOtherButtons: true,\n\t\t\tModifiers:                 MouseModifiers(d, 32),\n\t\t}\n\t// Mouse button middle down\n\tcase 33, 41, 49, 57:\n\t\treturn &PointerButtonPress{\n\t\t\tButton:                    BTN_MIDDLE,\n\t\t\tNeedToReleaseOtherButtons: true,\n\t\t\tModifiers:                 MouseModifiers(d, 33),\n\t\t}\n\t// Mouse button right down\n\tcase 34, 42, 50, 58:\n\t\treturn &PointerButtonPress{\n\t\t\tButton:                    BTN_RIGHT,\n\t\t\tNeedToReleaseOtherButtons: true,\n\t\t\tModifiers:                 MouseModifiers(d, 34),\n\t\t}\n\t// Mouse button up (cannot be sure which button)\n\tcase 35, 43, 51, 59:\n\t\treturn &PointerButtonRelease{\n\t\t\tNeedsButtonGuessing: true,\n\t\t\tModifiers:           MouseModifiers(d, 35),\n\t\t}\n\t// Mouse wheel up\n\tcase 96, 104, 112, 120:\n\t\treturn &PointerWheel{\n\t\t\tUp:        true,\n\t\t\tModifiers: MouseModifiers(d, 96),\n\t\t}\n\t// Mouse wheel down\n\tcase 97, 105, 113, 121:\n\t\treturn &PointerWheel{\n\t\t\tUp:        false,\n\t\t\tModifiers: MouseModifiers(d, 97),\n\t\t}\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "termeverything/RawMode.go",
    "content": "package termeverything\n\n/*\n#cgo CFLAGS: -Wall\n#include <termios.h>\n#include <unistd.h>\n\nstatic int get_termios(int fd, struct termios *t) { return tcgetattr(fd, t); }\nstatic int set_termios_now(int fd, const struct termios *t) { return tcsetattr(fd, TCSANOW, t); }\n\n// Put TTY into \"raw-ish\" mode for input, but keep output processing so stdout isn't garbled.\nstatic void make_raw(struct termios *t) {\n    cfmakeraw(t);               // disable canonical, echo, signals, etc.\n    t->c_cc[VMIN]  = 1;\n    t->c_cc[VTIME] = 0;\n\n    // Preserve output post-processing (NL -> CRNL), like the shell default.\n    t->c_oflag |= OPOST;\n#ifdef ONLCR\n    t->c_oflag |= ONLCR;\n#endif\n}\n*/\nimport \"C\"\nimport \"fmt\"\n\nfunc EnableRawModeFD(fd int) (func() error, error) {\n\tif C.isatty(C.int(fd)) == 0 {\n\t\treturn func() error { return nil }, nil\n\t}\n\n\tvar orig C.struct_termios\n\tif C.get_termios(C.int(fd), &orig) != 0 {\n\t\treturn nil, fmt.Errorf(\"tcgetattr failed\")\n\t}\n\n\traw := orig\n\tC.make_raw(&raw)\n\n\tif C.set_termios_now(C.int(fd), &raw) != 0 {\n\t\treturn nil, fmt.Errorf(\"tcsetattr (raw) failed\")\n\t}\n\n\trestored := false\n\trestore := func() error {\n\t\tif restored {\n\t\t\treturn nil\n\t\t}\n\t\trestored = true\n\t\tif C.set_termios_now(C.int(fd), &orig) != 0 {\n\t\t\treturn fmt.Errorf(\"tcsetattr (restore) failed\")\n\t\t}\n\t\treturn nil\n\t}\n\n\treturn restore, nil\n}\n"
  },
  {
    "path": "termeverything/Readme.md",
    "content": "In this package we do everything you need to interact with a Wayland compositor from a terminal application. This includes handling input events, rendering to surfaces, and managing windows."
  },
  {
    "path": "termeverything/RenderMarkdownToTerminal.go",
    "content": "package termeverything\n\nimport (\n\t\"strings\"\n\n\t\"github.com/mmulet/term.everything/escapecodes\"\n)\n\nfunc RenderMarkdownToTerminal(markdown string) string {\n\tvar outLines []string\n\tfor _, line := range strings.Split(markdown, \"\\n\") {\n\t\tif strings.HasPrefix(line, \"# \") {\n\t\t\toutLines = append(outLines, escapecodes.FgGreen+escapecodes.Underline+renderCode(line[2:])+escapecodes.Reset)\n\t\t\tcontinue\n\t\t}\n\t\tif strings.HasPrefix(line, \"## \") {\n\t\t\toutLines = append(outLines, escapecodes.FgCyan+escapecodes.Underline+renderCode(line[3:])+escapecodes.Reset)\n\t\t\tcontinue\n\t\t}\n\t\toutLines = append(outLines, renderCode(line))\n\t}\n\treturn strings.Join(outLines, \"\\n\")\n}\n\nfunc renderCode(line string) string {\n\tvar outLine strings.Builder\n\tinCode := false\n\tfor _, char := range line {\n\t\tif char != '`' {\n\t\t\toutLine.WriteRune(char)\n\t\t\tcontinue\n\t\t}\n\t\tif inCode {\n\t\t\toutLine.WriteString(escapecodes.Reset)\n\t\t\tinCode = false\n\t\t\tcontinue\n\t\t}\n\t\tinCode = true\n\t\toutLine.WriteString(escapecodes.FgYellow)\n\t}\n\treturn outLine.String()\n}\n"
  },
  {
    "path": "termeverything/SetVirtualMonitorSize.go",
    "content": "package termeverything\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/mmulet/term.everything/wayland\"\n)\n\nfunc SetVirtualMonitorSize(newVirtualMonitorSize string) {\n\tif newVirtualMonitorSize == \"\" {\n\t\treturn\n\t}\n\tparts := strings.Split(newVirtualMonitorSize, \"x\")\n\tif len(parts) != 2 {\n\t\tfmt.Fprintf(os.Stderr, \"Invalid virtual monitor size %s, expected <width>x<height>\\n\", newVirtualMonitorSize)\n\t\tos.Exit(1)\n\t}\n\twidth, err1 := strconv.Atoi(parts[0])\n\theight, err2 := strconv.Atoi(parts[1])\n\tif err1 != nil || err2 != nil {\n\t\tfmt.Fprintf(os.Stderr, \"Invalid virtual monitor size %s, expected <width>x<height>\\n\", newVirtualMonitorSize)\n\t\tos.Exit(1)\n\t}\n\tif width <= 0 || height <= 0 {\n\t\tfmt.Fprintf(os.Stderr, \"Invalid virtual monitor size %s, expected <width>x<height>\\n\", newVirtualMonitorSize)\n\t\tos.Exit(1)\n\t}\n\twayland.VirtualMonitorSize.Width = wayland.Pixels(width)\n\twayland.VirtualMonitorSize.Height = wayland.Pixels(height)\n}\n"
  },
  {
    "path": "termeverything/StatusLine.go",
    "content": "package termeverything\n\nimport (\n\t\"fmt\"\n\t\"net/url\"\n\t\"os\"\n\t\"os/exec\"\n\t\"strings\"\n\n\t\"github.com/mmulet/term.everything/escapecodes\"\n\t\"github.com/mmulet/term.everything/framebuffertoansi\"\n)\n\ntype LineButton struct {\n\tString   string\n\tCallback func()\n\tKeycode  *Linux_Event_Codes\n}\n\ntype StatusLineTextOrButton interface {\n\tIsStatusLineTextOrButton()\n}\n\ntype StatusLineText struct {\n\tString string\n}\n\nfunc (s *StatusLineText) IsStatusLineTextOrButton() {}\n\ntype StatusLineButton struct {\n\tButton LineButton\n}\n\nfunc (s *StatusLineButton) IsStatusLineTextOrButton() {}\n\ntype Status_Line struct {\n\tTextLoopTime float64\n\n\tShowStatusLine bool\n\n\tTerminalMousePosition struct {\n\t\tx int\n\t\ty int\n\t}\n\n\tTerminalMouseButton struct {\n\t\tpressed         bool\n\t\tframe_held_time float64\n\t}\n\n\tb       map[string]*StatusLineButton\n\tSponsor *StatusLineButton\n\tBugs    *StatusLineButton\n}\n\nfunc (s *Status_Line) UpdateMousePosition(code *PointerMove) {\n\tif code == nil {\n\t\treturn\n\t}\n\ts.TerminalMousePosition.x = code.Col\n\ts.TerminalMousePosition.y = code.Row\n}\n\nfunc (s *Status_Line) HandleTerminalMousePress(pressed bool) {\n\tif pressed {\n\t\tif s.TerminalMouseButton.pressed {\n\t\t\t/**\n\t\t\t * Mouse state has not changed\n\t\t\t * do nothing\n\t\t\t */\n\t\t\treturn\n\t\t}\n\t\ts.TerminalMouseButton.pressed = true\n\t\ts.TerminalMouseButton.frame_held_time = 0\n\t\treturn\n\t}\n\ts.TerminalMouseButton.pressed = false\n\ts.TerminalMouseButton.frame_held_time = 0\n}\n\nfunc (s *Status_Line) PostFrame(delta_time float64) {\n\tif s.TerminalMouseButton.pressed {\n\t\ts.TerminalMouseButton.frame_held_time += delta_time\n\t}\n}\n\nfunc MakeStatusLine() *Status_Line {\n\tsl := &Status_Line{\n\t\tShowStatusLine: true,\n\t}\n\tsl.TerminalMousePosition.x = -1\n\tsl.TerminalMousePosition.y = -1\n\n\tescape := KEY_ESC\n\tsl.b = map[string]*StatusLineButton{\n\t\t\"escape\": &StatusLineButton{\n\t\t\tButton: LineButton{\n\t\t\t\tKeycode: &escape,\n\t\t\t\tString:  \"[ESC] to quit\",\n\t\t\t\tCallback: func() {\n\t\t\t\t\tGlobalExitChan <- 0\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t\"left\": &StatusLineButton{\n\t\t\tButton: LineButton{\n\t\t\t\tString: \"[]\",\n\t\t\t\tCallback: func() {\n\t\t\t\t\tfmt.Println(\"left\")\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tsl.Sponsor = &StatusLineButton{\n\t\tButton: LineButton{\n\t\t\tString: \"[Sponsor this project]\",\n\t\t\tCallback: func() {\n\t\t\t\t_ = exec.Command(\"xdg-open\", \"https://github.com/sponsors/mmulet\").Start()\n\t\t\t},\n\t\t},\n\t}\n\n\tsl.Bugs = &StatusLineButton{\n\t\tButton: LineButton{\n\t\t\tString: \"[Report bugs here]\",\n\t\t\tCallback: func() {\n\t\t\t\ttitle := url.QueryEscape(\"Bug Report\")\n\t\t\t\tbody := url.QueryEscape(sl.buildBugBody())\n\t\t\t\t_ = exec.Command(\"xdg-open\",\n\t\t\t\t\t\"https://github.com/mmulet/term.everything/issues/new?title=\"+title+\"&body=\"+body).Start()\n\t\t\t},\n\t\t},\n\t}\n\n\treturn sl\n}\n\nfunc (s *Status_Line) Draw(delta_time float64, app_title *string, keys_pressed_this_frame map[Linux_Event_Codes]bool) string {\n\tif !s.ShowStatusLine {\n\t\treturn \"\"\n\t}\n\n\ttext := s.Line(keys_pressed_this_frame,\n\t\ts.b[\"escape\"], &StatusLineText{\" \"},\n\t\ts.Sponsor, &StatusLineText{\" | \"},\n\t\ts.ChooseAppTitle(app_title), &StatusLineText{\" | \"},\n\t)\n\n\ts.TextLoopTime += delta_time\n\n\twidth := 0\n\tif winsize, err := framebuffertoansi.GetWinsize(os.Stdout.Fd()); err == nil {\n\t\twidth = int(winsize.Col)\n\t}\n\tif width > 1 && len(text) >= width {\n\t\treturn text[:width-1]\n\t}\n\treturn text\n}\n\nfunc (s *Status_Line) buildBugBody() string {\n\treturn fmt.Sprintf(`\nQuick question before you fill this out:\n  Is your app opening a new window instead of opening in the terminal?\n    If so, do you have any other windows of the current app open?\n    For example, firefox likes to open a new window (not in the terminal)\n    if you already have at least one firefox window open.\n    Close all other windows, and see if the problem still happens.\n\n## Describe the bug\nA clear and concise description of what the bug is.\n\n## To Reproduce\nSteps to reproduce the behavior:\n1. Go to '...'\n2. Click on '....'\n3. Scroll down to '....'\n4. See error\n\n## Expected behavior\nA clear and concise description of what you expected to happen.\n\n## Screenshots\nIf applicable, add screenshots to help explain your problem.\n\n## Additional context\nAdd any other context about the problem here.\n        \n\n## System Information\nGenerated from your system, please include this information in your report:\n- Platform: %s\n- Architecture: %s\n- Terminal: %s\n- OS: %s\n- OS Details: %s\n- XDG_SESSION_TYPE: %s\n- Wayland Display: %s\n- X11 Display: %s\n- term.everything version: %s\n        `,\n\t\tos.Getenv(\"GOOS\"),\n\t\tos.Getenv(\"GOARCH\"),\n\t\tgetEnvOr(\"TERM\", \"N/A\"),\n\t\tos.Getenv(\"GOOS\"),\n\t\ts.GetOsDetails(),\n\t\tgetEnvOr(\"XDG_SESSION_TYPE\", \"N/A\"),\n\t\tgetEnvOr(\"WAYLAND_DISPLAY\", \"N/A\"),\n\t\tgetEnvOr(\"DISPLAY\", \"N/A\"),\n\t\tversion,\n\t)\n}\n\nfunc getEnvOr(k, def string) string {\n\tv := os.Getenv(k)\n\tif v == \"\" {\n\t\treturn def\n\t}\n\treturn v\n}\n\nfunc (s *Status_Line) ChooseAppTitle(appTitle *string) StatusLineTextOrButton {\n\tif appTitle == nil || *appTitle == \"\" {\n\t\treturn s.Bugs\n\t}\n\treturn &StatusLineText{*appTitle}\n}\n\nfunc (s *Status_Line) KeyboardKeyHitButton(button LineButton, keys_pressed_this_frame map[Linux_Event_Codes]bool) LineButton {\n\tif button.Keycode == nil {\n\t\treturn button\n\t}\n\tif _, ok := keys_pressed_this_frame[*button.Keycode]; ok {\n\t\tbutton.Callback()\n\t\t// Replace callback with no-op\n\t\tbutton.Callback = func() {}\n\t\treturn button\n\t}\n\treturn button\n}\n\nfunc (s *Status_Line) Line(keys_pressed_this_frame map[Linux_Event_Codes]bool, parts ...StatusLineTextOrButton) string {\n\tposition := 0\n\tvar out strings.Builder\n\n\tfor _, v := range parts {\n\t\tswitch it := v.(type) {\n\t\tcase *StatusLineText:\n\t\t\tout.WriteString(it.String)\n\t\t\tposition += len(it.String)\n\t\tcase *StatusLineButton:\n\t\t\tbtn := s.KeyboardKeyHitButton(it.Button, keys_pressed_this_frame)\n\t\t\tnextString := btn.String\n\t\t\t/**\n\t\t\t * for the rare case where\n\t\t\t * both click on button and\n\t\t\t * hold key at the same time\n\t\t\t */\n\t\t\talready_called_callback := false\n\t\t\tif s.TerminalMousePosition.y == 0 &&\n\t\t\t\tint(s.TerminalMousePosition.x) >= position &&\n\t\t\t\tint(s.TerminalMousePosition.x) < position+len(nextString) {\n\t\t\t\tout.WriteString(escapecodes.BgWhite + escapecodes.FgBlack + nextString + escapecodes.Reset)\n\t\t\t\tif s.TerminalMouseButton.pressed &&\n\t\t\t\t\ts.TerminalMouseButton.frame_held_time == 0 {\n\t\t\t\t\tif !already_called_callback {\n\t\t\t\t\t\tbtn.Callback()\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tout.WriteString(nextString)\n\t\t\t}\n\t\t\tposition += len(nextString)\n\t\t}\n\t}\n\treturn out.String()\n}\n\nfunc (s *Status_Line) GetOsDetails() string {\n\tdata, err := os.ReadFile(\"/etc/os-release\")\n\tif err != nil {\n\t\treturn \"Unable to determine OS details\"\n\t}\n\tlines := strings.Split(string(data), \"\\n\")\n\tosInfo := make(map[string]string)\n\tfor _, line := range lines {\n\t\tparts := strings.SplitN(line, \"=\", 2)\n\t\tif len(parts) != 2 {\n\t\t\tcontinue\n\t\t}\n\t\tkey := parts[0]\n\t\tvalue := strings.Trim(parts[1], `\"`)\n\t\tosInfo[key] = value\n\t}\n\treturn fmt.Sprintf(\"%s (ID: %s, VERSION: %s)\",\n\t\tfirstOr(osInfo[\"PRETTY_NAME\"], \"Unknown\"),\n\t\tfirstOr(osInfo[\"ID\"], \"N/A\"),\n\t\tfirstOr(osInfo[\"VERSION\"], \"N/A\"),\n\t)\n}\n\nfunc firstOr(a, b string) string {\n\tif a == \"\" {\n\t\treturn b\n\t}\n\treturn a\n}\n"
  },
  {
    "path": "termeverything/TerminalDrawLoop.go",
    "content": "package termeverything\n\nimport (\n\t_ \"embed\"\n\t\"os\"\n\t\"slices\"\n\t\"strconv\"\n\t\"time\"\n\n\t\"github.com/mmulet/term.everything/framebuffertoansi\"\n\t\"github.com/mmulet/term.everything/wayland\"\n\t\"github.com/mmulet/term.everything/wayland/protocols\"\n)\n\n//go:embed resources/icon.png\nvar iconPNG []byte\n\ntype FrameInputState struct {\n\tKeysPressedThisFrame map[Linux_Event_Codes]bool\n\tMouseMoveThisFrame   bool\n}\n\nfunc MakeFrameInputState() FrameInputState {\n\treturn FrameInputState{\n\t\tKeysPressedThisFrame: make(map[Linux_Event_Codes]bool),\n\t\tMouseMoveThisFrame:   false,\n\t}\n}\n\ntype TerminalDrawLoop struct {\n\tVirtualMonitorSize wayland.Size\n\n\tClients []*wayland.Client\n\n\tTimeOfLastTerminalDraw *float64\n\n\tHideStatusBar bool\n\n\t/**\n\t * Don't draw until at least MinTerminalTimeSeconds has passed\n\t * since the last frame has been drawn to the terminal. (Not drawn\n\t * to the canvas, that is done as fast as possible)\n\t *\n\t * This is set from the --max-frame-rate argument.\n\t */\n\tMinTerminalTimeSeconds *float64\n\n\tDrawState *framebuffertoansi.DrawState\n\n\tDesktop *wayland.Desktop\n\n\tSharedRenderedScreenSize *RenderedScreenSize\n\n\tFrameEvents chan XkbdCode\n\n\tTimeOfStartOfLastFrame *float64\n\n\tDesiredFrameTimeSeconds float64\n\n\tStatusLine *Status_Line\n\n\tGetClients      chan *wayland.Client\n\tFirstDrawDone   bool\n\tLastDrawSize    framebuffertoansi.WinSize\n\tFrameInputState FrameInputState\n}\n\nfunc MakeTerminalDrawLoop(desktop_size wayland.Size,\n\thide_status_bar bool,\n\twillShowAppRightAtStartup bool,\n\tsharedRenderedScreenSize *RenderedScreenSize,\n\tframeEvents chan XkbdCode,\n\targs *CommandLineArgs,\n\n) *TerminalDrawLoop {\n\ttw := &TerminalDrawLoop{\n\t\tClients:                  make([]*wayland.Client, 0),\n\t\tTimeOfLastTerminalDraw:   nil,\n\t\tMinTerminalTimeSeconds:   nil,\n\t\tSharedRenderedScreenSize: sharedRenderedScreenSize,\n\t\tHideStatusBar:            hide_status_bar,\n\t\tDrawState: framebuffertoansi.MakeDrawState(\n\t\t\tDisplayServerType() == DisplayServerTypeX11,\n\t\t),\n\t\tVirtualMonitorSize: desktop_size,\n\n\t\tDesktop: wayland.MakeDesktop(wayland.Size{\n\t\t\tWidth:  desktop_size.Width,\n\t\t\tHeight: desktop_size.Height,\n\t\t}, willShowAppRightAtStartup, iconPNG),\n\n\t\tTimeOfStartOfLastFrame:  nil,\n\t\tDesiredFrameTimeSeconds: 0.016, // ~60 FPS\n\t\tStatusLine:              MakeStatusLine(),\n\t\tFrameEvents:             frameEvents,\n\t\tGetClients:              make(chan *wayland.Client, 32),\n\t\tFrameInputState:         MakeFrameInputState(),\n\t}\n\tif args != nil && args.MaxFrameRate != \"\" {\n\t\tif fps, err := strconv.ParseFloat(args.MaxFrameRate, 64); err == nil && fps > 0 {\n\t\t\tv := 1.0 / fps\n\t\t\ttw.MinTerminalTimeSeconds = &v\n\t\t}\n\t}\n\n\treturn tw\n}\n\nfunc (tw *TerminalDrawLoop) GetAppTitle() *string {\n\tfor _, s := range tw.Clients {\n\t\tfor topLevelID := range s.TopLevelSurfaces() {\n\t\t\ttop_level := wayland.GetXdgToplevelObject(s, topLevelID)\n\t\t\tif top_level == nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\treturn top_level.Title\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (tw *TerminalDrawLoop) DrawToTerminal(status_line string) {\n\n\t// if protocols.DebugRequests {\n\t// \tfmt.Println(\"Debugging!!!\")\n\t// } else {\n\t// \tfmt.Println(\"Not debugging.\")\n\t// }\n\n\tvar statusLine *string\n\tif !tw.HideStatusBar {\n\t\tstatusLine = &status_line\n\t}\n\n\twidthCells, heightCells := tw.DrawState.DrawDesktop(\n\t\ttw.Desktop.Buffer,\n\t\ttw.VirtualMonitorSize.Width,\n\t\ttw.VirtualMonitorSize.Height,\n\t\tstatusLine,\n\t)\n\ttw.SharedRenderedScreenSize.WidthCells = &widthCells\n\ttw.SharedRenderedScreenSize.HeightCells = &heightCells\n\n}\n\nfunc (tw *TerminalDrawLoop) MainLoop() {\n\tfor {\n\t\ttw.DrawClients()\n\t\ttimeout := time.After(time.Duration(tw.DesiredFrameTimeSeconds * float64(time.Second)))\n\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase code := <-tw.FrameEvents:\n\t\t\t\tswitch c := code.(type) {\n\t\t\t\tcase *KeyCode:\n\t\t\t\t\ttw.FrameInputState.KeysPressedThisFrame[c.KeyCode] = true\n\t\t\t\tcase *PointerMove:\n\t\t\t\t\ttw.StatusLine.UpdateMousePosition(c)\n\t\t\t\t\ttw.FrameInputState.MouseMoveThisFrame = true\n\t\t\t\tcase *PointerButtonPress:\n\t\t\t\t\ttw.StatusLine.HandleTerminalMousePress(true)\n\t\t\t\tcase *PointerButtonRelease:\n\t\t\t\t\ttw.StatusLine.HandleTerminalMousePress(false)\n\t\t\t\tcase *PointerWheel:\n\t\t\t\t}\n\t\t\tcase client := <-tw.GetClients:\n\t\t\t\t//TODO removing clients\n\t\t\t\ttw.Clients = append(tw.Clients, client)\n\t\t\tcase <-timeout:\n\t\t\t\tgoto KeyReadLoop\n\t\t\t}\n\t\t}\n\tKeyReadLoop:\n\t\t// /**\n\t\t//  * I know sleep is bad for timing.\n\t\t//  * @TODO replace with polling later on.\n\t\t//  */\n\t\t// time.Sleep(time.Duration(tw.DesiredFrameTimeSeconds * float64(time.Second)))\n\t}\n}\n\nfunc (tw *TerminalDrawLoop) DrawClients() {\n\tdefer tw.ResetFrameState()\n\tstart_of_frame := float64(time.Now().UnixMilli()) / 1000.0\n\tvar delta_time float64\n\tif tw.TimeOfStartOfLastFrame != nil {\n\t\tdelta_time = start_of_frame - *tw.TimeOfStartOfLastFrame\n\t} else {\n\t\tdelta_time = tw.DesiredFrameTimeSeconds\n\t}\n\tnum_draw_requests := 0\n\tfor _, s := range tw.Clients {\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase callback_id := <-s.FrameDrawRequests:\n\t\t\t\tprotocols.WlCallback_done(s, callback_id, uint32(time.Now().UnixMilli()))\n\t\t\t\tnum_draw_requests++\n\t\t\tdefault:\n\t\t\t\tgoto DoneCallbacks\n\t\t\t}\n\t\t}\n\tDoneCallbacks:\n\t}\n\tclients_to_delete := make([]int, 0)\n\tfor i, s := range tw.Clients {\n\t\ts.Access.Lock()\n\t\tif s.Status != wayland.ClientStatus_Connected {\n\t\t\ts.Access.Unlock()\n\t\t\tclients_to_delete = append(clients_to_delete, i)\n\t\t\tcontinue\n\t\t} else {\n\t\t\tdefer s.Access.Unlock()\n\t\t}\n\t}\n\tfor i := len(clients_to_delete) - 1; i >= 0; i-- {\n\t\tindex := clients_to_delete[i]\n\t\ttw.Clients = slices.Delete(tw.Clients, index, index+1)\n\t}\n\n\tfor _, s := range tw.Clients {\n\t\tpointer_surface_id := wayland.Pointer.PointerSurfaceID[s]\n\t\tif pointer_surface_id == nil {\n\t\t\tcontinue\n\t\t}\n\t\tsurface := wayland.GetWlSurfaceObject(s, *pointer_surface_id)\n\t\tif surface == nil {\n\t\t\tcontinue\n\t\t}\n\t\tsurface.Position.X = int32(wayland.Pointer.WindowX)\n\t\tsurface.Position.Y = int32(wayland.Pointer.WindowY)\n\t\tsurface.Position.Z = 1000\n\n\t}\n\n\ttw.Desktop.DrawClients(tw.Clients)\n\n\tstatus_line := tw.StatusLine.Draw(delta_time, tw.GetAppTitle(), tw.FrameInputState.KeysPressedThisFrame)\n\n\tif tw.ShouldDrawFrame(start_of_frame, num_draw_requests) {\n\t\ttw.DrawToTerminal(status_line)\n\t}\n\n\t// const draw_time = Date.now();\n\n\t// const time_until_next_frame = Math.max(\n\t//   0,\n\t//   this.desired_frame_time_seconds - (draw_time - start_of_frame)\n\t// );\n\n\ttw.TimeOfStartOfLastFrame = &start_of_frame\n\n\ttw.StatusLine.PostFrame(delta_time)\n\n}\n\nfunc (tw *TerminalDrawLoop) ResetFrameState() {\n\ttw.FrameInputState.MouseMoveThisFrame = false\n\tclear(tw.FrameInputState.KeysPressedThisFrame)\n}\n\nfunc (tw *TerminalDrawLoop) ShouldDrawFrame(start_of_frame float64, num_draw_requests int) (should_draw bool) {\n\tdefer func() {\n\t\tif should_draw {\n\t\t\ttw.FirstDrawDone = true\n\t\t}\n\t}()\n\tif tw.MinTerminalTimeSeconds != nil {\n\t\tlast := 0.0\n\t\tif tw.TimeOfLastTerminalDraw != nil {\n\t\t\tlast = *tw.TimeOfLastTerminalDraw\n\t\t}\n\t\tif start_of_frame-last < *tw.MinTerminalTimeSeconds {\n\t\t\treturn false\n\t\t}\n\t\ttw.TimeOfLastTerminalDraw = &start_of_frame\n\t}\n\tif protocols.DebugRequests {\n\t\treturn false\n\t}\n\n\tif winsize, err := framebuffertoansi.GetWinsize(os.Stdout.Fd()); err == nil {\n\t\tdefer func() {\n\t\t\ttw.LastDrawSize = winsize\n\t\t}()\n\t\tif winsize != tw.LastDrawSize {\n\t\t\treturn true\n\t\t}\n\t}\n\tif num_draw_requests == 0 {\n\t\treturn tw.FrameInputState.MouseMoveThisFrame || !tw.FirstDrawDone\n\t}\n\treturn true\n}\n"
  },
  {
    "path": "termeverything/TerminalWindow.go",
    "content": "package termeverything\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"os/signal\"\n\t\"slices\"\n\t\"syscall\"\n\n\t\"github.com/mmulet/term.everything/escapecodes\"\n\t\"github.com/mmulet/term.everything/framebuffertoansi\"\n\t\"github.com/mmulet/term.everything/wayland\"\n\t\"github.com/mmulet/term.everything/wayland/protocols\"\n)\n\ntype RenderedScreenSize struct {\n\tWidthCells  *int\n\tHeightCells *int\n}\n\ntype WindowMode int\n\nconst (\n\tWindowMode_Passthrough WindowMode = iota\n\tWindowMode_Capture\n)\n\nvar GlobalExitChan = make(chan int)\n\ntype TerminalWindow struct {\n\tSocketListener     *wayland.SocketListener\n\tVirtualMonitorSize wayland.Size\n\n\tMode WindowMode\n\n\tFrameEvents chan XkbdCode\n\n\tArgs *CommandLineArgs\n\n\tPressedMouseButton *LINUX_BUTTON_CODES\n\n\tClients []*wayland.Client\n\n\tGetClients chan *wayland.Client\n\n\tSharedRenderedScreenSize *RenderedScreenSize\n\n\tRestoreTerminalMode func() error\n}\n\nfunc MakeTerminalWindow(\n\tsocket_listener *wayland.SocketListener,\n\tdesktop_size wayland.Size,\n\targs *CommandLineArgs,\n\n) *TerminalWindow {\n\n\trestoreTerminalMode, err := EnableRawModeFD(int(os.Stdin.Fd()))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\ttw := &TerminalWindow{\n\t\tSocketListener:           socket_listener,\n\t\tVirtualMonitorSize:       desktop_size,\n\t\tMode:                     WindowMode_Passthrough,\n\t\tFrameEvents:              make(chan XkbdCode, 8192),\n\t\tArgs:                     args,\n\t\tPressedMouseButton:       nil,\n\t\tSharedRenderedScreenSize: &RenderedScreenSize{},\n\t\tClients:                  make([]*wayland.Client, 0),\n\t\t// RestoreTerminalMode:      func() error { return nil },\n\t\tRestoreTerminalMode: restoreTerminalMode,\n\t\tGetClients:          make(chan *wayland.Client, 32),\n\t}\n\n\tif !protocols.DebugRequests {\n\t\tos.Stdout.WriteString(escapecodes.EnableAlternativeScreenBuffer)\n\t\tos.Stdout.WriteString(escapecodes.EnableMouseTracking)\n\t\tos.Stdout.WriteString(escapecodes.EnableSGR)\n\n\t\tos.Stdout.WriteString(escapecodes.HideCursor)\n\t}\n\n\tsigCh := make(chan os.Signal, 1)\n\tsignal.Notify(sigCh,\n\t\tsyscall.SIGINT,\n\t\tsyscall.SIGQUIT,\n\t\tsyscall.SIGTERM,\n\t\tsyscall.SIGUSR1,\n\t\tsyscall.SIGUSR2,\n\t)\n\tgo func() {\n\t\texit_code := 0\n\t\tselect {\n\t\tcase exit_code = <-GlobalExitChan:\n\t\tcase <-sigCh:\n\t\t}\n\t\ttw.OnExit()\n\t\tos.Exit(exit_code)\n\t}()\n\n\treturn tw\n}\n\nfunc (tw *TerminalWindow) OnExit() {\n\tfor _, s := range tw.Clients {\n\t\tfor surface := range s.TopLevelSurfaces() {\n\t\t\tprotocols.XdgToplevel_close(s, surface)\n\t\t}\n\t}\n\ttw.RestoreTerminalMode()\n\n\tos.Stdout.WriteString(escapecodes.DisableAlternativeScreenBuffer)\n\tos.Stdout.WriteString(escapecodes.ShowCursor)\n\n\t// TODO re-enable if enabled above\n\t// os.Stdout.WriteString(escapecodes.DisableNormalMouseTracking)\n\tos.Stdout.WriteString(escapecodes.DisableMouseTracking)\n\n}\n\nfunc (tw *TerminalWindow) InputLoop() {\n\tbuf := make([]byte, 4096)\n\tfor {\n\n\t\tn, err := os.Stdin.Read(buf)\n\n\t\tif err != nil || n == 0 {\n\t\t\tfmt.Printf(\"Error reading stdin: %v\\n\", err)\n\t\t\treturn\n\t\t}\n\t\tchunk := buf[:n]\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase client := <-tw.GetClients:\n\t\t\t\t//TODO removing client\n\t\t\t\ttw.Clients = append(tw.Clients, client)\n\t\t\tdefault:\n\t\t\t\tgoto GotData\n\t\t\t}\n\t\t}\n\tGotData:\n\t\tcodes := ConvertKeycodeToXbdCode(chunk)\n\t\ttw.ProcessCodes(codes)\n\t}\n}\n\nfunc (tw *TerminalWindow) ProcessCodes(codes []XkbdCode) {\n\tclients_to_delete := make([]int, 0)\n\tfor i, s := range tw.Clients {\n\t\ts.Access.Lock()\n\t\tif s.Status != wayland.ClientStatus_Connected {\n\t\t\ts.Access.Unlock()\n\t\t\tclients_to_delete = append(clients_to_delete, i)\n\t\t\tcontinue\n\t\t} else {\n\t\t\tdefer s.Access.Unlock()\n\t\t}\n\t}\n\tfor i := len(clients_to_delete) - 1; i >= 0; i-- {\n\t\tindex := clients_to_delete[i]\n\t\ttw.Clients = slices.Delete(tw.Clients, index, index+1)\n\t}\n\n\tfor _, code := range codes {\n\t\ttw.FrameEvents <- code\n\n\t\tfor _, s := range tw.Clients {\n\t\t\tif keyboard_map := protocols.GetGlobalWlKeyboardBinds(s); keyboard_map != nil {\n\t\t\t\tmodifiers := code.GetModifiers()\n\t\t\t\tser := wayland.GetNextEventSerial()\n\t\t\t\tfor keyboardID := range keyboard_map {\n\t\t\t\t\tprotocols.WlKeyboard_modifiers(\n\t\t\t\t\t\ts,\n\t\t\t\t\t\tkeyboardID,\n\t\t\t\t\t\tser,\n\t\t\t\t\t\tuint32(modifiers),\n\t\t\t\t\t\t0, 0, 0,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tswitch c := code.(type) {\n\t\tcase *KeyCode:\n\t\t\twayland.SendKeyboardKey(tw.Clients, uint32(c.KeyCode), true)\n\t\t\t// Send key released immediately\n\t\t\twayland.SendKeyboardKey(tw.Clients, uint32(c.KeyCode), false)\n\n\t\tcase *PointerMove:\n\t\t\tcols, rows := tw.CurrentTerminalSize()\n\t\t\tx := float32(c.Col) *\n\t\t\t\t(float32(tw.VirtualMonitorSize.Width) /\n\t\t\t\t\tfloat32(cols))\n\t\t\ty := float32(c.Row) *\n\t\t\t\t(float32(tw.VirtualMonitorSize.Height) /\n\t\t\t\t\tfloat32(rows))\n\n\t\t\twayland.SendPointerMotion(tw.Clients, x, y)\n\n\t\tcase *PointerButtonPress:\n\n\t\t\trelease := tw.GetButtonToReleaseAndUpdatePressedMouseButton(c.Button)\n\t\t\twayland.SendPointerButton(tw.Clients, uint32(c.Button), true)\n\t\t\tif c.NeedToReleaseOtherButtons && release != nil {\n\t\t\t\twayland.SendPointerButton(tw.Clients, uint32(*release), false)\n\t\t\t}\n\n\t\tcase *PointerButtonRelease:\n\t\t\tbuttonToRelease := c.Button\n\t\t\tif c.NeedsButtonGuessing {\n\t\t\t\tif tw.PressedMouseButton == nil {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tbuttonToRelease = *tw.PressedMouseButton\n\t\t\t\ttw.PressedMouseButton = nil\n\t\t\t}\n\n\t\t\twayland.SendPointerButton(tw.Clients, uint32(buttonToRelease), false)\n\n\t\tcase *PointerWheel:\n\t\t\t_, rows := tw.CurrentTerminalSize()\n\n\t\t\tvar scale float32 = 0.5\n\t\t\tif (c.Modifiers & ModAlt) != 0 {\n\t\t\t\tscale = 1\n\t\t\t}\n\t\t\tamount := scale * float32(tw.ScrollDirection(c.Up)) * float32(tw.VirtualMonitorSize.Height) / float32(rows)\n\t\t\twayland.SendPointerAxis(tw.Clients, protocols.WlPointerAxis_enum_vertical_scroll, amount)\n\t\tdefault:\n\t\t\t// literal never_default(code) equivalent: do nothing\n\t\t}\n\t}\n}\n\nfunc (tw *TerminalWindow) ScrollDirection(code_up bool) float32 {\n\tvar code float32 = 1.0\n\tif code_up {\n\t\tcode = -1.0\n\t}\n\tvar reverse float32 = 1.0\n\tif tw.Args != nil && tw.Args.ReverseScroll {\n\t\treverse = -1.0\n\t}\n\treturn code * reverse\n}\n\n/**\n * Because we only get release updates for one button at a time\n * assume that when you press another mouse button you will\n * release the one you already have pressed.\n */\nfunc (tw *TerminalWindow) GetButtonToReleaseAndUpdatePressedMouseButton(new_pressed_button LINUX_BUTTON_CODES) *LINUX_BUTTON_CODES {\n\told_pressed_mouse_button := tw.PressedMouseButton\n\ttw.PressedMouseButton = &new_pressed_button\n\t//TODO I think this a bug, but keeping it for now because I dont\n\t// want to make any behavior changes while porting\n\tif old_pressed_mouse_button == nil || *tw.PressedMouseButton == new_pressed_button {\n\t\treturn nil\n\t}\n\treturn old_pressed_mouse_button\n}\n\nfunc (tw *TerminalWindow) CurrentTerminalSize() (cols, rows int) {\n\tif tw.SharedRenderedScreenSize != nil && tw.SharedRenderedScreenSize.WidthCells != nil && tw.SharedRenderedScreenSize.HeightCells != nil {\n\t\treturn *tw.SharedRenderedScreenSize.WidthCells, *tw.SharedRenderedScreenSize.HeightCells\n\t}\n\tws, err := framebuffertoansi.GetWinsize(1)\n\tif err != nil || ws.Col <= 0 || ws.Row <= 0 {\n\t\treturn 80, 24\n\t}\n\treturn int(ws.Col), int(ws.Row)\n}\n"
  },
  {
    "path": "termeverything/profile.go",
    "content": "//go:build profile\n// +build profile\n\npackage termeverything\n\nimport (\n\t_ \"net/http/pprof\"\n\n\t\"log\"\n\t\"net/http\"\n)\n\nfunc init() {\n\tgo func() {\n\t\tlog.Println(\"pprof at http://127.0.0.1:6060/debug/pprof/\")\n\t\t_ = http.ListenAndServe(\"127.0.0.1:6060\", nil)\n\t}()\n}\n"
  },
  {
    "path": "termeverything/resources/LICENSES.txt",
    "content": "This app (term.everything❗mmulet.com) is\ncopyright 2025 Late for Dinner Studios, LLC\n\nLicensed under the GNU Affero General Public License v3.0\nlicenses: AGPL-3.0-only\nrepository: https://github.com/mmulet/term.everything\nlicenseFile: https://github.com/mmulet/term.everything/blob/main/LICENSE.txt\npublisher: Late for Dinner Studios, LLC\nlead developer: Michael Mulet\nmaintainer: Michael Mulet\nemail: m@mmulet.com\n\nThird-party Dependencies:\n├─ Go Standard Library\n│  ├─ licenses: BSD-3-Clause\n│  ├─ repository: https://github.com/golang/go\n│  └─ licenseFile: https://github.com/golang/go/blob/master/LICENSE\n├─ musl libc (including libm. and pthread)\n│  ├─ licenses: MIT\n│  ├─ repository: https://git.musl-libc.org/cgit/musl/\n│  └─ licenseFile: https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT\n└─ libchafa\n   ├─ licenses: LGPL-3.0\n   ├─ repository: https://github.com/hpjansson/chafa\n   └─ licenseFile: https://github.com/hpjansson/chafa?tab=LGPL-3.0-1-ov-file\n   ├─  GLib – 2.0\n   |  ├─ licenses: LGPL-2.1-or-later\n   |  ├─ repository: https://gitlab.gnome.org/GNOME/glib/\n   |  └─ licenseFile: https://gitlab.gnome.org/GNOME/glib/-/blob/main/LICENSES/LGPL-2.1-or-later.txt\n   ├─ pcre2-8\n   |  ├─ licenses: BSD\n   |  ├─ repository: https://github.com/PCRE2Project/pcre2\n   |  └─ licenseFile: https://github.com/PCRE2Project/pcre2/blob/main/LICENCE.md\n   ├─ libatomic\n   │  ├─ licenses: GPL-3.0-with-GCC-exception\n   │  ├─ repository: https://gcc.gnu.org/\n   │  └─ licenseFile: https://gcc.gnu.org/onlinedocs/libstdc++/manual/license.html (GCC Runtime Library Exception)\n   ├─ libintl (from GNU gettext)\n   │  ├─ licenses: LGPL-2.1-or-later\n   │  ├─ repository: https://www.gnu.org/software/gettext/\n   │  └─ licenseFile: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html"
  },
  {
    "path": "termeverything/resources/help.md",
    "content": "Usage:\n\n```\nterm.everything❗mmulet.com-dont_forget_to_chmod_+x_this_file [options]\n                                      [-- some_app_to_term [some_app_args]]\n```\n## Typical Usage:\n\n- Navigate to the directory containing the app:\n  `cd <directory with the app>`\n- Ensure the app has execute permissions:\n  `chmod +x ./term.everything❗mmulet.com-dont_forget_to_chmod_+x_this_file`\n- Then run (if you want to run firefox for example):\n  `./term.everything❗mmulet.com-dont_forget_to_chmod_+x_this_file firefox`\n\n## App didn't open in the terminal?\nIf that app already has a window open, try closing all the existing windows.\n\nOr try using `--support-old-apps` to add support for older applications:\n\n- `term.everything❗mmulet.com-dont_forget_to_chmod_+x_this_file --support-old-apps \\\n-- firefox`\n\n## Advanced Usage:\n\nSet a custom Wayland display name along with a custom Xwayland display name:\n`./term.everything❗mmulet.com-dont_forget_to_chmod_+x_this_file --wayland-display-name \\\nwayland-3--xwayland \":2 -retro\" -- firefox`\n\n## Galaxy Brain Usage:\n\n- Boot up 5 terminals (A, Bob, Cob, Dobby, E-obby).\n- Run the app in terminal A:\n  `./term.everything❗mmulet.com-dont_forget_to_chmod_+x_this_file --wayland-display-name \\`\n`wayland-2`\n- Then in terminal Bob run:\n  `WAYLAND_DISPLAY=wayland-2 Xwayland :2 -retro`\n- In terminal Cob run:\n  `matchbox-window-manager -display :2`\n- In terminal Dobby run:\n  `DISPLAY=:2 <some_other_x11_app>`\n- In terminal E-obby run:\n  `WAYLAND_DISPLAY=wayland-2 <some_other_wayland_app>`\n\nThe app in terminal A hosts a Wayland display (a virtual desktop). Terminal Bob\nruns Xwayland for X11 apps, pointing to terminal A. Terminal Cob runs the X11\nwindow manager for terminal Bob. Terminal Dobby is an X11 app connecting to Bob,\nand terminal E-obby runs a Wayland app connecting to terminal A.\n\n## Options:\n\n`--wayland-display-name <name>`  \nThe Wayland display name.\n@default to wayland-2 (or wayland-3 if\nwayland-2 is in use,etc).\n\n`--xwayland \"<all options in one pair of quotes>\"`  \nRun an Xwayland display for X11 compatibility (if installed and on the PATH).\nterm.everything does not support a rootless X11 server. Default is empty.\n\n`--xwayland-wm \"<command to launch the x11 window manager in quotes>\"`  \nSpecifies the window manager for Xwayland. Default is:  \n\"matchbox-window-manager -display <the Xwayland_display from --xwayland>\"\n\n`--virtual-monitor-size <width>x<height>`  \nSets the virtual monitor size in pixels (the display size for all apps). A\nsmall size is recommended to prevent performance issues. Default is 640x480.\n\n`--support-old-apps`  \nAlias for `--xwayland \":5 -retro\" --xwayland-wm \\\n\"matchbox-window-manager -display :5\"`. Enables support for older apps.\n\n`--`  \nEverything after `--` is executed inside the terminal with these environment\nvariables:  \nWAYLAND_DISPLAY=<wayland-display-name>  \nDISPLAY=<xwayland-display>\n\n`--shell <absolute_path_to_shell>`  \nThe shell used to launch the app. Default is `/bin/bash`.\n\n`--hide-status-bar`  \nHides the status bar at the top of the terminal. Default is false.\n\n`--version`  \nPrint the version number.  \n`-h, --help`  \nShow this help message.\n\n`--licenses`\nPrint the open source licenses of libraries used in this app.\n\n`--reverse-scroll`\nReverse scroll direction. It's great if you ssh into a linux machine from a mac.\n\n`--max-frame-rate`\nLimit drawing to the terminal to $N frames per second. Accepts float.\n\n`--debug-log`\nLog most debug statements to debug.log instead of printing to console\n\n# Environment Variables\n`TERM_EVERYTHING_PIXEL_MODE`\nValues:\n- ITERM2 \n- KITTY\n- SIXELS\n- SYMBOLS\n\n`TERM_EVERYTHING_CANVAS_MODE`\nValues:\n- TRUECOLOR\n- INDEXED_256\n- INDEXED_240\n- INDEXED_16\n- FGBG_BGFG\n- FGBG\n- INDEXED_8\n- INDEXED_16_8\n\n`TERM_EVERYTHING_PIXEL_TYPE`\nValues:\n- RGBA8\n- BGRA8\n- ARGB8\n- ABGR8\n- RGBA8_PREMULTIPLIED\n- BGRA8_PREMULTIPLIED\n- ARGB8_PREMULTIPLIED\n- ABGR8_PREMULTIPLIED\n\n`TERM_EVERYTHING_SYMBOLS`\nValues:\nsee https://github.com/hpjansson/chafa/blob/b790c7e365f6a95aaa9cce985ff16a1c1f914482/chafa/chafa-symbol-map.h#L36\nRemove CHAFA_SYMBOL_TAG. For example: `CHAFA_SYMBOL_TAG_ALL` -> `ALL`\n"
  },
  {
    "path": "wayland/ApplyWlSurfaceDoubleBufferedState.go",
    "content": "package wayland\n\nimport (\n\t\"github.com/mmulet/term.everything/wayland/pointerslices\"\n\t\"github.com/mmulet/term.everything/wayland/protocols\"\n)\n\ntype PendingBufferUpdates struct {\n\tSurface protocols.ObjectID[protocols.WlSurface]\n\tBuffer  *protocols.ObjectID[protocols.WlBuffer]\n\tZIndex  int\n}\n\nfunc ApplyWlSurfaceDoubleBufferedState(\n\ts protocols.ClientState,\n\tsurfaceObjectID protocols.ObjectID[protocols.WlSurface],\n\tsyncSetByParent bool,\n\taccumulator []PendingBufferUpdates,\n\tzIndex int,\n) []PendingBufferUpdates {\n\t/**\n\t * Could be a child surface\n\t */\n\tsurface := GetWlSurfaceObject(s, surfaceObjectID)\n\tif surface == nil {\n\t\treturn accumulator\n\t}\n\n\tupdate := &surface.PendingUpdate\n\tif update.Buffer != nil {\n\t\taccumulator = append(accumulator, PendingBufferUpdates{\n\t\t\tSurface: surfaceObjectID,\n\t\t\tBuffer:  update.Buffer,\n\t\t\tZIndex:  zIndex,\n\t\t})\n\t}\n\n\tif update.BufferScale != nil {\n\t\tsurface.BufferScale = *update.BufferScale\n\t}\n\n\tif update.BufferTransform != nil {\n\t\tsurface.BufferTransform = *update.BufferTransform\n\t}\n\n\tif update.Damage != nil || update.DamageBuffer != nil {\n\t\tsurface.Damaged = true\n\t} else {\n\t\tsurface.Damaged = false\n\t}\n\n\t// offset: add to current offset (doc semantics)\n\tif update.Offset != nil {\n\t\t/**\n\t\t * @TODO Docs say:\n\t\t * The x and y arguments specify the location of the new pending\n\t\t * buffer's upper left corner,\n\t\t * relative to the current buffer's upper left corner,\n\t\t * in surface-local coordinates.\n\t\t * In other words, the x and y,\n\t\t * combined with the new surface size define in\n\t\t * which directions the surface's size changes.\n\t\t *\n\t\t * So I think this means I should add the offset to the current offset\n\t\t * of the surface, not just set it to the offset.\n\t\t */\n\t\tsurface.Offset.X += update.Offset.X\n\t\tsurface.Offset.Y += update.Offset.Y\n\n\t\t/**\n\t\t * From the docs:\n\t\t * On wl_surface.offset requests to the pointer surface, hotspot_x and hotspot_y are decremented by the x and y parameters passed to the request. The offset must be applied by wl_surface.commit as usual.\n\t\t */\n\t\t// if (surface.role?.type === \"cursor\" && surface.role.data) {\n\t\t//   surface.role.data.hotspot.x -= update.offset.x;\n\t\t//   surface.role.data.hotspot.y -= update.offset.y;\n\t\t// }\n\t}\n\n\tif update.InputRegion != nil {\n\t\tif surface.InputRegion != nil && !AreSame(surface.InputRegion, update.InputRegion) {\n\t\t\tRemoveObject(s, *surface.InputRegion)\n\t\t}\n\t\tsurface.InputRegion = update.InputRegion\n\t}\n\n\tif update.OpaqueRegion != nil {\n\t\tif surface.OpaqueRegion != nil && !AreSame(surface.OpaqueRegion, update.OpaqueRegion) {\n\t\t\tRemoveObject(s, *surface.OpaqueRegion)\n\t\t}\n\t\tsurface.OpaqueRegion = update.OpaqueRegion\n\t}\n\n\tif update.AddSubSurface != nil {\n\t\tfor _, subID := range update.AddSubSurface {\n\t\t\tsurface.ChildrenInDrawOrder = append(\n\t\t\t\t[]*protocols.ObjectID[protocols.WlSurface]{&subID},\n\t\t\t\tsurface.ChildrenInDrawOrder...,\n\t\t\t)\n\t\t}\n\t}\n\n\tif update.SetChildPosition != nil {\n\t\tfor _, childPosition := range update.SetChildPosition {\n\t\t\tif !pointerslices.Contains(surface.ChildrenInDrawOrder, childPosition.Child) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tchildSurface := GetWlSurfaceObject(s, childPosition.Child)\n\t\t\tif childSurface == nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\trole, ok := childSurface.Role.(*SurfaceRoleSubSurface)\n\t\t\tif !ok || role.Data == nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tsub := GetWlSubsurfaceObject(s, *role.Data)\n\t\t\tif sub == nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tsub.Position = Point{\n\t\t\t\tX: childPosition.X,\n\t\t\t\tY: childPosition.Y,\n\t\t\t}\n\t\t}\n\t}\n\n\tif update.ZOrderSubsurfaces != nil {\n\t\tfor _, zUpdate := range update.ZOrderSubsurfaces {\n\t\t\tindex_of_child := pointerslices.Index(surface.ChildrenInDrawOrder, zUpdate.ChildToMove)\n\t\t\tif index_of_child == -1 {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tindex_of_relative_to := pointerslices.IndexOfItemOrNil(surface.ChildrenInDrawOrder, zUpdate.RelativeTo)\n\t\t\tif index_of_relative_to == -1 {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t/**\n\t\t\t* Remove the child from the list\n\t\t\t* then reinsert it at the correct index\n\t\t\t* either above or below the relative_to child\n\t\t\t* Since it is drawn in order, above means it will\n\t\t\t* be added to the array after the relative_to child\n\t\t\t* and below means it will be added before the relative_to child\n\t\t\t */\n\t\t\tsurface.ChildrenInDrawOrder = pointerslices.Delete(surface.ChildrenInDrawOrder, index_of_child, index_of_child+1)\n\n\t\t\tvar offset int\n\t\t\tif zUpdate.Type == ZOrderTypeAbove {\n\t\t\t\toffset = 1\n\t\t\t} else {\n\t\t\t\toffset = 0\n\t\t\t}\n\t\t\tsurface.ChildrenInDrawOrder = pointerslices.Insert(surface.ChildrenInDrawOrder, index_of_relative_to+offset, &zUpdate.ChildToMove)\n\t\t}\n\t}\n\n\tif update.XdgSurfaceWindowGeometry != nil {\n\t\tif xdg_surface_state_id := surface.XdgSurfaceState; xdg_surface_state_id != nil {\n\t\t\tif xdg_surface_state := GetXdgSurfaceObject(s, *xdg_surface_state_id); xdg_surface_state != nil {\n\t\t\t\txdg_surface_state.WindowGeometry = *update.XdgSurfaceWindowGeometry\n\t\t\t}\n\t\t}\n\t}\n\n\tif role, ok := surface.Role.(*SurfaceRoleXdgToplevel); ok && role.Data != nil {\n\t\ttop := GetXdgToplevelObject(s, *role.Data)\n\t\tif top != nil && top.PendingState != nil {\n\n\t\t\tif top.PendingState.MaxSize != nil {\n\t\t\t\ttop.MaxSize = top.PendingState.MaxSize\n\t\t\t}\n\n\t\t\tif top.PendingState.MinSize != nil {\n\t\t\t\ttop.MinSize = top.PendingState.MinSize\n\t\t\t}\n\t\t\ttop.PendingState = nil\n\t\t}\n\t}\n\n\t// if (\n\t//   surface.has_role_data_of_type(\"xdg_toplevel\") &&\n\t//   surface.role.data.pending_state\n\t// ) {\n\t//   if (surface.role.data.pending_state.max_size) {\n\t//     surface.role.data.max_size = surface.role.data.pending_state.max_size;\n\t//   }\n\t//   if (surface.role.data.pending_state.min_size) {\n\t//     surface.role.data.min_size = surface.role.data.pending_state.min_size;\n\t//   }\n\t//   delete surface.role.data.pending_state;\n\t// }\n\n\tif update.XwaylandSurfarfaceV1Serial != nil {\n\t\tif role, ok := surface.Role.(*SurfaceRoleXWaylandSurface); ok {\n\t\t\tif role.Data == nil {\n\t\t\t\trole.Data = &SurfaceRoleWaylandSurfaceData{}\n\t\t\t}\n\t\t\t(*role.Data).Serial = update.XwaylandSurfarfaceV1Serial\n\t\t}\n\t}\n\n\tsurface.ResetPendingUpdate()\n\n\tfor _, childSurfaceObjectID := range surface.ChildrenInDrawOrder {\n\n\t\tif childSurfaceObjectID == nil {\n\t\t\tcontinue\n\t\t}\n\n\t\tif syncSetByParent {\n\t\t\taccumulator = ApplyWlSurfaceDoubleBufferedState(\n\t\t\t\ts,\n\t\t\t\t*childSurfaceObjectID,\n\t\t\t\tsyncSetByParent,\n\t\t\t\taccumulator,\n\t\t\t\tzIndex+1,\n\t\t\t)\n\t\t\tcontinue\n\t\t}\n\n\t\tchildSurface := GetWlSurfaceObject(s, *childSurfaceObjectID)\n\t\tif childSurface == nil {\n\t\t\tcontinue\n\t\t}\n\t\trole, ok := childSurface.Role.(*SurfaceRoleSubSurface)\n\t\tif !ok || role.Data == nil {\n\t\t\tcontinue\n\t\t}\n\t\tsub := GetWlSubsurfaceObject(s, *role.Data)\n\t\tif sub == nil {\n\t\t\tcontinue\n\t\t}\n\t\t// if (\n\t\t//   child_surface.role.type !== \"sub_surface\" ||\n\t\t//   child_surface.role.data === null\n\t\t// ) {\n\t\t//   continue;\n\t\t// }\n\t\t// if (!child_surface.role.data.sync) {\n\t\tif !sub.Sync {\n\t\t\t/**\n\t\t\t * The child is not set to sync with the parent\n\t\t\t * so do not apply state changes now\n\t\t\t */\n\t\t\tcontinue\n\t\t}\n\t\taccumulator = ApplyWlSurfaceDoubleBufferedState(\n\t\t\ts,\n\t\t\t*childSurfaceObjectID,\n\t\t\ttrue,\n\t\t\taccumulator,\n\t\t\tzIndex+1,\n\t\t)\n\t}\n\treturn accumulator\n}\n"
  },
  {
    "path": "wayland/Client.go",
    "content": "package wayland\n\nimport (\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"log\"\n\t\"net\"\n\t\"slices\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/mmulet/term.everything/wayland/protocols\"\n)\n\ntype ClientStatus int\n\nconst (\n\tClientStatus_Connected    ClientStatus = 0\n\tClientStatus_Disconnected ClientStatus = 2\n)\n\ntype Client struct {\n\tStatus ClientStatus\n\n\tdrawableSurfaces map[protocols.ObjectID[protocols.WlSurface]]bool\n\ttopLevelSurfaces map[protocols.ObjectID[protocols.XdgToplevel]]bool\n\n\tUnixConnection *net.UnixConn\n\n\tCompositorVersion uint32\n\n\tDisplayID protocols.ObjectID[protocols.WlDisplay]\n\n\tmessageBuffer []byte\n\n\tOutgoingChannel chan protocols.OutgoingEvent\n\n\tDecoder *MessageDecoder\n\n\tUnclaimedFDs []protocols.FileDescriptor\n\n\tObjects map[protocols.AnyObjectID]any\n\n\tRolesToSurfaces map[protocols.AnyObjectID]protocols.ObjectID[protocols.WlSurface]\n\n\tFrameDrawRequests chan protocols.ObjectID[protocols.WlCallback]\n\n\tGlobalBinds map[protocols.GlobalID]any\n\n\tLastGetMessageTime time.Time\n\n\tAccess sync.Mutex\n}\n\nfunc (c *Client) AddFrameDrawRequest(cb protocols.ObjectID[protocols.WlCallback]) {\n\tc.FrameDrawRequests <- cb\n}\n\nfunc (c *Client) GetSurfaceIDFromRole(roleObjectID protocols.AnyObjectID) *protocols.ObjectID[protocols.WlSurface] {\n\tif sid, ok := c.RolesToSurfaces[roleObjectID]; ok {\n\t\treturn &sid\n\t}\n\treturn nil\n}\n\nfunc (c *Client) GetSurfaceFromRole(roleObjectID protocols.AnyObjectID) any {\n\tsidAny := c.GetSurfaceIDFromRole(roleObjectID)\n\tif sidAny == nil {\n\t\treturn nil\n\t}\n\tsurface := GetWlSurfaceObject(c, *sidAny)\n\treturn surface\n}\n\nfunc (c *Client) UnregisterRoleToSurface(roleID protocols.AnyObjectID) {\n\tdelete(c.RolesToSurfaces, roleID)\n}\n\nfunc (c *Client) RegisterRoleToSurface(roleID protocols.AnyObjectID, surfaceID protocols.ObjectID[protocols.WlSurface]) {\n\tc.RolesToSurfaces[roleID] = surfaceID\n}\n\n/**\n * Seed if maybe_desceneding_id is a descendant of surface_id\n * @param s\n * @param surface_id\n * @param maybe_descendant_id\n */\nfunc (c *Client) FindDescendantSurface(surfaceID protocols.ObjectID[protocols.WlSurface], maybeDescendantID protocols.ObjectID[protocols.WlSurface]) bool {\n\n\tsurface := GetWlSurfaceObject(c, surfaceID)\n\tif surface == nil {\n\t\treturn false\n\t}\n\n\tfor _, childID := range surface.ChildrenInDrawOrder {\n\t\tif childID == nil {\n\t\t\tcontinue\n\t\t}\n\t\tif *childID == maybeDescendantID {\n\t\t\treturn true\n\t\t}\n\t}\n\n\tfor _, childID := range surface.ChildrenInDrawOrder {\n\t\tif childID == nil {\n\t\t\tcontinue\n\t\t}\n\t\tif c.FindDescendantSurface(*childID, maybeDescendantID) {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n\nfunc (c *Client) SendError(objectID protocols.AnyObjectID, code uint32, message string) {\n\tprotocols.WlDisplay_error(c,\n\t\tprotocols.ObjectID[protocols.WlDisplay](protocols.GlobalID_WlDisplay),\n\t\tobjectID,\n\t\tcode,\n\t\tmessage,\n\t)\n}\n\nfunc (c *Client) GetGlobalBinds(globalID protocols.GlobalID) any {\n\treturn c.GlobalBinds[globalID]\n}\n\n/**\n * Add a bound object_id to a list\n * of global_ids. SO that you can\n * ask, What are all the objects bound\n * to this global for this client?\n * @param global_id\n * @param object_id\n */\n// func (c *Client) AddGlobalBind(globalID protocols.GlobalID, objectID protocols.AnyObjectID, version protocols.Version) {\n// \tbinds, ok := c.GlobalBinds[globalID]\n// \tif !ok {\n// \t\tbinds = make(map[protocols.AnyObjectID]protocols.Version)\n// \t\tc.GlobalBinds[globalID] = binds\n// \t}\n// \tbinds[objectID] = version\n// }\n\nfunc (c *Client) AddObject(id protocols.AnyObjectID, v any) {\n\tif v == nil {\n\t\tlog.Printf(\"AddObject: object is nil for id %d\", uint32(id))\n\t}\n\tif _, already_have := c.Objects[id]; already_have {\n\t\tlog.Printf(\"AddObject: object already exists for id %d\", uint32(id))\n\t}\n\tc.Objects[id] = v\n}\n\nfunc (c *Client) RemoveObject(id protocols.AnyObjectID) {\n\tdelete(c.Objects, id)\n}\n\nfunc (c *Client) GetObject(id protocols.AnyObjectID) any {\n\tobject, ok := c.Objects[id]\n\tif !ok {\n\t\treturn c.GetGlobalObjectByID(uint32(id))\n\t}\n\treturn object\n}\n\nfunc (c *Client) GetGlobalObjectByID(globalID uint32) any {\n\tswitch globalID {\n\tcase uint32(protocols.GlobalID_WlDisplay):\n\t\treturn Global_WlDisplay\n\tcase uint32(protocols.GlobalID_WlOutput):\n\t\treturn Global_WlOutput\n\tcase uint32(protocols.GlobalID_WlSeat):\n\t\treturn Global_WlSeat\n\tcase uint32(protocols.GlobalID_WlShm):\n\t\treturn Global_WlShm\n\tcase uint32(protocols.GlobalID_WlCompositor):\n\t\treturn Global_WlCompositor\n\tcase uint32(protocols.GlobalID_WlSubcompositor):\n\t\treturn Global_WlSubcompositor\n\tcase uint32(protocols.GlobalID_XdgWmBase):\n\t\treturn Global_XdgWmBase\n\tcase uint32(protocols.GlobalID_WlDataDeviceManager):\n\t\treturn Global_WlDataDeviceManager\n\tcase uint32(protocols.GlobalID_WlKeyboard):\n\t\treturn Global_WlKeyboard\n\tcase uint32(protocols.GlobalID_WlPointer):\n\t\treturn Global_WlPointer\n\tcase uint32(protocols.GlobalID_ZwpXwaylandKeyboardGrabManagerV1):\n\t\treturn Global_ZwpXwaylandKeyboardGrabManagerV1\n\tcase uint32(protocols.GlobalID_XwaylandShellV1):\n\t\treturn Global_XwaylandShellV1\n\tcase uint32(protocols.GlobalID_WlDataDevice):\n\t\treturn Global_WlDataDevice\n\tcase uint32(protocols.GlobalID_WlTouch):\n\t\treturn Global_WlTouch\n\tcase uint32(protocols.GlobalID_ZxdgDecorationManagerV1):\n\t\treturn Global_ZxdgDecorationManagerV1\n\t}\n\treturn nil\n}\n\nfunc MakeClient(conn *net.UnixConn) *Client {\n\treturn &Client{\n\t\tStatus:            ClientStatus_Connected,\n\t\tUnixConnection:    conn,\n\t\tCompositorVersion: 1,\n\t\tDecoder:           MakeMessageDecoder(),\n\t\tDisplayID:         protocols.ObjectID[protocols.WlDisplay](1),\n\n\t\tmessageBuffer: make([]byte, 64*1024),\n\n\t\tOutgoingChannel: make(chan protocols.OutgoingEvent, 8192),\n\n\t\tUnclaimedFDs:    make([]protocols.FileDescriptor, 0, 8),\n\t\tObjects:         make(map[protocols.AnyObjectID]any),\n\t\tRolesToSurfaces: make(map[protocols.AnyObjectID]protocols.ObjectID[protocols.WlSurface]),\n\n\t\tdrawableSurfaces: make(map[protocols.ObjectID[protocols.WlSurface]]bool),\n\t\ttopLevelSurfaces: make(map[protocols.ObjectID[protocols.XdgToplevel]]bool),\n\n\t\tGlobalBinds:       make(map[protocols.GlobalID]any),\n\t\tFrameDrawRequests: make(chan protocols.ObjectID[protocols.WlCallback], 1024),\n\t}\n}\n\nfunc (c *Client) MainLoop() error {\n\tdefer func() {\n\t\tc.Status = ClientStatus_Disconnected\n\t\tif c.UnixConnection != nil {\n\t\t\tif err := c.UnixConnection.Close(); err != nil {\n\t\t\t}\n\t\t}\n\t}()\n\tfor {\n\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase ev := <-c.OutgoingChannel:\n\n\t\t\t\tif err := c.SendPendingMessage(ev); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\tgoto drained\n\t\t\t}\n\t\t}\n\tdrained:\n\n\t\t// Receive once with short deadline; parse and dispatch.\n\t\tn, fds, err := GetMessageAndFileDescriptors(c.UnixConnection, c.messageBuffer)\n\t\tif err != nil {\n\t\t\t// treat unexpected read errors as fatal\n\t\t\treturn err\n\t\t}\n\t\tif err := c.ParseMessages(n, fds); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n}\n\nfunc (c *Client) Send(ev protocols.OutgoingEvent) {\n\t// Allow backpressure to naturally block the sender goroutine.\n\tc.OutgoingChannel <- ev\n}\n\n/**\n *\n * @param message\n * @returns Returns if we should continue listening or sending on this socket any more\n * returns falsy mostly if the client has disconnected\n */\nfunc (c *Client) SendPendingMessage(ev protocols.OutgoingEvent) error {\n\tc.Access.Lock()\n\tdefer c.Access.Unlock()\n\tif protocols.DebugRequests {\n\t\tlog.Printf(\"client -> eid=%d opcode=%d len=%d fd=%v\",\n\t\t\tuint32(ev.ObjectID), ev.Opcode, len(ev.Data), ev.FileDescriptor)\n\t}\n\t// if WaylandDebugTimeOnly() {\n\n\t// \tlog.Printf(\"client -> eid=%d opcode=%d len=%d fd=%v\",\n\t// \t\tuint32(ev.ObjectID), ev.Opcode, len(ev.Data), ev.FileDescriptor)\n\t// }\n\t/**\n\t * 8 bytes is the header length + the length of the message\n\t * #### Header is\n\t * - 4 bytes for object_id\n\t * - 2 bytes for opcode\n\t * - 2 bytes for size\n\t */\n\tsize := 8 + len(ev.Data)\n\tbuf := make([]byte, size)\n\n\t// Wayland header: object_id (u32), size (u16), opcode (u16)\n\tbinary.LittleEndian.PutUint32(buf[0:4], uint32(ev.ObjectID))\n\tbinary.LittleEndian.PutUint16(buf[4:6], uint16(ev.Opcode))\n\tbinary.LittleEndian.PutUint16(buf[6:8], uint16(size))\n\tcopy(buf[8:], ev.Data)\n\n\tvar fds []int\n\tif ev.FileDescriptor != nil {\n\t\tfds = []int{int(*ev.FileDescriptor)}\n\t}\n\treturn SendMessageAndFileDescriptors(c.UnixConnection, buf, fds)\n\t// re\n\n\t// if err != nil {\n\t// \t// if EPIPE or similar => disconnect\n\t// \tif errors.Is(err, syscall.EPIPE) || errors.Is(err, syscall.ECONNRESET) {\n\t// \t\treturn false\n\t// \t}\n\t// \tlog.Printf(\"Send error: %v (n=%d ok=%v)\", err, n, ok)\n\t// \treturn false\n\t// }\n\t// return true\n}\n\nfunc (c *Client) ParseMessages(n int, fds []int) error {\n\tc.Access.Lock()\n\tdefer c.Access.Unlock()\n\t// if len(fds) > 0 && WaylandDebugTimeOnly() {\n\t// \tlog.Printf(\"client: received %d file descriptors\", len(fds))\n\t// }\n\tfor _, fd := range fds {\n\t\tc.UnclaimedFDs = append(c.UnclaimedFDs, protocols.FileDescriptor(fd))\n\t}\n\n\tif n < 0 {\n\t\treturn fmt.Errorf(\"negative byte count received: %d\", n)\n\t}\n\n\tif n == 0 {\n\t\t/**\n\t\t* Time out\n\t\t */\n\t\treturn nil\n\t}\n\n\tmsgs := c.Decoder.Consume(c.messageBuffer[:n])\n\tfor i := range msgs {\n\t\tm := msgs[i]\n\t\tobj := c.GetObject(m.ObjectID)\n\t\tif obj == nil {\n\t\t\t// if WaylandDebugTimeOnly() {\n\t\t\t// \tlog.Printf(\"client: request for unknown object %d\", uint32(m.ObjectID))\n\t\t\t// }\n\t\t\tcontinue\n\t\t}\n\n\t\ttheType, ok := obj.(protocols.OnRequestable)\n\t\tif !ok {\n\t\t\tlog.Printf(\"client: object %d has unknown type; cannot dispatch\", uint32(m.ObjectID))\n\t\t\tcontinue\n\t\t}\n\t\ttheType.OnRequest(c, m)\n\t}\n\treturn nil\n}\n\nfunc (c *Client) ClaimFileDescriptor() *protocols.FileDescriptor {\n\tif len(c.UnclaimedFDs) == 0 {\n\t\treturn nil\n\t}\n\tfd := c.UnclaimedFDs[0]\n\tc.UnclaimedFDs = slices.Delete(c.UnclaimedFDs, 0, 1)\n\treturn &fd\n}\n\nfunc (c *Client) SetCompositorVersion(v uint32) { c.CompositorVersion = v }\nfunc (c *Client) GetCompositorVersion() uint32  { return c.CompositorVersion }\n\nfunc (c *Client) DrawableSurfaces() map[protocols.ObjectID[protocols.WlSurface]]bool {\n\treturn c.drawableSurfaces\n}\nfunc (c *Client) TopLevelSurfaces() map[protocols.ObjectID[protocols.XdgToplevel]]bool {\n\treturn c.topLevelSurfaces\n}\n"
  },
  {
    "path": "wayland/ClientGlobal.go",
    "content": "package wayland\n\nimport \"github.com/mmulet/term.everything/wayland/protocols\"\n\nfunc (c *Client) AddGlobalWlShmBind(objectID protocols.ObjectID[protocols.WlShm], version protocols.Version) {\n\tbinds, ok := c.GlobalBinds[protocols.GlobalID_WlShm]\n\tif !ok {\n\t\tbinds = make(map[protocols.ObjectID[protocols.WlShm]]protocols.Version)\n\t\tc.GlobalBinds[protocols.GlobalID_WlShm] = binds\n\t}\n\tbinds.(map[protocols.ObjectID[protocols.WlShm]]protocols.Version)[objectID] = version\n}\n\nfunc (c *Client) AddGlobalWlSeatBind(objectID protocols.ObjectID[protocols.WlSeat], version protocols.Version) {\n\tbinds, ok := c.GlobalBinds[protocols.GlobalID_WlSeat]\n\tif !ok {\n\t\tbinds = make(map[protocols.ObjectID[protocols.WlSeat]]protocols.Version)\n\t\tc.GlobalBinds[protocols.GlobalID_WlSeat] = binds\n\t}\n\tbinds.(map[protocols.ObjectID[protocols.WlSeat]]protocols.Version)[objectID] = version\n}\n\nfunc (c *Client) AddGlobalWlOutputBind(objectID protocols.ObjectID[protocols.WlOutput], version protocols.Version) {\n\tbinds, ok := c.GlobalBinds[protocols.GlobalID_WlOutput]\n\tif !ok {\n\t\tbinds = make(map[protocols.ObjectID[protocols.WlOutput]]protocols.Version)\n\t\tc.GlobalBinds[protocols.GlobalID_WlOutput] = binds\n\t}\n\tbinds.(map[protocols.ObjectID[protocols.WlOutput]]protocols.Version)[objectID] = version\n}\n\nfunc (c *Client) AddGlobalWlKeyboardBind(objectID protocols.ObjectID[protocols.WlKeyboard], version protocols.Version) {\n\tbinds, ok := c.GlobalBinds[protocols.GlobalID_WlKeyboard]\n\tif !ok {\n\t\tbinds = make(map[protocols.ObjectID[protocols.WlKeyboard]]protocols.Version)\n\t\tc.GlobalBinds[protocols.GlobalID_WlKeyboard] = binds\n\t}\n\tbinds.(map[protocols.ObjectID[protocols.WlKeyboard]]protocols.Version)[objectID] = version\n}\n\nfunc (c *Client) AddGlobalWlPointerBind(objectID protocols.ObjectID[protocols.WlPointer], version protocols.Version) {\n\tbinds, ok := c.GlobalBinds[protocols.GlobalID_WlPointer]\n\tif !ok {\n\t\tbinds = make(map[protocols.ObjectID[protocols.WlPointer]]protocols.Version)\n\t\tc.GlobalBinds[protocols.GlobalID_WlPointer] = binds\n\t}\n\tbinds.(map[protocols.ObjectID[protocols.WlPointer]]protocols.Version)[objectID] = version\n}\n\nfunc (c *Client) AddGlobalWlTouchBind(objectID protocols.ObjectID[protocols.WlTouch], version protocols.Version) {\n\tbinds, ok := c.GlobalBinds[protocols.GlobalID_WlTouch]\n\tif !ok {\n\t\tbinds = make(map[protocols.ObjectID[protocols.WlTouch]]protocols.Version)\n\t\tc.GlobalBinds[protocols.GlobalID_WlTouch] = binds\n\t}\n\tbinds.(map[protocols.ObjectID[protocols.WlTouch]]protocols.Version)[objectID] = version\n}\n\nfunc (c *Client) AddGlobalWlDataDeviceBind(objectID protocols.ObjectID[protocols.WlDataDevice], version protocols.Version) {\n\tbinds, ok := c.GlobalBinds[protocols.GlobalID_WlDataDevice]\n\tif !ok {\n\t\tbinds = make(map[protocols.ObjectID[protocols.WlDataDevice]]protocols.Version)\n\t\tc.GlobalBinds[protocols.GlobalID_WlDataDevice] = binds\n\t}\n\tbinds.(map[protocols.ObjectID[protocols.WlDataDevice]]protocols.Version)[objectID] = version\n}\n\nfunc (c *Client) AddGlobalZwpXwaylandKeyboardGrabManagerV1Bind(objectID protocols.ObjectID[protocols.ZwpXwaylandKeyboardGrabManagerV1], version protocols.Version) {\n\tbinds, ok := c.GlobalBinds[protocols.GlobalID_ZwpXwaylandKeyboardGrabManagerV1]\n\tif !ok {\n\t\tbinds = make(map[protocols.ObjectID[protocols.ZwpXwaylandKeyboardGrabManagerV1]]protocols.Version)\n\t\tc.GlobalBinds[protocols.GlobalID_ZwpXwaylandKeyboardGrabManagerV1] = binds\n\t}\n\tbinds.(map[protocols.ObjectID[protocols.ZwpXwaylandKeyboardGrabManagerV1]]protocols.Version)[objectID] = version\n}\n\nfunc (c *Client) RemoveGlobalWlShmBind(objectID protocols.ObjectID[protocols.WlShm]) {\n\tbinds, ok := c.GlobalBinds[protocols.GlobalID_WlShm]\n\tif !ok {\n\t\treturn\n\t}\n\tdelete(binds.(map[protocols.ObjectID[protocols.WlShm]]protocols.Version), objectID)\n}\n\nfunc (c *Client) RemoveGlobalWlSeatBind(objectID protocols.ObjectID[protocols.WlSeat]) {\n\tbinds, ok := c.GlobalBinds[protocols.GlobalID_WlSeat]\n\tif !ok {\n\t\treturn\n\t}\n\tdelete(binds.(map[protocols.ObjectID[protocols.WlSeat]]protocols.Version), objectID)\n}\n\nfunc (c *Client) RemoveGlobalWlOutputBind(objectID protocols.ObjectID[protocols.WlOutput]) {\n\tbinds, ok := c.GlobalBinds[protocols.GlobalID_WlOutput]\n\tif !ok {\n\t\treturn\n\t}\n\tdelete(binds.(map[protocols.ObjectID[protocols.WlOutput]]protocols.Version), objectID)\n}\nfunc (c *Client) RemoveGlobalWlKeyboardBind(objectID protocols.ObjectID[protocols.WlKeyboard]) {\n\tbinds, ok := c.GlobalBinds[protocols.GlobalID_WlKeyboard]\n\tif !ok {\n\t\treturn\n\t}\n\tdelete(binds.(map[protocols.ObjectID[protocols.WlKeyboard]]protocols.Version), objectID)\n}\n\nfunc (c *Client) RemoveGlobalWlPointerBind(objectID protocols.ObjectID[protocols.WlPointer]) {\n\tbinds, ok := c.GlobalBinds[protocols.GlobalID_WlPointer]\n\tif !ok {\n\t\treturn\n\t}\n\tdelete(binds.(map[protocols.ObjectID[protocols.WlPointer]]protocols.Version), objectID)\n}\n\nfunc (c *Client) RemoveGlobalWlTouchBind(objectID protocols.ObjectID[protocols.WlTouch]) {\n\tbinds, ok := c.GlobalBinds[protocols.GlobalID_WlTouch]\n\tif !ok {\n\t\treturn\n\t}\n\tdelete(binds.(map[protocols.ObjectID[protocols.WlTouch]]protocols.Version), objectID)\n}\n\nfunc (c *Client) RemoveGlobalWlDataDeviceBind(objectID protocols.ObjectID[protocols.WlDataDevice]) {\n\tbinds, ok := c.GlobalBinds[protocols.GlobalID_WlDataDevice]\n\tif !ok {\n\t\treturn\n\t}\n\tdelete(binds.(map[protocols.ObjectID[protocols.WlDataDevice]]protocols.Version), objectID)\n}\n\nfunc (c *Client) RemoveGlobalZwpXwaylandKeyboardGrabManagerV1Bind(objectID protocols.ObjectID[protocols.ZwpXwaylandKeyboardGrabManagerV1]) {\n\tbinds, ok := c.GlobalBinds[protocols.GlobalID_ZwpXwaylandKeyboardGrabManagerV1]\n\tif !ok {\n\t\treturn\n\t}\n\tdelete(binds.(map[protocols.ObjectID[protocols.ZwpXwaylandKeyboardGrabManagerV1]]protocols.Version), objectID)\n}\n"
  },
  {
    "path": "wayland/CopyBufferToWlSurfaceTexture.go",
    "content": "package wayland\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/mmulet/term.everything/wayland/protocols\"\n)\n\nfunc CopyBufferToWlSurfaceTexture(\n\ts protocols.ClientState,\n\tsurfaceID protocols.ObjectID[protocols.WlSurface],\n\tzIndex int,\n\tmaybebufferID *protocols.ObjectID[protocols.WlBuffer],\n) {\n\tsurface := GetWlSurfaceObject(s, surfaceID)\n\tif maybebufferID == nil {\n\t\tdelete(s.DrawableSurfaces(), surfaceID)\n\t\t/**\n\t\t * Time to remove the texture from the surface\n\t\t */\n\t\tif surface == nil {\n\t\t\treturn\n\t\t}\n\t\tsurface.Texture = nil\n\t\treturn\n\t}\n\tbufferId := *maybebufferID\n\tif surface == nil {\n\t\treturn\n\t}\n\n\tpool := GetWlPoolObject_FromBuffer(s, bufferId)\n\tif pool == nil {\n\t\tfmt.Println(\"Could not get pool delegate; can't commit\")\n\t\treturn\n\t}\n\n\tif pool.MapState == MapStateDestroyed {\n\t\tfmt.Printf(\"Could not get pool.buffer_pointer; can't commit! pool %d buffer %d\\n\",\n\t\t\tpool.WlShmPoolObjectID, bufferId)\n\t\treturn\n\t}\n\n\tbufferInfo, ok := pool.Buffers[bufferId]\n\tif !ok {\n\t\tfmt.Println(\"Could not get buffer_info; can't commit\")\n\t\treturn\n\t}\n\n\tx := surface.Offset.X\n\ty := surface.Offset.Y\n\n\tif surface.Role == nil {\n\t\treturn\n\t}\n\n\tswitch role := surface.Role.(type) {\n\tcase *SurfaceRoleXdgPopup:\n\t\treturn\n\tcase *SurfaceRoleSubSurface:\n\t\tif role.Data != nil {\n\t\t\tsub_surface := GetWlSubsurfaceObject(s, *role.Data)\n\t\t\tif sub_surface != nil {\n\t\t\t\tx = sub_surface.Position.X\n\t\t\t\ty = sub_surface.Position.Y\n\t\t\t}\n\t\t\t/**\n\t\t\t * @TODO should this be relative to the parent?\n\t\t\t */\n\t\t}\n\tcase *SurfaceRoleXWaylandSurface:\n\t\t/**\n\t\t * @TODO\n\t\t */\n\t\tfmt.Println(\"ON commit xwayland_surface_v1\")\n\tcase *SurfaceRoleXdgToplevel:\n\t\tif surface.XdgSurfaceState != nil {\n\t\t\txdg_surface_state := GetXdgSurfaceObject(s, *surface.XdgSurfaceState)\n\t\t\tif xdg_surface_state != nil {\n\t\t\t\t// x = surface.xdg_surface_state.window_geometry.x;\n\t\t\t\t// y = surface.xdg_surface_state.window_geometry.y;\n\t\t\t\t// console.log(\n\t\t\t\t//   \"reposition xdg_toplevel, \",\n\t\t\t\t//   x,\n\t\t\t\t//   y,\n\t\t\t\t//   \"for surface\",\n\t\t\t\t//   surface_id\n\t\t\t\t// );\n\t\t\t}\n\t\t}\n\tcase *SurfaceRoleCursor:\n\t\t/**\n\t\t * @TODO is this right?\n\t\t */\n\t\tif !role.HasData() {\n\t\t\t/**\n\t\t\t * From the docs:\n\t\t\t * When the use as a cursor ends, the wl_surface is unmapped\n\t\t\t *\n\t\t\t * So I think that means if it isn't a cursor anymore,\n\t\t\t * we should not draw it\n\t\t\t */\n\t\t\treturn\n\t\t}\n\t\tx += int32(Pointer.WindowX) + role.Data.Hotspot.X\n\t\ty += int32(Pointer.WindowY) + role.Data.Hotspot.Y\n\n\t}\n\tsurface.Position.X = x\n\tsurface.Position.Y = y\n\tsurface.Position.Z = int32(zIndex)\n\n\tif surface.Texture != nil {\n\t\tif surface.Texture.Stride != uint32(bufferInfo.Stride) ||\n\t\t\tsurface.Texture.Width != uint32(bufferInfo.Width) ||\n\t\t\tsurface.Texture.Height != uint32(bufferInfo.Height) {\n\t\t\tsurface.Texture = nil\n\t\t}\n\t}\n\n\tif surface.Texture == nil {\n\t\tsize := int(bufferInfo.Stride) * int(bufferInfo.Height)\n\t\tif size < 0 {\n\t\t\tfmt.Println(\"Invalid buffer size; can't commit\")\n\t\t\treturn\n\t\t}\n\t\tsurface.Texture = &Texture{\n\t\t\tStride: uint32(bufferInfo.Stride),\n\t\t\tWidth:  uint32(bufferInfo.Width),\n\t\t\tHeight: uint32(bufferInfo.Height),\n\t\t\tData:   make([]byte, size),\n\t\t}\n\t}\n\n\tmemMap, ok := pool.MemMaps[pool.WlShmPoolObjectID]\n\tif !ok {\n\t\tfmt.Println(\"No memmap for pool; can't commit\")\n\t\treturn\n\t}\n\n\ttotal := int(bufferInfo.Stride) * int(bufferInfo.Height)\n\tif total < 0 || total > len(surface.Texture.Data) {\n\t\tfmt.Println(\"Computed copy size out of bounds; can't commit\")\n\t\treturn\n\t}\n\n\toffset := int(bufferInfo.Offset)\n\n\tsrc := memMap.Bytes\n\tif offset < 0 || offset+total > len(src) {\n\t\tfmt.Println(\"Pool memory bounds error during copy; can't commit\")\n\t\treturn\n\n\t}\n\n\tcopy(surface.Texture.Data, src[offset:offset+total])\n\n\ts.DrawableSurfaces()[surfaceID] = true\n}\n"
  },
  {
    "path": "wayland/Desktop.go",
    "content": "package wayland\n\nimport (\n\t\"bytes\"\n\t\"image\"\n\t\"image/draw\"\n\t_ \"image/png\"\n\t\"sort\"\n\t\"time\"\n\n\t\"github.com/mmulet/term.everything/wayland/protocols\"\n)\n\ntype Desktop struct {\n\tWidth  int\n\tHeight int\n\tStride int // bytes per row (Width * 4)\n\n\t// Back buffer as image.RGBA (Pix backed by Buffer)\n\tBuffer []byte\n\tRGBA   *image.RGBA\n\n\tIconImg *image.NRGBA\n\n\tCreatedAt                 time.Time\n\tWillShowAppRightAtStartup bool\n}\n\nfunc MakeDesktop(size Size, willShowAppRightAtStartup bool, iconPNG []byte) *Desktop {\n\tw := int(size.Width)\n\th := int(size.Height)\n\tbuf := make([]byte, w*h*4)\n\n\tcd := &Desktop{\n\t\tWidth:  w,\n\t\tHeight: h,\n\t\tStride: w * 4,\n\t\tBuffer: buf,\n\t\tRGBA: &image.RGBA{\n\t\t\tPix:    buf,\n\t\t\tStride: w * 4,\n\t\t\tRect:   image.Rect(0, 0, w, h),\n\t\t},\n\t\tCreatedAt:                 time.Now(),\n\t\tWillShowAppRightAtStartup: willShowAppRightAtStartup,\n\t}\n\tcd.IconImg = RgbaToBgra(DecodeIconToNRGBA(iconPNG))\n\treturn cd\n}\n\nfunc RgbaToBgra(src *image.NRGBA) *image.NRGBA {\n\tif src == nil {\n\t\treturn nil\n\t}\n\tb := src.Bounds()\n\tdst := image.NewNRGBA(b)\n\tfor y := b.Min.Y; y < b.Max.Y; y++ {\n\t\tfor x := b.Min.X; x < b.Max.X; x++ {\n\t\t\toff := src.PixOffset(x, y)\n\t\t\tr := src.Pix[off+0]\n\t\t\tg := src.Pix[off+1]\n\t\t\tbb := src.Pix[off+2]\n\t\t\ta := src.Pix[off+3]\n\n\t\t\tdstOff := dst.PixOffset(x, y)\n\t\t\tdst.Pix[dstOff+0] = bb\n\t\t\tdst.Pix[dstOff+1] = g\n\t\t\tdst.Pix[dstOff+2] = r\n\t\t\tdst.Pix[dstOff+3] = a\n\t\t}\n\t}\n\treturn dst\n}\n\nfunc DecodeIconToNRGBA(data []byte) *image.NRGBA {\n\tif len(data) == 0 {\n\t\treturn nil\n\t}\n\timg, _, err := image.Decode(bytes.NewReader(data))\n\tif err != nil {\n\t\treturn nil\n\t}\n\tif rgba, ok := img.(*image.NRGBA); ok {\n\t\treturn rgba\n\t}\n\tb := img.Bounds()\n\n\trgba := image.NewNRGBA(b)\n\tdraw.Draw(rgba, b, img, b.Min, draw.Src)\n\treturn rgba\n}\n\nfunc (cd *Desktop) DrawImage(src image.Image, dx, dy int) {\n\tif src == nil {\n\t\treturn\n\t}\n\tsb := src.Bounds()\n\tr := image.Rect(dx, dy, dx+sb.Dx(), dy+sb.Dy())\n\tdraw.Draw(cd.RGBA, r, src, sb.Min, draw.Over)\n}\n\n/*\n* If we will show an app right at startup,\n     * we want to wait a bit before potentially\n     * drawing the icon. Otherwise it will\n     * flash the icon, and the show the app\n     * content which is annoying.\n     *\n*/\nfunc (cd *Desktop) AfterOpeningTimeout() bool {\n\tif !cd.WillShowAppRightAtStartup {\n\t\treturn true\n\t}\n\treturn time.Since(cd.CreatedAt) >= 500*time.Millisecond\n}\n\nfunc (cd *Desktop) Clear() {\n\tclear(cd.Buffer)\n}\n\ntype SortedSurfaceEntry struct {\n\tSurface   *WlSurface\n\tSrc       *image.RGBA\n\tSurfaceID protocols.ObjectID[protocols.WlSurface]\n}\n\ntype SortedSurfaceEntryParentLocation struct {\n\tparentID protocols.ObjectID[protocols.WlSurface]\n\tx, y     int\n}\n\nfunc (cd *Desktop) DrawClients(clients []*Client) {\n\n\tsorted := make([]SortedSurfaceEntry, 0, 64)\n\n\tchildToParent := make(map[protocols.ObjectID[protocols.WlSurface]]SortedSurfaceEntryParentLocation)\n\n\tfor _, c := range clients {\n\t\tif c == nil {\n\t\t\tcontinue\n\t\t}\n\t\tfor surface_id := range c.DrawableSurfaces() {\n\t\t\tsurface := GetWlSurfaceObject(c, surface_id)\n\t\t\tif surface == nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\ttex := surface.Texture.AsRGBA()\n\t\t\tif tex == nil {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tfor _, child := range surface.ChildrenInDrawOrder {\n\t\t\t\tif child == nil {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tchildToParent[*child] = SortedSurfaceEntryParentLocation{\n\t\t\t\t\tparentID: surface_id,\n\t\t\t\t\tx:        int(surface.Position.X),\n\t\t\t\t\ty:        int(surface.Position.Y),\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tsorted = append(sorted, SortedSurfaceEntry{\n\t\t\t\tSurface:   surface,\n\t\t\t\tSrc:       tex,\n\t\t\t\tSurfaceID: surface_id,\n\t\t\t})\n\t\t}\n\t}\n\n\tsort.Slice(sorted, func(i, j int) bool {\n\t\tzi := sorted[i].Surface.Position.Z\n\t\tzj := sorted[j].Surface.Position.Z\n\t\tif zi == zj {\n\t\t\treturn sorted[i].SurfaceID < sorted[j].SurfaceID\n\t\t}\n\t\treturn zi < zj\n\t})\n\n\tcd.Clear()\n\n\tif len(sorted) == 0 && cd.AfterOpeningTimeout() {\n\t\tcd.DrawImage(cd.IconImg, 0, 0)\n\t\treturn\n\t}\n\n\tfor _, it := range sorted {\n\t\t/**\n\t\t * Recursively get the position by adding\n\t\t * all ancestor position\n\t\t */\n\t\tx := int(it.Surface.Position.X)\n\t\ty := int(it.Surface.Position.Y)\n\t\tparent, ok := childToParent[it.SurfaceID]\n\t\tfor ok {\n\t\t\tx += parent.x\n\t\t\ty += parent.y\n\t\t\tparent, ok = childToParent[parent.parentID]\n\t\t}\n\t\tcd.DrawImage(it.Src, x, y)\n\t}\n}\n"
  },
  {
    "path": "wayland/GetMessageAnd_fileDescriptors.go",
    "content": "package wayland\n\nimport (\n\t\"errors\"\n\t\"io\"\n\t\"net\"\n\t\"syscall\"\n\t\"time\"\n)\n\nconst (\n\tGetMessage_timeout      = 1 * time.Millisecond\n\tGetMessage_maxFDsInCmsg = 10  // matches C++: CMSG_SPACE(sizeof(int) * 10)\n\tGetMessage_hardFDLimit  = 255 // matches C++ guard in the copy loop\n\tGetMessage_intSizeBytes = 4   // sizeof(int) on Linux\n)\n\nvar oob = make([]byte, syscall.CmsgSpace(GetMessage_intSizeBytes*GetMessage_maxFDsInCmsg))\n\nfunc GetMessageAndFileDescriptors(conn *net.UnixConn, buf []byte) (n int, fds []int, err error) {\n\n\t// 10ms \"select\"-style timeout\n\tif err := conn.SetReadDeadline(time.Now().Add(GetMessage_timeout)); err != nil {\n\t\treturn 0, nil, err\n\t}\n\tdefer conn.SetReadDeadline(time.Time{})\n\n\tn, oobn, _, _, rerr := conn.ReadMsgUnix(buf, oob)\n\n\t// Timeout -> continue with no data/fds.\n\tif ne, ok := rerr.(net.Error); ok && ne.Timeout() {\n\t\treturn 0, nil, nil\n\t}\n\tif rerr != nil {\n\t\tif errors.Is(rerr, io.EOF) {\n\t\t\treturn n, nil, nil\n\t\t}\n\t\t// Treat as terminal like the C++ (returns false).\n\t\treturn n, nil, rerr\n\t}\n\tif n == 0 {\n\t\t// EOF on stream\n\t\treturn 0, nil, nil\n\t}\n\n\t// Parse as many rights as fit; ignore truncation like the C++.\n\tif oobn > 0 {\n\t\tif cmsgs, perr := syscall.ParseSocketControlMessage(oob[:oobn]); perr == nil {\n\t\t\tfor _, cmsg := range cmsgs {\n\t\t\t\tif rights, rerr := syscall.ParseUnixRights(&cmsg); rerr == nil && len(rights) > 0 {\n\t\t\t\t\tfds = append(fds, rights...)\n\t\t\t\t\tif len(fds) >= GetMessage_hardFDLimit {\n\t\t\t\t\t\tfds = fds[:GetMessage_hardFDLimit]\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn n, fds, nil\n}\n"
  },
  {
    "path": "wayland/Globals.go",
    "content": "package wayland\n\nimport \"github.com/mmulet/term.everything/wayland/protocols\"\n\nvar Global_WlDisplay = MakeWLDisplay()\nvar Global_WlOutput = MakeWlOutput()\nvar Global_WlSeat = MakeWLSeat()\nvar Global_WlShm = MakeWlShm()\nvar Global_WlCompositor = MakeWlCompositor()\nvar Global_WlSubcompositor = MakeWlSubcompositor()\nvar Global_XdgWmBase = MakeXdgWmBase()\nvar Global_WlDataDeviceManager = MakeWlDataDeviceManager()\nvar Global_WlKeyboard = MakeWlKeyboard()\nvar Global_WlPointer = &protocols.WlPointer{\n\tDelegate: &Pointer,\n}\nvar Global_ZwpXwaylandKeyboardGrabManagerV1 = MakeZwpXwaylandKeyboardGrabManagerV1()\nvar Global_XwaylandShellV1 = MakeXwaylandShellV1()\nvar Global_WlDataDevice = Global_WlSeat\n\nvar Global_WlTouch = MakeWlTouch()\n\nvar Global_ZxdgDecorationManagerV1 = MakeZxdgDecorationManagerV1()\n"
  },
  {
    "path": "wayland/InputEvents.go",
    "content": "package wayland\n\nimport (\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/mmulet/term.everything/wayland/protocols\"\n)\n\nvar (\n\tserialMutex sync.Mutex\n\tnextSerial  uint32 = 0\n)\n\nfunc GetNextEventSerial() uint32 {\n\tserialMutex.Lock()\n\tdefer serialMutex.Unlock()\n\tnextSerial++\n\treturn nextSerial\n}\n\nfunc getNextSerial() uint32 {\n\treturn GetNextEventSerial()\n}\n\nfunc SendPointerMotion(clients []*Client, x, y float32) {\n\t// Update global pointer position for cursor drawing\n\tPointer.WindowX = x\n\tPointer.WindowY = y\n\n\ttimestamp := uint32(time.Now().UnixMilli())\n\tfor _, client := range clients {\n\t\tif client.Status != ClientStatus_Connected {\n\t\t\tcontinue\n\t\t}\n\t\tif pointerBinds := protocols.GetGlobalWlPointerBinds(client); pointerBinds != nil {\n\t\t\tfor pointerID, version := range pointerBinds {\n\t\t\t\tprotocols.WlPointer_motion(client, pointerID, timestamp, x, y)\n\t\t\t\tprotocols.WlPointer_frame(client, uint32(version), pointerID)\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc SendPointerButton(clients []*Client, button uint32, pressed bool) {\n\ttimestamp := uint32(time.Now().UnixMilli())\n\tser := getNextSerial()\n\tstate := protocols.WlPointerButtonState_enum_released\n\tif pressed {\n\t\tstate = protocols.WlPointerButtonState_enum_pressed\n\t}\n\tfor _, client := range clients {\n\t\tif client.Status != ClientStatus_Connected {\n\t\t\tcontinue\n\t\t}\n\t\tif pointerBinds := protocols.GetGlobalWlPointerBinds(client); pointerBinds != nil {\n\t\t\tfor pointerID, version := range pointerBinds {\n\t\t\t\tprotocols.WlPointer_button(client, pointerID, ser, timestamp, button, state)\n\t\t\t\tprotocols.WlPointer_frame(client, uint32(version), pointerID)\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc SendPointerAxis(clients []*Client, axis protocols.WlPointerAxis_enum, value float32) {\n\ttimestamp := uint32(time.Now().UnixMilli())\n\tfor _, client := range clients {\n\t\tif client.Status != ClientStatus_Connected {\n\t\t\tcontinue\n\t\t}\n\t\tif pointerBinds := protocols.GetGlobalWlPointerBinds(client); pointerBinds != nil {\n\t\t\tfor pointerID, version := range pointerBinds {\n\t\t\t\tprotocols.WlPointer_axis(client, pointerID, timestamp, axis, value)\n\t\t\t\tprotocols.WlPointer_frame(client, uint32(version), pointerID)\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc SendKeyboardKey(clients []*Client, key uint32, pressed bool) {\n\ttimestamp := uint32(time.Now().UnixMilli())\n\tser := getNextSerial()\n\tstate := protocols.WlKeyboardKeyState_enum_released\n\tif pressed {\n\t\tstate = protocols.WlKeyboardKeyState_enum_pressed\n\t}\n\tfor _, client := range clients {\n\t\tif client.Status != ClientStatus_Connected {\n\t\t\tcontinue\n\t\t}\n\t\tif keyboardBinds := protocols.GetGlobalWlKeyboardBinds(client); keyboardBinds != nil {\n\t\t\tfor keyboardID := range keyboardBinds {\n\t\t\t\tprotocols.WlKeyboard_key(client, keyboardID, ser, timestamp, key, state)\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "wayland/ListenToWaylandSocket.go",
    "content": "package wayland\n\nimport (\n\t\"fmt\"\n\t\"net\"\n)\n\nfunc ListenToWaylandSocket(socketName string, socketPath string) (listner *net.UnixListener, fd int, e error) {\n\n\tif err := removeFileIfExists(socketPath); err != nil {\n\t\treturn nil, -1, fmt.Errorf(\"remove existing socket: %w\", err)\n\t}\n\n\taddr := &net.UnixAddr{\n\t\tName: socketPath,\n\t\tNet:  \"unix\",\n\t}\n\tln, err := net.ListenUnix(\"unix\", addr)\n\tif err != nil {\n\t\treturn nil, -1, fmt.Errorf(\"listen unix: %w\", err)\n\t}\n\n\tfile, err := ln.File()\n\tif err != nil {\n\t\t_ = ln.Close()\n\t\treturn nil, -1, fmt.Errorf(\"get listener file: %w\", err)\n\t}\n\tfd = int(file.Fd())\n\t_ = file.Close()\n\n\treturn ln, fd, nil\n}\n"
  },
  {
    "path": "wayland/MemMap.go",
    "content": "package wayland\n\n/*\n#include \"mmap.h\"\n*/\nimport \"C\"\n\nimport (\n\t\"fmt\"\n\t\"unsafe\"\n)\n\ntype MemMapInfo struct {\n\tBytes          []byte\n\tAddr           unsafe.Pointer\n\tSize           C.size_t\n\tFileDescriptor C.int\n\tUnMapped       bool\n}\n\nfunc NewMemMapInfo(fd int, size uint64) (MemMapInfo, error) {\n\tfdNum := C.int(fd)\n\tc_size := C.size_t(size)\n\taddr := C.mmap_fd(fdNum, c_size)\n\tif addr == C.map_failed() {\n\t\treturn MemMapInfo{\n\t\t\tAddr:           addr,\n\t\t\tSize:           c_size,\n\t\t\tFileDescriptor: fdNum,\n\t\t\tUnMapped:       true,\n\t\t}, fmt.Errorf(\"failed to mmap fd %d\", fdNum)\n\t}\n\n\tinfo := MemMapInfo{\n\t\tAddr:           addr,\n\t\tSize:           c_size,\n\t\tFileDescriptor: fdNum,\n\t\tUnMapped:       false,\n\t}\n\tinfo.Bytes = unsafe.Slice((*byte)(info.Addr), info.Size)\n\treturn info, nil\n}\n\nfunc (m *MemMapInfo) Unmap() {\n\tif m.UnMapped {\n\t\treturn\n\t}\n\n\tC.unmap(m.Addr, m.Size)\n\tm.UnMapped = true\n\tm.Bytes = nil\n}\n"
  },
  {
    "path": "wayland/MessageDecoder.go",
    "content": "package wayland\n\nimport \"github.com/mmulet/term.everything/wayland/protocols\"\n\nconst (\n\tstateObjectID protocols.DecodeStateType = iota\n\tstateOpcode\n\tstateSize\n\tstateData\n)\n\nfunc initialDecodeState() protocols.DecodeState {\n\treturn protocols.DecodeState{\n\t\tPhase:    stateObjectID,\n\t\tI:        0,\n\t\tObjectID: 0,\n\t\tOpcode:   0,\n\t\tSize:     0,\n\t\tData:     nil,\n\t}\n}\n\ntype MessageDecoder struct {\n\tstate protocols.DecodeState\n}\n\nfunc MakeMessageDecoder() *MessageDecoder {\n\treturn &MessageDecoder{\n\t\tstate: initialDecodeState(),\n\t}\n}\n\nfunc (d *MessageDecoder) reset() {\n\td.state = initialDecodeState()\n}\n\nfunc (d *MessageDecoder) nextState() {\n\td.state.I = 0\n\tswitch d.state.Phase {\n\tcase stateObjectID:\n\t\td.state.Phase = stateOpcode\n\t\td.state.Opcode = 0\n\tcase stateOpcode:\n\t\td.state.Phase = stateSize\n\t\td.state.Size = 0\n\tcase stateSize:\n\t\td.state.Phase = stateData\n\t\td.state.Data = d.state.Data[:0]\n\t\t// 8 is the header size; no payload means return to initial state\n\t\tif d.state.Size == 8 {\n\t\t\td.reset()\n\t\t}\n\tcase stateData:\n\t\td.reset()\n\t}\n}\n\nfunc (d *MessageDecoder) Consume(buf []byte) []protocols.Message {\n\n\tout := make([]protocols.Message, 0)\n\tfor _, b := range buf {\n\t\tswitch d.state.Phase {\n\t\tcase stateObjectID:\n\t\t\td.state.ObjectID |= protocols.AnyObjectID(b) << d.state.I\n\t\t\td.state.I += 8\n\t\t\tif d.state.I == 32 {\n\t\t\t\td.nextState()\n\t\t\t}\n\t\tcase stateOpcode:\n\t\t\td.state.Opcode |= uint16(b) << d.state.I\n\t\t\td.state.I += 8\n\t\t\tif d.state.I == 16 {\n\t\t\t\td.nextState()\n\t\t\t}\n\t\tcase stateSize:\n\t\t\td.state.Size |= uint16(b) << d.state.I\n\t\t\td.state.I += 8\n\t\t\tif d.state.I == 16 {\n\t\t\t\tif d.state.Size == 8 {\n\t\t\t\t\t// zero-size payload message (header-only)\n\t\t\t\t\tout = append(out, protocols.Message{\n\t\t\t\t\t\tObjectID: d.state.ObjectID,\n\t\t\t\t\t\tOpcode:   d.state.Opcode,\n\t\t\t\t\t\tSize:     d.state.Size,\n\t\t\t\t\t\tData:     []byte{},\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\td.nextState()\n\t\t\t}\n\t\tcase stateData:\n\t\t\td.state.Data = append(d.state.Data, b)\n\t\t\t// size includes 8-byte header, so payload length is size-8\n\t\t\twant := int(d.state.Size) - 8\n\t\t\tif len(d.state.Data) == want {\n\t\t\t\t// copy data to detach from internal buffer\n\t\t\t\tpayload := make([]byte, want)\n\t\t\t\tcopy(payload, d.state.Data)\n\t\t\t\tout = append(out, protocols.Message{\n\t\t\t\t\tObjectID: d.state.ObjectID,\n\t\t\t\t\tOpcode:   d.state.Opcode,\n\t\t\t\t\tSize:     d.state.Size,\n\t\t\t\t\tData:     payload,\n\t\t\t\t})\n\t\t\t\td.nextState()\n\t\t\t}\n\t\t}\n\t}\n\n\treturn out\n}\n"
  },
  {
    "path": "wayland/Readme.md",
    "content": "In this package, we provide utilities for working with Wayland protocol over Unix domain sockets. This will hopefully be a reusable package for custom go Wayland compositors (that I will use at least)."
  },
  {
    "path": "wayland/SendMessageAndFileDescriptors.go",
    "content": "package wayland\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"syscall\"\n)\n\nfunc SendMessageAndFileDescriptors(conn *net.UnixConn, buf []byte, fds []int) error {\n\tif len(buf) == 0 {\n\t\treturn nil\n\t}\n\n\ttotal := 0\n\toobFirst := syscall.UnixRights(fds...)\n\n\tfor total < len(buf) {\n\t\tchunk := buf[total:]\n\t\tvar oob []byte\n\t\tif total == 0 {\n\t\t\toob = oobFirst // send FDs only once\n\t\t}\n\n\t\tn, _, err := conn.WriteMsgUnix(chunk, oob, nil)\n\t\tif err != nil || n == -1 {\n\t\t\tvar out_error error\n\t\t\tif err != nil {\n\t\t\t\tout_error = err\n\t\t\t} else {\n\t\t\t\tout_error = fmt.Errorf(\"N -1 on send message\")\n\t\t\t}\n\t\t\treturn out_error\n\t\t}\n\t\ttotal += n\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "wayland/SocketListener.go",
    "content": "package wayland\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/mmulet/term.everything/wayland/protocols\"\n)\n\n// SocketListener listens for new Wayland client connections on a Unix socket.\n// It provides a channel to receive new connections. Whoevere reads from\n// the channel is responsible for closing the connections when done.\ntype SocketListener struct {\n\tWaylandDisplayName string\n\tSocketPath         string\n\tListener           *net.UnixListener\n\n\tOnConnection chan *net.UnixConn\n}\n\ntype HasDisplayName interface {\n\tWaylandDisplayName() string\n}\n\nfunc MakeSocketListener(args HasDisplayName) (*SocketListener, error) {\n\tdisplayName := GetWaylandDisplayName(args)\n\tsocketPath := GetSocketPathFromName(displayName)\n\n\tif protocols.DebugRequests {\n\t\tfmt.Fprintf(os.Stderr, \"Wayland socket path: %s\\n\", socketPath)\n\t}\n\n\tln, fd, err := ListenToWaylandSocket(displayName, socketPath)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to listen on wayland socket: %w\", err)\n\t}\n\t_ = fd\n\n\tw := &SocketListener{\n\t\tWaylandDisplayName: displayName,\n\t\tSocketPath:         socketPath,\n\t\tListener:           ln,\n\t\tOnConnection:       make(chan *net.UnixConn, 32),\n\t}\n\n\treturn w, nil\n}\n\nfunc (w *SocketListener) MainLoop() error {\n\tfor {\n\t\tconn, err := w.Listener.AcceptUnix()\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to accept connection: %w\", err)\n\t\t}\n\t\tw.OnConnection <- conn\n\t}\n}\n\nfunc (w *SocketListener) MainLoopThenClose() error {\n\tdefer w.Close()\n\treturn w.MainLoop()\n}\n\nfunc (w *SocketListener) Close() error {\n\tif w.Listener != nil {\n\t\tw.Listener.Close()\n\t}\n\treturn removeFileIfExists(w.SocketPath)\n}\n\nfunc GetWaylandDisplayName(args HasDisplayName) string {\n\tif args.WaylandDisplayName() != \"\" {\n\t\treturn args.WaylandDisplayName()\n\t}\n\tif v := os.Getenv(\"WAYLAND_DISPLAY_NAME\"); v != \"\" {\n\t\treturn v\n\t}\n\n\tfor i := 2; i < 1000; i++ {\n\t\tname := fmt.Sprintf(\"wayland-%d\", i)\n\t\tpath := GetSocketPathFromName(name)\n\t\tif _, err := os.Stat(path); err == nil {\n\t\t\tcontinue\n\t\t} else if os.IsNotExist(err) {\n\t\t\treturn name\n\t\t} else {\n\t\t\tcontinue\n\t\t}\n\t}\n\tfmt.Fprintf(os.Stderr, \"Failed to find an open wayland socket name. Pass one with --wayland-display-name <name>\\n\")\n\tos.Exit(1)\n\treturn \"\"\n}\n\nfunc GetSocketPathFromName(socketName string) string {\n\truntimeDir := os.Getenv(\"XDG_RUNTIME_DIR\")\n\tif runtimeDir == \"\" {\n\t\truntimeDir = \"/tmp\"\n\t}\n\treturn filepath.Join(runtimeDir, socketName)\n}\n\nfunc removeFileIfExists(p string) error {\n\tif p == \"\" {\n\t\treturn fmt.Errorf(\"empty path\")\n\t}\n\tif _, err := os.Lstat(p); err != nil {\n\t\tif os.IsNotExist(err) {\n\t\t\treturn nil\n\t\t}\n\t\treturn err\n\t}\n\treturn os.Remove(p)\n}\n"
  },
  {
    "path": "wayland/SurfaceRole.go",
    "content": "package wayland\n\nimport \"github.com/mmulet/term.everything/wayland/protocols\"\n\n/**\n * Surface roles can be thought of as type.\n * [source ](https://wayland.app/protocols/wayland#wl_surface)\n * Things you may do:\n * 1. if unset you may assign it a role\n * 2. if assigned a role you may *not* change it to another role\n * 3. if assigned a role you may *may* assign it the *same* role\n * 4. The role may destroyed, allowing you assign it to the role again (maybe with different data), but not a different role.\n * 5. If the surface is destroyed before the role is destroyed, that is an error.\n */\ntype SurfaceRole interface {\n\tsurface_role()\n\tHasData() bool\n\tClearData()\n}\n\ntype SurfaceRoleXdgPopup struct {\n\tData *protocols.ObjectID[protocols.XdgPopup]\n}\n\nfunc (r *SurfaceRoleXdgPopup) surface_role() {}\nfunc (r *SurfaceRoleXdgPopup) HasData() bool {\n\treturn r.Data != nil\n}\n\nfunc (r *SurfaceRoleXdgPopup) ClearData() {\n\tr.Data = nil\n}\n\ntype CursorHotspot struct {\n\tX, Y int32\n}\n\ntype SurfaceRoleCursorData struct {\n\tHotspot CursorHotspot\n}\n\ntype SurfaceRoleCursor struct {\n\tData *SurfaceRoleCursorData\n}\n\nfunc (r *SurfaceRoleCursor) surface_role() {}\nfunc (r *SurfaceRoleCursor) HasData() bool {\n\treturn r.Data != nil\n}\nfunc (r *SurfaceRoleCursor) ClearData() {\n\tr.Data = nil\n}\n\ntype ToplevelPendingState struct {\n\tMinSize *Size\n\tMaxSize *Size\n}\n\ntype SurfaceRoleXdgToplevel struct {\n\tData *protocols.ObjectID[protocols.XdgToplevel]\n}\n\nfunc (r *SurfaceRoleXdgToplevel) surface_role() {}\nfunc (r *SurfaceRoleXdgToplevel) HasData() bool {\n\treturn r.Data != nil\n}\n\nfunc (r *SurfaceRoleXdgToplevel) ClearData() {\n\tr.Data = nil\n}\n\ntype SurfaceRoleWaylandSurfaceData struct {\n\tSerial *XWaylandSurfaceV1Serial\n}\n\ntype SurfaceRoleXWaylandSurface struct {\n\tData *SurfaceRoleWaylandSurfaceData\n}\n\nfunc (r *SurfaceRoleXWaylandSurface) surface_role() {}\nfunc (r *SurfaceRoleXWaylandSurface) HasData() bool {\n\treturn r.Data != nil\n}\n\nfunc (r *SurfaceRoleXWaylandSurface) ClearData() {\n\tr.Data = nil\n}\n\ntype SurfaceRoleSubSurface struct {\n\tData *protocols.ObjectID[protocols.WlSubsurface]\n}\n\nfunc (r *SurfaceRoleSubSurface) surface_role() {}\nfunc (r *SurfaceRoleSubSurface) HasData() bool {\n\treturn r.Data != nil\n}\nfunc (r *SurfaceRoleSubSurface) ClearData() {\n\tr.Data = nil\n}\n"
  },
  {
    "path": "wayland/SurfaceUpdate.go",
    "content": "package wayland\n\nimport \"github.com/mmulet/term.everything/wayland/protocols\"\n\ntype SurfaceUpdate struct {\n\tOffset *Point\n\n\tDamage []Rect\n\n\tDamageBuffer []Rect\n\n\tBufferScale *int32\n\n\tBufferTransform *protocols.WlOutputTransform_enum\n\n\tInputRegion *protocols.ObjectID[protocols.WlRegion]\n\n\tOpaqueRegion *protocols.ObjectID[protocols.WlRegion]\n\n\tBuffer *protocols.ObjectID[protocols.WlBuffer]\n\n\t/**\n\t * You should unshift when adding to\n\t * this array so that the objects will\n\t * be added in the correct order. (ie\n\t * the ones added last will be on top)\n\t */\n\tAddSubSurface []protocols.ObjectID[protocols.WlSurface]\n\n\tXdgSurfaceWindowGeometry *XdgWindowGeometry\n\n\t/**\n\t * set_child_position and z_oder_subsurfaces\n\t * take place whenever the parent surface is committed,\n\t * thus they are part of the SurfaceUpdate of the parent\n\t */\n\tSetChildPosition []ChildPosition\n\n\t/**\n\t * null means above or below the parent.\n\t */\n\tZOrderSubsurfaces []ZOrderSubsurface\n\n\tXwaylandSurfarfaceV1Serial *XWaylandSurfaceV1Serial\n}\n\ntype Point struct {\n\tX int32\n\tY int32\n}\n\ntype Rect struct {\n\tX      int32\n\tY      int32\n\tWidth  int32\n\tHeight int32\n}\n\n// ChildPosition mirrors { child: Object_ID<wl_surface>; x: number; y: number }\ntype ChildPosition struct {\n\tChild protocols.ObjectID[protocols.WlSurface]\n\tX     int32\n\tY     int32\n}\n\ntype ZOrderSubsurface struct {\n\tType        ZOrder\n\tChildToMove protocols.ObjectID[protocols.WlSurface]\n\t/**\n\t * nil means above or below the parent.\n\t */\n\tRelativeTo *protocols.ObjectID[protocols.WlSurface]\n}\n\ntype ZOrder int\n\nconst (\n\tZOrderTypeAbove ZOrder = iota\n\tZOrderTypeBelow ZOrder = iota + 1\n)\n\ntype XWaylandSurfaceV1Serial struct {\n\tLow uint32\n\tHi  uint32\n}\n"
  },
  {
    "path": "wayland/VirtualMonitorSize.go",
    "content": "package wayland\n\ntype Pixels int\n\ntype PixelSize struct {\n\tWidth  Pixels\n\tHeight Pixels\n}\n\nvar VirtualMonitorSize = PixelSize{\n\tWidth:  640,\n\tHeight: 480,\n}\n"
  },
  {
    "path": "wayland/doc.go",
    "content": "// Package wayland provides a pure Go implementation of a Wayland compositor.\n//\n// This package allows you to create Wayland servers that can host Wayland clients\n// (such as browsers, terminals, and other applications) and render their output\n// to your own display surface.\n//\n// # Basic Usage\n//\n// To create a Wayland compositor, you need to:\n//\n//  1. Create a socket listener with [MakeSocketListener]\n//  2. Accept client connections\n//  3. Handle frame requests and render client surfaces\n//\n// # Minimal Example\n//\n// First, implement the args interface to provide the display name:\n//\n//\ttype Args struct {\n//\t\tDisplayName string\n//\t}\n//\n//\tfunc (a *Args) WaylandDisplayName() string {\n//\t\treturn a.DisplayName // empty string auto-generates a name\n//\t}\n//\n// Create the socket listener and start accepting connections:\n//\n//\targs := &Args{DisplayName: \"\"}\n//\tlistener, err := wayland.MakeSocketListener(args)\n//\tif err != nil {\n//\t\tlog.Fatal(err)\n//\t}\n//\tgo listener.MainLoopThenClose()\n//\n//\t// Track connected clients\n//\tvar clients []*wayland.Client\n//\tvar mu sync.Mutex\n//\n//\t// Accept new client connections\n//\tgo func() {\n//\t\tfor conn := range listener.OnConnection {\n//\t\t\tclient := wayland.MakeClient(conn)\n//\t\t\tmu.Lock()\n//\t\t\tclients = append(clients, client)\n//\t\t\tmu.Unlock()\n//\t\t\tgo client.MainLoop()\n//\t\t\tgo handleFrameRequests(client)\n//\t\t}\n//\t}()\n//\n// Handle frame callbacks to know when clients want to redraw:\n//\n//\tfunc handleFrameRequests(client *wayland.Client) {\n//\t\tfor callbackID := range client.FrameDrawRequests {\n//\t\t\tprotocols.WlCallback_done(client, callbackID, uint32(time.Now().UnixMilli()))\n//\t\t\tif client.Status != wayland.ClientStatus_Connected {\n//\t\t\t\tbreak\n//\t\t\t}\n//\t\t\t// Signal your render loop that a redraw is needed\n//\t\t}\n//\t}\n//\n// Create a desktop for compositing and render in your main loop:\n//\n//\tdesktop := wayland.MakeDesktop(\n//\t\twayland.Size{Width: 800, Height: 600},\n//\t\tfalse,     // useLinuxDMABuf\n//\t\ticonPNG,   // icon data for the desktop\n//\t)\n//\n//\t// In your render loop:\n//\tdesktop.DrawClients(clients)\n//\t// desktop.Buffer now contains RGBA pixel data\n//\t// desktop.Stride is the row stride in bytes\n//\n// Forward input events to clients:\n//\n//\t// Mouse movement (x, y in surface coordinates)\n//\twayland.SendPointerMotion(clients, float32(x), float32(y))\n//\n//\t// Mouse buttons (use Linux BTN_LEFT=0x110, BTN_RIGHT=0x111, etc.)\n//\twayland.SendPointerButton(clients, 0x110, true)  // pressed\n//\twayland.SendPointerButton(clients, 0x110, false) // released\n//\n//\t// Mouse scroll (axis: protocols.WlPointerAxis_enum_vertical_scroll)\n//\twayland.SendPointerAxis(clients, protocols.WlPointerAxis_enum_vertical_scroll, 15.0)\n//\n//\t// Keyboard (use Linux evdev keycodes, e.g., 30 for 'A')\n//\twayland.SendKeyboardKey(clients, 30, true)  // key down\n//\twayland.SendKeyboardKey(clients, 30, false) // key up\n//\n// Launch a Wayland client with the correct environment:\n//\n//\tcmd := exec.Command(\"weston-terminal\")\n//\tcmd.Env = append(os.Environ(),\n//\t\t\"WAYLAND_DISPLAY=\"+listener.WaylandDisplayName,\n//\t\t\"XDG_SESSION_TYPE=wayland\",\n//\t)\n//\tcmd.Start()\npackage wayland\n"
  },
  {
    "path": "wayland/generate/Protocol.go",
    "content": "package main\n\nimport (\n\t\"encoding/xml\"\n\t\"fmt\"\n\t\"strings\"\n)\n\nfunc ToPascalCase(s string) string {\n\tparts := strings.FieldsFunc(s, func(r rune) bool { return r == '_' })\n\tfor i, part := range parts {\n\t\tif len(part) > 0 {\n\t\t\tparts[i] = strings.ToUpper(part[:1]) + strings.ToLower(part[1:])\n\t\t}\n\t}\n\treturn strings.Join(parts, \"\")\n}\n\nfunc enumName(interfaceName, enumNameWithDot string) string {\n\n\tnewEnumName := enumNameWithDot\n\tif !strings.Contains(enumNameWithDot, \".\") {\n\t\tnewEnumName = interfaceName + newEnumName\n\t}\n\n\tparts := strings.FieldsFunc(newEnumName, func(r rune) bool { return r == '.' })\n\n\tfor i, part := range parts {\n\t\tif len(part) > 0 {\n\t\t\tparts[i] = strings.ToUpper(part[:1]) + part[1:]\n\t\t}\n\t}\n\n\tnewEnumName = strings.Join(parts, \"\")\n\treturn newEnumName + \"_enum\"\n}\n\ntype Protocol struct {\n\tXMLName    xml.Name    `xml:\"protocol\"`\n\tName       string      `xml:\"name,attr\"`\n\tInterfaces []Interface `xml:\"interface\"`\n\tCopyright  string      `xml:\"copyright\"`\n}\n\ntype InterfaceAttr struct {\n\tName    string `xml:\"name,attr\"`\n\tVersion string `xml:\"version,attr\"`\n}\n\ntype Interface struct {\n\tInterfaceAttr\n\tDescription any              `xml:\"description\"`\n\tRequests    []EventOrRequest `xml:\"request\"`\n\tEvents      []EventOrRequest `xml:\"event\"`\n\tEnums       []Enum           `xml:\"enum\"`\n}\n\ntype Description struct {\n\tSummary string `xml:\"summary,attr\"`\n}\n\ntype Enum struct {\n\tName    string  `xml:\"name,attr\"`\n\tEntries []Entry `xml:\"entry\"`\n}\n\ntype Entry struct {\n\tName    string `xml:\"name,attr\"`\n\tValue   string `xml:\"value,attr\"`\n\tSummary string `xml:\"summary,attr\"`\n}\n\ntype EventOrRequestAttr struct {\n\tName  string  `xml:\"name,attr\"`\n\tSince *string `xml:\"since,attr,omitempty\"`\n}\n\ntype EventOrRequest struct {\n\tEventOrRequestAttr\n\tArgs        []Arg        `xml:\"arg\"`\n\tDescription *Description `xml:\"description\"`\n}\n\ntype Arg interface {\n\tArgKind() string\n\tName() string\n}\n\ntype ArgCommon struct {\n\tArgName string\n}\n\nfunc (c ArgCommon) Name() string { return c.ArgName }\n\ntype ArgNewID struct {\n\tArgCommon\n\tInterface *string\n}\n\nfunc (*ArgNewID) ArgKind() string { return \"new_id\" }\n\ntype ArgObject struct {\n\tArgCommon\n\tInterface *string\n\tAllowNull *bool\n}\n\nfunc (*ArgObject) ArgKind() string { return \"object\" }\n\ntype ArgUint struct {\n\tArgCommon\n\tEnum *string\n}\n\nfunc (*ArgUint) ArgKind() string { return \"uint\" }\n\ntype ArgString struct {\n\tArgCommon\n\tAllowNull *bool\n}\n\nfunc (*ArgString) ArgKind() string { return \"string\" }\n\ntype ArgInt struct {\n\tArgCommon\n}\n\nfunc (*ArgInt) ArgKind() string { return \"int\" }\n\ntype ArgFd struct {\n\tArgCommon\n}\n\nfunc (*ArgFd) ArgKind() string { return \"fd\" }\n\ntype ArgFixed struct {\n\tArgCommon\n}\n\nfunc (*ArgFixed) ArgKind() string { return \"fixed\" }\n\ntype ArgArray struct {\n\tArgCommon\n}\n\nfunc (*ArgArray) ArgKind() string { return \"array\" }\n\nfunc sanitizedArgName(arg Arg) string {\n\tswitch arg.Name() {\n\tcase \"interface\":\n\t\treturn \"interface_\"\n\tcase \"class\":\n\t\treturn \"class_\"\n\tcase \"make\":\n\t\treturn \"make_\"\n\tdefault:\n\t\treturn arg.Name()\n\t}\n}\n\ntype argXML struct {\n\tName      string  `xml:\"name,attr\"`\n\tType      string  `xml:\"type,attr\"`\n\tInterface *string `xml:\"interface,attr\"`\n\tAllowNull *bool   `xml:\"allow-null,attr\"`\n\tEnum      *string `xml:\"enum,attr\"`\n}\n\ntype eventOrRequestXML struct {\n\tName        string       `xml:\"name,attr\"`\n\tSince       *string      `xml:\"since,attr,omitempty\"`\n\tDescription *Description `xml:\"description\"`\n\tArgs        []argXML     `xml:\"arg\"`\n}\n\ntype interfaceXML struct {\n\tInterfaceAttr\n\tDescription any                 `xml:\"description\"`\n\tRequests    []eventOrRequestXML `xml:\"request\"`\n\tEvents      []eventOrRequestXML `xml:\"event\"`\n\tEnums       []Enum              `xml:\"enum\"`\n}\n\ntype protocolXML struct {\n\tXMLName    xml.Name       `xml:\"protocol\"`\n\tName       string         `xml:\"name,attr\"`\n\tInterfaces []interfaceXML `xml:\"interface\"`\n\tCopyright  string         `xml:\"copyright\"`\n}\n\nfunc convertEventOrRequestXML(x eventOrRequestXML) (EventOrRequest, error) {\n\tout := EventOrRequest{\n\t\tEventOrRequestAttr: EventOrRequestAttr{\n\t\t\tName:  x.Name,\n\t\t\tSince: x.Since,\n\t\t},\n\t\tDescription: x.Description,\n\t\tArgs:        make([]Arg, 0, len(x.Args)),\n\t}\n\n\tfor _, ax := range x.Args {\n\t\tvar a Arg\n\t\tswitch ax.Type {\n\t\tcase \"new_id\":\n\n\t\t\tvar iface *string\n\t\t\tif ax.Interface != nil {\n\t\t\t\tifaceStr := ToPascalCase(*ax.Interface)\n\t\t\t\tiface = &ifaceStr\n\t\t\t}\n\n\t\t\ta = &ArgNewID{\n\t\t\t\tArgCommon: ArgCommon{ArgName: ax.Name},\n\t\t\t\tInterface: iface,\n\t\t\t}\n\t\tcase \"object\":\n\t\t\tvar iface *string\n\t\t\tif ax.Interface != nil {\n\t\t\t\tifaceStr := ToPascalCase(*ax.Interface)\n\t\t\t\tiface = &ifaceStr\n\t\t\t}\n\t\t\ta = &ArgObject{\n\t\t\t\tArgCommon: ArgCommon{ArgName: ax.Name},\n\t\t\t\tInterface: iface,\n\t\t\t\tAllowNull: ax.AllowNull,\n\t\t\t}\n\t\tcase \"uint\":\n\t\t\tvar enum *string\n\t\t\tif ax.Enum != nil {\n\t\t\t\tenumStr := ToPascalCase(*ax.Enum)\n\t\t\t\tenum = &enumStr\n\t\t\t}\n\t\t\ta = &ArgUint{\n\t\t\t\tArgCommon: ArgCommon{ArgName: ax.Name},\n\t\t\t\tEnum:      enum,\n\t\t\t}\n\t\tcase \"string\":\n\t\t\ta = &ArgString{\n\t\t\t\tArgCommon: ArgCommon{ArgName: ax.Name},\n\t\t\t\tAllowNull: ax.AllowNull,\n\t\t\t}\n\t\tcase \"int\":\n\t\t\ta = &ArgInt{ArgCommon: ArgCommon{ArgName: ax.Name}}\n\t\tcase \"fd\":\n\t\t\ta = &ArgFd{ArgCommon: ArgCommon{ArgName: ax.Name}}\n\t\tcase \"fixed\":\n\t\t\ta = &ArgFixed{ArgCommon: ArgCommon{ArgName: ax.Name}}\n\t\tcase \"array\":\n\t\t\ta = &ArgArray{ArgCommon: ArgCommon{ArgName: ax.Name}}\n\t\tdefault:\n\t\t\treturn EventOrRequest{}, fmt.Errorf(\"unknown arg type: %q\", ax.Type)\n\t\t}\n\t\tout.Args = append(out.Args, a)\n\t}\n\n\treturn out, nil\n}\n\nfunc UnmarshalProtocolXML(data []byte) (*Protocol, error) {\n\tvar tmp protocolXML\n\tif err := xml.Unmarshal(data, &tmp); err != nil {\n\t\treturn nil, err\n\t}\n\n\tout := &Protocol{\n\t\tXMLName:   tmp.XMLName,\n\t\tName:      tmp.Name,\n\t\tCopyright: tmp.Copyright,\n\t}\n\tout.Interfaces = make([]Interface, len(tmp.Interfaces))\n\n\tfor i, ix := range tmp.Interfaces {\n\n\t\tout_enums := make([]Enum, len(ix.Enums))\n\t\tfor j, ex := range ix.Enums {\n\t\t\tout_enums[j] = Enum{\n\t\t\t\tName:    ToPascalCase(ex.Name),\n\t\t\t\tEntries: ex.Entries,\n\t\t\t}\n\t\t}\n\n\t\tiface := Interface{\n\t\t\tInterfaceAttr: InterfaceAttr{\n\t\t\t\tName:    ToPascalCase(ix.Name),\n\t\t\t\tVersion: ix.Version,\n\t\t\t},\n\t\t\tDescription: ix.Description,\n\t\t\tEnums:       out_enums,\n\t\t\tRequests:    make([]EventOrRequest, len(ix.Requests)),\n\t\t\tEvents:      make([]EventOrRequest, len(ix.Events)),\n\t\t}\n\n\t\tfor j, rx := range ix.Requests {\n\t\t\tev, err := convertEventOrRequestXML(rx)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"interface %q request %d (%s): %w\", ix.Name, j, rx.Name, err)\n\t\t\t}\n\t\t\tiface.Requests[j] = ev\n\t\t}\n\n\t\tfor j, ex := range ix.Events {\n\t\t\tev, err := convertEventOrRequestXML(ex)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"interface %q event %d (%s): %w\", ix.Name, j, ex.Name, err)\n\t\t\t}\n\t\t\tiface.Events[j] = ev\n\t\t}\n\n\t\tout.Interfaces[i] = iface\n\t}\n\n\treturn out, nil\n}\n\nfunc generateGoType(interfaceName string, a Arg, event bool) string {\n\tname := sanitizedArgName(a)\n\n\tswitch v := a.(type) {\n\tcase *ArgNewID:\n\t\tif v.Interface != nil {\n\t\t\treturn fmt.Sprintf(\"%s ObjectID[%s]\", name, *v.Interface)\n\t\t}\n\t\treturn fmt.Sprintf(\"%sInterface string, %sVersion uint32, %sID AnyObjectID\", name, name, name)\n\n\tcase *ArgObject:\n\t\tif v.Interface != nil {\n\t\t\tif v.AllowNull != nil && *v.AllowNull {\n\t\t\t\treturn fmt.Sprintf(\"%s *ObjectID[%s]\", name, *v.Interface)\n\t\t\t}\n\t\t\treturn fmt.Sprintf(\"%s ObjectID[%s]\", name, *v.Interface)\n\t\t}\n\t\treturn fmt.Sprintf(\"%s AnyObjectID\", name)\n\n\tcase *ArgUint:\n\t\tif v.Enum == nil {\n\t\t\treturn fmt.Sprintf(\"%s uint32\", name)\n\t\t}\n\t\treturn fmt.Sprintf(\"%s %s\", name, enumName(interfaceName, *v.Enum))\n\n\tcase *ArgString:\n\t\treturn fmt.Sprintf(\"%s string\", name)\n\n\tcase *ArgInt:\n\t\treturn fmt.Sprintf(\"%s int32\", name)\n\n\tcase *ArgFd:\n\t\tif event {\n\t\t\treturn fmt.Sprintf(\"%s FileDescriptor\", name)\n\t\t}\n\t\treturn fmt.Sprintf(\"%s *FileDescriptor\", name)\n\n\tcase *ArgFixed:\n\t\tif event {\n\t\t\t// TODO is this right?\n\t\t\treturn fmt.Sprintf(\"%s float32\", name)\n\t\t}\n\t\treturn fmt.Sprintf(\"%s Fixed\", name)\n\n\tcase *ArgArray:\n\t\treturn fmt.Sprintf(\"%s []byte\", name)\n\tdefault:\n\t\tpanic(fmt.Errorf(\"unknown arg kind: %T\", a))\n\t}\n}\n"
  },
  {
    "path": "wayland/generate/build_protocol.go",
    "content": "package main\n\nimport (\n\t\"bytes\"\n\t\"embed\"\n\t\"fmt\"\n\t\"path/filepath\"\n\t\"slices\"\n\t\"strings\"\n\t\"text/template\"\n)\n\ntype BuildProtocolOut struct {\n\tProtocolFile string\n\tHelperFile   string\n}\n\nfunc buildProtocol(fs embed.FS, file string, protocolsPackageNameForHelper string, interfacesToGenHelpersFor []string) (BuildProtocolOut, error) {\n\tdata, err := fs.ReadFile(filepath.Join(\"resources\", file))\n\tif err != nil {\n\t\treturn BuildProtocolOut{}, err\n\t}\n\n\tproto, err := UnmarshalProtocolXML(data)\n\tif err != nil {\n\t\treturn BuildProtocolOut{}, fmt.Errorf(\"unmarshal %s: %w\", file, err)\n\t}\n\n\tvar out strings.Builder\n\n\tvar helperOut strings.Builder\n\n\thelperTemplate := template.Must(template.New(\"helperGetObject\").Parse(`\nfunc Get{{.Name}}Object(cs {{.Pkg}}ClientState, id {{.Pkg}}ObjectID[{{.Pkg}}{{.Name}}]) *{{.Name}} {\n    v := cs.GetObject({{.Pkg}}AnyObjectID(id))\n    if v == nil {\n        return nil\n    }\n    o := v.({{.Pkg}}WaylandObject[{{.Pkg}}{{.Name}}_delegate])\n    d := o.GetDelegate()\n    return d.(*{{.Name}})\n}\n`))\n\n\tfor _, intf := range proto.Interfaces {\n\t\tfmt.Fprintf(&out, \"type %s_delegate interface {\\n\", intf.Name)\n\t\tout.WriteString(genInterfaceInterface(intf))\n\t\tout.WriteString(\"}\\n\\n\")\n\n\t\tfmt.Fprintf(&out, \"type %s struct {\\n\", intf.Name)\n\t\tfmt.Fprintf(&out, \"    Delegate %s_delegate\\n\", intf.Name)\n\t\tout.WriteString(\"}\\n\\n\")\n\n\t\tget_delegate_template := `func (p *%s) GetDelegate() %s_delegate {\n\t\t\treturn p.Delegate\n\t\t}\n\t\t`\n\t\tfmt.Fprintf(&out, get_delegate_template, intf.Name, intf.Name)\n\n\t\tget_bindable_template := `func (p *%s) GetBindable() OnBindable {\n\t\t\treturn p.Delegate\n\t\t}\n\t\t`\n\t\tfmt.Fprintf(&out, get_bindable_template, intf.Name)\n\n\t\t// get_object_template := `\n\t\t// func Get%sObject(cs ClientState, id ObjectID[%s]) WaylandObject[%s_delegate] {\n\t\t// \tv := cs.GetObject(AnyObjectID(id))\n\t\t// \tif v == nil {\n\t\t// \t\treturn nil\n\t\t// \t}\n\t\t// \treturn v.(WaylandObject[%s_delegate])\n\t\t// }\n\t\t// `\n\t\t// fmt.Fprintf(&out, get_object_template, intf.Name, intf.Name, intf.Name, intf.Name)\n\t\t// out.WriteString(\"\\n\")\n\n\t\tout.WriteString(genEvents(intf))\n\t\tout.WriteString(\"\\n\")\n\n\t\trequestHandler := genRequestHandler(intf)\n\n\t\tfmt.Fprintf(&out, \"func (p *%s) OnRequest(s FileDescriptorClaimClientState, message Message) {\\n\", intf.Name)\n\n\t\tif requestHandler != \"\" {\n\t\t\tout.WriteString(\"    _data_in_offset__ := 0\\n\")\n\t\t\tout.WriteString(\"    _ = _data_in_offset__\\n\")\n\t\t\tout.WriteString(\"    d := p.Delegate\\n\")\n\t\t}\n\t\tout.WriteString(\"    switch message.Opcode {\\n\")\n\t\tout.WriteString(requestHandler)\n\t\tout.WriteString(\"    default:\\n\")\n\t\tfmt.Fprintf(&out, \"        fmt.Println(\\\"Unknown opcode on %s\\\", message.Opcode)\\n\", intf.Name)\n\t\tout.WriteString(\"    }\\n\")\n\t\tout.WriteString(\"}\\n\\n\")\n\n\t\tout.WriteString(genEnums(intf))\n\t\tout.WriteString(\"\\n\")\n\n\t\tif len(interfacesToGenHelpersFor) == 0 || slices.Contains(interfacesToGenHelpersFor, intf.Name) {\n\t\t\tvar buf bytes.Buffer\n\t\t\t_ = helperTemplate.Execute(&buf, struct {\n\t\t\t\tName string\n\t\t\t\tPkg  string\n\t\t\t}{\n\t\t\t\tName: intf.Name,\n\t\t\t\tPkg:  filepath.Base(protocolsPackageNameForHelper) + \".\",\n\t\t\t})\n\t\t\thelperOut.WriteString(buf.String())\n\t\t\thelperOut.WriteString(\"\\n\")\n\n\t\t}\n\n\t}\n\n\treturn BuildProtocolOut{\n\t\tProtocolFile: out.String(),\n\t\tHelperFile:   helperOut.String(),\n\t}, nil\n}\n"
  },
  {
    "path": "wayland/generate/gen_enums.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"unicode\"\n)\n\nfunc genEnums(intf Interface) string {\n\tif len(intf.Enums) == 0 {\n\t\treturn \"\"\n\t}\n\n\tvar b strings.Builder\n\tfor _, en := range intf.Enums {\n\t\tenumType := enumName(intf.Name, en.Name)\n\n\t\tfmt.Fprintf(&b, \"type %s uint32\\n\\n\", enumType)\n\n\t\tif len(en.Entries) > 0 {\n\t\t\tb.WriteString(\"const (\\n\")\n\t\t\tfor _, e := range en.Entries {\n\t\t\t\tconstName := sanitizeConstName(e.Name)\n\t\t\t\tfullName := enumType + \"_\" + constName\n\t\t\t\tfmt.Fprintf(&b, \"    %s %s = %s\\n\", fullName, enumType, e.Value)\n\t\t\t}\n\t\t\tb.WriteString(\")\\n\\n\")\n\t\t}\n\t}\n\n\treturn b.String()\n}\nfunc sanitizeConstName(s string) string {\n\tif s == \"\" {\n\t\treturn \"_\"\n\t}\n\tvar out strings.Builder\n\tfor i, r := range s {\n\t\tswitch {\n\t\tcase i == 0 && unicode.IsDigit(r):\n\t\t\tout.WriteRune('_')\n\t\t\tout.WriteRune(r)\n\t\tcase (i == 0 && (unicode.IsLetter(r) || r == '_')) ||\n\t\t\t(i > 0 && (unicode.IsLetter(r) || unicode.IsDigit(r) || r == '_')):\n\t\t\tout.WriteRune(r)\n\t\tdefault:\n\t\t\tout.WriteRune('_')\n\t\t}\n\t}\n\tid := out.String()\n\tswitch id {\n\tcase \"break\", \"default\", \"func\", \"interface\", \"select\",\n\t\t\"case\", \"defer\", \"go\", \"map\", \"struct\",\n\t\t\"chan\", \"else\", \"goto\", \"package\", \"switch\",\n\t\t\"const\", \"fallthrough\", \"if\", \"range\", \"type\",\n\t\t\"continue\", \"for\", \"import\", \"return\", \"var\":\n\t\treturn id + \"_\"\n\t}\n\treturn id\n}\n"
  },
  {
    "path": "wayland/generate/gen_events.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\nfunc genEvents(i Interface) string {\n\tif len(i.Events) == 0 {\n\t\treturn \"\"\n\t}\n\tvar out strings.Builder\n\n\tfor idx, ev := range i.Events {\n\t\tvar argSig []string\n\t\tfor _, a := range ev.Args {\n\t\t\targSig = append(argSig, generateGoType(i.Name, a, true))\n\t\t}\n\n\t\tout.WriteString(\"\\n\")\n\t\tout.WriteString(fmt.Sprintf(\"func %s_%s(\", i.Name, ev.Name))\n\t\tout.WriteString(\"s Sender, \")\n\t\tif ev.Since != nil && *ev.Since != \"\" {\n\t\t\tout.WriteString(\"boundVersion uint32, \")\n\t\t}\n\t\tout.WriteString(fmt.Sprintf(\"eventObjectID ObjectID[%s]\", i.Name))\n\t\tif len(argSig) > 0 {\n\t\t\tout.WriteString(\", \")\n\t\t\tout.WriteString(strings.Join(argSig, \", \"))\n\t\t}\n\t\tout.WriteString(\") {\\n\")\n\n\t\tif ev.Since != nil && *ev.Since != \"\" {\n\t\t\tout.WriteString(fmt.Sprintf(\"    if boundVersion < %s {\\n\", *ev.Since))\n\t\t\tout.WriteString(\"        // Event not available in this version; skip\\n\")\n\t\t\tout.WriteString(\"        return\\n\")\n\t\t\tout.WriteString(\"    }\\n\")\n\t\t}\n\n\t\tneedUint32, needInt32 := false, false\n\t\tfor _, a := range ev.Args {\n\t\t\tswitch a.(type) {\n\t\t\tcase *ArgFixed:\n\t\t\t\tneedInt32 = true\n\t\t\tcase *ArgInt:\n\t\t\t\tneedInt32 = true\n\t\t\tcase *ArgUint, *ArgNewID, *ArgObject:\n\t\t\t\tneedUint32 = true\n\t\t\tcase *ArgString, *ArgArray:\n\t\t\t\tneedUint32 = true\n\t\t\tcase *ArgFd:\n\t\t\t}\n\t\t}\n\n\t\tout.WriteString(\"    data := make([]byte, 0)\\n\")\n\t\tif needUint32 {\n\t\t\tout.WriteString(\"    putUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\\n\")\n\t\t}\n\t\tif needInt32 {\n\t\t\tif needUint32 {\n\t\t\t\tout.WriteString(\"    putInt32 := func(v int32) { putUint32(uint32(v)) }\\n\")\n\t\t\t} else {\n\t\t\t\tout.WriteString(\"    putInt32 := func(v int32) { uv := uint32(v); data = append(data, byte(uv), byte(uv>>8), byte(uv>>16), byte(uv>>24)) }\\n\")\n\t\t\t}\n\t\t}\n\t\tout.WriteString(\"    var fileDescriptor *FileDescriptor\\n\")\n\n\t\tfor _, a := range ev.Args {\n\t\t\tname := sanitizedArgName(a)\n\t\t\tswitch v := a.(type) {\n\t\t\tcase *ArgFixed:\n\t\t\t\tout.WriteString(fmt.Sprintf(\"    // fixed: 24.8\\n    putInt32(int32(%s * 256.0))\\n\", name))\n\t\t\tcase *ArgInt:\n\t\t\t\tout.WriteString(fmt.Sprintf(\"    putInt32(int32(%s))\\n\", name))\n\t\t\tcase *ArgUint:\n\t\t\t\tout.WriteString(fmt.Sprintf(\"    putUint32(uint32(%s))\\n\", name))\n\t\t\tcase *ArgNewID:\n\t\t\t\tout.WriteString(fmt.Sprintf(\"    putUint32(uint32(%s))\\n\", name))\n\t\t\tcase *ArgObject:\n\t\t\t\tif v.Interface != nil && v.AllowNull != nil && *v.AllowNull {\n\t\t\t\t\ttmp := \"__tmp_\" + name\n\t\t\t\t\tout.WriteString(fmt.Sprintf(\"    var %s uint32\\n\", tmp))\n\t\t\t\t\tout.WriteString(fmt.Sprintf(\"    if %s != nil { %s = uint32(*%s) }\\n\", name, tmp, name))\n\t\t\t\t\tout.WriteString(fmt.Sprintf(\"    putUint32(%s)\\n\", tmp))\n\t\t\t\t} else {\n\t\t\t\t\tout.WriteString(fmt.Sprintf(\"    putUint32(uint32(%s))\\n\", name))\n\t\t\t\t}\n\t\t\tcase *ArgFd:\n\t\t\t\tout.WriteString(fmt.Sprintf(\"    fileDescriptor = &%s\\n\", name))\n\t\t\tcase *ArgString:\n\t\t\t\tout.WriteString(fmt.Sprintf(\n\t\t\t\t\t\"    {\\n\"+\n\t\t\t\t\t\t\"        b := []byte(%s)\\n\"+\n\t\t\t\t\t\t\"        total := len(b) + 1 // include null terminator\\n\"+\n\t\t\t\t\t\t\"        putUint32(uint32(total))\\n\"+\n\t\t\t\t\t\t\"        data = append(data, b...)\\n\"+\n\t\t\t\t\t\t\"        data = append(data, 0)\\n\"+\n\t\t\t\t\t\t\"        if pad := (4 - (total %% 4)) %% 4; pad != 0 {\\n\"+\n\t\t\t\t\t\t\"            data = append(data, make([]byte, pad)...)\\n\"+\n\t\t\t\t\t\t\"        }\\n\"+\n\t\t\t\t\t\t\"    }\\n\", name))\n\t\t\tcase *ArgArray:\n\t\t\t\tout.WriteString(fmt.Sprintf(\n\t\t\t\t\t\"    {\\n\"+\n\t\t\t\t\t\t\"        n := len(%s)\\n\"+\n\t\t\t\t\t\t\"        putUint32(uint32(n))\\n\"+\n\t\t\t\t\t\t\"        data = append(data, %s...)\\n\"+\n\t\t\t\t\t\t\"        if pad := (4 - (n %% 4)) %% 4; pad != 0 {\\n\"+\n\t\t\t\t\t\t\"            data = append(data, make([]byte, pad)...)\\n\"+\n\t\t\t\t\t\t\"        }\\n\"+\n\t\t\t\t\t\t\"    }\\n\", name, name))\n\t\t\tdefault:\n\t\t\t\tout.WriteString(fmt.Sprintf(\"    // TODO: unhandled arg kind: %T\\n\", a))\n\t\t\t}\n\t\t}\n\t\tout.WriteString(\"    obj := OutgoingEvent{\\n\")\n\t\tout.WriteString(\"        ObjectID:       AnyObjectID(eventObjectID),\\n\")\n\t\tout.WriteString(fmt.Sprintf(\"        Opcode:         %d,\\n\", idx))\n\t\tout.WriteString(\"        Data:           data,\\n\")\n\t\tout.WriteString(\"        FileDescriptor: fileDescriptor,\\n\")\n\t\tout.WriteString(\"    }\\n\")\n\t\tout.WriteString(\"    s.Send(obj)\\n\")\n\n\t\tout.WriteString(\"}\\n\")\n\t}\n\n\treturn out.String()\n}\n"
  },
  {
    "path": "wayland/generate/gen_interface_interface.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\nfunc genInterfaceInterface(iface Interface) string {\n\ton_bind_declaration := \"OnBind(s ClientState, name AnyObjectID, interface_ string, new_id AnyObjectID, version_number uint32)\\n\"\n\tif len(iface.Requests) == 0 {\n\t\treturn on_bind_declaration\n\t}\n\n\tvar b strings.Builder\n\n\tfor _, req := range iface.Requests {\n\t\tparams := []string{\n\t\t\t\"s ClientState\",\n\t\t\tfmt.Sprintf(\"object_id ObjectID[%s]\", iface.Name),\n\t\t}\n\t\tfor _, a := range req.Args {\n\t\t\tparams = append(params, generateGoType(iface.Name, a, false))\n\t\t}\n\n\t\tmethodName := fmt.Sprintf(\"%s_%s\", iface.Name, req.Name)\n\t\tsignature := fmt.Sprintf(\"%s(%s)\", methodName, strings.Join(params, \", \"))\n\n\t\tif req.Name == \"destroy\" || req.Name == \"release\" {\n\t\t\tsignature += \" bool\"\n\t\t}\n\n\t\tb.WriteString(signature)\n\t\tb.WriteByte('\\n')\n\t}\n\n\t// b.WriteString(fmt.Sprintf(\n\t// \t// \"%s_on_bind(s ClientState, name ObjectID[%s], interface_ string, new_id ObjectID[%s], version_number uint32)\\n\",\n\t// \t\"%s_on_bind(s ClientState, name ObjectID[%s], interface_ string, new_id ObjectID[%s], version_number uint32)\\n\",\n\t// \tiface.Name, iface.Name, iface.Name,\n\t// ))\n\n\tb.WriteString(on_bind_declaration)\n\n\tswitch iface.Name {\n\tcase \"WlKeyboard\":\n\t\tb.WriteString(\"AfterGetKeyboard(s ClientState, object_id ObjectID[WlKeyboard])\\n\")\n\tcase \"WlPointer\":\n\t\tb.WriteString(\"AfterGetPointer(s ClientState, object_id ObjectID[WlPointer])\\n\")\n\t}\n\n\treturn b.String()\n}\n"
  },
  {
    "path": "wayland/generate/gen_request_handler.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\nfunc argFlatmap(a Arg, postfix string) []string {\n\tswitch v := a.(type) {\n\tcase *ArgNewID:\n\t\tif v.Interface == nil {\n\t\t\tbase := sanitizedArgName(a)\n\t\t\treturn []string{\n\t\t\t\tbase + \"Interface\" + postfix,\n\t\t\t\tbase + \"Version\" + postfix,\n\t\t\t\tbase + \"ID\" + postfix,\n\t\t\t}\n\t\t}\n\t}\n\treturn []string{sanitizedArgName(a) + postfix}\n}\n\nfunc genRequestHandler(i Interface) string {\n\tif len(i.Requests) == 0 {\n\t\treturn \"\"\n\t}\n\n\tvar out strings.Builder\n\n\tfor idx, req := range i.Requests {\n\t\tvar argList []string\n\t\tfor _, a := range req.Args {\n\t\t\targList = append(argList, argFlatmap(a, \"\")...)\n\t\t}\n\n\t\tvar debugPieces []string\n\t\tfor _, a := range req.Args {\n\t\t\tfor _, nm := range argFlatmap(a, \"\") {\n\t\t\t\tdebugPieces = append(debugPieces, fmt.Sprintf(\"\\\"%s: \\\", %s\", nm, nm))\n\t\t\t}\n\t\t}\n\t\tdebugArgs := \"\"\n\t\tif len(debugPieces) > 0 {\n\t\t\tdebugArgs = strings.Join(debugPieces, \", \\\", \\\", \")\n\t\t} else {\n\t\t\tdebugArgs = \"\\\")\\\"\"\n\t\t}\n\n\t\tisAutoRemove := req.Name == \"release\" || req.Name == \"destroy\"\n\n\t\tfmt.Fprintf(&out, \"case %d: {\\n\\n\", idx)\n\n\t\tfor _, a := range req.Args {\n\t\t\tout.WriteString(genArgParseCode(a, i.Name))\n\t\t\tout.WriteString(\"\\n\")\n\t\t}\n\n\t\tout.WriteString(\"if DebugRequests {\\n\")\n\t\tfmt.Fprintf(&out, \"  fmt.Print(\\\"%s@\\\", message.ObjectID, \\\".%s(\\\")\\n\", i.Name, req.Name)\n\t\tif len(debugPieces) > 0 {\n\t\t\tfmt.Fprintf(&out, \"  fmt.Println(%s, \\\")\\\")\\n\", debugArgs)\n\t\t} else {\n\t\t\tout.WriteString(\"  fmt.Println(\\\")\\\")\\n\")\n\t\t}\n\t\tout.WriteString(\"}\\n\\n\")\n\n\t\tcall := fmt.Sprintf(\"d.%s_%s(s, ObjectID[%s](message.ObjectID), %s)\", i.Name, req.Name, i.Name, strings.Join(argList, \", \"))\n\t\tif isAutoRemove {\n\t\t\tfmt.Fprintf(&out, \"autoRemove := %s\\n\", call)\n\t\t} else {\n\t\t\tfmt.Fprintf(&out, \"%s\\n\", call)\n\t\t}\n\n\t\tif req.Name == \"release\" {\n\t\t\tout.WriteString(\"if autoRemove {\\n\")\n\t\t\tout.WriteString(\"  s.RemoveObject(message.ObjectID)\\n\")\n\n\t\t\tswitch i.Name {\n\t\t\tcase \"WlShm\", \"WlSeat\", \"WlOutput\", \"WlKeyboard\", \"WlPointer\", \"WlTouch\", \"WlDataDevice\", \"ZwpXwaylandKeyboardGrabManagerV1\":\n\t\t\t\tfmt.Fprintf(&out, \"  s.RemoveGlobal%sBind(ObjectID[%s](message.ObjectID))\\n\", i.Name, i.Name)\n\t\t\t}\n\n\t\t\tout.WriteString(\"}\\n\")\n\t\t}\n\t\tif req.Name == \"destroy\" {\n\t\t\tout.WriteString(\"if autoRemove {\\n\")\n\t\t\tout.WriteString(\"  s.RemoveObject(message.ObjectID)\\n\")\n\t\t\tout.WriteString(\"}\\n\")\n\t\t}\n\n\t\tout.WriteString(\"break\\n\")\n\t\tout.WriteString(\"}\\n\\n\")\n\t}\n\n\treturn out.String()\n}\n\nfunc genArgParseCode(a Arg, interfaceName string) string {\n\tname := sanitizedArgName(a)\n\n\tswitch v := a.(type) {\n\tcase *ArgFixed:\n\t\treturn fmt.Sprintf(`%sRaw := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n  uint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n%s := float64(int32(%sRaw)) / 256.0\n_data_in_offset__ += 4\n`, name, name, name)\n\n\tcase *ArgNewID:\n\t\tif v.Interface == nil {\n\t\t\treturn genArgParseCode(&ArgString{ArgCommon: ArgCommon{ArgName: name + \"Interface\"}}, interfaceName) +\n\t\t\t\tgenArgParseCode(&ArgUint{ArgCommon: ArgCommon{ArgName: name + \"Version\"}}, interfaceName) +\n\t\t\t\tgenArgParseCode(&ArgObject{ArgCommon: ArgCommon{ArgName: name + \"ID\"}}, interfaceName)\n\t\t}\n\t\treturn fmt.Sprintf(`%sVal := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n  uint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n%s := ObjectID[%s](%sVal)\n_data_in_offset__ += 4\n`, name, name, *v.Interface, name)\n\n\tcase *ArgUint:\n\t\tif v.Enum != nil {\n\t\t\treturn fmt.Sprintf(`%s := %s(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n  uint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n_data_in_offset__ += 4\n`, name, enumName(interfaceName, *v.Enum))\n\t\t}\n\t\treturn fmt.Sprintf(`%s := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n  uint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n_data_in_offset__ += 4\n`, name)\n\n\tcase *ArgInt:\n\t\treturn fmt.Sprintf(`%s := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n  uint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n_data_in_offset__ += 4\n`, name)\n\n\tcase *ArgObject:\n\t\tif v.Interface != nil {\n\t\t\tif v.AllowNull != nil && *v.AllowNull {\n\t\t\t\treturn fmt.Sprintf(`%sTmp := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n  uint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n_data_in_offset__ += 4\nvar %s *ObjectID[%s]\nif %sTmp != 0 {\n  tmp := ObjectID[%s](%sTmp)\n  %s = &tmp\n}\n`, name, name, *v.Interface, name, *v.Interface, name, name)\n\t\t\t}\n\t\t\treturn fmt.Sprintf(`%s := ObjectID[%s](uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n  uint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n_data_in_offset__ += 4\n`, name, *v.Interface)\n\t\t}\n\t\treturn fmt.Sprintf(`%s := AnyObjectID(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n  uint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n_data_in_offset__ += 4\n`, name)\n\n\tcase *ArgString:\n\t\treturn fmt.Sprintf(`%sLen := int(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n  uint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n_data_in_offset__ += 4\n%s := string(message.Data[_data_in_offset__ : _data_in_offset__+%sLen-1]) // NUL-terminated\n// 4-byte alignment\nif %sLen%%4 != 0 {\n  _data_in_offset__ += %sLen + (4 - (%sLen %% 4))\n} else {\n  _data_in_offset__ += %sLen\n}\n`, name, name, name, name, name, name, name)\n\n\tcase *ArgArray:\n\t\treturn fmt.Sprintf(`%sLen := int(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n  uint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n_data_in_offset__ += 4\n%s := message.Data[_data_in_offset__ : _data_in_offset__+%sLen]\nif %sLen%%4 != 0 {\n  _data_in_offset__ += %sLen + (4 - (%sLen %% 4))\n} else {\n  _data_in_offset__ += %sLen\n}\n`, name, name, name, name, name, name, name)\n\n\tcase *ArgFd:\n\t\treturn fmt.Sprintf(`%s := s.ClaimFileDescriptor()\n`, name)\n\n\tdefault:\n\t\tpanic(fmt.Errorf(\"unknown arg kind: %T\", a))\n\t}\n}\n"
  },
  {
    "path": "wayland/generate/protocols.go",
    "content": "package main\n\nimport (\n\t\"embed\"\n\t\"fmt\"\n\t\"go/format\"\n\t\"log\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"sort\"\n\t\"sync\"\n)\n\n//go:embed resources\nvar protocolsFS embed.FS\n\nfunc main() {\n\n\tvar outDir string\n\tif len(os.Args) > 1 {\n\t\toutDir = os.Args[1]\n\t} else {\n\t\tlog.Fatal(`Usage: protocols protocol_out_dir [helpers_out_dir protocols_package ...interfaces]\n\nGenerates protocol bindings into protocol_out_dir\nOptionally, generate helper functions into helpers_out_dir\nOutput helper function into helpers_out_dir (usually want this be a different package than protocols)\nSo if so, also provide protocols_package as the package name for protocols package like github.com/mmulet/term.everything/wayland/protocols\nIf you omit this we'll assume the helpers are in the same package as protocols\n\nIf you provide interfaces, we'll only generate those those helpers. separated by space.\n`)\n\t}\n\tvar helpersOutDir string\n\n\tif len(os.Args) > 2 {\n\t\thelpersOutDir = os.Args[2]\n\t}\n\n\tvar currentDirInPackage string\n\tif len(os.Args) > 3 {\n\t\tcurrentDirInPackage = os.Args[3]\n\t} else {\n\t\tcurrentDirInPackage = \"wayland/protocols\"\n\t}\n\n\tfmt.Println(currentDirInPackage)\n\n\tprotocolsPackage := filepath.Join(currentDirInPackage, outDir)\n\tprotocolsPackage = filepath.Clean(protocolsPackage)\n\n\tfmt.Println(protocolsPackage)\n\n\tvar interfacesToGenHelpersFor []string\n\tif len(os.Args) > 4 {\n\t\tfor i := 4; i < len(os.Args); i++ {\n\t\t\tinterfacesToGenHelpersFor = append(interfacesToGenHelpersFor, os.Args[i])\n\t\t}\n\t}\n\n\tentries, err := protocolsFS.ReadDir(\"resources\")\n\tif err != nil {\n\t\tlog.Fatalf(\"read embedded dir resources: %v\", err)\n\t}\n\n\tvar files []string\n\tfor _, e := range entries {\n\t\tif e.IsDir() {\n\t\t\tcontinue\n\t\t}\n\t\tfiles = append(files, e.Name())\n\t}\n\tsort.Strings(files)\n\n\tresults := make([]BuildProtocolOut, len(files))\n\tvar wg sync.WaitGroup\n\terrOnce := make(chan error, 1)\n\tfor i, f := range files {\n\t\twg.Add(1)\n\t\tgo func(idx int, file string) {\n\t\t\tdefer wg.Done()\n\t\t\tout, err := buildProtocol(protocolsFS, file, protocolsPackage, interfacesToGenHelpersFor)\n\t\t\tif err != nil {\n\t\t\t\tselect {\n\t\t\t\tcase errOnce <- err:\n\t\t\t\tdefault:\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\t\t\tresults[idx] = out\n\t\t}(i, f)\n\t}\n\twg.Wait()\n\tselect {\n\tcase e := <-errOnce:\n\t\tlog.Fatal(e)\n\tdefault:\n\t}\n\n\twriteOutputFiles := func(outDir string, results []BuildProtocolOut, helper bool) {\n\t\tpkg := filepath.Base(outDir)\n\n\t\tvar additionalImport string\n\t\tif helper {\n\t\t\tadditionalImport = fmt.Sprintf(`import \"%s\"`, protocolsPackage)\n\t\t} else {\n\t\t\tadditionalImport = `import \"fmt\"`\n\t\t}\n\n\t\toutFile := fmt.Sprintf(`// Code generated by `+\"`cmd/protocols`\"+`; DO NOT EDIT.\n\n\tpackage %s\n\n\t`, pkg)\n\n\t\tif err := os.MkdirAll(outDir, 0755); err != nil {\n\t\t\tlog.Fatalf(\"create dir %s: %v\", outDir, err)\n\t\t}\n\n\t\tfor i, s := range results {\n\t\t\tvar out string\n\t\t\tvar dest string\n\t\t\tif helper {\n\t\t\t\tif s.HelperFile == \"\" {\n\t\t\t\t\tout = outFile\n\t\t\t\t} else {\n\t\t\t\t\tout = outFile + additionalImport + \"\\n\" + s.HelperFile\n\t\t\t\t}\n\n\t\t\t\tdest = filepath.Join(outDir, filepath.Base(files[i])+\".helper.go\")\n\n\t\t\t} else {\n\t\t\t\tout = outFile + additionalImport + \"\\n\" + s.ProtocolFile\n\t\t\t\tdest = filepath.Join(outDir, filepath.Base(files[i])+\".go\")\n\n\t\t\t}\n\t\t\tformatted, err := format.Source([]byte(out))\n\t\t\tif err != nil {\n\t\t\t\tlog.Fatalf(\"format %s: %v\", dest, err)\n\t\t\t}\n\n\t\t\tif err := os.WriteFile(dest, formatted, 0o644); err != nil {\n\t\t\t\tlog.Fatalf(\"write %s: %v\", dest, err)\n\t\t\t}\n\n\t\t\tfmt.Println(\"wrote\", dest)\n\n\t\t}\n\t}\n\n\twriteOutputFiles(outDir, results, false)\n\n\tif helpersOutDir == \"\" {\n\t\treturn\n\t}\n\thelpersOutDir, err = filepath.Abs(helpersOutDir)\n\tif err != nil {\n\t\tlog.Fatalf(\"abs path for helpersOutDir: %v\", err)\n\t}\n\tprint(\"Generating helpers into \", helpersOutDir, \"\\n\")\n\n\twriteOutputFiles(helpersOutDir, results, true)\n\n}\n"
  },
  {
    "path": "wayland/generate/resources/wayland.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<protocol name=\"wayland\">\n\n  <copyright>\n    Copyright © 2008-2011 Kristian Høgsberg\n    Copyright © 2010-2011 Intel Corporation\n    Copyright © 2012-2013 Collabora, Ltd.\n\n    Permission is hereby granted, free of charge, to any person\n    obtaining a copy of this software and associated documentation files\n    (the \"Software\"), to deal in the Software without restriction,\n    including without limitation the rights to use, copy, modify, merge,\n    publish, distribute, sublicense, and/or sell copies of the Software,\n    and to permit persons to whom the Software is furnished to do so,\n    subject to the following conditions:\n\n    The above copyright notice and this permission notice (including the\n    next paragraph) shall be included in all copies or substantial\n    portions of the Software.\n\n    THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n    NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\n    BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\n    ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\n    CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n    SOFTWARE.\n  </copyright>\n\n  <interface name=\"wl_display\" version=\"1\">\n    <description summary=\"core global object\">\n      The core global object.  This is a special singleton object.  It\n      is used for internal Wayland protocol features.\n    </description>\n\n    <request name=\"sync\">\n      <description summary=\"asynchronous roundtrip\">\n\tThe sync request asks the server to emit the 'done' event\n\ton the returned wl_callback object.  Since requests are\n\thandled in-order and events are delivered in-order, this can\n\tbe used as a barrier to ensure all previous requests and the\n\tresulting events have been handled.\n\n\tThe object returned by this request will be destroyed by the\n\tcompositor after the callback is fired and as such the client must not\n\tattempt to use it after that point.\n\n\tThe callback_data passed in the callback is undefined and should be ignored.\n      </description>\n      <arg name=\"callback\" type=\"new_id\" interface=\"wl_callback\"\n\t   summary=\"callback object for the sync request\"/>\n    </request>\n\n    <request name=\"get_registry\">\n      <description summary=\"get global registry object\">\n\tThis request creates a registry object that allows the client\n\tto list and bind the global objects available from the\n\tcompositor.\n\n\tIt should be noted that the server side resources consumed in\n\tresponse to a get_registry request can only be released when the\n\tclient disconnects, not when the client side proxy is destroyed.\n\tTherefore, clients should invoke get_registry as infrequently as\n\tpossible to avoid wasting memory.\n      </description>\n      <arg name=\"registry\" type=\"new_id\" interface=\"wl_registry\"\n\t   summary=\"global registry object\"/>\n    </request>\n\n    <event name=\"error\">\n      <description summary=\"fatal error event\">\n\tThe error event is sent out when a fatal (non-recoverable)\n\terror has occurred.  The object_id argument is the object\n\twhere the error occurred, most often in response to a request\n\tto that object.  The code identifies the error and is defined\n\tby the object interface.  As such, each interface defines its\n\town set of error codes.  The message is a brief description\n\tof the error, for (debugging) convenience.\n      </description>\n      <arg name=\"object_id\" type=\"object\" summary=\"object where the error occurred\"/>\n      <arg name=\"code\" type=\"uint\" summary=\"error code\"/>\n      <arg name=\"message\" type=\"string\" summary=\"error description\"/>\n    </event>\n\n    <enum name=\"error\">\n      <description summary=\"global error values\">\n\tThese errors are global and can be emitted in response to any\n\tserver request.\n      </description>\n      <entry name=\"invalid_object\" value=\"0\"\n\t     summary=\"server couldn't find object\"/>\n      <entry name=\"invalid_method\" value=\"1\"\n\t     summary=\"method doesn't exist on the specified interface or malformed request\"/>\n      <entry name=\"no_memory\" value=\"2\"\n\t     summary=\"server is out of memory\"/>\n      <entry name=\"implementation\" value=\"3\"\n\t     summary=\"implementation error in compositor\"/>\n    </enum>\n\n    <event name=\"delete_id\">\n      <description summary=\"acknowledge object ID deletion\">\n\tThis event is used internally by the object ID management\n\tlogic. When a client deletes an object that it had created,\n\tthe server will send this event to acknowledge that it has\n\tseen the delete request. When the client receives this event,\n\tit will know that it can safely reuse the object ID.\n      </description>\n      <arg name=\"id\" type=\"uint\" summary=\"deleted object ID\"/>\n    </event>\n  </interface>\n\n  <interface name=\"wl_registry\" version=\"1\">\n    <description summary=\"global registry object\">\n      The singleton global registry object.  The server has a number of\n      global objects that are available to all clients.  These objects\n      typically represent an actual object in the server (for example,\n      an input device) or they are singleton objects that provide\n      extension functionality.\n\n      When a client creates a registry object, the registry object\n      will emit a global event for each global currently in the\n      registry.  Globals come and go as a result of device or\n      monitor hotplugs, reconfiguration or other events, and the\n      registry will send out global and global_remove events to\n      keep the client up to date with the changes.  To mark the end\n      of the initial burst of events, the client can use the\n      wl_display.sync request immediately after calling\n      wl_display.get_registry.\n\n      A client can bind to a global object by using the bind\n      request.  This creates a client-side handle that lets the object\n      emit events to the client and lets the client invoke requests on\n      the object.\n    </description>\n\n    <request name=\"bind\">\n      <description summary=\"bind an object to the display\">\n\tBinds a new, client-created object to the server using the\n\tspecified name as the identifier.\n      </description>\n      <arg name=\"name\" type=\"uint\" summary=\"unique numeric name of the object\"/>\n      <arg name=\"id\" type=\"new_id\" summary=\"bounded object\"/>\n    </request>\n\n    <event name=\"global\">\n      <description summary=\"announce global object\">\n\tNotify the client of global objects.\n\n\tThe event notifies the client that a global object with\n\tthe given name is now available, and it implements the\n\tgiven version of the given interface.\n      </description>\n      <arg name=\"name\" type=\"uint\" summary=\"numeric name of the global object\"/>\n      <arg name=\"interface\" type=\"string\" summary=\"interface implemented by the object\"/>\n      <arg name=\"version\" type=\"uint\" summary=\"interface version\"/>\n    </event>\n\n    <event name=\"global_remove\">\n      <description summary=\"announce removal of global object\">\n\tNotify the client of removed global objects.\n\n\tThis event notifies the client that the global identified\n\tby name is no longer available.  If the client bound to\n\tthe global using the bind request, the client should now\n\tdestroy that object.\n\n\tThe object remains valid and requests to the object will be\n\tignored until the client destroys it, to avoid races between\n\tthe global going away and a client sending a request to it.\n      </description>\n      <arg name=\"name\" type=\"uint\" summary=\"numeric name of the global object\"/>\n    </event>\n  </interface>\n\n  <interface name=\"wl_callback\" version=\"1\">\n    <description summary=\"callback object\">\n      Clients can handle the 'done' event to get notified when\n      the related request is done.\n\n      Note, because wl_callback objects are created from multiple independent\n      factory interfaces, the wl_callback interface is frozen at version 1.\n    </description>\n\n    <event name=\"done\" type=\"destructor\">\n      <description summary=\"done event\">\n\tNotify the client when the related request is done.\n      </description>\n      <arg name=\"callback_data\" type=\"uint\" summary=\"request-specific data for the callback\"/>\n    </event>\n  </interface>\n\n  <interface name=\"wl_compositor\" version=\"6\">\n    <description summary=\"the compositor singleton\">\n      A compositor.  This object is a singleton global.  The\n      compositor is in charge of combining the contents of multiple\n      surfaces into one displayable output.\n    </description>\n\n    <request name=\"create_surface\">\n      <description summary=\"create new surface\">\n\tAsk the compositor to create a new surface.\n      </description>\n      <arg name=\"id\" type=\"new_id\" interface=\"wl_surface\" summary=\"the new surface\"/>\n    </request>\n\n    <request name=\"create_region\">\n      <description summary=\"create new region\">\n\tAsk the compositor to create a new region.\n      </description>\n      <arg name=\"id\" type=\"new_id\" interface=\"wl_region\" summary=\"the new region\"/>\n    </request>\n  </interface>\n\n  <interface name=\"wl_shm_pool\" version=\"2\">\n    <description summary=\"a shared memory pool\">\n      The wl_shm_pool object encapsulates a piece of memory shared\n      between the compositor and client.  Through the wl_shm_pool\n      object, the client can allocate shared memory wl_buffer objects.\n      All objects created through the same pool share the same\n      underlying mapped memory. Reusing the mapped memory avoids the\n      setup/teardown overhead and is useful when interactively resizing\n      a surface or for many small buffers.\n    </description>\n\n    <request name=\"create_buffer\">\n      <description summary=\"create a buffer from the pool\">\n\tCreate a wl_buffer object from the pool.\n\n\tThe buffer is created offset bytes into the pool and has\n\twidth and height as specified.  The stride argument specifies\n\tthe number of bytes from the beginning of one row to the beginning\n\tof the next.  The format is the pixel format of the buffer and\n\tmust be one of those advertised through the wl_shm.format event.\n\n\tA buffer will keep a reference to the pool it was created from\n\tso it is valid to destroy the pool immediately after creating\n\ta buffer from it.\n      </description>\n      <arg name=\"id\" type=\"new_id\" interface=\"wl_buffer\" summary=\"buffer to create\"/>\n      <arg name=\"offset\" type=\"int\" summary=\"buffer byte offset within the pool\"/>\n      <arg name=\"width\" type=\"int\" summary=\"buffer width, in pixels\"/>\n      <arg name=\"height\" type=\"int\" summary=\"buffer height, in pixels\"/>\n      <arg name=\"stride\" type=\"int\" summary=\"number of bytes from the beginning of one row to the beginning of the next row\"/>\n      <arg name=\"format\" type=\"uint\" enum=\"wl_shm.format\" summary=\"buffer pixel format\"/>\n    </request>\n\n    <request name=\"destroy\" type=\"destructor\">\n      <description summary=\"destroy the pool\">\n\tDestroy the shared memory pool.\n\n\tThe mmapped memory will be released when all\n\tbuffers that have been created from this pool\n\tare gone.\n      </description>\n    </request>\n\n    <request name=\"resize\">\n      <description summary=\"change the size of the pool mapping\">\n\tThis request will cause the server to remap the backing memory\n\tfor the pool from the file descriptor passed when the pool was\n\tcreated, but using the new size.  This request can only be\n\tused to make the pool bigger.\n\n\tThis request only changes the amount of bytes that are mmapped\n\tby the server and does not touch the file corresponding to the\n\tfile descriptor passed at creation time. It is the client's\n\tresponsibility to ensure that the file is at least as big as\n\tthe new pool size.\n      </description>\n      <arg name=\"size\" type=\"int\" summary=\"new size of the pool, in bytes\"/>\n    </request>\n  </interface>\n\n  <interface name=\"wl_shm\" version=\"2\">\n    <description summary=\"shared memory support\">\n      A singleton global object that provides support for shared\n      memory.\n\n      Clients can create wl_shm_pool objects using the create_pool\n      request.\n\n      On binding the wl_shm object one or more format events\n      are emitted to inform clients about the valid pixel formats\n      that can be used for buffers.\n    </description>\n\n    <enum name=\"error\">\n      <description summary=\"wl_shm error values\">\n\tThese errors can be emitted in response to wl_shm requests.\n      </description>\n      <entry name=\"invalid_format\" value=\"0\" summary=\"buffer format is not known\"/>\n      <entry name=\"invalid_stride\" value=\"1\" summary=\"invalid size or stride during pool or buffer creation\"/>\n      <entry name=\"invalid_fd\" value=\"2\" summary=\"mmapping the file descriptor failed\"/>\n    </enum>\n\n    <enum name=\"format\">\n      <description summary=\"pixel formats\">\n\tThis describes the memory layout of an individual pixel.\n\n\tAll renderers should support argb8888 and xrgb8888 but any other\n\tformats are optional and may not be supported by the particular\n\trenderer in use.\n\n\tThe drm format codes match the macros defined in drm_fourcc.h, except\n\targb8888 and xrgb8888. The formats actually supported by the compositor\n\twill be reported by the format event.\n\n\tFor all wl_shm formats and unless specified in another protocol\n\textension, pre-multiplied alpha is used for pixel values.\n      </description>\n      <!-- Note to protocol writers: don't update this list manually, instead\n\t   run the automated script that keeps it in sync with drm_fourcc.h. -->\n      <entry name=\"argb8888\" value=\"0\" summary=\"32-bit ARGB format, [31:0] A:R:G:B 8:8:8:8 little endian\"/>\n      <entry name=\"xrgb8888\" value=\"1\" summary=\"32-bit RGB format, [31:0] x:R:G:B 8:8:8:8 little endian\"/>\n      <entry name=\"c8\" value=\"0x20203843\" summary=\"8-bit color index format, [7:0] C\"/>\n      <entry name=\"rgb332\" value=\"0x38424752\" summary=\"8-bit RGB format, [7:0] R:G:B 3:3:2\"/>\n      <entry name=\"bgr233\" value=\"0x38524742\" summary=\"8-bit BGR format, [7:0] B:G:R 2:3:3\"/>\n      <entry name=\"xrgb4444\" value=\"0x32315258\" summary=\"16-bit xRGB format, [15:0] x:R:G:B 4:4:4:4 little endian\"/>\n      <entry name=\"xbgr4444\" value=\"0x32314258\" summary=\"16-bit xBGR format, [15:0] x:B:G:R 4:4:4:4 little endian\"/>\n      <entry name=\"rgbx4444\" value=\"0x32315852\" summary=\"16-bit RGBx format, [15:0] R:G:B:x 4:4:4:4 little endian\"/>\n      <entry name=\"bgrx4444\" value=\"0x32315842\" summary=\"16-bit BGRx format, [15:0] B:G:R:x 4:4:4:4 little endian\"/>\n      <entry name=\"argb4444\" value=\"0x32315241\" summary=\"16-bit ARGB format, [15:0] A:R:G:B 4:4:4:4 little endian\"/>\n      <entry name=\"abgr4444\" value=\"0x32314241\" summary=\"16-bit ABGR format, [15:0] A:B:G:R 4:4:4:4 little endian\"/>\n      <entry name=\"rgba4444\" value=\"0x32314152\" summary=\"16-bit RBGA format, [15:0] R:G:B:A 4:4:4:4 little endian\"/>\n      <entry name=\"bgra4444\" value=\"0x32314142\" summary=\"16-bit BGRA format, [15:0] B:G:R:A 4:4:4:4 little endian\"/>\n      <entry name=\"xrgb1555\" value=\"0x35315258\" summary=\"16-bit xRGB format, [15:0] x:R:G:B 1:5:5:5 little endian\"/>\n      <entry name=\"xbgr1555\" value=\"0x35314258\" summary=\"16-bit xBGR 1555 format, [15:0] x:B:G:R 1:5:5:5 little endian\"/>\n      <entry name=\"rgbx5551\" value=\"0x35315852\" summary=\"16-bit RGBx 5551 format, [15:0] R:G:B:x 5:5:5:1 little endian\"/>\n      <entry name=\"bgrx5551\" value=\"0x35315842\" summary=\"16-bit BGRx 5551 format, [15:0] B:G:R:x 5:5:5:1 little endian\"/>\n      <entry name=\"argb1555\" value=\"0x35315241\" summary=\"16-bit ARGB 1555 format, [15:0] A:R:G:B 1:5:5:5 little endian\"/>\n      <entry name=\"abgr1555\" value=\"0x35314241\" summary=\"16-bit ABGR 1555 format, [15:0] A:B:G:R 1:5:5:5 little endian\"/>\n      <entry name=\"rgba5551\" value=\"0x35314152\" summary=\"16-bit RGBA 5551 format, [15:0] R:G:B:A 5:5:5:1 little endian\"/>\n      <entry name=\"bgra5551\" value=\"0x35314142\" summary=\"16-bit BGRA 5551 format, [15:0] B:G:R:A 5:5:5:1 little endian\"/>\n      <entry name=\"rgb565\" value=\"0x36314752\" summary=\"16-bit RGB 565 format, [15:0] R:G:B 5:6:5 little endian\"/>\n      <entry name=\"bgr565\" value=\"0x36314742\" summary=\"16-bit BGR 565 format, [15:0] B:G:R 5:6:5 little endian\"/>\n      <entry name=\"rgb888\" value=\"0x34324752\" summary=\"24-bit RGB format, [23:0] R:G:B little endian\"/>\n      <entry name=\"bgr888\" value=\"0x34324742\" summary=\"24-bit BGR format, [23:0] B:G:R little endian\"/>\n      <entry name=\"xbgr8888\" value=\"0x34324258\" summary=\"32-bit xBGR format, [31:0] x:B:G:R 8:8:8:8 little endian\"/>\n      <entry name=\"rgbx8888\" value=\"0x34325852\" summary=\"32-bit RGBx format, [31:0] R:G:B:x 8:8:8:8 little endian\"/>\n      <entry name=\"bgrx8888\" value=\"0x34325842\" summary=\"32-bit BGRx format, [31:0] B:G:R:x 8:8:8:8 little endian\"/>\n      <entry name=\"abgr8888\" value=\"0x34324241\" summary=\"32-bit ABGR format, [31:0] A:B:G:R 8:8:8:8 little endian\"/>\n      <entry name=\"rgba8888\" value=\"0x34324152\" summary=\"32-bit RGBA format, [31:0] R:G:B:A 8:8:8:8 little endian\"/>\n      <entry name=\"bgra8888\" value=\"0x34324142\" summary=\"32-bit BGRA format, [31:0] B:G:R:A 8:8:8:8 little endian\"/>\n      <entry name=\"xrgb2101010\" value=\"0x30335258\" summary=\"32-bit xRGB format, [31:0] x:R:G:B 2:10:10:10 little endian\"/>\n      <entry name=\"xbgr2101010\" value=\"0x30334258\" summary=\"32-bit xBGR format, [31:0] x:B:G:R 2:10:10:10 little endian\"/>\n      <entry name=\"rgbx1010102\" value=\"0x30335852\" summary=\"32-bit RGBx format, [31:0] R:G:B:x 10:10:10:2 little endian\"/>\n      <entry name=\"bgrx1010102\" value=\"0x30335842\" summary=\"32-bit BGRx format, [31:0] B:G:R:x 10:10:10:2 little endian\"/>\n      <entry name=\"argb2101010\" value=\"0x30335241\" summary=\"32-bit ARGB format, [31:0] A:R:G:B 2:10:10:10 little endian\"/>\n      <entry name=\"abgr2101010\" value=\"0x30334241\" summary=\"32-bit ABGR format, [31:0] A:B:G:R 2:10:10:10 little endian\"/>\n      <entry name=\"rgba1010102\" value=\"0x30334152\" summary=\"32-bit RGBA format, [31:0] R:G:B:A 10:10:10:2 little endian\"/>\n      <entry name=\"bgra1010102\" value=\"0x30334142\" summary=\"32-bit BGRA format, [31:0] B:G:R:A 10:10:10:2 little endian\"/>\n      <entry name=\"yuyv\" value=\"0x56595559\" summary=\"packed YCbCr format, [31:0] Cr0:Y1:Cb0:Y0 8:8:8:8 little endian\"/>\n      <entry name=\"yvyu\" value=\"0x55595659\" summary=\"packed YCbCr format, [31:0] Cb0:Y1:Cr0:Y0 8:8:8:8 little endian\"/>\n      <entry name=\"uyvy\" value=\"0x59565955\" summary=\"packed YCbCr format, [31:0] Y1:Cr0:Y0:Cb0 8:8:8:8 little endian\"/>\n      <entry name=\"vyuy\" value=\"0x59555956\" summary=\"packed YCbCr format, [31:0] Y1:Cb0:Y0:Cr0 8:8:8:8 little endian\"/>\n      <entry name=\"ayuv\" value=\"0x56555941\" summary=\"packed AYCbCr format, [31:0] A:Y:Cb:Cr 8:8:8:8 little endian\"/>\n      <entry name=\"nv12\" value=\"0x3231564e\" summary=\"2 plane YCbCr Cr:Cb format, 2x2 subsampled Cr:Cb plane\"/>\n      <entry name=\"nv21\" value=\"0x3132564e\" summary=\"2 plane YCbCr Cb:Cr format, 2x2 subsampled Cb:Cr plane\"/>\n      <entry name=\"nv16\" value=\"0x3631564e\" summary=\"2 plane YCbCr Cr:Cb format, 2x1 subsampled Cr:Cb plane\"/>\n      <entry name=\"nv61\" value=\"0x3136564e\" summary=\"2 plane YCbCr Cb:Cr format, 2x1 subsampled Cb:Cr plane\"/>\n      <entry name=\"yuv410\" value=\"0x39565559\" summary=\"3 plane YCbCr format, 4x4 subsampled Cb (1) and Cr (2) planes\"/>\n      <entry name=\"yvu410\" value=\"0x39555659\" summary=\"3 plane YCbCr format, 4x4 subsampled Cr (1) and Cb (2) planes\"/>\n      <entry name=\"yuv411\" value=\"0x31315559\" summary=\"3 plane YCbCr format, 4x1 subsampled Cb (1) and Cr (2) planes\"/>\n      <entry name=\"yvu411\" value=\"0x31315659\" summary=\"3 plane YCbCr format, 4x1 subsampled Cr (1) and Cb (2) planes\"/>\n      <entry name=\"yuv420\" value=\"0x32315559\" summary=\"3 plane YCbCr format, 2x2 subsampled Cb (1) and Cr (2) planes\"/>\n      <entry name=\"yvu420\" value=\"0x32315659\" summary=\"3 plane YCbCr format, 2x2 subsampled Cr (1) and Cb (2) planes\"/>\n      <entry name=\"yuv422\" value=\"0x36315559\" summary=\"3 plane YCbCr format, 2x1 subsampled Cb (1) and Cr (2) planes\"/>\n      <entry name=\"yvu422\" value=\"0x36315659\" summary=\"3 plane YCbCr format, 2x1 subsampled Cr (1) and Cb (2) planes\"/>\n      <entry name=\"yuv444\" value=\"0x34325559\" summary=\"3 plane YCbCr format, non-subsampled Cb (1) and Cr (2) planes\"/>\n      <entry name=\"yvu444\" value=\"0x34325659\" summary=\"3 plane YCbCr format, non-subsampled Cr (1) and Cb (2) planes\"/>\n      <entry name=\"r8\" value=\"0x20203852\" summary=\"[7:0] R\"/>\n      <entry name=\"r16\" value=\"0x20363152\" summary=\"[15:0] R little endian\"/>\n      <entry name=\"rg88\" value=\"0x38384752\" summary=\"[15:0] R:G 8:8 little endian\"/>\n      <entry name=\"gr88\" value=\"0x38385247\" summary=\"[15:0] G:R 8:8 little endian\"/>\n      <entry name=\"rg1616\" value=\"0x32334752\" summary=\"[31:0] R:G 16:16 little endian\"/>\n      <entry name=\"gr1616\" value=\"0x32335247\" summary=\"[31:0] G:R 16:16 little endian\"/>\n      <entry name=\"xrgb16161616f\" value=\"0x48345258\" summary=\"[63:0] x:R:G:B 16:16:16:16 little endian\"/>\n      <entry name=\"xbgr16161616f\" value=\"0x48344258\" summary=\"[63:0] x:B:G:R 16:16:16:16 little endian\"/>\n      <entry name=\"argb16161616f\" value=\"0x48345241\" summary=\"[63:0] A:R:G:B 16:16:16:16 little endian\"/>\n      <entry name=\"abgr16161616f\" value=\"0x48344241\" summary=\"[63:0] A:B:G:R 16:16:16:16 little endian\"/>\n      <entry name=\"xyuv8888\" value=\"0x56555958\" summary=\"[31:0] X:Y:Cb:Cr 8:8:8:8 little endian\"/>\n      <entry name=\"vuy888\" value=\"0x34325556\" summary=\"[23:0] Cr:Cb:Y 8:8:8 little endian\"/>\n      <entry name=\"vuy101010\" value=\"0x30335556\" summary=\"Y followed by U then V, 10:10:10. Non-linear modifier only\"/>\n      <entry name=\"y210\" value=\"0x30313259\" summary=\"[63:0] Cr0:0:Y1:0:Cb0:0:Y0:0 10:6:10:6:10:6:10:6 little endian per 2 Y pixels\"/>\n      <entry name=\"y212\" value=\"0x32313259\" summary=\"[63:0] Cr0:0:Y1:0:Cb0:0:Y0:0 12:4:12:4:12:4:12:4 little endian per 2 Y pixels\"/>\n      <entry name=\"y216\" value=\"0x36313259\" summary=\"[63:0] Cr0:Y1:Cb0:Y0 16:16:16:16 little endian per 2 Y pixels\"/>\n      <entry name=\"y410\" value=\"0x30313459\" summary=\"[31:0] A:Cr:Y:Cb 2:10:10:10 little endian\"/>\n      <entry name=\"y412\" value=\"0x32313459\" summary=\"[63:0] A:0:Cr:0:Y:0:Cb:0 12:4:12:4:12:4:12:4 little endian\"/>\n      <entry name=\"y416\" value=\"0x36313459\" summary=\"[63:0] A:Cr:Y:Cb 16:16:16:16 little endian\"/>\n      <entry name=\"xvyu2101010\" value=\"0x30335658\" summary=\"[31:0] X:Cr:Y:Cb 2:10:10:10 little endian\"/>\n      <entry name=\"xvyu12_16161616\" value=\"0x36335658\" summary=\"[63:0] X:0:Cr:0:Y:0:Cb:0 12:4:12:4:12:4:12:4 little endian\"/>\n      <entry name=\"xvyu16161616\" value=\"0x38345658\" summary=\"[63:0] X:Cr:Y:Cb 16:16:16:16 little endian\"/>\n      <entry name=\"y0l0\" value=\"0x304c3059\" summary=\"[63:0]   A3:A2:Y3:0:Cr0:0:Y2:0:A1:A0:Y1:0:Cb0:0:Y0:0  1:1:8:2:8:2:8:2:1:1:8:2:8:2:8:2 little endian\"/>\n      <entry name=\"x0l0\" value=\"0x304c3058\" summary=\"[63:0]   X3:X2:Y3:0:Cr0:0:Y2:0:X1:X0:Y1:0:Cb0:0:Y0:0  1:1:8:2:8:2:8:2:1:1:8:2:8:2:8:2 little endian\"/>\n      <entry name=\"y0l2\" value=\"0x324c3059\" summary=\"[63:0]   A3:A2:Y3:Cr0:Y2:A1:A0:Y1:Cb0:Y0  1:1:10:10:10:1:1:10:10:10 little endian\"/>\n      <entry name=\"x0l2\" value=\"0x324c3058\" summary=\"[63:0]   X3:X2:Y3:Cr0:Y2:X1:X0:Y1:Cb0:Y0  1:1:10:10:10:1:1:10:10:10 little endian\"/>\n      <entry name=\"yuv420_8bit\" value=\"0x38305559\"/>\n      <entry name=\"yuv420_10bit\" value=\"0x30315559\"/>\n      <entry name=\"xrgb8888_a8\" value=\"0x38415258\"/>\n      <entry name=\"xbgr8888_a8\" value=\"0x38414258\"/>\n      <entry name=\"rgbx8888_a8\" value=\"0x38415852\"/>\n      <entry name=\"bgrx8888_a8\" value=\"0x38415842\"/>\n      <entry name=\"rgb888_a8\" value=\"0x38413852\"/>\n      <entry name=\"bgr888_a8\" value=\"0x38413842\"/>\n      <entry name=\"rgb565_a8\" value=\"0x38413552\"/>\n      <entry name=\"bgr565_a8\" value=\"0x38413542\"/>\n      <entry name=\"nv24\" value=\"0x3432564e\" summary=\"non-subsampled Cr:Cb plane\"/>\n      <entry name=\"nv42\" value=\"0x3234564e\" summary=\"non-subsampled Cb:Cr plane\"/>\n      <entry name=\"p210\" value=\"0x30313250\" summary=\"2x1 subsampled Cr:Cb plane, 10 bit per channel\"/>\n      <entry name=\"p010\" value=\"0x30313050\" summary=\"2x2 subsampled Cr:Cb plane 10 bits per channel\"/>\n      <entry name=\"p012\" value=\"0x32313050\" summary=\"2x2 subsampled Cr:Cb plane 12 bits per channel\"/>\n      <entry name=\"p016\" value=\"0x36313050\" summary=\"2x2 subsampled Cr:Cb plane 16 bits per channel\"/>\n      <entry name=\"axbxgxrx106106106106\" value=\"0x30314241\" summary=\"[63:0] A:x:B:x:G:x:R:x 10:6:10:6:10:6:10:6 little endian\"/>\n      <entry name=\"nv15\" value=\"0x3531564e\" summary=\"2x2 subsampled Cr:Cb plane\"/>\n      <entry name=\"q410\" value=\"0x30313451\"/>\n      <entry name=\"q401\" value=\"0x31303451\"/>\n      <entry name=\"xrgb16161616\" value=\"0x38345258\" summary=\"[63:0] x:R:G:B 16:16:16:16 little endian\"/>\n      <entry name=\"xbgr16161616\" value=\"0x38344258\" summary=\"[63:0] x:B:G:R 16:16:16:16 little endian\"/>\n      <entry name=\"argb16161616\" value=\"0x38345241\" summary=\"[63:0] A:R:G:B 16:16:16:16 little endian\"/>\n      <entry name=\"abgr16161616\" value=\"0x38344241\" summary=\"[63:0] A:B:G:R 16:16:16:16 little endian\"/>\n      <entry name=\"c1\" value=\"0x20203143\" summary=\"[7:0] C0:C1:C2:C3:C4:C5:C6:C7 1:1:1:1:1:1:1:1 eight pixels/byte\"/>\n      <entry name=\"c2\" value=\"0x20203243\" summary=\"[7:0] C0:C1:C2:C3 2:2:2:2 four pixels/byte\"/>\n      <entry name=\"c4\" value=\"0x20203443\" summary=\"[7:0] C0:C1 4:4 two pixels/byte\"/>\n      <entry name=\"d1\" value=\"0x20203144\" summary=\"[7:0] D0:D1:D2:D3:D4:D5:D6:D7 1:1:1:1:1:1:1:1 eight pixels/byte\"/>\n      <entry name=\"d2\" value=\"0x20203244\" summary=\"[7:0] D0:D1:D2:D3 2:2:2:2 four pixels/byte\"/>\n      <entry name=\"d4\" value=\"0x20203444\" summary=\"[7:0] D0:D1 4:4 two pixels/byte\"/>\n      <entry name=\"d8\" value=\"0x20203844\" summary=\"[7:0] D\"/>\n      <entry name=\"r1\" value=\"0x20203152\" summary=\"[7:0] R0:R1:R2:R3:R4:R5:R6:R7 1:1:1:1:1:1:1:1 eight pixels/byte\"/>\n      <entry name=\"r2\" value=\"0x20203252\" summary=\"[7:0] R0:R1:R2:R3 2:2:2:2 four pixels/byte\"/>\n      <entry name=\"r4\" value=\"0x20203452\" summary=\"[7:0] R0:R1 4:4 two pixels/byte\"/>\n      <entry name=\"r10\" value=\"0x20303152\" summary=\"[15:0] x:R 6:10 little endian\"/>\n      <entry name=\"r12\" value=\"0x20323152\" summary=\"[15:0] x:R 4:12 little endian\"/>\n      <entry name=\"avuy8888\" value=\"0x59555641\" summary=\"[31:0] A:Cr:Cb:Y 8:8:8:8 little endian\"/>\n      <entry name=\"xvuy8888\" value=\"0x59555658\" summary=\"[31:0] X:Cr:Cb:Y 8:8:8:8 little endian\"/>\n      <entry name=\"p030\" value=\"0x30333050\" summary=\"2x2 subsampled Cr:Cb plane 10 bits per channel packed\"/>\n    </enum>\n\n    <request name=\"create_pool\">\n      <description summary=\"create a shm pool\">\n\tCreate a new wl_shm_pool object.\n\n\tThe pool can be used to create shared memory based buffer\n\tobjects.  The server will mmap size bytes of the passed file\n\tdescriptor, to use as backing memory for the pool.\n      </description>\n      <arg name=\"id\" type=\"new_id\" interface=\"wl_shm_pool\" summary=\"pool to create\"/>\n      <arg name=\"fd\" type=\"fd\" summary=\"file descriptor for the pool\"/>\n      <arg name=\"size\" type=\"int\" summary=\"pool size, in bytes\"/>\n    </request>\n\n    <event name=\"format\">\n      <description summary=\"pixel format description\">\n\tInforms the client about a valid pixel format that\n\tcan be used for buffers. Known formats include\n\targb8888 and xrgb8888.\n      </description>\n      <arg name=\"format\" type=\"uint\" enum=\"format\" summary=\"buffer pixel format\"/>\n    </event>\n\n    <!-- Version 2 additions -->\n\n    <request name=\"release\" type=\"destructor\" since=\"2\">\n      <description summary=\"release the shm object\">\n\tUsing this request a client can tell the server that it is not going to\n\tuse the shm object anymore.\n\n\tObjects created via this interface remain unaffected.\n      </description>\n    </request>\n  </interface>\n\n  <interface name=\"wl_buffer\" version=\"1\">\n    <description summary=\"content for a wl_surface\">\n      A buffer provides the content for a wl_surface. Buffers are\n      created through factory interfaces such as wl_shm, wp_linux_buffer_params\n      (from the linux-dmabuf protocol extension) or similar. It has a width and\n      a height and can be attached to a wl_surface, but the mechanism by which a\n      client provides and updates the contents is defined by the buffer factory\n      interface.\n\n      Color channels are assumed to be electrical rather than optical (in other\n      words, encoded with a transfer function) unless otherwise specified. If\n      the buffer uses a format that has an alpha channel, the alpha channel is\n      assumed to be premultiplied into the electrical color channel values\n      (after transfer function encoding) unless otherwise specified.\n\n      Note, because wl_buffer objects are created from multiple independent\n      factory interfaces, the wl_buffer interface is frozen at version 1.\n    </description>\n\n    <request name=\"destroy\" type=\"destructor\">\n      <description summary=\"destroy a buffer\">\n\tDestroy a buffer. If and how you need to release the backing\n\tstorage is defined by the buffer factory interface.\n\n\tFor possible side-effects to a surface, see wl_surface.attach.\n      </description>\n    </request>\n\n    <event name=\"release\">\n      <description summary=\"compositor releases buffer\">\n\tSent when this wl_buffer is no longer used by the compositor.\n\tThe client is now free to reuse or destroy this buffer and its\n\tbacking storage.\n\n\tIf a client receives a release event before the frame callback\n\trequested in the same wl_surface.commit that attaches this\n\twl_buffer to a surface, then the client is immediately free to\n\treuse the buffer and its backing storage, and does not need a\n\tsecond buffer for the next surface content update. Typically\n\tthis is possible, when the compositor maintains a copy of the\n\twl_surface contents, e.g. as a GL texture. This is an important\n\toptimization for GL(ES) compositors with wl_shm clients.\n      </description>\n    </event>\n  </interface>\n\n  <interface name=\"wl_data_offer\" version=\"3\">\n    <description summary=\"offer to transfer data\">\n      A wl_data_offer represents a piece of data offered for transfer\n      by another client (the source client).  It is used by the\n      copy-and-paste and drag-and-drop mechanisms.  The offer\n      describes the different mime types that the data can be\n      converted to and provides the mechanism for transferring the\n      data directly from the source client.\n    </description>\n\n    <enum name=\"error\">\n      <entry name=\"invalid_finish\" value=\"0\"\n\t     summary=\"finish request was called untimely\"/>\n      <entry name=\"invalid_action_mask\" value=\"1\"\n\t     summary=\"action mask contains invalid values\"/>\n      <entry name=\"invalid_action\" value=\"2\"\n\t     summary=\"action argument has an invalid value\"/>\n      <entry name=\"invalid_offer\" value=\"3\"\n\t     summary=\"offer doesn't accept this request\"/>\n    </enum>\n\n    <request name=\"accept\">\n      <description summary=\"accept one of the offered mime types\">\n\tIndicate that the client can accept the given mime type, or\n\tNULL for not accepted.\n\n\tFor objects of version 2 or older, this request is used by the\n\tclient to give feedback whether the client can receive the given\n\tmime type, or NULL if none is accepted; the feedback does not\n\tdetermine whether the drag-and-drop operation succeeds or not.\n\n\tFor objects of version 3 or newer, this request determines the\n\tfinal result of the drag-and-drop operation. If the end result\n\tis that no mime types were accepted, the drag-and-drop operation\n\twill be cancelled and the corresponding drag source will receive\n\twl_data_source.cancelled. Clients may still use this event in\n\tconjunction with wl_data_source.action for feedback.\n      </description>\n      <arg name=\"serial\" type=\"uint\" summary=\"serial number of the accept request\"/>\n      <arg name=\"mime_type\" type=\"string\" allow-null=\"true\" summary=\"mime type accepted by the client\"/>\n    </request>\n\n    <request name=\"receive\">\n      <description summary=\"request that the data is transferred\">\n\tTo transfer the offered data, the client issues this request\n\tand indicates the mime type it wants to receive.  The transfer\n\thappens through the passed file descriptor (typically created\n\twith the pipe system call).  The source client writes the data\n\tin the mime type representation requested and then closes the\n\tfile descriptor.\n\n\tThe receiving client reads from the read end of the pipe until\n\tEOF and then closes its end, at which point the transfer is\n\tcomplete.\n\n\tThis request may happen multiple times for different mime types,\n\tboth before and after wl_data_device.drop. Drag-and-drop destination\n\tclients may preemptively fetch data or examine it more closely to\n\tdetermine acceptance.\n      </description>\n      <arg name=\"mime_type\" type=\"string\" summary=\"mime type desired by receiver\"/>\n      <arg name=\"fd\" type=\"fd\" summary=\"file descriptor for data transfer\"/>\n    </request>\n\n    <request name=\"destroy\" type=\"destructor\">\n      <description summary=\"destroy data offer\">\n\tDestroy the data offer.\n      </description>\n    </request>\n\n    <event name=\"offer\">\n      <description summary=\"advertise offered mime type\">\n\tSent immediately after creating the wl_data_offer object.  One\n\tevent per offered mime type.\n      </description>\n      <arg name=\"mime_type\" type=\"string\" summary=\"offered mime type\"/>\n    </event>\n\n    <!-- Version 3 additions -->\n\n    <request name=\"finish\" since=\"3\">\n      <description summary=\"the offer will no longer be used\">\n\tNotifies the compositor that the drag destination successfully\n\tfinished the drag-and-drop operation.\n\n\tUpon receiving this request, the compositor will emit\n\twl_data_source.dnd_finished on the drag source client.\n\n\tIt is a client error to perform other requests than\n\twl_data_offer.destroy after this one. It is also an error to perform\n\tthis request after a NULL mime type has been set in\n\twl_data_offer.accept or no action was received through\n\twl_data_offer.action.\n\n\tIf wl_data_offer.finish request is received for a non drag and drop\n\toperation, the invalid_finish protocol error is raised.\n      </description>\n    </request>\n\n    <request name=\"set_actions\" since=\"3\">\n      <description summary=\"set the available/preferred drag-and-drop actions\">\n\tSets the actions that the destination side client supports for\n\tthis operation. This request may trigger the emission of\n\twl_data_source.action and wl_data_offer.action events if the compositor\n\tneeds to change the selected action.\n\n\tThis request can be called multiple times throughout the\n\tdrag-and-drop operation, typically in response to wl_data_device.enter\n\tor wl_data_device.motion events.\n\n\tThis request determines the final result of the drag-and-drop\n\toperation. If the end result is that no action is accepted,\n\tthe drag source will receive wl_data_source.cancelled.\n\n\tThe dnd_actions argument must contain only values expressed in the\n\twl_data_device_manager.dnd_actions enum, and the preferred_action\n\targument must only contain one of those values set, otherwise it\n\twill result in a protocol error.\n\n\tWhile managing an \"ask\" action, the destination drag-and-drop client\n\tmay perform further wl_data_offer.receive requests, and is expected\n\tto perform one last wl_data_offer.set_actions request with a preferred\n\taction other than \"ask\" (and optionally wl_data_offer.accept) before\n\trequesting wl_data_offer.finish, in order to convey the action selected\n\tby the user. If the preferred action is not in the\n\twl_data_offer.source_actions mask, an error will be raised.\n\n\tIf the \"ask\" action is dismissed (e.g. user cancellation), the client\n\tis expected to perform wl_data_offer.destroy right away.\n\n\tThis request can only be made on drag-and-drop offers, a protocol error\n\twill be raised otherwise.\n      </description>\n      <arg name=\"dnd_actions\" type=\"uint\" summary=\"actions supported by the destination client\"\n\t   enum=\"wl_data_device_manager.dnd_action\"/>\n      <arg name=\"preferred_action\" type=\"uint\" summary=\"action preferred by the destination client\"\n\t   enum=\"wl_data_device_manager.dnd_action\"/>\n    </request>\n\n    <event name=\"source_actions\" since=\"3\">\n      <description summary=\"notify the source-side available actions\">\n\tThis event indicates the actions offered by the data source. It\n\twill be sent immediately after creating the wl_data_offer object,\n\tor anytime the source side changes its offered actions through\n\twl_data_source.set_actions.\n      </description>\n      <arg name=\"source_actions\" type=\"uint\" summary=\"actions offered by the data source\"\n\t   enum=\"wl_data_device_manager.dnd_action\"/>\n    </event>\n\n    <event name=\"action\" since=\"3\">\n      <description summary=\"notify the selected action\">\n\tThis event indicates the action selected by the compositor after\n\tmatching the source/destination side actions. Only one action (or\n\tnone) will be offered here.\n\n\tThis event can be emitted multiple times during the drag-and-drop\n\toperation in response to destination side action changes through\n\twl_data_offer.set_actions.\n\n\tThis event will no longer be emitted after wl_data_device.drop\n\thappened on the drag-and-drop destination, the client must\n\thonor the last action received, or the last preferred one set\n\tthrough wl_data_offer.set_actions when handling an \"ask\" action.\n\n\tCompositors may also change the selected action on the fly, mainly\n\tin response to keyboard modifier changes during the drag-and-drop\n\toperation.\n\n\tThe most recent action received is always the valid one. Prior to\n\treceiving wl_data_device.drop, the chosen action may change (e.g.\n\tdue to keyboard modifiers being pressed). At the time of receiving\n\twl_data_device.drop the drag-and-drop destination must honor the\n\tlast action received.\n\n\tAction changes may still happen after wl_data_device.drop,\n\tespecially on \"ask\" actions, where the drag-and-drop destination\n\tmay choose another action afterwards. Action changes happening\n\tat this stage are always the result of inter-client negotiation, the\n\tcompositor shall no longer be able to induce a different action.\n\n\tUpon \"ask\" actions, it is expected that the drag-and-drop destination\n\tmay potentially choose a different action and/or mime type,\n\tbased on wl_data_offer.source_actions and finally chosen by the\n\tuser (e.g. popping up a menu with the available options). The\n\tfinal wl_data_offer.set_actions and wl_data_offer.accept requests\n\tmust happen before the call to wl_data_offer.finish.\n      </description>\n      <arg name=\"dnd_action\" type=\"uint\" summary=\"action selected by the compositor\"\n\t   enum=\"wl_data_device_manager.dnd_action\"/>\n    </event>\n  </interface>\n\n  <interface name=\"wl_data_source\" version=\"3\">\n    <description summary=\"offer to transfer data\">\n      The wl_data_source object is the source side of a wl_data_offer.\n      It is created by the source client in a data transfer and\n      provides a way to describe the offered data and a way to respond\n      to requests to transfer the data.\n    </description>\n\n    <enum name=\"error\">\n      <entry name=\"invalid_action_mask\" value=\"0\"\n\t     summary=\"action mask contains invalid values\"/>\n      <entry name=\"invalid_source\" value=\"1\"\n\t     summary=\"source doesn't accept this request\"/>\n    </enum>\n\n    <request name=\"offer\">\n      <description summary=\"add an offered mime type\">\n\tThis request adds a mime type to the set of mime types\n\tadvertised to targets.  Can be called several times to offer\n\tmultiple types.\n      </description>\n      <arg name=\"mime_type\" type=\"string\" summary=\"mime type offered by the data source\"/>\n    </request>\n\n    <request name=\"destroy\" type=\"destructor\">\n      <description summary=\"destroy the data source\">\n\tDestroy the data source.\n      </description>\n    </request>\n\n    <event name=\"target\">\n      <description summary=\"a target accepts an offered mime type\">\n\tSent when a target accepts pointer_focus or motion events.  If\n\ta target does not accept any of the offered types, type is NULL.\n\n\tUsed for feedback during drag-and-drop.\n      </description>\n      <arg name=\"mime_type\" type=\"string\" allow-null=\"true\" summary=\"mime type accepted by the target\"/>\n    </event>\n\n    <event name=\"send\">\n      <description summary=\"send the data\">\n\tRequest for data from the client.  Send the data as the\n\tspecified mime type over the passed file descriptor, then\n\tclose it.\n      </description>\n      <arg name=\"mime_type\" type=\"string\" summary=\"mime type for the data\"/>\n      <arg name=\"fd\" type=\"fd\" summary=\"file descriptor for the data\"/>\n    </event>\n\n    <event name=\"cancelled\">\n      <description summary=\"selection was cancelled\">\n\tThis data source is no longer valid. There are several reasons why\n\tthis could happen:\n\n\t- The data source has been replaced by another data source.\n\t- The drag-and-drop operation was performed, but the drop destination\n\t  did not accept any of the mime types offered through\n\t  wl_data_source.target.\n\t- The drag-and-drop operation was performed, but the drop destination\n\t  did not select any of the actions present in the mask offered through\n\t  wl_data_source.action.\n\t- The drag-and-drop operation was performed but didn't happen over a\n\t  surface.\n\t- The compositor cancelled the drag-and-drop operation (e.g. compositor\n\t  dependent timeouts to avoid stale drag-and-drop transfers).\n\n\tThe client should clean up and destroy this data source.\n\n\tFor objects of version 2 or older, wl_data_source.cancelled will\n\tonly be emitted if the data source was replaced by another data\n\tsource.\n      </description>\n    </event>\n\n    <!-- Version 3 additions -->\n\n    <request name=\"set_actions\" since=\"3\">\n      <description summary=\"set the available drag-and-drop actions\">\n\tSets the actions that the source side client supports for this\n\toperation. This request may trigger wl_data_source.action and\n\twl_data_offer.action events if the compositor needs to change the\n\tselected action.\n\n\tThe dnd_actions argument must contain only values expressed in the\n\twl_data_device_manager.dnd_actions enum, otherwise it will result\n\tin a protocol error.\n\n\tThis request must be made once only, and can only be made on sources\n\tused in drag-and-drop, so it must be performed before\n\twl_data_device.start_drag. Attempting to use the source other than\n\tfor drag-and-drop will raise a protocol error.\n      </description>\n      <arg name=\"dnd_actions\" type=\"uint\" summary=\"actions supported by the data source\"\n\t   enum=\"wl_data_device_manager.dnd_action\"/>\n    </request>\n\n    <event name=\"dnd_drop_performed\" since=\"3\">\n      <description summary=\"the drag-and-drop operation physically finished\">\n\tThe user performed the drop action. This event does not indicate\n\tacceptance, wl_data_source.cancelled may still be emitted afterwards\n\tif the drop destination does not accept any mime type.\n\n\tHowever, this event might however not be received if the compositor\n\tcancelled the drag-and-drop operation before this event could happen.\n\n\tNote that the data_source may still be used in the future and should\n\tnot be destroyed here.\n      </description>\n    </event>\n\n    <event name=\"dnd_finished\" since=\"3\">\n      <description summary=\"the drag-and-drop operation concluded\">\n\tThe drop destination finished interoperating with this data\n\tsource, so the client is now free to destroy this data source and\n\tfree all associated data.\n\n\tIf the action used to perform the operation was \"move\", the\n\tsource can now delete the transferred data.\n      </description>\n    </event>\n\n    <event name=\"action\" since=\"3\">\n      <description summary=\"notify the selected action\">\n\tThis event indicates the action selected by the compositor after\n\tmatching the source/destination side actions. Only one action (or\n\tnone) will be offered here.\n\n\tThis event can be emitted multiple times during the drag-and-drop\n\toperation, mainly in response to destination side changes through\n\twl_data_offer.set_actions, and as the data device enters/leaves\n\tsurfaces.\n\n\tIt is only possible to receive this event after\n\twl_data_source.dnd_drop_performed if the drag-and-drop operation\n\tended in an \"ask\" action, in which case the final wl_data_source.action\n\tevent will happen immediately before wl_data_source.dnd_finished.\n\n\tCompositors may also change the selected action on the fly, mainly\n\tin response to keyboard modifier changes during the drag-and-drop\n\toperation.\n\n\tThe most recent action received is always the valid one. The chosen\n\taction may change alongside negotiation (e.g. an \"ask\" action can turn\n\tinto a \"move\" operation), so the effects of the final action must\n\talways be applied in wl_data_offer.dnd_finished.\n\n\tClients can trigger cursor surface changes from this point, so\n\tthey reflect the current action.\n      </description>\n      <arg name=\"dnd_action\" type=\"uint\" summary=\"action selected by the compositor\"\n\t   enum=\"wl_data_device_manager.dnd_action\"/>\n    </event>\n  </interface>\n\n  <interface name=\"wl_data_device\" version=\"3\">\n    <description summary=\"data transfer device\">\n      There is one wl_data_device per seat which can be obtained\n      from the global wl_data_device_manager singleton.\n\n      A wl_data_device provides access to inter-client data transfer\n      mechanisms such as copy-and-paste and drag-and-drop.\n    </description>\n\n    <enum name=\"error\">\n      <entry name=\"role\" value=\"0\" summary=\"given wl_surface has another role\"/>\n      <entry name=\"used_source\" value=\"1\" summary=\"source has already been used\"/>\n    </enum>\n\n    <request name=\"start_drag\">\n      <description summary=\"start drag-and-drop operation\">\n\tThis request asks the compositor to start a drag-and-drop\n\toperation on behalf of the client.\n\n\tThe source argument is the data source that provides the data\n\tfor the eventual data transfer. If source is NULL, enter, leave\n\tand motion events are sent only to the client that initiated the\n\tdrag and the client is expected to handle the data passing\n\tinternally. If source is destroyed, the drag-and-drop session will be\n\tcancelled.\n\n\tThe origin surface is the surface where the drag originates and\n\tthe client must have an active implicit grab that matches the\n\tserial.\n\n\tThe icon surface is an optional (can be NULL) surface that\n\tprovides an icon to be moved around with the cursor.  Initially,\n\tthe top-left corner of the icon surface is placed at the cursor\n\thotspot, but subsequent wl_surface.offset requests can move the\n\trelative position. Attach requests must be confirmed with\n\twl_surface.commit as usual. The icon surface is given the role of\n\ta drag-and-drop icon. If the icon surface already has another role,\n\tit raises a protocol error.\n\n\tThe input region is ignored for wl_surfaces with the role of a\n\tdrag-and-drop icon.\n\n\tThe given source may not be used in any further set_selection or\n\tstart_drag requests. Attempting to reuse a previously-used source\n\tmay send a used_source error.\n      </description>\n      <arg name=\"source\" type=\"object\" interface=\"wl_data_source\" allow-null=\"true\" summary=\"data source for the eventual transfer\"/>\n      <arg name=\"origin\" type=\"object\" interface=\"wl_surface\" summary=\"surface where the drag originates\"/>\n      <arg name=\"icon\" type=\"object\" interface=\"wl_surface\" allow-null=\"true\" summary=\"drag-and-drop icon surface\"/>\n      <arg name=\"serial\" type=\"uint\" summary=\"serial number of the implicit grab on the origin\"/>\n    </request>\n\n    <request name=\"set_selection\">\n      <description summary=\"copy data to the selection\">\n\tThis request asks the compositor to set the selection\n\tto the data from the source on behalf of the client.\n\n\tTo unset the selection, set the source to NULL.\n\n\tThe given source may not be used in any further set_selection or\n\tstart_drag requests. Attempting to reuse a previously-used source\n\tmay send a used_source error.\n      </description>\n      <arg name=\"source\" type=\"object\" interface=\"wl_data_source\" allow-null=\"true\" summary=\"data source for the selection\"/>\n      <arg name=\"serial\" type=\"uint\" summary=\"serial number of the event that triggered this request\"/>\n    </request>\n\n    <event name=\"data_offer\">\n      <description summary=\"introduce a new wl_data_offer\">\n\tThe data_offer event introduces a new wl_data_offer object,\n\twhich will subsequently be used in either the\n\tdata_device.enter event (for drag-and-drop) or the\n\tdata_device.selection event (for selections).  Immediately\n\tfollowing the data_device.data_offer event, the new data_offer\n\tobject will send out data_offer.offer events to describe the\n\tmime types it offers.\n      </description>\n      <arg name=\"id\" type=\"new_id\" interface=\"wl_data_offer\" summary=\"the new data_offer object\"/>\n    </event>\n\n    <event name=\"enter\">\n      <description summary=\"initiate drag-and-drop session\">\n\tThis event is sent when an active drag-and-drop pointer enters\n\ta surface owned by the client.  The position of the pointer at\n\tenter time is provided by the x and y arguments, in surface-local\n\tcoordinates.\n      </description>\n      <arg name=\"serial\" type=\"uint\" summary=\"serial number of the enter event\"/>\n      <arg name=\"surface\" type=\"object\" interface=\"wl_surface\" summary=\"client surface entered\"/>\n      <arg name=\"x\" type=\"fixed\" summary=\"surface-local x coordinate\"/>\n      <arg name=\"y\" type=\"fixed\" summary=\"surface-local y coordinate\"/>\n      <arg name=\"id\" type=\"object\" interface=\"wl_data_offer\" allow-null=\"true\"\n\t   summary=\"source data_offer object\"/>\n    </event>\n\n    <event name=\"leave\">\n      <description summary=\"end drag-and-drop session\">\n\tThis event is sent when the drag-and-drop pointer leaves the\n\tsurface and the session ends.  The client must destroy the\n\twl_data_offer introduced at enter time at this point.\n      </description>\n    </event>\n\n    <event name=\"motion\">\n      <description summary=\"drag-and-drop session motion\">\n\tThis event is sent when the drag-and-drop pointer moves within\n\tthe currently focused surface. The new position of the pointer\n\tis provided by the x and y arguments, in surface-local\n\tcoordinates.\n      </description>\n      <arg name=\"time\" type=\"uint\" summary=\"timestamp with millisecond granularity\"/>\n      <arg name=\"x\" type=\"fixed\" summary=\"surface-local x coordinate\"/>\n      <arg name=\"y\" type=\"fixed\" summary=\"surface-local y coordinate\"/>\n    </event>\n\n    <event name=\"drop\">\n      <description summary=\"end drag-and-drop session successfully\">\n\tThe event is sent when a drag-and-drop operation is ended\n\tbecause the implicit grab is removed.\n\n\tThe drag-and-drop destination is expected to honor the last action\n\treceived through wl_data_offer.action, if the resulting action is\n\t\"copy\" or \"move\", the destination can still perform\n\twl_data_offer.receive requests, and is expected to end all\n\ttransfers with a wl_data_offer.finish request.\n\n\tIf the resulting action is \"ask\", the action will not be considered\n\tfinal. The drag-and-drop destination is expected to perform one last\n\twl_data_offer.set_actions request, or wl_data_offer.destroy in order\n\tto cancel the operation.\n      </description>\n    </event>\n\n    <event name=\"selection\">\n      <description summary=\"advertise new selection\">\n\tThe selection event is sent out to notify the client of a new\n\twl_data_offer for the selection for this device.  The\n\tdata_device.data_offer and the data_offer.offer events are\n\tsent out immediately before this event to introduce the data\n\toffer object.  The selection event is sent to a client\n\timmediately before receiving keyboard focus and when a new\n\tselection is set while the client has keyboard focus.  The\n\tdata_offer is valid until a new data_offer or NULL is received\n\tor until the client loses keyboard focus.  Switching surface with\n\tkeyboard focus within the same client doesn't mean a new selection\n\twill be sent.  The client must destroy the previous selection\n\tdata_offer, if any, upon receiving this event.\n      </description>\n      <arg name=\"id\" type=\"object\" interface=\"wl_data_offer\" allow-null=\"true\"\n\t   summary=\"selection data_offer object\"/>\n    </event>\n\n    <!-- Version 2 additions -->\n\n    <request name=\"release\" type=\"destructor\" since=\"2\">\n      <description summary=\"destroy data device\">\n\tThis request destroys the data device.\n      </description>\n    </request>\n  </interface>\n\n  <interface name=\"wl_data_device_manager\" version=\"3\">\n    <description summary=\"data transfer interface\">\n      The wl_data_device_manager is a singleton global object that\n      provides access to inter-client data transfer mechanisms such as\n      copy-and-paste and drag-and-drop.  These mechanisms are tied to\n      a wl_seat and this interface lets a client get a wl_data_device\n      corresponding to a wl_seat.\n\n      Depending on the version bound, the objects created from the bound\n      wl_data_device_manager object will have different requirements for\n      functioning properly. See wl_data_source.set_actions,\n      wl_data_offer.accept and wl_data_offer.finish for details.\n    </description>\n\n    <request name=\"create_data_source\">\n      <description summary=\"create a new data source\">\n\tCreate a new data source.\n      </description>\n      <arg name=\"id\" type=\"new_id\" interface=\"wl_data_source\" summary=\"data source to create\"/>\n    </request>\n\n    <request name=\"get_data_device\">\n      <description summary=\"create a new data device\">\n\tCreate a new data device for a given seat.\n      </description>\n      <arg name=\"id\" type=\"new_id\" interface=\"wl_data_device\" summary=\"data device to create\"/>\n      <arg name=\"seat\" type=\"object\" interface=\"wl_seat\" summary=\"seat associated with the data device\"/>\n    </request>\n\n    <!-- Version 3 additions -->\n\n    <enum name=\"dnd_action\" bitfield=\"true\" since=\"3\">\n      <description summary=\"drag and drop actions\">\n\tThis is a bitmask of the available/preferred actions in a\n\tdrag-and-drop operation.\n\n\tIn the compositor, the selected action is a result of matching the\n\tactions offered by the source and destination sides.  \"action\" events\n\twith a \"none\" action will be sent to both source and destination if\n\tthere is no match. All further checks will effectively happen on\n\t(source actions ∩ destination actions).\n\n\tIn addition, compositors may also pick different actions in\n\treaction to key modifiers being pressed. One common design that\n\tis used in major toolkits (and the behavior recommended for\n\tcompositors) is:\n\n\t- If no modifiers are pressed, the first match (in bit order)\n\t  will be used.\n\t- Pressing Shift selects \"move\", if enabled in the mask.\n\t- Pressing Control selects \"copy\", if enabled in the mask.\n\n\tBehavior beyond that is considered implementation-dependent.\n\tCompositors may for example bind other modifiers (like Alt/Meta)\n\tor drags initiated with other buttons than BTN_LEFT to specific\n\tactions (e.g. \"ask\").\n      </description>\n      <entry name=\"none\" value=\"0\" summary=\"no action\"/>\n      <entry name=\"copy\" value=\"1\" summary=\"copy action\"/>\n      <entry name=\"move\" value=\"2\" summary=\"move action\"/>\n      <entry name=\"ask\" value=\"4\" summary=\"ask action\"/>\n    </enum>\n  </interface>\n\n  <interface name=\"wl_shell\" version=\"1\">\n    <description summary=\"create desktop-style surfaces\">\n      This interface is implemented by servers that provide\n      desktop-style user interfaces.\n\n      It allows clients to associate a wl_shell_surface with\n      a basic surface.\n\n      Note! This protocol is deprecated and not intended for production use.\n      For desktop-style user interfaces, use xdg_shell. Compositors and clients\n      should not implement this interface.\n    </description>\n\n    <enum name=\"error\">\n      <entry name=\"role\" value=\"0\" summary=\"given wl_surface has another role\"/>\n    </enum>\n\n    <request name=\"get_shell_surface\">\n      <description summary=\"create a shell surface from a surface\">\n\tCreate a shell surface for an existing surface. This gives\n\tthe wl_surface the role of a shell surface. If the wl_surface\n\talready has another role, it raises a protocol error.\n\n\tOnly one shell surface can be associated with a given surface.\n      </description>\n      <arg name=\"id\" type=\"new_id\" interface=\"wl_shell_surface\" summary=\"shell surface to create\"/>\n      <arg name=\"surface\" type=\"object\" interface=\"wl_surface\" summary=\"surface to be given the shell surface role\"/>\n    </request>\n  </interface>\n\n  <interface name=\"wl_shell_surface\" version=\"1\">\n    <description summary=\"desktop-style metadata interface\">\n      An interface that may be implemented by a wl_surface, for\n      implementations that provide a desktop-style user interface.\n\n      It provides requests to treat surfaces like toplevel, fullscreen\n      or popup windows, move, resize or maximize them, associate\n      metadata like title and class, etc.\n\n      On the server side the object is automatically destroyed when\n      the related wl_surface is destroyed. On the client side,\n      wl_shell_surface_destroy() must be called before destroying\n      the wl_surface object.\n    </description>\n\n    <request name=\"pong\">\n      <description summary=\"respond to a ping event\">\n\tA client must respond to a ping event with a pong request or\n\tthe client may be deemed unresponsive.\n      </description>\n      <arg name=\"serial\" type=\"uint\" summary=\"serial number of the ping event\"/>\n    </request>\n\n    <request name=\"move\">\n      <description summary=\"start an interactive move\">\n\tStart a pointer-driven move of the surface.\n\n\tThis request must be used in response to a button press event.\n\tThe server may ignore move requests depending on the state of\n\tthe surface (e.g. fullscreen or maximized).\n      </description>\n      <arg name=\"seat\" type=\"object\" interface=\"wl_seat\" summary=\"seat whose pointer is used\"/>\n      <arg name=\"serial\" type=\"uint\" summary=\"serial number of the implicit grab on the pointer\"/>\n    </request>\n\n    <enum name=\"resize\" bitfield=\"true\">\n      <description summary=\"edge values for resizing\">\n\tThese values are used to indicate which edge of a surface\n\tis being dragged in a resize operation. The server may\n\tuse this information to adapt its behavior, e.g. choose\n\tan appropriate cursor image.\n      </description>\n      <entry name=\"none\" value=\"0\" summary=\"no edge\"/>\n      <entry name=\"top\" value=\"1\" summary=\"top edge\"/>\n      <entry name=\"bottom\" value=\"2\" summary=\"bottom edge\"/>\n      <entry name=\"left\" value=\"4\" summary=\"left edge\"/>\n      <entry name=\"top_left\" value=\"5\" summary=\"top and left edges\"/>\n      <entry name=\"bottom_left\" value=\"6\" summary=\"bottom and left edges\"/>\n      <entry name=\"right\" value=\"8\" summary=\"right edge\"/>\n      <entry name=\"top_right\" value=\"9\" summary=\"top and right edges\"/>\n      <entry name=\"bottom_right\" value=\"10\" summary=\"bottom and right edges\"/>\n    </enum>\n\n    <request name=\"resize\">\n      <description summary=\"start an interactive resize\">\n\tStart a pointer-driven resizing of the surface.\n\n\tThis request must be used in response to a button press event.\n\tThe server may ignore resize requests depending on the state of\n\tthe surface (e.g. fullscreen or maximized).\n      </description>\n      <arg name=\"seat\" type=\"object\" interface=\"wl_seat\" summary=\"seat whose pointer is used\"/>\n      <arg name=\"serial\" type=\"uint\" summary=\"serial number of the implicit grab on the pointer\"/>\n      <arg name=\"edges\" type=\"uint\" enum=\"resize\" summary=\"which edge or corner is being dragged\"/>\n    </request>\n\n    <request name=\"set_toplevel\">\n      <description summary=\"make the surface a toplevel surface\">\n\tMap the surface as a toplevel surface.\n\n\tA toplevel surface is not fullscreen, maximized or transient.\n      </description>\n    </request>\n\n    <enum name=\"transient\" bitfield=\"true\">\n      <description summary=\"details of transient behaviour\">\n\tThese flags specify details of the expected behaviour\n\tof transient surfaces. Used in the set_transient request.\n      </description>\n      <entry name=\"inactive\" value=\"0x1\" summary=\"do not set keyboard focus\"/>\n    </enum>\n\n    <request name=\"set_transient\">\n      <description summary=\"make the surface a transient surface\">\n\tMap the surface relative to an existing surface.\n\n\tThe x and y arguments specify the location of the upper left\n\tcorner of the surface relative to the upper left corner of the\n\tparent surface, in surface-local coordinates.\n\n\tThe flags argument controls details of the transient behaviour.\n      </description>\n      <arg name=\"parent\" type=\"object\" interface=\"wl_surface\" summary=\"parent surface\"/>\n      <arg name=\"x\" type=\"int\" summary=\"surface-local x coordinate\"/>\n      <arg name=\"y\" type=\"int\" summary=\"surface-local y coordinate\"/>\n      <arg name=\"flags\" type=\"uint\" enum=\"transient\" summary=\"transient surface behavior\"/>\n    </request>\n\n    <enum name=\"fullscreen_method\">\n      <description summary=\"different method to set the surface fullscreen\">\n\tHints to indicate to the compositor how to deal with a conflict\n\tbetween the dimensions of the surface and the dimensions of the\n\toutput. The compositor is free to ignore this parameter.\n      </description>\n      <entry name=\"default\" value=\"0\" summary=\"no preference, apply default policy\"/>\n      <entry name=\"scale\" value=\"1\" summary=\"scale, preserve the surface's aspect ratio and center on output\"/>\n      <entry name=\"driver\" value=\"2\" summary=\"switch output mode to the smallest mode that can fit the surface, add black borders to compensate size mismatch\"/>\n      <entry name=\"fill\" value=\"3\" summary=\"no upscaling, center on output and add black borders to compensate size mismatch\"/>\n    </enum>\n\n    <request name=\"set_fullscreen\">\n      <description summary=\"make the surface a fullscreen surface\">\n\tMap the surface as a fullscreen surface.\n\n\tIf an output parameter is given then the surface will be made\n\tfullscreen on that output. If the client does not specify the\n\toutput then the compositor will apply its policy - usually\n\tchoosing the output on which the surface has the biggest surface\n\tarea.\n\n\tThe client may specify a method to resolve a size conflict\n\tbetween the output size and the surface size - this is provided\n\tthrough the method parameter.\n\n\tThe framerate parameter is used only when the method is set\n\tto \"driver\", to indicate the preferred framerate. A value of 0\n\tindicates that the client does not care about framerate.  The\n\tframerate is specified in mHz, that is framerate of 60000 is 60Hz.\n\n\tA method of \"scale\" or \"driver\" implies a scaling operation of\n\tthe surface, either via a direct scaling operation or a change of\n\tthe output mode. This will override any kind of output scaling, so\n\tthat mapping a surface with a buffer size equal to the mode can\n\tfill the screen independent of buffer_scale.\n\n\tA method of \"fill\" means we don't scale up the buffer, however\n\tany output scale is applied. This means that you may run into\n\tan edge case where the application maps a buffer with the same\n\tsize of the output mode but buffer_scale 1 (thus making a\n\tsurface larger than the output). In this case it is allowed to\n\tdownscale the results to fit the screen.\n\n\tThe compositor must reply to this request with a configure event\n\twith the dimensions for the output on which the surface will\n\tbe made fullscreen.\n      </description>\n      <arg name=\"method\" type=\"uint\" enum=\"fullscreen_method\" summary=\"method for resolving size conflict\"/>\n      <arg name=\"framerate\" type=\"uint\" summary=\"framerate in mHz\"/>\n      <arg name=\"output\" type=\"object\" interface=\"wl_output\" allow-null=\"true\"\n\t   summary=\"output on which the surface is to be fullscreen\"/>\n    </request>\n\n    <request name=\"set_popup\">\n      <description summary=\"make the surface a popup surface\">\n\tMap the surface as a popup.\n\n\tA popup surface is a transient surface with an added pointer\n\tgrab.\n\n\tAn existing implicit grab will be changed to owner-events mode,\n\tand the popup grab will continue after the implicit grab ends\n\t(i.e. releasing the mouse button does not cause the popup to\n\tbe unmapped).\n\n\tThe popup grab continues until the window is destroyed or a\n\tmouse button is pressed in any other client's window. A click\n\tin any of the client's surfaces is reported as normal, however,\n\tclicks in other clients' surfaces will be discarded and trigger\n\tthe callback.\n\n\tThe x and y arguments specify the location of the upper left\n\tcorner of the surface relative to the upper left corner of the\n\tparent surface, in surface-local coordinates.\n      </description>\n      <arg name=\"seat\" type=\"object\" interface=\"wl_seat\" summary=\"seat whose pointer is used\"/>\n      <arg name=\"serial\" type=\"uint\" summary=\"serial number of the implicit grab on the pointer\"/>\n      <arg name=\"parent\" type=\"object\" interface=\"wl_surface\" summary=\"parent surface\"/>\n      <arg name=\"x\" type=\"int\" summary=\"surface-local x coordinate\"/>\n      <arg name=\"y\" type=\"int\" summary=\"surface-local y coordinate\"/>\n      <arg name=\"flags\" type=\"uint\" enum=\"transient\" summary=\"transient surface behavior\"/>\n    </request>\n\n    <request name=\"set_maximized\">\n      <description summary=\"make the surface a maximized surface\">\n\tMap the surface as a maximized surface.\n\n\tIf an output parameter is given then the surface will be\n\tmaximized on that output. If the client does not specify the\n\toutput then the compositor will apply its policy - usually\n\tchoosing the output on which the surface has the biggest surface\n\tarea.\n\n\tThe compositor will reply with a configure event telling\n\tthe expected new surface size. The operation is completed\n\ton the next buffer attach to this surface.\n\n\tA maximized surface typically fills the entire output it is\n\tbound to, except for desktop elements such as panels. This is\n\tthe main difference between a maximized shell surface and a\n\tfullscreen shell surface.\n\n\tThe details depend on the compositor implementation.\n      </description>\n      <arg name=\"output\" type=\"object\" interface=\"wl_output\" allow-null=\"true\"\n\t   summary=\"output on which the surface is to be maximized\"/>\n    </request>\n\n    <request name=\"set_title\">\n      <description summary=\"set surface title\">\n\tSet a short title for the surface.\n\n\tThis string may be used to identify the surface in a task bar,\n\twindow list, or other user interface elements provided by the\n\tcompositor.\n\n\tThe string must be encoded in UTF-8.\n      </description>\n      <arg name=\"title\" type=\"string\" summary=\"surface title\"/>\n    </request>\n\n    <request name=\"set_class\">\n      <description summary=\"set surface class\">\n\tSet a class for the surface.\n\n\tThe surface class identifies the general class of applications\n\tto which the surface belongs. A common convention is to use the\n\tfile name (or the full path if it is a non-standard location) of\n\tthe application's .desktop file as the class.\n      </description>\n      <arg name=\"class_\" type=\"string\" summary=\"surface class\"/>\n    </request>\n\n    <event name=\"ping\">\n      <description summary=\"ping client\">\n\tPing a client to check if it is receiving events and sending\n\trequests. A client is expected to reply with a pong request.\n      </description>\n      <arg name=\"serial\" type=\"uint\" summary=\"serial number of the ping\"/>\n    </event>\n\n    <event name=\"configure\">\n      <description summary=\"suggest resize\">\n\tThe configure event asks the client to resize its surface.\n\n\tThe size is a hint, in the sense that the client is free to\n\tignore it if it doesn't resize, pick a smaller size (to\n\tsatisfy aspect ratio or resize in steps of NxM pixels).\n\n\tThe edges parameter provides a hint about how the surface\n\twas resized. The client may use this information to decide\n\thow to adjust its content to the new size (e.g. a scrolling\n\tarea might adjust its content position to leave the viewable\n\tcontent unmoved).\n\n\tThe client is free to dismiss all but the last configure\n\tevent it received.\n\n\tThe width and height arguments specify the size of the window\n\tin surface-local coordinates.\n      </description>\n      <arg name=\"edges\" type=\"uint\" enum=\"resize\" summary=\"how the surface was resized\"/>\n      <arg name=\"width\" type=\"int\" summary=\"new width of the surface\"/>\n      <arg name=\"height\" type=\"int\" summary=\"new height of the surface\"/>\n    </event>\n\n    <event name=\"popup_done\">\n      <description summary=\"popup interaction is done\">\n\tThe popup_done event is sent out when a popup grab is broken,\n\tthat is, when the user clicks a surface that doesn't belong\n\tto the client owning the popup surface.\n      </description>\n    </event>\n  </interface>\n\n  <interface name=\"wl_surface\" version=\"6\">\n    <description summary=\"an onscreen surface\">\n      A surface is a rectangular area that may be displayed on zero\n      or more outputs, and shown any number of times at the compositor's\n      discretion. They can present wl_buffers, receive user input, and\n      define a local coordinate system.\n\n      The size of a surface (and relative positions on it) is described\n      in surface-local coordinates, which may differ from the buffer\n      coordinates of the pixel content, in case a buffer_transform\n      or a buffer_scale is used.\n\n      A surface without a \"role\" is fairly useless: a compositor does\n      not know where, when or how to present it. The role is the\n      purpose of a wl_surface. Examples of roles are a cursor for a\n      pointer (as set by wl_pointer.set_cursor), a drag icon\n      (wl_data_device.start_drag), a sub-surface\n      (wl_subcompositor.get_subsurface), and a window as defined by a\n      shell protocol (e.g. wl_shell.get_shell_surface).\n\n      A surface can have only one role at a time. Initially a\n      wl_surface does not have a role. Once a wl_surface is given a\n      role, it is set permanently for the whole lifetime of the\n      wl_surface object. Giving the current role again is allowed,\n      unless explicitly forbidden by the relevant interface\n      specification.\n\n      Surface roles are given by requests in other interfaces such as\n      wl_pointer.set_cursor. The request should explicitly mention\n      that this request gives a role to a wl_surface. Often, this\n      request also creates a new protocol object that represents the\n      role and adds additional functionality to wl_surface. When a\n      client wants to destroy a wl_surface, they must destroy this role\n      object before the wl_surface, otherwise a defunct_role_object error is\n      sent.\n\n      Destroying the role object does not remove the role from the\n      wl_surface, but it may stop the wl_surface from \"playing the role\".\n      For instance, if a wl_subsurface object is destroyed, the wl_surface\n      it was created for will be unmapped and forget its position and\n      z-order. It is allowed to create a wl_subsurface for the same\n      wl_surface again, but it is not allowed to use the wl_surface as\n      a cursor (cursor is a different role than sub-surface, and role\n      switching is not allowed).\n    </description>\n\n    <enum name=\"error\">\n      <description summary=\"wl_surface error values\">\n\tThese errors can be emitted in response to wl_surface requests.\n      </description>\n      <entry name=\"invalid_scale\" value=\"0\" summary=\"buffer scale value is invalid\"/>\n      <entry name=\"invalid_transform\" value=\"1\" summary=\"buffer transform value is invalid\"/>\n      <entry name=\"invalid_size\" value=\"2\" summary=\"buffer size is invalid\"/>\n      <entry name=\"invalid_offset\" value=\"3\" summary=\"buffer offset is invalid\"/>\n      <entry name=\"defunct_role_object\" value=\"4\"\n\t     summary=\"surface was destroyed before its role object\"/>\n    </enum>\n\n    <request name=\"destroy\" type=\"destructor\">\n      <description summary=\"delete surface\">\n\tDeletes the surface and invalidates its object ID.\n      </description>\n    </request>\n\n    <request name=\"attach\">\n      <description summary=\"set the surface contents\">\n\tSet a buffer as the content of this surface.\n\n\tThe new size of the surface is calculated based on the buffer\n\tsize transformed by the inverse buffer_transform and the\n\tinverse buffer_scale. This means that at commit time the supplied\n\tbuffer size must be an integer multiple of the buffer_scale. If\n\tthat's not the case, an invalid_size error is sent.\n\n\tThe x and y arguments specify the location of the new pending\n\tbuffer's upper left corner, relative to the current buffer's upper\n\tleft corner, in surface-local coordinates. In other words, the\n\tx and y, combined with the new surface size define in which\n\tdirections the surface's size changes. Setting anything other than 0\n\tas x and y arguments is discouraged, and should instead be replaced\n\twith using the separate wl_surface.offset request.\n\n\tWhen the bound wl_surface version is 5 or higher, passing any\n\tnon-zero x or y is a protocol violation, and will result in an\n\t'invalid_offset' error being raised. The x and y arguments are ignored\n\tand do not change the pending state. To achieve equivalent semantics,\n\tuse wl_surface.offset.\n\n\tSurface contents are double-buffered state, see wl_surface.commit.\n\n\tThe initial surface contents are void; there is no content.\n\twl_surface.attach assigns the given wl_buffer as the pending\n\twl_buffer. wl_surface.commit makes the pending wl_buffer the new\n\tsurface contents, and the size of the surface becomes the size\n\tcalculated from the wl_buffer, as described above. After commit,\n\tthere is no pending buffer until the next attach.\n\n\tCommitting a pending wl_buffer allows the compositor to read the\n\tpixels in the wl_buffer. The compositor may access the pixels at\n\tany time after the wl_surface.commit request. When the compositor\n\twill not access the pixels anymore, it will send the\n\twl_buffer.release event. Only after receiving wl_buffer.release,\n\tthe client may reuse the wl_buffer. A wl_buffer that has been\n\tattached and then replaced by another attach instead of committed\n\twill not receive a release event, and is not used by the\n\tcompositor.\n\n\tIf a pending wl_buffer has been committed to more than one wl_surface,\n\tthe delivery of wl_buffer.release events becomes undefined. A well\n\tbehaved client should not rely on wl_buffer.release events in this\n\tcase. Alternatively, a client could create multiple wl_buffer objects\n\tfrom the same backing storage or use wp_linux_buffer_release.\n\n\tDestroying the wl_buffer after wl_buffer.release does not change\n\tthe surface contents. Destroying the wl_buffer before wl_buffer.release\n\tis allowed as long as the underlying buffer storage isn't re-used (this\n\tcan happen e.g. on client process termination). However, if the client\n\tdestroys the wl_buffer before receiving the wl_buffer.release event and\n\tmutates the underlying buffer storage, the surface contents become\n\tundefined immediately.\n\n\tIf wl_surface.attach is sent with a NULL wl_buffer, the\n\tfollowing wl_surface.commit will remove the surface content.\n\n\tIf a pending wl_buffer has been destroyed, the result is not specified.\n\tMany compositors are known to remove the surface content on the following\n\twl_surface.commit, but this behaviour is not universal. Clients seeking to\n\tmaximise compatibility should not destroy pending buffers and should\n\tensure that they explicitly remove content from surfaces, even after\n\tdestroying buffers.\n      </description>\n      <arg name=\"buffer\" type=\"object\" interface=\"wl_buffer\" allow-null=\"true\"\n\t   summary=\"buffer of surface contents\"/>\n      <arg name=\"x\" type=\"int\" summary=\"surface-local x coordinate\"/>\n      <arg name=\"y\" type=\"int\" summary=\"surface-local y coordinate\"/>\n    </request>\n\n    <request name=\"damage\">\n      <description summary=\"mark part of the surface damaged\">\n\tThis request is used to describe the regions where the pending\n\tbuffer is different from the current surface contents, and where\n\tthe surface therefore needs to be repainted. The compositor\n\tignores the parts of the damage that fall outside of the surface.\n\n\tDamage is double-buffered state, see wl_surface.commit.\n\n\tThe damage rectangle is specified in surface-local coordinates,\n\twhere x and y specify the upper left corner of the damage rectangle.\n\n\tThe initial value for pending damage is empty: no damage.\n\twl_surface.damage adds pending damage: the new pending damage\n\tis the union of old pending damage and the given rectangle.\n\n\twl_surface.commit assigns pending damage as the current damage,\n\tand clears pending damage. The server will clear the current\n\tdamage as it repaints the surface.\n\n\tNote! New clients should not use this request. Instead damage can be\n\tposted with wl_surface.damage_buffer which uses buffer coordinates\n\tinstead of surface coordinates.\n      </description>\n      <arg name=\"x\" type=\"int\" summary=\"surface-local x coordinate\"/>\n      <arg name=\"y\" type=\"int\" summary=\"surface-local y coordinate\"/>\n      <arg name=\"width\" type=\"int\" summary=\"width of damage rectangle\"/>\n      <arg name=\"height\" type=\"int\" summary=\"height of damage rectangle\"/>\n    </request>\n\n    <request name=\"frame\">\n      <description summary=\"request a frame throttling hint\">\n\tRequest a notification when it is a good time to start drawing a new\n\tframe, by creating a frame callback. This is useful for throttling\n\tredrawing operations, and driving animations.\n\n\tWhen a client is animating on a wl_surface, it can use the 'frame'\n\trequest to get notified when it is a good time to draw and commit the\n\tnext frame of animation. If the client commits an update earlier than\n\tthat, it is likely that some updates will not make it to the display,\n\tand the client is wasting resources by drawing too often.\n\n\tThe frame request will take effect on the next wl_surface.commit.\n\tThe notification will only be posted for one frame unless\n\trequested again. For a wl_surface, the notifications are posted in\n\tthe order the frame requests were committed.\n\n\tThe server must send the notifications so that a client\n\twill not send excessive updates, while still allowing\n\tthe highest possible update rate for clients that wait for the reply\n\tbefore drawing again. The server should give some time for the client\n\tto draw and commit after sending the frame callback events to let it\n\thit the next output refresh.\n\n\tA server should avoid signaling the frame callbacks if the\n\tsurface is not visible in any way, e.g. the surface is off-screen,\n\tor completely obscured by other opaque surfaces.\n\n\tThe object returned by this request will be destroyed by the\n\tcompositor after the callback is fired and as such the client must not\n\tattempt to use it after that point.\n\n\tThe callback_data passed in the callback is the current time, in\n\tmilliseconds, with an undefined base.\n      </description>\n      <arg name=\"callback\" type=\"new_id\" interface=\"wl_callback\" summary=\"callback object for the frame request\"/>\n    </request>\n\n    <request name=\"set_opaque_region\">\n      <description summary=\"set opaque region\">\n\tThis request sets the region of the surface that contains\n\topaque content.\n\n\tThe opaque region is an optimization hint for the compositor\n\tthat lets it optimize the redrawing of content behind opaque\n\tregions.  Setting an opaque region is not required for correct\n\tbehaviour, but marking transparent content as opaque will result\n\tin repaint artifacts.\n\n\tThe opaque region is specified in surface-local coordinates.\n\n\tThe compositor ignores the parts of the opaque region that fall\n\toutside of the surface.\n\n\tOpaque region is double-buffered state, see wl_surface.commit.\n\n\twl_surface.set_opaque_region changes the pending opaque region.\n\twl_surface.commit copies the pending region to the current region.\n\tOtherwise, the pending and current regions are never changed.\n\n\tThe initial value for an opaque region is empty. Setting the pending\n\topaque region has copy semantics, and the wl_region object can be\n\tdestroyed immediately. A NULL wl_region causes the pending opaque\n\tregion to be set to empty.\n      </description>\n      <arg name=\"region\" type=\"object\" interface=\"wl_region\" allow-null=\"true\"\n\t   summary=\"opaque region of the surface\"/>\n    </request>\n\n    <request name=\"set_input_region\">\n      <description summary=\"set input region\">\n\tThis request sets the region of the surface that can receive\n\tpointer and touch events.\n\n\tInput events happening outside of this region will try the next\n\tsurface in the server surface stack. The compositor ignores the\n\tparts of the input region that fall outside of the surface.\n\n\tThe input region is specified in surface-local coordinates.\n\n\tInput region is double-buffered state, see wl_surface.commit.\n\n\twl_surface.set_input_region changes the pending input region.\n\twl_surface.commit copies the pending region to the current region.\n\tOtherwise the pending and current regions are never changed,\n\texcept cursor and icon surfaces are special cases, see\n\twl_pointer.set_cursor and wl_data_device.start_drag.\n\n\tThe initial value for an input region is infinite. That means the\n\twhole surface will accept input. Setting the pending input region\n\thas copy semantics, and the wl_region object can be destroyed\n\timmediately. A NULL wl_region causes the input region to be set\n\tto infinite.\n      </description>\n      <arg name=\"region\" type=\"object\" interface=\"wl_region\" allow-null=\"true\"\n\t   summary=\"input region of the surface\"/>\n    </request>\n\n    <request name=\"commit\">\n      <description summary=\"commit pending surface state\">\n\tSurface state (input, opaque, and damage regions, attached buffers,\n\tetc.) is double-buffered. Protocol requests modify the pending state,\n\tas opposed to the active state in use by the compositor.\n\n\tA commit request atomically creates a content update from the pending\n\tstate, even if the pending state has not been touched. The content\n\tupdate is placed in a queue until it becomes active. After commit, the\n\tnew pending state is as documented for each related request.\n\n\tWhen the content update is applied, the wl_buffer is applied before all\n\tother state. This means that all coordinates in double-buffered state\n\tare relative to the newly attached wl_buffers, except for\n\twl_surface.attach itself. If there is no newly attached wl_buffer, the\n\tcoordinates are relative to the previous content update.\n\n\tAll requests that need a commit to become effective are documented\n\tto affect double-buffered state.\n\n\tOther interfaces may add further double-buffered surface state.\n      </description>\n    </request>\n\n    <event name=\"enter\">\n      <description summary=\"surface enters an output\">\n\tThis is emitted whenever a surface's creation, movement, or resizing\n\tresults in some part of it being within the scanout region of an\n\toutput.\n\n\tNote that a surface may be overlapping with zero or more outputs.\n      </description>\n      <arg name=\"output\" type=\"object\" interface=\"wl_output\" summary=\"output entered by the surface\"/>\n    </event>\n\n    <event name=\"leave\">\n      <description summary=\"surface leaves an output\">\n\tThis is emitted whenever a surface's creation, movement, or resizing\n\tresults in it no longer having any part of it within the scanout region\n\tof an output.\n\n\tClients should not use the number of outputs the surface is on for frame\n\tthrottling purposes. The surface might be hidden even if no leave event\n\thas been sent, and the compositor might expect new surface content\n\tupdates even if no enter event has been sent. The frame event should be\n\tused instead.\n      </description>\n      <arg name=\"output\" type=\"object\" interface=\"wl_output\" summary=\"output left by the surface\"/>\n    </event>\n\n    <!-- Version 2 additions -->\n\n    <request name=\"set_buffer_transform\" since=\"2\">\n      <description summary=\"sets the buffer transformation\">\n\tThis request sets the transformation that the client has already applied\n\tto the content of the buffer. The accepted values for the transform\n\tparameter are the values for wl_output.transform.\n\n\tThe compositor applies the inverse of this transformation whenever it\n\tuses the buffer contents.\n\n\tBuffer transform is double-buffered state, see wl_surface.commit.\n\n\tA newly created surface has its buffer transformation set to normal.\n\n\twl_surface.set_buffer_transform changes the pending buffer\n\ttransformation. wl_surface.commit copies the pending buffer\n\ttransformation to the current one. Otherwise, the pending and current\n\tvalues are never changed.\n\n\tThe purpose of this request is to allow clients to render content\n\taccording to the output transform, thus permitting the compositor to\n\tuse certain optimizations even if the display is rotated. Using\n\thardware overlays and scanning out a client buffer for fullscreen\n\tsurfaces are examples of such optimizations. Those optimizations are\n\thighly dependent on the compositor implementation, so the use of this\n\trequest should be considered on a case-by-case basis.\n\n\tNote that if the transform value includes 90 or 270 degree rotation,\n\tthe width of the buffer will become the surface height and the height\n\tof the buffer will become the surface width.\n\n\tIf transform is not one of the values from the\n\twl_output.transform enum the invalid_transform protocol error\n\tis raised.\n      </description>\n      <arg name=\"transform\" type=\"int\" enum=\"wl_output.transform\"\n\t   summary=\"transform for interpreting buffer contents\"/>\n    </request>\n\n    <!-- Version 3 additions -->\n\n    <request name=\"set_buffer_scale\" since=\"3\">\n      <description summary=\"sets the buffer scaling factor\">\n\tThis request sets an optional scaling factor on how the compositor\n\tinterprets the contents of the buffer attached to the window.\n\n\tBuffer scale is double-buffered state, see wl_surface.commit.\n\n\tA newly created surface has its buffer scale set to 1.\n\n\twl_surface.set_buffer_scale changes the pending buffer scale.\n\twl_surface.commit copies the pending buffer scale to the current one.\n\tOtherwise, the pending and current values are never changed.\n\n\tThe purpose of this request is to allow clients to supply higher\n\tresolution buffer data for use on high resolution outputs. It is\n\tintended that you pick the same buffer scale as the scale of the\n\toutput that the surface is displayed on. This means the compositor\n\tcan avoid scaling when rendering the surface on that output.\n\n\tNote that if the scale is larger than 1, then you have to attach\n\ta buffer that is larger (by a factor of scale in each dimension)\n\tthan the desired surface size.\n\n\tIf scale is not greater than 0 the invalid_scale protocol error is\n\traised.\n      </description>\n      <arg name=\"scale\" type=\"int\"\n\t   summary=\"scale for interpreting buffer contents\"/>\n    </request>\n\n    <!-- Version 4 additions -->\n    <request name=\"damage_buffer\" since=\"4\">\n      <description summary=\"mark part of the surface damaged using buffer coordinates\">\n\tThis request is used to describe the regions where the pending\n\tbuffer is different from the current surface contents, and where\n\tthe surface therefore needs to be repainted. The compositor\n\tignores the parts of the damage that fall outside of the surface.\n\n\tDamage is double-buffered state, see wl_surface.commit.\n\n\tThe damage rectangle is specified in buffer coordinates,\n\twhere x and y specify the upper left corner of the damage rectangle.\n\n\tThe initial value for pending damage is empty: no damage.\n\twl_surface.damage_buffer adds pending damage: the new pending\n\tdamage is the union of old pending damage and the given rectangle.\n\n\twl_surface.commit assigns pending damage as the current damage,\n\tand clears pending damage. The server will clear the current\n\tdamage as it repaints the surface.\n\n\tThis request differs from wl_surface.damage in only one way - it\n\ttakes damage in buffer coordinates instead of surface-local\n\tcoordinates. While this generally is more intuitive than surface\n\tcoordinates, it is especially desirable when using wp_viewport\n\tor when a drawing library (like EGL) is unaware of buffer scale\n\tand buffer transform.\n\n\tNote: Because buffer transformation changes and damage requests may\n\tbe interleaved in the protocol stream, it is impossible to determine\n\tthe actual mapping between surface and buffer damage until\n\twl_surface.commit time. Therefore, compositors wishing to take both\n\tkinds of damage into account will have to accumulate damage from the\n\ttwo requests separately and only transform from one to the other\n\tafter receiving the wl_surface.commit.\n      </description>\n      <arg name=\"x\" type=\"int\" summary=\"buffer-local x coordinate\"/>\n      <arg name=\"y\" type=\"int\" summary=\"buffer-local y coordinate\"/>\n      <arg name=\"width\" type=\"int\" summary=\"width of damage rectangle\"/>\n      <arg name=\"height\" type=\"int\" summary=\"height of damage rectangle\"/>\n    </request>\n\n    <!-- Version 5 additions -->\n\n    <request name=\"offset\" since=\"5\">\n      <description summary=\"set the surface contents offset\">\n\tThe x and y arguments specify the location of the new pending\n\tbuffer's upper left corner, relative to the current buffer's upper\n\tleft corner, in surface-local coordinates. In other words, the\n\tx and y, combined with the new surface size define in which\n\tdirections the surface's size changes.\n\n\tSurface location offset is double-buffered state, see\n\twl_surface.commit.\n\n\tThis request is semantically equivalent to and the replaces the x and y\n\targuments in the wl_surface.attach request in wl_surface versions prior\n\tto 5. See wl_surface.attach for details.\n      </description>\n      <arg name=\"x\" type=\"int\" summary=\"surface-local x coordinate\"/>\n      <arg name=\"y\" type=\"int\" summary=\"surface-local y coordinate\"/>\n    </request>\n\n    <!-- Version 6 additions -->\n\n    <event name=\"preferred_buffer_scale\" since=\"6\">\n      <description summary=\"preferred buffer scale for the surface\">\n\tThis event indicates the preferred buffer scale for this surface. It is\n\tsent whenever the compositor's preference changes.\n\n\tBefore receiving this event the preferred buffer scale for this surface\n\tis 1.\n\n\tIt is intended that scaling aware clients use this event to scale their\n\tcontent and use wl_surface.set_buffer_scale to indicate the scale they\n\thave rendered with. This allows clients to supply a higher detail\n\tbuffer.\n\n\tThe compositor shall emit a scale value greater than 0.\n      </description>\n      <arg name=\"factor\" type=\"int\" summary=\"preferred scaling factor\"/>\n    </event>\n\n    <event name=\"preferred_buffer_transform\" since=\"6\">\n      <description summary=\"preferred buffer transform for the surface\">\n\tThis event indicates the preferred buffer transform for this surface.\n\tIt is sent whenever the compositor's preference changes.\n\n\tBefore receiving this event the preferred buffer transform for this\n\tsurface is normal.\n\n\tApplying this transformation to the surface buffer contents and using\n\twl_surface.set_buffer_transform might allow the compositor to use the\n\tsurface buffer more efficiently.\n      </description>\n      <arg name=\"transform\" type=\"uint\" enum=\"wl_output.transform\"\n\t   summary=\"preferred transform\"/>\n    </event>\n   </interface>\n\n  <interface name=\"wl_seat\" version=\"9\">\n    <description summary=\"group of input devices\">\n      A seat is a group of keyboards, pointer and touch devices. This\n      object is published as a global during start up, or when such a\n      device is hot plugged.  A seat typically has a pointer and\n      maintains a keyboard focus and a pointer focus.\n    </description>\n\n    <enum name=\"capability\" bitfield=\"true\">\n      <description summary=\"seat capability bitmask\">\n\tThis is a bitmask of capabilities this seat has; if a member is\n\tset, then it is present on the seat.\n      </description>\n      <entry name=\"pointer\" value=\"1\" summary=\"the seat has pointer devices\"/>\n      <entry name=\"keyboard\" value=\"2\" summary=\"the seat has one or more keyboards\"/>\n      <entry name=\"touch\" value=\"4\" summary=\"the seat has touch devices\"/>\n    </enum>\n\n    <enum name=\"error\">\n      <description summary=\"wl_seat error values\">\n\tThese errors can be emitted in response to wl_seat requests.\n      </description>\n      <entry name=\"missing_capability\" value=\"0\"\n\t     summary=\"get_pointer, get_keyboard or get_touch called on seat without the matching capability\"/>\n    </enum>\n\n    <event name=\"capabilities\">\n      <description summary=\"seat capabilities changed\">\n\tThis is emitted whenever a seat gains or loses the pointer,\n\tkeyboard or touch capabilities.  The argument is a capability\n\tenum containing the complete set of capabilities this seat has.\n\n\tWhen the pointer capability is added, a client may create a\n\twl_pointer object using the wl_seat.get_pointer request. This object\n\twill receive pointer events until the capability is removed in the\n\tfuture.\n\n\tWhen the pointer capability is removed, a client should destroy the\n\twl_pointer objects associated with the seat where the capability was\n\tremoved, using the wl_pointer.release request. No further pointer\n\tevents will be received on these objects.\n\n\tIn some compositors, if a seat regains the pointer capability and a\n\tclient has a previously obtained wl_pointer object of version 4 or\n\tless, that object may start sending pointer events again. This\n\tbehavior is considered a misinterpretation of the intended behavior\n\tand must not be relied upon by the client. wl_pointer objects of\n\tversion 5 or later must not send events if created before the most\n\trecent event notifying the client of an added pointer capability.\n\n\tThe above behavior also applies to wl_keyboard and wl_touch with the\n\tkeyboard and touch capabilities, respectively.\n      </description>\n      <arg name=\"capabilities\" type=\"uint\" enum=\"capability\" summary=\"capabilities of the seat\"/>\n    </event>\n\n    <request name=\"get_pointer\">\n      <description summary=\"return pointer object\">\n\tThe ID provided will be initialized to the wl_pointer interface\n\tfor this seat.\n\n\tThis request only takes effect if the seat has the pointer\n\tcapability, or has had the pointer capability in the past.\n\tIt is a protocol violation to issue this request on a seat that has\n\tnever had the pointer capability. The missing_capability error will\n\tbe sent in this case.\n      </description>\n      <arg name=\"id\" type=\"new_id\" interface=\"wl_pointer\" summary=\"seat pointer\"/>\n    </request>\n\n    <request name=\"get_keyboard\">\n      <description summary=\"return keyboard object\">\n\tThe ID provided will be initialized to the wl_keyboard interface\n\tfor this seat.\n\n\tThis request only takes effect if the seat has the keyboard\n\tcapability, or has had the keyboard capability in the past.\n\tIt is a protocol violation to issue this request on a seat that has\n\tnever had the keyboard capability. The missing_capability error will\n\tbe sent in this case.\n      </description>\n      <arg name=\"id\" type=\"new_id\" interface=\"wl_keyboard\" summary=\"seat keyboard\"/>\n    </request>\n\n    <request name=\"get_touch\">\n      <description summary=\"return touch object\">\n\tThe ID provided will be initialized to the wl_touch interface\n\tfor this seat.\n\n\tThis request only takes effect if the seat has the touch\n\tcapability, or has had the touch capability in the past.\n\tIt is a protocol violation to issue this request on a seat that has\n\tnever had the touch capability. The missing_capability error will\n\tbe sent in this case.\n      </description>\n      <arg name=\"id\" type=\"new_id\" interface=\"wl_touch\" summary=\"seat touch interface\"/>\n    </request>\n\n    <!-- Version 2 additions -->\n\n    <event name=\"name\" since=\"2\">\n      <description summary=\"unique identifier for this seat\">\n\tIn a multi-seat configuration the seat name can be used by clients to\n\thelp identify which physical devices the seat represents.\n\n\tThe seat name is a UTF-8 string with no convention defined for its\n\tcontents. Each name is unique among all wl_seat globals. The name is\n\tonly guaranteed to be unique for the current compositor instance.\n\n\tThe same seat names are used for all clients. Thus, the name can be\n\tshared across processes to refer to a specific wl_seat global.\n\n\tThe name event is sent after binding to the seat global. This event is\n\tonly sent once per seat object, and the name does not change over the\n\tlifetime of the wl_seat global.\n\n\tCompositors may re-use the same seat name if the wl_seat global is\n\tdestroyed and re-created later.\n      </description>\n      <arg name=\"name\" type=\"string\" summary=\"seat identifier\"/>\n    </event>\n\n    <!-- Version 5 additions -->\n\n    <request name=\"release\" type=\"destructor\" since=\"5\">\n      <description summary=\"release the seat object\">\n\tUsing this request a client can tell the server that it is not going to\n\tuse the seat object anymore.\n      </description>\n    </request>\n\n  </interface>\n\n  <interface name=\"wl_pointer\" version=\"9\">\n    <description summary=\"pointer input device\">\n      The wl_pointer interface represents one or more input devices,\n      such as mice, which control the pointer location and pointer_focus\n      of a seat.\n\n      The wl_pointer interface generates motion, enter and leave\n      events for the surfaces that the pointer is located over,\n      and button and axis events for button presses, button releases\n      and scrolling.\n    </description>\n\n    <enum name=\"error\">\n      <entry name=\"role\" value=\"0\" summary=\"given wl_surface has another role\"/>\n    </enum>\n\n    <request name=\"set_cursor\">\n      <description summary=\"set the pointer surface\">\n\tSet the pointer surface, i.e., the surface that contains the\n\tpointer image (cursor). This request gives the surface the role\n\tof a cursor. If the surface already has another role, it raises\n\ta protocol error.\n\n\tThe cursor actually changes only if the pointer\n\tfocus for this device is one of the requesting client's surfaces\n\tor the surface parameter is the current pointer surface. If\n\tthere was a previous surface set with this request it is\n\treplaced. If surface is NULL, the pointer image is hidden.\n\n\tThe parameters hotspot_x and hotspot_y define the position of\n\tthe pointer surface relative to the pointer location. Its\n\ttop-left corner is always at (x, y) - (hotspot_x, hotspot_y),\n\twhere (x, y) are the coordinates of the pointer location, in\n\tsurface-local coordinates.\n\n\tOn wl_surface.offset requests to the pointer surface, hotspot_x\n\tand hotspot_y are decremented by the x and y parameters\n\tpassed to the request. The offset must be applied by\n\twl_surface.commit as usual.\n\n\tThe hotspot can also be updated by passing the currently set\n\tpointer surface to this request with new values for hotspot_x\n\tand hotspot_y.\n\n\tThe input region is ignored for wl_surfaces with the role of\n\ta cursor. When the use as a cursor ends, the wl_surface is\n\tunmapped.\n\n\tThe serial parameter must match the latest wl_pointer.enter\n\tserial number sent to the client. Otherwise the request will be\n\tignored.\n      </description>\n      <arg name=\"serial\" type=\"uint\" summary=\"serial number of the enter event\"/>\n      <arg name=\"surface\" type=\"object\" interface=\"wl_surface\" allow-null=\"true\"\n\t   summary=\"pointer surface\"/>\n      <arg name=\"hotspot_x\" type=\"int\" summary=\"surface-local x coordinate\"/>\n      <arg name=\"hotspot_y\" type=\"int\" summary=\"surface-local y coordinate\"/>\n    </request>\n\n    <event name=\"enter\">\n      <description summary=\"enter event\">\n\tNotification that this seat's pointer is focused on a certain\n\tsurface.\n\n\tWhen a seat's focus enters a surface, the pointer image\n\tis undefined and a client should respond to this event by setting\n\tan appropriate pointer image with the set_cursor request.\n      </description>\n      <arg name=\"serial\" type=\"uint\" summary=\"serial number of the enter event\"/>\n      <arg name=\"surface\" type=\"object\" interface=\"wl_surface\" summary=\"surface entered by the pointer\"/>\n      <arg name=\"surface_x\" type=\"fixed\" summary=\"surface-local x coordinate\"/>\n      <arg name=\"surface_y\" type=\"fixed\" summary=\"surface-local y coordinate\"/>\n    </event>\n\n    <event name=\"leave\">\n      <description summary=\"leave event\">\n\tNotification that this seat's pointer is no longer focused on\n\ta certain surface.\n\n\tThe leave notification is sent before the enter notification\n\tfor the new focus.\n      </description>\n      <arg name=\"serial\" type=\"uint\" summary=\"serial number of the leave event\"/>\n      <arg name=\"surface\" type=\"object\" interface=\"wl_surface\" summary=\"surface left by the pointer\"/>\n    </event>\n\n    <event name=\"motion\">\n      <description summary=\"pointer motion event\">\n\tNotification of pointer location change. The arguments\n\tsurface_x and surface_y are the location relative to the\n\tfocused surface.\n      </description>\n      <arg name=\"time\" type=\"uint\" summary=\"timestamp with millisecond granularity\"/>\n      <arg name=\"surface_x\" type=\"fixed\" summary=\"surface-local x coordinate\"/>\n      <arg name=\"surface_y\" type=\"fixed\" summary=\"surface-local y coordinate\"/>\n    </event>\n\n    <enum name=\"button_state\">\n      <description summary=\"physical button state\">\n\tDescribes the physical state of a button that produced the button\n\tevent.\n      </description>\n      <entry name=\"released\" value=\"0\" summary=\"the button is not pressed\"/>\n      <entry name=\"pressed\" value=\"1\" summary=\"the button is pressed\"/>\n    </enum>\n\n    <event name=\"button\">\n      <description summary=\"pointer button event\">\n\tMouse button click and release notifications.\n\n\tThe location of the click is given by the last motion or\n\tenter event.\n\tThe time argument is a timestamp with millisecond\n\tgranularity, with an undefined base.\n\n\tThe button is a button code as defined in the Linux kernel's\n\tlinux/input-event-codes.h header file, e.g. BTN_LEFT.\n\n\tAny 16-bit button code value is reserved for future additions to the\n\tkernel's event code list. All other button codes above 0xFFFF are\n\tcurrently undefined but may be used in future versions of this\n\tprotocol.\n      </description>\n      <arg name=\"serial\" type=\"uint\" summary=\"serial number of the button event\"/>\n      <arg name=\"time\" type=\"uint\" summary=\"timestamp with millisecond granularity\"/>\n      <arg name=\"button\" type=\"uint\" summary=\"button that produced the event\"/>\n      <arg name=\"state\" type=\"uint\" enum=\"button_state\" summary=\"physical state of the button\"/>\n    </event>\n\n    <enum name=\"axis\">\n      <description summary=\"axis types\">\n\tDescribes the axis types of scroll events.\n      </description>\n      <entry name=\"vertical_scroll\" value=\"0\" summary=\"vertical axis\"/>\n      <entry name=\"horizontal_scroll\" value=\"1\" summary=\"horizontal axis\"/>\n    </enum>\n\n    <event name=\"axis\">\n      <description summary=\"axis event\">\n\tScroll and other axis notifications.\n\n\tFor scroll events (vertical and horizontal scroll axes), the\n\tvalue parameter is the length of a vector along the specified\n\taxis in a coordinate space identical to those of motion events,\n\trepresenting a relative movement along the specified axis.\n\n\tFor devices that support movements non-parallel to axes multiple\n\taxis events will be emitted.\n\n\tWhen applicable, for example for touch pads, the server can\n\tchoose to emit scroll events where the motion vector is\n\tequivalent to a motion event vector.\n\n\tWhen applicable, a client can transform its content relative to the\n\tscroll distance.\n      </description>\n      <arg name=\"time\" type=\"uint\" summary=\"timestamp with millisecond granularity\"/>\n      <arg name=\"axis\" type=\"uint\" enum=\"axis\" summary=\"axis type\"/>\n      <arg name=\"value\" type=\"fixed\" summary=\"length of vector in surface-local coordinate space\"/>\n    </event>\n\n    <!-- Version 3 additions -->\n\n    <request name=\"release\" type=\"destructor\" since=\"3\">\n      <description summary=\"release the pointer object\">\n\tUsing this request a client can tell the server that it is not going to\n\tuse the pointer object anymore.\n\n\tThis request destroys the pointer proxy object, so clients must not call\n\twl_pointer_destroy() after using this request.\n      </description>\n    </request>\n\n    <!-- Version 5 additions -->\n\n    <event name=\"frame\" since=\"5\">\n      <description summary=\"end of a pointer event sequence\">\n\tIndicates the end of a set of events that logically belong together.\n\tA client is expected to accumulate the data in all events within the\n\tframe before proceeding.\n\n\tAll wl_pointer events before a wl_pointer.frame event belong\n\tlogically together. For example, in a diagonal scroll motion the\n\tcompositor will send an optional wl_pointer.axis_source event, two\n\twl_pointer.axis events (horizontal and vertical) and finally a\n\twl_pointer.frame event. The client may use this information to\n\tcalculate a diagonal vector for scrolling.\n\n\tWhen multiple wl_pointer.axis events occur within the same frame,\n\tthe motion vector is the combined motion of all events.\n\tWhen a wl_pointer.axis and a wl_pointer.axis_stop event occur within\n\tthe same frame, this indicates that axis movement in one axis has\n\tstopped but continues in the other axis.\n\tWhen multiple wl_pointer.axis_stop events occur within the same\n\tframe, this indicates that these axes stopped in the same instance.\n\n\tA wl_pointer.frame event is sent for every logical event group,\n\teven if the group only contains a single wl_pointer event.\n\tSpecifically, a client may get a sequence: motion, frame, button,\n\tframe, axis, frame, axis_stop, frame.\n\n\tThe wl_pointer.enter and wl_pointer.leave events are logical events\n\tgenerated by the compositor and not the hardware. These events are\n\talso grouped by a wl_pointer.frame. When a pointer moves from one\n\tsurface to another, a compositor should group the\n\twl_pointer.leave event within the same wl_pointer.frame.\n\tHowever, a client must not rely on wl_pointer.leave and\n\twl_pointer.enter being in the same wl_pointer.frame.\n\tCompositor-specific policies may require the wl_pointer.leave and\n\twl_pointer.enter event being split across multiple wl_pointer.frame\n\tgroups.\n      </description>\n    </event>\n\n    <enum name=\"axis_source\">\n      <description summary=\"axis source types\">\n\tDescribes the source types for axis events. This indicates to the\n\tclient how an axis event was physically generated; a client may\n\tadjust the user interface accordingly. For example, scroll events\n\tfrom a \"finger\" source may be in a smooth coordinate space with\n\tkinetic scrolling whereas a \"wheel\" source may be in discrete steps\n\tof a number of lines.\n\n\tThe \"continuous\" axis source is a device generating events in a\n\tcontinuous coordinate space, but using something other than a\n\tfinger. One example for this source is button-based scrolling where\n\tthe vertical motion of a device is converted to scroll events while\n\ta button is held down.\n\n\tThe \"wheel tilt\" axis source indicates that the actual device is a\n\twheel but the scroll event is not caused by a rotation but a\n\t(usually sideways) tilt of the wheel.\n      </description>\n      <entry name=\"wheel\" value=\"0\" summary=\"a physical wheel rotation\" />\n      <entry name=\"finger\" value=\"1\" summary=\"finger on a touch surface\" />\n      <entry name=\"continuous\" value=\"2\" summary=\"continuous coordinate space\"/>\n      <entry name=\"wheel_tilt\" value=\"3\" summary=\"a physical wheel tilt\" since=\"6\"/>\n    </enum>\n\n    <event name=\"axis_source\" since=\"5\">\n      <description summary=\"axis source event\">\n\tSource information for scroll and other axes.\n\n\tThis event does not occur on its own. It is sent before a\n\twl_pointer.frame event and carries the source information for\n\tall events within that frame.\n\n\tThe source specifies how this event was generated. If the source is\n\twl_pointer.axis_source.finger, a wl_pointer.axis_stop event will be\n\tsent when the user lifts the finger off the device.\n\n\tIf the source is wl_pointer.axis_source.wheel,\n\twl_pointer.axis_source.wheel_tilt or\n\twl_pointer.axis_source.continuous, a wl_pointer.axis_stop event may\n\tor may not be sent. Whether a compositor sends an axis_stop event\n\tfor these sources is hardware-specific and implementation-dependent;\n\tclients must not rely on receiving an axis_stop event for these\n\tscroll sources and should treat scroll sequences from these scroll\n\tsources as unterminated by default.\n\n\tThis event is optional. If the source is unknown for a particular\n\taxis event sequence, no event is sent.\n\tOnly one wl_pointer.axis_source event is permitted per frame.\n\n\tThe order of wl_pointer.axis_discrete and wl_pointer.axis_source is\n\tnot guaranteed.\n      </description>\n      <arg name=\"axis_source\" type=\"uint\" enum=\"axis_source\" summary=\"source of the axis event\"/>\n    </event>\n\n    <event name=\"axis_stop\" since=\"5\">\n      <description summary=\"axis stop event\">\n\tStop notification for scroll and other axes.\n\n\tFor some wl_pointer.axis_source types, a wl_pointer.axis_stop event\n\tis sent to notify a client that the axis sequence has terminated.\n\tThis enables the client to implement kinetic scrolling.\n\tSee the wl_pointer.axis_source documentation for information on when\n\tthis event may be generated.\n\n\tAny wl_pointer.axis events with the same axis_source after this\n\tevent should be considered as the start of a new axis motion.\n\n\tThe timestamp is to be interpreted identical to the timestamp in the\n\twl_pointer.axis event. The timestamp value may be the same as a\n\tpreceding wl_pointer.axis event.\n      </description>\n      <arg name=\"time\" type=\"uint\" summary=\"timestamp with millisecond granularity\"/>\n      <arg name=\"axis\" type=\"uint\" enum=\"axis\" summary=\"the axis stopped with this event\"/>\n    </event>\n\n    <event name=\"axis_discrete\" since=\"5\" deprecated-since=\"8\">\n      <description summary=\"axis click event\">\n\tDiscrete step information for scroll and other axes.\n\n\tThis event carries the axis value of the wl_pointer.axis event in\n\tdiscrete steps (e.g. mouse wheel clicks).\n\n\tThis event is deprecated with wl_pointer version 8 - this event is not\n\tsent to clients supporting version 8 or later.\n\n\tThis event does not occur on its own, it is coupled with a\n\twl_pointer.axis event that represents this axis value on a\n\tcontinuous scale. The protocol guarantees that each axis_discrete\n\tevent is always followed by exactly one axis event with the same\n\taxis number within the same wl_pointer.frame. Note that the protocol\n\tallows for other events to occur between the axis_discrete and\n\tits coupled axis event, including other axis_discrete or axis\n\tevents. A wl_pointer.frame must not contain more than one axis_discrete\n\tevent per axis type.\n\n\tThis event is optional; continuous scrolling devices\n\tlike two-finger scrolling on touchpads do not have discrete\n\tsteps and do not generate this event.\n\n\tThe discrete value carries the directional information. e.g. a value\n\tof -2 is two steps towards the negative direction of this axis.\n\n\tThe axis number is identical to the axis number in the associated\n\taxis event.\n\n\tThe order of wl_pointer.axis_discrete and wl_pointer.axis_source is\n\tnot guaranteed.\n      </description>\n      <arg name=\"axis\" type=\"uint\" enum=\"axis\" summary=\"axis type\"/>\n      <arg name=\"discrete\" type=\"int\" summary=\"number of steps\"/>\n    </event>\n\n    <event name=\"axis_value120\" since=\"8\">\n      <description summary=\"axis high-resolution scroll event\">\n\tDiscrete high-resolution scroll information.\n\n\tThis event carries high-resolution wheel scroll information,\n\twith each multiple of 120 representing one logical scroll step\n\t(a wheel detent). For example, an axis_value120 of 30 is one quarter of\n\ta logical scroll step in the positive direction, a value120 of\n\t-240 are two logical scroll steps in the negative direction within the\n\tsame hardware event.\n\tClients that rely on discrete scrolling should accumulate the\n\tvalue120 to multiples of 120 before processing the event.\n\n\tThe value120 must not be zero.\n\n\tThis event replaces the wl_pointer.axis_discrete event in clients\n\tsupporting wl_pointer version 8 or later.\n\n\tWhere a wl_pointer.axis_source event occurs in the same\n\twl_pointer.frame, the axis source applies to this event.\n\n\tThe order of wl_pointer.axis_value120 and wl_pointer.axis_source is\n\tnot guaranteed.\n      </description>\n      <arg name=\"axis\" type=\"uint\" enum=\"axis\" summary=\"axis type\"/>\n      <arg name=\"value120\" type=\"int\" summary=\"scroll distance as fraction of 120\"/>\n    </event>\n\n    <!-- Version 9 additions -->\n\n    <enum name=\"axis_relative_direction\">\n      <description summary=\"axis relative direction\">\n\tThis specifies the direction of the physical motion that caused a\n\twl_pointer.axis event, relative to the wl_pointer.axis direction.\n      </description>\n      <entry name=\"identical\" value=\"0\"\n\t  summary=\"physical motion matches axis direction\"/>\n      <entry name=\"inverted\" value=\"1\"\n\t  summary=\"physical motion is the inverse of the axis direction\"/>\n    </enum>\n\n    <event name=\"axis_relative_direction\" since=\"9\">\n      <description summary=\"axis relative physical direction event\">\n\tRelative directional information of the entity causing the axis\n\tmotion.\n\n\tFor a wl_pointer.axis event, the wl_pointer.axis_relative_direction\n\tevent specifies the movement direction of the entity causing the\n\twl_pointer.axis event. For example:\n\t- if a user's fingers on a touchpad move down and this\n\t  causes a wl_pointer.axis vertical_scroll down event, the physical\n\t  direction is 'identical'\n\t- if a user's fingers on a touchpad move down and this causes a\n\t  wl_pointer.axis vertical_scroll up scroll up event ('natural\n\t  scrolling'), the physical direction is 'inverted'.\n\n\tA client may use this information to adjust scroll motion of\n\tcomponents. Specifically, enabling natural scrolling causes the\n\tcontent to change direction compared to traditional scrolling.\n\tSome widgets like volume control sliders should usually match the\n\tphysical direction regardless of whether natural scrolling is\n\tactive. This event enables clients to match the scroll direction of\n\ta widget to the physical direction.\n\n\tThis event does not occur on its own, it is coupled with a\n\twl_pointer.axis event that represents this axis value.\n\tThe protocol guarantees that each axis_relative_direction event is\n\talways followed by exactly one axis event with the same\n\taxis number within the same wl_pointer.frame. Note that the protocol\n\tallows for other events to occur between the axis_relative_direction\n\tand its coupled axis event.\n\n\tThe axis number is identical to the axis number in the associated\n\taxis event.\n\n\tThe order of wl_pointer.axis_relative_direction,\n\twl_pointer.axis_discrete and wl_pointer.axis_source is not\n\tguaranteed.\n      </description>\n      <arg name=\"axis\" type=\"uint\" enum=\"axis\" summary=\"axis type\"/>\n      <arg name=\"direction\" type=\"uint\" enum=\"axis_relative_direction\"\n\t  summary=\"physical direction relative to axis motion\"/>\n    </event>\n  </interface>\n\n  <interface name=\"wl_keyboard\" version=\"9\">\n    <description summary=\"keyboard input device\">\n      The wl_keyboard interface represents one or more keyboards\n      associated with a seat.\n\n      Each wl_keyboard has the following logical state:\n\n      - an active surface (possibly null),\n      - the keys currently logically down,\n      - the active modifiers,\n      - the active group.\n\n      By default, the active surface is null, the keys currently logically down\n      are empty, the active modifiers and the active group are 0.\n    </description>\n\n    <enum name=\"keymap_format\">\n      <description summary=\"keyboard mapping format\">\n\tThis specifies the format of the keymap provided to the\n\tclient with the wl_keyboard.keymap event.\n      </description>\n      <entry name=\"no_keymap\" value=\"0\"\n\t     summary=\"no keymap; client must understand how to interpret the raw keycode\"/>\n      <entry name=\"xkb_v1\" value=\"1\"\n\t     summary=\"libxkbcommon compatible, null-terminated string; to determine the xkb keycode, clients must add 8 to the key event keycode\"/>\n    </enum>\n\n    <event name=\"keymap\">\n      <description summary=\"keyboard mapping\">\n\tThis event provides a file descriptor to the client which can be\n\tmemory-mapped in read-only mode to provide a keyboard mapping\n\tdescription.\n\n\tFrom version 7 onwards, the fd must be mapped with MAP_PRIVATE by\n\tthe recipient, as MAP_SHARED may fail.\n      </description>\n      <arg name=\"format\" type=\"uint\" enum=\"keymap_format\" summary=\"keymap format\"/>\n      <arg name=\"fd\" type=\"fd\" summary=\"keymap file descriptor\"/>\n      <arg name=\"size\" type=\"uint\" summary=\"keymap size, in bytes\"/>\n    </event>\n\n    <event name=\"enter\">\n      <description summary=\"enter event\">\n\tNotification that this seat's keyboard focus is on a certain\n\tsurface.\n\n\tThe compositor must send the wl_keyboard.modifiers event after this\n\tevent.\n\n\tIn the wl_keyboard logical state, this event sets the active surface to\n\tthe surface argument and the keys currently logically down to the keys\n\tin the keys argument. The compositor must not send this event if the\n\twl_keyboard already had an active surface immediately before this event.\n      </description>\n      <arg name=\"serial\" type=\"uint\" summary=\"serial number of the enter event\"/>\n      <arg name=\"surface\" type=\"object\" interface=\"wl_surface\" summary=\"surface gaining keyboard focus\"/>\n      <arg name=\"keys\" type=\"array\" summary=\"the keys currently logically down\"/>\n    </event>\n\n    <event name=\"leave\">\n      <description summary=\"leave event\">\n\tNotification that this seat's keyboard focus is no longer on\n\ta certain surface.\n\n\tThe leave notification is sent before the enter notification\n\tfor the new focus.\n\n\tIn the wl_keyboard logical state, this event resets all values to their\n\tdefaults. The compositor must not send this event if the active surface\n\tof the wl_keyboard was not equal to the surface argument immediately\n\tbefore this event.\n      </description>\n      <arg name=\"serial\" type=\"uint\" summary=\"serial number of the leave event\"/>\n      <arg name=\"surface\" type=\"object\" interface=\"wl_surface\" summary=\"surface that lost keyboard focus\"/>\n    </event>\n\n    <enum name=\"key_state\">\n      <description summary=\"physical key state\">\n\tDescribes the physical state of a key that produced the key event.\n      </description>\n      <entry name=\"released\" value=\"0\" summary=\"key is not pressed\"/>\n      <entry name=\"pressed\" value=\"1\" summary=\"key is pressed\"/>\n    </enum>\n\n    <event name=\"key\">\n      <description summary=\"key event\">\n\tA key was pressed or released.\n\tThe time argument is a timestamp with millisecond\n\tgranularity, with an undefined base.\n\n\tThe key is a platform-specific key code that can be interpreted\n\tby feeding it to the keyboard mapping (see the keymap event).\n\n\tIf this event produces a change in modifiers, then the resulting\n\twl_keyboard.modifiers event must be sent after this event.\n\n\tIn the wl_keyboard logical state, this event adds the key to the keys\n\tcurrently logically down (if the state argument is pressed) or removes\n\tthe key from the keys currently logically down (if the state argument is\n\treleased). The compositor must not send this event if the wl_keyboard\n\tdid not have an active surface immediately before this event. The\n\tcompositor must not send this event if state is pressed (resp. released)\n\tand the key was already logically down (resp. was not logically down)\n\timmediately before this event.\n      </description>\n      <arg name=\"serial\" type=\"uint\" summary=\"serial number of the key event\"/>\n      <arg name=\"time\" type=\"uint\" summary=\"timestamp with millisecond granularity\"/>\n      <arg name=\"key\" type=\"uint\" summary=\"key that produced the event\"/>\n      <arg name=\"state\" type=\"uint\" enum=\"key_state\" summary=\"physical state of the key\"/>\n    </event>\n\n    <event name=\"modifiers\">\n      <description summary=\"modifier and group state\">\n\tNotifies clients that the modifier and/or group state has\n\tchanged, and it should update its local state.\n\n\tThe compositor may send this event without a surface of the client\n\thaving keyboard focus, for example to tie modifier information to\n\tpointer focus instead. If a modifier event with pressed modifiers is sent\n\twithout a prior enter event, the client can assume the modifier state is\n\tvalid until it receives the next wl_keyboard.modifiers event. In order to\n\treset the modifier state again, the compositor can send a\n\twl_keyboard.modifiers event with no pressed modifiers.\n\n\tIn the wl_keyboard logical state, this event updates the modifiers and\n\tgroup.\n      </description>\n      <arg name=\"serial\" type=\"uint\" summary=\"serial number of the modifiers event\"/>\n      <arg name=\"mods_depressed\" type=\"uint\" summary=\"depressed modifiers\"/>\n      <arg name=\"mods_latched\" type=\"uint\" summary=\"latched modifiers\"/>\n      <arg name=\"mods_locked\" type=\"uint\" summary=\"locked modifiers\"/>\n      <arg name=\"group\" type=\"uint\" summary=\"keyboard layout\"/>\n    </event>\n\n    <!-- Version 3 additions -->\n\n    <request name=\"release\" type=\"destructor\" since=\"3\">\n      <description summary=\"release the keyboard object\"/>\n    </request>\n\n    <!-- Version 4 additions -->\n\n    <event name=\"repeat_info\" since=\"4\">\n      <description summary=\"repeat rate and delay\">\n\tInforms the client about the keyboard's repeat rate and delay.\n\n\tThis event is sent as soon as the wl_keyboard object has been created,\n\tand is guaranteed to be received by the client before any key press\n\tevent.\n\n\tNegative values for either rate or delay are illegal. A rate of zero\n\twill disable any repeating (regardless of the value of delay).\n\n\tThis event can be sent later on as well with a new value if necessary,\n\tso clients should continue listening for the event past the creation\n\tof wl_keyboard.\n      </description>\n      <arg name=\"rate\" type=\"int\"\n\t   summary=\"the rate of repeating keys in characters per second\"/>\n      <arg name=\"delay\" type=\"int\"\n\t   summary=\"delay in milliseconds since key down until repeating starts\"/>\n    </event>\n  </interface>\n\n  <interface name=\"wl_touch\" version=\"9\">\n    <description summary=\"touchscreen input device\">\n      The wl_touch interface represents a touchscreen\n      associated with a seat.\n\n      Touch interactions can consist of one or more contacts.\n      For each contact, a series of events is generated, starting\n      with a down event, followed by zero or more motion events,\n      and ending with an up event. Events relating to the same\n      contact point can be identified by the ID of the sequence.\n    </description>\n\n    <event name=\"down\">\n      <description summary=\"touch down event and beginning of a touch sequence\">\n\tA new touch point has appeared on the surface. This touch point is\n\tassigned a unique ID. Future events from this touch point reference\n\tthis ID. The ID ceases to be valid after a touch up event and may be\n\treused in the future.\n      </description>\n      <arg name=\"serial\" type=\"uint\" summary=\"serial number of the touch down event\"/>\n      <arg name=\"time\" type=\"uint\" summary=\"timestamp with millisecond granularity\"/>\n      <arg name=\"surface\" type=\"object\" interface=\"wl_surface\" summary=\"surface touched\"/>\n      <arg name=\"id\" type=\"int\" summary=\"the unique ID of this touch point\"/>\n      <arg name=\"x\" type=\"fixed\" summary=\"surface-local x coordinate\"/>\n      <arg name=\"y\" type=\"fixed\" summary=\"surface-local y coordinate\"/>\n    </event>\n\n    <event name=\"up\">\n      <description summary=\"end of a touch event sequence\">\n\tThe touch point has disappeared. No further events will be sent for\n\tthis touch point and the touch point's ID is released and may be\n\treused in a future touch down event.\n      </description>\n      <arg name=\"serial\" type=\"uint\" summary=\"serial number of the touch up event\"/>\n      <arg name=\"time\" type=\"uint\" summary=\"timestamp with millisecond granularity\"/>\n      <arg name=\"id\" type=\"int\" summary=\"the unique ID of this touch point\"/>\n    </event>\n\n    <event name=\"motion\">\n      <description summary=\"update of touch point coordinates\">\n\tA touch point has changed coordinates.\n      </description>\n      <arg name=\"time\" type=\"uint\" summary=\"timestamp with millisecond granularity\"/>\n      <arg name=\"id\" type=\"int\" summary=\"the unique ID of this touch point\"/>\n      <arg name=\"x\" type=\"fixed\" summary=\"surface-local x coordinate\"/>\n      <arg name=\"y\" type=\"fixed\" summary=\"surface-local y coordinate\"/>\n    </event>\n\n    <event name=\"frame\">\n      <description summary=\"end of touch frame event\">\n\tIndicates the end of a set of events that logically belong together.\n\tA client is expected to accumulate the data in all events within the\n\tframe before proceeding.\n\n\tA wl_touch.frame terminates at least one event but otherwise no\n\tguarantee is provided about the set of events within a frame. A client\n\tmust assume that any state not updated in a frame is unchanged from the\n\tpreviously known state.\n      </description>\n    </event>\n\n    <event name=\"cancel\">\n      <description summary=\"touch session cancelled\">\n\tSent if the compositor decides the touch stream is a global\n\tgesture. No further events are sent to the clients from that\n\tparticular gesture. Touch cancellation applies to all touch points\n\tcurrently active on this client's surface. The client is\n\tresponsible for finalizing the touch points, future touch points on\n\tthis surface may reuse the touch point ID.\n\n\tNo frame event is required after the cancel event.\n      </description>\n    </event>\n\n    <!-- Version 3 additions -->\n\n    <request name=\"release\" type=\"destructor\" since=\"3\">\n      <description summary=\"release the touch object\"/>\n    </request>\n\n    <!-- Version 6 additions -->\n\n    <event name=\"shape\" since=\"6\">\n      <description summary=\"update shape of touch point\">\n\tSent when a touchpoint has changed its shape.\n\n\tThis event does not occur on its own. It is sent before a\n\twl_touch.frame event and carries the new shape information for\n\tany previously reported, or new touch points of that frame.\n\n\tOther events describing the touch point such as wl_touch.down,\n\twl_touch.motion or wl_touch.orientation may be sent within the\n\tsame wl_touch.frame. A client should treat these events as a single\n\tlogical touch point update. The order of wl_touch.shape,\n\twl_touch.orientation and wl_touch.motion is not guaranteed.\n\tA wl_touch.down event is guaranteed to occur before the first\n\twl_touch.shape event for this touch ID but both events may occur within\n\tthe same wl_touch.frame.\n\n\tA touchpoint shape is approximated by an ellipse through the major and\n\tminor axis length. The major axis length describes the longer diameter\n\tof the ellipse, while the minor axis length describes the shorter\n\tdiameter. Major and minor are orthogonal and both are specified in\n\tsurface-local coordinates. The center of the ellipse is always at the\n\ttouchpoint location as reported by wl_touch.down or wl_touch.move.\n\n\tThis event is only sent by the compositor if the touch device supports\n\tshape reports. The client has to make reasonable assumptions about the\n\tshape if it did not receive this event.\n      </description>\n      <arg name=\"id\" type=\"int\" summary=\"the unique ID of this touch point\"/>\n      <arg name=\"major\" type=\"fixed\" summary=\"length of the major axis in surface-local coordinates\"/>\n      <arg name=\"minor\" type=\"fixed\" summary=\"length of the minor axis in surface-local coordinates\"/>\n    </event>\n\n    <event name=\"orientation\" since=\"6\">\n      <description summary=\"update orientation of touch point\">\n\tSent when a touchpoint has changed its orientation.\n\n\tThis event does not occur on its own. It is sent before a\n\twl_touch.frame event and carries the new shape information for\n\tany previously reported, or new touch points of that frame.\n\n\tOther events describing the touch point such as wl_touch.down,\n\twl_touch.motion or wl_touch.shape may be sent within the\n\tsame wl_touch.frame. A client should treat these events as a single\n\tlogical touch point update. The order of wl_touch.shape,\n\twl_touch.orientation and wl_touch.motion is not guaranteed.\n\tA wl_touch.down event is guaranteed to occur before the first\n\twl_touch.orientation event for this touch ID but both events may occur\n\twithin the same wl_touch.frame.\n\n\tThe orientation describes the clockwise angle of a touchpoint's major\n\taxis to the positive surface y-axis and is normalized to the -180 to\n\t+180 degree range. The granularity of orientation depends on the touch\n\tdevice, some devices only support binary rotation values between 0 and\n\t90 degrees.\n\n\tThis event is only sent by the compositor if the touch device supports\n\torientation reports.\n      </description>\n      <arg name=\"id\" type=\"int\" summary=\"the unique ID of this touch point\"/>\n      <arg name=\"orientation\" type=\"fixed\" summary=\"angle between major axis and positive surface y-axis in degrees\"/>\n    </event>\n  </interface>\n\n  <interface name=\"wl_output\" version=\"4\">\n    <description summary=\"compositor output region\">\n      An output describes part of the compositor geometry.  The\n      compositor works in the 'compositor coordinate system' and an\n      output corresponds to a rectangular area in that space that is\n      actually visible.  This typically corresponds to a monitor that\n      displays part of the compositor space.  This object is published\n      as global during start up, or when a monitor is hotplugged.\n    </description>\n\n    <enum name=\"subpixel\">\n      <description summary=\"subpixel geometry information\">\n\tThis enumeration describes how the physical\n\tpixels on an output are laid out.\n      </description>\n      <entry name=\"unknown\" value=\"0\" summary=\"unknown geometry\"/>\n      <entry name=\"none\" value=\"1\" summary=\"no geometry\"/>\n      <entry name=\"horizontal_rgb\" value=\"2\" summary=\"horizontal RGB\"/>\n      <entry name=\"horizontal_bgr\" value=\"3\" summary=\"horizontal BGR\"/>\n      <entry name=\"vertical_rgb\" value=\"4\" summary=\"vertical RGB\"/>\n      <entry name=\"vertical_bgr\" value=\"5\" summary=\"vertical BGR\"/>\n    </enum>\n\n    <enum name=\"transform\">\n      <description summary=\"transformation applied to buffer contents\">\n\tThis describes transformations that clients and compositors apply to\n\tbuffer contents.\n\n\tThe flipped values correspond to an initial flip around a\n\tvertical axis followed by rotation.\n\n\tThe purpose is mainly to allow clients to render accordingly and\n\ttell the compositor, so that for fullscreen surfaces, the\n\tcompositor will still be able to scan out directly from client\n\tsurfaces.\n      </description>\n      <entry name=\"normal\" value=\"0\" summary=\"no transform\"/>\n      <entry name=\"90\" value=\"1\" summary=\"90 degrees counter-clockwise\"/>\n      <entry name=\"180\" value=\"2\" summary=\"180 degrees counter-clockwise\"/>\n      <entry name=\"270\" value=\"3\" summary=\"270 degrees counter-clockwise\"/>\n      <entry name=\"flipped\" value=\"4\" summary=\"180 degree flip around a vertical axis\"/>\n      <entry name=\"flipped_90\" value=\"5\" summary=\"flip and rotate 90 degrees counter-clockwise\"/>\n      <entry name=\"flipped_180\" value=\"6\" summary=\"flip and rotate 180 degrees counter-clockwise\"/>\n      <entry name=\"flipped_270\" value=\"7\" summary=\"flip and rotate 270 degrees counter-clockwise\"/>\n    </enum>\n\n    <event name=\"geometry\">\n      <description summary=\"properties of the output\">\n\tThe geometry event describes geometric properties of the output.\n\tThe event is sent when binding to the output object and whenever\n\tany of the properties change.\n\n\tThe physical size can be set to zero if it doesn't make sense for this\n\toutput (e.g. for projectors or virtual outputs).\n\n\tThe geometry event will be followed by a done event (starting from\n\tversion 2).\n\n\tClients should use wl_surface.preferred_buffer_transform instead of the\n\ttransform advertised by this event to find the preferred buffer\n\ttransform to use for a surface.\n\n\tNote: wl_output only advertises partial information about the output\n\tposition and identification. Some compositors, for instance those not\n\timplementing a desktop-style output layout or those exposing virtual\n\toutputs, might fake this information. Instead of using x and y, clients\n\tshould use xdg_output.logical_position. Instead of using make and model,\n\tclients should use name and description.\n      </description>\n      <arg name=\"x\" type=\"int\"\n\t   summary=\"x position within the global compositor space\"/>\n      <arg name=\"y\" type=\"int\"\n\t   summary=\"y position within the global compositor space\"/>\n      <arg name=\"physical_width\" type=\"int\"\n\t   summary=\"width in millimeters of the output\"/>\n      <arg name=\"physical_height\" type=\"int\"\n\t   summary=\"height in millimeters of the output\"/>\n      <arg name=\"subpixel\" type=\"int\" enum=\"subpixel\"\n\t   summary=\"subpixel orientation of the output\"/>\n      <arg name=\"make\" type=\"string\"\n\t   summary=\"textual description of the manufacturer\"/>\n      <arg name=\"model\" type=\"string\"\n\t   summary=\"textual description of the model\"/>\n      <arg name=\"transform\" type=\"int\" enum=\"transform\"\n\t   summary=\"additional transformation applied to buffer contents during presentation\"/>\n    </event>\n\n    <enum name=\"mode\" bitfield=\"true\">\n      <description summary=\"mode information\">\n\tThese flags describe properties of an output mode.\n\tThey are used in the flags bitfield of the mode event.\n      </description>\n      <entry name=\"current\" value=\"0x1\"\n\t     summary=\"indicates this is the current mode\"/>\n      <entry name=\"preferred\" value=\"0x2\"\n\t     summary=\"indicates this is the preferred mode\"/>\n    </enum>\n\n    <event name=\"mode\">\n      <description summary=\"advertise available modes for the output\">\n\tThe mode event describes an available mode for the output.\n\n\tThe event is sent when binding to the output object and there\n\twill always be one mode, the current mode.  The event is sent\n\tagain if an output changes mode, for the mode that is now\n\tcurrent.  In other words, the current mode is always the last\n\tmode that was received with the current flag set.\n\n\tNon-current modes are deprecated. A compositor can decide to only\n\tadvertise the current mode and never send other modes. Clients\n\tshould not rely on non-current modes.\n\n\tThe size of a mode is given in physical hardware units of\n\tthe output device. This is not necessarily the same as\n\tthe output size in the global compositor space. For instance,\n\tthe output may be scaled, as described in wl_output.scale,\n\tor transformed, as described in wl_output.transform. Clients\n\twilling to retrieve the output size in the global compositor\n\tspace should use xdg_output.logical_size instead.\n\n\tThe vertical refresh rate can be set to zero if it doesn't make\n\tsense for this output (e.g. for virtual outputs).\n\n\tThe mode event will be followed by a done event (starting from\n\tversion 2).\n\n\tClients should not use the refresh rate to schedule frames. Instead,\n\tthey should use the wl_surface.frame event or the presentation-time\n\tprotocol.\n\n\tNote: this information is not always meaningful for all outputs. Some\n\tcompositors, such as those exposing virtual outputs, might fake the\n\trefresh rate or the size.\n      </description>\n      <arg name=\"flags\" type=\"uint\" enum=\"mode\" summary=\"bitfield of mode flags\"/>\n      <arg name=\"width\" type=\"int\" summary=\"width of the mode in hardware units\"/>\n      <arg name=\"height\" type=\"int\" summary=\"height of the mode in hardware units\"/>\n      <arg name=\"refresh\" type=\"int\" summary=\"vertical refresh rate in mHz\"/>\n    </event>\n\n    <!-- Version 2 additions -->\n\n    <event name=\"done\" since=\"2\">\n      <description summary=\"sent all information about output\">\n\tThis event is sent after all other properties have been\n\tsent after binding to the output object and after any\n\tother property changes done after that. This allows\n\tchanges to the output properties to be seen as\n\tatomic, even if they happen via multiple events.\n      </description>\n    </event>\n\n    <event name=\"scale\" since=\"2\">\n      <description summary=\"output scaling properties\">\n\tThis event contains scaling geometry information\n\tthat is not in the geometry event. It may be sent after\n\tbinding the output object or if the output scale changes\n\tlater. The compositor will emit a non-zero, positive\n\tvalue for scale. If it is not sent, the client should\n\tassume a scale of 1.\n\n\tA scale larger than 1 means that the compositor will\n\tautomatically scale surface buffers by this amount\n\twhen rendering. This is used for very high resolution\n\tdisplays where applications rendering at the native\n\tresolution would be too small to be legible.\n\n\tClients should use wl_surface.preferred_buffer_scale\n\tinstead of this event to find the preferred buffer\n\tscale to use for a surface.\n\n\tThe scale event will be followed by a done event.\n      </description>\n      <arg name=\"factor\" type=\"int\" summary=\"scaling factor of output\"/>\n    </event>\n\n    <!-- Version 3 additions -->\n\n    <request name=\"release\" type=\"destructor\" since=\"3\">\n      <description summary=\"release the output object\">\n\tUsing this request a client can tell the server that it is not going to\n\tuse the output object anymore.\n      </description>\n    </request>\n\n    <!-- Version 4 additions -->\n\n    <event name=\"name\" since=\"4\">\n      <description summary=\"name of this output\">\n\tMany compositors will assign user-friendly names to their outputs, show\n\tthem to the user, allow the user to refer to an output, etc. The client\n\tmay wish to know this name as well to offer the user similar behaviors.\n\n\tThe name is a UTF-8 string with no convention defined for its contents.\n\tEach name is unique among all wl_output globals. The name is only\n\tguaranteed to be unique for the compositor instance.\n\n\tThe same output name is used for all clients for a given wl_output\n\tglobal. Thus, the name can be shared across processes to refer to a\n\tspecific wl_output global.\n\n\tThe name is not guaranteed to be persistent across sessions, thus cannot\n\tbe used to reliably identify an output in e.g. configuration files.\n\n\tExamples of names include 'HDMI-A-1', 'WL-1', 'X11-1', etc. However, do\n\tnot assume that the name is a reflection of an underlying DRM connector,\n\tX11 connection, etc.\n\n\tThe name event is sent after binding the output object. This event is\n\tonly sent once per output object, and the name does not change over the\n\tlifetime of the wl_output global.\n\n\tCompositors may re-use the same output name if the wl_output global is\n\tdestroyed and re-created later. Compositors should avoid re-using the\n\tsame name if possible.\n\n\tThe name event will be followed by a done event.\n      </description>\n      <arg name=\"name\" type=\"string\" summary=\"output name\"/>\n    </event>\n\n    <event name=\"description\" since=\"4\">\n      <description summary=\"human-readable description of this output\">\n\tMany compositors can produce human-readable descriptions of their\n\toutputs. The client may wish to know this description as well, e.g. for\n\toutput selection purposes.\n\n\tThe description is a UTF-8 string with no convention defined for its\n\tcontents. The description is not guaranteed to be unique among all\n\twl_output globals. Examples might include 'Foocorp 11\" Display' or\n\t'Virtual X11 output via :1'.\n\n\tThe description event is sent after binding the output object and\n\twhenever the description changes. The description is optional, and may\n\tnot be sent at all.\n\n\tThe description event will be followed by a done event.\n      </description>\n      <arg name=\"description\" type=\"string\" summary=\"output description\"/>\n    </event>\n  </interface>\n\n  <interface name=\"wl_region\" version=\"1\">\n    <description summary=\"region interface\">\n      A region object describes an area.\n\n      Region objects are used to describe the opaque and input\n      regions of a surface.\n    </description>\n\n    <request name=\"destroy\" type=\"destructor\">\n      <description summary=\"destroy region\">\n\tDestroy the region.  This will invalidate the object ID.\n      </description>\n    </request>\n\n    <request name=\"add\">\n      <description summary=\"add rectangle to region\">\n\tAdd the specified rectangle to the region.\n      </description>\n      <arg name=\"x\" type=\"int\" summary=\"region-local x coordinate\"/>\n      <arg name=\"y\" type=\"int\" summary=\"region-local y coordinate\"/>\n      <arg name=\"width\" type=\"int\" summary=\"rectangle width\"/>\n      <arg name=\"height\" type=\"int\" summary=\"rectangle height\"/>\n    </request>\n\n    <request name=\"subtract\">\n      <description summary=\"subtract rectangle from region\">\n\tSubtract the specified rectangle from the region.\n      </description>\n      <arg name=\"x\" type=\"int\" summary=\"region-local x coordinate\"/>\n      <arg name=\"y\" type=\"int\" summary=\"region-local y coordinate\"/>\n      <arg name=\"width\" type=\"int\" summary=\"rectangle width\"/>\n      <arg name=\"height\" type=\"int\" summary=\"rectangle height\"/>\n    </request>\n  </interface>\n\n  <interface name=\"wl_subcompositor\" version=\"1\">\n    <description summary=\"sub-surface compositing\">\n      The global interface exposing sub-surface compositing capabilities.\n      A wl_surface, that has sub-surfaces associated, is called the\n      parent surface. Sub-surfaces can be arbitrarily nested and create\n      a tree of sub-surfaces.\n\n      The root surface in a tree of sub-surfaces is the main\n      surface. The main surface cannot be a sub-surface, because\n      sub-surfaces must always have a parent.\n\n      A main surface with its sub-surfaces forms a (compound) window.\n      For window management purposes, this set of wl_surface objects is\n      to be considered as a single window, and it should also behave as\n      such.\n\n      The aim of sub-surfaces is to offload some of the compositing work\n      within a window from clients to the compositor. A prime example is\n      a video player with decorations and video in separate wl_surface\n      objects. This should allow the compositor to pass YUV video buffer\n      processing to dedicated overlay hardware when possible.\n    </description>\n\n    <request name=\"destroy\" type=\"destructor\">\n      <description summary=\"unbind from the subcompositor interface\">\n\tInforms the server that the client will not be using this\n\tprotocol object anymore. This does not affect any other\n\tobjects, wl_subsurface objects included.\n      </description>\n    </request>\n\n    <enum name=\"error\">\n      <entry name=\"bad_surface\" value=\"0\"\n\t     summary=\"the to-be sub-surface is invalid\"/>\n      <entry name=\"bad_parent\" value=\"1\"\n\t     summary=\"the to-be sub-surface parent is invalid\"/>\n    </enum>\n\n    <request name=\"get_subsurface\">\n      <description summary=\"give a surface the role sub-surface\">\n\tCreate a sub-surface interface for the given surface, and\n\tassociate it with the given parent surface. This turns a\n\tplain wl_surface into a sub-surface.\n\n\tThe to-be sub-surface must not already have another role, and it\n\tmust not have an existing wl_subsurface object. Otherwise the\n\tbad_surface protocol error is raised.\n\n\tAdding sub-surfaces to a parent is a double-buffered operation on the\n\tparent (see wl_surface.commit). The effect of adding a sub-surface\n\tbecomes visible on the next time the state of the parent surface is\n\tapplied.\n\n\tThe parent surface must not be one of the child surface's descendants,\n\tand the parent must be different from the child surface, otherwise the\n\tbad_parent protocol error is raised.\n\n\tThis request modifies the behaviour of wl_surface.commit request on\n\tthe sub-surface, see the documentation on wl_subsurface interface.\n      </description>\n      <arg name=\"id\" type=\"new_id\" interface=\"wl_subsurface\"\n\t   summary=\"the new sub-surface object ID\"/>\n      <arg name=\"surface\" type=\"object\" interface=\"wl_surface\"\n\t   summary=\"the surface to be turned into a sub-surface\"/>\n      <arg name=\"parent\" type=\"object\" interface=\"wl_surface\"\n\t   summary=\"the parent surface\"/>\n    </request>\n  </interface>\n\n  <interface name=\"wl_subsurface\" version=\"1\">\n    <description summary=\"sub-surface interface to a wl_surface\">\n      An additional interface to a wl_surface object, which has been\n      made a sub-surface. A sub-surface has one parent surface. A\n      sub-surface's size and position are not limited to that of the parent.\n      Particularly, a sub-surface is not automatically clipped to its\n      parent's area.\n\n      A sub-surface becomes mapped, when a non-NULL wl_buffer is applied\n      and the parent surface is mapped. The order of which one happens\n      first is irrelevant. A sub-surface is hidden if the parent becomes\n      hidden, or if a NULL wl_buffer is applied. These rules apply\n      recursively through the tree of surfaces.\n\n      The behaviour of a wl_surface.commit request on a sub-surface\n      depends on the sub-surface's mode. The possible modes are\n      synchronized and desynchronized, see methods\n      wl_subsurface.set_sync and wl_subsurface.set_desync. Synchronized\n      mode caches the wl_surface state to be applied when the parent's\n      state gets applied, and desynchronized mode applies the pending\n      wl_surface state directly. A sub-surface is initially in the\n      synchronized mode.\n\n      Sub-surfaces also have another kind of state, which is managed by\n      wl_subsurface requests, as opposed to wl_surface requests. This\n      state includes the sub-surface position relative to the parent\n      surface (wl_subsurface.set_position), and the stacking order of\n      the parent and its sub-surfaces (wl_subsurface.place_above and\n      .place_below). This state is applied when the parent surface's\n      wl_surface state is applied, regardless of the sub-surface's mode.\n      As the exception, set_sync and set_desync are effective immediately.\n\n      The main surface can be thought to be always in desynchronized mode,\n      since it does not have a parent in the sub-surfaces sense.\n\n      Even if a sub-surface is in desynchronized mode, it will behave as\n      in synchronized mode, if its parent surface behaves as in\n      synchronized mode. This rule is applied recursively throughout the\n      tree of surfaces. This means, that one can set a sub-surface into\n      synchronized mode, and then assume that all its child and grand-child\n      sub-surfaces are synchronized, too, without explicitly setting them.\n\n      Destroying a sub-surface takes effect immediately. If you need to\n      synchronize the removal of a sub-surface to the parent surface update,\n      unmap the sub-surface first by attaching a NULL wl_buffer, update parent,\n      and then destroy the sub-surface.\n\n      If the parent wl_surface object is destroyed, the sub-surface is\n      unmapped.\n\n      A sub-surface never has the keyboard focus of any seat.\n\n      The wl_surface.offset request is ignored: clients must use set_position\n      instead to move the sub-surface.\n    </description>\n\n    <request name=\"destroy\" type=\"destructor\">\n      <description summary=\"remove sub-surface interface\">\n\tThe sub-surface interface is removed from the wl_surface object\n\tthat was turned into a sub-surface with a\n\twl_subcompositor.get_subsurface request. The wl_surface's association\n\tto the parent is deleted. The wl_surface is unmapped immediately.\n      </description>\n    </request>\n\n    <enum name=\"error\">\n      <entry name=\"bad_surface\" value=\"0\"\n\t     summary=\"wl_surface is not a sibling or the parent\"/>\n    </enum>\n\n    <request name=\"set_position\">\n      <description summary=\"reposition the sub-surface\">\n\tThis schedules a sub-surface position change.\n\tThe sub-surface will be moved so that its origin (top left\n\tcorner pixel) will be at the location x, y of the parent surface\n\tcoordinate system. The coordinates are not restricted to the parent\n\tsurface area. Negative values are allowed.\n\n\tThe scheduled coordinates will take effect whenever the state of the\n\tparent surface is applied.\n\n\tIf more than one set_position request is invoked by the client before\n\tthe commit of the parent surface, the position of a new request always\n\treplaces the scheduled position from any previous request.\n\n\tThe initial position is 0, 0.\n      </description>\n      <arg name=\"x\" type=\"int\" summary=\"x coordinate in the parent surface\"/>\n      <arg name=\"y\" type=\"int\" summary=\"y coordinate in the parent surface\"/>\n    </request>\n\n    <request name=\"place_above\">\n      <description summary=\"restack the sub-surface\">\n\tThis sub-surface is taken from the stack, and put back just\n\tabove the reference surface, changing the z-order of the sub-surfaces.\n\tThe reference surface must be one of the sibling surfaces, or the\n\tparent surface. Using any other surface, including this sub-surface,\n\twill cause a protocol error.\n\n\tThe z-order is double-buffered. Requests are handled in order and\n\tapplied immediately to a pending state. The final pending state is\n\tcopied to the active state the next time the state of the parent\n\tsurface is applied.\n\n\tA new sub-surface is initially added as the top-most in the stack\n\tof its siblings and parent.\n      </description>\n      <arg name=\"sibling\" type=\"object\" interface=\"wl_surface\"\n\t   summary=\"the reference surface\"/>\n    </request>\n\n    <request name=\"place_below\">\n      <description summary=\"restack the sub-surface\">\n\tThe sub-surface is placed just below the reference surface.\n\tSee wl_subsurface.place_above.\n      </description>\n      <arg name=\"sibling\" type=\"object\" interface=\"wl_surface\"\n\t   summary=\"the reference surface\"/>\n    </request>\n\n    <request name=\"set_sync\">\n      <description summary=\"set sub-surface to synchronized mode\">\n\tChange the commit behaviour of the sub-surface to synchronized\n\tmode, also described as the parent dependent mode.\n\n\tIn synchronized mode, wl_surface.commit on a sub-surface will\n\taccumulate the committed state in a cache, but the state will\n\tnot be applied and hence will not change the compositor output.\n\tThe cached state is applied to the sub-surface immediately after\n\tthe parent surface's state is applied. This ensures atomic\n\tupdates of the parent and all its synchronized sub-surfaces.\n\tApplying the cached state will invalidate the cache, so further\n\tparent surface commits do not (re-)apply old state.\n\n\tSee wl_subsurface for the recursive effect of this mode.\n      </description>\n    </request>\n\n    <request name=\"set_desync\">\n      <description summary=\"set sub-surface to desynchronized mode\">\n\tChange the commit behaviour of the sub-surface to desynchronized\n\tmode, also described as independent or freely running mode.\n\n\tIn desynchronized mode, wl_surface.commit on a sub-surface will\n\tapply the pending state directly, without caching, as happens\n\tnormally with a wl_surface. Calling wl_surface.commit on the\n\tparent surface has no effect on the sub-surface's wl_surface\n\tstate. This mode allows a sub-surface to be updated on its own.\n\n\tIf cached state exists when wl_surface.commit is called in\n\tdesynchronized mode, the pending state is added to the cached\n\tstate, and applied as a whole. This invalidates the cache.\n\n\tNote: even if a sub-surface is set to desynchronized, a parent\n\tsub-surface may override it to behave as synchronized. For details,\n\tsee wl_subsurface.\n\n\tIf a surface's parent surface behaves as desynchronized, then\n\tthe cached state is applied on set_desync.\n      </description>\n    </request>\n  </interface>\n\n</protocol>\n"
  },
  {
    "path": "wayland/generate/resources/xdg-decoration-unstable-v1.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<protocol name=\"xdg_decoration_unstable_v1\">\n  <copyright>\n    Copyright © 2018 Simon Ser\n\n    Permission is hereby granted, free of charge, to any person obtaining a\n    copy of this software and associated documentation files (the \"Software\"),\n    to deal in the Software without restriction, including without limitation\n    the rights to use, copy, modify, merge, publish, distribute, sublicense,\n    and/or sell copies of the Software, and to permit persons to whom the\n    Software is furnished to do so, subject to the following conditions:\n\n    The above copyright notice and this permission notice (including the next\n    paragraph) shall be included in all copies or substantial portions of the\n    Software.\n\n    THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL\n    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n    DEALINGS IN THE SOFTWARE.\n  </copyright>\n\n  <interface name=\"zxdg_decoration_manager_v1\" version=\"1\">\n    <description summary=\"window decoration manager\">\n      This interface allows a compositor to announce support for server-side\n      decorations.\n\n      A window decoration is a set of window controls as deemed appropriate by\n      the party managing them, such as user interface components used to move,\n      resize and change a window's state.\n\n      A client can use this protocol to request being decorated by a supporting\n      compositor.\n\n      If compositor and client do not negotiate the use of a server-side\n      decoration using this protocol, clients continue to self-decorate as they\n      see fit.\n\n      Warning! The protocol described in this file is experimental and\n      backward incompatible changes may be made. Backward compatible changes\n      may be added together with the corresponding interface version bump.\n      Backward incompatible changes are done by bumping the version number in\n      the protocol and interface names and resetting the interface version.\n      Once the protocol is to be declared stable, the 'z' prefix and the\n      version number in the protocol and interface names are removed and the\n      interface version number is reset.\n    </description>\n\n    <request name=\"destroy\" type=\"destructor\">\n      <description summary=\"destroy the decoration manager object\">\n        Destroy the decoration manager. This doesn't destroy objects created\n        with the manager.\n      </description>\n    </request>\n\n    <request name=\"get_toplevel_decoration\">\n      <description summary=\"create a new toplevel decoration object\">\n        Create a new decoration object associated with the given toplevel.\n\n        Creating an xdg_toplevel_decoration from an xdg_toplevel which has a\n        buffer attached or committed is a client error, and any attempts by a\n        client to attach or manipulate a buffer prior to the first\n        xdg_toplevel_decoration.configure event must also be treated as\n        errors.\n      </description>\n      <arg name=\"id\" type=\"new_id\" interface=\"zxdg_toplevel_decoration_v1\"/>\n      <arg name=\"toplevel\" type=\"object\" interface=\"xdg_toplevel\"/>\n    </request>\n  </interface>\n\n  <interface name=\"zxdg_toplevel_decoration_v1\" version=\"1\">\n    <description summary=\"decoration object for a toplevel surface\">\n      The decoration object allows the compositor to toggle server-side window\n      decorations for a toplevel surface. The client can request to switch to\n      another mode.\n\n      The xdg_toplevel_decoration object must be destroyed before its\n      xdg_toplevel.\n    </description>\n\n    <enum name=\"error\">\n      <entry name=\"unconfigured_buffer\" value=\"0\"\n        summary=\"xdg_toplevel has a buffer attached before configure\"/>\n      <entry name=\"already_constructed\" value=\"1\"\n        summary=\"xdg_toplevel already has a decoration object\"/>\n      <entry name=\"orphaned\" value=\"2\"\n        summary=\"xdg_toplevel destroyed before the decoration object\"/>\n      <entry name=\"invalid_mode\" value=\"3\" summary=\"invalid mode\"/>\n    </enum>\n\n    <request name=\"destroy\" type=\"destructor\">\n      <description summary=\"destroy the decoration object\">\n        Switch back to a mode without any server-side decorations at the next\n        commit.\n      </description>\n    </request>\n\n    <enum name=\"mode\">\n      <description summary=\"window decoration modes\">\n        These values describe window decoration modes.\n      </description>\n      <entry name=\"client_side\" value=\"1\"\n        summary=\"no server-side window decoration\"/>\n      <entry name=\"server_side\" value=\"2\"\n        summary=\"server-side window decoration\"/>\n    </enum>\n\n    <request name=\"set_mode\">\n      <description summary=\"set the decoration mode\">\n        Set the toplevel surface decoration mode. This informs the compositor\n        that the client prefers the provided decoration mode.\n\n        After requesting a decoration mode, the compositor will respond by\n        emitting an xdg_surface.configure event. The client should then update\n        its content, drawing it without decorations if the received mode is\n        server-side decorations. The client must also acknowledge the configure\n        when committing the new content (see xdg_surface.ack_configure).\n\n        The compositor can decide not to use the client's mode and enforce a\n        different mode instead.\n\n        Clients whose decoration mode depend on the xdg_toplevel state may send\n        a set_mode request in response to an xdg_surface.configure event and wait\n        for the next xdg_surface.configure event to prevent unwanted state.\n        Such clients are responsible for preventing configure loops and must\n        make sure not to send multiple successive set_mode requests with the\n        same decoration mode.\n\n        If an invalid mode is supplied by the client, the invalid_mode protocol\n        error is raised by the compositor.\n      </description>\n      <arg name=\"mode\" type=\"uint\" enum=\"mode\" summary=\"the decoration mode\"/>\n    </request>\n\n    <request name=\"unset_mode\">\n      <description summary=\"unset the decoration mode\">\n        Unset the toplevel surface decoration mode. This informs the compositor\n        that the client doesn't prefer a particular decoration mode.\n\n        This request has the same semantics as set_mode.\n      </description>\n    </request>\n\n    <event name=\"configure\">\n      <description summary=\"notify a decoration mode change\">\n        The configure event configures the effective decoration mode. The\n        configured state should not be applied immediately. Clients must send an\n        ack_configure in response to this event. See xdg_surface.configure and\n        xdg_surface.ack_configure for details.\n\n        A configure event can be sent at any time. The specified mode must be\n        obeyed by the client.\n      </description>\n      <arg name=\"mode\" type=\"uint\" enum=\"mode\" summary=\"the decoration mode\"/>\n    </event>\n  </interface>\n</protocol>"
  },
  {
    "path": "wayland/generate/resources/xdg-shell.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<protocol name=\"xdg_shell\">\n\n\n  <copyright>\n    Copyright © 2008-2013 Kristian Høgsberg\n    Copyright © 2013      Rafael Antognolli\n    Copyright © 2013      Jasper St. Pierre\n    Copyright © 2010-2013 Intel Corporation\n    Copyright © 2015-2017 Samsung Electronics Co., Ltd\n    Copyright © 2015-2017 Red Hat Inc.\n\n    Permission is hereby granted, free of charge, to any person obtaining a\n    copy of this software and associated documentation files (the \"Software\"),\n    to deal in the Software without restriction, including without limitation\n    the rights to use, copy, modify, merge, publish, distribute, sublicense,\n    and/or sell copies of the Software, and to permit persons to whom the\n    Software is furnished to do so, subject to the following conditions:\n\n    The above copyright notice and this permission notice (including the next\n    paragraph) shall be included in all copies or substantial portions of the\n    Software.\n\n    THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL\n    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n    DEALINGS IN THE SOFTWARE.\n  </copyright>\n\n  <interface name=\"xdg_wm_base\" version=\"6\">\n    <description summary=\"create desktop-style surfaces\">\n      The xdg_wm_base interface is exposed as a global object enabling clients\n      to turn their wl_surfaces into windows in a desktop environment. It\n      defines the basic functionality needed for clients and the compositor to\n      create windows that can be dragged, resized, maximized, etc, as well as\n      creating transient windows such as popup menus.\n    </description>\n\n    <enum name=\"error\">\n      <entry name=\"role\" value=\"0\" summary=\"given wl_surface has another role\"/>\n      <entry name=\"defunct_surfaces\" value=\"1\"\n\t     summary=\"xdg_wm_base was destroyed before children\"/>\n      <entry name=\"not_the_topmost_popup\" value=\"2\"\n\t     summary=\"the client tried to map or destroy a non-topmost popup\"/>\n      <entry name=\"invalid_popup_parent\" value=\"3\"\n\t     summary=\"the client specified an invalid popup parent surface\"/>\n      <entry name=\"invalid_surface_state\" value=\"4\"\n\t     summary=\"the client provided an invalid surface state\"/>\n      <entry name=\"invalid_positioner\" value=\"5\"\n\t     summary=\"the client provided an invalid positioner\"/>\n      <entry name=\"unresponsive\" value=\"6\"\n\t     summary=\"the client didn’t respond to a ping event in time\"/>\n    </enum>\n\n    <request name=\"destroy\" type=\"destructor\">\n      <description summary=\"destroy xdg_wm_base\">\n\tDestroy this xdg_wm_base object.\n\n\tDestroying a bound xdg_wm_base object while there are surfaces\n\tstill alive created by this xdg_wm_base object instance is illegal\n\tand will result in a defunct_surfaces error.\n      </description>\n    </request>\n\n    <request name=\"create_positioner\">\n      <description summary=\"create a positioner object\">\n\tCreate a positioner object. A positioner object is used to position\n\tsurfaces relative to some parent surface. See the interface description\n\tand xdg_surface.get_popup for details.\n      </description>\n      <arg name=\"id\" type=\"new_id\" interface=\"xdg_positioner\"/>\n    </request>\n\n    <request name=\"get_xdg_surface\">\n      <description summary=\"create a shell surface from a surface\">\n\tThis creates an xdg_surface for the given surface. While xdg_surface\n\titself is not a role, the corresponding surface may only be assigned\n\ta role extending xdg_surface, such as xdg_toplevel or xdg_popup. It is\n\tillegal to create an xdg_surface for a wl_surface which already has an\n\tassigned role and this will result in a role error.\n\n\tThis creates an xdg_surface for the given surface. An xdg_surface is\n\tused as basis to define a role to a given surface, such as xdg_toplevel\n\tor xdg_popup. It also manages functionality shared between xdg_surface\n\tbased surface roles.\n\n\tSee the documentation of xdg_surface for more details about what an\n\txdg_surface is and how it is used.\n      </description>\n      <arg name=\"id\" type=\"new_id\" interface=\"xdg_surface\"/>\n      <arg name=\"surface\" type=\"object\" interface=\"wl_surface\"/>\n    </request>\n\n    <request name=\"pong\">\n      <description summary=\"respond to a ping event\">\n\tA client must respond to a ping event with a pong request or\n\tthe client may be deemed unresponsive. See xdg_wm_base.ping\n\tand xdg_wm_base.error.unresponsive.\n      </description>\n      <arg name=\"serial\" type=\"uint\" summary=\"serial of the ping event\"/>\n    </request>\n\n    <event name=\"ping\">\n      <description summary=\"check if the client is alive\">\n\tThe ping event asks the client if it's still alive. Pass the\n\tserial specified in the event back to the compositor by sending\n\ta \"pong\" request back with the specified serial. See xdg_wm_base.pong.\n\n\tCompositors can use this to determine if the client is still\n\talive. It's unspecified what will happen if the client doesn't\n\trespond to the ping request, or in what timeframe. Clients should\n\ttry to respond in a reasonable amount of time. The “unresponsive”\n\terror is provided for compositors that wish to disconnect unresponsive\n\tclients.\n\n\tA compositor is free to ping in any way it wants, but a client must\n\talways respond to any xdg_wm_base object it created.\n      </description>\n      <arg name=\"serial\" type=\"uint\" summary=\"pass this to the pong request\"/>\n    </event>\n  </interface>\n\n  <interface name=\"xdg_positioner\" version=\"6\">\n    <description summary=\"child surface positioner\">\n      The xdg_positioner provides a collection of rules for the placement of a\n      child surface relative to a parent surface. Rules can be defined to ensure\n      the child surface remains within the visible area's borders, and to\n      specify how the child surface changes its position, such as sliding along\n      an axis, or flipping around a rectangle. These positioner-created rules are\n      constrained by the requirement that a child surface must intersect with or\n      be at least partially adjacent to its parent surface.\n\n      See the various requests for details about possible rules.\n\n      At the time of the request, the compositor makes a copy of the rules\n      specified by the xdg_positioner. Thus, after the request is complete the\n      xdg_positioner object can be destroyed or reused; further changes to the\n      object will have no effect on previous usages.\n\n      For an xdg_positioner object to be considered complete, it must have a\n      non-zero size set by set_size, and a non-zero anchor rectangle set by\n      set_anchor_rect. Passing an incomplete xdg_positioner object when\n      positioning a surface raises an invalid_positioner error.\n    </description>\n\n    <enum name=\"error\">\n      <entry name=\"invalid_input\" value=\"0\" summary=\"invalid input provided\"/>\n    </enum>\n\n    <request name=\"destroy\" type=\"destructor\">\n      <description summary=\"destroy the xdg_positioner object\">\n\tNotify the compositor that the xdg_positioner will no longer be used.\n      </description>\n    </request>\n\n    <request name=\"set_size\">\n      <description summary=\"set the size of the to-be positioned rectangle\">\n\tSet the size of the surface that is to be positioned with the positioner\n\tobject. The size is in surface-local coordinates and corresponds to the\n\twindow geometry. See xdg_surface.set_window_geometry.\n\n\tIf a zero or negative size is set the invalid_input error is raised.\n      </description>\n      <arg name=\"width\" type=\"int\" summary=\"width of positioned rectangle\"/>\n      <arg name=\"height\" type=\"int\" summary=\"height of positioned rectangle\"/>\n    </request>\n\n    <request name=\"set_anchor_rect\">\n      <description summary=\"set the anchor rectangle within the parent surface\">\n\tSpecify the anchor rectangle within the parent surface that the child\n\tsurface will be placed relative to. The rectangle is relative to the\n\twindow geometry as defined by xdg_surface.set_window_geometry of the\n\tparent surface.\n\n\tWhen the xdg_positioner object is used to position a child surface, the\n\tanchor rectangle may not extend outside the window geometry of the\n\tpositioned child's parent surface.\n\n\tIf a negative size is set the invalid_input error is raised.\n      </description>\n      <arg name=\"x\" type=\"int\" summary=\"x position of anchor rectangle\"/>\n      <arg name=\"y\" type=\"int\" summary=\"y position of anchor rectangle\"/>\n      <arg name=\"width\" type=\"int\" summary=\"width of anchor rectangle\"/>\n      <arg name=\"height\" type=\"int\" summary=\"height of anchor rectangle\"/>\n    </request>\n\n    <enum name=\"anchor\">\n      <entry name=\"none\" value=\"0\"/>\n      <entry name=\"top\" value=\"1\"/>\n      <entry name=\"bottom\" value=\"2\"/>\n      <entry name=\"left\" value=\"3\"/>\n      <entry name=\"right\" value=\"4\"/>\n      <entry name=\"top_left\" value=\"5\"/>\n      <entry name=\"bottom_left\" value=\"6\"/>\n      <entry name=\"top_right\" value=\"7\"/>\n      <entry name=\"bottom_right\" value=\"8\"/>\n    </enum>\n\n    <request name=\"set_anchor\">\n      <description summary=\"set anchor rectangle anchor\">\n\tDefines the anchor point for the anchor rectangle. The specified anchor\n\tis used derive an anchor point that the child surface will be\n\tpositioned relative to. If a corner anchor is set (e.g. 'top_left' or\n\t'bottom_right'), the anchor point will be at the specified corner;\n\totherwise, the derived anchor point will be centered on the specified\n\tedge, or in the center of the anchor rectangle if no edge is specified.\n      </description>\n      <arg name=\"anchor\" type=\"uint\" enum=\"anchor\"\n\t   summary=\"anchor\"/>\n    </request>\n\n    <enum name=\"gravity\">\n      <entry name=\"none\" value=\"0\"/>\n      <entry name=\"top\" value=\"1\"/>\n      <entry name=\"bottom\" value=\"2\"/>\n      <entry name=\"left\" value=\"3\"/>\n      <entry name=\"right\" value=\"4\"/>\n      <entry name=\"top_left\" value=\"5\"/>\n      <entry name=\"bottom_left\" value=\"6\"/>\n      <entry name=\"top_right\" value=\"7\"/>\n      <entry name=\"bottom_right\" value=\"8\"/>\n    </enum>\n\n    <request name=\"set_gravity\">\n      <description summary=\"set child surface gravity\">\n\tDefines in what direction a surface should be positioned, relative to\n\tthe anchor point of the parent surface. If a corner gravity is\n\tspecified (e.g. 'bottom_right' or 'top_left'), then the child surface\n\twill be placed towards the specified gravity; otherwise, the child\n\tsurface will be centered over the anchor point on any axis that had no\n\tgravity specified. If the gravity is not in the ‘gravity’ enum, an\n\tinvalid_input error is raised.\n      </description>\n      <arg name=\"gravity\" type=\"uint\" enum=\"gravity\"\n\t   summary=\"gravity direction\"/>\n    </request>\n\n    <enum name=\"constraint_adjustment\" bitfield=\"true\">\n      <description summary=\"constraint adjustments\">\n\tThe constraint adjustment value define ways the compositor will adjust\n\tthe position of the surface, if the unadjusted position would result\n\tin the surface being partly constrained.\n\n\tWhether a surface is considered 'constrained' is left to the compositor\n\tto determine. For example, the surface may be partly outside the\n\tcompositor's defined 'work area', thus necessitating the child surface's\n\tposition be adjusted until it is entirely inside the work area.\n\n\tThe adjustments can be combined, according to a defined precedence: 1)\n\tFlip, 2) Slide, 3) Resize.\n      </description>\n      <entry name=\"none\" value=\"0\">\n\t<description summary=\"don't move the child surface when constrained\">\n\t  Don't alter the surface position even if it is constrained on some\n\t  axis, for example partially outside the edge of an output.\n\t</description>\n      </entry>\n      <entry name=\"slide_x\" value=\"1\">\n\t<description summary=\"move along the x axis until unconstrained\">\n\t  Slide the surface along the x axis until it is no longer constrained.\n\n\t  First try to slide towards the direction of the gravity on the x axis\n\t  until either the edge in the opposite direction of the gravity is\n\t  unconstrained or the edge in the direction of the gravity is\n\t  constrained.\n\n\t  Then try to slide towards the opposite direction of the gravity on the\n\t  x axis until either the edge in the direction of the gravity is\n\t  unconstrained or the edge in the opposite direction of the gravity is\n\t  constrained.\n\t</description>\n      </entry>\n      <entry name=\"slide_y\" value=\"2\">\n\t<description summary=\"move along the y axis until unconstrained\">\n\t  Slide the surface along the y axis until it is no longer constrained.\n\n\t  First try to slide towards the direction of the gravity on the y axis\n\t  until either the edge in the opposite direction of the gravity is\n\t  unconstrained or the edge in the direction of the gravity is\n\t  constrained.\n\n\t  Then try to slide towards the opposite direction of the gravity on the\n\t  y axis until either the edge in the direction of the gravity is\n\t  unconstrained or the edge in the opposite direction of the gravity is\n\t  constrained.\n\t</description>\n      </entry>\n      <entry name=\"flip_x\" value=\"4\">\n\t<description summary=\"invert the anchor and gravity on the x axis\">\n\t  Invert the anchor and gravity on the x axis if the surface is\n\t  constrained on the x axis. For example, if the left edge of the\n\t  surface is constrained, the gravity is 'left' and the anchor is\n\t  'left', change the gravity to 'right' and the anchor to 'right'.\n\n\t  If the adjusted position also ends up being constrained, the resulting\n\t  position of the flip_x adjustment will be the one before the\n\t  adjustment.\n\t</description>\n      </entry>\n      <entry name=\"flip_y\" value=\"8\">\n\t<description summary=\"invert the anchor and gravity on the y axis\">\n\t  Invert the anchor and gravity on the y axis if the surface is\n\t  constrained on the y axis. For example, if the bottom edge of the\n\t  surface is constrained, the gravity is 'bottom' and the anchor is\n\t  'bottom', change the gravity to 'top' and the anchor to 'top'.\n\n\t  The adjusted position is calculated given the original anchor\n\t  rectangle and offset, but with the new flipped anchor and gravity\n\t  values.\n\n\t  If the adjusted position also ends up being constrained, the resulting\n\t  position of the flip_y adjustment will be the one before the\n\t  adjustment.\n\t</description>\n      </entry>\n      <entry name=\"resize_x\" value=\"16\">\n\t<description summary=\"horizontally resize the surface\">\n\t  Resize the surface horizontally so that it is completely\n\t  unconstrained.\n\t</description>\n      </entry>\n      <entry name=\"resize_y\" value=\"32\">\n\t<description summary=\"vertically resize the surface\">\n\t  Resize the surface vertically so that it is completely unconstrained.\n\t</description>\n      </entry>\n    </enum>\n\n    <request name=\"set_constraint_adjustment\">\n      <description summary=\"set the adjustment to be done when constrained\">\n\tSpecify how the window should be positioned if the originally intended\n\tposition caused the surface to be constrained, meaning at least\n\tpartially outside positioning boundaries set by the compositor. The\n\tadjustment is set by constructing a bitmask describing the adjustment to\n\tbe made when the surface is constrained on that axis.\n\n\tIf no bit for one axis is set, the compositor will assume that the child\n\tsurface should not change its position on that axis when constrained.\n\n\tIf more than one bit for one axis is set, the order of how adjustments\n\tare applied is specified in the corresponding adjustment descriptions.\n\n\tThe default adjustment is none.\n      </description>\n      <arg name=\"constraint_adjustment\" type=\"uint\" enum=\"constraint_adjustment\"\n\t   summary=\"bit mask of constraint adjustments\"/>\n    </request>\n\n    <request name=\"set_offset\">\n      <description summary=\"set surface position offset\">\n\tSpecify the surface position offset relative to the position of the\n\tanchor on the anchor rectangle and the anchor on the surface. For\n\texample if the anchor of the anchor rectangle is at (x, y), the surface\n\thas the gravity bottom|right, and the offset is (ox, oy), the calculated\n\tsurface position will be (x + ox, y + oy). The offset position of the\n\tsurface is the one used for constraint testing. See\n\tset_constraint_adjustment.\n\n\tAn example use case is placing a popup menu on top of a user interface\n\telement, while aligning the user interface element of the parent surface\n\twith some user interface element placed somewhere in the popup surface.\n      </description>\n      <arg name=\"x\" type=\"int\" summary=\"surface position x offset\"/>\n      <arg name=\"y\" type=\"int\" summary=\"surface position y offset\"/>\n    </request>\n\n    <!-- Version 3 additions -->\n\n    <request name=\"set_reactive\" since=\"3\">\n      <description summary=\"continuously reconstrain the surface\">\n\tWhen set reactive, the surface is reconstrained if the conditions used\n\tfor constraining changed, e.g. the parent window moved.\n\n\tIf the conditions changed and the popup was reconstrained, an\n\txdg_popup.configure event is sent with updated geometry, followed by an\n\txdg_surface.configure event.\n      </description>\n    </request>\n\n    <request name=\"set_parent_size\" since=\"3\">\n      <description summary=\"\">\n\tSet the parent window geometry the compositor should use when\n\tpositioning the popup. The compositor may use this information to\n\tdetermine the future state the popup should be constrained using. If\n\tthis doesn't match the dimension of the parent the popup is eventually\n\tpositioned against, the behavior is undefined.\n\n\tThe arguments are given in the surface-local coordinate space.\n      </description>\n      <arg name=\"parent_width\" type=\"int\"\n\t   summary=\"future window geometry width of parent\"/>\n      <arg name=\"parent_height\" type=\"int\"\n\t   summary=\"future window geometry height of parent\"/>\n    </request>\n\n    <request name=\"set_parent_configure\" since=\"3\">\n      <description summary=\"set parent configure this is a response to\">\n\tSet the serial of an xdg_surface.configure event this positioner will be\n\tused in response to. The compositor may use this information together\n\twith set_parent_size to determine what future state the popup should be\n\tconstrained using.\n      </description>\n      <arg name=\"serial\" type=\"uint\"\n\t   summary=\"serial of parent configure event\"/>\n    </request>\n  </interface>\n\n  <interface name=\"xdg_surface\" version=\"6\">\n    <description summary=\"desktop user interface surface base interface\">\n      An interface that may be implemented by a wl_surface, for\n      implementations that provide a desktop-style user interface.\n\n      It provides a base set of functionality required to construct user\n      interface elements requiring management by the compositor, such as\n      toplevel windows, menus, etc. The types of functionality are split into\n      xdg_surface roles.\n\n      Creating an xdg_surface does not set the role for a wl_surface. In order\n      to map an xdg_surface, the client must create a role-specific object\n      using, e.g., get_toplevel, get_popup. The wl_surface for any given\n      xdg_surface can have at most one role, and may not be assigned any role\n      not based on xdg_surface.\n\n      A role must be assigned before any other requests are made to the\n      xdg_surface object.\n\n      The client must call wl_surface.commit on the corresponding wl_surface\n      for the xdg_surface state to take effect.\n\n      Creating an xdg_surface from a wl_surface which has a buffer attached or\n      committed is a client error, and any attempts by a client to attach or\n      manipulate a buffer prior to the first xdg_surface.configure call must\n      also be treated as errors.\n\n      After creating a role-specific object and setting it up (e.g. by sending\n      the title, app ID, size constraints, parent, etc), the client must\n      perform an initial commit without any buffer attached. The compositor\n      will reply with initial wl_surface state such as\n      wl_surface.preferred_buffer_scale followed by an xdg_surface.configure\n      event. The client must acknowledge it and is then allowed to attach a\n      buffer to map the surface.\n\n      Mapping an xdg_surface-based role surface is defined as making it\n      possible for the surface to be shown by the compositor. Note that\n      a mapped surface is not guaranteed to be visible once it is mapped.\n\n      For an xdg_surface to be mapped by the compositor, the following\n      conditions must be met:\n      (1) the client has assigned an xdg_surface-based role to the surface\n      (2) the client has set and committed the xdg_surface state and the\n\t  role-dependent state to the surface\n      (3) the client has committed a buffer to the surface\n\n      A newly-unmapped surface is considered to have met condition (1) out\n      of the 3 required conditions for mapping a surface if its role surface\n      has not been destroyed, i.e. the client must perform the initial commit\n      again before attaching a buffer.\n    </description>\n\n    <enum name=\"error\">\n      <entry name=\"not_constructed\" value=\"1\"\n\t     summary=\"Surface was not fully constructed\"/>\n      <entry name=\"already_constructed\" value=\"2\"\n\t     summary=\"Surface was already constructed\"/>\n      <entry name=\"unconfigured_buffer\" value=\"3\"\n\t     summary=\"Attaching a buffer to an unconfigured surface\"/>\n      <entry name=\"invalid_serial\" value=\"4\"\n\t     summary=\"Invalid serial number when acking a configure event\"/>\n      <entry name=\"invalid_size\" value=\"5\"\n\t     summary=\"Width or height was zero or negative\"/>\n      <entry name=\"defunct_role_object\" value=\"6\"\n\t     summary=\"Surface was destroyed before its role object\"/>\n    </enum>\n\n    <request name=\"destroy\" type=\"destructor\">\n      <description summary=\"destroy the xdg_surface\">\n\tDestroy the xdg_surface object. An xdg_surface must only be destroyed\n\tafter its role object has been destroyed, otherwise\n\ta defunct_role_object error is raised.\n      </description>\n    </request>\n\n    <request name=\"get_toplevel\">\n      <description summary=\"assign the xdg_toplevel surface role\">\n\tThis creates an xdg_toplevel object for the given xdg_surface and gives\n\tthe associated wl_surface the xdg_toplevel role.\n\n\tSee the documentation of xdg_toplevel for more details about what an\n\txdg_toplevel is and how it is used.\n      </description>\n      <arg name=\"id\" type=\"new_id\" interface=\"xdg_toplevel\"/>\n    </request>\n\n    <request name=\"get_popup\">\n      <description summary=\"assign the xdg_popup surface role\">\n\tThis creates an xdg_popup object for the given xdg_surface and gives\n\tthe associated wl_surface the xdg_popup role.\n\n\tIf null is passed as a parent, a parent surface must be specified using\n\tsome other protocol, before committing the initial state.\n\n\tSee the documentation of xdg_popup for more details about what an\n\txdg_popup is and how it is used.\n      </description>\n      <arg name=\"id\" type=\"new_id\" interface=\"xdg_popup\"/>\n      <arg name=\"parent\" type=\"object\" interface=\"xdg_surface\" allow-null=\"true\"/>\n      <arg name=\"positioner\" type=\"object\" interface=\"xdg_positioner\"/>\n    </request>\n\n    <request name=\"set_window_geometry\">\n      <description summary=\"set the new window geometry\">\n\tThe window geometry of a surface is its \"visible bounds\" from the\n\tuser's perspective. Client-side decorations often have invisible\n\tportions like drop-shadows which should be ignored for the\n\tpurposes of aligning, placing and constraining windows.\n\n\tThe window geometry is double-buffered state, see wl_surface.commit.\n\n\tWhen maintaining a position, the compositor should treat the (x, y)\n\tcoordinate of the window geometry as the top left corner of the window.\n\tA client changing the (x, y) window geometry coordinate should in\n\tgeneral not alter the position of the window.\n\n\tOnce the window geometry of the surface is set, it is not possible to\n\tunset it, and it will remain the same until set_window_geometry is\n\tcalled again, even if a new subsurface or buffer is attached.\n\n\tIf never set, the value is the full bounds of the surface,\n\tincluding any subsurfaces. This updates dynamically on every\n\tcommit. This unset is meant for extremely simple clients.\n\n\tThe arguments are given in the surface-local coordinate space of\n\tthe wl_surface associated with this xdg_surface, and may extend outside\n\tof the wl_surface itself to mark parts of the subsurface tree as part of\n\tthe window geometry.\n\n\tWhen applied, the effective window geometry will be the set window\n\tgeometry clamped to the bounding rectangle of the combined\n\tgeometry of the surface of the xdg_surface and the associated\n\tsubsurfaces.\n\n\tThe effective geometry will not be recalculated unless a new call to\n\tset_window_geometry is done and the new pending surface state is\n\tsubsequently applied.\n\n\tThe width and height of the effective window geometry must be\n\tgreater than zero. Setting an invalid size will raise an\n\tinvalid_size error.\n      </description>\n      <arg name=\"x\" type=\"int\"/>\n      <arg name=\"y\" type=\"int\"/>\n      <arg name=\"width\" type=\"int\"/>\n      <arg name=\"height\" type=\"int\"/>\n    </request>\n\n    <request name=\"ack_configure\">\n      <description summary=\"ack a configure event\">\n\tWhen a configure event is received, if a client commits the\n\tsurface in response to the configure event, then the client\n\tmust make an ack_configure request sometime before the commit\n\trequest, passing along the serial of the configure event.\n\n\tFor instance, for toplevel surfaces the compositor might use this\n\tinformation to move a surface to the top left only when the client has\n\tdrawn itself for the maximized or fullscreen state.\n\n\tIf the client receives multiple configure events before it\n\tcan respond to one, it only has to ack the last configure event.\n\tAcking a configure event that was never sent raises an invalid_serial\n\terror.\n\n\tA client is not required to commit immediately after sending\n\tan ack_configure request - it may even ack_configure several times\n\tbefore its next surface commit.\n\n\tA client may send multiple ack_configure requests before committing, but\n\tonly the last request sent before a commit indicates which configure\n\tevent the client really is responding to.\n\n\tSending an ack_configure request consumes the serial number sent with\n\tthe request, as well as serial numbers sent by all configure events\n\tsent on this xdg_surface prior to the configure event referenced by\n\tthe committed serial.\n\n\tIt is an error to issue multiple ack_configure requests referencing a\n\tserial from the same configure event, or to issue an ack_configure\n\trequest referencing a serial from a configure event issued before the\n\tevent identified by the last ack_configure request for the same\n\txdg_surface. Doing so will raise an invalid_serial error.\n      </description>\n      <arg name=\"serial\" type=\"uint\" summary=\"the serial from the configure event\"/>\n    </request>\n\n    <event name=\"configure\">\n      <description summary=\"suggest a surface change\">\n\tThe configure event marks the end of a configure sequence. A configure\n\tsequence is a set of one or more events configuring the state of the\n\txdg_surface, including the final xdg_surface.configure event.\n\n\tWhere applicable, xdg_surface surface roles will during a configure\n\tsequence extend this event as a latched state sent as events before the\n\txdg_surface.configure event. Such events should be considered to make up\n\ta set of atomically applied configuration states, where the\n\txdg_surface.configure commits the accumulated state.\n\n\tClients should arrange their surface for the new states, and then send\n\tan ack_configure request with the serial sent in this configure event at\n\tsome point before committing the new surface.\n\n\tIf the client receives multiple configure events before it can respond\n\tto one, it is free to discard all but the last event it received.\n      </description>\n      <arg name=\"serial\" type=\"uint\" summary=\"serial of the configure event\"/>\n    </event>\n\n  </interface>\n\n  <interface name=\"xdg_toplevel\" version=\"6\">\n    <description summary=\"toplevel surface\">\n      This interface defines an xdg_surface role which allows a surface to,\n      among other things, set window-like properties such as maximize,\n      fullscreen, and minimize, set application-specific metadata like title and\n      id, and well as trigger user interactive operations such as interactive\n      resize and move.\n\n      A xdg_toplevel by default is responsible for providing the full intended\n      visual representation of the toplevel, which depending on the window\n      state, may mean things like a title bar, window controls and drop shadow.\n\n      Unmapping an xdg_toplevel means that the surface cannot be shown\n      by the compositor until it is explicitly mapped again.\n      All active operations (e.g., move, resize) are canceled and all\n      attributes (e.g. title, state, stacking, ...) are discarded for\n      an xdg_toplevel surface when it is unmapped. The xdg_toplevel returns to\n      the state it had right after xdg_surface.get_toplevel. The client\n      can re-map the toplevel by performing a commit without any buffer\n      attached, waiting for a configure event and handling it as usual (see\n      xdg_surface description).\n\n      Attaching a null buffer to a toplevel unmaps the surface.\n    </description>\n\n    <request name=\"destroy\" type=\"destructor\">\n      <description summary=\"destroy the xdg_toplevel\">\n\tThis request destroys the role surface and unmaps the surface;\n\tsee \"Unmapping\" behavior in interface section for details.\n      </description>\n    </request>\n\n    <enum name=\"error\">\n      <entry name=\"invalid_resize_edge\" value=\"0\" summary=\"provided value is\n        not a valid variant of the resize_edge enum\"/>\n      <entry name=\"invalid_parent\" value=\"1\"\n        summary=\"invalid parent toplevel\"/>\n      <entry name=\"invalid_size\" value=\"2\"\n\tsummary=\"client provided an invalid min or max size\"/>\n    </enum>\n\n    <request name=\"set_parent\">\n      <description summary=\"set the parent of this surface\">\n\tSet the \"parent\" of this surface. This surface should be stacked\n\tabove the parent surface and all other ancestor surfaces.\n\n\tParent surfaces should be set on dialogs, toolboxes, or other\n\t\"auxiliary\" surfaces, so that the parent is raised when the dialog\n\tis raised.\n\n\tSetting a null parent for a child surface unsets its parent. Setting\n\ta null parent for a surface which currently has no parent is a no-op.\n\n\tOnly mapped surfaces can have child surfaces. Setting a parent which\n\tis not mapped is equivalent to setting a null parent. If a surface\n\tbecomes unmapped, its children's parent is set to the parent of\n\tthe now-unmapped surface. If the now-unmapped surface has no parent,\n\tits children's parent is unset. If the now-unmapped surface becomes\n\tmapped again, its parent-child relationship is not restored.\n\n\tThe parent toplevel must not be one of the child toplevel's\n\tdescendants, and the parent must be different from the child toplevel,\n\totherwise the invalid_parent protocol error is raised.\n      </description>\n      <arg name=\"parent\" type=\"object\" interface=\"xdg_toplevel\" allow-null=\"true\"/>\n    </request>\n\n    <request name=\"set_title\">\n      <description summary=\"set surface title\">\n\tSet a short title for the surface.\n\n\tThis string may be used to identify the surface in a task bar,\n\twindow list, or other user interface elements provided by the\n\tcompositor.\n\n\tThe string must be encoded in UTF-8.\n      </description>\n      <arg name=\"title\" type=\"string\"/>\n    </request>\n\n    <request name=\"set_app_id\">\n      <description summary=\"set application ID\">\n\tSet an application identifier for the surface.\n\n\tThe app ID identifies the general class of applications to which\n\tthe surface belongs. The compositor can use this to group multiple\n\tsurfaces together, or to determine how to launch a new application.\n\n\tFor D-Bus activatable applications, the app ID is used as the D-Bus\n\tservice name.\n\n\tThe compositor shell will try to group application surfaces together\n\tby their app ID. As a best practice, it is suggested to select app\n\tID's that match the basename of the application's .desktop file.\n\tFor example, \"org.freedesktop.FooViewer\" where the .desktop file is\n\t\"org.freedesktop.FooViewer.desktop\".\n\n\tLike other properties, a set_app_id request can be sent after the\n\txdg_toplevel has been mapped to update the property.\n\n\tSee the desktop-entry specification [0] for more details on\n\tapplication identifiers and how they relate to well-known D-Bus\n\tnames and .desktop files.\n\n\t[0] https://standards.freedesktop.org/desktop-entry-spec/\n      </description>\n      <arg name=\"app_id\" type=\"string\"/>\n    </request>\n\n    <request name=\"show_window_menu\">\n      <description summary=\"show the window menu\">\n\tClients implementing client-side decorations might want to show\n\ta context menu when right-clicking on the decorations, giving the\n\tuser a menu that they can use to maximize or minimize the window.\n\n\tThis request asks the compositor to pop up such a window menu at\n\tthe given position, relative to the local surface coordinates of\n\tthe parent surface. There are no guarantees as to what menu items\n\tthe window menu contains, or even if a window menu will be drawn\n\tat all.\n\n\tThis request must be used in response to some sort of user action\n\tlike a button press, key press, or touch down event.\n      </description>\n      <arg name=\"seat\" type=\"object\" interface=\"wl_seat\" summary=\"the wl_seat of the user event\"/>\n      <arg name=\"serial\" type=\"uint\" summary=\"the serial of the user event\"/>\n      <arg name=\"x\" type=\"int\" summary=\"the x position to pop up the window menu at\"/>\n      <arg name=\"y\" type=\"int\" summary=\"the y position to pop up the window menu at\"/>\n    </request>\n\n    <request name=\"move\">\n      <description summary=\"start an interactive move\">\n\tStart an interactive, user-driven move of the surface.\n\n\tThis request must be used in response to some sort of user action\n\tlike a button press, key press, or touch down event. The passed\n\tserial is used to determine the type of interactive move (touch,\n\tpointer, etc).\n\n\tThe server may ignore move requests depending on the state of\n\tthe surface (e.g. fullscreen or maximized), or if the passed serial\n\tis no longer valid.\n\n\tIf triggered, the surface will lose the focus of the device\n\t(wl_pointer, wl_touch, etc) used for the move. It is up to the\n\tcompositor to visually indicate that the move is taking place, such as\n\tupdating a pointer cursor, during the move. There is no guarantee\n\tthat the device focus will return when the move is completed.\n      </description>\n      <arg name=\"seat\" type=\"object\" interface=\"wl_seat\" summary=\"the wl_seat of the user event\"/>\n      <arg name=\"serial\" type=\"uint\" summary=\"the serial of the user event\"/>\n    </request>\n\n    <enum name=\"resize_edge\">\n      <description summary=\"edge values for resizing\">\n\tThese values are used to indicate which edge of a surface\n\tis being dragged in a resize operation.\n      </description>\n      <entry name=\"none\" value=\"0\"/>\n      <entry name=\"top\" value=\"1\"/>\n      <entry name=\"bottom\" value=\"2\"/>\n      <entry name=\"left\" value=\"4\"/>\n      <entry name=\"top_left\" value=\"5\"/>\n      <entry name=\"bottom_left\" value=\"6\"/>\n      <entry name=\"right\" value=\"8\"/>\n      <entry name=\"top_right\" value=\"9\"/>\n      <entry name=\"bottom_right\" value=\"10\"/>\n    </enum>\n\n    <request name=\"resize\">\n      <description summary=\"start an interactive resize\">\n\tStart a user-driven, interactive resize of the surface.\n\n\tThis request must be used in response to some sort of user action\n\tlike a button press, key press, or touch down event. The passed\n\tserial is used to determine the type of interactive resize (touch,\n\tpointer, etc).\n\n\tThe server may ignore resize requests depending on the state of\n\tthe surface (e.g. fullscreen or maximized).\n\n\tIf triggered, the client will receive configure events with the\n\t\"resize\" state enum value and the expected sizes. See the \"resize\"\n\tenum value for more details about what is required. The client\n\tmust also acknowledge configure events using \"ack_configure\". After\n\tthe resize is completed, the client will receive another \"configure\"\n\tevent without the resize state.\n\n\tIf triggered, the surface also will lose the focus of the device\n\t(wl_pointer, wl_touch, etc) used for the resize. It is up to the\n\tcompositor to visually indicate that the resize is taking place,\n\tsuch as updating a pointer cursor, during the resize. There is no\n\tguarantee that the device focus will return when the resize is\n\tcompleted.\n\n\tThe edges parameter specifies how the surface should be resized, and\n\tis one of the values of the resize_edge enum. Values not matching\n\ta variant of the enum will cause the invalid_resize_edge protocol error.\n\tThe compositor may use this information to update the surface position\n\tfor example when dragging the top left corner. The compositor may also\n\tuse this information to adapt its behavior, e.g. choose an appropriate\n\tcursor image.\n      </description>\n      <arg name=\"seat\" type=\"object\" interface=\"wl_seat\" summary=\"the wl_seat of the user event\"/>\n      <arg name=\"serial\" type=\"uint\" summary=\"the serial of the user event\"/>\n      <arg name=\"edges\" type=\"uint\" enum=\"resize_edge\" summary=\"which edge or corner is being dragged\"/>\n    </request>\n\n    <enum name=\"state\">\n      <description summary=\"types of state on the surface\">\n\tThe different state values used on the surface. This is designed for\n\tstate values like maximized, fullscreen. It is paired with the\n\tconfigure event to ensure that both the client and the compositor\n\tsetting the state can be synchronized.\n\n\tStates set in this way are double-buffered, see wl_surface.commit.\n      </description>\n      <entry name=\"maximized\" value=\"1\" summary=\"the surface is maximized\">\n\t<description summary=\"the surface is maximized\">\n\t  The surface is maximized. The window geometry specified in the configure\n\t  event must be obeyed by the client, or the xdg_wm_base.invalid_surface_state\n\t  error is raised.\n\n\t  The client should draw without shadow or other\n\t  decoration outside of the window geometry.\n\t</description>\n      </entry>\n      <entry name=\"fullscreen\" value=\"2\" summary=\"the surface is fullscreen\">\n\t<description summary=\"the surface is fullscreen\">\n\t  The surface is fullscreen. The window geometry specified in the\n\t  configure event is a maximum; the client cannot resize beyond it. For\n\t  a surface to cover the whole fullscreened area, the geometry\n\t  dimensions must be obeyed by the client. For more details, see\n\t  xdg_toplevel.set_fullscreen.\n\t</description>\n      </entry>\n      <entry name=\"resizing\" value=\"3\" summary=\"the surface is being resized\">\n\t<description summary=\"the surface is being resized\">\n\t  The surface is being resized. The window geometry specified in the\n\t  configure event is a maximum; the client cannot resize beyond it.\n\t  Clients that have aspect ratio or cell sizing configuration can use\n\t  a smaller size, however.\n\t</description>\n      </entry>\n      <entry name=\"activated\" value=\"4\" summary=\"the surface is now activated\">\n\t<description summary=\"the surface is now activated\">\n\t  Client window decorations should be painted as if the window is\n\t  active. Do not assume this means that the window actually has\n\t  keyboard or pointer focus.\n\t</description>\n      </entry>\n      <entry name=\"tiled_left\" value=\"5\" since=\"2\">\n\t<description summary=\"the surface’s left edge is tiled\">\n\t  The window is currently in a tiled layout and the left edge is\n\t  considered to be adjacent to another part of the tiling grid.\n\n\t  The client should draw without shadow or other decoration outside of\n\t  the window geometry on the left edge.\n\t</description>\n      </entry>\n      <entry name=\"tiled_right\" value=\"6\" since=\"2\">\n\t<description summary=\"the surface’s right edge is tiled\">\n\t  The window is currently in a tiled layout and the right edge is\n\t  considered to be adjacent to another part of the tiling grid.\n\n\t  The client should draw without shadow or other decoration outside of\n\t  the window geometry on the right edge.\n\t</description>\n      </entry>\n      <entry name=\"tiled_top\" value=\"7\" since=\"2\">\n\t<description summary=\"the surface’s top edge is tiled\">\n\t  The window is currently in a tiled layout and the top edge is\n\t  considered to be adjacent to another part of the tiling grid.\n\n\t  The client should draw without shadow or other decoration outside of\n\t  the window geometry on the top edge.\n\t</description>\n      </entry>\n      <entry name=\"tiled_bottom\" value=\"8\" since=\"2\">\n\t<description summary=\"the surface’s bottom edge is tiled\">\n\t  The window is currently in a tiled layout and the bottom edge is\n\t  considered to be adjacent to another part of the tiling grid.\n\n\t  The client should draw without shadow or other decoration outside of\n\t  the window geometry on the bottom edge.\n\t</description>\n      </entry>\n      <entry name=\"suspended\" value=\"9\" since=\"6\">\n        <description summary=\"surface repaint is suspended\">\n\t  The surface is currently not ordinarily being repainted; for\n\t  example because its content is occluded by another window, or its\n\t  outputs are switched off due to screen locking.\n\t</description>\n      </entry>\n    </enum>\n\n    <request name=\"set_max_size\">\n      <description summary=\"set the maximum size\">\n\tSet a maximum size for the window.\n\n\tThe client can specify a maximum size so that the compositor does\n\tnot try to configure the window beyond this size.\n\n\tThe width and height arguments are in window geometry coordinates.\n\tSee xdg_surface.set_window_geometry.\n\n\tValues set in this way are double-buffered, see wl_surface.commit.\n\n\tThe compositor can use this information to allow or disallow\n\tdifferent states like maximize or fullscreen and draw accurate\n\tanimations.\n\n\tSimilarly, a tiling window manager may use this information to\n\tplace and resize client windows in a more effective way.\n\n\tThe client should not rely on the compositor to obey the maximum\n\tsize. The compositor may decide to ignore the values set by the\n\tclient and request a larger size.\n\n\tIf never set, or a value of zero in the request, means that the\n\tclient has no expected maximum size in the given dimension.\n\tAs a result, a client wishing to reset the maximum size\n\tto an unspecified state can use zero for width and height in the\n\trequest.\n\n\tRequesting a maximum size to be smaller than the minimum size of\n\ta surface is illegal and will result in an invalid_size error.\n\n\tThe width and height must be greater than or equal to zero. Using\n\tstrictly negative values for width or height will result in a\n\tinvalid_size error.\n      </description>\n      <arg name=\"width\" type=\"int\"/>\n      <arg name=\"height\" type=\"int\"/>\n    </request>\n\n    <request name=\"set_min_size\">\n      <description summary=\"set the minimum size\">\n\tSet a minimum size for the window.\n\n\tThe client can specify a minimum size so that the compositor does\n\tnot try to configure the window below this size.\n\n\tThe width and height arguments are in window geometry coordinates.\n\tSee xdg_surface.set_window_geometry.\n\n\tValues set in this way are double-buffered, see wl_surface.commit.\n\n\tThe compositor can use this information to allow or disallow\n\tdifferent states like maximize or fullscreen and draw accurate\n\tanimations.\n\n\tSimilarly, a tiling window manager may use this information to\n\tplace and resize client windows in a more effective way.\n\n\tThe client should not rely on the compositor to obey the minimum\n\tsize. The compositor may decide to ignore the values set by the\n\tclient and request a smaller size.\n\n\tIf never set, or a value of zero in the request, means that the\n\tclient has no expected minimum size in the given dimension.\n\tAs a result, a client wishing to reset the minimum size\n\tto an unspecified state can use zero for width and height in the\n\trequest.\n\n\tRequesting a minimum size to be larger than the maximum size of\n\ta surface is illegal and will result in an invalid_size error.\n\n\tThe width and height must be greater than or equal to zero. Using\n\tstrictly negative values for width and height will result in a\n\tinvalid_size error.\n      </description>\n      <arg name=\"width\" type=\"int\"/>\n      <arg name=\"height\" type=\"int\"/>\n    </request>\n\n    <request name=\"set_maximized\">\n      <description summary=\"maximize the window\">\n\tMaximize the surface.\n\n\tAfter requesting that the surface should be maximized, the compositor\n\twill respond by emitting a configure event. Whether this configure\n\tactually sets the window maximized is subject to compositor policies.\n\tThe client must then update its content, drawing in the configured\n\tstate. The client must also acknowledge the configure when committing\n\tthe new content (see ack_configure).\n\n\tIt is up to the compositor to decide how and where to maximize the\n\tsurface, for example which output and what region of the screen should\n\tbe used.\n\n\tIf the surface was already maximized, the compositor will still emit\n\ta configure event with the \"maximized\" state.\n\n\tIf the surface is in a fullscreen state, this request has no direct\n\teffect. It may alter the state the surface is returned to when\n\tunmaximized unless overridden by the compositor.\n      </description>\n    </request>\n\n    <request name=\"unset_maximized\">\n      <description summary=\"unmaximize the window\">\n\tUnmaximize the surface.\n\n\tAfter requesting that the surface should be unmaximized, the compositor\n\twill respond by emitting a configure event. Whether this actually\n\tun-maximizes the window is subject to compositor policies.\n\tIf available and applicable, the compositor will include the window\n\tgeometry dimensions the window had prior to being maximized in the\n\tconfigure event. The client must then update its content, drawing it in\n\tthe configured state. The client must also acknowledge the configure\n\twhen committing the new content (see ack_configure).\n\n\tIt is up to the compositor to position the surface after it was\n\tunmaximized; usually the position the surface had before maximizing, if\n\tapplicable.\n\n\tIf the surface was already not maximized, the compositor will still\n\temit a configure event without the \"maximized\" state.\n\n\tIf the surface is in a fullscreen state, this request has no direct\n\teffect. It may alter the state the surface is returned to when\n\tunmaximized unless overridden by the compositor.\n      </description>\n    </request>\n\n    <request name=\"set_fullscreen\">\n      <description summary=\"set the window as fullscreen on an output\">\n\tMake the surface fullscreen.\n\n\tAfter requesting that the surface should be fullscreened, the\n\tcompositor will respond by emitting a configure event. Whether the\n\tclient is actually put into a fullscreen state is subject to compositor\n\tpolicies. The client must also acknowledge the configure when\n\tcommitting the new content (see ack_configure).\n\n\tThe output passed by the request indicates the client's preference as\n\tto which display it should be set fullscreen on. If this value is NULL,\n\tit's up to the compositor to choose which display will be used to map\n\tthis surface.\n\n\tIf the surface doesn't cover the whole output, the compositor will\n\tposition the surface in the center of the output and compensate with\n\twith border fill covering the rest of the output. The content of the\n\tborder fill is undefined, but should be assumed to be in some way that\n\tattempts to blend into the surrounding area (e.g. solid black).\n\n\tIf the fullscreened surface is not opaque, the compositor must make\n\tsure that other screen content not part of the same surface tree (made\n\tup of subsurfaces, popups or similarly coupled surfaces) are not\n\tvisible below the fullscreened surface.\n      </description>\n      <arg name=\"output\" type=\"object\" interface=\"wl_output\" allow-null=\"true\"/>\n    </request>\n\n    <request name=\"unset_fullscreen\">\n      <description summary=\"unset the window as fullscreen\">\n\tMake the surface no longer fullscreen.\n\n\tAfter requesting that the surface should be unfullscreened, the\n\tcompositor will respond by emitting a configure event.\n\tWhether this actually removes the fullscreen state of the client is\n\tsubject to compositor policies.\n\n\tMaking a surface unfullscreen sets states for the surface based on the following:\n\t* the state(s) it may have had before becoming fullscreen\n\t* any state(s) decided by the compositor\n\t* any state(s) requested by the client while the surface was fullscreen\n\n\tThe compositor may include the previous window geometry dimensions in\n\tthe configure event, if applicable.\n\n\tThe client must also acknowledge the configure when committing the new\n\tcontent (see ack_configure).\n      </description>\n    </request>\n\n    <request name=\"set_minimized\">\n      <description summary=\"set the window as minimized\">\n\tRequest that the compositor minimize your surface. There is no\n\tway to know if the surface is currently minimized, nor is there\n\tany way to unset minimization on this surface.\n\n\tIf you are looking to throttle redrawing when minimized, please\n\tinstead use the wl_surface.frame event for this, as this will\n\talso work with live previews on windows in Alt-Tab, Expose or\n\tsimilar compositor features.\n      </description>\n    </request>\n\n    <event name=\"configure\">\n      <description summary=\"suggest a surface change\">\n\tThis configure event asks the client to resize its toplevel surface or\n\tto change its state. The configured state should not be applied\n\timmediately. See xdg_surface.configure for details.\n\n\tThe width and height arguments specify a hint to the window\n\tabout how its surface should be resized in window geometry\n\tcoordinates. See set_window_geometry.\n\n\tIf the width or height arguments are zero, it means the client\n\tshould decide its own window dimension. This may happen when the\n\tcompositor needs to configure the state of the surface but doesn't\n\thave any information about any previous or expected dimension.\n\n\tThe states listed in the event specify how the width/height\n\targuments should be interpreted, and possibly how it should be\n\tdrawn.\n\n\tClients must send an ack_configure in response to this event. See\n\txdg_surface.configure and xdg_surface.ack_configure for details.\n      </description>\n      <arg name=\"width\" type=\"int\"/>\n      <arg name=\"height\" type=\"int\"/>\n      <arg name=\"states\" type=\"array\"/>\n    </event>\n\n    <event name=\"close\">\n      <description summary=\"surface wants to be closed\">\n\tThe close event is sent by the compositor when the user\n\twants the surface to be closed. This should be equivalent to\n\tthe user clicking the close button in client-side decorations,\n\tif your application has any.\n\n\tThis is only a request that the user intends to close the\n\twindow. The client may choose to ignore this request, or show\n\ta dialog to ask the user to save their data, etc.\n      </description>\n    </event>\n\n    <!-- Version 4 additions -->\n\n    <event name=\"configure_bounds\" since=\"4\">\n      <description summary=\"recommended window geometry bounds\">\n\tThe configure_bounds event may be sent prior to a xdg_toplevel.configure\n\tevent to communicate the bounds a window geometry size is recommended\n\tto constrain to.\n\n\tThe passed width and height are in surface coordinate space. If width\n\tand height are 0, it means bounds is unknown and equivalent to as if no\n\tconfigure_bounds event was ever sent for this surface.\n\n\tThe bounds can for example correspond to the size of a monitor excluding\n\tany panels or other shell components, so that a surface isn't created in\n\ta way that it cannot fit.\n\n\tThe bounds may change at any point, and in such a case, a new\n\txdg_toplevel.configure_bounds will be sent, followed by\n\txdg_toplevel.configure and xdg_surface.configure.\n      </description>\n      <arg name=\"width\" type=\"int\"/>\n      <arg name=\"height\" type=\"int\"/>\n    </event>\n\n    <!-- Version 5 additions -->\n\n    <enum name=\"wm_capabilities\" since=\"5\">\n      <entry name=\"window_menu\" value=\"1\" summary=\"show_window_menu is available\"/>\n      <entry name=\"maximize\" value=\"2\" summary=\"set_maximized and unset_maximized are available\"/>\n      <entry name=\"fullscreen\" value=\"3\" summary=\"set_fullscreen and unset_fullscreen are available\"/>\n      <entry name=\"minimize\" value=\"4\" summary=\"set_minimized is available\"/>\n    </enum>\n\n    <event name=\"wm_capabilities\" since=\"5\">\n      <description summary=\"compositor capabilities\">\n\tThis event advertises the capabilities supported by the compositor. If\n\ta capability isn't supported, clients should hide or disable the UI\n\telements that expose this functionality. For instance, if the\n\tcompositor doesn't advertise support for minimized toplevels, a button\n\ttriggering the set_minimized request should not be displayed.\n\n\tThe compositor will ignore requests it doesn't support. For instance,\n\ta compositor which doesn't advertise support for minimized will ignore\n\tset_minimized requests.\n\n\tCompositors must send this event once before the first\n\txdg_surface.configure event. When the capabilities change, compositors\n\tmust send this event again and then send an xdg_surface.configure\n\tevent.\n\n\tThe configured state should not be applied immediately. See\n\txdg_surface.configure for details.\n\n\tThe capabilities are sent as an array of 32-bit unsigned integers in\n\tnative endianness.\n      </description>\n      <arg name=\"capabilities\" type=\"array\" summary=\"array of 32-bit capabilities\"/>\n    </event>\n  </interface>\n\n  <interface name=\"xdg_popup\" version=\"6\">\n    <description summary=\"short-lived, popup surfaces for menus\">\n      A popup surface is a short-lived, temporary surface. It can be used to\n      implement for example menus, popovers, tooltips and other similar user\n      interface concepts.\n\n      A popup can be made to take an explicit grab. See xdg_popup.grab for\n      details.\n\n      When the popup is dismissed, a popup_done event will be sent out, and at\n      the same time the surface will be unmapped. See the xdg_popup.popup_done\n      event for details.\n\n      Explicitly destroying the xdg_popup object will also dismiss the popup and\n      unmap the surface. Clients that want to dismiss the popup when another\n      surface of their own is clicked should dismiss the popup using the destroy\n      request.\n\n      A newly created xdg_popup will be stacked on top of all previously created\n      xdg_popup surfaces associated with the same xdg_toplevel.\n\n      The parent of an xdg_popup must be mapped (see the xdg_surface\n      description) before the xdg_popup itself.\n\n      The client must call wl_surface.commit on the corresponding wl_surface\n      for the xdg_popup state to take effect.\n    </description>\n\n    <enum name=\"error\">\n      <entry name=\"invalid_grab\" value=\"0\"\n\t     summary=\"tried to grab after being mapped\"/>\n    </enum>\n\n    <request name=\"destroy\" type=\"destructor\">\n      <description summary=\"remove xdg_popup interface\">\n\tThis destroys the popup. Explicitly destroying the xdg_popup\n\tobject will also dismiss the popup, and unmap the surface.\n\n\tIf this xdg_popup is not the \"topmost\" popup, the\n\txdg_wm_base.not_the_topmost_popup protocol error will be sent.\n      </description>\n    </request>\n\n    <request name=\"grab\">\n      <description summary=\"make the popup take an explicit grab\">\n\tThis request makes the created popup take an explicit grab. An explicit\n\tgrab will be dismissed when the user dismisses the popup, or when the\n\tclient destroys the xdg_popup. This can be done by the user clicking\n\toutside the surface, using the keyboard, or even locking the screen\n\tthrough closing the lid or a timeout.\n\n\tIf the compositor denies the grab, the popup will be immediately\n\tdismissed.\n\n\tThis request must be used in response to some sort of user action like a\n\tbutton press, key press, or touch down event. The serial number of the\n\tevent should be passed as 'serial'.\n\n\tThe parent of a grabbing popup must either be an xdg_toplevel surface or\n\tanother xdg_popup with an explicit grab. If the parent is another\n\txdg_popup it means that the popups are nested, with this popup now being\n\tthe topmost popup.\n\n\tNested popups must be destroyed in the reverse order they were created\n\tin, e.g. the only popup you are allowed to destroy at all times is the\n\ttopmost one.\n\n\tWhen compositors choose to dismiss a popup, they may dismiss every\n\tnested grabbing popup as well. When a compositor dismisses popups, it\n\twill follow the same dismissing order as required from the client.\n\n\tIf the topmost grabbing popup is destroyed, the grab will be returned to\n\tthe parent of the popup, if that parent previously had an explicit grab.\n\n\tIf the parent is a grabbing popup which has already been dismissed, this\n\tpopup will be immediately dismissed. If the parent is a popup that did\n\tnot take an explicit grab, an error will be raised.\n\n\tDuring a popup grab, the client owning the grab will receive pointer\n\tand touch events for all their surfaces as normal (similar to an\n\t\"owner-events\" grab in X11 parlance), while the top most grabbing popup\n\twill always have keyboard focus.\n      </description>\n      <arg name=\"seat\" type=\"object\" interface=\"wl_seat\"\n\t   summary=\"the wl_seat of the user event\"/>\n      <arg name=\"serial\" type=\"uint\" summary=\"the serial of the user event\"/>\n    </request>\n\n    <event name=\"configure\">\n      <description summary=\"configure the popup surface\">\n\tThis event asks the popup surface to configure itself given the\n\tconfiguration. The configured state should not be applied immediately.\n\tSee xdg_surface.configure for details.\n\n\tThe x and y arguments represent the position the popup was placed at\n\tgiven the xdg_positioner rule, relative to the upper left corner of the\n\twindow geometry of the parent surface.\n\n\tFor version 2 or older, the configure event for an xdg_popup is only\n\tever sent once for the initial configuration. Starting with version 3,\n\tit may be sent again if the popup is setup with an xdg_positioner with\n\tset_reactive requested, or in response to xdg_popup.reposition requests.\n      </description>\n      <arg name=\"x\" type=\"int\"\n\t   summary=\"x position relative to parent surface window geometry\"/>\n      <arg name=\"y\" type=\"int\"\n\t   summary=\"y position relative to parent surface window geometry\"/>\n      <arg name=\"width\" type=\"int\" summary=\"window geometry width\"/>\n      <arg name=\"height\" type=\"int\" summary=\"window geometry height\"/>\n    </event>\n\n    <event name=\"popup_done\">\n      <description summary=\"popup interaction is done\">\n\tThe popup_done event is sent out when a popup is dismissed by the\n\tcompositor. The client should destroy the xdg_popup object at this\n\tpoint.\n      </description>\n    </event>\n\n    <!-- Version 3 additions -->\n\n    <request name=\"reposition\" since=\"3\">\n      <description summary=\"recalculate the popup's location\">\n\tReposition an already-mapped popup. The popup will be placed given the\n\tdetails in the passed xdg_positioner object, and a\n\txdg_popup.repositioned followed by xdg_popup.configure and\n\txdg_surface.configure will be emitted in response. Any parameters set\n\tby the previous positioner will be discarded.\n\n\tThe passed token will be sent in the corresponding\n\txdg_popup.repositioned event. The new popup position will not take\n\teffect until the corresponding configure event is acknowledged by the\n\tclient. See xdg_popup.repositioned for details. The token itself is\n\topaque, and has no other special meaning.\n\n\tIf multiple reposition requests are sent, the compositor may skip all\n\tbut the last one.\n\n\tIf the popup is repositioned in response to a configure event for its\n\tparent, the client should send an xdg_positioner.set_parent_configure\n\tand possibly an xdg_positioner.set_parent_size request to allow the\n\tcompositor to properly constrain the popup.\n\n\tIf the popup is repositioned together with a parent that is being\n\tresized, but not in response to a configure event, the client should\n\tsend an xdg_positioner.set_parent_size request.\n      </description>\n      <arg name=\"positioner\" type=\"object\" interface=\"xdg_positioner\"/>\n      <arg name=\"token\" type=\"uint\" summary=\"reposition request token\"/>\n    </request>\n\n    <event name=\"repositioned\" since=\"3\">\n      <description summary=\"signal the completion of a repositioned request\">\n\tThe repositioned event is sent as part of a popup configuration\n\tsequence, together with xdg_popup.configure and lastly\n\txdg_surface.configure to notify the completion of a reposition request.\n\n\tThe repositioned event is to notify about the completion of a\n\txdg_popup.reposition request. The token argument is the token passed\n\tin the xdg_popup.reposition request.\n\n\tImmediately after this event is emitted, xdg_popup.configure and\n\txdg_surface.configure will be sent with the updated size and position,\n\tas well as a new configure serial.\n\n\tThe client should optionally update the content of the popup, but must\n\tacknowledge the new popup configuration for the new position to take\n\teffect. See xdg_surface.ack_configure for details.\n      </description>\n      <arg name=\"token\" type=\"uint\" summary=\"reposition request token\"/>\n    </event>\n\n  </interface>\n</protocol>\n"
  },
  {
    "path": "wayland/generate/resources/xwayland-keyboard-grab-unstable-v1.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<protocol name=\"xwayland_keyboard_grab_unstable_v1\">\n\n  <copyright>\n    Copyright © 2017 Red Hat Inc.\n\n    Permission is hereby granted, free of charge, to any person obtaining a\n    copy of this software and associated documentation files (the \"Software\"),\n    to deal in the Software without restriction, including without limitation\n    the rights to use, copy, modify, merge, publish, distribute, sublicense,\n    and/or sell copies of the Software, and to permit persons to whom the\n    Software is furnished to do so, subject to the following conditions:\n\n    The above copyright notice and this permission notice (including the next\n    paragraph) shall be included in all copies or substantial portions of the\n    Software.\n\n    THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL\n    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n    DEALINGS IN THE SOFTWARE.\n  </copyright>\n\n  <description summary=\"Protocol for grabbing the keyboard from Xwayland\">\n    This protocol is application-specific to meet the needs of the X11\n    protocol through Xwayland. It provides a way for Xwayland to request\n    all keyboard events to be forwarded to a surface even when the\n    surface does not have keyboard focus.\n\n    In the X11 protocol, a client may request an \"active grab\" on the\n    keyboard. On success, all key events are reported only to the\n    grabbing X11 client. For details, see XGrabKeyboard(3).\n\n    The core Wayland protocol does not have a notion of an active\n    keyboard grab. When running in Xwayland, X11 applications may\n    acquire an active grab inside Xwayland but that cannot be translated\n    to the Wayland compositor who may set the input focus to some other\n    surface. In doing so, it breaks the X11 client assumption that all\n    key events are reported to the grabbing client.\n\n    This protocol specifies a way for Xwayland to request all keyboard\n    be directed to the given surface. The protocol does not guarantee\n    that the compositor will honor this request and it does not\n    prescribe user interfaces on how to handle the respond. For example,\n    a compositor may inform the user that all key events are now\n    forwarded to the given client surface, or it may ask the user for\n    permission to do so.\n\n    Compositors are required to restrict access to this application\n    specific protocol to Xwayland alone.\n\n    Warning! The protocol described in this file is experimental and\n    backward incompatible changes may be made. Backward compatible\n    changes may be added together with the corresponding interface\n    version bump.\n    Backward incompatible changes are done by bumping the version\n    number in the protocol and interface names and resetting the\n    interface version. Once the protocol is to be declared stable,\n    the 'z' prefix and the version number in the protocol and\n    interface names are removed and the interface version number is\n    reset.\n  </description>\n\n  <interface name=\"zwp_xwayland_keyboard_grab_manager_v1\" version=\"1\">\n    <description summary=\"context object for keyboard grab manager\">\n      A global interface used for grabbing the keyboard.\n    </description>\n\n    <request name=\"destroy\" type=\"destructor\">\n      <description summary=\"destroy the keyboard grab manager\">\n\tDestroy the keyboard grab manager.\n      </description>\n    </request>\n\n    <request name=\"grab_keyboard\">\n      <description summary=\"grab the keyboard to a surface\">\n\tThe grab_keyboard request asks for a grab of the keyboard, forcing\n\tthe keyboard focus for the given seat upon the given surface.\n\n\tThe protocol provides no guarantee that the grab is ever satisfied,\n\tand does not require the compositor to send an error if the grab\n\tcannot ever be satisfied. It is thus possible to request a keyboard\n\tgrab that will never be effective.\n\n\tThe protocol:\n\n\t* does not guarantee that the grab itself is applied for a surface,\n\t  the grab request may be silently ignored by the compositor,\n\t* does not guarantee that any events are sent to this client even\n\t  if the grab is applied to a surface,\n\t* does not guarantee that events sent to this client are exhaustive,\n\t  a compositor may filter some events for its own consumption,\n\t* does not guarantee that events sent to this client are continuous,\n\t  a compositor may change and reroute keyboard events while the grab\n\t  is nominally active.\n      </description>\n\n      <arg name=\"id\" type=\"new_id\" interface=\"zwp_xwayland_keyboard_grab_v1\"/>\n      <arg name=\"surface\" type=\"object\" interface=\"wl_surface\"\n\t   summary=\"surface to report keyboard events to\"/>\n      <arg name=\"seat\" type=\"object\" interface=\"wl_seat\"\n\t   summary=\"the seat for which the keyboard should be grabbed\"/>\n    </request>\n  </interface>\n\n  <interface name=\"zwp_xwayland_keyboard_grab_v1\" version=\"1\">\n    <description summary=\"interface for grabbing the keyboard\">\n      A global interface used for grabbing the keyboard.\n    </description>\n\n    <request name=\"destroy\" type=\"destructor\">\n      <description summary=\"destroy the grabbed keyboard object\">\n\tDestroy the grabbed keyboard object. If applicable, the compositor\n\twill ungrab the keyboard.\n      </description>\n    </request>\n  </interface>\n</protocol>"
  },
  {
    "path": "wayland/generate/resources/xwayland-shell-v1.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<protocol name=\"xwayland_shell_v1\">\n\n  <copyright>\n    Copyright © 2022 Joshua Ashton\n\n    Permission is hereby granted, free of charge, to any person obtaining a\n    copy of this software and associated documentation files (the \"Software\"),\n    to deal in the Software without restriction, including without limitation\n    the rights to use, copy, modify, merge, publish, distribute, sublicense,\n    and/or sell copies of the Software, and to permit persons to whom the\n    Software is furnished to do so, subject to the following conditions:\n\n    The above copyright notice and this permission notice (including the next\n    paragraph) shall be included in all copies or substantial portions of the\n    Software.\n\n    THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL\n    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n    DEALINGS IN THE SOFTWARE.\n  </copyright>\n\n  <description summary=\"Protocol for associating X11 windows to wl_surfaces\">\n    This protocol adds a xwayland_surface role which allows an Xwayland\n    server to associate an X11 window to a wl_surface.\n    \n    Before this protocol, this would be done via the Xwayland server\n    providing the wl_surface's resource id via the a client message with\n    the WL_SURFACE_ID atom on the X window.\n    This was problematic as a race could occur if the wl_surface\n    associated with a WL_SURFACE_ID for a window was destroyed before the\n    client message was processed by the compositor and another surface\n    (or other object) had taken its id due to recycling.\n    \n    This protocol solves the problem by moving the X11 window to wl_surface\n    association step to the Wayland side, which means that the association\n    cannot happen out-of-sync with the resource lifetime of the wl_surface.\n    \n    This protocol avoids duplicating the race on the other side by adding a\n    non-zero monotonic serial number which is entirely unique that is set on\n    both the wl_surface (via. xwayland_surface_v1's set_serial method) and\n    the X11 window (via. the `WL_SURFACE_SERIAL` client message) that can be\n    used to associate them, and synchronize the two timelines.\n\n    The key words \"must\", \"must not\", \"required\", \"shall\", \"shall not\",\n    \"should\", \"should not\", \"recommended\",  \"may\", and \"optional\" in this\n    document are to be interpreted as described in IETF RFC 2119.\n\n    Warning! The protocol described in this file is currently in the testing\n    phase. Backward compatible changes may be added together with the\n    corresponding interface version bump. Backward incompatible changes can\n    only be done by creating a new major version of the extension.\n  </description>\n\n  <interface name=\"xwayland_shell_v1\" version=\"1\">\n    <description summary=\"context object for Xwayland shell\">\n      xwayland_shell_v1 is a singleton global object that\n      provides the ability to create a xwayland_surface_v1 object\n      for a given wl_surface.\n\n      This interface is intended to be bound by the Xwayland server.\n\n      A compositor must not allow clients other than Xwayland to\n      bind to this interface. A compositor should hide this global\n      from other clients' wl_registry.\n      A client the compositor does not consider to be an Xwayland\n      server attempting to bind this interface will result in\n      an implementation-defined error.\n\n      An Xwayland server that has bound this interface must not\n      set the `WL_SURFACE_ID` atom on a window.\n    </description>\n\n    <enum name=\"error\">\n      <entry name=\"role\" value=\"0\" summary=\"given wl_surface has another role\"/>\n    </enum>\n\n    <request name=\"destroy\" type=\"destructor\">\n      <description summary=\"destroy the Xwayland shell object\">\n        Destroy the xwayland_shell_v1 object.\n\n        The child objects created via this interface are unaffected.\n      </description>\n    </request>\n\n    <request name=\"get_xwayland_surface\">\n      <description summary=\"assign the xwayland_surface surface role\">\n        Create an xwayland_surface_v1 interface for a given wl_surface\n        object and gives it the xwayland_surface role.\n        \n        It is illegal to create an xwayland_surface_v1 for a wl_surface\n        which already has an assigned role and this will result in the\n        `role` protocol error.\n\n        See the documentation of xwayland_surface_v1 for more details\n        about what an xwayland_surface_v1 is and how it is used.\n      </description>\n\n      <arg name=\"id\" type=\"new_id\" interface=\"xwayland_surface_v1\"/>\n      <arg name=\"surface\" type=\"object\" interface=\"wl_surface\"/>\n    </request>\n  </interface>\n\n  <interface name=\"xwayland_surface_v1\" version=\"1\">\n    <description summary=\"interface for associating Xwayland windows to wl_surfaces\">\n      An Xwayland surface is a surface managed by an Xwayland server.\n      It is used for associating surfaces to Xwayland windows.\n\n      The Xwayland server associated with actions in this interface is\n      determined by the Wayland client making the request.\n\n      The client must call wl_surface.commit on the corresponding wl_surface\n      for the xwayland_surface_v1 state to take effect.\n    </description>\n\n    <enum name=\"error\">\n      <entry name=\"already_associated\" value=\"0\" summary=\"given wl_surface is already associated with an X11 window\"/>\n      <entry name=\"invalid_serial\" value=\"1\" summary=\"serial was not valid\"/>\n    </enum>\n\n    <request name=\"set_serial\">\n      <description summary=\"associates a Xwayland window to a wl_surface\">\n        Associates an Xwayland window to a wl_surface.\n        The association state is double-buffered, see wl_surface.commit.\n\n        The `serial_lo` and `serial_hi` parameters specify a non-zero\n        monotonic serial number which is entirely unique and provided by the\n        Xwayland server equal to the serial value provided by a client message\n        with a message type of the `WL_SURFACE_SERIAL` atom on the X11 window\n        for this surface to be associated to.\n\n        The serial value in the `WL_SURFACE_SERIAL` client message is specified\n        as having the lo-bits specified in `l[0]` and the hi-bits specified\n        in `l[1]`.\n\n        If the serial value provided by `serial_lo` and `serial_hi` is not\n        valid, the `invalid_serial` protocol error will be raised.\n\n        An X11 window may be associated with multiple surfaces throughout its\n        lifespan. (eg. unmapping and remapping a window).\n        \n        For each wl_surface, this state must not be committed more than once,\n        otherwise the `already_associated` protocol error will be raised.\n      </description>\n      <arg name=\"serial_lo\" type=\"uint\" summary=\"The lower 32-bits of the serial number associated with the X11 window\"/>\n      <arg name=\"serial_hi\" type=\"uint\" summary=\"The upper 32-bits of the serial number associated with the X11 window\"/>\n    </request>\n\n    <request name=\"destroy\" type=\"destructor\">\n      <description summary=\"destroy the Xwayland surface object\">\n        Destroy the xwayland_surface_v1 object.\n\n        Any already existing associations are unaffected by this action.\n      </description>\n    </request>\n  </interface>\n</protocol>"
  },
  {
    "path": "wayland/generate.go",
    "content": "package wayland\n\n//go:generate sh -c \"go run ./generate ./protocols . $(go list) WlSurface XdgPositioner XdgSurface WlPointer WlSubsurface XdgToplevel\"\n"
  },
  {
    "path": "wayland/mmap.c",
    "content": "#include <fcntl.h>\n#include <sys/mman.h>\n#include <unistd.h>\n#include <stdio.h>\n#include <stdbool.h>\n\n\nvoid *mmap_fd(int fd, size_t size)\n{\n    int prot = PROT_READ | PROT_WRITE;\n    int flags = MAP_SHARED;\n    void *addr = mmap(NULL, size, prot, flags, fd, 0);\n    if (addr == MAP_FAILED)\n    {\n        perror(\"mmap\");\n        return MAP_FAILED;\n    }\n\n    return addr;\n}\n\nbool unmap(void* addr, size_t size) {\n\tif (addr != MAP_FAILED) {\n\t\tif (munmap(addr, size) == -1) {\n\t\t\tperror(\"munmap in unmap\");\n            return false;\n\t\t}\n\t}\n    return true;\n}\n\nvoid* remap(int fd, void* addr, size_t size, size_t new_size) {\n \tif (new_size == size)\n    {\n        return addr;\n    }\n    if (addr == MAP_FAILED)\n    {\n        return MAP_FAILED;\n    }\n    bool unmap_success = unmap(addr, size);\n    if (!unmap_success) {\n        return MAP_FAILED;\n    }\n    addr = mmap_fd(fd, new_size);\n    if (addr == MAP_FAILED)\n    {\n        perror(\"mmap in remap\");\n        return MAP_FAILED;\n    }\n    size = new_size;\n    return addr;\n}\n\nvoid* map_failed(void) {\n\treturn MAP_FAILED;\n}"
  },
  {
    "path": "wayland/mmap.h",
    "content": "\n#include <unistd.h>\n#include <stdbool.h>\n\nvoid *mmap_fd(int fd, size_t size);\nbool unmap(void* addr, size_t size);\nvoid* remap(int fd, void* addr, size_t size, size_t new_size);\nvoid* map_failed(void);"
  },
  {
    "path": "wayland/pointerslices/Readme.md",
    "content": "This implements parts of the slices package of the stdlib but for slices that contain pointers, less bugs."
  },
  {
    "path": "wayland/pointerslices/lib.go",
    "content": "package pointerslices\n\nimport \"slices\"\n\nfunc Contains[T comparable](slice []*T, item T) bool {\n\tfor _, s := range slice {\n\t\tif s == nil {\n\t\t\tcontinue\n\t\t}\n\t\tif *s == item {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc DeleteFunc[T any](slice []*T, f func(T) bool) []*T {\n\tfor i, s := range slice {\n\t\tif s == nil {\n\t\t\tcontinue\n\t\t}\n\t\tif f(*s) {\n\t\t\treturn slices.Delete(slice, i, i+1)\n\t\t}\n\t}\n\treturn slice\n}\n\nfunc Index[T comparable](slice []*T, item T) int {\n\tfor i, s := range slice {\n\t\tif s == nil {\n\t\t\tcontinue\n\t\t}\n\t\tif *s == item {\n\t\t\treturn i\n\t\t}\n\t}\n\treturn -1\n}\n\n// Compares for value equality, not pointer equality\n// But will return the index of nil if item is nil and there is a nil in the slice\nfunc IndexOfItemOrNil[T comparable](slice []*T, item *T) int {\n\tfor i, s := range slice {\n\t\tif s == nil && item == nil {\n\t\t\treturn i\n\t\t}\n\t\tif s != nil && item != nil && *s == *item {\n\t\t\treturn i\n\t\t}\n\t}\n\treturn -1\n}\n\nfunc Delete[T any](slice []*T, start, end int) []*T {\n\treturn slices.Delete(slice, start, end)\n}\n\nfunc Insert[T any](slice []*T, index int, values ...*T) []*T {\n\treturn slices.Insert(slice, index, values...)\n}\n"
  },
  {
    "path": "wayland/protocols/GlobalObjects.go",
    "content": "package protocols\n\ntype GlobalID AnyObjectID\ntype Version uint32\n\nconst (\n\tGlobalID_WlDisplay                        GlobalID = 1\n\tGlobalID_WlCompositor                     GlobalID = 0xff00000\n\tGlobalID_WlSubcompositor                  GlobalID = 0xff00001\n\tGlobalID_WlOutput                         GlobalID = 0xff00002\n\tGlobalID_WlSeat                           GlobalID = 0xff00003\n\tGlobalID_WlShm                            GlobalID = 0xff00004\n\tGlobalID_XdgWmBase                        GlobalID = 0xff00005\n\tGlobalID_WlDataDeviceManager              GlobalID = 0xff00006\n\tGlobalID_WlKeyboard                       GlobalID = 0xff00007\n\tGlobalID_WlPointer                        GlobalID = 0xff00008\n\tGlobalID_ZwpXwaylandKeyboardGrabManagerV1 GlobalID = 0xff00009\n\tGlobalID_XwaylandShellV1                  GlobalID = 0xff00011\n\tGlobalID_WlDataDevice                     GlobalID = 0xff00012\n\tGlobalID_WlTouch                          GlobalID = 0xff00013\n\tGlobalID_ZxdgDecorationManagerV1          GlobalID = 0xff00014\n)\n\ntype AdvertisedGlobalObjectName struct {\n\tName    string\n\tId      GlobalID\n\tVersion uint32\n}\n\nvar AdvertisedGlobalObjectNames = []AdvertisedGlobalObjectName{\n\t{\"wl_compositor\", GlobalID_WlCompositor, 6},\n\t/**\n\t * Turning off the wl_subcompositor will turn off\n\t * decorations. Any other side effects??? Looks like\n\t * GameScope has it turned off, so maybe we could do that\n\t * too.\n\t *\n\t * some programs will crash if wl_subcompositor is not\n\t * advertised.\n\t */\n\t{\"wl_subcompositor\", GlobalID_WlSubcompositor, 1},\n\t{\"wl_output\", GlobalID_WlOutput, 5},\n\n\t{\"wl_seat\", GlobalID_WlSeat, 10},\n\t{\"wl_shm\", GlobalID_WlShm, 2},\n\t{\"xdg_wm_base\", GlobalID_XdgWmBase, 6},\n\t{\"wl_data_device_manager\", GlobalID_WlDataDeviceManager, 3},\n\t{\"zxdg_decoration_manager_v1\", GlobalID_ZxdgDecorationManagerV1, 1},\n\t/**\n\t * @TODO only advertise these to Xwayland clients\n\t */\n\t{\"zwp_xwayland_keyboard_grab_manager_v1\", GlobalID_ZwpXwaylandKeyboardGrabManagerV1, 1},\n\t{\"xwayland_shell_v1\", GlobalID_XwaylandShellV1, 1},\n}\n\nfunc GetGlobalWlDisplayBinds(cs ClientState) map[ObjectID[WlDisplay]]Version {\n\n\tv := cs.GetGlobalBinds(GlobalID(GlobalID_WlDisplay))\n\tif v == nil {\n\t\treturn nil\n\t}\n\tm := v.(map[ObjectID[WlDisplay]]Version)\n\treturn m\n}\n\nfunc GetGlobalWlCompositorBinds(cs ClientState) map[ObjectID[WlCompositor]]Version {\n\n\tv := cs.GetGlobalBinds(GlobalID(GlobalID_WlCompositor))\n\tif v == nil {\n\t\treturn nil\n\t}\n\tm := v.(map[ObjectID[WlCompositor]]Version)\n\treturn m\n}\n\nfunc GetGlobalWlSubcompositorBinds(cs ClientState) map[ObjectID[WlSubcompositor]]Version {\n\n\tv := cs.GetGlobalBinds(GlobalID(GlobalID_WlSubcompositor))\n\tif v == nil {\n\t\treturn nil\n\t}\n\tm := v.(map[ObjectID[WlSubcompositor]]Version)\n\treturn m\n}\n\nfunc GetGlobalWlOutputBinds(cs ClientState) map[ObjectID[WlOutput]]Version {\n\n\tv := cs.GetGlobalBinds(GlobalID(GlobalID_WlOutput))\n\tif v == nil {\n\t\treturn nil\n\t}\n\tm := v.(map[ObjectID[WlOutput]]Version)\n\treturn m\n}\n\nfunc GetGlobalWlSeatBinds(cs ClientState) map[ObjectID[WlSeat]]Version {\n\n\tv := cs.GetGlobalBinds(GlobalID(GlobalID_WlSeat))\n\tif v == nil {\n\t\treturn nil\n\t}\n\tm := v.(map[ObjectID[WlSeat]]Version)\n\treturn m\n}\n\nfunc GetGlobalWlShmBinds(cs ClientState) map[ObjectID[WlShm]]Version {\n\n\tv := cs.GetGlobalBinds(GlobalID(GlobalID_WlShm))\n\tif v == nil {\n\t\treturn nil\n\t}\n\tm := v.(map[ObjectID[WlShm]]Version)\n\treturn m\n}\n\nfunc GetGlobalXdgWmBaseBinds(cs ClientState) map[ObjectID[XdgWmBase]]Version {\n\n\tv := cs.GetGlobalBinds(GlobalID(GlobalID_XdgWmBase))\n\tif v == nil {\n\t\treturn nil\n\t}\n\tm := v.(map[ObjectID[XdgWmBase]]Version)\n\treturn m\n}\n\nfunc GetGlobalWlDataDeviceManagerBinds(cs ClientState) map[ObjectID[WlDataDeviceManager]]Version {\n\n\tv := cs.GetGlobalBinds(GlobalID(GlobalID_WlDataDeviceManager))\n\tif v == nil {\n\t\treturn nil\n\t}\n\tm := v.(map[ObjectID[WlDataDeviceManager]]Version)\n\treturn m\n}\n\nfunc GetGlobalWlKeyboardBinds(cs ClientState) map[ObjectID[WlKeyboard]]Version {\n\n\tv := cs.GetGlobalBinds(GlobalID(GlobalID_WlKeyboard))\n\tif v == nil {\n\t\treturn nil\n\t}\n\tm := v.(map[ObjectID[WlKeyboard]]Version)\n\treturn m\n}\n\nfunc GetGlobalWlPointerBinds(cs ClientState) map[ObjectID[WlPointer]]Version {\n\n\tv := cs.GetGlobalBinds(GlobalID(GlobalID_WlPointer))\n\tif v == nil {\n\t\treturn nil\n\t}\n\tm := v.(map[ObjectID[WlPointer]]Version)\n\treturn m\n}\n\nfunc GetGlobalZwpXwaylandKeyboardGrabManagerV1Binds(cs ClientState) map[ObjectID[ZwpXwaylandKeyboardGrabManagerV1]]Version {\n\n\tv := cs.GetGlobalBinds(GlobalID(GlobalID_ZwpXwaylandKeyboardGrabManagerV1))\n\tif v == nil {\n\t\treturn nil\n\t}\n\tm := v.(map[ObjectID[ZwpXwaylandKeyboardGrabManagerV1]]Version)\n\treturn m\n}\n\nfunc GetGlobalXwaylandShellV1Binds(cs ClientState) map[ObjectID[XwaylandShellV1]]Version {\n\n\tv := cs.GetGlobalBinds(GlobalID(GlobalID_XwaylandShellV1))\n\tif v == nil {\n\t\treturn nil\n\t}\n\tm := v.(map[ObjectID[XwaylandShellV1]]Version)\n\treturn m\n}\n\nfunc GetGlobalWlDataDeviceBinds(cs ClientState) map[ObjectID[WlDataDevice]]Version {\n\n\tv := cs.GetGlobalBinds(GlobalID(GlobalID_WlDataDevice))\n\tif v == nil {\n\t\treturn nil\n\t}\n\tm := v.(map[ObjectID[WlDataDevice]]Version)\n\treturn m\n}\n\nfunc GetGlobalWlTouchBinds(cs ClientState) map[ObjectID[WlTouch]]Version {\n\n\tv := cs.GetGlobalBinds(GlobalID(GlobalID_WlTouch))\n\tif v == nil {\n\t\treturn nil\n\t}\n\tm := v.(map[ObjectID[WlTouch]]Version)\n\treturn m\n}\n\nfunc GetGlobalZxdgDecorationManagerV1Binds(cs ClientState) map[ObjectID[ZxdgDecorationManagerV1]]Version {\n\n\tv := cs.GetGlobalBinds(GlobalID(GlobalID_ZxdgDecorationManagerV1))\n\tif v == nil {\n\t\treturn nil\n\t}\n\tm := v.(map[ObjectID[ZxdgDecorationManagerV1]]Version)\n\treturn m\n}\n"
  },
  {
    "path": "wayland/protocols/structs.go",
    "content": "package protocols\n\ntype ObjectID[T any] uint32\n\ntype AnyObjectID = ObjectID[any]\n\ntype OnBindable interface {\n\tOnBind(s ClientState, name AnyObjectID, interface_ string, new_id AnyObjectID, version_number uint32)\n}\n\ntype HasBindable interface {\n\tGetBindable() OnBindable\n}\n\ntype WaylandObject[T OnBindable] interface {\n\tGetDelegate() T\n\tOnRequest(s FileDescriptorClaimClientState, message Message)\n\tGetBindable() OnBindable\n}\n\ntype OnRequestable interface {\n\tOnRequest(s FileDescriptorClaimClientState, message Message)\n}\n\n// Don't use these functions directly; use the ones in wayland/types.go\ntype ClientState interface {\n\tRemoveObject(AnyObjectID)\n\t// RemoveGlobalBind(GlobalID, AnyObjectID)\n\tAddObject(AnyObjectID, any)\n\tSetCompositorVersion(uint32)\n\tGetCompositorVersion() uint32\n\tGetObject(AnyObjectID) any\n\n\tRegisterRoleToSurface(AnyObjectID, ObjectID[WlSurface])\n\tUnregisterRoleToSurface(AnyObjectID)\n\tSend(OutgoingEvent)\n\tSendError(AnyObjectID, uint32, string)\n\n\tDrawableSurfaces() map[ObjectID[WlSurface]]bool\n\tTopLevelSurfaces() map[ObjectID[XdgToplevel]]bool\n\tAddFrameDrawRequest(ObjectID[WlCallback])\n\n\tGetSurfaceIDFromRole(AnyObjectID) *ObjectID[WlSurface]\n\n\tGetSurfaceFromRole(AnyObjectID) any\n\n\tFindDescendantSurface(ObjectID[WlSurface], ObjectID[WlSurface]) bool\n\n\tGetGlobalBinds(GlobalID) any\n\t// AddGlobalBind(GlobalID, AnyObjectID, Version)\n\n\tAddGlobalWlShmBind(ObjectID[WlShm], Version)\n\tAddGlobalWlSeatBind(ObjectID[WlSeat], Version)\n\tAddGlobalWlOutputBind(ObjectID[WlOutput], Version)\n\tAddGlobalWlKeyboardBind(ObjectID[WlKeyboard], Version)\n\tAddGlobalWlPointerBind(ObjectID[WlPointer], Version)\n\tAddGlobalWlTouchBind(ObjectID[WlTouch], Version)\n\tAddGlobalWlDataDeviceBind(ObjectID[WlDataDevice], Version)\n\tAddGlobalZwpXwaylandKeyboardGrabManagerV1Bind(ObjectID[ZwpXwaylandKeyboardGrabManagerV1], Version)\n\n\tRemoveGlobalWlShmBind(ObjectID[WlShm])\n\tRemoveGlobalWlSeatBind(ObjectID[WlSeat])\n\tRemoveGlobalWlOutputBind(ObjectID[WlOutput])\n\tRemoveGlobalWlKeyboardBind(ObjectID[WlKeyboard])\n\tRemoveGlobalWlPointerBind(ObjectID[WlPointer])\n\tRemoveGlobalWlTouchBind(ObjectID[WlTouch])\n\tRemoveGlobalWlDataDeviceBind(ObjectID[WlDataDevice])\n\tRemoveGlobalZwpXwaylandKeyboardGrabManagerV1Bind(ObjectID[ZwpXwaylandKeyboardGrabManagerV1])\n}\n\ntype OutgoingEvent struct {\n\tObjectID       AnyObjectID\n\tOpcode         uint16\n\tData           []byte\n\tFileDescriptor *FileDescriptor\n}\n\ntype FileDescriptorClaimClientState interface {\n\tClientState\n\tClaimFileDescriptor() *FileDescriptor\n}\ntype FileDescriptor int\n\ntype Sender interface {\n\tSend(OutgoingEvent)\n}\n\ntype DecodeStateType int\n\ntype Message struct {\n\tObjectID AnyObjectID\n\tOpcode   uint16\n\tSize     uint16\n\tData     []byte\n}\n\ntype DecodeState struct {\n\tPhase    DecodeStateType\n\tI        uint // bit offset within current field (0,8,16,24)\n\tObjectID AnyObjectID\n\tOpcode   uint16\n\tSize     uint16\n\tData     []byte\n}\n\ntype Fixed = float64\n"
  },
  {
    "path": "wayland/protocols/wayland.xml.go",
    "content": "// Code generated by `cmd/protocols`; DO NOT EDIT.\n\npackage protocols\n\nimport \"fmt\"\n\ntype WlDisplay_delegate interface {\n\tWlDisplay_sync(s ClientState, object_id ObjectID[WlDisplay], callback ObjectID[WlCallback])\n\tWlDisplay_get_registry(s ClientState, object_id ObjectID[WlDisplay], registry ObjectID[WlRegistry])\n\tOnBind(s ClientState, name AnyObjectID, interface_ string, new_id AnyObjectID, version_number uint32)\n}\n\ntype WlDisplay struct {\n\tDelegate WlDisplay_delegate\n}\n\nfunc (p *WlDisplay) GetDelegate() WlDisplay_delegate {\n\treturn p.Delegate\n}\nfunc (p *WlDisplay) GetBindable() OnBindable {\n\treturn p.Delegate\n}\n\nfunc WlDisplay_error(s Sender, eventObjectID ObjectID[WlDisplay], object_id AnyObjectID, code uint32, message string) {\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tvar fileDescriptor *FileDescriptor\n\tputUint32(uint32(object_id))\n\tputUint32(uint32(code))\n\t{\n\t\tb := []byte(message)\n\t\ttotal := len(b) + 1 // include null terminator\n\t\tputUint32(uint32(total))\n\t\tdata = append(data, b...)\n\t\tdata = append(data, 0)\n\t\tif pad := (4 - (total % 4)) % 4; pad != 0 {\n\t\t\tdata = append(data, make([]byte, pad)...)\n\t\t}\n\t}\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         0,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc WlDisplay_delete_id(s Sender, eventObjectID ObjectID[WlDisplay], id uint32) {\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tvar fileDescriptor *FileDescriptor\n\tputUint32(uint32(id))\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         1,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc (p *WlDisplay) OnRequest(s FileDescriptorClaimClientState, message Message) {\n\t_data_in_offset__ := 0\n\t_ = _data_in_offset__\n\td := p.Delegate\n\tswitch message.Opcode {\n\tcase 0:\n\t\t{\n\n\t\t\tcallbackVal := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\tcallback := ObjectID[WlCallback](callbackVal)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlDisplay@\", message.ObjectID, \".sync(\")\n\t\t\t\tfmt.Println(\"callback: \", callback, \")\")\n\t\t\t}\n\n\t\t\td.WlDisplay_sync(s, ObjectID[WlDisplay](message.ObjectID), callback)\n\t\t\tbreak\n\t\t}\n\n\tcase 1:\n\t\t{\n\n\t\t\tregistryVal := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\tregistry := ObjectID[WlRegistry](registryVal)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlDisplay@\", message.ObjectID, \".get_registry(\")\n\t\t\t\tfmt.Println(\"registry: \", registry, \")\")\n\t\t\t}\n\n\t\t\td.WlDisplay_get_registry(s, ObjectID[WlDisplay](message.ObjectID), registry)\n\t\t\tbreak\n\t\t}\n\n\tdefault:\n\t\tfmt.Println(\"Unknown opcode on WlDisplay\", message.Opcode)\n\t}\n}\n\ntype WlDisplayError_enum uint32\n\nconst (\n\tWlDisplayError_enum_invalid_object WlDisplayError_enum = 0\n\tWlDisplayError_enum_invalid_method WlDisplayError_enum = 1\n\tWlDisplayError_enum_no_memory      WlDisplayError_enum = 2\n\tWlDisplayError_enum_implementation WlDisplayError_enum = 3\n)\n\ntype WlRegistry_delegate interface {\n\tWlRegistry_bind(s ClientState, object_id ObjectID[WlRegistry], name uint32, idInterface string, idVersion uint32, idID AnyObjectID)\n\tOnBind(s ClientState, name AnyObjectID, interface_ string, new_id AnyObjectID, version_number uint32)\n}\n\ntype WlRegistry struct {\n\tDelegate WlRegistry_delegate\n}\n\nfunc (p *WlRegistry) GetDelegate() WlRegistry_delegate {\n\treturn p.Delegate\n}\nfunc (p *WlRegistry) GetBindable() OnBindable {\n\treturn p.Delegate\n}\n\nfunc WlRegistry_global(s Sender, eventObjectID ObjectID[WlRegistry], name uint32, interface_ string, version uint32) {\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tvar fileDescriptor *FileDescriptor\n\tputUint32(uint32(name))\n\t{\n\t\tb := []byte(interface_)\n\t\ttotal := len(b) + 1 // include null terminator\n\t\tputUint32(uint32(total))\n\t\tdata = append(data, b...)\n\t\tdata = append(data, 0)\n\t\tif pad := (4 - (total % 4)) % 4; pad != 0 {\n\t\t\tdata = append(data, make([]byte, pad)...)\n\t\t}\n\t}\n\tputUint32(uint32(version))\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         0,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc WlRegistry_global_remove(s Sender, eventObjectID ObjectID[WlRegistry], name uint32) {\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tvar fileDescriptor *FileDescriptor\n\tputUint32(uint32(name))\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         1,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc (p *WlRegistry) OnRequest(s FileDescriptorClaimClientState, message Message) {\n\t_data_in_offset__ := 0\n\t_ = _data_in_offset__\n\td := p.Delegate\n\tswitch message.Opcode {\n\tcase 0:\n\t\t{\n\n\t\t\tname := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tidInterfaceLen := int(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\t\t\tidInterface := string(message.Data[_data_in_offset__ : _data_in_offset__+idInterfaceLen-1]) // NUL-terminated\n\t\t\t// 4-byte alignment\n\t\t\tif idInterfaceLen%4 != 0 {\n\t\t\t\t_data_in_offset__ += idInterfaceLen + (4 - (idInterfaceLen % 4))\n\t\t\t} else {\n\t\t\t\t_data_in_offset__ += idInterfaceLen\n\t\t\t}\n\t\t\tidVersion := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\t_data_in_offset__ += 4\n\t\t\tidID := AnyObjectID(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlRegistry@\", message.ObjectID, \".bind(\")\n\t\t\t\tfmt.Println(\"name: \", name, \", \", \"idInterface: \", idInterface, \", \", \"idVersion: \", idVersion, \", \", \"idID: \", idID, \")\")\n\t\t\t}\n\n\t\t\td.WlRegistry_bind(s, ObjectID[WlRegistry](message.ObjectID), name, idInterface, idVersion, idID)\n\t\t\tbreak\n\t\t}\n\n\tdefault:\n\t\tfmt.Println(\"Unknown opcode on WlRegistry\", message.Opcode)\n\t}\n}\n\ntype WlCallback_delegate interface {\n\tOnBind(s ClientState, name AnyObjectID, interface_ string, new_id AnyObjectID, version_number uint32)\n}\n\ntype WlCallback struct {\n\tDelegate WlCallback_delegate\n}\n\nfunc (p *WlCallback) GetDelegate() WlCallback_delegate {\n\treturn p.Delegate\n}\nfunc (p *WlCallback) GetBindable() OnBindable {\n\treturn p.Delegate\n}\n\nfunc WlCallback_done(s Sender, eventObjectID ObjectID[WlCallback], callback_data uint32) {\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tvar fileDescriptor *FileDescriptor\n\tputUint32(uint32(callback_data))\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         0,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc (p *WlCallback) OnRequest(s FileDescriptorClaimClientState, message Message) {\n\tswitch message.Opcode {\n\tdefault:\n\t\tfmt.Println(\"Unknown opcode on WlCallback\", message.Opcode)\n\t}\n}\n\ntype WlCompositor_delegate interface {\n\tWlCompositor_create_surface(s ClientState, object_id ObjectID[WlCompositor], id ObjectID[WlSurface])\n\tWlCompositor_create_region(s ClientState, object_id ObjectID[WlCompositor], id ObjectID[WlRegion])\n\tOnBind(s ClientState, name AnyObjectID, interface_ string, new_id AnyObjectID, version_number uint32)\n}\n\ntype WlCompositor struct {\n\tDelegate WlCompositor_delegate\n}\n\nfunc (p *WlCompositor) GetDelegate() WlCompositor_delegate {\n\treturn p.Delegate\n}\nfunc (p *WlCompositor) GetBindable() OnBindable {\n\treturn p.Delegate\n}\n\nfunc (p *WlCompositor) OnRequest(s FileDescriptorClaimClientState, message Message) {\n\t_data_in_offset__ := 0\n\t_ = _data_in_offset__\n\td := p.Delegate\n\tswitch message.Opcode {\n\tcase 0:\n\t\t{\n\n\t\t\tidVal := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\tid := ObjectID[WlSurface](idVal)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlCompositor@\", message.ObjectID, \".create_surface(\")\n\t\t\t\tfmt.Println(\"id: \", id, \")\")\n\t\t\t}\n\n\t\t\td.WlCompositor_create_surface(s, ObjectID[WlCompositor](message.ObjectID), id)\n\t\t\tbreak\n\t\t}\n\n\tcase 1:\n\t\t{\n\n\t\t\tidVal := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\tid := ObjectID[WlRegion](idVal)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlCompositor@\", message.ObjectID, \".create_region(\")\n\t\t\t\tfmt.Println(\"id: \", id, \")\")\n\t\t\t}\n\n\t\t\td.WlCompositor_create_region(s, ObjectID[WlCompositor](message.ObjectID), id)\n\t\t\tbreak\n\t\t}\n\n\tdefault:\n\t\tfmt.Println(\"Unknown opcode on WlCompositor\", message.Opcode)\n\t}\n}\n\ntype WlShmPool_delegate interface {\n\tWlShmPool_create_buffer(s ClientState, object_id ObjectID[WlShmPool], id ObjectID[WlBuffer], offset int32, width int32, height int32, stride int32, format WlShmFormat_enum)\n\tWlShmPool_destroy(s ClientState, object_id ObjectID[WlShmPool]) bool\n\tWlShmPool_resize(s ClientState, object_id ObjectID[WlShmPool], size int32)\n\tOnBind(s ClientState, name AnyObjectID, interface_ string, new_id AnyObjectID, version_number uint32)\n}\n\ntype WlShmPool struct {\n\tDelegate WlShmPool_delegate\n}\n\nfunc (p *WlShmPool) GetDelegate() WlShmPool_delegate {\n\treturn p.Delegate\n}\nfunc (p *WlShmPool) GetBindable() OnBindable {\n\treturn p.Delegate\n}\n\nfunc (p *WlShmPool) OnRequest(s FileDescriptorClaimClientState, message Message) {\n\t_data_in_offset__ := 0\n\t_ = _data_in_offset__\n\td := p.Delegate\n\tswitch message.Opcode {\n\tcase 0:\n\t\t{\n\n\t\t\tidVal := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\tid := ObjectID[WlBuffer](idVal)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\toffset := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\twidth := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\theight := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tstride := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tformat := WlShmFormat_enum(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlShmPool@\", message.ObjectID, \".create_buffer(\")\n\t\t\t\tfmt.Println(\"id: \", id, \", \", \"offset: \", offset, \", \", \"width: \", width, \", \", \"height: \", height, \", \", \"stride: \", stride, \", \", \"format: \", format, \")\")\n\t\t\t}\n\n\t\t\td.WlShmPool_create_buffer(s, ObjectID[WlShmPool](message.ObjectID), id, offset, width, height, stride, format)\n\t\t\tbreak\n\t\t}\n\n\tcase 1:\n\t\t{\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlShmPool@\", message.ObjectID, \".destroy(\")\n\t\t\t\tfmt.Println(\")\")\n\t\t\t}\n\n\t\t\tautoRemove := d.WlShmPool_destroy(s, ObjectID[WlShmPool](message.ObjectID))\n\t\t\tif autoRemove {\n\t\t\t\ts.RemoveObject(message.ObjectID)\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\n\tcase 2:\n\t\t{\n\n\t\t\tsize := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlShmPool@\", message.ObjectID, \".resize(\")\n\t\t\t\tfmt.Println(\"size: \", size, \")\")\n\t\t\t}\n\n\t\t\td.WlShmPool_resize(s, ObjectID[WlShmPool](message.ObjectID), size)\n\t\t\tbreak\n\t\t}\n\n\tdefault:\n\t\tfmt.Println(\"Unknown opcode on WlShmPool\", message.Opcode)\n\t}\n}\n\ntype WlShm_delegate interface {\n\tWlShm_create_pool(s ClientState, object_id ObjectID[WlShm], id ObjectID[WlShmPool], fd *FileDescriptor, size int32)\n\tWlShm_release(s ClientState, object_id ObjectID[WlShm]) bool\n\tOnBind(s ClientState, name AnyObjectID, interface_ string, new_id AnyObjectID, version_number uint32)\n}\n\ntype WlShm struct {\n\tDelegate WlShm_delegate\n}\n\nfunc (p *WlShm) GetDelegate() WlShm_delegate {\n\treturn p.Delegate\n}\nfunc (p *WlShm) GetBindable() OnBindable {\n\treturn p.Delegate\n}\n\nfunc WlShm_format(s Sender, eventObjectID ObjectID[WlShm], format WlShmFormat_enum) {\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tvar fileDescriptor *FileDescriptor\n\tputUint32(uint32(format))\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         0,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc (p *WlShm) OnRequest(s FileDescriptorClaimClientState, message Message) {\n\t_data_in_offset__ := 0\n\t_ = _data_in_offset__\n\td := p.Delegate\n\tswitch message.Opcode {\n\tcase 0:\n\t\t{\n\n\t\t\tidVal := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\tid := ObjectID[WlShmPool](idVal)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tfd := s.ClaimFileDescriptor()\n\n\t\t\tsize := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlShm@\", message.ObjectID, \".create_pool(\")\n\t\t\t\tfmt.Println(\"id: \", id, \", \", \"fd: \", fd, \", \", \"size: \", size, \")\")\n\t\t\t}\n\n\t\t\td.WlShm_create_pool(s, ObjectID[WlShm](message.ObjectID), id, fd, size)\n\t\t\tbreak\n\t\t}\n\n\tcase 1:\n\t\t{\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlShm@\", message.ObjectID, \".release(\")\n\t\t\t\tfmt.Println(\")\")\n\t\t\t}\n\n\t\t\tautoRemove := d.WlShm_release(s, ObjectID[WlShm](message.ObjectID))\n\t\t\tif autoRemove {\n\t\t\t\ts.RemoveObject(message.ObjectID)\n\t\t\t\ts.RemoveGlobalWlShmBind(ObjectID[WlShm](message.ObjectID))\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\n\tdefault:\n\t\tfmt.Println(\"Unknown opcode on WlShm\", message.Opcode)\n\t}\n}\n\ntype WlShmError_enum uint32\n\nconst (\n\tWlShmError_enum_invalid_format WlShmError_enum = 0\n\tWlShmError_enum_invalid_stride WlShmError_enum = 1\n\tWlShmError_enum_invalid_fd     WlShmError_enum = 2\n)\n\ntype WlShmFormat_enum uint32\n\nconst (\n\tWlShmFormat_enum_argb8888             WlShmFormat_enum = 0\n\tWlShmFormat_enum_xrgb8888             WlShmFormat_enum = 1\n\tWlShmFormat_enum_c8                   WlShmFormat_enum = 0x20203843\n\tWlShmFormat_enum_rgb332               WlShmFormat_enum = 0x38424752\n\tWlShmFormat_enum_bgr233               WlShmFormat_enum = 0x38524742\n\tWlShmFormat_enum_xrgb4444             WlShmFormat_enum = 0x32315258\n\tWlShmFormat_enum_xbgr4444             WlShmFormat_enum = 0x32314258\n\tWlShmFormat_enum_rgbx4444             WlShmFormat_enum = 0x32315852\n\tWlShmFormat_enum_bgrx4444             WlShmFormat_enum = 0x32315842\n\tWlShmFormat_enum_argb4444             WlShmFormat_enum = 0x32315241\n\tWlShmFormat_enum_abgr4444             WlShmFormat_enum = 0x32314241\n\tWlShmFormat_enum_rgba4444             WlShmFormat_enum = 0x32314152\n\tWlShmFormat_enum_bgra4444             WlShmFormat_enum = 0x32314142\n\tWlShmFormat_enum_xrgb1555             WlShmFormat_enum = 0x35315258\n\tWlShmFormat_enum_xbgr1555             WlShmFormat_enum = 0x35314258\n\tWlShmFormat_enum_rgbx5551             WlShmFormat_enum = 0x35315852\n\tWlShmFormat_enum_bgrx5551             WlShmFormat_enum = 0x35315842\n\tWlShmFormat_enum_argb1555             WlShmFormat_enum = 0x35315241\n\tWlShmFormat_enum_abgr1555             WlShmFormat_enum = 0x35314241\n\tWlShmFormat_enum_rgba5551             WlShmFormat_enum = 0x35314152\n\tWlShmFormat_enum_bgra5551             WlShmFormat_enum = 0x35314142\n\tWlShmFormat_enum_rgb565               WlShmFormat_enum = 0x36314752\n\tWlShmFormat_enum_bgr565               WlShmFormat_enum = 0x36314742\n\tWlShmFormat_enum_rgb888               WlShmFormat_enum = 0x34324752\n\tWlShmFormat_enum_bgr888               WlShmFormat_enum = 0x34324742\n\tWlShmFormat_enum_xbgr8888             WlShmFormat_enum = 0x34324258\n\tWlShmFormat_enum_rgbx8888             WlShmFormat_enum = 0x34325852\n\tWlShmFormat_enum_bgrx8888             WlShmFormat_enum = 0x34325842\n\tWlShmFormat_enum_abgr8888             WlShmFormat_enum = 0x34324241\n\tWlShmFormat_enum_rgba8888             WlShmFormat_enum = 0x34324152\n\tWlShmFormat_enum_bgra8888             WlShmFormat_enum = 0x34324142\n\tWlShmFormat_enum_xrgb2101010          WlShmFormat_enum = 0x30335258\n\tWlShmFormat_enum_xbgr2101010          WlShmFormat_enum = 0x30334258\n\tWlShmFormat_enum_rgbx1010102          WlShmFormat_enum = 0x30335852\n\tWlShmFormat_enum_bgrx1010102          WlShmFormat_enum = 0x30335842\n\tWlShmFormat_enum_argb2101010          WlShmFormat_enum = 0x30335241\n\tWlShmFormat_enum_abgr2101010          WlShmFormat_enum = 0x30334241\n\tWlShmFormat_enum_rgba1010102          WlShmFormat_enum = 0x30334152\n\tWlShmFormat_enum_bgra1010102          WlShmFormat_enum = 0x30334142\n\tWlShmFormat_enum_yuyv                 WlShmFormat_enum = 0x56595559\n\tWlShmFormat_enum_yvyu                 WlShmFormat_enum = 0x55595659\n\tWlShmFormat_enum_uyvy                 WlShmFormat_enum = 0x59565955\n\tWlShmFormat_enum_vyuy                 WlShmFormat_enum = 0x59555956\n\tWlShmFormat_enum_ayuv                 WlShmFormat_enum = 0x56555941\n\tWlShmFormat_enum_nv12                 WlShmFormat_enum = 0x3231564e\n\tWlShmFormat_enum_nv21                 WlShmFormat_enum = 0x3132564e\n\tWlShmFormat_enum_nv16                 WlShmFormat_enum = 0x3631564e\n\tWlShmFormat_enum_nv61                 WlShmFormat_enum = 0x3136564e\n\tWlShmFormat_enum_yuv410               WlShmFormat_enum = 0x39565559\n\tWlShmFormat_enum_yvu410               WlShmFormat_enum = 0x39555659\n\tWlShmFormat_enum_yuv411               WlShmFormat_enum = 0x31315559\n\tWlShmFormat_enum_yvu411               WlShmFormat_enum = 0x31315659\n\tWlShmFormat_enum_yuv420               WlShmFormat_enum = 0x32315559\n\tWlShmFormat_enum_yvu420               WlShmFormat_enum = 0x32315659\n\tWlShmFormat_enum_yuv422               WlShmFormat_enum = 0x36315559\n\tWlShmFormat_enum_yvu422               WlShmFormat_enum = 0x36315659\n\tWlShmFormat_enum_yuv444               WlShmFormat_enum = 0x34325559\n\tWlShmFormat_enum_yvu444               WlShmFormat_enum = 0x34325659\n\tWlShmFormat_enum_r8                   WlShmFormat_enum = 0x20203852\n\tWlShmFormat_enum_r16                  WlShmFormat_enum = 0x20363152\n\tWlShmFormat_enum_rg88                 WlShmFormat_enum = 0x38384752\n\tWlShmFormat_enum_gr88                 WlShmFormat_enum = 0x38385247\n\tWlShmFormat_enum_rg1616               WlShmFormat_enum = 0x32334752\n\tWlShmFormat_enum_gr1616               WlShmFormat_enum = 0x32335247\n\tWlShmFormat_enum_xrgb16161616f        WlShmFormat_enum = 0x48345258\n\tWlShmFormat_enum_xbgr16161616f        WlShmFormat_enum = 0x48344258\n\tWlShmFormat_enum_argb16161616f        WlShmFormat_enum = 0x48345241\n\tWlShmFormat_enum_abgr16161616f        WlShmFormat_enum = 0x48344241\n\tWlShmFormat_enum_xyuv8888             WlShmFormat_enum = 0x56555958\n\tWlShmFormat_enum_vuy888               WlShmFormat_enum = 0x34325556\n\tWlShmFormat_enum_vuy101010            WlShmFormat_enum = 0x30335556\n\tWlShmFormat_enum_y210                 WlShmFormat_enum = 0x30313259\n\tWlShmFormat_enum_y212                 WlShmFormat_enum = 0x32313259\n\tWlShmFormat_enum_y216                 WlShmFormat_enum = 0x36313259\n\tWlShmFormat_enum_y410                 WlShmFormat_enum = 0x30313459\n\tWlShmFormat_enum_y412                 WlShmFormat_enum = 0x32313459\n\tWlShmFormat_enum_y416                 WlShmFormat_enum = 0x36313459\n\tWlShmFormat_enum_xvyu2101010          WlShmFormat_enum = 0x30335658\n\tWlShmFormat_enum_xvyu12_16161616      WlShmFormat_enum = 0x36335658\n\tWlShmFormat_enum_xvyu16161616         WlShmFormat_enum = 0x38345658\n\tWlShmFormat_enum_y0l0                 WlShmFormat_enum = 0x304c3059\n\tWlShmFormat_enum_x0l0                 WlShmFormat_enum = 0x304c3058\n\tWlShmFormat_enum_y0l2                 WlShmFormat_enum = 0x324c3059\n\tWlShmFormat_enum_x0l2                 WlShmFormat_enum = 0x324c3058\n\tWlShmFormat_enum_yuv420_8bit          WlShmFormat_enum = 0x38305559\n\tWlShmFormat_enum_yuv420_10bit         WlShmFormat_enum = 0x30315559\n\tWlShmFormat_enum_xrgb8888_a8          WlShmFormat_enum = 0x38415258\n\tWlShmFormat_enum_xbgr8888_a8          WlShmFormat_enum = 0x38414258\n\tWlShmFormat_enum_rgbx8888_a8          WlShmFormat_enum = 0x38415852\n\tWlShmFormat_enum_bgrx8888_a8          WlShmFormat_enum = 0x38415842\n\tWlShmFormat_enum_rgb888_a8            WlShmFormat_enum = 0x38413852\n\tWlShmFormat_enum_bgr888_a8            WlShmFormat_enum = 0x38413842\n\tWlShmFormat_enum_rgb565_a8            WlShmFormat_enum = 0x38413552\n\tWlShmFormat_enum_bgr565_a8            WlShmFormat_enum = 0x38413542\n\tWlShmFormat_enum_nv24                 WlShmFormat_enum = 0x3432564e\n\tWlShmFormat_enum_nv42                 WlShmFormat_enum = 0x3234564e\n\tWlShmFormat_enum_p210                 WlShmFormat_enum = 0x30313250\n\tWlShmFormat_enum_p010                 WlShmFormat_enum = 0x30313050\n\tWlShmFormat_enum_p012                 WlShmFormat_enum = 0x32313050\n\tWlShmFormat_enum_p016                 WlShmFormat_enum = 0x36313050\n\tWlShmFormat_enum_axbxgxrx106106106106 WlShmFormat_enum = 0x30314241\n\tWlShmFormat_enum_nv15                 WlShmFormat_enum = 0x3531564e\n\tWlShmFormat_enum_q410                 WlShmFormat_enum = 0x30313451\n\tWlShmFormat_enum_q401                 WlShmFormat_enum = 0x31303451\n\tWlShmFormat_enum_xrgb16161616         WlShmFormat_enum = 0x38345258\n\tWlShmFormat_enum_xbgr16161616         WlShmFormat_enum = 0x38344258\n\tWlShmFormat_enum_argb16161616         WlShmFormat_enum = 0x38345241\n\tWlShmFormat_enum_abgr16161616         WlShmFormat_enum = 0x38344241\n\tWlShmFormat_enum_c1                   WlShmFormat_enum = 0x20203143\n\tWlShmFormat_enum_c2                   WlShmFormat_enum = 0x20203243\n\tWlShmFormat_enum_c4                   WlShmFormat_enum = 0x20203443\n\tWlShmFormat_enum_d1                   WlShmFormat_enum = 0x20203144\n\tWlShmFormat_enum_d2                   WlShmFormat_enum = 0x20203244\n\tWlShmFormat_enum_d4                   WlShmFormat_enum = 0x20203444\n\tWlShmFormat_enum_d8                   WlShmFormat_enum = 0x20203844\n\tWlShmFormat_enum_r1                   WlShmFormat_enum = 0x20203152\n\tWlShmFormat_enum_r2                   WlShmFormat_enum = 0x20203252\n\tWlShmFormat_enum_r4                   WlShmFormat_enum = 0x20203452\n\tWlShmFormat_enum_r10                  WlShmFormat_enum = 0x20303152\n\tWlShmFormat_enum_r12                  WlShmFormat_enum = 0x20323152\n\tWlShmFormat_enum_avuy8888             WlShmFormat_enum = 0x59555641\n\tWlShmFormat_enum_xvuy8888             WlShmFormat_enum = 0x59555658\n\tWlShmFormat_enum_p030                 WlShmFormat_enum = 0x30333050\n)\n\ntype WlBuffer_delegate interface {\n\tWlBuffer_destroy(s ClientState, object_id ObjectID[WlBuffer]) bool\n\tOnBind(s ClientState, name AnyObjectID, interface_ string, new_id AnyObjectID, version_number uint32)\n}\n\ntype WlBuffer struct {\n\tDelegate WlBuffer_delegate\n}\n\nfunc (p *WlBuffer) GetDelegate() WlBuffer_delegate {\n\treturn p.Delegate\n}\nfunc (p *WlBuffer) GetBindable() OnBindable {\n\treturn p.Delegate\n}\n\nfunc WlBuffer_release(s Sender, eventObjectID ObjectID[WlBuffer]) {\n\tdata := make([]byte, 0)\n\tvar fileDescriptor *FileDescriptor\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         0,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc (p *WlBuffer) OnRequest(s FileDescriptorClaimClientState, message Message) {\n\t_data_in_offset__ := 0\n\t_ = _data_in_offset__\n\td := p.Delegate\n\tswitch message.Opcode {\n\tcase 0:\n\t\t{\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlBuffer@\", message.ObjectID, \".destroy(\")\n\t\t\t\tfmt.Println(\")\")\n\t\t\t}\n\n\t\t\tautoRemove := d.WlBuffer_destroy(s, ObjectID[WlBuffer](message.ObjectID))\n\t\t\tif autoRemove {\n\t\t\t\ts.RemoveObject(message.ObjectID)\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\n\tdefault:\n\t\tfmt.Println(\"Unknown opcode on WlBuffer\", message.Opcode)\n\t}\n}\n\ntype WlDataOffer_delegate interface {\n\tWlDataOffer_accept(s ClientState, object_id ObjectID[WlDataOffer], serial uint32, mime_type string)\n\tWlDataOffer_receive(s ClientState, object_id ObjectID[WlDataOffer], mime_type string, fd *FileDescriptor)\n\tWlDataOffer_destroy(s ClientState, object_id ObjectID[WlDataOffer]) bool\n\tWlDataOffer_finish(s ClientState, object_id ObjectID[WlDataOffer])\n\tWlDataOffer_set_actions(s ClientState, object_id ObjectID[WlDataOffer], dnd_actions WlDataDeviceManagerDndAction_enum, preferred_action WlDataDeviceManagerDndAction_enum)\n\tOnBind(s ClientState, name AnyObjectID, interface_ string, new_id AnyObjectID, version_number uint32)\n}\n\ntype WlDataOffer struct {\n\tDelegate WlDataOffer_delegate\n}\n\nfunc (p *WlDataOffer) GetDelegate() WlDataOffer_delegate {\n\treturn p.Delegate\n}\nfunc (p *WlDataOffer) GetBindable() OnBindable {\n\treturn p.Delegate\n}\n\nfunc WlDataOffer_offer(s Sender, eventObjectID ObjectID[WlDataOffer], mime_type string) {\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tvar fileDescriptor *FileDescriptor\n\t{\n\t\tb := []byte(mime_type)\n\t\ttotal := len(b) + 1 // include null terminator\n\t\tputUint32(uint32(total))\n\t\tdata = append(data, b...)\n\t\tdata = append(data, 0)\n\t\tif pad := (4 - (total % 4)) % 4; pad != 0 {\n\t\t\tdata = append(data, make([]byte, pad)...)\n\t\t}\n\t}\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         0,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc WlDataOffer_source_actions(s Sender, boundVersion uint32, eventObjectID ObjectID[WlDataOffer], source_actions WlDataDeviceManagerDndAction_enum) {\n\tif boundVersion < 3 {\n\t\t// Event not available in this version; skip\n\t\treturn\n\t}\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tvar fileDescriptor *FileDescriptor\n\tputUint32(uint32(source_actions))\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         1,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc WlDataOffer_action(s Sender, boundVersion uint32, eventObjectID ObjectID[WlDataOffer], dnd_action WlDataDeviceManagerDndAction_enum) {\n\tif boundVersion < 3 {\n\t\t// Event not available in this version; skip\n\t\treturn\n\t}\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tvar fileDescriptor *FileDescriptor\n\tputUint32(uint32(dnd_action))\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         2,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc (p *WlDataOffer) OnRequest(s FileDescriptorClaimClientState, message Message) {\n\t_data_in_offset__ := 0\n\t_ = _data_in_offset__\n\td := p.Delegate\n\tswitch message.Opcode {\n\tcase 0:\n\t\t{\n\n\t\t\tserial := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tmime_typeLen := int(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\t\t\tmime_type := string(message.Data[_data_in_offset__ : _data_in_offset__+mime_typeLen-1]) // NUL-terminated\n\t\t\t// 4-byte alignment\n\t\t\tif mime_typeLen%4 != 0 {\n\t\t\t\t_data_in_offset__ += mime_typeLen + (4 - (mime_typeLen % 4))\n\t\t\t} else {\n\t\t\t\t_data_in_offset__ += mime_typeLen\n\t\t\t}\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlDataOffer@\", message.ObjectID, \".accept(\")\n\t\t\t\tfmt.Println(\"serial: \", serial, \", \", \"mime_type: \", mime_type, \")\")\n\t\t\t}\n\n\t\t\td.WlDataOffer_accept(s, ObjectID[WlDataOffer](message.ObjectID), serial, mime_type)\n\t\t\tbreak\n\t\t}\n\n\tcase 1:\n\t\t{\n\n\t\t\tmime_typeLen := int(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\t\t\tmime_type := string(message.Data[_data_in_offset__ : _data_in_offset__+mime_typeLen-1]) // NUL-terminated\n\t\t\t// 4-byte alignment\n\t\t\tif mime_typeLen%4 != 0 {\n\t\t\t\t_data_in_offset__ += mime_typeLen + (4 - (mime_typeLen % 4))\n\t\t\t} else {\n\t\t\t\t_data_in_offset__ += mime_typeLen\n\t\t\t}\n\n\t\t\tfd := s.ClaimFileDescriptor()\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlDataOffer@\", message.ObjectID, \".receive(\")\n\t\t\t\tfmt.Println(\"mime_type: \", mime_type, \", \", \"fd: \", fd, \")\")\n\t\t\t}\n\n\t\t\td.WlDataOffer_receive(s, ObjectID[WlDataOffer](message.ObjectID), mime_type, fd)\n\t\t\tbreak\n\t\t}\n\n\tcase 2:\n\t\t{\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlDataOffer@\", message.ObjectID, \".destroy(\")\n\t\t\t\tfmt.Println(\")\")\n\t\t\t}\n\n\t\t\tautoRemove := d.WlDataOffer_destroy(s, ObjectID[WlDataOffer](message.ObjectID))\n\t\t\tif autoRemove {\n\t\t\t\ts.RemoveObject(message.ObjectID)\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\n\tcase 3:\n\t\t{\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlDataOffer@\", message.ObjectID, \".finish(\")\n\t\t\t\tfmt.Println(\")\")\n\t\t\t}\n\n\t\t\td.WlDataOffer_finish(s, ObjectID[WlDataOffer](message.ObjectID))\n\t\t\tbreak\n\t\t}\n\n\tcase 4:\n\t\t{\n\n\t\t\tdnd_actions := WlDataDeviceManagerDndAction_enum(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tpreferred_action := WlDataDeviceManagerDndAction_enum(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlDataOffer@\", message.ObjectID, \".set_actions(\")\n\t\t\t\tfmt.Println(\"dnd_actions: \", dnd_actions, \", \", \"preferred_action: \", preferred_action, \")\")\n\t\t\t}\n\n\t\t\td.WlDataOffer_set_actions(s, ObjectID[WlDataOffer](message.ObjectID), dnd_actions, preferred_action)\n\t\t\tbreak\n\t\t}\n\n\tdefault:\n\t\tfmt.Println(\"Unknown opcode on WlDataOffer\", message.Opcode)\n\t}\n}\n\ntype WlDataOfferError_enum uint32\n\nconst (\n\tWlDataOfferError_enum_invalid_finish      WlDataOfferError_enum = 0\n\tWlDataOfferError_enum_invalid_action_mask WlDataOfferError_enum = 1\n\tWlDataOfferError_enum_invalid_action      WlDataOfferError_enum = 2\n\tWlDataOfferError_enum_invalid_offer       WlDataOfferError_enum = 3\n)\n\ntype WlDataSource_delegate interface {\n\tWlDataSource_offer(s ClientState, object_id ObjectID[WlDataSource], mime_type string)\n\tWlDataSource_destroy(s ClientState, object_id ObjectID[WlDataSource]) bool\n\tWlDataSource_set_actions(s ClientState, object_id ObjectID[WlDataSource], dnd_actions WlDataDeviceManagerDndAction_enum)\n\tOnBind(s ClientState, name AnyObjectID, interface_ string, new_id AnyObjectID, version_number uint32)\n}\n\ntype WlDataSource struct {\n\tDelegate WlDataSource_delegate\n}\n\nfunc (p *WlDataSource) GetDelegate() WlDataSource_delegate {\n\treturn p.Delegate\n}\nfunc (p *WlDataSource) GetBindable() OnBindable {\n\treturn p.Delegate\n}\n\nfunc WlDataSource_target(s Sender, eventObjectID ObjectID[WlDataSource], mime_type string) {\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tvar fileDescriptor *FileDescriptor\n\t{\n\t\tb := []byte(mime_type)\n\t\ttotal := len(b) + 1 // include null terminator\n\t\tputUint32(uint32(total))\n\t\tdata = append(data, b...)\n\t\tdata = append(data, 0)\n\t\tif pad := (4 - (total % 4)) % 4; pad != 0 {\n\t\t\tdata = append(data, make([]byte, pad)...)\n\t\t}\n\t}\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         0,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc WlDataSource_send(s Sender, eventObjectID ObjectID[WlDataSource], mime_type string, fd FileDescriptor) {\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tvar fileDescriptor *FileDescriptor\n\t{\n\t\tb := []byte(mime_type)\n\t\ttotal := len(b) + 1 // include null terminator\n\t\tputUint32(uint32(total))\n\t\tdata = append(data, b...)\n\t\tdata = append(data, 0)\n\t\tif pad := (4 - (total % 4)) % 4; pad != 0 {\n\t\t\tdata = append(data, make([]byte, pad)...)\n\t\t}\n\t}\n\tfileDescriptor = &fd\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         1,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc WlDataSource_cancelled(s Sender, eventObjectID ObjectID[WlDataSource]) {\n\tdata := make([]byte, 0)\n\tvar fileDescriptor *FileDescriptor\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         2,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc WlDataSource_dnd_drop_performed(s Sender, boundVersion uint32, eventObjectID ObjectID[WlDataSource]) {\n\tif boundVersion < 3 {\n\t\t// Event not available in this version; skip\n\t\treturn\n\t}\n\tdata := make([]byte, 0)\n\tvar fileDescriptor *FileDescriptor\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         3,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc WlDataSource_dnd_finished(s Sender, boundVersion uint32, eventObjectID ObjectID[WlDataSource]) {\n\tif boundVersion < 3 {\n\t\t// Event not available in this version; skip\n\t\treturn\n\t}\n\tdata := make([]byte, 0)\n\tvar fileDescriptor *FileDescriptor\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         4,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc WlDataSource_action(s Sender, boundVersion uint32, eventObjectID ObjectID[WlDataSource], dnd_action WlDataDeviceManagerDndAction_enum) {\n\tif boundVersion < 3 {\n\t\t// Event not available in this version; skip\n\t\treturn\n\t}\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tvar fileDescriptor *FileDescriptor\n\tputUint32(uint32(dnd_action))\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         5,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc (p *WlDataSource) OnRequest(s FileDescriptorClaimClientState, message Message) {\n\t_data_in_offset__ := 0\n\t_ = _data_in_offset__\n\td := p.Delegate\n\tswitch message.Opcode {\n\tcase 0:\n\t\t{\n\n\t\t\tmime_typeLen := int(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\t\t\tmime_type := string(message.Data[_data_in_offset__ : _data_in_offset__+mime_typeLen-1]) // NUL-terminated\n\t\t\t// 4-byte alignment\n\t\t\tif mime_typeLen%4 != 0 {\n\t\t\t\t_data_in_offset__ += mime_typeLen + (4 - (mime_typeLen % 4))\n\t\t\t} else {\n\t\t\t\t_data_in_offset__ += mime_typeLen\n\t\t\t}\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlDataSource@\", message.ObjectID, \".offer(\")\n\t\t\t\tfmt.Println(\"mime_type: \", mime_type, \")\")\n\t\t\t}\n\n\t\t\td.WlDataSource_offer(s, ObjectID[WlDataSource](message.ObjectID), mime_type)\n\t\t\tbreak\n\t\t}\n\n\tcase 1:\n\t\t{\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlDataSource@\", message.ObjectID, \".destroy(\")\n\t\t\t\tfmt.Println(\")\")\n\t\t\t}\n\n\t\t\tautoRemove := d.WlDataSource_destroy(s, ObjectID[WlDataSource](message.ObjectID))\n\t\t\tif autoRemove {\n\t\t\t\ts.RemoveObject(message.ObjectID)\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\n\tcase 2:\n\t\t{\n\n\t\t\tdnd_actions := WlDataDeviceManagerDndAction_enum(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlDataSource@\", message.ObjectID, \".set_actions(\")\n\t\t\t\tfmt.Println(\"dnd_actions: \", dnd_actions, \")\")\n\t\t\t}\n\n\t\t\td.WlDataSource_set_actions(s, ObjectID[WlDataSource](message.ObjectID), dnd_actions)\n\t\t\tbreak\n\t\t}\n\n\tdefault:\n\t\tfmt.Println(\"Unknown opcode on WlDataSource\", message.Opcode)\n\t}\n}\n\ntype WlDataSourceError_enum uint32\n\nconst (\n\tWlDataSourceError_enum_invalid_action_mask WlDataSourceError_enum = 0\n\tWlDataSourceError_enum_invalid_source      WlDataSourceError_enum = 1\n)\n\ntype WlDataDevice_delegate interface {\n\tWlDataDevice_start_drag(s ClientState, object_id ObjectID[WlDataDevice], source *ObjectID[WlDataSource], origin ObjectID[WlSurface], icon *ObjectID[WlSurface], serial uint32)\n\tWlDataDevice_set_selection(s ClientState, object_id ObjectID[WlDataDevice], source *ObjectID[WlDataSource], serial uint32)\n\tWlDataDevice_release(s ClientState, object_id ObjectID[WlDataDevice]) bool\n\tOnBind(s ClientState, name AnyObjectID, interface_ string, new_id AnyObjectID, version_number uint32)\n}\n\ntype WlDataDevice struct {\n\tDelegate WlDataDevice_delegate\n}\n\nfunc (p *WlDataDevice) GetDelegate() WlDataDevice_delegate {\n\treturn p.Delegate\n}\nfunc (p *WlDataDevice) GetBindable() OnBindable {\n\treturn p.Delegate\n}\n\nfunc WlDataDevice_data_offer(s Sender, eventObjectID ObjectID[WlDataDevice], id ObjectID[WlDataOffer]) {\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tvar fileDescriptor *FileDescriptor\n\tputUint32(uint32(id))\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         0,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc WlDataDevice_enter(s Sender, eventObjectID ObjectID[WlDataDevice], serial uint32, surface ObjectID[WlSurface], x float32, y float32, id *ObjectID[WlDataOffer]) {\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tputInt32 := func(v int32) { putUint32(uint32(v)) }\n\tvar fileDescriptor *FileDescriptor\n\tputUint32(uint32(serial))\n\tputUint32(uint32(surface))\n\t// fixed: 24.8\n\tputInt32(int32(x * 256.0))\n\t// fixed: 24.8\n\tputInt32(int32(y * 256.0))\n\tvar __tmp_id uint32\n\tif id != nil {\n\t\t__tmp_id = uint32(*id)\n\t}\n\tputUint32(__tmp_id)\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         1,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc WlDataDevice_leave(s Sender, eventObjectID ObjectID[WlDataDevice]) {\n\tdata := make([]byte, 0)\n\tvar fileDescriptor *FileDescriptor\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         2,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc WlDataDevice_motion(s Sender, eventObjectID ObjectID[WlDataDevice], time uint32, x float32, y float32) {\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tputInt32 := func(v int32) { putUint32(uint32(v)) }\n\tvar fileDescriptor *FileDescriptor\n\tputUint32(uint32(time))\n\t// fixed: 24.8\n\tputInt32(int32(x * 256.0))\n\t// fixed: 24.8\n\tputInt32(int32(y * 256.0))\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         3,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc WlDataDevice_drop(s Sender, eventObjectID ObjectID[WlDataDevice]) {\n\tdata := make([]byte, 0)\n\tvar fileDescriptor *FileDescriptor\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         4,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc WlDataDevice_selection(s Sender, eventObjectID ObjectID[WlDataDevice], id *ObjectID[WlDataOffer]) {\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tvar fileDescriptor *FileDescriptor\n\tvar __tmp_id uint32\n\tif id != nil {\n\t\t__tmp_id = uint32(*id)\n\t}\n\tputUint32(__tmp_id)\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         5,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc (p *WlDataDevice) OnRequest(s FileDescriptorClaimClientState, message Message) {\n\t_data_in_offset__ := 0\n\t_ = _data_in_offset__\n\td := p.Delegate\n\tswitch message.Opcode {\n\tcase 0:\n\t\t{\n\n\t\t\tsourceTmp := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\t_data_in_offset__ += 4\n\t\t\tvar source *ObjectID[WlDataSource]\n\t\t\tif sourceTmp != 0 {\n\t\t\t\ttmp := ObjectID[WlDataSource](sourceTmp)\n\t\t\t\tsource = &tmp\n\t\t\t}\n\n\t\t\torigin := ObjectID[WlSurface](uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\ticonTmp := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\t_data_in_offset__ += 4\n\t\t\tvar icon *ObjectID[WlSurface]\n\t\t\tif iconTmp != 0 {\n\t\t\t\ttmp := ObjectID[WlSurface](iconTmp)\n\t\t\t\ticon = &tmp\n\t\t\t}\n\n\t\t\tserial := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlDataDevice@\", message.ObjectID, \".start_drag(\")\n\t\t\t\tfmt.Println(\"source: \", source, \", \", \"origin: \", origin, \", \", \"icon: \", icon, \", \", \"serial: \", serial, \")\")\n\t\t\t}\n\n\t\t\td.WlDataDevice_start_drag(s, ObjectID[WlDataDevice](message.ObjectID), source, origin, icon, serial)\n\t\t\tbreak\n\t\t}\n\n\tcase 1:\n\t\t{\n\n\t\t\tsourceTmp := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\t_data_in_offset__ += 4\n\t\t\tvar source *ObjectID[WlDataSource]\n\t\t\tif sourceTmp != 0 {\n\t\t\t\ttmp := ObjectID[WlDataSource](sourceTmp)\n\t\t\t\tsource = &tmp\n\t\t\t}\n\n\t\t\tserial := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlDataDevice@\", message.ObjectID, \".set_selection(\")\n\t\t\t\tfmt.Println(\"source: \", source, \", \", \"serial: \", serial, \")\")\n\t\t\t}\n\n\t\t\td.WlDataDevice_set_selection(s, ObjectID[WlDataDevice](message.ObjectID), source, serial)\n\t\t\tbreak\n\t\t}\n\n\tcase 2:\n\t\t{\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlDataDevice@\", message.ObjectID, \".release(\")\n\t\t\t\tfmt.Println(\")\")\n\t\t\t}\n\n\t\t\tautoRemove := d.WlDataDevice_release(s, ObjectID[WlDataDevice](message.ObjectID))\n\t\t\tif autoRemove {\n\t\t\t\ts.RemoveObject(message.ObjectID)\n\t\t\t\ts.RemoveGlobalWlDataDeviceBind(ObjectID[WlDataDevice](message.ObjectID))\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\n\tdefault:\n\t\tfmt.Println(\"Unknown opcode on WlDataDevice\", message.Opcode)\n\t}\n}\n\ntype WlDataDeviceError_enum uint32\n\nconst (\n\tWlDataDeviceError_enum_role        WlDataDeviceError_enum = 0\n\tWlDataDeviceError_enum_used_source WlDataDeviceError_enum = 1\n)\n\ntype WlDataDeviceManager_delegate interface {\n\tWlDataDeviceManager_create_data_source(s ClientState, object_id ObjectID[WlDataDeviceManager], id ObjectID[WlDataSource])\n\tWlDataDeviceManager_get_data_device(s ClientState, object_id ObjectID[WlDataDeviceManager], id ObjectID[WlDataDevice], seat ObjectID[WlSeat])\n\tOnBind(s ClientState, name AnyObjectID, interface_ string, new_id AnyObjectID, version_number uint32)\n}\n\ntype WlDataDeviceManager struct {\n\tDelegate WlDataDeviceManager_delegate\n}\n\nfunc (p *WlDataDeviceManager) GetDelegate() WlDataDeviceManager_delegate {\n\treturn p.Delegate\n}\nfunc (p *WlDataDeviceManager) GetBindable() OnBindable {\n\treturn p.Delegate\n}\n\nfunc (p *WlDataDeviceManager) OnRequest(s FileDescriptorClaimClientState, message Message) {\n\t_data_in_offset__ := 0\n\t_ = _data_in_offset__\n\td := p.Delegate\n\tswitch message.Opcode {\n\tcase 0:\n\t\t{\n\n\t\t\tidVal := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\tid := ObjectID[WlDataSource](idVal)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlDataDeviceManager@\", message.ObjectID, \".create_data_source(\")\n\t\t\t\tfmt.Println(\"id: \", id, \")\")\n\t\t\t}\n\n\t\t\td.WlDataDeviceManager_create_data_source(s, ObjectID[WlDataDeviceManager](message.ObjectID), id)\n\t\t\tbreak\n\t\t}\n\n\tcase 1:\n\t\t{\n\n\t\t\tidVal := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\tid := ObjectID[WlDataDevice](idVal)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tseat := ObjectID[WlSeat](uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlDataDeviceManager@\", message.ObjectID, \".get_data_device(\")\n\t\t\t\tfmt.Println(\"id: \", id, \", \", \"seat: \", seat, \")\")\n\t\t\t}\n\n\t\t\td.WlDataDeviceManager_get_data_device(s, ObjectID[WlDataDeviceManager](message.ObjectID), id, seat)\n\t\t\tbreak\n\t\t}\n\n\tdefault:\n\t\tfmt.Println(\"Unknown opcode on WlDataDeviceManager\", message.Opcode)\n\t}\n}\n\ntype WlDataDeviceManagerDndAction_enum uint32\n\nconst (\n\tWlDataDeviceManagerDndAction_enum_none WlDataDeviceManagerDndAction_enum = 0\n\tWlDataDeviceManagerDndAction_enum_copy WlDataDeviceManagerDndAction_enum = 1\n\tWlDataDeviceManagerDndAction_enum_move WlDataDeviceManagerDndAction_enum = 2\n\tWlDataDeviceManagerDndAction_enum_ask  WlDataDeviceManagerDndAction_enum = 4\n)\n\ntype WlShell_delegate interface {\n\tWlShell_get_shell_surface(s ClientState, object_id ObjectID[WlShell], id ObjectID[WlShellSurface], surface ObjectID[WlSurface])\n\tOnBind(s ClientState, name AnyObjectID, interface_ string, new_id AnyObjectID, version_number uint32)\n}\n\ntype WlShell struct {\n\tDelegate WlShell_delegate\n}\n\nfunc (p *WlShell) GetDelegate() WlShell_delegate {\n\treturn p.Delegate\n}\nfunc (p *WlShell) GetBindable() OnBindable {\n\treturn p.Delegate\n}\n\nfunc (p *WlShell) OnRequest(s FileDescriptorClaimClientState, message Message) {\n\t_data_in_offset__ := 0\n\t_ = _data_in_offset__\n\td := p.Delegate\n\tswitch message.Opcode {\n\tcase 0:\n\t\t{\n\n\t\t\tidVal := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\tid := ObjectID[WlShellSurface](idVal)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tsurface := ObjectID[WlSurface](uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlShell@\", message.ObjectID, \".get_shell_surface(\")\n\t\t\t\tfmt.Println(\"id: \", id, \", \", \"surface: \", surface, \")\")\n\t\t\t}\n\n\t\t\td.WlShell_get_shell_surface(s, ObjectID[WlShell](message.ObjectID), id, surface)\n\t\t\tbreak\n\t\t}\n\n\tdefault:\n\t\tfmt.Println(\"Unknown opcode on WlShell\", message.Opcode)\n\t}\n}\n\ntype WlShellError_enum uint32\n\nconst (\n\tWlShellError_enum_role WlShellError_enum = 0\n)\n\ntype WlShellSurface_delegate interface {\n\tWlShellSurface_pong(s ClientState, object_id ObjectID[WlShellSurface], serial uint32)\n\tWlShellSurface_move(s ClientState, object_id ObjectID[WlShellSurface], seat ObjectID[WlSeat], serial uint32)\n\tWlShellSurface_resize(s ClientState, object_id ObjectID[WlShellSurface], seat ObjectID[WlSeat], serial uint32, edges WlShellSurfaceResize_enum)\n\tWlShellSurface_set_toplevel(s ClientState, object_id ObjectID[WlShellSurface])\n\tWlShellSurface_set_transient(s ClientState, object_id ObjectID[WlShellSurface], parent ObjectID[WlSurface], x int32, y int32, flags WlShellSurfaceTransient_enum)\n\tWlShellSurface_set_fullscreen(s ClientState, object_id ObjectID[WlShellSurface], method WlShellSurfaceFullscreenMethod_enum, framerate uint32, output *ObjectID[WlOutput])\n\tWlShellSurface_set_popup(s ClientState, object_id ObjectID[WlShellSurface], seat ObjectID[WlSeat], serial uint32, parent ObjectID[WlSurface], x int32, y int32, flags WlShellSurfaceTransient_enum)\n\tWlShellSurface_set_maximized(s ClientState, object_id ObjectID[WlShellSurface], output *ObjectID[WlOutput])\n\tWlShellSurface_set_title(s ClientState, object_id ObjectID[WlShellSurface], title string)\n\tWlShellSurface_set_class(s ClientState, object_id ObjectID[WlShellSurface], class_ string)\n\tOnBind(s ClientState, name AnyObjectID, interface_ string, new_id AnyObjectID, version_number uint32)\n}\n\ntype WlShellSurface struct {\n\tDelegate WlShellSurface_delegate\n}\n\nfunc (p *WlShellSurface) GetDelegate() WlShellSurface_delegate {\n\treturn p.Delegate\n}\nfunc (p *WlShellSurface) GetBindable() OnBindable {\n\treturn p.Delegate\n}\n\nfunc WlShellSurface_ping(s Sender, eventObjectID ObjectID[WlShellSurface], serial uint32) {\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tvar fileDescriptor *FileDescriptor\n\tputUint32(uint32(serial))\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         0,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc WlShellSurface_configure(s Sender, eventObjectID ObjectID[WlShellSurface], edges WlShellSurfaceResize_enum, width int32, height int32) {\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tputInt32 := func(v int32) { putUint32(uint32(v)) }\n\tvar fileDescriptor *FileDescriptor\n\tputUint32(uint32(edges))\n\tputInt32(int32(width))\n\tputInt32(int32(height))\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         1,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc WlShellSurface_popup_done(s Sender, eventObjectID ObjectID[WlShellSurface]) {\n\tdata := make([]byte, 0)\n\tvar fileDescriptor *FileDescriptor\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         2,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc (p *WlShellSurface) OnRequest(s FileDescriptorClaimClientState, message Message) {\n\t_data_in_offset__ := 0\n\t_ = _data_in_offset__\n\td := p.Delegate\n\tswitch message.Opcode {\n\tcase 0:\n\t\t{\n\n\t\t\tserial := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlShellSurface@\", message.ObjectID, \".pong(\")\n\t\t\t\tfmt.Println(\"serial: \", serial, \")\")\n\t\t\t}\n\n\t\t\td.WlShellSurface_pong(s, ObjectID[WlShellSurface](message.ObjectID), serial)\n\t\t\tbreak\n\t\t}\n\n\tcase 1:\n\t\t{\n\n\t\t\tseat := ObjectID[WlSeat](uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tserial := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlShellSurface@\", message.ObjectID, \".move(\")\n\t\t\t\tfmt.Println(\"seat: \", seat, \", \", \"serial: \", serial, \")\")\n\t\t\t}\n\n\t\t\td.WlShellSurface_move(s, ObjectID[WlShellSurface](message.ObjectID), seat, serial)\n\t\t\tbreak\n\t\t}\n\n\tcase 2:\n\t\t{\n\n\t\t\tseat := ObjectID[WlSeat](uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tserial := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tedges := WlShellSurfaceResize_enum(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlShellSurface@\", message.ObjectID, \".resize(\")\n\t\t\t\tfmt.Println(\"seat: \", seat, \", \", \"serial: \", serial, \", \", \"edges: \", edges, \")\")\n\t\t\t}\n\n\t\t\td.WlShellSurface_resize(s, ObjectID[WlShellSurface](message.ObjectID), seat, serial, edges)\n\t\t\tbreak\n\t\t}\n\n\tcase 3:\n\t\t{\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlShellSurface@\", message.ObjectID, \".set_toplevel(\")\n\t\t\t\tfmt.Println(\")\")\n\t\t\t}\n\n\t\t\td.WlShellSurface_set_toplevel(s, ObjectID[WlShellSurface](message.ObjectID))\n\t\t\tbreak\n\t\t}\n\n\tcase 4:\n\t\t{\n\n\t\t\tparent := ObjectID[WlSurface](uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tx := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\ty := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tflags := WlShellSurfaceTransient_enum(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlShellSurface@\", message.ObjectID, \".set_transient(\")\n\t\t\t\tfmt.Println(\"parent: \", parent, \", \", \"x: \", x, \", \", \"y: \", y, \", \", \"flags: \", flags, \")\")\n\t\t\t}\n\n\t\t\td.WlShellSurface_set_transient(s, ObjectID[WlShellSurface](message.ObjectID), parent, x, y, flags)\n\t\t\tbreak\n\t\t}\n\n\tcase 5:\n\t\t{\n\n\t\t\tmethod := WlShellSurfaceFullscreenMethod_enum(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tframerate := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\t_data_in_offset__ += 4\n\n\t\t\toutputTmp := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\t_data_in_offset__ += 4\n\t\t\tvar output *ObjectID[WlOutput]\n\t\t\tif outputTmp != 0 {\n\t\t\t\ttmp := ObjectID[WlOutput](outputTmp)\n\t\t\t\toutput = &tmp\n\t\t\t}\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlShellSurface@\", message.ObjectID, \".set_fullscreen(\")\n\t\t\t\tfmt.Println(\"method: \", method, \", \", \"framerate: \", framerate, \", \", \"output: \", output, \")\")\n\t\t\t}\n\n\t\t\td.WlShellSurface_set_fullscreen(s, ObjectID[WlShellSurface](message.ObjectID), method, framerate, output)\n\t\t\tbreak\n\t\t}\n\n\tcase 6:\n\t\t{\n\n\t\t\tseat := ObjectID[WlSeat](uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tserial := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tparent := ObjectID[WlSurface](uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tx := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\ty := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tflags := WlShellSurfaceTransient_enum(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlShellSurface@\", message.ObjectID, \".set_popup(\")\n\t\t\t\tfmt.Println(\"seat: \", seat, \", \", \"serial: \", serial, \", \", \"parent: \", parent, \", \", \"x: \", x, \", \", \"y: \", y, \", \", \"flags: \", flags, \")\")\n\t\t\t}\n\n\t\t\td.WlShellSurface_set_popup(s, ObjectID[WlShellSurface](message.ObjectID), seat, serial, parent, x, y, flags)\n\t\t\tbreak\n\t\t}\n\n\tcase 7:\n\t\t{\n\n\t\t\toutputTmp := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\t_data_in_offset__ += 4\n\t\t\tvar output *ObjectID[WlOutput]\n\t\t\tif outputTmp != 0 {\n\t\t\t\ttmp := ObjectID[WlOutput](outputTmp)\n\t\t\t\toutput = &tmp\n\t\t\t}\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlShellSurface@\", message.ObjectID, \".set_maximized(\")\n\t\t\t\tfmt.Println(\"output: \", output, \")\")\n\t\t\t}\n\n\t\t\td.WlShellSurface_set_maximized(s, ObjectID[WlShellSurface](message.ObjectID), output)\n\t\t\tbreak\n\t\t}\n\n\tcase 8:\n\t\t{\n\n\t\t\ttitleLen := int(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\t\t\ttitle := string(message.Data[_data_in_offset__ : _data_in_offset__+titleLen-1]) // NUL-terminated\n\t\t\t// 4-byte alignment\n\t\t\tif titleLen%4 != 0 {\n\t\t\t\t_data_in_offset__ += titleLen + (4 - (titleLen % 4))\n\t\t\t} else {\n\t\t\t\t_data_in_offset__ += titleLen\n\t\t\t}\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlShellSurface@\", message.ObjectID, \".set_title(\")\n\t\t\t\tfmt.Println(\"title: \", title, \")\")\n\t\t\t}\n\n\t\t\td.WlShellSurface_set_title(s, ObjectID[WlShellSurface](message.ObjectID), title)\n\t\t\tbreak\n\t\t}\n\n\tcase 9:\n\t\t{\n\n\t\t\tclass_Len := int(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\t\t\tclass_ := string(message.Data[_data_in_offset__ : _data_in_offset__+class_Len-1]) // NUL-terminated\n\t\t\t// 4-byte alignment\n\t\t\tif class_Len%4 != 0 {\n\t\t\t\t_data_in_offset__ += class_Len + (4 - (class_Len % 4))\n\t\t\t} else {\n\t\t\t\t_data_in_offset__ += class_Len\n\t\t\t}\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlShellSurface@\", message.ObjectID, \".set_class(\")\n\t\t\t\tfmt.Println(\"class_: \", class_, \")\")\n\t\t\t}\n\n\t\t\td.WlShellSurface_set_class(s, ObjectID[WlShellSurface](message.ObjectID), class_)\n\t\t\tbreak\n\t\t}\n\n\tdefault:\n\t\tfmt.Println(\"Unknown opcode on WlShellSurface\", message.Opcode)\n\t}\n}\n\ntype WlShellSurfaceResize_enum uint32\n\nconst (\n\tWlShellSurfaceResize_enum_none         WlShellSurfaceResize_enum = 0\n\tWlShellSurfaceResize_enum_top          WlShellSurfaceResize_enum = 1\n\tWlShellSurfaceResize_enum_bottom       WlShellSurfaceResize_enum = 2\n\tWlShellSurfaceResize_enum_left         WlShellSurfaceResize_enum = 4\n\tWlShellSurfaceResize_enum_top_left     WlShellSurfaceResize_enum = 5\n\tWlShellSurfaceResize_enum_bottom_left  WlShellSurfaceResize_enum = 6\n\tWlShellSurfaceResize_enum_right        WlShellSurfaceResize_enum = 8\n\tWlShellSurfaceResize_enum_top_right    WlShellSurfaceResize_enum = 9\n\tWlShellSurfaceResize_enum_bottom_right WlShellSurfaceResize_enum = 10\n)\n\ntype WlShellSurfaceTransient_enum uint32\n\nconst (\n\tWlShellSurfaceTransient_enum_inactive WlShellSurfaceTransient_enum = 0x1\n)\n\ntype WlShellSurfaceFullscreenMethod_enum uint32\n\nconst (\n\tWlShellSurfaceFullscreenMethod_enum_default_ WlShellSurfaceFullscreenMethod_enum = 0\n\tWlShellSurfaceFullscreenMethod_enum_scale    WlShellSurfaceFullscreenMethod_enum = 1\n\tWlShellSurfaceFullscreenMethod_enum_driver   WlShellSurfaceFullscreenMethod_enum = 2\n\tWlShellSurfaceFullscreenMethod_enum_fill     WlShellSurfaceFullscreenMethod_enum = 3\n)\n\ntype WlSurface_delegate interface {\n\tWlSurface_destroy(s ClientState, object_id ObjectID[WlSurface]) bool\n\tWlSurface_attach(s ClientState, object_id ObjectID[WlSurface], buffer *ObjectID[WlBuffer], x int32, y int32)\n\tWlSurface_damage(s ClientState, object_id ObjectID[WlSurface], x int32, y int32, width int32, height int32)\n\tWlSurface_frame(s ClientState, object_id ObjectID[WlSurface], callback ObjectID[WlCallback])\n\tWlSurface_set_opaque_region(s ClientState, object_id ObjectID[WlSurface], region *ObjectID[WlRegion])\n\tWlSurface_set_input_region(s ClientState, object_id ObjectID[WlSurface], region *ObjectID[WlRegion])\n\tWlSurface_commit(s ClientState, object_id ObjectID[WlSurface])\n\tWlSurface_set_buffer_transform(s ClientState, object_id ObjectID[WlSurface], transform int32)\n\tWlSurface_set_buffer_scale(s ClientState, object_id ObjectID[WlSurface], scale int32)\n\tWlSurface_damage_buffer(s ClientState, object_id ObjectID[WlSurface], x int32, y int32, width int32, height int32)\n\tWlSurface_offset(s ClientState, object_id ObjectID[WlSurface], x int32, y int32)\n\tOnBind(s ClientState, name AnyObjectID, interface_ string, new_id AnyObjectID, version_number uint32)\n}\n\ntype WlSurface struct {\n\tDelegate WlSurface_delegate\n}\n\nfunc (p *WlSurface) GetDelegate() WlSurface_delegate {\n\treturn p.Delegate\n}\nfunc (p *WlSurface) GetBindable() OnBindable {\n\treturn p.Delegate\n}\n\nfunc WlSurface_enter(s Sender, eventObjectID ObjectID[WlSurface], output ObjectID[WlOutput]) {\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tvar fileDescriptor *FileDescriptor\n\tputUint32(uint32(output))\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         0,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc WlSurface_leave(s Sender, eventObjectID ObjectID[WlSurface], output ObjectID[WlOutput]) {\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tvar fileDescriptor *FileDescriptor\n\tputUint32(uint32(output))\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         1,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc WlSurface_preferred_buffer_scale(s Sender, boundVersion uint32, eventObjectID ObjectID[WlSurface], factor int32) {\n\tif boundVersion < 6 {\n\t\t// Event not available in this version; skip\n\t\treturn\n\t}\n\tdata := make([]byte, 0)\n\tputInt32 := func(v int32) { uv := uint32(v); data = append(data, byte(uv), byte(uv>>8), byte(uv>>16), byte(uv>>24)) }\n\tvar fileDescriptor *FileDescriptor\n\tputInt32(int32(factor))\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         2,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc WlSurface_preferred_buffer_transform(s Sender, boundVersion uint32, eventObjectID ObjectID[WlSurface], transform WlOutputTransform_enum) {\n\tif boundVersion < 6 {\n\t\t// Event not available in this version; skip\n\t\treturn\n\t}\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tvar fileDescriptor *FileDescriptor\n\tputUint32(uint32(transform))\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         3,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc (p *WlSurface) OnRequest(s FileDescriptorClaimClientState, message Message) {\n\t_data_in_offset__ := 0\n\t_ = _data_in_offset__\n\td := p.Delegate\n\tswitch message.Opcode {\n\tcase 0:\n\t\t{\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlSurface@\", message.ObjectID, \".destroy(\")\n\t\t\t\tfmt.Println(\")\")\n\t\t\t}\n\n\t\t\tautoRemove := d.WlSurface_destroy(s, ObjectID[WlSurface](message.ObjectID))\n\t\t\tif autoRemove {\n\t\t\t\ts.RemoveObject(message.ObjectID)\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\n\tcase 1:\n\t\t{\n\n\t\t\tbufferTmp := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\t_data_in_offset__ += 4\n\t\t\tvar buffer *ObjectID[WlBuffer]\n\t\t\tif bufferTmp != 0 {\n\t\t\t\ttmp := ObjectID[WlBuffer](bufferTmp)\n\t\t\t\tbuffer = &tmp\n\t\t\t}\n\n\t\t\tx := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\ty := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlSurface@\", message.ObjectID, \".attach(\")\n\t\t\t\tfmt.Println(\"buffer: \", buffer, \", \", \"x: \", x, \", \", \"y: \", y, \")\")\n\t\t\t}\n\n\t\t\td.WlSurface_attach(s, ObjectID[WlSurface](message.ObjectID), buffer, x, y)\n\t\t\tbreak\n\t\t}\n\n\tcase 2:\n\t\t{\n\n\t\t\tx := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\ty := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\twidth := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\theight := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlSurface@\", message.ObjectID, \".damage(\")\n\t\t\t\tfmt.Println(\"x: \", x, \", \", \"y: \", y, \", \", \"width: \", width, \", \", \"height: \", height, \")\")\n\t\t\t}\n\n\t\t\td.WlSurface_damage(s, ObjectID[WlSurface](message.ObjectID), x, y, width, height)\n\t\t\tbreak\n\t\t}\n\n\tcase 3:\n\t\t{\n\n\t\t\tcallbackVal := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\tcallback := ObjectID[WlCallback](callbackVal)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlSurface@\", message.ObjectID, \".frame(\")\n\t\t\t\tfmt.Println(\"callback: \", callback, \")\")\n\t\t\t}\n\n\t\t\td.WlSurface_frame(s, ObjectID[WlSurface](message.ObjectID), callback)\n\t\t\tbreak\n\t\t}\n\n\tcase 4:\n\t\t{\n\n\t\t\tregionTmp := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\t_data_in_offset__ += 4\n\t\t\tvar region *ObjectID[WlRegion]\n\t\t\tif regionTmp != 0 {\n\t\t\t\ttmp := ObjectID[WlRegion](regionTmp)\n\t\t\t\tregion = &tmp\n\t\t\t}\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlSurface@\", message.ObjectID, \".set_opaque_region(\")\n\t\t\t\tfmt.Println(\"region: \", region, \")\")\n\t\t\t}\n\n\t\t\td.WlSurface_set_opaque_region(s, ObjectID[WlSurface](message.ObjectID), region)\n\t\t\tbreak\n\t\t}\n\n\tcase 5:\n\t\t{\n\n\t\t\tregionTmp := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\t_data_in_offset__ += 4\n\t\t\tvar region *ObjectID[WlRegion]\n\t\t\tif regionTmp != 0 {\n\t\t\t\ttmp := ObjectID[WlRegion](regionTmp)\n\t\t\t\tregion = &tmp\n\t\t\t}\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlSurface@\", message.ObjectID, \".set_input_region(\")\n\t\t\t\tfmt.Println(\"region: \", region, \")\")\n\t\t\t}\n\n\t\t\td.WlSurface_set_input_region(s, ObjectID[WlSurface](message.ObjectID), region)\n\t\t\tbreak\n\t\t}\n\n\tcase 6:\n\t\t{\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlSurface@\", message.ObjectID, \".commit(\")\n\t\t\t\tfmt.Println(\")\")\n\t\t\t}\n\n\t\t\td.WlSurface_commit(s, ObjectID[WlSurface](message.ObjectID))\n\t\t\tbreak\n\t\t}\n\n\tcase 7:\n\t\t{\n\n\t\t\ttransform := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlSurface@\", message.ObjectID, \".set_buffer_transform(\")\n\t\t\t\tfmt.Println(\"transform: \", transform, \")\")\n\t\t\t}\n\n\t\t\td.WlSurface_set_buffer_transform(s, ObjectID[WlSurface](message.ObjectID), transform)\n\t\t\tbreak\n\t\t}\n\n\tcase 8:\n\t\t{\n\n\t\t\tscale := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlSurface@\", message.ObjectID, \".set_buffer_scale(\")\n\t\t\t\tfmt.Println(\"scale: \", scale, \")\")\n\t\t\t}\n\n\t\t\td.WlSurface_set_buffer_scale(s, ObjectID[WlSurface](message.ObjectID), scale)\n\t\t\tbreak\n\t\t}\n\n\tcase 9:\n\t\t{\n\n\t\t\tx := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\ty := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\twidth := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\theight := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlSurface@\", message.ObjectID, \".damage_buffer(\")\n\t\t\t\tfmt.Println(\"x: \", x, \", \", \"y: \", y, \", \", \"width: \", width, \", \", \"height: \", height, \")\")\n\t\t\t}\n\n\t\t\td.WlSurface_damage_buffer(s, ObjectID[WlSurface](message.ObjectID), x, y, width, height)\n\t\t\tbreak\n\t\t}\n\n\tcase 10:\n\t\t{\n\n\t\t\tx := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\ty := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlSurface@\", message.ObjectID, \".offset(\")\n\t\t\t\tfmt.Println(\"x: \", x, \", \", \"y: \", y, \")\")\n\t\t\t}\n\n\t\t\td.WlSurface_offset(s, ObjectID[WlSurface](message.ObjectID), x, y)\n\t\t\tbreak\n\t\t}\n\n\tdefault:\n\t\tfmt.Println(\"Unknown opcode on WlSurface\", message.Opcode)\n\t}\n}\n\ntype WlSurfaceError_enum uint32\n\nconst (\n\tWlSurfaceError_enum_invalid_scale       WlSurfaceError_enum = 0\n\tWlSurfaceError_enum_invalid_transform   WlSurfaceError_enum = 1\n\tWlSurfaceError_enum_invalid_size        WlSurfaceError_enum = 2\n\tWlSurfaceError_enum_invalid_offset      WlSurfaceError_enum = 3\n\tWlSurfaceError_enum_defunct_role_object WlSurfaceError_enum = 4\n)\n\ntype WlSeat_delegate interface {\n\tWlSeat_get_pointer(s ClientState, object_id ObjectID[WlSeat], id ObjectID[WlPointer])\n\tWlSeat_get_keyboard(s ClientState, object_id ObjectID[WlSeat], id ObjectID[WlKeyboard])\n\tWlSeat_get_touch(s ClientState, object_id ObjectID[WlSeat], id ObjectID[WlTouch])\n\tWlSeat_release(s ClientState, object_id ObjectID[WlSeat]) bool\n\tOnBind(s ClientState, name AnyObjectID, interface_ string, new_id AnyObjectID, version_number uint32)\n}\n\ntype WlSeat struct {\n\tDelegate WlSeat_delegate\n}\n\nfunc (p *WlSeat) GetDelegate() WlSeat_delegate {\n\treturn p.Delegate\n}\nfunc (p *WlSeat) GetBindable() OnBindable {\n\treturn p.Delegate\n}\n\nfunc WlSeat_capabilities(s Sender, eventObjectID ObjectID[WlSeat], capabilities WlSeatCapability_enum) {\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tvar fileDescriptor *FileDescriptor\n\tputUint32(uint32(capabilities))\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         0,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc WlSeat_name(s Sender, boundVersion uint32, eventObjectID ObjectID[WlSeat], name string) {\n\tif boundVersion < 2 {\n\t\t// Event not available in this version; skip\n\t\treturn\n\t}\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tvar fileDescriptor *FileDescriptor\n\t{\n\t\tb := []byte(name)\n\t\ttotal := len(b) + 1 // include null terminator\n\t\tputUint32(uint32(total))\n\t\tdata = append(data, b...)\n\t\tdata = append(data, 0)\n\t\tif pad := (4 - (total % 4)) % 4; pad != 0 {\n\t\t\tdata = append(data, make([]byte, pad)...)\n\t\t}\n\t}\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         1,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc (p *WlSeat) OnRequest(s FileDescriptorClaimClientState, message Message) {\n\t_data_in_offset__ := 0\n\t_ = _data_in_offset__\n\td := p.Delegate\n\tswitch message.Opcode {\n\tcase 0:\n\t\t{\n\n\t\t\tidVal := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\tid := ObjectID[WlPointer](idVal)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlSeat@\", message.ObjectID, \".get_pointer(\")\n\t\t\t\tfmt.Println(\"id: \", id, \")\")\n\t\t\t}\n\n\t\t\td.WlSeat_get_pointer(s, ObjectID[WlSeat](message.ObjectID), id)\n\t\t\tbreak\n\t\t}\n\n\tcase 1:\n\t\t{\n\n\t\t\tidVal := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\tid := ObjectID[WlKeyboard](idVal)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlSeat@\", message.ObjectID, \".get_keyboard(\")\n\t\t\t\tfmt.Println(\"id: \", id, \")\")\n\t\t\t}\n\n\t\t\td.WlSeat_get_keyboard(s, ObjectID[WlSeat](message.ObjectID), id)\n\t\t\tbreak\n\t\t}\n\n\tcase 2:\n\t\t{\n\n\t\t\tidVal := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\tid := ObjectID[WlTouch](idVal)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlSeat@\", message.ObjectID, \".get_touch(\")\n\t\t\t\tfmt.Println(\"id: \", id, \")\")\n\t\t\t}\n\n\t\t\td.WlSeat_get_touch(s, ObjectID[WlSeat](message.ObjectID), id)\n\t\t\tbreak\n\t\t}\n\n\tcase 3:\n\t\t{\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlSeat@\", message.ObjectID, \".release(\")\n\t\t\t\tfmt.Println(\")\")\n\t\t\t}\n\n\t\t\tautoRemove := d.WlSeat_release(s, ObjectID[WlSeat](message.ObjectID))\n\t\t\tif autoRemove {\n\t\t\t\ts.RemoveObject(message.ObjectID)\n\t\t\t\ts.RemoveGlobalWlSeatBind(ObjectID[WlSeat](message.ObjectID))\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\n\tdefault:\n\t\tfmt.Println(\"Unknown opcode on WlSeat\", message.Opcode)\n\t}\n}\n\ntype WlSeatCapability_enum uint32\n\nconst (\n\tWlSeatCapability_enum_pointer  WlSeatCapability_enum = 1\n\tWlSeatCapability_enum_keyboard WlSeatCapability_enum = 2\n\tWlSeatCapability_enum_touch    WlSeatCapability_enum = 4\n)\n\ntype WlSeatError_enum uint32\n\nconst (\n\tWlSeatError_enum_missing_capability WlSeatError_enum = 0\n)\n\ntype WlPointer_delegate interface {\n\tWlPointer_set_cursor(s ClientState, object_id ObjectID[WlPointer], serial uint32, surface *ObjectID[WlSurface], hotspot_x int32, hotspot_y int32)\n\tWlPointer_release(s ClientState, object_id ObjectID[WlPointer]) bool\n\tOnBind(s ClientState, name AnyObjectID, interface_ string, new_id AnyObjectID, version_number uint32)\n\tAfterGetPointer(s ClientState, object_id ObjectID[WlPointer])\n}\n\ntype WlPointer struct {\n\tDelegate WlPointer_delegate\n}\n\nfunc (p *WlPointer) GetDelegate() WlPointer_delegate {\n\treturn p.Delegate\n}\nfunc (p *WlPointer) GetBindable() OnBindable {\n\treturn p.Delegate\n}\n\nfunc WlPointer_enter(s Sender, eventObjectID ObjectID[WlPointer], serial uint32, surface ObjectID[WlSurface], surface_x float32, surface_y float32) {\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tputInt32 := func(v int32) { putUint32(uint32(v)) }\n\tvar fileDescriptor *FileDescriptor\n\tputUint32(uint32(serial))\n\tputUint32(uint32(surface))\n\t// fixed: 24.8\n\tputInt32(int32(surface_x * 256.0))\n\t// fixed: 24.8\n\tputInt32(int32(surface_y * 256.0))\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         0,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc WlPointer_leave(s Sender, eventObjectID ObjectID[WlPointer], serial uint32, surface ObjectID[WlSurface]) {\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tvar fileDescriptor *FileDescriptor\n\tputUint32(uint32(serial))\n\tputUint32(uint32(surface))\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         1,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc WlPointer_motion(s Sender, eventObjectID ObjectID[WlPointer], time uint32, surface_x float32, surface_y float32) {\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tputInt32 := func(v int32) { putUint32(uint32(v)) }\n\tvar fileDescriptor *FileDescriptor\n\tputUint32(uint32(time))\n\t// fixed: 24.8\n\tputInt32(int32(surface_x * 256.0))\n\t// fixed: 24.8\n\tputInt32(int32(surface_y * 256.0))\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         2,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc WlPointer_button(s Sender, eventObjectID ObjectID[WlPointer], serial uint32, time uint32, button uint32, state WlPointerButtonState_enum) {\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tvar fileDescriptor *FileDescriptor\n\tputUint32(uint32(serial))\n\tputUint32(uint32(time))\n\tputUint32(uint32(button))\n\tputUint32(uint32(state))\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         3,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc WlPointer_axis(s Sender, eventObjectID ObjectID[WlPointer], time uint32, axis WlPointerAxis_enum, value float32) {\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tputInt32 := func(v int32) { putUint32(uint32(v)) }\n\tvar fileDescriptor *FileDescriptor\n\tputUint32(uint32(time))\n\tputUint32(uint32(axis))\n\t// fixed: 24.8\n\tputInt32(int32(value * 256.0))\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         4,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc WlPointer_frame(s Sender, boundVersion uint32, eventObjectID ObjectID[WlPointer]) {\n\tif boundVersion < 5 {\n\t\t// Event not available in this version; skip\n\t\treturn\n\t}\n\tdata := make([]byte, 0)\n\tvar fileDescriptor *FileDescriptor\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         5,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc WlPointer_axis_source(s Sender, boundVersion uint32, eventObjectID ObjectID[WlPointer], axis_source WlPointerAxisSource_enum) {\n\tif boundVersion < 5 {\n\t\t// Event not available in this version; skip\n\t\treturn\n\t}\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tvar fileDescriptor *FileDescriptor\n\tputUint32(uint32(axis_source))\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         6,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc WlPointer_axis_stop(s Sender, boundVersion uint32, eventObjectID ObjectID[WlPointer], time uint32, axis WlPointerAxis_enum) {\n\tif boundVersion < 5 {\n\t\t// Event not available in this version; skip\n\t\treturn\n\t}\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tvar fileDescriptor *FileDescriptor\n\tputUint32(uint32(time))\n\tputUint32(uint32(axis))\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         7,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc WlPointer_axis_discrete(s Sender, boundVersion uint32, eventObjectID ObjectID[WlPointer], axis WlPointerAxis_enum, discrete int32) {\n\tif boundVersion < 5 {\n\t\t// Event not available in this version; skip\n\t\treturn\n\t}\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tputInt32 := func(v int32) { putUint32(uint32(v)) }\n\tvar fileDescriptor *FileDescriptor\n\tputUint32(uint32(axis))\n\tputInt32(int32(discrete))\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         8,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc WlPointer_axis_value120(s Sender, boundVersion uint32, eventObjectID ObjectID[WlPointer], axis WlPointerAxis_enum, value120 int32) {\n\tif boundVersion < 8 {\n\t\t// Event not available in this version; skip\n\t\treturn\n\t}\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tputInt32 := func(v int32) { putUint32(uint32(v)) }\n\tvar fileDescriptor *FileDescriptor\n\tputUint32(uint32(axis))\n\tputInt32(int32(value120))\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         9,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc WlPointer_axis_relative_direction(s Sender, boundVersion uint32, eventObjectID ObjectID[WlPointer], axis WlPointerAxis_enum, direction WlPointerAxisRelativeDirection_enum) {\n\tif boundVersion < 9 {\n\t\t// Event not available in this version; skip\n\t\treturn\n\t}\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tvar fileDescriptor *FileDescriptor\n\tputUint32(uint32(axis))\n\tputUint32(uint32(direction))\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         10,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc (p *WlPointer) OnRequest(s FileDescriptorClaimClientState, message Message) {\n\t_data_in_offset__ := 0\n\t_ = _data_in_offset__\n\td := p.Delegate\n\tswitch message.Opcode {\n\tcase 0:\n\t\t{\n\n\t\t\tserial := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tsurfaceTmp := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\t_data_in_offset__ += 4\n\t\t\tvar surface *ObjectID[WlSurface]\n\t\t\tif surfaceTmp != 0 {\n\t\t\t\ttmp := ObjectID[WlSurface](surfaceTmp)\n\t\t\t\tsurface = &tmp\n\t\t\t}\n\n\t\t\thotspot_x := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\thotspot_y := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlPointer@\", message.ObjectID, \".set_cursor(\")\n\t\t\t\tfmt.Println(\"serial: \", serial, \", \", \"surface: \", surface, \", \", \"hotspot_x: \", hotspot_x, \", \", \"hotspot_y: \", hotspot_y, \")\")\n\t\t\t}\n\n\t\t\td.WlPointer_set_cursor(s, ObjectID[WlPointer](message.ObjectID), serial, surface, hotspot_x, hotspot_y)\n\t\t\tbreak\n\t\t}\n\n\tcase 1:\n\t\t{\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlPointer@\", message.ObjectID, \".release(\")\n\t\t\t\tfmt.Println(\")\")\n\t\t\t}\n\n\t\t\tautoRemove := d.WlPointer_release(s, ObjectID[WlPointer](message.ObjectID))\n\t\t\tif autoRemove {\n\t\t\t\ts.RemoveObject(message.ObjectID)\n\t\t\t\ts.RemoveGlobalWlPointerBind(ObjectID[WlPointer](message.ObjectID))\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\n\tdefault:\n\t\tfmt.Println(\"Unknown opcode on WlPointer\", message.Opcode)\n\t}\n}\n\ntype WlPointerError_enum uint32\n\nconst (\n\tWlPointerError_enum_role WlPointerError_enum = 0\n)\n\ntype WlPointerButtonState_enum uint32\n\nconst (\n\tWlPointerButtonState_enum_released WlPointerButtonState_enum = 0\n\tWlPointerButtonState_enum_pressed  WlPointerButtonState_enum = 1\n)\n\ntype WlPointerAxis_enum uint32\n\nconst (\n\tWlPointerAxis_enum_vertical_scroll   WlPointerAxis_enum = 0\n\tWlPointerAxis_enum_horizontal_scroll WlPointerAxis_enum = 1\n)\n\ntype WlPointerAxisSource_enum uint32\n\nconst (\n\tWlPointerAxisSource_enum_wheel      WlPointerAxisSource_enum = 0\n\tWlPointerAxisSource_enum_finger     WlPointerAxisSource_enum = 1\n\tWlPointerAxisSource_enum_continuous WlPointerAxisSource_enum = 2\n\tWlPointerAxisSource_enum_wheel_tilt WlPointerAxisSource_enum = 3\n)\n\ntype WlPointerAxisRelativeDirection_enum uint32\n\nconst (\n\tWlPointerAxisRelativeDirection_enum_identical WlPointerAxisRelativeDirection_enum = 0\n\tWlPointerAxisRelativeDirection_enum_inverted  WlPointerAxisRelativeDirection_enum = 1\n)\n\ntype WlKeyboard_delegate interface {\n\tWlKeyboard_release(s ClientState, object_id ObjectID[WlKeyboard]) bool\n\tOnBind(s ClientState, name AnyObjectID, interface_ string, new_id AnyObjectID, version_number uint32)\n\tAfterGetKeyboard(s ClientState, object_id ObjectID[WlKeyboard])\n}\n\ntype WlKeyboard struct {\n\tDelegate WlKeyboard_delegate\n}\n\nfunc (p *WlKeyboard) GetDelegate() WlKeyboard_delegate {\n\treturn p.Delegate\n}\nfunc (p *WlKeyboard) GetBindable() OnBindable {\n\treturn p.Delegate\n}\n\nfunc WlKeyboard_keymap(s Sender, eventObjectID ObjectID[WlKeyboard], format WlKeyboardKeymapFormat_enum, fd FileDescriptor, size uint32) {\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tvar fileDescriptor *FileDescriptor\n\tputUint32(uint32(format))\n\tfileDescriptor = &fd\n\tputUint32(uint32(size))\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         0,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc WlKeyboard_enter(s Sender, eventObjectID ObjectID[WlKeyboard], serial uint32, surface ObjectID[WlSurface], keys []byte) {\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tvar fileDescriptor *FileDescriptor\n\tputUint32(uint32(serial))\n\tputUint32(uint32(surface))\n\t{\n\t\tn := len(keys)\n\t\tputUint32(uint32(n))\n\t\tdata = append(data, keys...)\n\t\tif pad := (4 - (n % 4)) % 4; pad != 0 {\n\t\t\tdata = append(data, make([]byte, pad)...)\n\t\t}\n\t}\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         1,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc WlKeyboard_leave(s Sender, eventObjectID ObjectID[WlKeyboard], serial uint32, surface ObjectID[WlSurface]) {\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tvar fileDescriptor *FileDescriptor\n\tputUint32(uint32(serial))\n\tputUint32(uint32(surface))\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         2,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc WlKeyboard_key(s Sender, eventObjectID ObjectID[WlKeyboard], serial uint32, time uint32, key uint32, state WlKeyboardKeyState_enum) {\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tvar fileDescriptor *FileDescriptor\n\tputUint32(uint32(serial))\n\tputUint32(uint32(time))\n\tputUint32(uint32(key))\n\tputUint32(uint32(state))\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         3,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc WlKeyboard_modifiers(s Sender, eventObjectID ObjectID[WlKeyboard], serial uint32, mods_depressed uint32, mods_latched uint32, mods_locked uint32, group uint32) {\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tvar fileDescriptor *FileDescriptor\n\tputUint32(uint32(serial))\n\tputUint32(uint32(mods_depressed))\n\tputUint32(uint32(mods_latched))\n\tputUint32(uint32(mods_locked))\n\tputUint32(uint32(group))\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         4,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc WlKeyboard_repeat_info(s Sender, boundVersion uint32, eventObjectID ObjectID[WlKeyboard], rate int32, delay int32) {\n\tif boundVersion < 4 {\n\t\t// Event not available in this version; skip\n\t\treturn\n\t}\n\tdata := make([]byte, 0)\n\tputInt32 := func(v int32) { uv := uint32(v); data = append(data, byte(uv), byte(uv>>8), byte(uv>>16), byte(uv>>24)) }\n\tvar fileDescriptor *FileDescriptor\n\tputInt32(int32(rate))\n\tputInt32(int32(delay))\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         5,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc (p *WlKeyboard) OnRequest(s FileDescriptorClaimClientState, message Message) {\n\t_data_in_offset__ := 0\n\t_ = _data_in_offset__\n\td := p.Delegate\n\tswitch message.Opcode {\n\tcase 0:\n\t\t{\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlKeyboard@\", message.ObjectID, \".release(\")\n\t\t\t\tfmt.Println(\")\")\n\t\t\t}\n\n\t\t\tautoRemove := d.WlKeyboard_release(s, ObjectID[WlKeyboard](message.ObjectID))\n\t\t\tif autoRemove {\n\t\t\t\ts.RemoveObject(message.ObjectID)\n\t\t\t\ts.RemoveGlobalWlKeyboardBind(ObjectID[WlKeyboard](message.ObjectID))\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\n\tdefault:\n\t\tfmt.Println(\"Unknown opcode on WlKeyboard\", message.Opcode)\n\t}\n}\n\ntype WlKeyboardKeymapFormat_enum uint32\n\nconst (\n\tWlKeyboardKeymapFormat_enum_no_keymap WlKeyboardKeymapFormat_enum = 0\n\tWlKeyboardKeymapFormat_enum_xkb_v1    WlKeyboardKeymapFormat_enum = 1\n)\n\ntype WlKeyboardKeyState_enum uint32\n\nconst (\n\tWlKeyboardKeyState_enum_released WlKeyboardKeyState_enum = 0\n\tWlKeyboardKeyState_enum_pressed  WlKeyboardKeyState_enum = 1\n)\n\ntype WlTouch_delegate interface {\n\tWlTouch_release(s ClientState, object_id ObjectID[WlTouch]) bool\n\tOnBind(s ClientState, name AnyObjectID, interface_ string, new_id AnyObjectID, version_number uint32)\n}\n\ntype WlTouch struct {\n\tDelegate WlTouch_delegate\n}\n\nfunc (p *WlTouch) GetDelegate() WlTouch_delegate {\n\treturn p.Delegate\n}\nfunc (p *WlTouch) GetBindable() OnBindable {\n\treturn p.Delegate\n}\n\nfunc WlTouch_down(s Sender, eventObjectID ObjectID[WlTouch], serial uint32, time uint32, surface ObjectID[WlSurface], id int32, x float32, y float32) {\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tputInt32 := func(v int32) { putUint32(uint32(v)) }\n\tvar fileDescriptor *FileDescriptor\n\tputUint32(uint32(serial))\n\tputUint32(uint32(time))\n\tputUint32(uint32(surface))\n\tputInt32(int32(id))\n\t// fixed: 24.8\n\tputInt32(int32(x * 256.0))\n\t// fixed: 24.8\n\tputInt32(int32(y * 256.0))\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         0,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc WlTouch_up(s Sender, eventObjectID ObjectID[WlTouch], serial uint32, time uint32, id int32) {\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tputInt32 := func(v int32) { putUint32(uint32(v)) }\n\tvar fileDescriptor *FileDescriptor\n\tputUint32(uint32(serial))\n\tputUint32(uint32(time))\n\tputInt32(int32(id))\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         1,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc WlTouch_motion(s Sender, eventObjectID ObjectID[WlTouch], time uint32, id int32, x float32, y float32) {\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tputInt32 := func(v int32) { putUint32(uint32(v)) }\n\tvar fileDescriptor *FileDescriptor\n\tputUint32(uint32(time))\n\tputInt32(int32(id))\n\t// fixed: 24.8\n\tputInt32(int32(x * 256.0))\n\t// fixed: 24.8\n\tputInt32(int32(y * 256.0))\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         2,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc WlTouch_frame(s Sender, eventObjectID ObjectID[WlTouch]) {\n\tdata := make([]byte, 0)\n\tvar fileDescriptor *FileDescriptor\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         3,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc WlTouch_cancel(s Sender, eventObjectID ObjectID[WlTouch]) {\n\tdata := make([]byte, 0)\n\tvar fileDescriptor *FileDescriptor\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         4,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc WlTouch_shape(s Sender, boundVersion uint32, eventObjectID ObjectID[WlTouch], id int32, major float32, minor float32) {\n\tif boundVersion < 6 {\n\t\t// Event not available in this version; skip\n\t\treturn\n\t}\n\tdata := make([]byte, 0)\n\tputInt32 := func(v int32) { uv := uint32(v); data = append(data, byte(uv), byte(uv>>8), byte(uv>>16), byte(uv>>24)) }\n\tvar fileDescriptor *FileDescriptor\n\tputInt32(int32(id))\n\t// fixed: 24.8\n\tputInt32(int32(major * 256.0))\n\t// fixed: 24.8\n\tputInt32(int32(minor * 256.0))\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         5,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc WlTouch_orientation(s Sender, boundVersion uint32, eventObjectID ObjectID[WlTouch], id int32, orientation float32) {\n\tif boundVersion < 6 {\n\t\t// Event not available in this version; skip\n\t\treturn\n\t}\n\tdata := make([]byte, 0)\n\tputInt32 := func(v int32) { uv := uint32(v); data = append(data, byte(uv), byte(uv>>8), byte(uv>>16), byte(uv>>24)) }\n\tvar fileDescriptor *FileDescriptor\n\tputInt32(int32(id))\n\t// fixed: 24.8\n\tputInt32(int32(orientation * 256.0))\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         6,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc (p *WlTouch) OnRequest(s FileDescriptorClaimClientState, message Message) {\n\t_data_in_offset__ := 0\n\t_ = _data_in_offset__\n\td := p.Delegate\n\tswitch message.Opcode {\n\tcase 0:\n\t\t{\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlTouch@\", message.ObjectID, \".release(\")\n\t\t\t\tfmt.Println(\")\")\n\t\t\t}\n\n\t\t\tautoRemove := d.WlTouch_release(s, ObjectID[WlTouch](message.ObjectID))\n\t\t\tif autoRemove {\n\t\t\t\ts.RemoveObject(message.ObjectID)\n\t\t\t\ts.RemoveGlobalWlTouchBind(ObjectID[WlTouch](message.ObjectID))\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\n\tdefault:\n\t\tfmt.Println(\"Unknown opcode on WlTouch\", message.Opcode)\n\t}\n}\n\ntype WlOutput_delegate interface {\n\tWlOutput_release(s ClientState, object_id ObjectID[WlOutput]) bool\n\tOnBind(s ClientState, name AnyObjectID, interface_ string, new_id AnyObjectID, version_number uint32)\n}\n\ntype WlOutput struct {\n\tDelegate WlOutput_delegate\n}\n\nfunc (p *WlOutput) GetDelegate() WlOutput_delegate {\n\treturn p.Delegate\n}\nfunc (p *WlOutput) GetBindable() OnBindable {\n\treturn p.Delegate\n}\n\nfunc WlOutput_geometry(s Sender, eventObjectID ObjectID[WlOutput], x int32, y int32, physical_width int32, physical_height int32, subpixel int32, make_ string, model string, transform int32) {\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tputInt32 := func(v int32) { putUint32(uint32(v)) }\n\tvar fileDescriptor *FileDescriptor\n\tputInt32(int32(x))\n\tputInt32(int32(y))\n\tputInt32(int32(physical_width))\n\tputInt32(int32(physical_height))\n\tputInt32(int32(subpixel))\n\t{\n\t\tb := []byte(make_)\n\t\ttotal := len(b) + 1 // include null terminator\n\t\tputUint32(uint32(total))\n\t\tdata = append(data, b...)\n\t\tdata = append(data, 0)\n\t\tif pad := (4 - (total % 4)) % 4; pad != 0 {\n\t\t\tdata = append(data, make([]byte, pad)...)\n\t\t}\n\t}\n\t{\n\t\tb := []byte(model)\n\t\ttotal := len(b) + 1 // include null terminator\n\t\tputUint32(uint32(total))\n\t\tdata = append(data, b...)\n\t\tdata = append(data, 0)\n\t\tif pad := (4 - (total % 4)) % 4; pad != 0 {\n\t\t\tdata = append(data, make([]byte, pad)...)\n\t\t}\n\t}\n\tputInt32(int32(transform))\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         0,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc WlOutput_mode(s Sender, eventObjectID ObjectID[WlOutput], flags WlOutputMode_enum, width int32, height int32, refresh int32) {\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tputInt32 := func(v int32) { putUint32(uint32(v)) }\n\tvar fileDescriptor *FileDescriptor\n\tputUint32(uint32(flags))\n\tputInt32(int32(width))\n\tputInt32(int32(height))\n\tputInt32(int32(refresh))\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         1,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc WlOutput_done(s Sender, boundVersion uint32, eventObjectID ObjectID[WlOutput]) {\n\tif boundVersion < 2 {\n\t\t// Event not available in this version; skip\n\t\treturn\n\t}\n\tdata := make([]byte, 0)\n\tvar fileDescriptor *FileDescriptor\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         2,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc WlOutput_scale(s Sender, boundVersion uint32, eventObjectID ObjectID[WlOutput], factor int32) {\n\tif boundVersion < 2 {\n\t\t// Event not available in this version; skip\n\t\treturn\n\t}\n\tdata := make([]byte, 0)\n\tputInt32 := func(v int32) { uv := uint32(v); data = append(data, byte(uv), byte(uv>>8), byte(uv>>16), byte(uv>>24)) }\n\tvar fileDescriptor *FileDescriptor\n\tputInt32(int32(factor))\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         3,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc WlOutput_name(s Sender, boundVersion uint32, eventObjectID ObjectID[WlOutput], name string) {\n\tif boundVersion < 4 {\n\t\t// Event not available in this version; skip\n\t\treturn\n\t}\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tvar fileDescriptor *FileDescriptor\n\t{\n\t\tb := []byte(name)\n\t\ttotal := len(b) + 1 // include null terminator\n\t\tputUint32(uint32(total))\n\t\tdata = append(data, b...)\n\t\tdata = append(data, 0)\n\t\tif pad := (4 - (total % 4)) % 4; pad != 0 {\n\t\t\tdata = append(data, make([]byte, pad)...)\n\t\t}\n\t}\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         4,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc WlOutput_description(s Sender, boundVersion uint32, eventObjectID ObjectID[WlOutput], description string) {\n\tif boundVersion < 4 {\n\t\t// Event not available in this version; skip\n\t\treturn\n\t}\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tvar fileDescriptor *FileDescriptor\n\t{\n\t\tb := []byte(description)\n\t\ttotal := len(b) + 1 // include null terminator\n\t\tputUint32(uint32(total))\n\t\tdata = append(data, b...)\n\t\tdata = append(data, 0)\n\t\tif pad := (4 - (total % 4)) % 4; pad != 0 {\n\t\t\tdata = append(data, make([]byte, pad)...)\n\t\t}\n\t}\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         5,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc (p *WlOutput) OnRequest(s FileDescriptorClaimClientState, message Message) {\n\t_data_in_offset__ := 0\n\t_ = _data_in_offset__\n\td := p.Delegate\n\tswitch message.Opcode {\n\tcase 0:\n\t\t{\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlOutput@\", message.ObjectID, \".release(\")\n\t\t\t\tfmt.Println(\")\")\n\t\t\t}\n\n\t\t\tautoRemove := d.WlOutput_release(s, ObjectID[WlOutput](message.ObjectID))\n\t\t\tif autoRemove {\n\t\t\t\ts.RemoveObject(message.ObjectID)\n\t\t\t\ts.RemoveGlobalWlOutputBind(ObjectID[WlOutput](message.ObjectID))\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\n\tdefault:\n\t\tfmt.Println(\"Unknown opcode on WlOutput\", message.Opcode)\n\t}\n}\n\ntype WlOutputSubpixel_enum uint32\n\nconst (\n\tWlOutputSubpixel_enum_unknown        WlOutputSubpixel_enum = 0\n\tWlOutputSubpixel_enum_none           WlOutputSubpixel_enum = 1\n\tWlOutputSubpixel_enum_horizontal_rgb WlOutputSubpixel_enum = 2\n\tWlOutputSubpixel_enum_horizontal_bgr WlOutputSubpixel_enum = 3\n\tWlOutputSubpixel_enum_vertical_rgb   WlOutputSubpixel_enum = 4\n\tWlOutputSubpixel_enum_vertical_bgr   WlOutputSubpixel_enum = 5\n)\n\ntype WlOutputTransform_enum uint32\n\nconst (\n\tWlOutputTransform_enum_normal      WlOutputTransform_enum = 0\n\tWlOutputTransform_enum__90         WlOutputTransform_enum = 1\n\tWlOutputTransform_enum__180        WlOutputTransform_enum = 2\n\tWlOutputTransform_enum__270        WlOutputTransform_enum = 3\n\tWlOutputTransform_enum_flipped     WlOutputTransform_enum = 4\n\tWlOutputTransform_enum_flipped_90  WlOutputTransform_enum = 5\n\tWlOutputTransform_enum_flipped_180 WlOutputTransform_enum = 6\n\tWlOutputTransform_enum_flipped_270 WlOutputTransform_enum = 7\n)\n\ntype WlOutputMode_enum uint32\n\nconst (\n\tWlOutputMode_enum_current   WlOutputMode_enum = 0x1\n\tWlOutputMode_enum_preferred WlOutputMode_enum = 0x2\n)\n\ntype WlRegion_delegate interface {\n\tWlRegion_destroy(s ClientState, object_id ObjectID[WlRegion]) bool\n\tWlRegion_add(s ClientState, object_id ObjectID[WlRegion], x int32, y int32, width int32, height int32)\n\tWlRegion_subtract(s ClientState, object_id ObjectID[WlRegion], x int32, y int32, width int32, height int32)\n\tOnBind(s ClientState, name AnyObjectID, interface_ string, new_id AnyObjectID, version_number uint32)\n}\n\ntype WlRegion struct {\n\tDelegate WlRegion_delegate\n}\n\nfunc (p *WlRegion) GetDelegate() WlRegion_delegate {\n\treturn p.Delegate\n}\nfunc (p *WlRegion) GetBindable() OnBindable {\n\treturn p.Delegate\n}\n\nfunc (p *WlRegion) OnRequest(s FileDescriptorClaimClientState, message Message) {\n\t_data_in_offset__ := 0\n\t_ = _data_in_offset__\n\td := p.Delegate\n\tswitch message.Opcode {\n\tcase 0:\n\t\t{\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlRegion@\", message.ObjectID, \".destroy(\")\n\t\t\t\tfmt.Println(\")\")\n\t\t\t}\n\n\t\t\tautoRemove := d.WlRegion_destroy(s, ObjectID[WlRegion](message.ObjectID))\n\t\t\tif autoRemove {\n\t\t\t\ts.RemoveObject(message.ObjectID)\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\n\tcase 1:\n\t\t{\n\n\t\t\tx := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\ty := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\twidth := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\theight := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlRegion@\", message.ObjectID, \".add(\")\n\t\t\t\tfmt.Println(\"x: \", x, \", \", \"y: \", y, \", \", \"width: \", width, \", \", \"height: \", height, \")\")\n\t\t\t}\n\n\t\t\td.WlRegion_add(s, ObjectID[WlRegion](message.ObjectID), x, y, width, height)\n\t\t\tbreak\n\t\t}\n\n\tcase 2:\n\t\t{\n\n\t\t\tx := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\ty := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\twidth := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\theight := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlRegion@\", message.ObjectID, \".subtract(\")\n\t\t\t\tfmt.Println(\"x: \", x, \", \", \"y: \", y, \", \", \"width: \", width, \", \", \"height: \", height, \")\")\n\t\t\t}\n\n\t\t\td.WlRegion_subtract(s, ObjectID[WlRegion](message.ObjectID), x, y, width, height)\n\t\t\tbreak\n\t\t}\n\n\tdefault:\n\t\tfmt.Println(\"Unknown opcode on WlRegion\", message.Opcode)\n\t}\n}\n\ntype WlSubcompositor_delegate interface {\n\tWlSubcompositor_destroy(s ClientState, object_id ObjectID[WlSubcompositor]) bool\n\tWlSubcompositor_get_subsurface(s ClientState, object_id ObjectID[WlSubcompositor], id ObjectID[WlSubsurface], surface ObjectID[WlSurface], parent ObjectID[WlSurface])\n\tOnBind(s ClientState, name AnyObjectID, interface_ string, new_id AnyObjectID, version_number uint32)\n}\n\ntype WlSubcompositor struct {\n\tDelegate WlSubcompositor_delegate\n}\n\nfunc (p *WlSubcompositor) GetDelegate() WlSubcompositor_delegate {\n\treturn p.Delegate\n}\nfunc (p *WlSubcompositor) GetBindable() OnBindable {\n\treturn p.Delegate\n}\n\nfunc (p *WlSubcompositor) OnRequest(s FileDescriptorClaimClientState, message Message) {\n\t_data_in_offset__ := 0\n\t_ = _data_in_offset__\n\td := p.Delegate\n\tswitch message.Opcode {\n\tcase 0:\n\t\t{\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlSubcompositor@\", message.ObjectID, \".destroy(\")\n\t\t\t\tfmt.Println(\")\")\n\t\t\t}\n\n\t\t\tautoRemove := d.WlSubcompositor_destroy(s, ObjectID[WlSubcompositor](message.ObjectID))\n\t\t\tif autoRemove {\n\t\t\t\ts.RemoveObject(message.ObjectID)\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\n\tcase 1:\n\t\t{\n\n\t\t\tidVal := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\tid := ObjectID[WlSubsurface](idVal)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tsurface := ObjectID[WlSurface](uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tparent := ObjectID[WlSurface](uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlSubcompositor@\", message.ObjectID, \".get_subsurface(\")\n\t\t\t\tfmt.Println(\"id: \", id, \", \", \"surface: \", surface, \", \", \"parent: \", parent, \")\")\n\t\t\t}\n\n\t\t\td.WlSubcompositor_get_subsurface(s, ObjectID[WlSubcompositor](message.ObjectID), id, surface, parent)\n\t\t\tbreak\n\t\t}\n\n\tdefault:\n\t\tfmt.Println(\"Unknown opcode on WlSubcompositor\", message.Opcode)\n\t}\n}\n\ntype WlSubcompositorError_enum uint32\n\nconst (\n\tWlSubcompositorError_enum_bad_surface WlSubcompositorError_enum = 0\n\tWlSubcompositorError_enum_bad_parent  WlSubcompositorError_enum = 1\n)\n\ntype WlSubsurface_delegate interface {\n\tWlSubsurface_destroy(s ClientState, object_id ObjectID[WlSubsurface]) bool\n\tWlSubsurface_set_position(s ClientState, object_id ObjectID[WlSubsurface], x int32, y int32)\n\tWlSubsurface_place_above(s ClientState, object_id ObjectID[WlSubsurface], sibling ObjectID[WlSurface])\n\tWlSubsurface_place_below(s ClientState, object_id ObjectID[WlSubsurface], sibling ObjectID[WlSurface])\n\tWlSubsurface_set_sync(s ClientState, object_id ObjectID[WlSubsurface])\n\tWlSubsurface_set_desync(s ClientState, object_id ObjectID[WlSubsurface])\n\tOnBind(s ClientState, name AnyObjectID, interface_ string, new_id AnyObjectID, version_number uint32)\n}\n\ntype WlSubsurface struct {\n\tDelegate WlSubsurface_delegate\n}\n\nfunc (p *WlSubsurface) GetDelegate() WlSubsurface_delegate {\n\treturn p.Delegate\n}\nfunc (p *WlSubsurface) GetBindable() OnBindable {\n\treturn p.Delegate\n}\n\nfunc (p *WlSubsurface) OnRequest(s FileDescriptorClaimClientState, message Message) {\n\t_data_in_offset__ := 0\n\t_ = _data_in_offset__\n\td := p.Delegate\n\tswitch message.Opcode {\n\tcase 0:\n\t\t{\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlSubsurface@\", message.ObjectID, \".destroy(\")\n\t\t\t\tfmt.Println(\")\")\n\t\t\t}\n\n\t\t\tautoRemove := d.WlSubsurface_destroy(s, ObjectID[WlSubsurface](message.ObjectID))\n\t\t\tif autoRemove {\n\t\t\t\ts.RemoveObject(message.ObjectID)\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\n\tcase 1:\n\t\t{\n\n\t\t\tx := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\ty := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlSubsurface@\", message.ObjectID, \".set_position(\")\n\t\t\t\tfmt.Println(\"x: \", x, \", \", \"y: \", y, \")\")\n\t\t\t}\n\n\t\t\td.WlSubsurface_set_position(s, ObjectID[WlSubsurface](message.ObjectID), x, y)\n\t\t\tbreak\n\t\t}\n\n\tcase 2:\n\t\t{\n\n\t\t\tsibling := ObjectID[WlSurface](uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlSubsurface@\", message.ObjectID, \".place_above(\")\n\t\t\t\tfmt.Println(\"sibling: \", sibling, \")\")\n\t\t\t}\n\n\t\t\td.WlSubsurface_place_above(s, ObjectID[WlSubsurface](message.ObjectID), sibling)\n\t\t\tbreak\n\t\t}\n\n\tcase 3:\n\t\t{\n\n\t\t\tsibling := ObjectID[WlSurface](uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlSubsurface@\", message.ObjectID, \".place_below(\")\n\t\t\t\tfmt.Println(\"sibling: \", sibling, \")\")\n\t\t\t}\n\n\t\t\td.WlSubsurface_place_below(s, ObjectID[WlSubsurface](message.ObjectID), sibling)\n\t\t\tbreak\n\t\t}\n\n\tcase 4:\n\t\t{\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlSubsurface@\", message.ObjectID, \".set_sync(\")\n\t\t\t\tfmt.Println(\")\")\n\t\t\t}\n\n\t\t\td.WlSubsurface_set_sync(s, ObjectID[WlSubsurface](message.ObjectID))\n\t\t\tbreak\n\t\t}\n\n\tcase 5:\n\t\t{\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"WlSubsurface@\", message.ObjectID, \".set_desync(\")\n\t\t\t\tfmt.Println(\")\")\n\t\t\t}\n\n\t\t\td.WlSubsurface_set_desync(s, ObjectID[WlSubsurface](message.ObjectID))\n\t\t\tbreak\n\t\t}\n\n\tdefault:\n\t\tfmt.Println(\"Unknown opcode on WlSubsurface\", message.Opcode)\n\t}\n}\n\ntype WlSubsurfaceError_enum uint32\n\nconst (\n\tWlSubsurfaceError_enum_bad_surface WlSubsurfaceError_enum = 0\n)\n"
  },
  {
    "path": "wayland/protocols/wayland_debug.go",
    "content": "//go:build debug\n// +build debug\n\npackage protocols\n\nconst DebugRequests = true\n"
  },
  {
    "path": "wayland/protocols/wayland_nodebug.go",
    "content": "//go:build !debug\n// +build !debug\n\npackage protocols\n\nconst DebugRequests = false\n"
  },
  {
    "path": "wayland/protocols/xdg-decoration-unstable-v1.xml.go",
    "content": "// Code generated by `cmd/protocols`; DO NOT EDIT.\n\npackage protocols\n\nimport \"fmt\"\n\ntype ZxdgDecorationManagerV1_delegate interface {\n\tZxdgDecorationManagerV1_destroy(s ClientState, object_id ObjectID[ZxdgDecorationManagerV1]) bool\n\tZxdgDecorationManagerV1_get_toplevel_decoration(s ClientState, object_id ObjectID[ZxdgDecorationManagerV1], id ObjectID[ZxdgToplevelDecorationV1], toplevel ObjectID[XdgToplevel])\n\tOnBind(s ClientState, name AnyObjectID, interface_ string, new_id AnyObjectID, version_number uint32)\n}\n\ntype ZxdgDecorationManagerV1 struct {\n\tDelegate ZxdgDecorationManagerV1_delegate\n}\n\nfunc (p *ZxdgDecorationManagerV1) GetDelegate() ZxdgDecorationManagerV1_delegate {\n\treturn p.Delegate\n}\nfunc (p *ZxdgDecorationManagerV1) GetBindable() OnBindable {\n\treturn p.Delegate\n}\n\nfunc (p *ZxdgDecorationManagerV1) OnRequest(s FileDescriptorClaimClientState, message Message) {\n\t_data_in_offset__ := 0\n\t_ = _data_in_offset__\n\td := p.Delegate\n\tswitch message.Opcode {\n\tcase 0:\n\t\t{\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"ZxdgDecorationManagerV1@\", message.ObjectID, \".destroy(\")\n\t\t\t\tfmt.Println(\")\")\n\t\t\t}\n\n\t\t\tautoRemove := d.ZxdgDecorationManagerV1_destroy(s, ObjectID[ZxdgDecorationManagerV1](message.ObjectID))\n\t\t\tif autoRemove {\n\t\t\t\ts.RemoveObject(message.ObjectID)\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\n\tcase 1:\n\t\t{\n\n\t\t\tidVal := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\tid := ObjectID[ZxdgToplevelDecorationV1](idVal)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\ttoplevel := ObjectID[XdgToplevel](uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"ZxdgDecorationManagerV1@\", message.ObjectID, \".get_toplevel_decoration(\")\n\t\t\t\tfmt.Println(\"id: \", id, \", \", \"toplevel: \", toplevel, \")\")\n\t\t\t}\n\n\t\t\td.ZxdgDecorationManagerV1_get_toplevel_decoration(s, ObjectID[ZxdgDecorationManagerV1](message.ObjectID), id, toplevel)\n\t\t\tbreak\n\t\t}\n\n\tdefault:\n\t\tfmt.Println(\"Unknown opcode on ZxdgDecorationManagerV1\", message.Opcode)\n\t}\n}\n\ntype ZxdgToplevelDecorationV1_delegate interface {\n\tZxdgToplevelDecorationV1_destroy(s ClientState, object_id ObjectID[ZxdgToplevelDecorationV1]) bool\n\tZxdgToplevelDecorationV1_set_mode(s ClientState, object_id ObjectID[ZxdgToplevelDecorationV1], mode ZxdgToplevelDecorationV1Mode_enum)\n\tZxdgToplevelDecorationV1_unset_mode(s ClientState, object_id ObjectID[ZxdgToplevelDecorationV1])\n\tOnBind(s ClientState, name AnyObjectID, interface_ string, new_id AnyObjectID, version_number uint32)\n}\n\ntype ZxdgToplevelDecorationV1 struct {\n\tDelegate ZxdgToplevelDecorationV1_delegate\n}\n\nfunc (p *ZxdgToplevelDecorationV1) GetDelegate() ZxdgToplevelDecorationV1_delegate {\n\treturn p.Delegate\n}\nfunc (p *ZxdgToplevelDecorationV1) GetBindable() OnBindable {\n\treturn p.Delegate\n}\n\nfunc ZxdgToplevelDecorationV1_configure(s Sender, eventObjectID ObjectID[ZxdgToplevelDecorationV1], mode ZxdgToplevelDecorationV1Mode_enum) {\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tvar fileDescriptor *FileDescriptor\n\tputUint32(uint32(mode))\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         0,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc (p *ZxdgToplevelDecorationV1) OnRequest(s FileDescriptorClaimClientState, message Message) {\n\t_data_in_offset__ := 0\n\t_ = _data_in_offset__\n\td := p.Delegate\n\tswitch message.Opcode {\n\tcase 0:\n\t\t{\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"ZxdgToplevelDecorationV1@\", message.ObjectID, \".destroy(\")\n\t\t\t\tfmt.Println(\")\")\n\t\t\t}\n\n\t\t\tautoRemove := d.ZxdgToplevelDecorationV1_destroy(s, ObjectID[ZxdgToplevelDecorationV1](message.ObjectID))\n\t\t\tif autoRemove {\n\t\t\t\ts.RemoveObject(message.ObjectID)\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\n\tcase 1:\n\t\t{\n\n\t\t\tmode := ZxdgToplevelDecorationV1Mode_enum(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"ZxdgToplevelDecorationV1@\", message.ObjectID, \".set_mode(\")\n\t\t\t\tfmt.Println(\"mode: \", mode, \")\")\n\t\t\t}\n\n\t\t\td.ZxdgToplevelDecorationV1_set_mode(s, ObjectID[ZxdgToplevelDecorationV1](message.ObjectID), mode)\n\t\t\tbreak\n\t\t}\n\n\tcase 2:\n\t\t{\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"ZxdgToplevelDecorationV1@\", message.ObjectID, \".unset_mode(\")\n\t\t\t\tfmt.Println(\")\")\n\t\t\t}\n\n\t\t\td.ZxdgToplevelDecorationV1_unset_mode(s, ObjectID[ZxdgToplevelDecorationV1](message.ObjectID))\n\t\t\tbreak\n\t\t}\n\n\tdefault:\n\t\tfmt.Println(\"Unknown opcode on ZxdgToplevelDecorationV1\", message.Opcode)\n\t}\n}\n\ntype ZxdgToplevelDecorationV1Error_enum uint32\n\nconst (\n\tZxdgToplevelDecorationV1Error_enum_unconfigured_buffer ZxdgToplevelDecorationV1Error_enum = 0\n\tZxdgToplevelDecorationV1Error_enum_already_constructed ZxdgToplevelDecorationV1Error_enum = 1\n\tZxdgToplevelDecorationV1Error_enum_orphaned            ZxdgToplevelDecorationV1Error_enum = 2\n\tZxdgToplevelDecorationV1Error_enum_invalid_mode        ZxdgToplevelDecorationV1Error_enum = 3\n)\n\ntype ZxdgToplevelDecorationV1Mode_enum uint32\n\nconst (\n\tZxdgToplevelDecorationV1Mode_enum_client_side ZxdgToplevelDecorationV1Mode_enum = 1\n\tZxdgToplevelDecorationV1Mode_enum_server_side ZxdgToplevelDecorationV1Mode_enum = 2\n)\n"
  },
  {
    "path": "wayland/protocols/xdg-shell.xml.go",
    "content": "// Code generated by `cmd/protocols`; DO NOT EDIT.\n\npackage protocols\n\nimport \"fmt\"\n\ntype XdgWmBase_delegate interface {\n\tXdgWmBase_destroy(s ClientState, object_id ObjectID[XdgWmBase]) bool\n\tXdgWmBase_create_positioner(s ClientState, object_id ObjectID[XdgWmBase], id ObjectID[XdgPositioner])\n\tXdgWmBase_get_xdg_surface(s ClientState, object_id ObjectID[XdgWmBase], id ObjectID[XdgSurface], surface ObjectID[WlSurface])\n\tXdgWmBase_pong(s ClientState, object_id ObjectID[XdgWmBase], serial uint32)\n\tOnBind(s ClientState, name AnyObjectID, interface_ string, new_id AnyObjectID, version_number uint32)\n}\n\ntype XdgWmBase struct {\n\tDelegate XdgWmBase_delegate\n}\n\nfunc (p *XdgWmBase) GetDelegate() XdgWmBase_delegate {\n\treturn p.Delegate\n}\nfunc (p *XdgWmBase) GetBindable() OnBindable {\n\treturn p.Delegate\n}\n\nfunc XdgWmBase_ping(s Sender, eventObjectID ObjectID[XdgWmBase], serial uint32) {\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tvar fileDescriptor *FileDescriptor\n\tputUint32(uint32(serial))\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         0,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc (p *XdgWmBase) OnRequest(s FileDescriptorClaimClientState, message Message) {\n\t_data_in_offset__ := 0\n\t_ = _data_in_offset__\n\td := p.Delegate\n\tswitch message.Opcode {\n\tcase 0:\n\t\t{\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"XdgWmBase@\", message.ObjectID, \".destroy(\")\n\t\t\t\tfmt.Println(\")\")\n\t\t\t}\n\n\t\t\tautoRemove := d.XdgWmBase_destroy(s, ObjectID[XdgWmBase](message.ObjectID))\n\t\t\tif autoRemove {\n\t\t\t\ts.RemoveObject(message.ObjectID)\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\n\tcase 1:\n\t\t{\n\n\t\t\tidVal := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\tid := ObjectID[XdgPositioner](idVal)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"XdgWmBase@\", message.ObjectID, \".create_positioner(\")\n\t\t\t\tfmt.Println(\"id: \", id, \")\")\n\t\t\t}\n\n\t\t\td.XdgWmBase_create_positioner(s, ObjectID[XdgWmBase](message.ObjectID), id)\n\t\t\tbreak\n\t\t}\n\n\tcase 2:\n\t\t{\n\n\t\t\tidVal := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\tid := ObjectID[XdgSurface](idVal)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tsurface := ObjectID[WlSurface](uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"XdgWmBase@\", message.ObjectID, \".get_xdg_surface(\")\n\t\t\t\tfmt.Println(\"id: \", id, \", \", \"surface: \", surface, \")\")\n\t\t\t}\n\n\t\t\td.XdgWmBase_get_xdg_surface(s, ObjectID[XdgWmBase](message.ObjectID), id, surface)\n\t\t\tbreak\n\t\t}\n\n\tcase 3:\n\t\t{\n\n\t\t\tserial := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"XdgWmBase@\", message.ObjectID, \".pong(\")\n\t\t\t\tfmt.Println(\"serial: \", serial, \")\")\n\t\t\t}\n\n\t\t\td.XdgWmBase_pong(s, ObjectID[XdgWmBase](message.ObjectID), serial)\n\t\t\tbreak\n\t\t}\n\n\tdefault:\n\t\tfmt.Println(\"Unknown opcode on XdgWmBase\", message.Opcode)\n\t}\n}\n\ntype XdgWmBaseError_enum uint32\n\nconst (\n\tXdgWmBaseError_enum_role                  XdgWmBaseError_enum = 0\n\tXdgWmBaseError_enum_defunct_surfaces      XdgWmBaseError_enum = 1\n\tXdgWmBaseError_enum_not_the_topmost_popup XdgWmBaseError_enum = 2\n\tXdgWmBaseError_enum_invalid_popup_parent  XdgWmBaseError_enum = 3\n\tXdgWmBaseError_enum_invalid_surface_state XdgWmBaseError_enum = 4\n\tXdgWmBaseError_enum_invalid_positioner    XdgWmBaseError_enum = 5\n\tXdgWmBaseError_enum_unresponsive          XdgWmBaseError_enum = 6\n)\n\ntype XdgPositioner_delegate interface {\n\tXdgPositioner_destroy(s ClientState, object_id ObjectID[XdgPositioner]) bool\n\tXdgPositioner_set_size(s ClientState, object_id ObjectID[XdgPositioner], width int32, height int32)\n\tXdgPositioner_set_anchor_rect(s ClientState, object_id ObjectID[XdgPositioner], x int32, y int32, width int32, height int32)\n\tXdgPositioner_set_anchor(s ClientState, object_id ObjectID[XdgPositioner], anchor XdgPositionerAnchor_enum)\n\tXdgPositioner_set_gravity(s ClientState, object_id ObjectID[XdgPositioner], gravity XdgPositionerGravity_enum)\n\tXdgPositioner_set_constraint_adjustment(s ClientState, object_id ObjectID[XdgPositioner], constraint_adjustment XdgPositionerConstraintAdjustment_enum)\n\tXdgPositioner_set_offset(s ClientState, object_id ObjectID[XdgPositioner], x int32, y int32)\n\tXdgPositioner_set_reactive(s ClientState, object_id ObjectID[XdgPositioner])\n\tXdgPositioner_set_parent_size(s ClientState, object_id ObjectID[XdgPositioner], parent_width int32, parent_height int32)\n\tXdgPositioner_set_parent_configure(s ClientState, object_id ObjectID[XdgPositioner], serial uint32)\n\tOnBind(s ClientState, name AnyObjectID, interface_ string, new_id AnyObjectID, version_number uint32)\n}\n\ntype XdgPositioner struct {\n\tDelegate XdgPositioner_delegate\n}\n\nfunc (p *XdgPositioner) GetDelegate() XdgPositioner_delegate {\n\treturn p.Delegate\n}\nfunc (p *XdgPositioner) GetBindable() OnBindable {\n\treturn p.Delegate\n}\n\nfunc (p *XdgPositioner) OnRequest(s FileDescriptorClaimClientState, message Message) {\n\t_data_in_offset__ := 0\n\t_ = _data_in_offset__\n\td := p.Delegate\n\tswitch message.Opcode {\n\tcase 0:\n\t\t{\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"XdgPositioner@\", message.ObjectID, \".destroy(\")\n\t\t\t\tfmt.Println(\")\")\n\t\t\t}\n\n\t\t\tautoRemove := d.XdgPositioner_destroy(s, ObjectID[XdgPositioner](message.ObjectID))\n\t\t\tif autoRemove {\n\t\t\t\ts.RemoveObject(message.ObjectID)\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\n\tcase 1:\n\t\t{\n\n\t\t\twidth := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\theight := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"XdgPositioner@\", message.ObjectID, \".set_size(\")\n\t\t\t\tfmt.Println(\"width: \", width, \", \", \"height: \", height, \")\")\n\t\t\t}\n\n\t\t\td.XdgPositioner_set_size(s, ObjectID[XdgPositioner](message.ObjectID), width, height)\n\t\t\tbreak\n\t\t}\n\n\tcase 2:\n\t\t{\n\n\t\t\tx := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\ty := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\twidth := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\theight := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"XdgPositioner@\", message.ObjectID, \".set_anchor_rect(\")\n\t\t\t\tfmt.Println(\"x: \", x, \", \", \"y: \", y, \", \", \"width: \", width, \", \", \"height: \", height, \")\")\n\t\t\t}\n\n\t\t\td.XdgPositioner_set_anchor_rect(s, ObjectID[XdgPositioner](message.ObjectID), x, y, width, height)\n\t\t\tbreak\n\t\t}\n\n\tcase 3:\n\t\t{\n\n\t\t\tanchor := XdgPositionerAnchor_enum(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"XdgPositioner@\", message.ObjectID, \".set_anchor(\")\n\t\t\t\tfmt.Println(\"anchor: \", anchor, \")\")\n\t\t\t}\n\n\t\t\td.XdgPositioner_set_anchor(s, ObjectID[XdgPositioner](message.ObjectID), anchor)\n\t\t\tbreak\n\t\t}\n\n\tcase 4:\n\t\t{\n\n\t\t\tgravity := XdgPositionerGravity_enum(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"XdgPositioner@\", message.ObjectID, \".set_gravity(\")\n\t\t\t\tfmt.Println(\"gravity: \", gravity, \")\")\n\t\t\t}\n\n\t\t\td.XdgPositioner_set_gravity(s, ObjectID[XdgPositioner](message.ObjectID), gravity)\n\t\t\tbreak\n\t\t}\n\n\tcase 5:\n\t\t{\n\n\t\t\tconstraint_adjustment := XdgPositionerConstraintAdjustment_enum(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"XdgPositioner@\", message.ObjectID, \".set_constraint_adjustment(\")\n\t\t\t\tfmt.Println(\"constraint_adjustment: \", constraint_adjustment, \")\")\n\t\t\t}\n\n\t\t\td.XdgPositioner_set_constraint_adjustment(s, ObjectID[XdgPositioner](message.ObjectID), constraint_adjustment)\n\t\t\tbreak\n\t\t}\n\n\tcase 6:\n\t\t{\n\n\t\t\tx := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\ty := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"XdgPositioner@\", message.ObjectID, \".set_offset(\")\n\t\t\t\tfmt.Println(\"x: \", x, \", \", \"y: \", y, \")\")\n\t\t\t}\n\n\t\t\td.XdgPositioner_set_offset(s, ObjectID[XdgPositioner](message.ObjectID), x, y)\n\t\t\tbreak\n\t\t}\n\n\tcase 7:\n\t\t{\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"XdgPositioner@\", message.ObjectID, \".set_reactive(\")\n\t\t\t\tfmt.Println(\")\")\n\t\t\t}\n\n\t\t\td.XdgPositioner_set_reactive(s, ObjectID[XdgPositioner](message.ObjectID))\n\t\t\tbreak\n\t\t}\n\n\tcase 8:\n\t\t{\n\n\t\t\tparent_width := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tparent_height := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"XdgPositioner@\", message.ObjectID, \".set_parent_size(\")\n\t\t\t\tfmt.Println(\"parent_width: \", parent_width, \", \", \"parent_height: \", parent_height, \")\")\n\t\t\t}\n\n\t\t\td.XdgPositioner_set_parent_size(s, ObjectID[XdgPositioner](message.ObjectID), parent_width, parent_height)\n\t\t\tbreak\n\t\t}\n\n\tcase 9:\n\t\t{\n\n\t\t\tserial := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"XdgPositioner@\", message.ObjectID, \".set_parent_configure(\")\n\t\t\t\tfmt.Println(\"serial: \", serial, \")\")\n\t\t\t}\n\n\t\t\td.XdgPositioner_set_parent_configure(s, ObjectID[XdgPositioner](message.ObjectID), serial)\n\t\t\tbreak\n\t\t}\n\n\tdefault:\n\t\tfmt.Println(\"Unknown opcode on XdgPositioner\", message.Opcode)\n\t}\n}\n\ntype XdgPositionerError_enum uint32\n\nconst (\n\tXdgPositionerError_enum_invalid_input XdgPositionerError_enum = 0\n)\n\ntype XdgPositionerAnchor_enum uint32\n\nconst (\n\tXdgPositionerAnchor_enum_none         XdgPositionerAnchor_enum = 0\n\tXdgPositionerAnchor_enum_top          XdgPositionerAnchor_enum = 1\n\tXdgPositionerAnchor_enum_bottom       XdgPositionerAnchor_enum = 2\n\tXdgPositionerAnchor_enum_left         XdgPositionerAnchor_enum = 3\n\tXdgPositionerAnchor_enum_right        XdgPositionerAnchor_enum = 4\n\tXdgPositionerAnchor_enum_top_left     XdgPositionerAnchor_enum = 5\n\tXdgPositionerAnchor_enum_bottom_left  XdgPositionerAnchor_enum = 6\n\tXdgPositionerAnchor_enum_top_right    XdgPositionerAnchor_enum = 7\n\tXdgPositionerAnchor_enum_bottom_right XdgPositionerAnchor_enum = 8\n)\n\ntype XdgPositionerGravity_enum uint32\n\nconst (\n\tXdgPositionerGravity_enum_none         XdgPositionerGravity_enum = 0\n\tXdgPositionerGravity_enum_top          XdgPositionerGravity_enum = 1\n\tXdgPositionerGravity_enum_bottom       XdgPositionerGravity_enum = 2\n\tXdgPositionerGravity_enum_left         XdgPositionerGravity_enum = 3\n\tXdgPositionerGravity_enum_right        XdgPositionerGravity_enum = 4\n\tXdgPositionerGravity_enum_top_left     XdgPositionerGravity_enum = 5\n\tXdgPositionerGravity_enum_bottom_left  XdgPositionerGravity_enum = 6\n\tXdgPositionerGravity_enum_top_right    XdgPositionerGravity_enum = 7\n\tXdgPositionerGravity_enum_bottom_right XdgPositionerGravity_enum = 8\n)\n\ntype XdgPositionerConstraintAdjustment_enum uint32\n\nconst (\n\tXdgPositionerConstraintAdjustment_enum_none     XdgPositionerConstraintAdjustment_enum = 0\n\tXdgPositionerConstraintAdjustment_enum_slide_x  XdgPositionerConstraintAdjustment_enum = 1\n\tXdgPositionerConstraintAdjustment_enum_slide_y  XdgPositionerConstraintAdjustment_enum = 2\n\tXdgPositionerConstraintAdjustment_enum_flip_x   XdgPositionerConstraintAdjustment_enum = 4\n\tXdgPositionerConstraintAdjustment_enum_flip_y   XdgPositionerConstraintAdjustment_enum = 8\n\tXdgPositionerConstraintAdjustment_enum_resize_x XdgPositionerConstraintAdjustment_enum = 16\n\tXdgPositionerConstraintAdjustment_enum_resize_y XdgPositionerConstraintAdjustment_enum = 32\n)\n\ntype XdgSurface_delegate interface {\n\tXdgSurface_destroy(s ClientState, object_id ObjectID[XdgSurface]) bool\n\tXdgSurface_get_toplevel(s ClientState, object_id ObjectID[XdgSurface], id ObjectID[XdgToplevel])\n\tXdgSurface_get_popup(s ClientState, object_id ObjectID[XdgSurface], id ObjectID[XdgPopup], parent *ObjectID[XdgSurface], positioner ObjectID[XdgPositioner])\n\tXdgSurface_set_window_geometry(s ClientState, object_id ObjectID[XdgSurface], x int32, y int32, width int32, height int32)\n\tXdgSurface_ack_configure(s ClientState, object_id ObjectID[XdgSurface], serial uint32)\n\tOnBind(s ClientState, name AnyObjectID, interface_ string, new_id AnyObjectID, version_number uint32)\n}\n\ntype XdgSurface struct {\n\tDelegate XdgSurface_delegate\n}\n\nfunc (p *XdgSurface) GetDelegate() XdgSurface_delegate {\n\treturn p.Delegate\n}\nfunc (p *XdgSurface) GetBindable() OnBindable {\n\treturn p.Delegate\n}\n\nfunc XdgSurface_configure(s Sender, eventObjectID ObjectID[XdgSurface], serial uint32) {\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tvar fileDescriptor *FileDescriptor\n\tputUint32(uint32(serial))\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         0,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc (p *XdgSurface) OnRequest(s FileDescriptorClaimClientState, message Message) {\n\t_data_in_offset__ := 0\n\t_ = _data_in_offset__\n\td := p.Delegate\n\tswitch message.Opcode {\n\tcase 0:\n\t\t{\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"XdgSurface@\", message.ObjectID, \".destroy(\")\n\t\t\t\tfmt.Println(\")\")\n\t\t\t}\n\n\t\t\tautoRemove := d.XdgSurface_destroy(s, ObjectID[XdgSurface](message.ObjectID))\n\t\t\tif autoRemove {\n\t\t\t\ts.RemoveObject(message.ObjectID)\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\n\tcase 1:\n\t\t{\n\n\t\t\tidVal := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\tid := ObjectID[XdgToplevel](idVal)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"XdgSurface@\", message.ObjectID, \".get_toplevel(\")\n\t\t\t\tfmt.Println(\"id: \", id, \")\")\n\t\t\t}\n\n\t\t\td.XdgSurface_get_toplevel(s, ObjectID[XdgSurface](message.ObjectID), id)\n\t\t\tbreak\n\t\t}\n\n\tcase 2:\n\t\t{\n\n\t\t\tidVal := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\tid := ObjectID[XdgPopup](idVal)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tparentTmp := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\t_data_in_offset__ += 4\n\t\t\tvar parent *ObjectID[XdgSurface]\n\t\t\tif parentTmp != 0 {\n\t\t\t\ttmp := ObjectID[XdgSurface](parentTmp)\n\t\t\t\tparent = &tmp\n\t\t\t}\n\n\t\t\tpositioner := ObjectID[XdgPositioner](uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"XdgSurface@\", message.ObjectID, \".get_popup(\")\n\t\t\t\tfmt.Println(\"id: \", id, \", \", \"parent: \", parent, \", \", \"positioner: \", positioner, \")\")\n\t\t\t}\n\n\t\t\td.XdgSurface_get_popup(s, ObjectID[XdgSurface](message.ObjectID), id, parent, positioner)\n\t\t\tbreak\n\t\t}\n\n\tcase 3:\n\t\t{\n\n\t\t\tx := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\ty := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\twidth := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\theight := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"XdgSurface@\", message.ObjectID, \".set_window_geometry(\")\n\t\t\t\tfmt.Println(\"x: \", x, \", \", \"y: \", y, \", \", \"width: \", width, \", \", \"height: \", height, \")\")\n\t\t\t}\n\n\t\t\td.XdgSurface_set_window_geometry(s, ObjectID[XdgSurface](message.ObjectID), x, y, width, height)\n\t\t\tbreak\n\t\t}\n\n\tcase 4:\n\t\t{\n\n\t\t\tserial := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"XdgSurface@\", message.ObjectID, \".ack_configure(\")\n\t\t\t\tfmt.Println(\"serial: \", serial, \")\")\n\t\t\t}\n\n\t\t\td.XdgSurface_ack_configure(s, ObjectID[XdgSurface](message.ObjectID), serial)\n\t\t\tbreak\n\t\t}\n\n\tdefault:\n\t\tfmt.Println(\"Unknown opcode on XdgSurface\", message.Opcode)\n\t}\n}\n\ntype XdgSurfaceError_enum uint32\n\nconst (\n\tXdgSurfaceError_enum_not_constructed     XdgSurfaceError_enum = 1\n\tXdgSurfaceError_enum_already_constructed XdgSurfaceError_enum = 2\n\tXdgSurfaceError_enum_unconfigured_buffer XdgSurfaceError_enum = 3\n\tXdgSurfaceError_enum_invalid_serial      XdgSurfaceError_enum = 4\n\tXdgSurfaceError_enum_invalid_size        XdgSurfaceError_enum = 5\n\tXdgSurfaceError_enum_defunct_role_object XdgSurfaceError_enum = 6\n)\n\ntype XdgToplevel_delegate interface {\n\tXdgToplevel_destroy(s ClientState, object_id ObjectID[XdgToplevel]) bool\n\tXdgToplevel_set_parent(s ClientState, object_id ObjectID[XdgToplevel], parent *ObjectID[XdgToplevel])\n\tXdgToplevel_set_title(s ClientState, object_id ObjectID[XdgToplevel], title string)\n\tXdgToplevel_set_app_id(s ClientState, object_id ObjectID[XdgToplevel], app_id string)\n\tXdgToplevel_show_window_menu(s ClientState, object_id ObjectID[XdgToplevel], seat ObjectID[WlSeat], serial uint32, x int32, y int32)\n\tXdgToplevel_move(s ClientState, object_id ObjectID[XdgToplevel], seat ObjectID[WlSeat], serial uint32)\n\tXdgToplevel_resize(s ClientState, object_id ObjectID[XdgToplevel], seat ObjectID[WlSeat], serial uint32, edges XdgToplevelResizeEdge_enum)\n\tXdgToplevel_set_max_size(s ClientState, object_id ObjectID[XdgToplevel], width int32, height int32)\n\tXdgToplevel_set_min_size(s ClientState, object_id ObjectID[XdgToplevel], width int32, height int32)\n\tXdgToplevel_set_maximized(s ClientState, object_id ObjectID[XdgToplevel])\n\tXdgToplevel_unset_maximized(s ClientState, object_id ObjectID[XdgToplevel])\n\tXdgToplevel_set_fullscreen(s ClientState, object_id ObjectID[XdgToplevel], output *ObjectID[WlOutput])\n\tXdgToplevel_unset_fullscreen(s ClientState, object_id ObjectID[XdgToplevel])\n\tXdgToplevel_set_minimized(s ClientState, object_id ObjectID[XdgToplevel])\n\tOnBind(s ClientState, name AnyObjectID, interface_ string, new_id AnyObjectID, version_number uint32)\n}\n\ntype XdgToplevel struct {\n\tDelegate XdgToplevel_delegate\n}\n\nfunc (p *XdgToplevel) GetDelegate() XdgToplevel_delegate {\n\treturn p.Delegate\n}\nfunc (p *XdgToplevel) GetBindable() OnBindable {\n\treturn p.Delegate\n}\n\nfunc XdgToplevel_configure(s Sender, eventObjectID ObjectID[XdgToplevel], width int32, height int32, states []byte) {\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tputInt32 := func(v int32) { putUint32(uint32(v)) }\n\tvar fileDescriptor *FileDescriptor\n\tputInt32(int32(width))\n\tputInt32(int32(height))\n\t{\n\t\tn := len(states)\n\t\tputUint32(uint32(n))\n\t\tdata = append(data, states...)\n\t\tif pad := (4 - (n % 4)) % 4; pad != 0 {\n\t\t\tdata = append(data, make([]byte, pad)...)\n\t\t}\n\t}\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         0,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc XdgToplevel_close(s Sender, eventObjectID ObjectID[XdgToplevel]) {\n\tdata := make([]byte, 0)\n\tvar fileDescriptor *FileDescriptor\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         1,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc XdgToplevel_configure_bounds(s Sender, boundVersion uint32, eventObjectID ObjectID[XdgToplevel], width int32, height int32) {\n\tif boundVersion < 4 {\n\t\t// Event not available in this version; skip\n\t\treturn\n\t}\n\tdata := make([]byte, 0)\n\tputInt32 := func(v int32) { uv := uint32(v); data = append(data, byte(uv), byte(uv>>8), byte(uv>>16), byte(uv>>24)) }\n\tvar fileDescriptor *FileDescriptor\n\tputInt32(int32(width))\n\tputInt32(int32(height))\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         2,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc XdgToplevel_wm_capabilities(s Sender, boundVersion uint32, eventObjectID ObjectID[XdgToplevel], capabilities []byte) {\n\tif boundVersion < 5 {\n\t\t// Event not available in this version; skip\n\t\treturn\n\t}\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tvar fileDescriptor *FileDescriptor\n\t{\n\t\tn := len(capabilities)\n\t\tputUint32(uint32(n))\n\t\tdata = append(data, capabilities...)\n\t\tif pad := (4 - (n % 4)) % 4; pad != 0 {\n\t\t\tdata = append(data, make([]byte, pad)...)\n\t\t}\n\t}\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         3,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc (p *XdgToplevel) OnRequest(s FileDescriptorClaimClientState, message Message) {\n\t_data_in_offset__ := 0\n\t_ = _data_in_offset__\n\td := p.Delegate\n\tswitch message.Opcode {\n\tcase 0:\n\t\t{\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"XdgToplevel@\", message.ObjectID, \".destroy(\")\n\t\t\t\tfmt.Println(\")\")\n\t\t\t}\n\n\t\t\tautoRemove := d.XdgToplevel_destroy(s, ObjectID[XdgToplevel](message.ObjectID))\n\t\t\tif autoRemove {\n\t\t\t\ts.RemoveObject(message.ObjectID)\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\n\tcase 1:\n\t\t{\n\n\t\t\tparentTmp := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\t_data_in_offset__ += 4\n\t\t\tvar parent *ObjectID[XdgToplevel]\n\t\t\tif parentTmp != 0 {\n\t\t\t\ttmp := ObjectID[XdgToplevel](parentTmp)\n\t\t\t\tparent = &tmp\n\t\t\t}\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"XdgToplevel@\", message.ObjectID, \".set_parent(\")\n\t\t\t\tfmt.Println(\"parent: \", parent, \")\")\n\t\t\t}\n\n\t\t\td.XdgToplevel_set_parent(s, ObjectID[XdgToplevel](message.ObjectID), parent)\n\t\t\tbreak\n\t\t}\n\n\tcase 2:\n\t\t{\n\n\t\t\ttitleLen := int(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\t\t\ttitle := string(message.Data[_data_in_offset__ : _data_in_offset__+titleLen-1]) // NUL-terminated\n\t\t\t// 4-byte alignment\n\t\t\tif titleLen%4 != 0 {\n\t\t\t\t_data_in_offset__ += titleLen + (4 - (titleLen % 4))\n\t\t\t} else {\n\t\t\t\t_data_in_offset__ += titleLen\n\t\t\t}\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"XdgToplevel@\", message.ObjectID, \".set_title(\")\n\t\t\t\tfmt.Println(\"title: \", title, \")\")\n\t\t\t}\n\n\t\t\td.XdgToplevel_set_title(s, ObjectID[XdgToplevel](message.ObjectID), title)\n\t\t\tbreak\n\t\t}\n\n\tcase 3:\n\t\t{\n\n\t\t\tapp_idLen := int(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\t\t\tapp_id := string(message.Data[_data_in_offset__ : _data_in_offset__+app_idLen-1]) // NUL-terminated\n\t\t\t// 4-byte alignment\n\t\t\tif app_idLen%4 != 0 {\n\t\t\t\t_data_in_offset__ += app_idLen + (4 - (app_idLen % 4))\n\t\t\t} else {\n\t\t\t\t_data_in_offset__ += app_idLen\n\t\t\t}\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"XdgToplevel@\", message.ObjectID, \".set_app_id(\")\n\t\t\t\tfmt.Println(\"app_id: \", app_id, \")\")\n\t\t\t}\n\n\t\t\td.XdgToplevel_set_app_id(s, ObjectID[XdgToplevel](message.ObjectID), app_id)\n\t\t\tbreak\n\t\t}\n\n\tcase 4:\n\t\t{\n\n\t\t\tseat := ObjectID[WlSeat](uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tserial := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tx := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\ty := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"XdgToplevel@\", message.ObjectID, \".show_window_menu(\")\n\t\t\t\tfmt.Println(\"seat: \", seat, \", \", \"serial: \", serial, \", \", \"x: \", x, \", \", \"y: \", y, \")\")\n\t\t\t}\n\n\t\t\td.XdgToplevel_show_window_menu(s, ObjectID[XdgToplevel](message.ObjectID), seat, serial, x, y)\n\t\t\tbreak\n\t\t}\n\n\tcase 5:\n\t\t{\n\n\t\t\tseat := ObjectID[WlSeat](uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tserial := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"XdgToplevel@\", message.ObjectID, \".move(\")\n\t\t\t\tfmt.Println(\"seat: \", seat, \", \", \"serial: \", serial, \")\")\n\t\t\t}\n\n\t\t\td.XdgToplevel_move(s, ObjectID[XdgToplevel](message.ObjectID), seat, serial)\n\t\t\tbreak\n\t\t}\n\n\tcase 6:\n\t\t{\n\n\t\t\tseat := ObjectID[WlSeat](uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tserial := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tedges := XdgToplevelResizeEdge_enum(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"XdgToplevel@\", message.ObjectID, \".resize(\")\n\t\t\t\tfmt.Println(\"seat: \", seat, \", \", \"serial: \", serial, \", \", \"edges: \", edges, \")\")\n\t\t\t}\n\n\t\t\td.XdgToplevel_resize(s, ObjectID[XdgToplevel](message.ObjectID), seat, serial, edges)\n\t\t\tbreak\n\t\t}\n\n\tcase 7:\n\t\t{\n\n\t\t\twidth := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\theight := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"XdgToplevel@\", message.ObjectID, \".set_max_size(\")\n\t\t\t\tfmt.Println(\"width: \", width, \", \", \"height: \", height, \")\")\n\t\t\t}\n\n\t\t\td.XdgToplevel_set_max_size(s, ObjectID[XdgToplevel](message.ObjectID), width, height)\n\t\t\tbreak\n\t\t}\n\n\tcase 8:\n\t\t{\n\n\t\t\twidth := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\theight := int32(uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"XdgToplevel@\", message.ObjectID, \".set_min_size(\")\n\t\t\t\tfmt.Println(\"width: \", width, \", \", \"height: \", height, \")\")\n\t\t\t}\n\n\t\t\td.XdgToplevel_set_min_size(s, ObjectID[XdgToplevel](message.ObjectID), width, height)\n\t\t\tbreak\n\t\t}\n\n\tcase 9:\n\t\t{\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"XdgToplevel@\", message.ObjectID, \".set_maximized(\")\n\t\t\t\tfmt.Println(\")\")\n\t\t\t}\n\n\t\t\td.XdgToplevel_set_maximized(s, ObjectID[XdgToplevel](message.ObjectID))\n\t\t\tbreak\n\t\t}\n\n\tcase 10:\n\t\t{\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"XdgToplevel@\", message.ObjectID, \".unset_maximized(\")\n\t\t\t\tfmt.Println(\")\")\n\t\t\t}\n\n\t\t\td.XdgToplevel_unset_maximized(s, ObjectID[XdgToplevel](message.ObjectID))\n\t\t\tbreak\n\t\t}\n\n\tcase 11:\n\t\t{\n\n\t\t\toutputTmp := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\t_data_in_offset__ += 4\n\t\t\tvar output *ObjectID[WlOutput]\n\t\t\tif outputTmp != 0 {\n\t\t\t\ttmp := ObjectID[WlOutput](outputTmp)\n\t\t\t\toutput = &tmp\n\t\t\t}\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"XdgToplevel@\", message.ObjectID, \".set_fullscreen(\")\n\t\t\t\tfmt.Println(\"output: \", output, \")\")\n\t\t\t}\n\n\t\t\td.XdgToplevel_set_fullscreen(s, ObjectID[XdgToplevel](message.ObjectID), output)\n\t\t\tbreak\n\t\t}\n\n\tcase 12:\n\t\t{\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"XdgToplevel@\", message.ObjectID, \".unset_fullscreen(\")\n\t\t\t\tfmt.Println(\")\")\n\t\t\t}\n\n\t\t\td.XdgToplevel_unset_fullscreen(s, ObjectID[XdgToplevel](message.ObjectID))\n\t\t\tbreak\n\t\t}\n\n\tcase 13:\n\t\t{\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"XdgToplevel@\", message.ObjectID, \".set_minimized(\")\n\t\t\t\tfmt.Println(\")\")\n\t\t\t}\n\n\t\t\td.XdgToplevel_set_minimized(s, ObjectID[XdgToplevel](message.ObjectID))\n\t\t\tbreak\n\t\t}\n\n\tdefault:\n\t\tfmt.Println(\"Unknown opcode on XdgToplevel\", message.Opcode)\n\t}\n}\n\ntype XdgToplevelError_enum uint32\n\nconst (\n\tXdgToplevelError_enum_invalid_resize_edge XdgToplevelError_enum = 0\n\tXdgToplevelError_enum_invalid_parent      XdgToplevelError_enum = 1\n\tXdgToplevelError_enum_invalid_size        XdgToplevelError_enum = 2\n)\n\ntype XdgToplevelResizeEdge_enum uint32\n\nconst (\n\tXdgToplevelResizeEdge_enum_none         XdgToplevelResizeEdge_enum = 0\n\tXdgToplevelResizeEdge_enum_top          XdgToplevelResizeEdge_enum = 1\n\tXdgToplevelResizeEdge_enum_bottom       XdgToplevelResizeEdge_enum = 2\n\tXdgToplevelResizeEdge_enum_left         XdgToplevelResizeEdge_enum = 4\n\tXdgToplevelResizeEdge_enum_top_left     XdgToplevelResizeEdge_enum = 5\n\tXdgToplevelResizeEdge_enum_bottom_left  XdgToplevelResizeEdge_enum = 6\n\tXdgToplevelResizeEdge_enum_right        XdgToplevelResizeEdge_enum = 8\n\tXdgToplevelResizeEdge_enum_top_right    XdgToplevelResizeEdge_enum = 9\n\tXdgToplevelResizeEdge_enum_bottom_right XdgToplevelResizeEdge_enum = 10\n)\n\ntype XdgToplevelState_enum uint32\n\nconst (\n\tXdgToplevelState_enum_maximized    XdgToplevelState_enum = 1\n\tXdgToplevelState_enum_fullscreen   XdgToplevelState_enum = 2\n\tXdgToplevelState_enum_resizing     XdgToplevelState_enum = 3\n\tXdgToplevelState_enum_activated    XdgToplevelState_enum = 4\n\tXdgToplevelState_enum_tiled_left   XdgToplevelState_enum = 5\n\tXdgToplevelState_enum_tiled_right  XdgToplevelState_enum = 6\n\tXdgToplevelState_enum_tiled_top    XdgToplevelState_enum = 7\n\tXdgToplevelState_enum_tiled_bottom XdgToplevelState_enum = 8\n\tXdgToplevelState_enum_suspended    XdgToplevelState_enum = 9\n)\n\ntype XdgToplevelWmCapabilities_enum uint32\n\nconst (\n\tXdgToplevelWmCapabilities_enum_window_menu XdgToplevelWmCapabilities_enum = 1\n\tXdgToplevelWmCapabilities_enum_maximize    XdgToplevelWmCapabilities_enum = 2\n\tXdgToplevelWmCapabilities_enum_fullscreen  XdgToplevelWmCapabilities_enum = 3\n\tXdgToplevelWmCapabilities_enum_minimize    XdgToplevelWmCapabilities_enum = 4\n)\n\ntype XdgPopup_delegate interface {\n\tXdgPopup_destroy(s ClientState, object_id ObjectID[XdgPopup]) bool\n\tXdgPopup_grab(s ClientState, object_id ObjectID[XdgPopup], seat ObjectID[WlSeat], serial uint32)\n\tXdgPopup_reposition(s ClientState, object_id ObjectID[XdgPopup], positioner ObjectID[XdgPositioner], token uint32)\n\tOnBind(s ClientState, name AnyObjectID, interface_ string, new_id AnyObjectID, version_number uint32)\n}\n\ntype XdgPopup struct {\n\tDelegate XdgPopup_delegate\n}\n\nfunc (p *XdgPopup) GetDelegate() XdgPopup_delegate {\n\treturn p.Delegate\n}\nfunc (p *XdgPopup) GetBindable() OnBindable {\n\treturn p.Delegate\n}\n\nfunc XdgPopup_configure(s Sender, eventObjectID ObjectID[XdgPopup], x int32, y int32, width int32, height int32) {\n\tdata := make([]byte, 0)\n\tputInt32 := func(v int32) { uv := uint32(v); data = append(data, byte(uv), byte(uv>>8), byte(uv>>16), byte(uv>>24)) }\n\tvar fileDescriptor *FileDescriptor\n\tputInt32(int32(x))\n\tputInt32(int32(y))\n\tputInt32(int32(width))\n\tputInt32(int32(height))\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         0,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc XdgPopup_popup_done(s Sender, eventObjectID ObjectID[XdgPopup]) {\n\tdata := make([]byte, 0)\n\tvar fileDescriptor *FileDescriptor\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         1,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc XdgPopup_repositioned(s Sender, boundVersion uint32, eventObjectID ObjectID[XdgPopup], token uint32) {\n\tif boundVersion < 3 {\n\t\t// Event not available in this version; skip\n\t\treturn\n\t}\n\tdata := make([]byte, 0)\n\tputUint32 := func(v uint32) { data = append(data, byte(v), byte(v>>8), byte(v>>16), byte(v>>24)) }\n\tvar fileDescriptor *FileDescriptor\n\tputUint32(uint32(token))\n\tobj := OutgoingEvent{\n\t\tObjectID:       AnyObjectID(eventObjectID),\n\t\tOpcode:         2,\n\t\tData:           data,\n\t\tFileDescriptor: fileDescriptor,\n\t}\n\ts.Send(obj)\n}\n\nfunc (p *XdgPopup) OnRequest(s FileDescriptorClaimClientState, message Message) {\n\t_data_in_offset__ := 0\n\t_ = _data_in_offset__\n\td := p.Delegate\n\tswitch message.Opcode {\n\tcase 0:\n\t\t{\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"XdgPopup@\", message.ObjectID, \".destroy(\")\n\t\t\t\tfmt.Println(\")\")\n\t\t\t}\n\n\t\t\tautoRemove := d.XdgPopup_destroy(s, ObjectID[XdgPopup](message.ObjectID))\n\t\t\tif autoRemove {\n\t\t\t\ts.RemoveObject(message.ObjectID)\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\n\tcase 1:\n\t\t{\n\n\t\t\tseat := ObjectID[WlSeat](uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tserial := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"XdgPopup@\", message.ObjectID, \".grab(\")\n\t\t\t\tfmt.Println(\"seat: \", seat, \", \", \"serial: \", serial, \")\")\n\t\t\t}\n\n\t\t\td.XdgPopup_grab(s, ObjectID[XdgPopup](message.ObjectID), seat, serial)\n\t\t\tbreak\n\t\t}\n\n\tcase 2:\n\t\t{\n\n\t\t\tpositioner := ObjectID[XdgPositioner](uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\ttoken := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"XdgPopup@\", message.ObjectID, \".reposition(\")\n\t\t\t\tfmt.Println(\"positioner: \", positioner, \", \", \"token: \", token, \")\")\n\t\t\t}\n\n\t\t\td.XdgPopup_reposition(s, ObjectID[XdgPopup](message.ObjectID), positioner, token)\n\t\t\tbreak\n\t\t}\n\n\tdefault:\n\t\tfmt.Println(\"Unknown opcode on XdgPopup\", message.Opcode)\n\t}\n}\n\ntype XdgPopupError_enum uint32\n\nconst (\n\tXdgPopupError_enum_invalid_grab XdgPopupError_enum = 0\n)\n"
  },
  {
    "path": "wayland/protocols/xwayland-keyboard-grab-unstable-v1.xml.go",
    "content": "// Code generated by `cmd/protocols`; DO NOT EDIT.\n\npackage protocols\n\nimport \"fmt\"\n\ntype ZwpXwaylandKeyboardGrabManagerV1_delegate interface {\n\tZwpXwaylandKeyboardGrabManagerV1_destroy(s ClientState, object_id ObjectID[ZwpXwaylandKeyboardGrabManagerV1]) bool\n\tZwpXwaylandKeyboardGrabManagerV1_grab_keyboard(s ClientState, object_id ObjectID[ZwpXwaylandKeyboardGrabManagerV1], id ObjectID[ZwpXwaylandKeyboardGrabV1], surface ObjectID[WlSurface], seat ObjectID[WlSeat])\n\tOnBind(s ClientState, name AnyObjectID, interface_ string, new_id AnyObjectID, version_number uint32)\n}\n\ntype ZwpXwaylandKeyboardGrabManagerV1 struct {\n\tDelegate ZwpXwaylandKeyboardGrabManagerV1_delegate\n}\n\nfunc (p *ZwpXwaylandKeyboardGrabManagerV1) GetDelegate() ZwpXwaylandKeyboardGrabManagerV1_delegate {\n\treturn p.Delegate\n}\nfunc (p *ZwpXwaylandKeyboardGrabManagerV1) GetBindable() OnBindable {\n\treturn p.Delegate\n}\n\nfunc (p *ZwpXwaylandKeyboardGrabManagerV1) OnRequest(s FileDescriptorClaimClientState, message Message) {\n\t_data_in_offset__ := 0\n\t_ = _data_in_offset__\n\td := p.Delegate\n\tswitch message.Opcode {\n\tcase 0:\n\t\t{\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"ZwpXwaylandKeyboardGrabManagerV1@\", message.ObjectID, \".destroy(\")\n\t\t\t\tfmt.Println(\")\")\n\t\t\t}\n\n\t\t\tautoRemove := d.ZwpXwaylandKeyboardGrabManagerV1_destroy(s, ObjectID[ZwpXwaylandKeyboardGrabManagerV1](message.ObjectID))\n\t\t\tif autoRemove {\n\t\t\t\ts.RemoveObject(message.ObjectID)\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\n\tcase 1:\n\t\t{\n\n\t\t\tidVal := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\tid := ObjectID[ZwpXwaylandKeyboardGrabV1](idVal)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tsurface := ObjectID[WlSurface](uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tseat := ObjectID[WlSeat](uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"ZwpXwaylandKeyboardGrabManagerV1@\", message.ObjectID, \".grab_keyboard(\")\n\t\t\t\tfmt.Println(\"id: \", id, \", \", \"surface: \", surface, \", \", \"seat: \", seat, \")\")\n\t\t\t}\n\n\t\t\td.ZwpXwaylandKeyboardGrabManagerV1_grab_keyboard(s, ObjectID[ZwpXwaylandKeyboardGrabManagerV1](message.ObjectID), id, surface, seat)\n\t\t\tbreak\n\t\t}\n\n\tdefault:\n\t\tfmt.Println(\"Unknown opcode on ZwpXwaylandKeyboardGrabManagerV1\", message.Opcode)\n\t}\n}\n\ntype ZwpXwaylandKeyboardGrabV1_delegate interface {\n\tZwpXwaylandKeyboardGrabV1_destroy(s ClientState, object_id ObjectID[ZwpXwaylandKeyboardGrabV1]) bool\n\tOnBind(s ClientState, name AnyObjectID, interface_ string, new_id AnyObjectID, version_number uint32)\n}\n\ntype ZwpXwaylandKeyboardGrabV1 struct {\n\tDelegate ZwpXwaylandKeyboardGrabV1_delegate\n}\n\nfunc (p *ZwpXwaylandKeyboardGrabV1) GetDelegate() ZwpXwaylandKeyboardGrabV1_delegate {\n\treturn p.Delegate\n}\nfunc (p *ZwpXwaylandKeyboardGrabV1) GetBindable() OnBindable {\n\treturn p.Delegate\n}\n\nfunc (p *ZwpXwaylandKeyboardGrabV1) OnRequest(s FileDescriptorClaimClientState, message Message) {\n\t_data_in_offset__ := 0\n\t_ = _data_in_offset__\n\td := p.Delegate\n\tswitch message.Opcode {\n\tcase 0:\n\t\t{\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"ZwpXwaylandKeyboardGrabV1@\", message.ObjectID, \".destroy(\")\n\t\t\t\tfmt.Println(\")\")\n\t\t\t}\n\n\t\t\tautoRemove := d.ZwpXwaylandKeyboardGrabV1_destroy(s, ObjectID[ZwpXwaylandKeyboardGrabV1](message.ObjectID))\n\t\t\tif autoRemove {\n\t\t\t\ts.RemoveObject(message.ObjectID)\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\n\tdefault:\n\t\tfmt.Println(\"Unknown opcode on ZwpXwaylandKeyboardGrabV1\", message.Opcode)\n\t}\n}\n"
  },
  {
    "path": "wayland/protocols/xwayland-shell-v1.xml.go",
    "content": "// Code generated by `cmd/protocols`; DO NOT EDIT.\n\npackage protocols\n\nimport \"fmt\"\n\ntype XwaylandShellV1_delegate interface {\n\tXwaylandShellV1_destroy(s ClientState, object_id ObjectID[XwaylandShellV1]) bool\n\tXwaylandShellV1_get_xwayland_surface(s ClientState, object_id ObjectID[XwaylandShellV1], id ObjectID[XwaylandSurfaceV1], surface ObjectID[WlSurface])\n\tOnBind(s ClientState, name AnyObjectID, interface_ string, new_id AnyObjectID, version_number uint32)\n}\n\ntype XwaylandShellV1 struct {\n\tDelegate XwaylandShellV1_delegate\n}\n\nfunc (p *XwaylandShellV1) GetDelegate() XwaylandShellV1_delegate {\n\treturn p.Delegate\n}\nfunc (p *XwaylandShellV1) GetBindable() OnBindable {\n\treturn p.Delegate\n}\n\nfunc (p *XwaylandShellV1) OnRequest(s FileDescriptorClaimClientState, message Message) {\n\t_data_in_offset__ := 0\n\t_ = _data_in_offset__\n\td := p.Delegate\n\tswitch message.Opcode {\n\tcase 0:\n\t\t{\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"XwaylandShellV1@\", message.ObjectID, \".destroy(\")\n\t\t\t\tfmt.Println(\")\")\n\t\t\t}\n\n\t\t\tautoRemove := d.XwaylandShellV1_destroy(s, ObjectID[XwaylandShellV1](message.ObjectID))\n\t\t\tif autoRemove {\n\t\t\t\ts.RemoveObject(message.ObjectID)\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\n\tcase 1:\n\t\t{\n\n\t\t\tidVal := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\tid := ObjectID[XwaylandSurfaceV1](idVal)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tsurface := ObjectID[WlSurface](uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24)\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"XwaylandShellV1@\", message.ObjectID, \".get_xwayland_surface(\")\n\t\t\t\tfmt.Println(\"id: \", id, \", \", \"surface: \", surface, \")\")\n\t\t\t}\n\n\t\t\td.XwaylandShellV1_get_xwayland_surface(s, ObjectID[XwaylandShellV1](message.ObjectID), id, surface)\n\t\t\tbreak\n\t\t}\n\n\tdefault:\n\t\tfmt.Println(\"Unknown opcode on XwaylandShellV1\", message.Opcode)\n\t}\n}\n\ntype XwaylandShellV1Error_enum uint32\n\nconst (\n\tXwaylandShellV1Error_enum_role XwaylandShellV1Error_enum = 0\n)\n\ntype XwaylandSurfaceV1_delegate interface {\n\tXwaylandSurfaceV1_set_serial(s ClientState, object_id ObjectID[XwaylandSurfaceV1], serial_lo uint32, serial_hi uint32)\n\tXwaylandSurfaceV1_destroy(s ClientState, object_id ObjectID[XwaylandSurfaceV1]) bool\n\tOnBind(s ClientState, name AnyObjectID, interface_ string, new_id AnyObjectID, version_number uint32)\n}\n\ntype XwaylandSurfaceV1 struct {\n\tDelegate XwaylandSurfaceV1_delegate\n}\n\nfunc (p *XwaylandSurfaceV1) GetDelegate() XwaylandSurfaceV1_delegate {\n\treturn p.Delegate\n}\nfunc (p *XwaylandSurfaceV1) GetBindable() OnBindable {\n\treturn p.Delegate\n}\n\nfunc (p *XwaylandSurfaceV1) OnRequest(s FileDescriptorClaimClientState, message Message) {\n\t_data_in_offset__ := 0\n\t_ = _data_in_offset__\n\td := p.Delegate\n\tswitch message.Opcode {\n\tcase 0:\n\t\t{\n\n\t\t\tserial_lo := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tserial_hi := uint32(message.Data[_data_in_offset__+0]) | uint32(message.Data[_data_in_offset__+1])<<8 |\n\t\t\t\tuint32(message.Data[_data_in_offset__+2])<<16 | uint32(message.Data[_data_in_offset__+3])<<24\n\t\t\t_data_in_offset__ += 4\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"XwaylandSurfaceV1@\", message.ObjectID, \".set_serial(\")\n\t\t\t\tfmt.Println(\"serial_lo: \", serial_lo, \", \", \"serial_hi: \", serial_hi, \")\")\n\t\t\t}\n\n\t\t\td.XwaylandSurfaceV1_set_serial(s, ObjectID[XwaylandSurfaceV1](message.ObjectID), serial_lo, serial_hi)\n\t\t\tbreak\n\t\t}\n\n\tcase 1:\n\t\t{\n\n\t\t\tif DebugRequests {\n\t\t\t\tfmt.Print(\"XwaylandSurfaceV1@\", message.ObjectID, \".destroy(\")\n\t\t\t\tfmt.Println(\")\")\n\t\t\t}\n\n\t\t\tautoRemove := d.XwaylandSurfaceV1_destroy(s, ObjectID[XwaylandSurfaceV1](message.ObjectID))\n\t\t\tif autoRemove {\n\t\t\t\ts.RemoveObject(message.ObjectID)\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\n\tdefault:\n\t\tfmt.Println(\"Unknown opcode on XwaylandSurfaceV1\", message.Opcode)\n\t}\n}\n\ntype XwaylandSurfaceV1Error_enum uint32\n\nconst (\n\tXwaylandSurfaceV1Error_enum_already_associated XwaylandSurfaceV1Error_enum = 0\n\tXwaylandSurfaceV1Error_enum_invalid_serial     XwaylandSurfaceV1Error_enum = 1\n)\n"
  },
  {
    "path": "wayland/resources/server-1.xkb",
    "content": "xkb_keymap {\nxkb_keycodes \"evdev+aliases(qwerty)\" {\n    minimum = 8;\n    maximum = 255;\n     <ESC> = 9;\n    <AE01> = 10;\n    <AE02> = 11;\n    <AE03> = 12;\n    <AE04> = 13;\n    <AE05> = 14;\n    <AE06> = 15;\n    <AE07> = 16;\n    <AE08> = 17;\n    <AE09> = 18;\n    <AE10> = 19;\n    <AE11> = 20;\n    <AE12> = 21;\n    <BKSP> = 22;\n     <TAB> = 23;\n    <AD01> = 24;\n    <AD02> = 25;\n    <AD03> = 26;\n    <AD04> = 27;\n    <AD05> = 28;\n    <AD06> = 29;\n    <AD07> = 30;\n    <AD08> = 31;\n    <AD09> = 32;\n    <AD10> = 33;\n    <AD11> = 34;\n    <AD12> = 35;\n    <RTRN> = 36;\n    <LCTL> = 37;\n    <AC01> = 38;\n    <AC02> = 39;\n    <AC03> = 40;\n    <AC04> = 41;\n    <AC05> = 42;\n    <AC06> = 43;\n    <AC07> = 44;\n    <AC08> = 45;\n    <AC09> = 46;\n    <AC10> = 47;\n    <AC11> = 48;\n    <TLDE> = 49;\n    <LFSH> = 50;\n    <BKSL> = 51;\n    <AB01> = 52;\n    <AB02> = 53;\n    <AB03> = 54;\n    <AB04> = 55;\n    <AB05> = 56;\n    <AB06> = 57;\n    <AB07> = 58;\n    <AB08> = 59;\n    <AB09> = 60;\n    <AB10> = 61;\n    <RTSH> = 62;\n    <KPMU> = 63;\n    <LALT> = 64;\n    <SPCE> = 65;\n    <CAPS> = 66;\n    <FK01> = 67;\n    <FK02> = 68;\n    <FK03> = 69;\n    <FK04> = 70;\n    <FK05> = 71;\n    <FK06> = 72;\n    <FK07> = 73;\n    <FK08> = 74;\n    <FK09> = 75;\n    <FK10> = 76;\n    <NMLK> = 77;\n    <SCLK> = 78;\n     <KP7> = 79;\n     <KP8> = 80;\n     <KP9> = 81;\n    <KPSU> = 82;\n     <KP4> = 83;\n     <KP5> = 84;\n     <KP6> = 85;\n    <KPAD> = 86;\n     <KP1> = 87;\n     <KP2> = 88;\n     <KP3> = 89;\n     <KP0> = 90;\n    <KPDL> = 91;\n    <LVL3> = 92;\n    <LSGT> = 94;\n    <FK11> = 95;\n    <FK12> = 96;\n    <AB11> = 97;\n    <KATA> = 98;\n    <HIRA> = 99;\n    <HENK> = 100;\n    <HKTG> = 101;\n    <MUHE> = 102;\n    <JPCM> = 103;\n    <KPEN> = 104;\n    <RCTL> = 105;\n    <KPDV> = 106;\n    <PRSC> = 107;\n    <RALT> = 108;\n    <LNFD> = 109;\n    <HOME> = 110;\n      <UP> = 111;\n    <PGUP> = 112;\n    <LEFT> = 113;\n    <RGHT> = 114;\n     <END> = 115;\n    <DOWN> = 116;\n    <PGDN> = 117;\n     <INS> = 118;\n    <DELE> = 119;\n    <I120> = 120;\n    <MUTE> = 121;\n    <VOL-> = 122;\n    <VOL+> = 123;\n    <POWR> = 124;\n    <KPEQ> = 125;\n    <I126> = 126;\n    <PAUS> = 127;\n    <I128> = 128;\n    <I129> = 129;\n    <HNGL> = 130;\n    <HJCV> = 131;\n    <AE13> = 132;\n    <LWIN> = 133;\n    <RWIN> = 134;\n    <COMP> = 135;\n    <STOP> = 136;\n    <AGAI> = 137;\n    <PROP> = 138;\n    <UNDO> = 139;\n    <FRNT> = 140;\n    <COPY> = 141;\n    <OPEN> = 142;\n    <PAST> = 143;\n    <FIND> = 144;\n     <CUT> = 145;\n    <HELP> = 146;\n    <I147> = 147;\n    <I148> = 148;\n    <I149> = 149;\n    <I150> = 150;\n    <I151> = 151;\n    <I152> = 152;\n    <I153> = 153;\n    <I154> = 154;\n    <I155> = 155;\n    <I156> = 156;\n    <I157> = 157;\n    <I158> = 158;\n    <I159> = 159;\n    <I160> = 160;\n    <I161> = 161;\n    <I162> = 162;\n    <I163> = 163;\n    <I164> = 164;\n    <I165> = 165;\n    <I166> = 166;\n    <I167> = 167;\n    <I168> = 168;\n    <I169> = 169;\n    <I170> = 170;\n    <I171> = 171;\n    <I172> = 172;\n    <I173> = 173;\n    <I174> = 174;\n    <I175> = 175;\n    <I176> = 176;\n    <I177> = 177;\n    <I178> = 178;\n    <I179> = 179;\n    <I180> = 180;\n    <I181> = 181;\n    <I182> = 182;\n    <I183> = 183;\n    <I184> = 184;\n    <I185> = 185;\n    <I186> = 186;\n    <I187> = 187;\n    <I188> = 188;\n    <I189> = 189;\n    <I190> = 190;\n    <FK13> = 191;\n    <FK14> = 192;\n    <FK15> = 193;\n    <FK16> = 194;\n    <FK17> = 195;\n    <FK18> = 196;\n    <FK19> = 197;\n    <FK20> = 198;\n    <FK21> = 199;\n    <FK22> = 200;\n    <FK23> = 201;\n    <FK24> = 202;\n    <MDSW> = 203;\n     <ALT> = 204;\n    <META> = 205;\n    <SUPR> = 206;\n    <HYPR> = 207;\n    <I208> = 208;\n    <I209> = 209;\n    <I210> = 210;\n    <I211> = 211;\n    <I212> = 212;\n    <I213> = 213;\n    <I214> = 214;\n    <I215> = 215;\n    <I216> = 216;\n    <I217> = 217;\n    <I218> = 218;\n    <I219> = 219;\n    <I220> = 220;\n    <I221> = 221;\n    <I222> = 222;\n    <I223> = 223;\n    <I224> = 224;\n    <I225> = 225;\n    <I226> = 226;\n    <I227> = 227;\n    <I228> = 228;\n    <I229> = 229;\n    <I230> = 230;\n    <I231> = 231;\n    <I232> = 232;\n    <I233> = 233;\n    <I234> = 234;\n    <I235> = 235;\n    <I236> = 236;\n    <I237> = 237;\n    <I238> = 238;\n    <I239> = 239;\n    <I240> = 240;\n    <I241> = 241;\n    <I242> = 242;\n    <I243> = 243;\n    <I244> = 244;\n    <I245> = 245;\n    <I246> = 246;\n    <I247> = 247;\n    <I248> = 248;\n    <I249> = 249;\n    <I250> = 250;\n    <I251> = 251;\n    <I252> = 252;\n    <I253> = 253;\n    <I254> = 254;\n    <I255> = 255;\n    indicator 1 = \"Caps Lock\";\n    indicator 2 = \"Num Lock\";\n    indicator 3 = \"Scroll Lock\";\n    indicator 4 = \"Compose\";\n    indicator 5 = \"Kana\";\n    indicator 6 = \"Sleep\";\n    indicator 7 = \"Suspend\";\n    indicator 8 = \"Mute\";\n    indicator 9 = \"Misc\";\n    indicator 10 = \"Mail\";\n    indicator 11 = \"Charging\";\n    virtual indicator 12 = \"Shift Lock\";\n    virtual indicator 13 = \"Group 2\";\n    virtual indicator 14 = \"Mouse Keys\";\n    alias <AC12> = <BKSL>;\n    alias <MENU> = <COMP>;\n    alias <HZTG> = <TLDE>;\n    alias <LMTA> = <LWIN>;\n    alias <RMTA> = <RWIN>;\n    alias <OUTP> = <I235>;\n    alias <KITG> = <I236>;\n    alias <KIDN> = <I237>;\n    alias <KIUP> = <I238>;\n    alias <I121> = <MUTE>;\n    alias <I122> = <VOL->;\n    alias <I123> = <VOL+>;\n    alias <I124> = <POWR>;\n    alias <I125> = <KPEQ>;\n    alias <I127> = <PAUS>;\n    alias <I130> = <HNGL>;\n    alias <I131> = <HJCV>;\n    alias <I132> = <AE13>;\n    alias <I133> = <LWIN>;\n    alias <I134> = <RWIN>;\n    alias <I135> = <COMP>;\n    alias <I136> = <STOP>;\n    alias <I137> = <AGAI>;\n    alias <I138> = <PROP>;\n    alias <I139> = <UNDO>;\n    alias <I140> = <FRNT>;\n    alias <I141> = <COPY>;\n    alias <I142> = <OPEN>;\n    alias <I143> = <PAST>;\n    alias <I144> = <FIND>;\n    alias <I145> =  <CUT>;\n    alias <I146> = <HELP>;\n    alias <I191> = <FK13>;\n    alias <I192> = <FK14>;\n    alias <I193> = <FK15>;\n    alias <I194> = <FK16>;\n    alias <I195> = <FK17>;\n    alias <I196> = <FK18>;\n    alias <I197> = <FK19>;\n    alias <I198> = <FK20>;\n    alias <I199> = <FK21>;\n    alias <I200> = <FK22>;\n    alias <I201> = <FK23>;\n    alias <I202> = <FK24>;\n    alias <ALGR> = <RALT>;\n    alias <KPPT> = <I129>;\n    alias <LatQ> = <AD01>;\n    alias <LatW> = <AD02>;\n    alias <LatE> = <AD03>;\n    alias <LatR> = <AD04>;\n    alias <LatT> = <AD05>;\n    alias <LatY> = <AD06>;\n    alias <LatU> = <AD07>;\n    alias <LatI> = <AD08>;\n    alias <LatO> = <AD09>;\n    alias <LatP> = <AD10>;\n    alias <LatA> = <AC01>;\n    alias <LatS> = <AC02>;\n    alias <LatD> = <AC03>;\n    alias <LatF> = <AC04>;\n    alias <LatG> = <AC05>;\n    alias <LatH> = <AC06>;\n    alias <LatJ> = <AC07>;\n    alias <LatK> = <AC08>;\n    alias <LatL> = <AC09>;\n    alias <LatZ> = <AB01>;\n    alias <LatX> = <AB02>;\n    alias <LatC> = <AB03>;\n    alias <LatV> = <AB04>;\n    alias <LatB> = <AB05>;\n    alias <LatN> = <AB06>;\n    alias <LatM> = <AB07>;\n};\n\nxkb_types \"complete\" {\n\n    virtual_modifiers NumLock,Alt,LevelThree,LAlt,RAlt,RControl,LControl,ScrollLock,LevelFive,AltGr,Meta,Super,Hyper;\n\n    type \"ONE_LEVEL\" {\n        modifiers= none;\n        level_name[Level1]= \"Any\";\n    };\n    type \"TWO_LEVEL\" {\n        modifiers= Shift;\n        map[Shift]= Level2;\n        level_name[Level1]= \"Base\";\n        level_name[Level2]= \"Shift\";\n    };\n    type \"ALPHABETIC\" {\n        modifiers= Shift+Lock;\n        map[Shift]= Level2;\n        map[Lock]= Level2;\n        level_name[Level1]= \"Base\";\n        level_name[Level2]= \"Caps\";\n    };\n    type \"KEYPAD\" {\n        modifiers= Shift+NumLock;\n        map[NumLock]= Level2;\n        level_name[Level1]= \"Base\";\n        level_name[Level2]= \"Number\";\n    };\n    type \"SHIFT+ALT\" {\n        modifiers= Shift+Alt;\n        map[Shift+Alt]= Level2;\n        level_name[Level1]= \"Base\";\n        level_name[Level2]= \"Shift+Alt\";\n    };\n    type \"PC_SUPER_LEVEL2\" {\n        modifiers= Mod4;\n        map[Mod4]= Level2;\n        level_name[Level1]= \"Base\";\n        level_name[Level2]= \"Super\";\n    };\n    type \"PC_CONTROL_LEVEL2\" {\n        modifiers= Control;\n        map[Control]= Level2;\n        level_name[Level1]= \"Base\";\n        level_name[Level2]= \"Control\";\n    };\n    type \"PC_LCONTROL_LEVEL2\" {\n        modifiers= LControl;\n        map[LControl]= Level2;\n        level_name[Level1]= \"Base\";\n        level_name[Level2]= \"LControl\";\n    };\n    type \"PC_RCONTROL_LEVEL2\" {\n        modifiers= RControl;\n        map[RControl]= Level2;\n        level_name[Level1]= \"Base\";\n        level_name[Level2]= \"RControl\";\n    };\n    type \"PC_ALT_LEVEL2\" {\n        modifiers= Alt;\n        map[Alt]= Level2;\n        level_name[Level1]= \"Base\";\n        level_name[Level2]= \"Alt\";\n    };\n    type \"PC_LALT_LEVEL2\" {\n        modifiers= LAlt;\n        map[LAlt]= Level2;\n        level_name[Level1]= \"Base\";\n        level_name[Level2]= \"LAlt\";\n    };\n    type \"PC_RALT_LEVEL2\" {\n        modifiers= RAlt;\n        map[RAlt]= Level2;\n        level_name[Level1]= \"Base\";\n        level_name[Level2]= \"RAlt\";\n    };\n    type \"CTRL+ALT\" {\n        modifiers= Shift+Control+Alt+LevelThree;\n        map[Shift]= Level2;\n        preserve[Shift]= Shift;\n        map[LevelThree]= Level3;\n        map[Shift+LevelThree]= Level4;\n        preserve[Shift+LevelThree]= Shift;\n        map[Control+Alt]= Level5;\n        level_name[Level1]= \"Base\";\n        level_name[Level2]= \"Shift\";\n        level_name[Level3]= \"Alt Base\";\n        level_name[Level4]= \"Shift Alt\";\n        level_name[Level5]= \"Ctrl+Alt\";\n    };\n    type \"LOCAL_EIGHT_LEVEL\" {\n        modifiers= Shift+Lock+Control+LevelThree;\n        map[Shift+Lock]= Level1;\n        map[Shift]= Level2;\n        map[Lock]= Level2;\n        map[LevelThree]= Level3;\n        map[Shift+Lock+LevelThree]= Level3;\n        map[Shift+LevelThree]= Level4;\n        map[Lock+LevelThree]= Level4;\n        map[Control]= Level5;\n        map[Shift+Lock+Control]= Level5;\n        map[Shift+Control]= Level6;\n        map[Lock+Control]= Level6;\n        map[Control+LevelThree]= Level7;\n        map[Shift+Lock+Control+LevelThree]= Level7;\n        map[Shift+Control+LevelThree]= Level8;\n        map[Lock+Control+LevelThree]= Level8;\n        level_name[Level1]= \"Base\";\n        level_name[Level2]= \"Shift\";\n        level_name[Level3]= \"Level3\";\n        level_name[Level4]= \"Shift Level3\";\n        level_name[Level5]= \"Ctrl\";\n        level_name[Level6]= \"Shift Ctrl\";\n        level_name[Level7]= \"Level3 Ctrl\";\n        level_name[Level8]= \"Shift Level3 Ctrl\";\n    };\n    type \"THREE_LEVEL\" {\n        modifiers= Shift+LevelThree;\n        map[Shift]= Level2;\n        map[LevelThree]= Level3;\n        map[Shift+LevelThree]= Level3;\n        level_name[Level1]= \"Base\";\n        level_name[Level2]= \"Shift\";\n        level_name[Level3]= \"Level3\";\n    };\n    type \"EIGHT_LEVEL\" {\n        modifiers= Shift+LevelThree+LevelFive;\n        map[Shift]= Level2;\n        map[LevelThree]= Level3;\n        map[Shift+LevelThree]= Level4;\n        map[LevelFive]= Level5;\n        map[Shift+LevelFive]= Level6;\n        map[LevelThree+LevelFive]= Level7;\n        map[Shift+LevelThree+LevelFive]= Level8;\n        level_name[Level1]= \"Base\";\n        level_name[Level2]= \"Shift\";\n        level_name[Level3]= \"Alt Base\";\n        level_name[Level4]= \"Shift Alt\";\n        level_name[Level5]= \"X\";\n        level_name[Level6]= \"X Shift\";\n        level_name[Level7]= \"X Alt Base\";\n        level_name[Level8]= \"X Shift Alt\";\n    };\n    type \"EIGHT_LEVEL_ALPHABETIC\" {\n        modifiers= Shift+Lock+LevelThree+LevelFive;\n        map[Shift]= Level2;\n        map[Lock]= Level2;\n        map[LevelThree]= Level3;\n        map[Shift+LevelThree]= Level4;\n        map[Lock+LevelThree]= Level4;\n        map[Shift+Lock+LevelThree]= Level3;\n        map[LevelFive]= Level5;\n        map[Shift+LevelFive]= Level6;\n        map[Lock+LevelFive]= Level6;\n        map[LevelThree+LevelFive]= Level7;\n        map[Shift+LevelThree+LevelFive]= Level8;\n        map[Lock+LevelThree+LevelFive]= Level8;\n        map[Shift+Lock+LevelThree+LevelFive]= Level7;\n        level_name[Level1]= \"Base\";\n        level_name[Level2]= \"Shift\";\n        level_name[Level3]= \"Alt Base\";\n        level_name[Level4]= \"Shift Alt\";\n        level_name[Level5]= \"X\";\n        level_name[Level6]= \"X Shift\";\n        level_name[Level7]= \"X Alt Base\";\n        level_name[Level8]= \"X Shift Alt\";\n    };\n    type \"EIGHT_LEVEL_LEVEL_FIVE_LOCK\" {\n        modifiers= Shift+Lock+NumLock+LevelThree+LevelFive;\n        map[Shift]= Level2;\n        map[LevelThree]= Level3;\n        map[Shift+LevelThree]= Level4;\n        map[LevelFive]= Level5;\n        map[Shift+LevelFive]= Level6;\n        preserve[Shift+LevelFive]= Shift;\n        map[LevelThree+LevelFive]= Level7;\n        map[Shift+LevelThree+LevelFive]= Level8;\n        map[NumLock]= Level5;\n        map[Shift+NumLock]= Level6;\n        preserve[Shift+NumLock]= Shift;\n        map[NumLock+LevelThree]= Level7;\n        map[Shift+NumLock+LevelThree]= Level8;\n        map[Shift+NumLock+LevelFive]= Level2;\n        map[NumLock+LevelThree+LevelFive]= Level3;\n        map[Shift+NumLock+LevelThree+LevelFive]= Level4;\n        map[Shift+Lock]= Level2;\n        map[Lock+LevelThree]= Level3;\n        map[Shift+Lock+LevelThree]= Level4;\n        map[Lock+LevelFive]= Level5;\n        map[Shift+Lock+LevelFive]= Level6;\n        preserve[Shift+Lock+LevelFive]= Shift;\n        map[Lock+LevelThree+LevelFive]= Level7;\n        map[Shift+Lock+LevelThree+LevelFive]= Level8;\n        map[Lock+NumLock]= Level5;\n        map[Shift+Lock+NumLock]= Level6;\n        preserve[Shift+Lock+NumLock]= Shift;\n        map[Lock+NumLock+LevelThree]= Level7;\n        map[Shift+Lock+NumLock+LevelThree]= Level8;\n        map[Shift+Lock+NumLock+LevelFive]= Level2;\n        map[Lock+NumLock+LevelThree+LevelFive]= Level3;\n        map[Shift+Lock+NumLock+LevelThree+LevelFive]= Level4;\n        level_name[Level1]= \"Base\";\n        level_name[Level2]= \"Shift\";\n        level_name[Level3]= \"Alt Base\";\n        level_name[Level4]= \"Shift Alt\";\n        level_name[Level5]= \"X\";\n        level_name[Level6]= \"X Shift\";\n        level_name[Level7]= \"X Alt Base\";\n        level_name[Level8]= \"X Shift Alt\";\n    };\n    type \"EIGHT_LEVEL_ALPHABETIC_LEVEL_FIVE_LOCK\" {\n        modifiers= Shift+Lock+NumLock+LevelThree+LevelFive;\n        map[Shift]= Level2;\n        map[LevelThree]= Level3;\n        map[Shift+LevelThree]= Level4;\n        map[LevelFive]= Level5;\n        map[Shift+LevelFive]= Level6;\n        preserve[Shift+LevelFive]= Shift;\n        map[LevelThree+LevelFive]= Level7;\n        map[Shift+LevelThree+LevelFive]= Level8;\n        map[NumLock]= Level5;\n        map[Shift+NumLock]= Level6;\n        preserve[Shift+NumLock]= Shift;\n        map[NumLock+LevelThree]= Level7;\n        map[Shift+NumLock+LevelThree]= Level8;\n        map[Shift+NumLock+LevelFive]= Level2;\n        map[NumLock+LevelThree+LevelFive]= Level3;\n        map[Shift+NumLock+LevelThree+LevelFive]= Level4;\n        map[Lock]= Level2;\n        map[Lock+LevelThree]= Level3;\n        map[Shift+Lock+LevelThree]= Level4;\n        map[Lock+LevelFive]= Level5;\n        map[Shift+Lock+LevelFive]= Level6;\n        map[Lock+LevelThree+LevelFive]= Level7;\n        map[Shift+Lock+LevelThree+LevelFive]= Level8;\n        map[Lock+NumLock]= Level5;\n        map[Shift+Lock+NumLock]= Level6;\n        map[Lock+NumLock+LevelThree]= Level7;\n        map[Shift+Lock+NumLock+LevelThree]= Level8;\n        map[Lock+NumLock+LevelFive]= Level2;\n        map[Lock+NumLock+LevelThree+LevelFive]= Level4;\n        map[Shift+Lock+NumLock+LevelThree+LevelFive]= Level3;\n        level_name[Level1]= \"Base\";\n        level_name[Level2]= \"Shift\";\n        level_name[Level3]= \"Alt Base\";\n        level_name[Level4]= \"Shift Alt\";\n        level_name[Level5]= \"X\";\n        level_name[Level6]= \"X Shift\";\n        level_name[Level7]= \"X Alt Base\";\n        level_name[Level8]= \"X Shift Alt\";\n    };\n    type \"EIGHT_LEVEL_SEMIALPHABETIC\" {\n        modifiers= Shift+Lock+LevelThree+LevelFive;\n        map[Shift]= Level2;\n        map[Lock]= Level2;\n        map[LevelThree]= Level3;\n        map[Shift+LevelThree]= Level4;\n        map[Lock+LevelThree]= Level3;\n        preserve[Lock+LevelThree]= Lock;\n        map[Shift+Lock+LevelThree]= Level4;\n        preserve[Shift+Lock+LevelThree]= Lock;\n        map[LevelFive]= Level5;\n        map[Shift+LevelFive]= Level6;\n        map[Lock+LevelFive]= Level6;\n        preserve[Lock+LevelFive]= Lock;\n        map[Shift+Lock+LevelFive]= Level6;\n        preserve[Shift+Lock+LevelFive]= Lock;\n        map[LevelThree+LevelFive]= Level7;\n        map[Shift+LevelThree+LevelFive]= Level8;\n        map[Lock+LevelThree+LevelFive]= Level7;\n        preserve[Lock+LevelThree+LevelFive]= Lock;\n        map[Shift+Lock+LevelThree+LevelFive]= Level8;\n        preserve[Shift+Lock+LevelThree+LevelFive]= Lock;\n        level_name[Level1]= \"Base\";\n        level_name[Level2]= \"Shift\";\n        level_name[Level3]= \"Alt Base\";\n        level_name[Level4]= \"Shift Alt\";\n        level_name[Level5]= \"X\";\n        level_name[Level6]= \"X Shift\";\n        level_name[Level7]= \"X Alt Base\";\n        level_name[Level8]= \"X Shift Alt\";\n    };\n    type \"FOUR_LEVEL\" {\n        modifiers= Shift+LevelThree;\n        map[Shift]= Level2;\n        map[LevelThree]= Level3;\n        map[Shift+LevelThree]= Level4;\n        level_name[Level1]= \"Base\";\n        level_name[Level2]= \"Shift\";\n        level_name[Level3]= \"Alt Base\";\n        level_name[Level4]= \"Shift Alt\";\n    };\n    type \"FOUR_LEVEL_ALPHABETIC\" {\n        modifiers= Shift+Lock+LevelThree;\n        map[Shift]= Level2;\n        map[Lock]= Level2;\n        map[LevelThree]= Level3;\n        map[Shift+LevelThree]= Level4;\n        map[Lock+LevelThree]= Level4;\n        map[Shift+Lock+LevelThree]= Level3;\n        level_name[Level1]= \"Base\";\n        level_name[Level2]= \"Shift\";\n        level_name[Level3]= \"Alt Base\";\n        level_name[Level4]= \"Shift Alt\";\n    };\n    type \"FOUR_LEVEL_SEMIALPHABETIC\" {\n        modifiers= Shift+Lock+LevelThree;\n        map[Shift]= Level2;\n        map[Lock]= Level2;\n        map[LevelThree]= Level3;\n        map[Shift+LevelThree]= Level4;\n        map[Lock+LevelThree]= Level3;\n        preserve[Lock+LevelThree]= Lock;\n        map[Shift+Lock+LevelThree]= Level4;\n        preserve[Shift+Lock+LevelThree]= Lock;\n        level_name[Level1]= \"Base\";\n        level_name[Level2]= \"Shift\";\n        level_name[Level3]= \"Alt Base\";\n        level_name[Level4]= \"Shift Alt\";\n    };\n    type \"FOUR_LEVEL_MIXED_KEYPAD\" {\n        modifiers= Shift+NumLock+LevelThree;\n        map[Shift+NumLock]= Level1;\n        map[NumLock]= Level2;\n        map[Shift]= Level2;\n        map[LevelThree]= Level3;\n        map[NumLock+LevelThree]= Level3;\n        map[Shift+LevelThree]= Level4;\n        map[Shift+NumLock+LevelThree]= Level4;\n        level_name[Level1]= \"Base\";\n        level_name[Level2]= \"Number\";\n        level_name[Level3]= \"Alt Base\";\n        level_name[Level4]= \"Shift Alt\";\n    };\n    type \"FOUR_LEVEL_X\" {\n        modifiers= Shift+Control+Alt+LevelThree;\n        map[LevelThree]= Level2;\n        map[Shift+LevelThree]= Level3;\n        map[Control+Alt]= Level4;\n        level_name[Level1]= \"Base\";\n        level_name[Level2]= \"Alt Base\";\n        level_name[Level3]= \"Shift Alt\";\n        level_name[Level4]= \"Ctrl+Alt\";\n    };\n    type \"SEPARATE_CAPS_AND_SHIFT_ALPHABETIC\" {\n        modifiers= Shift+Lock+LevelThree;\n        map[Shift]= Level2;\n        map[Lock]= Level4;\n        preserve[Lock]= Lock;\n        map[LevelThree]= Level3;\n        map[Shift+LevelThree]= Level4;\n        map[Lock+LevelThree]= Level3;\n        preserve[Lock+LevelThree]= Lock;\n        map[Shift+Lock+LevelThree]= Level3;\n        level_name[Level1]= \"Base\";\n        level_name[Level2]= \"Shift\";\n        level_name[Level3]= \"AltGr Base\";\n        level_name[Level4]= \"Shift AltGr\";\n    };\n    type \"FOUR_LEVEL_PLUS_LOCK\" {\n        modifiers= Shift+Lock+LevelThree;\n        map[Shift]= Level2;\n        map[LevelThree]= Level3;\n        map[Shift+LevelThree]= Level4;\n        map[Lock]= Level5;\n        map[Shift+Lock]= Level2;\n        map[Lock+LevelThree]= Level3;\n        map[Shift+Lock+LevelThree]= Level4;\n        level_name[Level1]= \"Base\";\n        level_name[Level2]= \"Shift\";\n        level_name[Level3]= \"Alt Base\";\n        level_name[Level4]= \"Shift Alt\";\n        level_name[Level5]= \"Lock\";\n    };\n    type \"FOUR_LEVEL_KEYPAD\" {\n        modifiers= Shift+NumLock+LevelThree;\n        map[Shift]= Level2;\n        map[NumLock]= Level2;\n        map[LevelThree]= Level3;\n        map[Shift+LevelThree]= Level4;\n        map[NumLock+LevelThree]= Level4;\n        map[Shift+NumLock+LevelThree]= Level3;\n        level_name[Level1]= \"Base\";\n        level_name[Level2]= \"Number\";\n        level_name[Level3]= \"Alt Base\";\n        level_name[Level4]= \"Alt Number\";\n    };\n};\n\nxkb_compatibility \"complete\" {\n\n    virtual_modifiers NumLock,Alt,LevelThree,LAlt,RAlt,RControl,LControl,ScrollLock,LevelFive,AltGr,Meta,Super,Hyper;\n\n    interpret.useModMapMods= AnyLevel;\n    interpret.repeat= False;\n    interpret.locking= False;\n    interpret ISO_Level2_Latch+Exactly(Shift) {\n        useModMapMods=level1;\n        action= LatchMods(modifiers=Shift,clearLocks,latchToLock);\n    };\n    interpret Shift_Lock+AnyOf(Shift+Lock) {\n        action= LockMods(modifiers=Shift);\n    };\n    interpret Num_Lock+AnyOf(all) {\n        virtualModifier= NumLock;\n        action= LockMods(modifiers=NumLock);\n    };\n    interpret ISO_Level3_Shift+AnyOf(all) {\n        virtualModifier= LevelThree;\n        useModMapMods=level1;\n        action= SetMods(modifiers=LevelThree,clearLocks);\n    };\n    interpret ISO_Level3_Latch+AnyOf(all) {\n        virtualModifier= LevelThree;\n        useModMapMods=level1;\n        action= LatchMods(modifiers=LevelThree,clearLocks,latchToLock);\n    };\n    interpret ISO_Level3_Lock+AnyOf(all) {\n        virtualModifier= LevelThree;\n        useModMapMods=level1;\n        action= LockMods(modifiers=LevelThree);\n    };\n    interpret Alt_L+AnyOf(all) {\n        virtualModifier= Alt;\n        action= SetMods(modifiers=modMapMods,clearLocks);\n    };\n    interpret Alt_R+AnyOf(all) {\n        virtualModifier= Alt;\n        action= SetMods(modifiers=modMapMods,clearLocks);\n    };\n    interpret Meta_L+AnyOf(all) {\n        virtualModifier= Meta;\n        action= SetMods(modifiers=modMapMods,clearLocks);\n    };\n    interpret Meta_R+AnyOf(all) {\n        virtualModifier= Meta;\n        action= SetMods(modifiers=modMapMods,clearLocks);\n    };\n    interpret Super_L+AnyOf(all) {\n        virtualModifier= Super;\n        action= SetMods(modifiers=modMapMods,clearLocks);\n    };\n    interpret Super_R+AnyOf(all) {\n        virtualModifier= Super;\n        action= SetMods(modifiers=modMapMods,clearLocks);\n    };\n    interpret Hyper_L+AnyOf(all) {\n        virtualModifier= Hyper;\n        action= SetMods(modifiers=modMapMods,clearLocks);\n    };\n    interpret Hyper_R+AnyOf(all) {\n        virtualModifier= Hyper;\n        action= SetMods(modifiers=modMapMods,clearLocks);\n    };\n    interpret Scroll_Lock+AnyOf(all) {\n        virtualModifier= ScrollLock;\n        action= LockMods(modifiers=modMapMods);\n    };\n    interpret ISO_Level5_Shift+AnyOf(all) {\n        virtualModifier= LevelFive;\n        useModMapMods=level1;\n        action= SetMods(modifiers=LevelFive,clearLocks);\n    };\n    interpret ISO_Level5_Latch+AnyOf(all) {\n        virtualModifier= LevelFive;\n        useModMapMods=level1;\n        action= LatchMods(modifiers=LevelFive,clearLocks,latchToLock);\n    };\n    interpret ISO_Level5_Lock+AnyOf(all) {\n        virtualModifier= LevelFive;\n        useModMapMods=level1;\n        action= LockMods(modifiers=LevelFive);\n    };\n    interpret Mode_switch+AnyOfOrNone(all) {\n        virtualModifier= AltGr;\n        useModMapMods=level1;\n        action= SetGroup(group=+1);\n    };\n    interpret ISO_Level3_Shift+AnyOfOrNone(all) {\n        action= SetMods(modifiers=LevelThree,clearLocks);\n    };\n    interpret ISO_Level3_Latch+AnyOfOrNone(all) {\n        action= LatchMods(modifiers=LevelThree,clearLocks,latchToLock);\n    };\n    interpret ISO_Level3_Lock+AnyOfOrNone(all) {\n        action= LockMods(modifiers=LevelThree);\n    };\n    interpret ISO_Group_Latch+AnyOfOrNone(all) {\n        virtualModifier= AltGr;\n        useModMapMods=level1;\n        action= LatchGroup(group=2);\n    };\n    interpret ISO_Next_Group+AnyOfOrNone(all) {\n        virtualModifier= AltGr;\n        useModMapMods=level1;\n        action= LockGroup(group=+1);\n    };\n    interpret ISO_Prev_Group+AnyOfOrNone(all) {\n        virtualModifier= AltGr;\n        useModMapMods=level1;\n        action= LockGroup(group=-1);\n    };\n    interpret ISO_First_Group+AnyOfOrNone(all) {\n        action= LockGroup(group=1);\n    };\n    interpret ISO_Last_Group+AnyOfOrNone(all) {\n        action= LockGroup(group=2);\n    };\n    interpret KP_1+AnyOfOrNone(all) {\n        repeat= True;\n        action= MovePtr(x=-1,y=+1);\n    };\n    interpret KP_End+AnyOfOrNone(all) {\n        repeat= True;\n        action= MovePtr(x=-1,y=+1);\n    };\n    interpret KP_2+AnyOfOrNone(all) {\n        repeat= True;\n        action= MovePtr(x=+0,y=+1);\n    };\n    interpret KP_Down+AnyOfOrNone(all) {\n        repeat= True;\n        action= MovePtr(x=+0,y=+1);\n    };\n    interpret KP_3+AnyOfOrNone(all) {\n        repeat= True;\n        action= MovePtr(x=+1,y=+1);\n    };\n    interpret KP_Next+AnyOfOrNone(all) {\n        repeat= True;\n        action= MovePtr(x=+1,y=+1);\n    };\n    interpret KP_4+AnyOfOrNone(all) {\n        repeat= True;\n        action= MovePtr(x=-1,y=+0);\n    };\n    interpret KP_Left+AnyOfOrNone(all) {\n        repeat= True;\n        action= MovePtr(x=-1,y=+0);\n    };\n    interpret KP_6+AnyOfOrNone(all) {\n        repeat= True;\n        action= MovePtr(x=+1,y=+0);\n    };\n    interpret KP_Right+AnyOfOrNone(all) {\n        repeat= True;\n        action= MovePtr(x=+1,y=+0);\n    };\n    interpret KP_7+AnyOfOrNone(all) {\n        repeat= True;\n        action= MovePtr(x=-1,y=-1);\n    };\n    interpret KP_Home+AnyOfOrNone(all) {\n        repeat= True;\n        action= MovePtr(x=-1,y=-1);\n    };\n    interpret KP_8+AnyOfOrNone(all) {\n        repeat= True;\n        action= MovePtr(x=+0,y=-1);\n    };\n    interpret KP_Up+AnyOfOrNone(all) {\n        repeat= True;\n        action= MovePtr(x=+0,y=-1);\n    };\n    interpret KP_9+AnyOfOrNone(all) {\n        repeat= True;\n        action= MovePtr(x=+1,y=-1);\n    };\n    interpret KP_Prior+AnyOfOrNone(all) {\n        repeat= True;\n        action= MovePtr(x=+1,y=-1);\n    };\n    interpret KP_5+AnyOfOrNone(all) {\n        repeat= True;\n        action= PtrBtn(button=default);\n    };\n    interpret KP_Begin+AnyOfOrNone(all) {\n        repeat= True;\n        action= PtrBtn(button=default);\n    };\n    interpret KP_F2+AnyOfOrNone(all) {\n        repeat= True;\n        action= SetPtrDflt(affect=button,button=1);\n    };\n    interpret KP_Divide+AnyOfOrNone(all) {\n        repeat= True;\n        action= SetPtrDflt(affect=button,button=1);\n    };\n    interpret KP_F3+AnyOfOrNone(all) {\n        repeat= True;\n        action= SetPtrDflt(affect=button,button=2);\n    };\n    interpret KP_Multiply+AnyOfOrNone(all) {\n        repeat= True;\n        action= SetPtrDflt(affect=button,button=2);\n    };\n    interpret KP_F4+AnyOfOrNone(all) {\n        repeat= True;\n        action= SetPtrDflt(affect=button,button=3);\n    };\n    interpret KP_Subtract+AnyOfOrNone(all) {\n        repeat= True;\n        action= SetPtrDflt(affect=button,button=3);\n    };\n    interpret KP_Separator+AnyOfOrNone(all) {\n        repeat= True;\n        action= PtrBtn(button=default,count=2);\n    };\n    interpret KP_Add+AnyOfOrNone(all) {\n        repeat= True;\n        action= PtrBtn(button=default,count=2);\n    };\n    interpret KP_0+AnyOfOrNone(all) {\n        repeat= True;\n        action= LockPtrBtn(button=default,affect=lock);\n    };\n    interpret KP_Insert+AnyOfOrNone(all) {\n        repeat= True;\n        action= LockPtrBtn(button=default,affect=lock);\n    };\n    interpret KP_Decimal+AnyOfOrNone(all) {\n        repeat= True;\n        action= LockPtrBtn(button=default,affect=unlock);\n    };\n    interpret KP_Delete+AnyOfOrNone(all) {\n        repeat= True;\n        action= LockPtrBtn(button=default,affect=unlock);\n    };\n    interpret F25+AnyOfOrNone(all) {\n        repeat= True;\n        action= SetPtrDflt(affect=button,button=1);\n    };\n    interpret F26+AnyOfOrNone(all) {\n        repeat= True;\n        action= SetPtrDflt(affect=button,button=2);\n    };\n    interpret F27+AnyOfOrNone(all) {\n        repeat= True;\n        action= MovePtr(x=-1,y=-1);\n    };\n    interpret F29+AnyOfOrNone(all) {\n        repeat= True;\n        action= MovePtr(x=+1,y=-1);\n    };\n    interpret F31+AnyOfOrNone(all) {\n        repeat= True;\n        action= PtrBtn(button=default);\n    };\n    interpret F33+AnyOfOrNone(all) {\n        repeat= True;\n        action= MovePtr(x=-1,y=+1);\n    };\n    interpret F35+AnyOfOrNone(all) {\n        repeat= True;\n        action= MovePtr(x=+1,y=+1);\n    };\n    interpret Pointer_Button_Dflt+AnyOfOrNone(all) {\n        action= PtrBtn(button=default);\n    };\n    interpret Pointer_Button1+AnyOfOrNone(all) {\n        action= PtrBtn(button=1);\n    };\n    interpret Pointer_Button2+AnyOfOrNone(all) {\n        action= PtrBtn(button=2);\n    };\n    interpret Pointer_Button3+AnyOfOrNone(all) {\n        action= PtrBtn(button=3);\n    };\n    interpret Pointer_DblClick_Dflt+AnyOfOrNone(all) {\n        action= PtrBtn(button=default,count=2);\n    };\n    interpret Pointer_DblClick1+AnyOfOrNone(all) {\n        action= PtrBtn(button=1,count=2);\n    };\n    interpret Pointer_DblClick2+AnyOfOrNone(all) {\n        action= PtrBtn(button=2,count=2);\n    };\n    interpret Pointer_DblClick3+AnyOfOrNone(all) {\n        action= PtrBtn(button=3,count=2);\n    };\n    interpret Pointer_Drag_Dflt+AnyOfOrNone(all) {\n        action= LockPtrBtn(button=default,affect=both);\n    };\n    interpret Pointer_Drag1+AnyOfOrNone(all) {\n        action= LockPtrBtn(button=1,affect=both);\n    };\n    interpret Pointer_Drag2+AnyOfOrNone(all) {\n        action= LockPtrBtn(button=2,affect=both);\n    };\n    interpret Pointer_Drag3+AnyOfOrNone(all) {\n        action= LockPtrBtn(button=3,affect=both);\n    };\n    interpret Pointer_EnableKeys+AnyOfOrNone(all) {\n        action= LockControls(controls=MouseKeys);\n    };\n    interpret Pointer_Accelerate+AnyOfOrNone(all) {\n        action= LockControls(controls=MouseKeysAccel);\n    };\n    interpret Pointer_DfltBtnNext+AnyOfOrNone(all) {\n        action= SetPtrDflt(affect=button,button=+1);\n    };\n    interpret Pointer_DfltBtnPrev+AnyOfOrNone(all) {\n        action= SetPtrDflt(affect=button,button=-1);\n    };\n    interpret AccessX_Enable+AnyOfOrNone(all) {\n        action= LockControls(controls=AccessXKeys);\n    };\n    interpret AccessX_Feedback_Enable+AnyOfOrNone(all) {\n        action= LockControls(controls=AccessXFeedback);\n    };\n    interpret RepeatKeys_Enable+AnyOfOrNone(all) {\n        action= LockControls(controls=RepeatKeys);\n    };\n    interpret SlowKeys_Enable+AnyOfOrNone(all) {\n        action= LockControls(controls=SlowKeys);\n    };\n    interpret BounceKeys_Enable+AnyOfOrNone(all) {\n        action= LockControls(controls=BounceKeys);\n    };\n    interpret StickyKeys_Enable+AnyOfOrNone(all) {\n        action= LockControls(controls=StickyKeys);\n    };\n    interpret MouseKeys_Enable+AnyOfOrNone(all) {\n        action= LockControls(controls=MouseKeys);\n    };\n    interpret MouseKeys_Accel_Enable+AnyOfOrNone(all) {\n        action= LockControls(controls=MouseKeysAccel);\n    };\n    interpret Overlay1_Enable+AnyOfOrNone(all) {\n        action= LockControls(controls=Overlay1);\n    };\n    interpret Overlay2_Enable+AnyOfOrNone(all) {\n        action= LockControls(controls=Overlay2);\n    };\n    interpret AudibleBell_Enable+AnyOfOrNone(all) {\n        action= LockControls(controls=AudibleBell);\n    };\n    interpret Terminate_Server+AnyOfOrNone(all) {\n        action= Terminate();\n    };\n    interpret Alt_L+AnyOfOrNone(all) {\n        action= SetMods(modifiers=Alt,clearLocks);\n    };\n    interpret Alt_R+AnyOfOrNone(all) {\n        action= SetMods(modifiers=Alt,clearLocks);\n    };\n    interpret Meta_L+AnyOfOrNone(all) {\n        action= SetMods(modifiers=Meta,clearLocks);\n    };\n    interpret Meta_R+AnyOfOrNone(all) {\n        action= SetMods(modifiers=Meta,clearLocks);\n    };\n    interpret Super_L+AnyOfOrNone(all) {\n        action= SetMods(modifiers=Super,clearLocks);\n    };\n    interpret Super_R+AnyOfOrNone(all) {\n        action= SetMods(modifiers=Super,clearLocks);\n    };\n    interpret Hyper_L+AnyOfOrNone(all) {\n        action= SetMods(modifiers=Hyper,clearLocks);\n    };\n    interpret Hyper_R+AnyOfOrNone(all) {\n        action= SetMods(modifiers=Hyper,clearLocks);\n    };\n    interpret Shift_L+AnyOfOrNone(all) {\n        action= SetMods(modifiers=Shift,clearLocks);\n    };\n    interpret XF86Switch_VT_1+AnyOfOrNone(all) {\n        repeat= True;\n        action= SwitchScreen(screen=1,!same);\n    };\n    interpret XF86Switch_VT_2+AnyOfOrNone(all) {\n        repeat= True;\n        action= SwitchScreen(screen=2,!same);\n    };\n    interpret XF86Switch_VT_3+AnyOfOrNone(all) {\n        repeat= True;\n        action= SwitchScreen(screen=3,!same);\n    };\n    interpret XF86Switch_VT_4+AnyOfOrNone(all) {\n        repeat= True;\n        action= SwitchScreen(screen=4,!same);\n    };\n    interpret XF86Switch_VT_5+AnyOfOrNone(all) {\n        repeat= True;\n        action= SwitchScreen(screen=5,!same);\n    };\n    interpret XF86Switch_VT_6+AnyOfOrNone(all) {\n        repeat= True;\n        action= SwitchScreen(screen=6,!same);\n    };\n    interpret XF86Switch_VT_7+AnyOfOrNone(all) {\n        repeat= True;\n        action= SwitchScreen(screen=7,!same);\n    };\n    interpret XF86Switch_VT_8+AnyOfOrNone(all) {\n        repeat= True;\n        action= SwitchScreen(screen=8,!same);\n    };\n    interpret XF86Switch_VT_9+AnyOfOrNone(all) {\n        repeat= True;\n        action= SwitchScreen(screen=9,!same);\n    };\n    interpret XF86Switch_VT_10+AnyOfOrNone(all) {\n        repeat= True;\n        action= SwitchScreen(screen=10,!same);\n    };\n    interpret XF86Switch_VT_11+AnyOfOrNone(all) {\n        repeat= True;\n        action= SwitchScreen(screen=11,!same);\n    };\n    interpret XF86Switch_VT_12+AnyOfOrNone(all) {\n        repeat= True;\n        action= SwitchScreen(screen=12,!same);\n    };\n    interpret XF86LogGrabInfo+AnyOfOrNone(all) {\n        repeat= True;\n        action= Private(type=0x86,data[0]=0x50,data[1]=0x72,data[2]=0x47,data[3]=0x72,data[4]=0x62,data[5]=0x73,data[6]=0x00);\n    };\n    interpret XF86LogWindowTree+AnyOfOrNone(all) {\n        repeat= True;\n        action= Private(type=0x86,data[0]=0x50,data[1]=0x72,data[2]=0x57,data[3]=0x69,data[4]=0x6e,data[5]=0x73,data[6]=0x00);\n    };\n    interpret XF86Next_VMode+AnyOfOrNone(all) {\n        repeat= True;\n        action= Private(type=0x86,data[0]=0x2b,data[1]=0x56,data[2]=0x4d,data[3]=0x6f,data[4]=0x64,data[5]=0x65,data[6]=0x00);\n    };\n    interpret XF86Prev_VMode+AnyOfOrNone(all) {\n        repeat= True;\n        action= Private(type=0x86,data[0]=0x2d,data[1]=0x56,data[2]=0x4d,data[3]=0x6f,data[4]=0x64,data[5]=0x65,data[6]=0x00);\n    };\n    interpret ISO_Level5_Shift+AnyOfOrNone(all) {\n        action= SetMods(modifiers=LevelFive,clearLocks);\n    };\n    interpret ISO_Level5_Latch+AnyOfOrNone(all) {\n        action= LatchMods(modifiers=LevelFive,clearLocks,latchToLock);\n    };\n    interpret ISO_Level5_Lock+AnyOfOrNone(all) {\n        action= LockMods(modifiers=LevelFive);\n    };\n    interpret Caps_Lock+AnyOfOrNone(all) {\n        action= LockMods(modifiers=Lock);\n    };\n    interpret Any+Exactly(Lock) {\n        action= LockMods(modifiers=Lock);\n    };\n    interpret Any+AnyOf(all) {\n        action= SetMods(modifiers=modMapMods,clearLocks);\n    };\n    group 2 = AltGr;\n    group 3 = AltGr;\n    group 4 = AltGr;\n    indicator \"Caps Lock\" {\n        !allowExplicit;\n        whichModState= locked;\n        modifiers= Lock;\n    };\n    indicator \"Num Lock\" {\n        !allowExplicit;\n        whichModState= locked;\n        modifiers= NumLock;\n    };\n    indicator \"Scroll Lock\" {\n        whichModState= locked;\n        modifiers= ScrollLock;\n    };\n    indicator \"Shift Lock\" {\n        !allowExplicit;\n        whichModState= locked;\n        modifiers= Shift;\n    };\n    indicator \"Group 2\" {\n        !allowExplicit;\n        groups= 0xfe;\n    };\n    indicator \"Mouse Keys\" {\n        indicatorDrivesKeyboard;\n        controls= mouseKeys;\n    };\n};\n\nxkb_symbols \"pc+us+inet(evdev)\" {\n\n    name[group1]=\"English (US)\";\n\n    key  <ESC> {         [          Escape ] };\n    key <AE01> {         [               1,          exclam ] };\n    key <AE02> {         [               2,              at ] };\n    key <AE03> {         [               3,      numbersign ] };\n    key <AE04> {         [               4,          dollar ] };\n    key <AE05> {         [               5,         percent ] };\n    key <AE06> {         [               6,     asciicircum ] };\n    key <AE07> {         [               7,       ampersand ] };\n    key <AE08> {         [               8,        asterisk ] };\n    key <AE09> {         [               9,       parenleft ] };\n    key <AE10> {         [               0,      parenright ] };\n    key <AE11> {         [           minus,      underscore ] };\n    key <AE12> {         [           equal,            plus ] };\n    key <BKSP> {         [       BackSpace,       BackSpace ] };\n    key  <TAB> {         [             Tab,    ISO_Left_Tab ] };\n    key <AD01> {\n        type= \"ALPHABETIC\",\n        symbols[Group1]= [               q,               Q ]\n    };\n    key <AD02> {\n        type= \"ALPHABETIC\",\n        symbols[Group1]= [               w,               W ]\n    };\n    key <AD03> {\n        type= \"ALPHABETIC\",\n        symbols[Group1]= [               e,               E ]\n    };\n    key <AD04> {\n        type= \"ALPHABETIC\",\n        symbols[Group1]= [               r,               R ]\n    };\n    key <AD05> {\n        type= \"ALPHABETIC\",\n        symbols[Group1]= [               t,               T ]\n    };\n    key <AD06> {\n        type= \"ALPHABETIC\",\n        symbols[Group1]= [               y,               Y ]\n    };\n    key <AD07> {\n        type= \"ALPHABETIC\",\n        symbols[Group1]= [               u,               U ]\n    };\n    key <AD08> {\n        type= \"ALPHABETIC\",\n        symbols[Group1]= [               i,               I ]\n    };\n    key <AD09> {\n        type= \"ALPHABETIC\",\n        symbols[Group1]= [               o,               O ]\n    };\n    key <AD10> {\n        type= \"ALPHABETIC\",\n        symbols[Group1]= [               p,               P ]\n    };\n    key <AD11> {         [     bracketleft,       braceleft ] };\n    key <AD12> {         [    bracketright,      braceright ] };\n    key <RTRN> {         [          Return ] };\n    key <LCTL> {         [       Control_L ] };\n    key <AC01> {\n        type= \"ALPHABETIC\",\n        symbols[Group1]= [               a,               A ]\n    };\n    key <AC02> {\n        type= \"ALPHABETIC\",\n        symbols[Group1]= [               s,               S ]\n    };\n    key <AC03> {\n        type= \"ALPHABETIC\",\n        symbols[Group1]= [               d,               D ]\n    };\n    key <AC04> {\n        type= \"ALPHABETIC\",\n        symbols[Group1]= [               f,               F ]\n    };\n    key <AC05> {\n        type= \"ALPHABETIC\",\n        symbols[Group1]= [               g,               G ]\n    };\n    key <AC06> {\n        type= \"ALPHABETIC\",\n        symbols[Group1]= [               h,               H ]\n    };\n    key <AC07> {\n        type= \"ALPHABETIC\",\n        symbols[Group1]= [               j,               J ]\n    };\n    key <AC08> {\n        type= \"ALPHABETIC\",\n        symbols[Group1]= [               k,               K ]\n    };\n    key <AC09> {\n        type= \"ALPHABETIC\",\n        symbols[Group1]= [               l,               L ]\n    };\n    key <AC10> {         [       semicolon,           colon ] };\n    key <AC11> {         [      apostrophe,        quotedbl ] };\n    key <TLDE> {         [           grave,      asciitilde ] };\n    key <LFSH> {         [         Shift_L ] };\n    key <BKSL> {         [       backslash,             bar ] };\n    key <AB01> {\n        type= \"ALPHABETIC\",\n        symbols[Group1]= [               z,               Z ]\n    };\n    key <AB02> {\n        type= \"ALPHABETIC\",\n        symbols[Group1]= [               x,               X ]\n    };\n    key <AB03> {\n        type= \"ALPHABETIC\",\n        symbols[Group1]= [               c,               C ]\n    };\n    key <AB04> {\n        type= \"ALPHABETIC\",\n        symbols[Group1]= [               v,               V ]\n    };\n    key <AB05> {\n        type= \"ALPHABETIC\",\n        symbols[Group1]= [               b,               B ]\n    };\n    key <AB06> {\n        type= \"ALPHABETIC\",\n        symbols[Group1]= [               n,               N ]\n    };\n    key <AB07> {\n        type= \"ALPHABETIC\",\n        symbols[Group1]= [               m,               M ]\n    };\n    key <AB08> {         [           comma,            less ] };\n    key <AB09> {         [          period,         greater ] };\n    key <AB10> {         [           slash,        question ] };\n    key <RTSH> {         [         Shift_R ] };\n    key <KPMU> {\n        type= \"CTRL+ALT\",\n        symbols[Group1]= [     KP_Multiply,     KP_Multiply,     KP_Multiply,     KP_Multiply,   XF86ClearGrab ]\n    };\n    key <LALT> {         [           Alt_L,          Meta_L ] };\n    key <SPCE> {         [           space ] };\n    key <CAPS> {         [       Caps_Lock ] };\n    key <FK01> {\n        type= \"CTRL+ALT\",\n        symbols[Group1]= [              F1,              F1,              F1,              F1, XF86Switch_VT_1 ]\n    };\n    key <FK02> {\n        type= \"CTRL+ALT\",\n        symbols[Group1]= [              F2,              F2,              F2,              F2, XF86Switch_VT_2 ]\n    };\n    key <FK03> {\n        type= \"CTRL+ALT\",\n        symbols[Group1]= [              F3,              F3,              F3,              F3, XF86Switch_VT_3 ]\n    };\n    key <FK04> {\n        type= \"CTRL+ALT\",\n        symbols[Group1]= [              F4,              F4,              F4,              F4, XF86Switch_VT_4 ]\n    };\n    key <FK05> {\n        type= \"CTRL+ALT\",\n        symbols[Group1]= [              F5,              F5,              F5,              F5, XF86Switch_VT_5 ]\n    };\n    key <FK06> {\n        type= \"CTRL+ALT\",\n        symbols[Group1]= [              F6,              F6,              F6,              F6, XF86Switch_VT_6 ]\n    };\n    key <FK07> {\n        type= \"CTRL+ALT\",\n        symbols[Group1]= [              F7,              F7,              F7,              F7, XF86Switch_VT_7 ]\n    };\n    key <FK08> {\n        type= \"CTRL+ALT\",\n        symbols[Group1]= [              F8,              F8,              F8,              F8, XF86Switch_VT_8 ]\n    };\n    key <FK09> {\n        type= \"CTRL+ALT\",\n        symbols[Group1]= [              F9,              F9,              F9,              F9, XF86Switch_VT_9 ]\n    };\n    key <FK10> {\n        type= \"CTRL+ALT\",\n        symbols[Group1]= [             F10,             F10,             F10,             F10, XF86Switch_VT_10 ]\n    };\n    key <NMLK> {         [        Num_Lock ] };\n    key <SCLK> {         [     Scroll_Lock ] };\n    key  <KP7> {         [         KP_Home,            KP_7 ] };\n    key  <KP8> {         [           KP_Up,            KP_8 ] };\n    key  <KP9> {         [        KP_Prior,            KP_9 ] };\n    key <KPSU> {\n        type= \"CTRL+ALT\",\n        symbols[Group1]= [     KP_Subtract,     KP_Subtract,     KP_Subtract,     KP_Subtract,  XF86Prev_VMode ]\n    };\n    key  <KP4> {         [         KP_Left,            KP_4 ] };\n    key  <KP5> {         [        KP_Begin,            KP_5 ] };\n    key  <KP6> {         [        KP_Right,            KP_6 ] };\n    key <KPAD> {\n        type= \"CTRL+ALT\",\n        symbols[Group1]= [          KP_Add,          KP_Add,          KP_Add,          KP_Add,  XF86Next_VMode ]\n    };\n    key  <KP1> {         [          KP_End,            KP_1 ] };\n    key  <KP2> {         [         KP_Down,            KP_2 ] };\n    key  <KP3> {         [         KP_Next,            KP_3 ] };\n    key  <KP0> {         [       KP_Insert,            KP_0 ] };\n    key <KPDL> {         [       KP_Delete,      KP_Decimal ] };\n    key <LVL3> {         [ ISO_Level3_Shift ] };\n    key <LSGT> {\n        type= \"FOUR_LEVEL\",\n        symbols[Group1]= [            less,         greater,             bar,       brokenbar ]\n    };\n    key <FK11> {\n        type= \"CTRL+ALT\",\n        symbols[Group1]= [             F11,             F11,             F11,             F11, XF86Switch_VT_11 ]\n    };\n    key <FK12> {\n        type= \"CTRL+ALT\",\n        symbols[Group1]= [             F12,             F12,             F12,             F12, XF86Switch_VT_12 ]\n    };\n    key <KATA> {         [        Katakana ] };\n    key <HIRA> {         [        Hiragana ] };\n    key <HENK> {         [     Henkan_Mode ] };\n    key <HKTG> {         [ Hiragana_Katakana ] };\n    key <MUHE> {         [        Muhenkan ] };\n    key <KPEN> {         [        KP_Enter ] };\n    key <RCTL> {         [       Control_R ] };\n    key <KPDV> {\n        type= \"CTRL+ALT\",\n        symbols[Group1]= [       KP_Divide,       KP_Divide,       KP_Divide,       KP_Divide,      XF86Ungrab ]\n    };\n    key <PRSC> {\n        type= \"PC_ALT_LEVEL2\",\n        symbols[Group1]= [           Print,         Sys_Req ]\n    };\n    key <RALT> {\n        type= \"TWO_LEVEL\",\n        symbols[Group1]= [           Alt_R,          Meta_R ]\n    };\n    key <LNFD> {         [        Linefeed ] };\n    key <HOME> {         [            Home ] };\n    key   <UP> {         [              Up ] };\n    key <PGUP> {         [           Prior ] };\n    key <LEFT> {         [            Left ] };\n    key <RGHT> {         [           Right ] };\n    key  <END> {         [             End ] };\n    key <DOWN> {         [            Down ] };\n    key <PGDN> {         [            Next ] };\n    key  <INS> {         [          Insert ] };\n    key <DELE> {         [          Delete ] };\n    key <MUTE> {         [   XF86AudioMute ] };\n    key <VOL-> {         [ XF86AudioLowerVolume ] };\n    key <VOL+> {         [ XF86AudioRaiseVolume ] };\n    key <POWR> {         [    XF86PowerOff ] };\n    key <KPEQ> {         [        KP_Equal ] };\n    key <I126> {         [       plusminus ] };\n    key <PAUS> {\n        type= \"PC_CONTROL_LEVEL2\",\n        symbols[Group1]= [           Pause,           Break ]\n    };\n    key <I128> {         [     XF86LaunchA ] };\n    key <I129> {         [      KP_Decimal,      KP_Decimal ] };\n    key <HNGL> {         [          Hangul ] };\n    key <HJCV> {         [    Hangul_Hanja ] };\n    key <LWIN> {         [         Super_L ] };\n    key <RWIN> {         [         Super_R ] };\n    key <COMP> {         [            Menu ] };\n    key <STOP> {         [          Cancel ] };\n    key <AGAI> {         [            Redo ] };\n    key <PROP> {         [        SunProps ] };\n    key <UNDO> {         [            Undo ] };\n    key <FRNT> {         [        SunFront ] };\n    key <COPY> {         [        XF86Copy ] };\n    key <OPEN> {         [        XF86Open ] };\n    key <PAST> {         [       XF86Paste ] };\n    key <FIND> {         [            Find ] };\n    key  <CUT> {         [         XF86Cut ] };\n    key <HELP> {         [            Help ] };\n    key <I147> {         [      XF86MenuKB ] };\n    key <I148> {         [  XF86Calculator ] };\n    key <I150> {         [       XF86Sleep ] };\n    key <I151> {         [      XF86WakeUp ] };\n    key <I152> {         [    XF86Explorer ] };\n    key <I153> {         [        XF86Send ] };\n    key <I155> {         [        XF86Xfer ] };\n    key <I156> {         [     XF86Launch1 ] };\n    key <I157> {         [     XF86Launch2 ] };\n    key <I158> {         [         XF86WWW ] };\n    key <I159> {         [         XF86DOS ] };\n    key <I160> {         [ XF86ScreenSaver ] };\n    key <I161> {         [ XF86RotateWindows ] };\n    key <I162> {         [    XF86TaskPane ] };\n    key <I163> {         [        XF86Mail ] };\n    key <I164> {         [   XF86Favorites ] };\n    key <I165> {         [  XF86MyComputer ] };\n    key <I166> {         [        XF86Back ] };\n    key <I167> {         [     XF86Forward ] };\n    key <I169> {         [       XF86Eject ] };\n    key <I170> {         [       XF86Eject ] };\n    key <I171> {         [   XF86AudioNext ] };\n    key <I172> {         [   XF86AudioPlay,  XF86AudioPause ] };\n    key <I173> {         [   XF86AudioPrev ] };\n    key <I174> {         [   XF86AudioStop,       XF86Eject ] };\n    key <I175> {         [ XF86AudioRecord ] };\n    key <I176> {         [ XF86AudioRewind ] };\n    key <I177> {         [       XF86Phone ] };\n    key <I179> {         [       XF86Tools ] };\n    key <I180> {         [    XF86HomePage ] };\n    key <I181> {         [      XF86Reload ] };\n    key <I182> {         [       XF86Close ] };\n    key <I185> {         [    XF86ScrollUp ] };\n    key <I186> {         [  XF86ScrollDown ] };\n    key <I187> {         [       parenleft ] };\n    key <I188> {         [      parenright ] };\n    key <I189> {         [         XF86New ] };\n    key <I190> {         [            Redo ] };\n    key <FK13> {         [       XF86Tools ] };\n    key <FK14> {         [     XF86Launch5 ] };\n    key <FK15> {         [     XF86Launch6 ] };\n    key <FK16> {         [     XF86Launch7 ] };\n    key <FK17> {         [     XF86Launch8 ] };\n    key <FK18> {         [     XF86Launch9 ] };\n    key <FK20> {         [ XF86AudioMicMute ] };\n    key <FK21> {         [ XF86TouchpadToggle ] };\n    key <FK22> {         [  XF86TouchpadOn ] };\n    key <FK23> {         [ XF86TouchpadOff ] };\n    key <MDSW> {         [     Mode_switch ] };\n    key  <ALT> {         [        NoSymbol,           Alt_L ] };\n    key <META> {         [        NoSymbol,          Meta_L ] };\n    key <SUPR> {         [        NoSymbol,         Super_L ] };\n    key <HYPR> {         [        NoSymbol,         Hyper_L ] };\n    key <I208> {         [   XF86AudioPlay ] };\n    key <I209> {         [  XF86AudioPause ] };\n    key <I210> {         [     XF86Launch3 ] };\n    key <I211> {         [     XF86Launch4 ] };\n    key <I212> {         [     XF86LaunchB ] };\n    key <I213> {         [     XF86Suspend ] };\n    key <I214> {         [       XF86Close ] };\n    key <I215> {         [   XF86AudioPlay ] };\n    key <I216> {         [ XF86AudioForward ] };\n    key <I218> {         [           Print ] };\n    key <I220> {         [      XF86WebCam ] };\n    key <I221> {         [ XF86AudioPreset ] };\n    key <I223> {         [        XF86Mail ] };\n    key <I224> {         [   XF86Messenger ] };\n    key <I225> {         [      XF86Search ] };\n    key <I226> {         [          XF86Go ] };\n    key <I227> {         [     XF86Finance ] };\n    key <I228> {         [        XF86Game ] };\n    key <I229> {         [        XF86Shop ] };\n    key <I231> {         [          Cancel ] };\n    key <I232> {         [ XF86MonBrightnessDown ] };\n    key <I233> {         [ XF86MonBrightnessUp ] };\n    key <I234> {         [  XF86AudioMedia ] };\n    key <I235> {         [     XF86Display ] };\n    key <I236> {         [ XF86KbdLightOnOff ] };\n    key <I237> {         [ XF86KbdBrightnessDown ] };\n    key <I238> {         [ XF86KbdBrightnessUp ] };\n    key <I239> {         [        XF86Send ] };\n    key <I240> {         [       XF86Reply ] };\n    key <I241> {         [ XF86MailForward ] };\n    key <I242> {         [        XF86Save ] };\n    key <I243> {         [   XF86Documents ] };\n    key <I244> {         [     XF86Battery ] };\n    key <I245> {         [   XF86Bluetooth ] };\n    key <I246> {         [        XF86WLAN ] };\n    key <I247> {         [         XF86UWB ] };\n    key <I249> {         [  XF86Next_VMode ] };\n    key <I250> {         [  XF86Prev_VMode ] };\n    key <I251> {         [ XF86MonBrightnessCycle ] };\n    key <I252> {         [ XF86BrightnessAuto ] };\n    key <I253> {         [  XF86DisplayOff ] };\n    key <I254> {         [        XF86WWAN ] };\n    key <I255> {         [      XF86RFKill ] };\n    modifier_map Control { <LCTL> };\n    modifier_map Shift { <LFSH> };\n    modifier_map Shift { <RTSH> };\n    modifier_map Mod1 { <LALT> };\n    modifier_map Lock { <CAPS> };\n    modifier_map Mod2 { <NMLK> };\n    modifier_map Mod5 { <LVL3> };\n    modifier_map Control { <RCTL> };\n    modifier_map Mod1 { <RALT> };\n    modifier_map Mod4 { <LWIN> };\n    modifier_map Mod4 { <RWIN> };\n    modifier_map Mod5 { <MDSW> };\n    modifier_map Mod1 { <META> };\n    modifier_map Mod4 { <SUPR> };\n    modifier_map Mod4 { <HYPR> };\n};\n\nxkb_geometry \"pc(pc105)\" {\n\n    width=       470;\n    height=      180;\n\n    alias <AC00> = <CAPS>;\n    alias <AA00> = <LCTL>;\n\n    baseColor=   \"white\";\n    labelColor=  \"black\";\n    xfont=       \"-*-helvetica-medium-r-normal--*-120-*-*-*-*-iso8859-1\";\n    description= \"Generic 105-key PC\";\n\n    shape \"NORM\" {\n        corner= 1,\n        { [  18,  18 ] },\n        { [   2,   1 ], [  16,  16 ] }\n    };\n    shape \"BKSP\" {\n        corner= 1,\n        { [  38,  18 ] },\n        { [   2,   1 ], [  36,  16 ] }\n    };\n    shape \"TABK\" {\n        corner= 1,\n        { [  28,  18 ] },\n        { [   2,   1 ], [  26,  16 ] }\n    };\n    shape \"BKSL\" {\n        corner= 1,\n        { [  28,  18 ] },\n        { [   2,   1 ], [  26,  16 ] }\n    };\n    shape \"RTRN\" {\n        corner= 1,\n        { [   0,   0 ], [  28,   0 ], [  28,  37 ], [   5,  37 ],\n          [   5,  18 ], [   0,  18 ] },\n        { [   2,   1 ], [  26,   1 ], [  26,  35 ], [   7,  35 ],\n          [   7,  16 ], [   2,  16 ] },\n        approx= { [   5,   0 ], [  28,  37 ] }\n    };\n    shape \"CAPS\" {\n        corner= 1,\n        { [  33,  18 ] },\n        { [   2,   1 ], [  31,  16 ] }\n    };\n    shape \"LFSH\" {\n        corner= 1,\n        { [  25,  18 ] },\n        { [   2,   1 ], [  23,  16 ] }\n    };\n    shape \"RTSH\" {\n        corner= 1,\n        { [  50,  18 ] },\n        { [   2,   1 ], [  48,  16 ] }\n    };\n    shape \"MODK\" {\n        corner= 1,\n        { [  27,  18 ] },\n        { [   2,   1 ], [  25,  16 ] }\n    };\n    shape \"SMOD\" {\n        corner= 1,\n        { [  23,  18 ] },\n        { [   2,   1 ], [  21,  16 ] }\n    };\n    shape \"SPCE\" {\n        corner= 1,\n        { [ 113,  18 ] },\n        { [   2,   1 ], [ 111,  16 ] }\n    };\n    shape \"KP0\" {\n        corner= 1,\n        { [  37,  18 ] },\n        { [   2,   1 ], [  35,  16 ] }\n    };\n    shape \"KPAD\" {\n        corner= 1,\n        { [  18,  37 ] },\n        { [   2,   1 ], [  16,  35 ] }\n    };\n    shape \"LEDS\" { { [  75,  20 ] } };\n    shape \"LED\" { { [   5,   1 ] } };\n    section \"Function\" {\n        key.color= \"grey20\";\n        priority=  7;\n        top=       22;\n        left=      19;\n        width=     351;\n        height=    19;\n        row {\n            top=  1;\n            left= 1;\n            keys {\n                {  <ESC>, \"NORM\",   1 },\n                { <FK01>, \"NORM\",  20, color=\"white\" },\n                { <FK02>, \"NORM\",   1, color=\"white\" },\n                { <FK03>, \"NORM\",   1, color=\"white\" },\n                { <FK04>, \"NORM\",   1, color=\"white\" },\n                { <FK05>, \"NORM\",  11, color=\"white\" },\n                { <FK06>, \"NORM\",   1, color=\"white\" },\n                { <FK07>, \"NORM\",   1, color=\"white\" },\n                { <FK08>, \"NORM\",   1, color=\"white\" },\n                { <FK09>, \"NORM\",  11, color=\"white\" },\n                { <FK10>, \"NORM\",   1, color=\"white\" },\n                { <FK11>, \"NORM\",   1, color=\"white\" },\n                { <FK12>, \"NORM\",   1, color=\"white\" },\n                { <PRSC>, \"NORM\",   8, color=\"white\" },\n                { <SCLK>, \"NORM\",   1, color=\"white\" },\n                { <PAUS>, \"NORM\",   1, color=\"white\" }\n            };\n        };\n    }; // End of \"Function\" section\n\n    section \"Alpha\" {\n        key.color= \"white\";\n        priority=  8;\n        top=       61;\n        left=      19;\n        width=     287;\n        height=    95;\n        row {\n            top=  1;\n            left= 1;\n            keys {\n                { <TLDE>, \"NORM\",   1 }, { <AE01>, \"NORM\",   1 },\n                { <AE02>, \"NORM\",   1 }, { <AE03>, \"NORM\",   1 },\n                { <AE04>, \"NORM\",   1 }, { <AE05>, \"NORM\",   1 },\n                { <AE06>, \"NORM\",   1 }, { <AE07>, \"NORM\",   1 },\n                { <AE08>, \"NORM\",   1 }, { <AE09>, \"NORM\",   1 },\n                { <AE10>, \"NORM\",   1 }, { <AE11>, \"NORM\",   1 },\n                { <AE12>, \"NORM\",   1 },\n                { <BKSP>, \"BKSP\",   1, color=\"grey20\" }\n            };\n        };\n        row {\n            top=  20;\n            left= 1;\n            keys {\n                {  <TAB>, \"TABK\",   1, color=\"grey20\" },\n                { <AD01>, \"NORM\",   1 }, { <AD02>, \"NORM\",   1 },\n                { <AD03>, \"NORM\",   1 }, { <AD04>, \"NORM\",   1 },\n                { <AD05>, \"NORM\",   1 }, { <AD06>, \"NORM\",   1 },\n                { <AD07>, \"NORM\",   1 }, { <AD08>, \"NORM\",   1 },\n                { <AD09>, \"NORM\",   1 }, { <AD10>, \"NORM\",   1 },\n                { <AD11>, \"NORM\",   1 }, { <AD12>, \"NORM\",   1 },\n                { <RTRN>, \"RTRN\",   1, color=\"grey20\" }\n            };\n        };\n        row {\n            top=  39;\n            left= 1;\n            keys {\n                { <CAPS>, \"CAPS\",   1, color=\"grey20\" },\n                { <AC01>, \"NORM\",   1 }, { <AC02>, \"NORM\",   1 },\n                { <AC03>, \"NORM\",   1 }, { <AC04>, \"NORM\",   1 },\n                { <AC05>, \"NORM\",   1 }, { <AC06>, \"NORM\",   1 },\n                { <AC07>, \"NORM\",   1 }, { <AC08>, \"NORM\",   1 },\n                { <AC09>, \"NORM\",   1 }, { <AC10>, \"NORM\",   1 },\n                { <AC11>, \"NORM\",   1 }, { <BKSL>, \"NORM\",   1 }\n            };\n        };\n        row {\n            top=  58;\n            left= 1;\n            keys {\n                { <LFSH>, \"LFSH\",   1, color=\"grey20\" },\n                { <LSGT>, \"NORM\",   1 }, { <AB01>, \"NORM\",   1 },\n                { <AB02>, \"NORM\",   1 }, { <AB03>, \"NORM\",   1 },\n                { <AB04>, \"NORM\",   1 }, { <AB05>, \"NORM\",   1 },\n                { <AB06>, \"NORM\",   1 }, { <AB07>, \"NORM\",   1 },\n                { <AB08>, \"NORM\",   1 }, { <AB09>, \"NORM\",   1 },\n                { <AB10>, \"NORM\",   1 },\n                { <RTSH>, \"RTSH\",   1, color=\"grey20\" }\n            };\n        };\n        row {\n            top=  77;\n            left= 1;\n            keys {\n                { <LCTL>, \"MODK\",   1, color=\"grey20\" },\n                { <LWIN>, \"SMOD\",   1, color=\"grey20\" },\n                { <LALT>, \"SMOD\",   1, color=\"grey20\" },\n                { <SPCE>, \"SPCE\",   1 },\n                { <RALT>, \"SMOD\",   1, color=\"grey20\" },\n                { <RWIN>, \"SMOD\",   1, color=\"grey20\" },\n                { <MENU>, \"SMOD\",   1, color=\"grey20\" },\n                { <RCTL>, \"SMOD\",   1, color=\"grey20\" }\n            };\n        };\n    }; // End of \"Alpha\" section\n\n    section \"Editing\" {\n        key.color= \"grey20\";\n        priority=  9;\n        top=       61;\n        left=      312;\n        width=     58;\n        height=    95;\n        row {\n            top=  1;\n            left= 1;\n            keys {\n                {  <INS>, \"NORM\",   1 }, { <HOME>, \"NORM\",   1 },\n                { <PGUP>, \"NORM\",   1 }\n            };\n        };\n        row {\n            top=  20;\n            left= 1;\n            keys {\n                { <DELE>, \"NORM\",   1 }, {  <END>, \"NORM\",   1 },\n                { <PGDN>, \"NORM\",   1 }\n            };\n        };\n        row {\n            top=  58;\n            left= 20;\n            keys {\n                {   <UP>, \"NORM\",   1 }\n            };\n        };\n        row {\n            top=  77;\n            left= 1;\n            keys {\n                { <LEFT>, \"NORM\",   1 }, { <DOWN>, \"NORM\",   1 },\n                { <RGHT>, \"NORM\",   1 }\n            };\n        };\n    }; // End of \"Editing\" section\n\n    section \"Keypad\" {\n        key.color= \"grey20\";\n        priority=  10;\n        top=       61;\n        left=      376;\n        width=     77;\n        height=    95;\n        row {\n            top=  1;\n            left= 1;\n            keys {\n                { <NMLK>, \"NORM\",   1 }, { <KPDV>, \"NORM\",   1 },\n                { <KPMU>, \"NORM\",   1 }, { <KPSU>, \"NORM\",   1 }\n            };\n        };\n        row {\n            top=  20;\n            left= 1;\n            keys {\n                {  <KP7>, \"NORM\",   1, color=\"white\" },\n                {  <KP8>, \"NORM\",   1, color=\"white\" },\n                {  <KP9>, \"NORM\",   1, color=\"white\" },\n                { <KPAD>, \"KPAD\",   1 }\n            };\n        };\n        row {\n            top=  39;\n            left= 1;\n            keys {\n                {  <KP4>, \"NORM\",   1, color=\"white\" },\n                {  <KP5>, \"NORM\",   1, color=\"white\" },\n                {  <KP6>, \"NORM\",   1, color=\"white\" }\n            };\n        };\n        row {\n            top=  58;\n            left= 1;\n            keys {\n                {  <KP1>, \"NORM\",   1, color=\"white\" },\n                {  <KP2>, \"NORM\",   1, color=\"white\" },\n                {  <KP3>, \"NORM\",   1, color=\"white\" },\n                { <KPEN>, \"KPAD\",   1 }\n            };\n        };\n        row {\n            top=  77;\n            left= 1;\n            keys {\n                {  <KP0>, \"KP0\",   1, color=\"white\" },\n                { <KPDL>, \"NORM\",   1, color=\"white\" }\n            };\n        };\n    }; // End of \"Keypad\" section\n\n    solid \"LedPanel\" {\n        top=      22;\n        left=     377;\n        priority= 0;\n        color= \"grey10\";\n        shape= \"LEDS\";\n    };\n    indicator \"Num Lock\" {\n        top=      37;\n        left=     382;\n        priority= 1;\n        onColor= \"green\";\n        offColor= \"green30\";\n        shape= \"LED\";\n    };\n    indicator \"Caps Lock\" {\n        top=      37;\n        left=     407;\n        priority= 2;\n        onColor= \"green\";\n        offColor= \"green30\";\n        shape= \"LED\";\n    };\n    indicator \"Scroll Lock\" {\n        top=      37;\n        left=     433;\n        priority= 3;\n        onColor= \"green\";\n        offColor= \"green30\";\n        shape= \"LED\";\n    };\n    text \"NumLockLabel\" {\n        top=      25;\n        left=     378;\n        priority= 4;\n        width=  19.8;\n        height=  10;\n        XFont= \"-*-helvetica-medium-r-normal--*-120-*-*-*-*-iso8859-1\";\n        text=  \"Num\\nLock\";\n    };\n    text \"CapsLockLabel\" {\n        top=      25;\n        left=     403;\n        priority= 5;\n        width=  26.4;\n        height=  10;\n        XFont= \"-*-helvetica-medium-r-normal--*-120-*-*-*-*-iso8859-1\";\n        text=  \"Caps\\nLock\";\n    };\n    text \"ScrollLockLabel\" {\n        top=      25;\n        left=     428;\n        priority= 6;\n        width=  39.6;\n        height=  10;\n        XFont= \"-*-helvetica-medium-r-normal--*-120-*-*-*-*-iso8859-1\";\n        text=  \"Scroll\\nLock\";\n    };\n};\n\n};\n"
  },
  {
    "path": "wayland/types.go",
    "content": "package wayland\n\nimport (\n\t\"github.com/mmulet/term.everything/wayland/protocols\"\n)\n\ntype RoleOrXDGSurfaceObjectID interface {\n\tprotocols.ObjectID[protocols.XdgSurface] |\n\t\tprotocols.ObjectID[protocols.XdgPopup] |\n\t\tprotocols.ObjectID[protocols.WlSubsurface] |\n\t\tprotocols.ObjectID[protocols.XdgToplevel] |\n\t\tprotocols.ObjectID[protocols.XwaylandSurfaceV1]\n}\n\nfunc GetSurfaceFromRole[T RoleOrXDGSurfaceObjectID](cs protocols.ClientState, id T) *WlSurface {\n\treturn cs.GetSurfaceFromRole(protocols.AnyObjectID(id)).(*WlSurface)\n}\n\nfunc GetSurfaceIDFromRole[T RoleOrXDGSurfaceObjectID](cs protocols.ClientState, id T) *protocols.ObjectID[protocols.WlSurface] {\n\tsurfaceID := cs.GetSurfaceIDFromRole(protocols.AnyObjectID(id))\n\tif surfaceID == nil {\n\t\treturn nil\n\t}\n\tsid := protocols.ObjectID[protocols.WlSurface](*surfaceID)\n\treturn &sid\n}\n\nfunc UnregisterRoleToSurface[T RoleOrXDGSurfaceObjectID](cs protocols.ClientState, id T) {\n\tcs.UnregisterRoleToSurface(protocols.AnyObjectID(id))\n}\n\nfunc RegisterRoleToSurface[T RoleOrXDGSurfaceObjectID](cs protocols.ClientState, roleID T, surfaceID protocols.ObjectID[protocols.WlSurface]) {\n\tcs.RegisterRoleToSurface(protocols.AnyObjectID(roleID), surfaceID)\n}\n\nfunc AddObject[T any](cs protocols.ClientState, id protocols.ObjectID[T], v *T) {\n\tcs.AddObject(protocols.AnyObjectID(id), v)\n}\n\nfunc RemoveObject[T any](cs protocols.ClientState, id protocols.ObjectID[T]) {\n\tcs.RemoveObject(protocols.AnyObjectID(id))\n}\n\nfunc SendError[T any, U ~uint32 | ~uint8](cs protocols.ClientState, id protocols.ObjectID[T], code U, message string) {\n\tcs.SendError(protocols.AnyObjectID(id), uint32(code), message)\n}\n\ntype Size struct {\n\tWidth  uint32\n\tHeight uint32\n}\n\nfunc ToBytes[T ~uint8 | ~uint32](a []T) []byte {\n\tb := make([]byte, len(a))\n\tfor i, v := range a {\n\t\tb[i] = byte(v)\n\t}\n\treturn b\n}\n\nfunc AreSame[T comparable](a, b *T) bool {\n\tif a == nil && b == nil {\n\t\treturn true\n\t}\n\tif a == nil || b == nil {\n\t\treturn false\n\t}\n\treturn (*a) == (*b)\n}\n\nfunc GetWlPoolObject_FromBuffer(cs protocols.ClientState, id protocols.ObjectID[protocols.WlBuffer]) *WlShmPool {\n\tv := cs.GetObject(protocols.AnyObjectID(id))\n\tif v == nil {\n\t\treturn nil\n\t}\n\to := v.(protocols.WaylandObject[protocols.WlBuffer_delegate])\n\td := o.GetDelegate()\n\treturn d.(*WlShmPool)\n}\n"
  },
  {
    "path": "wayland/wayland.xml.helper.go",
    "content": "// Code generated by `cmd/protocols`; DO NOT EDIT.\n\npackage wayland\n\nimport \"github.com/mmulet/term.everything/wayland/protocols\"\n\nfunc GetWlSurfaceObject(cs protocols.ClientState, id protocols.ObjectID[protocols.WlSurface]) *WlSurface {\n\tv := cs.GetObject(protocols.AnyObjectID(id))\n\tif v == nil {\n\t\treturn nil\n\t}\n\to := v.(protocols.WaylandObject[protocols.WlSurface_delegate])\n\td := o.GetDelegate()\n\treturn d.(*WlSurface)\n}\n\nfunc GetWlPointerObject(cs protocols.ClientState, id protocols.ObjectID[protocols.WlPointer]) *WlPointer {\n\tv := cs.GetObject(protocols.AnyObjectID(id))\n\tif v == nil {\n\t\treturn nil\n\t}\n\to := v.(protocols.WaylandObject[protocols.WlPointer_delegate])\n\td := o.GetDelegate()\n\treturn d.(*WlPointer)\n}\n\nfunc GetWlSubsurfaceObject(cs protocols.ClientState, id protocols.ObjectID[protocols.WlSubsurface]) *WlSubsurface {\n\tv := cs.GetObject(protocols.AnyObjectID(id))\n\tif v == nil {\n\t\treturn nil\n\t}\n\to := v.(protocols.WaylandObject[protocols.WlSubsurface_delegate])\n\td := o.GetDelegate()\n\treturn d.(*WlSubsurface)\n}\n"
  },
  {
    "path": "wayland/wl_compositor.go",
    "content": "package wayland\n\nimport (\n\t\"github.com/mmulet/term.everything/wayland/protocols\"\n)\n\ntype WlCompositor struct{}\n\nfunc (c *WlCompositor) WlCompositor_create_surface(\n\ts protocols.ClientState,\n\t_ protocols.ObjectID[protocols.WlCompositor],\n\tid protocols.ObjectID[protocols.WlSurface],\n) {\n\tsurface := MakeWlSurface()\n\n\tAddObject(s, id, surface)\n\n\t// // s.bound_compositor_info?.surfaces.set(id, new Surface_Info(surface, 1));\n\t// // console.log(\"create surface\", id);\n\t// /**\n\t//  * @TODO check this code to see if it is needed\n\t//  */\n\t// // s.get_global_binds(Global_Ids.wl_output)?.forEach((output_id) => {\n\t// //   console.log(\"Output enter\", output_id, id);\n\t// //   wl_surface.enter(s, id, output_id);\n\t// // });\n\t//\n\t// // s.get_global_binds(Global_Ids.wl_keyboard)?.forEach((keyboard_id) => {\n\t// //   console.log(\"Keyboard enter\", keyboard_id, id);\n\t// //   wl_keyboard.enter(s, keyboard_id, 0, id, []);\n\t// // });\n\t//\n\t// // s.get_global_binds(Global_Ids.wl_pointer)?.forEach((pointer_id) => {\n\t// //   console.log(\"Pointer enter\", pointer_id, id);\n\t// //   wl_pointer.enter(\n\t// //     s,\n\t// //     pointer_id,\n\t// //     Math.round(Math.random() * 10_000),\n\t// //     id,\n\t// //     0,\n\t// //     0\n\t// //   );\n\t// //   wl_pointer.frame(s, pointer_id);\n\t// // });\n}\n\nfunc (c *WlCompositor) WlCompositor_create_region(\n\ts protocols.ClientState,\n\t_ protocols.ObjectID[protocols.WlCompositor],\n\tid protocols.ObjectID[protocols.WlRegion],\n) {\n\tregion := MakeWlRegion()\n\tAddObject(s, id, region)\n}\n\nfunc (c *WlCompositor) OnBind(\n\ts protocols.ClientState,\n\t_ protocols.AnyObjectID,\n\t_ string,\n\t_ protocols.AnyObjectID,\n\tversion uint32,\n) {\n\ts.SetCompositorVersion(version)\n}\n\nfunc MakeWlCompositor() *protocols.WlCompositor {\n\treturn &protocols.WlCompositor{\n\t\tDelegate: &WlCompositor{},\n\t}\n}\n"
  },
  {
    "path": "wayland/wl_data_device.go",
    "content": "package wayland\n\nimport (\n\t\"github.com/mmulet/term.everything/wayland/protocols\"\n)\n\ntype wl_data_device struct {\n\tSeat protocols.ObjectID[protocols.WlSeat]\n}\n\nfunc (w *wl_data_device) WlDataDevice_start_drag(\n\t_s protocols.ClientState,\n\t_object_id protocols.ObjectID[protocols.WlDataDevice],\n\t_source *protocols.ObjectID[protocols.WlDataSource],\n\t_origin protocols.ObjectID[protocols.WlSurface],\n\t_icon *protocols.ObjectID[protocols.WlSurface],\n\t_serial uint32,\n) {\n\t/** @TODO: Implement wl_data_device_start_drag */\n}\n\nfunc (w *wl_data_device) WlDataDevice_set_selection(\n\t_s protocols.ClientState,\n\t_object_id protocols.ObjectID[protocols.WlDataDevice],\n\t_source *protocols.ObjectID[protocols.WlDataSource],\n\t_serial uint32,\n) {\n\t/** @TODO: Implement wl_data_device_set_selection */\n}\n\nfunc (w *wl_data_device) WlDataDevice_release(\n\t_s protocols.ClientState,\n\t_object_id protocols.ObjectID[protocols.WlDataDevice],\n) bool {\n\treturn true\n}\n\nfunc (w *wl_data_device) WlDataDevice_on_bind(\n\t_s protocols.ClientState,\n\t_name protocols.ObjectID[protocols.WlDataDevice],\n\t_interface_ string,\n\t_new_id protocols.ObjectID[protocols.WlDataDevice],\n\t_version_number uint32,\n) {\n\t/** @TODO: Implement wl_data_device_on_bind */\n}\n\nfunc MakeWlDataDevice(seat protocols.ObjectID[protocols.WlSeat]) *wl_data_device {\n\treturn &wl_data_device{Seat: seat}\n}\n"
  },
  {
    "path": "wayland/wl_data_device_manager.go",
    "content": "package wayland\n\nimport (\n\t\"github.com/mmulet/term.everything/wayland/protocols\"\n)\n\ntype WlDataDeviceManagerImpl struct{}\n\nfunc (w *WlDataDeviceManagerImpl) WlDataDeviceManager_create_data_source(s protocols.ClientState, _object_id protocols.ObjectID[protocols.WlDataDeviceManager], id protocols.ObjectID[protocols.WlDataSource]) {\n\ts.AddObject(protocols.AnyObjectID(id), MakeWlDataSource())\n}\n\nfunc (w *WlDataDeviceManagerImpl) WlDataDeviceManager_get_data_device(s protocols.ClientState, _object_id protocols.ObjectID[protocols.WlDataDeviceManager], id protocols.ObjectID[protocols.WlDataDevice], seat protocols.ObjectID[protocols.WlSeat]) {\n\ts.AddObject(protocols.AnyObjectID(id), MakeWlDataDevice(seat))\n\t/** @TODO: Implement wl_data_device_manager_get_data_device */\n}\n\nfunc (w *WlDataDeviceManagerImpl) OnBind(\n\ts protocols.ClientState,\n\t_ protocols.AnyObjectID,\n\t_ string,\n\t_ protocols.AnyObjectID,\n\tversion uint32,\n) {\n\t/** @TODO: Implement wl_data_device_manager_on_bind */\n}\n\nfunc MakeWlDataDeviceManager() *protocols.WlDataDeviceManager {\n\treturn &protocols.WlDataDeviceManager{\n\t\tDelegate: &WlDataDeviceManagerImpl{},\n\t}\n}\n"
  },
  {
    "path": "wayland/wl_data_source.go",
    "content": "package wayland\n\nimport (\n\t\"github.com/mmulet/term.everything/wayland/protocols\"\n)\n\ntype WlDataSource struct {\n\tMimeTypes []string\n\tActions   protocols.WlDataDeviceManagerDndAction_enum\n}\n\nfunc (w *WlDataSource) WlDataSource_offer(\n\ts protocols.ClientState,\n\tobject_id protocols.ObjectID[protocols.WlDataSource],\n\tmime_type string,\n) {\n\tw.MimeTypes = append(w.MimeTypes, mime_type)\n}\n\nfunc (w *WlDataSource) WlDataSource_destroy(\n\ts protocols.ClientState,\n\tobject_id protocols.ObjectID[protocols.WlDataSource],\n) bool {\n\treturn true\n}\n\nfunc (w *WlDataSource) WlDataSource_set_actions(\n\ts protocols.ClientState,\n\tobject_id protocols.ObjectID[protocols.WlDataSource],\n\tdnd_actions protocols.WlDataDeviceManagerDndAction_enum,\n) {\n\tw.Actions = dnd_actions\n}\n\nfunc (w *WlDataSource) OnBind(\n\ts protocols.ClientState,\n\t_ protocols.AnyObjectID,\n\t_ string,\n\t_ protocols.AnyObjectID,\n\tversion uint32,\n) {\n\t// TODO: Implement wl_data_source_on_bind\n}\n\nfunc MakeWlDataSource() *protocols.WlDataSource {\n\tws := &WlDataSource{\n\t\tMimeTypes: []string{},\n\t\tActions:   protocols.WlDataDeviceManagerDndAction_enum_none,\n\t}\n\treturn &protocols.WlDataSource{\n\t\tDelegate: ws,\n\t}\n}\n"
  },
  {
    "path": "wayland/wl_display.go",
    "content": "package wayland\n\nimport \"github.com/mmulet/term.everything/wayland/protocols\"\n\ntype wl_display struct{}\n\nfunc (wd *wl_display) WlDisplay_sync(s protocols.ClientState, _object_id protocols.ObjectID[protocols.WlDisplay], callback protocols.ObjectID[protocols.WlCallback]) {\n\tprotocols.WlCallback_done(s, callback, 0)\n}\n\nfunc (wd *wl_display) WlDisplay_get_registry(s protocols.ClientState, _object_id protocols.ObjectID[protocols.WlDisplay], registry protocols.ObjectID[protocols.WlRegistry]) {\n\tregistry_object := MakeWlRegistry()\n\tAddObject(s, registry, registry_object)\n\tfor _, global := range protocols.AdvertisedGlobalObjectNames {\n\t\tprotocols.WlRegistry_global(s, registry, uint32(global.Id), global.Name, global.Version)\n\t}\n}\n\nfunc (wd *wl_display) OnBind(\n\ts protocols.ClientState,\n\t_ protocols.AnyObjectID,\n\t_ string,\n\t_ protocols.AnyObjectID,\n\tversion uint32,\n) {\n}\n\nfunc MakeWLDisplay() *protocols.WlDisplay {\n\treturn &protocols.WlDisplay{\n\t\tDelegate: &wl_display{},\n\t}\n}\n"
  },
  {
    "path": "wayland/wl_keyboard.go",
    "content": "package wayland\n\nimport (\n\t_ \"embed\"\n\t\"os\"\n\n\t\"github.com/mmulet/term.everything/wayland/protocols\"\n)\n\n//go:embed resources/server-1.xkb\nvar xkbKeymapData []byte\n\ntype WlKeyboard struct {\n\tKey_map_fd   protocols.FileDescriptor\n\tKey_map_size uint32\n\t// let's prevent the garbage collector from closing the file descriptor\n\tFile *os.File\n}\n\nfunc (o *WlKeyboard) WlKeyboard_release(s protocols.ClientState, _ protocols.ObjectID[protocols.WlKeyboard]) bool {\n\treturn true\n}\nfunc (o *WlKeyboard) OnBind(\n\ts protocols.ClientState,\n\t_ protocols.AnyObjectID,\n\t_ string,\n\t_ protocols.AnyObjectID,\n\tversion uint32,\n) {\n}\n\nfunc (o *WlKeyboard) AfterGetKeyboard(\n\ts protocols.ClientState,\n\tobject_id protocols.ObjectID[protocols.WlKeyboard],\n) {\n\tprotocols.WlKeyboard_keymap(\n\t\ts,\n\t\tobject_id,\n\t\tprotocols.WlKeyboardKeymapFormat_enum_xkb_v1,\n\t\to.Key_map_fd,\n\t\to.Key_map_size,\n\t)\n}\n\nfunc MakeWlKeyboard() *protocols.WlKeyboard {\n\n\tf, err := os.CreateTemp(os.TempDir(), \"xkb-keymap-*.xkb\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tif _, werr := f.Write(xkbKeymapData); werr != nil {\n\t\tf.Close()\n\t\tpanic(werr)\n\t}\n\tif _, serr := f.Seek(0, 0); serr != nil {\n\t\tf.Close()\n\t\tpanic(serr)\n\t}\n\treturn &protocols.WlKeyboard{\n\t\tDelegate: &WlKeyboard{\n\t\t\tKey_map_fd:   protocols.FileDescriptor(f.Fd()),\n\t\t\tKey_map_size: uint32(len(xkbKeymapData)),\n\t\t\tFile:         f,\n\t\t},\n\t}\n\n}\n"
  },
  {
    "path": "wayland/wl_output.go",
    "content": "package wayland\n\nimport (\n\t\"github.com/mmulet/term.everything/wayland/protocols\"\n)\n\ntype WlOutput struct {\n\tVersion uint32\n}\n\nfunc (o *WlOutput) WlOutput_release(s protocols.ClientState, _ protocols.ObjectID[protocols.WlOutput]) bool {\n\treturn true\n}\n\nfunc (o *WlOutput) OnBind(\n\ts protocols.ClientState,\n\t_ protocols.AnyObjectID,\n\t_ string,\n\tnewId_any protocols.AnyObjectID,\n\tversion uint32,\n) {\n\tnewID := protocols.ObjectID[protocols.WlOutput](newId_any)\n\to.Version = version\n\n\tprotocols.WlOutput_scale(s, o.Version, newID, 1)\n\n\tprotocols.WlOutput_name(s, o.Version, newID, \"term.everything Virtual Monitor\")\n\tprotocols.WlOutput_description(s, o.Version, newID, \"The best monitor\")\n\n\tprotocols.WlOutput_geometry(\n\t\ts,\n\t\tnewID,\n\t\t0,\n\t\t0,\n\t\tint32(VirtualMonitorSize.Width),\n\t\tint32(VirtualMonitorSize.Height),\n\t\tint32(protocols.WlOutputSubpixel_enum_unknown),\n\t\t\"Very Good\",\n\t\t\"The best model\",\n\t\tint32(protocols.WlOutputTransform_enum_normal),\n\t)\n\n\tprotocols.WlOutput_mode(\n\t\ts,\n\t\tnewID,\n\t\tprotocols.WlOutputMode_enum_current,\n\t\tint32(VirtualMonitorSize.Width),\n\t\tint32(VirtualMonitorSize.Height),\n\t\t60_000,\n\t)\n\n\tprotocols.WlOutput_done(s, version, newID)\n}\n\nfunc MakeWlOutput() *protocols.WlOutput {\n\treturn &protocols.WlOutput{\n\t\tDelegate: &WlOutput{\n\t\t\tVersion: 1,\n\t\t},\n\t}\n}\n"
  },
  {
    "path": "wayland/wl_pointer.go",
    "content": "package wayland\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/mmulet/term.everything/wayland/protocols\"\n)\n\ntype WlPointer struct {\n\t// Last cursor surface set via set_cursor\n\tPointerSurfaceID map[protocols.ClientState]*protocols.ObjectID[protocols.WlSurface]\n\n\tWindowX float32\n\tWindowY float32\n}\n\nfunc (p *WlPointer) WlPointer_set_cursor(\n\ts protocols.ClientState,\n\tobject_id protocols.ObjectID[protocols.WlPointer],\n\t_ uint32, // serial - TODO: validate most recent serial if/when tracked\n\tsurface_id *protocols.ObjectID[protocols.WlSurface],\n\thotspot_x int32,\n\thotspot_y int32,\n) {\n\t/**\n\t * @TODO look at the serial and see it if valid (you are only supposed\n\t * to respond to the most recent serial)\n\t */\n\t// if (serial <= this.last_pointer_enter_serial) {\n\t//   console.error(\"Ignoring set cursor for stale serial\");\n\t//   return;\n\t// }\n\n\tpointerSurfaceID, ok := p.PointerSurfaceID[s]\n\tif ok && !AreSame(pointerSurfaceID, surface_id) {\n\t\tif oldPointerSurface := GetWlSurfaceObject(s, *pointerSurfaceID); oldPointerSurface != nil {\n\t\t\toldPointerSurface.Texture = nil\n\t\t\tif oldPointerSurface.Role != nil {\n\t\t\t\tif _, isCursor := oldPointerSurface.Role.(*SurfaceRoleCursor); isCursor {\n\t\t\t\t\toldPointerSurface.Role = nil\n\t\t\t\t}\n\n\t\t\t}\n\t\t}\n\t}\n\n\tp.PointerSurfaceID[s] = surface_id\n\n\tif surface_id == nil {\n\t\treturn\n\t}\n\n\tsurface := GetWlSurfaceObject(s, *surface_id)\n\tif surface == nil {\n\t\tfmt.Printf(\"Surface not found\")\n\t\treturn\n\t}\n\n\t_, isCursor := surface.Role.(*SurfaceRoleCursor)\n\tif surface.Role != nil && !isCursor {\n\t\tSendError(s,\n\t\t\tobject_id,\n\t\t\tprotocols.WlPointerError_enum_role,\n\t\t\t\"Surface already has a role\")\n\t\tfmt.Printf(\"Surface already has a role\")\n\t\treturn\n\t}\n\n\tsurface.Role = &SurfaceRoleCursor{\n\t\tData: &SurfaceRoleCursorData{\n\t\t\tHotspot: CursorHotspot{\n\t\t\t\tX: hotspot_x,\n\t\t\t\tY: hotspot_y,\n\t\t\t},\n\t\t},\n\t}\n\n}\n\nfunc (p *WlPointer) AfterGetPointer(_ protocols.ClientState, _ protocols.ObjectID[protocols.WlPointer]) {\n\t/** @TODO: Implement wl_pointer_set_cursor */\n\t/**\n\t * @TODO probably pointer.enter\n\t */\n\t// this.last_pointer_enter_serial += 1;\n}\n\nfunc (p *WlPointer) WlPointer_release(\n\t_ protocols.ClientState,\n\t_ protocols.ObjectID[protocols.WlPointer],\n) bool {\n\treturn true\n}\n\nfunc (p *WlPointer) OnBind(\n\ts protocols.ClientState,\n\t_ protocols.AnyObjectID,\n\t_ string,\n\tnewId_any protocols.AnyObjectID,\n\tversion uint32,\n) {\n\t// No-op for now\n}\n\nfunc MakeWlPointer() *protocols.WlPointer {\n\treturn &protocols.WlPointer{\n\t\tDelegate: &Pointer,\n\t}\n}\n\nvar Pointer = WlPointer{\n\tPointerSurfaceID: make(map[protocols.ClientState]*protocols.ObjectID[protocols.WlSurface]),\n}\n"
  },
  {
    "path": "wayland/wl_region.go",
    "content": "package wayland\n\nimport (\n\t\"github.com/mmulet/term.everything/wayland/protocols\"\n)\n\nfunc auto_release(s protocols.ClientState,\n\tid protocols.ObjectID[protocols.WlRegion]) bool {\n\treturn true\n}\n\ntype WlRegion struct {\n}\n\nfunc (r *WlRegion) WlRegion_destroy(\n\ts protocols.ClientState,\n\tid protocols.ObjectID[protocols.WlRegion],\n) bool {\n\treturn true\n}\n\nfunc (r *WlRegion) WlRegion_add(\n\t_ protocols.ClientState,\n\t_ protocols.ObjectID[protocols.WlRegion],\n\tx int32,\n\ty int32,\n\twidth int32,\n\theight int32,\n) {\n\t// TODO: Implement proper region union semantics.\n}\n\nfunc (r *WlRegion) WlRegion_subtract(\n\t_ protocols.ClientState,\n\t_ protocols.ObjectID[protocols.WlRegion],\n\t_x int32,\n\t_y int32,\n\t_width int32,\n\t_height int32,\n) {\n\t// TODO: Implement proper region subtraction semantics.\n}\n\nfunc (r *WlRegion) OnBind(\n\ts protocols.ClientState,\n\t_ protocols.AnyObjectID,\n\t_ string,\n\tnewId_any protocols.AnyObjectID,\n\tversion uint32,\n) {\n\t// No-op for wl_region\n}\n\nfunc MakeWlRegion() *protocols.WlRegion {\n\treturn &protocols.WlRegion{\n\t\tDelegate: &WlRegion{},\n\t}\n}\n"
  },
  {
    "path": "wayland/wl_registry.go",
    "content": "package wayland\n\nimport (\n\t\"github.com/mmulet/term.everything/wayland/protocols\"\n)\n\ntype WlRegistryDelegateImpl struct{}\n\nfunc (w *WlRegistryDelegateImpl) WlRegistry_bind(s protocols.ClientState, object_id protocols.ObjectID[protocols.WlRegistry], name uint32, idInterface string, idVersion uint32, idID protocols.AnyObjectID) {\n\tobject := s.GetObject(protocols.AnyObjectID(name))\n\ts.AddObject(idID, object)\n\tversion := protocols.Version(idVersion)\n\n\tswitch name {\n\tcase uint32(protocols.GlobalID_WlShm):\n\t\ts.AddGlobalWlShmBind(protocols.ObjectID[protocols.WlShm](idID), version)\n\tcase uint32(protocols.GlobalID_WlSeat):\n\t\ts.AddGlobalWlSeatBind(protocols.ObjectID[protocols.WlSeat](idID), version)\n\tcase uint32(protocols.GlobalID_WlOutput):\n\t\ts.AddGlobalWlOutputBind(protocols.ObjectID[protocols.WlOutput](idID), version)\n\tcase uint32(protocols.GlobalID_WlKeyboard):\n\t\ts.AddGlobalWlKeyboardBind(protocols.ObjectID[protocols.WlKeyboard](idID), version)\n\tcase uint32(protocols.GlobalID_WlPointer):\n\t\ts.AddGlobalWlPointerBind(protocols.ObjectID[protocols.WlPointer](idID), version)\n\tcase uint32(protocols.GlobalID_WlTouch):\n\t\ts.AddGlobalWlTouchBind(protocols.ObjectID[protocols.WlTouch](idID), version)\n\tcase uint32(protocols.GlobalID_WlDataDevice):\n\t\ts.AddGlobalWlDataDeviceBind(protocols.ObjectID[protocols.WlDataDevice](idID), version)\n\tcase uint32(protocols.GlobalID_ZwpXwaylandKeyboardGrabManagerV1):\n\t\ts.AddGlobalZwpXwaylandKeyboardGrabManagerV1Bind(protocols.ObjectID[protocols.ZwpXwaylandKeyboardGrabManagerV1](idID), version)\n\t\t// const set = s.global_binds.get(name) ?? new Set();\n\t\t// set.add(id_id);\n\t\t// s.global_binds.set(name, set);\n\t}\n\t// TODO turn this back on\n\t//  if (wayland_debug_time_only()) {\n\t//     console.log(\n\t//       `client#${s.client_socket} ${id_interface}_on_bind(name:`,\n\t//       name,\n\t//       \",interface:\",\n\t//       id_interface,\n\t//       \",id:\",\n\t//       id_id,\n\t//       \",version:\",\n\t//       id_version,\n\t//       `)`\n\t//     );\n\t//   }\n\n\tif object != nil {\n\n\t\t// delegate := object.(protocols.WaylandObject[protocols.OnBindable]).GetDelegate()\n\n\t\tdelegate := object.(protocols.HasBindable).GetBindable()\n\t\tdelegate.OnBind(\n\t\t\ts,\n\t\t\tprotocols.AnyObjectID(name),\n\t\t\tidInterface,\n\t\t\tidID,\n\t\t\tidVersion,\n\t\t)\n\t}\n}\n\nfunc (w *WlRegistryDelegateImpl) OnBind(\n\ts protocols.ClientState,\n\t_ protocols.AnyObjectID,\n\t_ string,\n\tnewId_any protocols.AnyObjectID,\n\tversion uint32,\n) {\n}\n\nfunc MakeWlRegistry() *protocols.WlRegistry {\n\treturn &protocols.WlRegistry{\n\t\tDelegate: &WlRegistryDelegateImpl{},\n\t}\n}\n"
  },
  {
    "path": "wayland/wl_seat.go",
    "content": "package wayland\n\nimport (\n\t\"github.com/mmulet/term.everything/wayland/protocols\"\n)\n\ntype WlSeat struct {\n\tVersion uint32\n}\n\nfunc (w *WlSeat) WlSeat_get_pointer(\n\ts protocols.ClientState,\n\t_ protocols.ObjectID[protocols.WlSeat],\n\tid protocols.ObjectID[protocols.WlPointer],\n) {\n\ts.AddGlobalWlPointerBind(id, protocols.Version(w.Version))\n\tAddObject(s, id, Global_WlPointer)\n}\n\nfunc (w *WlSeat) WlSeat_get_keyboard(\n\ts protocols.ClientState,\n\t_ protocols.ObjectID[protocols.WlSeat],\n\tid protocols.ObjectID[protocols.WlKeyboard],\n) {\n\ts.AddGlobalWlKeyboardBind(id, protocols.Version(w.Version))\n\tAddObject(s, id, Global_WlKeyboard)\n\tGlobal_WlKeyboard.Delegate.AfterGetKeyboard(s, id)\n}\n\nfunc (w *WlSeat) WlSeat_get_touch(\n\ts protocols.ClientState,\n\tobject_id protocols.ObjectID[protocols.WlSeat],\n\t_ protocols.ObjectID[protocols.WlTouch],\n) {\n\tSendError(s, object_id, protocols.WlSeatError_enum_missing_capability, \"no touch\")\n}\n\nfunc (w *WlSeat) WlSeat_release(\n\t_ protocols.ClientState,\n\t_ protocols.ObjectID[protocols.WlSeat],\n) bool {\n\treturn true\n}\n\nfunc (w *WlSeat) OnBind(\n\ts protocols.ClientState,\n\t_ protocols.AnyObjectID,\n\t_ string,\n\tnewIdAny protocols.AnyObjectID,\n\tversion uint32,\n) {\n\tw.Version = version\n\tnewID := protocols.ObjectID[protocols.WlSeat](newIdAny)\n\n\t// w.capabilities(s, new_id, wl_seat_capability.pointer | wl_seat_capability.keyboard);\n\tprotocols.WlSeat_capabilities(\n\t\ts,\n\t\tnewID,\n\t\tprotocols.WlSeatCapability_enum_pointer|protocols.WlSeatCapability_enum_keyboard,\n\t)\n\tprotocols.WlSeat_name(s, version, newID, \"seat0\")\n}\n\nfunc MakeWLSeat() *protocols.WlSeat {\n\treturn &protocols.WlSeat{\n\t\tDelegate: &WlSeat{\n\t\t\tVersion: 1,\n\t\t},\n\t}\n}\n"
  },
  {
    "path": "wayland/wl_shm.go",
    "content": "package wayland\n\nimport (\n\t\"github.com/mmulet/term.everything/wayland/protocols\"\n)\n\ntype WlShm struct{}\n\nfunc (s *WlShm) WlShm_create_pool(\n\tcs protocols.ClientState,\n\t_objectID protocols.ObjectID[protocols.WlShm],\n\tid protocols.ObjectID[protocols.WlShmPool],\n\tfd *protocols.FileDescriptor,\n\tsize int32,\n) {\n\tAddObject(cs, id, MakeWlShmPool(cs, id, *fd, size))\n}\n\n/**\n * Here's what this does according to the docs:\n * Using this request a client can tell the server that it is not going to use the shm object anymore.\n *   Objects created via this interface remain unaffected.\n *\n * So I guess remove the object from the client, but leave all pools alone?\n * @param s\n * @param _object_id\n */\nfunc (s *WlShm) WlShm_release(\n\t_cs protocols.ClientState,\n\t_objectID protocols.ObjectID[protocols.WlShm],\n) bool {\n\treturn true\n}\n\nfunc (s *WlShm) OnBind(\n\tcs protocols.ClientState,\n\t_ protocols.AnyObjectID,\n\t_ string,\n\tnewId_any protocols.AnyObjectID,\n\tversion uint32,\n) {\n\n\t// WlShm_on_bind(\n\t// \tcs protocols.ClientState,\n\t// \t_name protocols.ObjectID[protocols.WlShm],\n\t// \t_interface_ string,\n\t// \tnewID protocols.ObjectID[protocols.WlShm],\n\t// \t_version uint32,\n\t// ) {\n\tnewID := protocols.ObjectID[protocols.WlShm](newId_any)\n\n\tprotocols.WlShm_format(cs, newID, protocols.WlShmFormat_enum_argb8888)\n}\n\n// Helper to construct a protocol object with this delegate (like static make() in TS)\nfunc MakeWlShm() *protocols.WlShm {\n\treturn &protocols.WlShm{Delegate: &WlShm{}}\n}\n"
  },
  {
    "path": "wayland/wl_shm_pool.go",
    "content": "package wayland\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/mmulet/term.everything/wayland/protocols\"\n)\n\ntype MapState int\n\nconst (\n\tMapStateDestroyed MapState = iota\n\tMapStateMmapped\n\tMapStateDestroyWhenBuffersEmpty\n)\n\ntype BufferInfo struct {\n\tOffset int32\n\tWidth  int32\n\tHeight int32\n\tStride int32\n\tFormat protocols.WlShmFormat_enum\n}\n\ntype WlShmPool struct {\n\tMapState          MapState\n\tBuffers           map[protocols.ObjectID[protocols.WlBuffer]]BufferInfo\n\tMemMaps           map[protocols.ObjectID[protocols.WlShmPool]]MemMapInfo\n\tWlShmPoolObjectID protocols.ObjectID[protocols.WlShmPool]\n}\n\nfunc (p *WlShmPool) WlShmPool_create_buffer(\n\ts protocols.ClientState,\n\t_objectID protocols.ObjectID[protocols.WlShmPool],\n\tid protocols.ObjectID[protocols.WlBuffer],\n\toffset int32,\n\twidth int32,\n\theight int32,\n\tstride int32,\n\tformat protocols.WlShmFormat_enum,\n) {\n\tbuf := &protocols.WlBuffer{\n\t\tDelegate: p,\n\t}\n\tAddObject(s, id, buf)\n\tp.Buffers[id] = BufferInfo{\n\t\tOffset: offset,\n\t\tWidth:  width,\n\t\tHeight: height,\n\t\tStride: stride,\n\t\tFormat: format,\n\t}\n}\n\nfunc (p *WlShmPool) OnDestroyShmPool(s protocols.ClientState, objectID protocols.ObjectID[protocols.WlShmPool]) {\n\tif memap, ok := p.MemMaps[objectID]; ok {\n\t\tmemap.Unmap()\n\t}\n\tp.MapState = MapStateDestroyed\n\tRemoveObject(s, objectID)\n}\n\n/**\n * This can be called by either on the buffer delegate or the pool delegate\n * @param s\n * @param _object_id Check This!! to see if it is the buffer id or the pool id\n * @returns false because wl_shm_pool hndles remove objet by itself\n */\nfunc (p *WlShmPool) WlShmPool_destroy(\n\ts protocols.ClientState,\n\tobjectID protocols.ObjectID[protocols.WlShmPool],\n) bool {\n\tbuffersEmpty := len(p.Buffers) <= 0\n\tswitch p.MapState {\n\tcase MapStateDestroyed, MapStateDestroyWhenBuffersEmpty:\n\t\treturn false\n\tcase MapStateMmapped:\n\t\tif buffersEmpty {\n\t\t\tp.OnDestroyShmPool(s, objectID)\n\t\t\treturn false\n\t\t}\n\t\tp.MapState = MapStateDestroyWhenBuffersEmpty\n\t\treturn false\n\tdefault:\n\t\tpanic(\"unexpected MapState\")\n\t}\n}\n\nfunc (p *WlShmPool) WlShmPool_resize(\n\ts protocols.ClientState,\n\tobjectID protocols.ObjectID[protocols.WlShmPool],\n\tsize int32,\n) {\n\tswitch p.MapState {\n\tcase MapStateDestroyed:\n\t\treturn\n\tcase MapStateMmapped, MapStateDestroyWhenBuffersEmpty:\n\t\tif old, ok := p.MemMaps[objectID]; ok {\n\n\t\t\tnewMap, err := NewMemMapInfo(int(old.FileDescriptor), uint64(size))\n\t\t\tif err != nil {\n\t\t\t\tfmt.Printf(\"Failed to remap mmap for pool %d: %v\\n\", objectID, err)\n\t\t\t\tp.MapState = MapStateDestroyed\n\t\t\t\treturn\n\t\t\t}\n\t\t\told.Unmap()\n\t\t\tp.MemMaps[objectID] = newMap\n\n\t\t\t// err := memap.Remap(uint64(size))\n\t\t\t// if err != nil {\n\t\t\t// \tfmt.Printf(\"Failed to remap mmap for pool %d: %v\\n\", _objectID, err)\n\t\t\t// \tp.MapState = MapStateDestroyed\n\t\t\t// \treturn\n\t\t\t// }\n\t\t\t// return\n\t\t}\n\t\treturn\n\tdefault:\n\t\tpanic(\"unexpected MapState\")\n\t}\n}\n\n/**\n * This can be called by either on the buffer delegate or the pool delegate\n * check the name and compare to object id\n * @param _s\n * @param _name\n * @param new_id\n * @param version\n */\nfunc (p *WlShmPool) WlShmPool_on_bind(\n\t_s protocols.ClientState,\n\t_name protocols.ObjectID[protocols.WlShmPool],\n\t_interface_ string,\n\tnewID protocols.ObjectID[protocols.WlShmPool],\n\tversion uint32,\n) {\n\tfmt.Printf(\"wl_shm_pool on_bind called with new_id: %d, version#: %d\\n\", newID, version)\n}\n\nfunc MakeWlShmPool(\n\tclient protocols.ClientState, // Assuming ClientState is the client\n\twlShmPoolObjectID protocols.ObjectID[protocols.WlShmPool],\n\tfd protocols.FileDescriptor,\n\tsize int32,\n) *protocols.WlShmPool {\n\n\tpool := &WlShmPool{\n\t\tMapState:          MapStateDestroyed,\n\t\tBuffers:           make(map[protocols.ObjectID[protocols.WlBuffer]]BufferInfo),\n\t\tMemMaps:           make(map[protocols.ObjectID[protocols.WlShmPool]]MemMapInfo),\n\t\tWlShmPoolObjectID: wlShmPoolObjectID,\n\t}\n\n\tmemMap, err := NewMemMapInfo(int(fd), uint64(size))\n\tif err != nil {\n\t\tfmt.Printf(\"Failed to create memmap for pool %d: %v\\n\", wlShmPoolObjectID, err)\n\t\treturn &protocols.WlShmPool{Delegate: pool}\n\t}\n\tpool.MapState = MapStateMmapped\n\tpool.MemMaps[wlShmPoolObjectID] = memMap\n\treturn &protocols.WlShmPool{Delegate: pool}\n}\n\nfunc (p *WlShmPool) OnBind(\n\ts protocols.ClientState,\n\t_ protocols.AnyObjectID,\n\t_ string,\n\tnewId_any protocols.AnyObjectID,\n\tversion uint32,\n) {\n\t// No-op\n}\n\nfunc (p *WlShmPool) WlBuffer_destroy(\n\ts protocols.ClientState,\n\tbufferObjectID protocols.ObjectID[protocols.WlBuffer],\n) bool {\n\tif _, exists := p.Buffers[bufferObjectID]; !exists {\n\t\tfmt.Printf(\"destroying a buffer that does not exist!, wl_shm_pool_id: %d, buffer_id: %d\\n\", p.WlShmPoolObjectID, bufferObjectID)\n\t\treturn true\n\t}\n\tdelete(p.Buffers, bufferObjectID)\n\tswitch p.MapState {\n\tcase MapStateDestroyed, MapStateMmapped:\n\t\treturn true\n\tcase MapStateDestroyWhenBuffersEmpty:\n\t\tif len(p.Buffers) > 0 {\n\t\t\treturn true\n\t\t}\n\t\tp.OnDestroyShmPool(s, p.WlShmPoolObjectID)\n\t\treturn true\n\tdefault:\n\t\tpanic(\"unexpected MapState\")\n\t}\n}\n"
  },
  {
    "path": "wayland/wl_subcompositor.go",
    "content": "package wayland\n\nimport (\n\t\"github.com/mmulet/term.everything/wayland/protocols\"\n)\n\ntype WlSubcompositor struct{}\n\nfunc (sc *WlSubcompositor) WlSubcompositor_destroy(\n\t_ protocols.ClientState,\n\t_ protocols.ObjectID[protocols.WlSubcompositor],\n) bool {\n\treturn true\n}\n\nfunc (sc *WlSubcompositor) WlSubcompositor_get_subsurface(\n\ts protocols.ClientState,\n\tobject_id protocols.ObjectID[protocols.WlSubcompositor],\n\tid protocols.ObjectID[protocols.WlSubsurface],\n\tsurface_id protocols.ObjectID[protocols.WlSurface],\n\tparent_surface_id protocols.ObjectID[protocols.WlSurface],\n) {\n\n\tsurface := GetWlSurfaceObject(s, surface_id)\n\tif surface == nil {\n\t\tSendError(\n\t\t\ts,\n\t\t\tobject_id,\n\t\t\tprotocols.WlSubcompositorError_enum_bad_surface,\n\t\t\t\"surface not found\",\n\t\t)\n\t\treturn\n\t}\n\n\tif surface.Role == nil {\n\t\tsurface.Role = &SurfaceRoleSubSurface{Data: nil}\n\t}\n\n\troleSub, ok := surface.Role.(*SurfaceRoleSubSurface)\n\tif !ok {\n\t\tSendError(\n\t\t\ts,\n\t\t\tobject_id,\n\t\t\tprotocols.WlSubcompositorError_enum_bad_surface,\n\t\t\t\"surface has different role instead of sub_surface\",\n\t\t)\n\t\treturn\n\t}\n\n\tif roleSub.HasData() {\n\t\tSendError(\n\t\t\ts,\n\t\t\tobject_id,\n\t\t\tprotocols.WlSubcompositorError_enum_bad_surface,\n\t\t\t\"surface already is a subsurface\",\n\t\t)\n\t\treturn\n\t}\n\n\tif surface_id == parent_surface_id {\n\t\tSendError(\n\t\t\ts,\n\t\t\tobject_id,\n\t\t\tprotocols.WlSubcompositorError_enum_bad_parent,\n\t\t\t\"parent == surface\",\n\t\t)\n\t\treturn\n\t}\n\n\tif s.FindDescendantSurface(surface_id, parent_surface_id) {\n\t\tSendError(\n\t\t\ts,\n\t\t\tobject_id,\n\t\t\tprotocols.WlSubcompositorError_enum_bad_parent,\n\t\t\t\"parent is a descendant of surface\",\n\t\t)\n\t\treturn\n\t}\n\n\tparent_surface := GetWlSurfaceObject(s, parent_surface_id)\n\tif parent_surface == nil {\n\t\tSendError(\n\t\t\ts,\n\t\t\tobject_id,\n\t\t\tprotocols.WlSubcompositorError_enum_bad_parent,\n\t\t\t\"parent not found\",\n\t\t)\n\t\treturn\n\t}\n\n\troleSub.Data = &id\n\tif parent_surface.PendingUpdate.AddSubSurface == nil {\n\t\tparent_surface.PendingUpdate.AddSubSurface = []protocols.ObjectID[protocols.WlSurface]{}\n\t}\n\tparent_surface.PendingUpdate.AddSubSurface = append(\n\t\tparent_surface.PendingUpdate.AddSubSurface,\n\t\tsurface_id,\n\t)\n\n\tRegisterRoleToSurface(s, id, surface_id)\n\tAddObject(s, id, MakeWlSubsurface(parent_surface_id))\n}\n\nfunc (sc *WlSubcompositor) OnBind(\n\t_ protocols.ClientState,\n\t_ protocols.AnyObjectID,\n\t_ string,\n\t_ protocols.AnyObjectID,\n\t_ uint32,\n) {\n}\n\nfunc MakeWlSubcompositor() *protocols.WlSubcompositor {\n\treturn &protocols.WlSubcompositor{\n\t\tDelegate: &WlSubcompositor{},\n\t}\n}\n"
  },
  {
    "path": "wayland/wl_subsurface.go",
    "content": "package wayland\n\nimport (\n\t\"github.com/mmulet/term.everything/wayland/pointerslices\"\n\t\"github.com/mmulet/term.everything/wayland/protocols\"\n)\n\ntype WlSubsurface struct {\n\tParent   protocols.ObjectID[protocols.WlSurface]\n\tSync     bool\n\tPosition Point\n}\n\n/**\n * wl_subsurface methods\n */\n\nfunc (ss *WlSubsurface) WlSubsurface_destroy(\n\ts protocols.ClientState,\n\tobject_id protocols.ObjectID[protocols.WlSubsurface],\n) bool {\n\t/**\n\t * Delete the association between the role object and the surface\n\t */\n\tsurfaceID := GetSurfaceIDFromRole(s, object_id)\n\n\tUnregisterRoleToSurface(s, object_id)\n\n\tif surfaceID == nil {\n\t\treturn true\n\t}\n\n\tsurface := GetWlSurfaceObject(s, *surfaceID)\n\tif surface == nil {\n\t\treturn true\n\t}\n\n\tif !surface.HasRoleData() {\n\t\treturn true\n\t}\n\n\t_, isSubSurface := surface.Role.(*SurfaceRoleSubSurface)\n\tif !isSubSurface {\n\t\treturn true\n\t}\n\n\tparent_surface := GetWlSurfaceObject(s, ss.Parent)\n\tif parent_surface != nil {\n\t\tparent_surface.ChildrenInDrawOrder = pointerslices.DeleteFunc(parent_surface.ChildrenInDrawOrder, func(id protocols.ObjectID[protocols.WlSurface]) bool {\n\t\t\treturn id == *surfaceID\n\t\t})\n\t}\n\tsurface.ClearRoleData()\n\treturn true\n}\n\nfunc (ss *WlSubsurface) WlSubsurface_set_position(\n\ts protocols.ClientState,\n\tobject_id protocols.ObjectID[protocols.WlSubsurface],\n\tx int32,\n\ty int32,\n) {\n\tsurfaceID := GetSurfaceIDFromRole(s, object_id)\n\tif surfaceID == nil {\n\t\tSendError(s, object_id, protocols.WlSubsurfaceError_enum_bad_surface, \"surface not found\")\n\t\treturn\n\t}\n\n\tparent := GetWlSurfaceObject(s, ss.Parent)\n\tif parent == nil {\n\t\tSendError(s, object_id, protocols.WlSubsurfaceError_enum_bad_surface, \"parent not found\")\n\t\treturn\n\t}\n\tif (*parent).PendingUpdate.SetChildPosition == nil {\n\t\t(*parent).PendingUpdate.SetChildPosition = []ChildPosition{}\n\t}\n\n\t(*parent).PendingUpdate.SetChildPosition = append(\n\t\t(*parent).PendingUpdate.SetChildPosition,\n\t\tChildPosition{\n\t\t\tChild: *surfaceID,\n\t\t\tX:     x,\n\t\t\tY:     y,\n\t\t},\n\t)\n}\n\nfunc (ss *WlSubsurface) WlSubsurface_place_above(\n\ts protocols.ClientState,\n\tobject_id protocols.ObjectID[protocols.WlSubsurface],\n\tsibling_or_parent_id protocols.ObjectID[protocols.WlSurface],\n) {\n\tss.PlaceSubsurface(s, object_id, sibling_or_parent_id, ZOrderTypeAbove)\n}\n\nfunc (ss *WlSubsurface) PlaceSubsurface(\n\ts protocols.ClientState,\n\tobject_id protocols.ObjectID[protocols.WlSubsurface],\n\tsibling_or_parent_id protocols.ObjectID[protocols.WlSurface],\n\taboveOrBelow ZOrder,\n) {\n\tsurfaceID := GetSurfaceIDFromRole(s, object_id)\n\tif surfaceID == nil {\n\t\tSendError(s, object_id, protocols.WlSubsurfaceError_enum_bad_surface, \"surface not found\")\n\t\treturn\n\t}\n\n\tparent := GetWlSurfaceObject(s, ss.Parent)\n\n\tif parent == nil {\n\t\tSendError(s, object_id, protocols.WlSubsurfaceError_enum_bad_surface, \"parent not found\")\n\t\treturn\n\t}\n\n\tvar id *protocols.ObjectID[protocols.WlSurface]\n\tif sibling_or_parent_id == ss.Parent {\n\t\tid = nil\n\t} else {\n\t\tid = &sibling_or_parent_id\n\t}\n\n\tif (*parent).PendingUpdate.ZOrderSubsurfaces == nil {\n\t\t(*parent).PendingUpdate.ZOrderSubsurfaces = []ZOrderSubsurface{}\n\t}\n\t(*parent).PendingUpdate.ZOrderSubsurfaces = append(\n\t\t(*parent).PendingUpdate.ZOrderSubsurfaces,\n\t\tZOrderSubsurface{\n\t\t\tType:        aboveOrBelow,\n\t\t\tChildToMove: *surfaceID,\n\t\t\tRelativeTo:  id,\n\t\t},\n\t)\n}\nfunc (ss *WlSubsurface) WlSubsurface_place_below(\n\ts protocols.ClientState,\n\tobject_id protocols.ObjectID[protocols.WlSubsurface],\n\tsibling_or_parent_id protocols.ObjectID[protocols.WlSurface],\n) {\n\tss.PlaceSubsurface(s, object_id, sibling_or_parent_id, ZOrderTypeBelow)\n}\n\nfunc (ss *WlSubsurface) WlSubsurface_set_sync(\n\t_ protocols.ClientState,\n\t_ protocols.ObjectID[protocols.WlSubsurface],\n) {\n\tss.Sync = true\n}\n\nfunc (ss *WlSubsurface) WlSubsurface_set_desync(\n\t_ protocols.ClientState,\n\t_ protocols.ObjectID[protocols.WlSubsurface],\n) {\n\tss.Sync = false\n}\n\nfunc (ss *WlSubsurface) OnBind(\n\tcs protocols.ClientState,\n\t_ protocols.AnyObjectID,\n\t_ string,\n\tnewId_any protocols.AnyObjectID,\n\tversion uint32,\n) {\n\t// No-op\n}\n\n// Constructor (literal to TS `static make(parent)` style)\nfunc MakeWlSubsurface(parent protocols.ObjectID[protocols.WlSurface]) *protocols.WlSubsurface {\n\treturn &protocols.WlSubsurface{\n\t\tDelegate: &WlSubsurface{\n\t\t\tParent:   parent,\n\t\t\tSync:     true,\n\t\t\tPosition: Point{X: 0, Y: 0},\n\t\t},\n\t}\n}\n"
  },
  {
    "path": "wayland/wl_surface.go",
    "content": "package wayland\n\nimport (\n\t\"fmt\"\n\t\"image\"\n\n\t\"github.com/mmulet/term.everything/wayland/protocols\"\n)\n\ntype Texture struct {\n\tStride uint32\n\tWidth  uint32\n\tHeight uint32\n\tData   []byte\n}\n\nfunc (t *Texture) AsRGBA() *image.RGBA {\n\tif t == nil || t.Width == 0 || t.Height == 0 || len(t.Data) == 0 {\n\t\treturn nil\n\t}\n\treturn &image.RGBA{\n\t\tPix:    t.Data,\n\t\tStride: int(t.Stride),\n\t\tRect:   image.Rect(0, 0, int(t.Width), int(t.Height)),\n\t}\n}\n\ntype WlSurface struct {\n\tPosition struct {\n\t\tX int32\n\t\tY int32\n\t\tZ int32\n\t}\n\n\tTexture *Texture\n\t/**\n\t * xdg_surface is not a role,\n\t * but have to keep track anyway.\n\t */\n\tXdgSurfaceState *protocols.ObjectID[protocols.XdgSurface]\n\n\t/**\n\t * nil represents to draw the current surface.\n\t * By index, 0 is the bottom, and the last index is the top.\n\t */\n\tChildrenInDrawOrder []*protocols.ObjectID[protocols.WlSurface]\n\n\tRole SurfaceRole\n\n\tBufferTransform protocols.WlOutputTransform_enum\n\tBufferScale     int32\n\n\t/**\n\t * Null means infinite, (ie we can accept input from everywhere)\n\t */\n\tInputRegion *protocols.ObjectID[protocols.WlRegion]\n\t/**\n\t * Unlink opaque region, null means empty!\n\t */\n\tOpaqueRegion *protocols.ObjectID[protocols.WlRegion]\n\n\tPendingUpdate SurfaceUpdate\n\n\tOffset Point\n\n\t/**\n\t * Don't care about regions for now.\n\t * Just need to clear this when the surface has\n\t * been drawn.\n\t */\n\tDamaged bool\n}\n\nfunc (w *WlSurface) ClearRoleData() {\n\tif w.Role == nil {\n\t\treturn\n\t}\n\tw.Role.ClearData()\n}\n\nfunc (w *WlSurface) HasRoleData() bool {\n\tif w.Role == nil {\n\t\treturn false\n\t}\n\treturn w.Role.HasData()\n}\n\n// destroy_texture = (s: Wayland_Client, surface_id: Object_ID<w>) => {\n//   // if (!this.texture) {\n//   //   return;\n//   // }\n\n//   delete s.texture_from_surface_id[surface_id];\n//   // cpp.destroy_texture_for_wl_surface(s.client_state, surface_id);\n//   // this.texture = null;\n// };\n\n/**\n *\n * Below are the wl_surface_delegate methods\n */\n\nfunc (w *WlSurface) WlSurface_destroy(\n\ts protocols.ClientState,\n\tobject_id protocols.ObjectID[protocols.WlSurface],\n) bool {\n\n\t// this.destroy_texture(s, object_id);\n\n\tif !w.HasRoleData() {\n\t\treturn true\n\t}\n\n\tSendError(s, object_id, protocols.WlSurfaceError_enum_defunct_role_object, \"Surface destroyed before role\")\n\tfmt.Printf(\"wl_surface@%d Destroying surface before role is destroyed\", object_id)\n\n\treturn true\n}\n\nfunc (w *WlSurface) WlSurface_attach(\n\ts protocols.ClientState,\n\tobject_id protocols.ObjectID[protocols.WlSurface],\n\tbuffer *protocols.ObjectID[protocols.WlBuffer],\n\tx int32,\n\ty int32,\n) {\n\tw.PendingUpdate.Buffer = buffer\n\tif buffer != nil && *buffer == 0 {\n\t\tw.PendingUpdate.Buffer = nil\n\t}\n\n\tif s.GetCompositorVersion() < 5 {\n\t\tw.Offset = Point{X: x, Y: y}\n\t\treturn\n\t}\n\tif x == 0 && y == 0 {\n\t\treturn\n\t}\n\n\tSendError(\n\t\ts,\n\t\tobject_id,\n\t\tprotocols.WlSurfaceError_enum_invalid_offset,\n\t\t\"x and y must be 0 if version >= 5\",\n\t)\n}\n\nfunc (w *WlSurface) WlSurface_damage(\n\t_ protocols.ClientState,\n\t_ protocols.ObjectID[protocols.WlSurface],\n\tx int32,\n\ty int32,\n\twidth int32,\n\theight int32,\n) {\n\tif w.PendingUpdate.Damage == nil {\n\t\tw.PendingUpdate.Damage = []Rect{}\n\t}\n\tw.PendingUpdate.Damage = append(w.PendingUpdate.Damage, Rect{X: x, Y: y, Width: width, Height: height})\n}\n\nfunc (w *WlSurface) WlSurface_frame(\n\ts protocols.ClientState,\n\t_ protocols.ObjectID[protocols.WlSurface],\n\tcallback protocols.ObjectID[protocols.WlCallback],\n) {\n\ts.AddFrameDrawRequest(callback)\n}\n\nfunc (w *WlSurface) WlSurface_set_opaque_region(\n\t_ protocols.ClientState,\n\t_ protocols.ObjectID[protocols.WlSurface],\n\tregion *protocols.ObjectID[protocols.WlRegion],\n) {\n\tw.PendingUpdate.OpaqueRegion = region\n}\n\nfunc (w *WlSurface) WlSurface_set_input_region(\n\t_ protocols.ClientState,\n\t_ protocols.ObjectID[protocols.WlSurface],\n\tregion *protocols.ObjectID[protocols.WlRegion],\n) {\n\tw.PendingUpdate.InputRegion = region\n}\n\nfunc (w *WlSurface) WlSurface_commit(\n\ts protocols.ClientState,\n\tobject_id protocols.ObjectID[protocols.WlSurface],\n) {\n\tpendingBufferTextureUpdates := []PendingBufferUpdates{}\n\tpendingBufferTextureUpdates = ApplyWlSurfaceDoubleBufferedState(s, object_id, false, pendingBufferTextureUpdates, 0)\n\n\tfor _, upd := range pendingBufferTextureUpdates {\n\t\tCopyBufferToWlSurfaceTexture(s, upd.Surface, upd.ZIndex, upd.Buffer)\n\t}\n\n\tfor _, upd := range pendingBufferTextureUpdates {\n\t\t/**\n\t\t * @TODO Is there every an occasion where the buffer would\n\t\t * be used more than once, ie can we always release it here?\n\t\t */\n\t\t// After consumption, tell client its buffer can be re-used\n\t\tif upd.Buffer != nil {\n\t\t\tprotocols.WlBuffer_release(s, *upd.Buffer)\n\t\t}\n\t}\n}\n\nfunc (w *WlSurface) WlSurface_set_buffer_transform(\n\t_ protocols.ClientState,\n\t_ protocols.ObjectID[protocols.WlSurface],\n\ttransform int32,\n) {\n\tt := protocols.WlOutputTransform_enum(transform)\n\tw.PendingUpdate.BufferTransform = &t\n}\n\nfunc (w *WlSurface) WlSurface_set_buffer_scale(\n\t_ protocols.ClientState,\n\t_ protocols.ObjectID[protocols.WlSurface],\n\tscale int32,\n) {\n\tw.PendingUpdate.BufferScale = &scale\n}\n\nfunc (w *WlSurface) WlSurface_damage_buffer(\n\t_ protocols.ClientState,\n\t_ protocols.ObjectID[protocols.WlSurface],\n\tx int32,\n\ty int32,\n\twidth int32,\n\theight int32,\n) {\n\tif w.PendingUpdate.DamageBuffer == nil {\n\t\tw.PendingUpdate.DamageBuffer = []Rect{}\n\t}\n\tw.PendingUpdate.DamageBuffer = append(w.PendingUpdate.DamageBuffer, Rect{X: x, Y: y, Width: width, Height: height})\n}\n\nfunc (w *WlSurface) WlSurface_offset(\n\t_ protocols.ClientState,\n\t_ protocols.ObjectID[protocols.WlSurface],\n\tx int32,\n\ty int32,\n) {\n\tw.PendingUpdate.Offset = &Point{X: x, Y: y}\n}\n\nfunc (w *WlSurface) OnBind(\n\tcs protocols.ClientState,\n\t_ protocols.AnyObjectID,\n\t_ string,\n\tnewId_any protocols.AnyObjectID,\n\tversion uint32,\n) {\n}\n\nfunc (w *WlSurface) ResetPendingUpdate() {\n\tw.PendingUpdate = SurfaceUpdate{}\n}\n\n// Constructor\nfunc MakeWlSurface() *protocols.WlSurface {\n\tws := &WlSurface{\n\t\tBufferScale:         1,\n\t\tChildrenInDrawOrder: []*protocols.ObjectID[protocols.WlSurface]{nil},\n\t\tPosition:            struct{ X, Y, Z int32 }{X: 0, Y: 0, Z: 0},\n\t\tXdgSurfaceState:     nil,\n\t\tInputRegion:         nil,\n\t\tOpaqueRegion:        nil,\n\t\tBufferTransform:     protocols.WlOutputTransform_enum_normal, // default transform can be set by client; nil means \"normal\" until set\n\t}\n\treturn &protocols.WlSurface{\n\t\tDelegate: ws,\n\t}\n}\n"
  },
  {
    "path": "wayland/wl_tough.go",
    "content": "package wayland\n\nimport (\n\t\"github.com/mmulet/term.everything/wayland/protocols\"\n)\n\ntype WlTouchDelegate struct {\n}\n\nfunc (w *WlTouchDelegate) WlTouch_release(s protocols.ClientState, object_id protocols.ObjectID[protocols.WlTouch]) bool {\n\treturn true\n}\n\nfunc (w *WlTouchDelegate) OnBind(s protocols.ClientState, name protocols.AnyObjectID, interface_ string, new_id protocols.AnyObjectID, version_number uint32) {\n\t/** @TODO: Implement wl_touch_on_bind */\n}\n\nfunc MakeWlTouch() *protocols.WlTouch {\n\treturn &protocols.WlTouch{\n\t\tDelegate: &WlTouchDelegate{},\n\t}\n}\n"
  },
  {
    "path": "wayland/xdg-decoration-unstable-v1.xml.helper.go",
    "content": "// Code generated by `cmd/protocols`; DO NOT EDIT.\n\npackage wayland\n"
  },
  {
    "path": "wayland/xdg-shell.xml.helper.go",
    "content": "// Code generated by `cmd/protocols`; DO NOT EDIT.\n\npackage wayland\n\nimport \"github.com/mmulet/term.everything/wayland/protocols\"\n\nfunc GetXdgPositionerObject(cs protocols.ClientState, id protocols.ObjectID[protocols.XdgPositioner]) *XdgPositioner {\n\tv := cs.GetObject(protocols.AnyObjectID(id))\n\tif v == nil {\n\t\treturn nil\n\t}\n\to := v.(protocols.WaylandObject[protocols.XdgPositioner_delegate])\n\td := o.GetDelegate()\n\treturn d.(*XdgPositioner)\n}\n\nfunc GetXdgSurfaceObject(cs protocols.ClientState, id protocols.ObjectID[protocols.XdgSurface]) *XdgSurface {\n\tv := cs.GetObject(protocols.AnyObjectID(id))\n\tif v == nil {\n\t\treturn nil\n\t}\n\to := v.(protocols.WaylandObject[protocols.XdgSurface_delegate])\n\td := o.GetDelegate()\n\treturn d.(*XdgSurface)\n}\n\nfunc GetXdgToplevelObject(cs protocols.ClientState, id protocols.ObjectID[protocols.XdgToplevel]) *XdgToplevel {\n\tv := cs.GetObject(protocols.AnyObjectID(id))\n\tif v == nil {\n\t\treturn nil\n\t}\n\to := v.(protocols.WaylandObject[protocols.XdgToplevel_delegate])\n\td := o.GetDelegate()\n\treturn d.(*XdgToplevel)\n}\n"
  },
  {
    "path": "wayland/xdg_popup.go",
    "content": "package wayland\n\nimport (\n\t\"github.com/mmulet/term.everything/wayland/protocols\"\n)\n\ntype XdgPopup struct {\n\tVersion uint32\n\tParent  *protocols.ObjectID[protocols.XdgSurface]\n\tState   XdgPositionerState\n\t/**\n\t * Only one instead of a queue because if multiple\n\t * position requests are sent we can ignore\n\t * all but the last one\n\t */\n\tpendingPosition       *XdgPositionerState\n\tpendingPositionSerial *uint32\n}\n\nfunc (x *XdgPopup) XdgPopup_destroy(\n\ts protocols.ClientState,\n\tobject_id protocols.ObjectID[protocols.XdgPopup],\n) bool {\n\tsurface := GetSurfaceFromRole(s, object_id)\n\tUnregisterRoleToSurface(s, object_id)\n\tif surface == nil {\n\t\treturn true\n\t}\n\tif surface.Role == nil {\n\t\treturn true\n\t}\n\n\t_, isPopup := surface.Role.(*SurfaceRoleXdgPopup)\n\tif !isPopup {\n\t\treturn true\n\t}\n\tsurface.ClearRoleData()\n\treturn true\n}\n\nfunc (x *XdgPopup) XdgPopup_grab(\n\t_ protocols.ClientState,\n\t_ protocols.ObjectID[protocols.XdgPopup],\n\t_ protocols.ObjectID[protocols.WlSeat],\n\t_ uint32,\n) {\n\t/** @TODO: Implement xdg_popup_grab */\n}\n\nfunc (x *XdgPopup) XdgPopup_reposition(\n\ts protocols.ClientState,\n\tobject_id protocols.ObjectID[protocols.XdgPopup],\n\tpositionerID protocols.ObjectID[protocols.XdgPositioner],\n\ttoken uint32,\n) {\n\tpositioner := GetXdgPositionerObject(s, positionerID)\n\tif positioner == nil {\n\t\treturn\n\t}\n\tnew_state := positioner.state\n\tst := new_state // copy\n\tx.pendingPosition = &st\n\tx.pendingPositionSerial = &token\n\n\tprotocols.XdgPopup_repositioned(s, x.Version, object_id, token)\n\n\t/**\n\t * @TODO figure out what\n\t * these values are\n\t */\n\tprotocols.XdgPopup_configure(s, object_id, 0, 0, int32(VirtualMonitorSize.Width), int32(VirtualMonitorSize.Height))\n\n\tsurface := GetSurfaceFromRole(s, object_id)\n\tif surface == nil {\n\t\treturn\n\t}\n\n\tif surface.XdgSurfaceState == nil {\n\t\treturn\n\t}\n\n\txdg_surface_state := GetXdgSurfaceObject(s, *surface.XdgSurfaceState)\n\tif xdg_surface_state == nil {\n\t\treturn\n\t}\n\n\tgo func() {\n\t\txdg_surface_state.configure(s)\n\t\t// reposition the popup somehow\n\t}()\n\n}\n\nfunc (x *XdgPopup) OnBind(\n\tcs protocols.ClientState,\n\t_ protocols.AnyObjectID,\n\t_ string,\n\tnewId_any protocols.AnyObjectID,\n\tversion uint32,\n) {\n}\n\nfunc MakeXdgPopup(\n\tversion uint32,\n\tparent *protocols.ObjectID[protocols.XdgSurface],\n\tstate XdgPositionerState,\n) *protocols.XdgPopup {\n\treturn &protocols.XdgPopup{\n\t\tDelegate: &XdgPopup{\n\t\t\tVersion: version,\n\t\t\tParent:  parent,\n\t\t\tState:   state,\n\t\t},\n\t}\n}\n"
  },
  {
    "path": "wayland/xdg_positioner.go",
    "content": "package wayland\n\nimport (\n\t\"github.com/mmulet/term.everything/wayland/protocols\"\n)\n\ntype anchorRect struct {\n\tX      int32\n\tY      int32\n\tWidth  int32\n\tHeight int32\n}\n\ntype offset struct {\n\tX int32\n\tY int32\n}\n\ntype XdgPositionerState struct {\n\tWidth                 int32\n\tHeight                int32\n\tAnchorRect            anchorRect\n\tAnchor                protocols.XdgPositionerAnchor_enum\n\tGravity               protocols.XdgPositionerGravity_enum\n\tConstraintAdjustment  protocols.XdgPositionerConstraintAdjustment_enum\n\tOffset                offset\n\tReactive              bool\n\tParentSize            Size\n\tParentConfigureSerial uint32\n}\n\ntype XdgPositioner struct {\n\tstate XdgPositionerState\n}\n\nfunc (x *XdgPositioner) XdgPositioner_destroy(\n\ts protocols.ClientState,\n\tid protocols.ObjectID[protocols.XdgPositioner],\n) bool {\n\treturn true\n}\n\nfunc (x *XdgPositioner) XdgPositioner_set_size(\n\t_ protocols.ClientState,\n\t_ protocols.ObjectID[protocols.XdgPositioner],\n\twidth int32,\n\theight int32,\n) {\n\tx.state.Width = width\n\tx.state.Height = height\n}\n\nfunc (x *XdgPositioner) XdgPositioner_set_anchor_rect(\n\t_ protocols.ClientState,\n\t_ protocols.ObjectID[protocols.XdgPositioner],\n\tax int32,\n\tay int32,\n\taw int32,\n\tah int32,\n) {\n\tx.state.AnchorRect = anchorRect{X: ax, Y: ay, Width: aw, Height: ah}\n}\n\nfunc (x *XdgPositioner) XdgPositioner_set_anchor(\n\t_ protocols.ClientState,\n\t_ protocols.ObjectID[protocols.XdgPositioner],\n\tanchor protocols.XdgPositionerAnchor_enum,\n) {\n\tx.state.Anchor = anchor\n}\n\nfunc (x *XdgPositioner) XdgPositioner_set_gravity(\n\t_ protocols.ClientState,\n\t_ protocols.ObjectID[protocols.XdgPositioner],\n\tgravity protocols.XdgPositionerGravity_enum,\n) {\n\tx.state.Gravity = gravity\n}\n\nfunc (x *XdgPositioner) XdgPositioner_set_constraint_adjustment(\n\t_ protocols.ClientState,\n\t_ protocols.ObjectID[protocols.XdgPositioner],\n\tadj protocols.XdgPositionerConstraintAdjustment_enum,\n) {\n\t/** @TODO: Implement xdg_positioner_set_constraint_adjustment */\n}\n\nfunc (x *XdgPositioner) XdgPositioner_set_offset(\n\t_ protocols.ClientState,\n\t_ protocols.ObjectID[protocols.XdgPositioner],\n\tox int32,\n\toy int32,\n) {\n\tx.state.Offset = offset{X: ox, Y: oy}\n}\n\nfunc (x *XdgPositioner) XdgPositioner_set_reactive(\n\t_ protocols.ClientState,\n\t_ protocols.ObjectID[protocols.XdgPositioner],\n) {\n\tx.state.Reactive = true\n}\n\nfunc (x *XdgPositioner) XdgPositioner_set_parent_size(\n\t_ protocols.ClientState,\n\t_ protocols.ObjectID[protocols.XdgPositioner],\n\tparentWidth int32,\n\tparentHeight int32,\n) {\n\tvar pw, ph uint32\n\tif parentWidth > 0 {\n\t\tpw = uint32(parentWidth)\n\t}\n\tif parentHeight > 0 {\n\t\tph = uint32(parentHeight)\n\t}\n\tx.state.ParentSize = Size{Width: pw, Height: ph}\n}\n\nfunc (x *XdgPositioner) XdgPositioner_set_parent_configure(\n\t_ protocols.ClientState,\n\t_ protocols.ObjectID[protocols.XdgPositioner],\n\tserial uint32,\n) {\n\tx.state.ParentConfigureSerial = serial\n}\n\nfunc (x *XdgPositioner) OnBind(\n\tcs protocols.ClientState,\n\t_ protocols.AnyObjectID,\n\t_ string,\n\tnewId_any protocols.AnyObjectID,\n\tversion uint32,\n) {\n}\n\nfunc MakeXdgPositioner() *protocols.XdgPositioner {\n\treturn &protocols.XdgPositioner{\n\t\tDelegate: &XdgPositioner{},\n\t}\n}\n"
  },
  {
    "path": "wayland/xdg_surface.go",
    "content": "package wayland\n\nimport (\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/mmulet/term.everything/wayland/protocols\"\n)\n\ntype XdgWindowGeometry struct {\n\tX      int32\n\tY      int32\n\tWidth  int32\n\tHeight int32\n}\n\ntype XdgSurface struct {\n\tVersion        uint32\n\tXdgSurfaceID   protocols.ObjectID[protocols.XdgSurface]\n\tOnConfigure    map[uint32]chan uint32\n\tLatestSerial   uint32\n\tWindowGeometry XdgWindowGeometry\n}\n\nvar GlobalEnterSerial uint32 = 0\n\n// Sends a configure event and waits for the client to ack it. Blocks until ack received.\nfunc (x *XdgSurface) configure(s protocols.ClientState) {\n\tserial := x.LatestSerial\n\tx.LatestSerial++\n\n\tconfigureChannel := make(chan uint32, 1)\n\tx.OnConfigure[serial] = configureChannel\n\n\tprotocols.XdgSurface_configure(s, x.XdgSurfaceID, serial)\n\n\t<-configureChannel\n\n}\n\n/**\n * xdg_surface methods\n */\n\nfunc (x *XdgSurface) XdgSurface_destroy(\n\ts protocols.ClientState,\n\tobjectID protocols.ObjectID[protocols.XdgSurface],\n) bool {\n\n\tif surface_id := GetSurfaceIDFromRole(s, objectID); surface_id != nil {\n\n\t\tif ws := GetWlSurfaceObject(s, *surface_id); ws != nil && ws.HasRoleData() {\n\t\t\tfmt.Printf(\"xdg_surface Destroying surface before role is destroyed\")\n\t\t\tSendError(\n\t\t\t\ts,\n\t\t\t\tobjectID,\n\t\t\t\tprotocols.XdgSurfaceError_enum_defunct_role_object,\n\t\t\t\t\"Surface destroyed before role\",\n\t\t\t)\n\t\t}\n\t}\n\n\tUnregisterRoleToSurface(s, objectID)\n\treturn true\n}\n\nfunc (x *XdgSurface) XdgSurface_get_toplevel(\n\ts protocols.ClientState,\n\txdgSurfaceObjectID protocols.ObjectID[protocols.XdgSurface],\n\tid protocols.ObjectID[protocols.XdgToplevel],\n) {\n\tsurface_id := GetSurfaceIDFromRole(s, xdgSurfaceObjectID)\n\tif surface_id == nil {\n\t\tSendError(s,\n\t\t\txdgSurfaceObjectID,\n\t\t\tprotocols.XdgSurfaceError_enum_not_constructed,\n\t\t\t\"surface not found\",\n\t\t)\n\t\treturn\n\t}\n\n\tsurface := GetSurfaceFromRole(s, xdgSurfaceObjectID)\n\tif surface == nil {\n\t\tSendError(s,\n\t\t\txdgSurfaceObjectID,\n\t\t\tprotocols.XdgSurfaceError_enum_not_constructed,\n\t\t\t\"surface not found\",\n\t\t)\n\t\treturn\n\t}\n\n\tif surface.Role == nil {\n\t\tsurface.Role = &SurfaceRoleXdgToplevel{}\n\t}\n\n\tsurfaceRole, surface_role_is_xdg_toplevel := surface.Role.(*SurfaceRoleXdgToplevel)\n\tif !surface_role_is_xdg_toplevel {\n\t\tSendError(s,\n\t\t\txdgSurfaceObjectID,\n\t\t\tprotocols.XdgSurfaceError_enum_defunct_role_object,\n\t\t\t\"surface not found\",\n\t\t)\n\t\treturn\n\t}\n\n\tif surfaceRole.Data != nil {\n\t\tSendError(s,\n\t\t\txdgSurfaceObjectID,\n\t\t\tprotocols.XdgSurfaceError_enum_defunct_role_object,\n\t\t\t\"surface already has a role\",\n\t\t)\n\t\treturn\n\t}\n\n\tsurfaceRole.Data = &id\n\tAddObject(s, id, MakeXdgToplevel())\n\n\tRegisterRoleToSurface(s, id, *surface_id)\n\ts.TopLevelSurfaces()[id] = true\n\n\tprotocols.XdgToplevel_configure(\n\t\ts,\n\t\tid,\n\t\tint32(VirtualMonitorSize.Width),\n\t\tint32(VirtualMonitorSize.Height),\n\t\tToBytes([]protocols.XdgToplevelState_enum{\n\t\t\tprotocols.XdgToplevelState_enum_maximized,\n\t\t\tprotocols.XdgToplevelState_enum_fullscreen,\n\t\t}),\n\t)\n\n\t// TODO this is necessary, but when?\n\tprotocols.XdgSurface_configure(s, xdgSurfaceObjectID, 0)\n\n\t// TODO should this be here\n\n\tif output_binds := protocols.GetGlobalWlOutputBinds(s); output_binds != nil {\n\t\tfor output_id, _ := range output_binds {\n\t\t\tprotocols.WlSurface_enter(s, *surface_id, output_id)\n\t\t}\n\t}\n\tserial := GlobalEnterSerial\n\tGlobalEnterSerial += 1\n\n\tif keyboard_binds := protocols.GetGlobalWlKeyboardBinds(s); keyboard_binds != nil {\n\n\t\tfor keyboard_id, _ := range keyboard_binds {\n\t\t\tprotocols.WlKeyboard_enter(s, keyboard_id, serial, *surface_id, []byte{})\n\t\t}\n\t}\n\n\tif pointer_binds := protocols.GetGlobalWlPointerBinds(s); pointer_binds != nil {\n\t\tfor pointer_id, version := range pointer_binds {\n\t\t\tprotocols.WlPointer_enter(s, pointer_id, serial, *surface_id, Pointer.WindowX, Pointer.WindowY)\n\t\t\tprotocols.WlPointer_frame(s, uint32(version), pointer_id)\n\t\t}\n\t}\n\n\t/**\n\t * commented because it\n\t * causes firefox to crash with:\n\t * \"GraphicsCriticalError\": \"|[0][GFX1-]: (ubuntu:gnome) Wayland protocol error: listener function for opcode 2 of xdg_toplevel is NULL\\n (t=0.503382) \",\n\t */\n\t// xdg_toplevel_funcs.configure_bounds(\n\t//   s,\n\t//   this.version,\n\t//   id,\n\t//   virtual_monitor_size.width,\n\t//   virtual_monitor_size.height\n\t// );\n\t/**\n\t * So with Xwayland clients, pointer enter doesn't stick?\n\t *\n\t * So let's do it again\n\t * after a timeout\n\t * @TODO where to actually put this?\n\t */\n\n\tgo func() {\n\t\ttime.Sleep(100 * time.Millisecond)\n\t\tif pointer_binds := protocols.GetGlobalWlPointerBinds(s); pointer_binds != nil {\n\t\t\tfor pointer_id, _ := range pointer_binds {\n\t\t\t\tpointer := GetWlPointerObject(s, pointer_id)\n\t\t\t\tif pointer == nil {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tprotocols.WlPointer_enter(s, pointer_id, 0, *surface_id, pointer.WindowX, pointer.WindowY)\n\t\t\t}\n\t\t}\n\t}()\n\n}\n\nfunc (x *XdgSurface) XdgSurface_get_popup(\n\ts protocols.ClientState,\n\txdgSurfaceObjectID protocols.ObjectID[protocols.XdgSurface],\n\tid protocols.ObjectID[protocols.XdgPopup],\n\tparent *protocols.ObjectID[protocols.XdgSurface],\n\tpositionerID protocols.ObjectID[protocols.XdgPositioner],\n) {\n\tsurface_id := GetSurfaceIDFromRole(s, xdgSurfaceObjectID)\n\tif surface_id == nil {\n\t\tSendError(\n\t\t\ts,\n\t\t\txdgSurfaceObjectID,\n\t\t\tprotocols.XdgSurfaceError_enum_not_constructed,\n\t\t\t\"surface not found\",\n\t\t)\n\t\treturn\n\t}\n\n\tsurface := GetSurfaceFromRole(s, xdgSurfaceObjectID)\n\tif surface == nil {\n\t\tSendError(\n\t\t\ts,\n\t\t\txdgSurfaceObjectID,\n\t\t\tprotocols.XdgSurfaceError_enum_not_constructed,\n\t\t\t\"surface not found\",\n\t\t)\n\t\treturn\n\t}\n\n\tif surface.Role == nil {\n\t\tsurface.Role = &SurfaceRoleXdgPopup{}\n\t}\n\n\tsurfaceRole, surface_role_is_xdg_popup := surface.Role.(*SurfaceRoleXdgPopup)\n\tif !surface_role_is_xdg_popup {\n\t\tSendError(\n\t\t\ts,\n\t\t\txdgSurfaceObjectID,\n\t\t\tprotocols.XdgSurfaceError_enum_defunct_role_object,\n\t\t\t\"surface role is not xdg_popup\",\n\t\t)\n\t\treturn\n\t}\n\tpositioner := GetXdgPositionerObject(s, positionerID)\n\tif positioner == nil {\n\t\tSendError(\n\t\t\ts,\n\t\t\txdgSurfaceObjectID,\n\t\t\tprotocols.XdgSurfaceError_enum_not_constructed,\n\t\t\t\"positioner not found\",\n\t\t)\n\t\treturn\n\t}\n\tsurfaceRole.Data = &id\n\n\tAddObject(s, id, MakeXdgPopup(x.Version, parent, positioner.state))\n\n\tRegisterRoleToSurface(s, id, *surface_id)\n\n\tprotocols.XdgPopup_configure(\n\t\ts,\n\t\tid,\n\t\t0, 0,\n\t\tint32(VirtualMonitorSize.Width),\n\t\tint32(VirtualMonitorSize.Height),\n\t)\n}\n\nfunc (x *XdgSurface) XdgSurface_set_window_geometry(\n\ts protocols.ClientState,\n\tobjectID protocols.ObjectID[protocols.XdgSurface],\n\twx int32,\n\twy int32,\n\tww int32,\n\twh int32,\n) {\n\n\tsurface := GetSurfaceFromRole(s, objectID)\n\tif surface == nil {\n\t\treturn\n\t}\n\n\tsurface.PendingUpdate.XdgSurfaceWindowGeometry = &XdgWindowGeometry{\n\t\tX:      wx,\n\t\tY:      wy,\n\t\tWidth:  ww,\n\t\tHeight: wh,\n\t}\n}\n\nfunc (x *XdgSurface) XdgSurface_ack_configure(\n\t_ protocols.ClientState,\n\t_ protocols.ObjectID[protocols.XdgSurface],\n\tserial uint32,\n) {\n\tif x.OnConfigure == nil {\n\t\treturn\n\t}\n\tif cb, ok := x.OnConfigure[serial]; ok && cb != nil {\n\t\tcb <- serial\n\t}\n\tfor k := range x.OnConfigure {\n\t\tif k > serial {\n\t\t\tcontinue\n\t\t}\n\t\t//TODO do I need to close the channel?\n\t\tif cb, ok := x.OnConfigure[k]; ok && cb != nil {\n\t\t\tclose(cb)\n\t\t}\n\t\tdelete(x.OnConfigure, k)\n\t}\n}\n\nfunc (x *XdgSurface) OnBind(\n\tcs protocols.ClientState,\n\t_ protocols.AnyObjectID,\n\t_ string,\n\tnewId_any protocols.AnyObjectID,\n\tversion uint32,\n) {\n}\n\nfunc MakeXdgSurface(version uint32, xdg_surface_id protocols.ObjectID[protocols.XdgSurface]) *protocols.XdgSurface {\n\treturn &protocols.XdgSurface{\n\t\tDelegate: &XdgSurface{\n\t\t\tVersion:      version,\n\t\t\tXdgSurfaceID: xdg_surface_id,\n\t\t\tOnConfigure:  make(map[uint32]chan uint32),\n\t\t},\n\t}\n}\n"
  },
  {
    "path": "wayland/xdg_toplevel.go",
    "content": "package wayland\n\nimport (\n\t\"github.com/mmulet/term.everything/wayland/protocols\"\n)\n\ntype PendingToplevelState struct {\n\tMaxSize *Size\n\tMinSize *Size\n}\n\ntype XdgToplevel struct {\n\tParent *protocols.ObjectID[protocols.XdgToplevel]\n\n\tTitle *string\n\tAppID string\n\n\tMaximized  bool\n\tFullscreen bool\n\n\tMinSize *Size\n\tMaxSize *Size\n\n\tPendingState *PendingToplevelState\n}\n\nfunc (t *XdgToplevel) XdgToplevel_destroy(\n\ts protocols.ClientState,\n\tobjectID protocols.ObjectID[protocols.XdgToplevel],\n) bool {\n\tsurface := GetSurfaceFromRole(s, objectID)\n\n\tUnregisterRoleToSurface(s, objectID)\n\ts.TopLevelSurfaces()[objectID] = false\n\tif surface != nil {\n\t\tsurface.ClearRoleData()\n\t}\n\treturn true\n\n}\n\nfunc (t *XdgToplevel) XdgToplevel_set_parent(\n\t_ protocols.ClientState,\n\t_ protocols.ObjectID[protocols.XdgToplevel],\n\tparent *protocols.ObjectID[protocols.XdgToplevel],\n) {\n\tt.Parent = parent\n}\n\nfunc (t *XdgToplevel) XdgToplevel_set_title(\n\t_ protocols.ClientState,\n\t_ protocols.ObjectID[protocols.XdgToplevel],\n\ttitle string,\n) {\n\tt.Title = &title\n}\n\nfunc (t *XdgToplevel) XdgToplevel_set_app_id(\n\t_ protocols.ClientState,\n\t_ protocols.ObjectID[protocols.XdgToplevel],\n\tappID string,\n) {\n\tt.AppID = appID\n}\n\nfunc (t *XdgToplevel) XdgToplevel_show_window_menu(\n\t_ protocols.ClientState,\n\t_ protocols.ObjectID[protocols.XdgToplevel],\n\t_ protocols.ObjectID[protocols.WlSeat],\n\t_ uint32, // serial\n\t_ int32, // x\n\t_ int32, // y\n) {\n\t// TODO: Implement show_window_menu\n}\n\nfunc (t *XdgToplevel) XdgToplevel_move(\n\t_ protocols.ClientState,\n\t_ protocols.ObjectID[protocols.XdgToplevel],\n\t_ protocols.ObjectID[protocols.WlSeat],\n\t_ uint32, // serial\n) {\n\t// TODO: Implement move\n}\n\nfunc (t *XdgToplevel) XdgToplevel_resize(\n\t_ protocols.ClientState,\n\t_ protocols.ObjectID[protocols.XdgToplevel],\n\t_ protocols.ObjectID[protocols.WlSeat],\n\t_ uint32, // serial\n\t_ protocols.XdgToplevelResizeEdge_enum, // edges\n) {\n\t// TODO: Implement resize\n}\n\nfunc (t *XdgToplevel) XdgToplevel_set_max_size(\n\t_ protocols.ClientState,\n\t_ protocols.ObjectID[protocols.XdgToplevel],\n\twidth int32,\n\theight int32,\n) {\n\n\tif t.PendingState == nil {\n\t\tt.PendingState = &PendingToplevelState{}\n\t}\n\n\tif width <= 0 || height <= 0 {\n\t\tt.PendingState.MaxSize = nil\n\t\treturn\n\t}\n\tt.PendingState.MaxSize = &Size{\n\t\tWidth:  uint32(width),\n\t\tHeight: uint32(height),\n\t}\n}\n\nfunc (t *XdgToplevel) XdgToplevel_set_min_size(\n\t_ protocols.ClientState,\n\t_ protocols.ObjectID[protocols.XdgToplevel],\n\twidth int32,\n\theight int32,\n) {\n\tif t.PendingState == nil {\n\t\tt.PendingState = &PendingToplevelState{}\n\t}\n\n\tif width <= 0 || height <= 0 {\n\t\tt.PendingState.MinSize = nil\n\t\treturn\n\t}\n\tt.PendingState.MinSize = &Size{\n\t\tWidth:  uint32(width),\n\t\tHeight: uint32(height),\n\t}\n}\n\nfunc (t *XdgToplevel) XdgToplevel_set_maximized(\n\ts protocols.ClientState,\n\tobjectID protocols.ObjectID[protocols.XdgToplevel],\n) {\n\tgo func() {\n\t\tif shouldChange := t.stateConfiguration(s, objectID, true, t.Fullscreen); shouldChange {\n\t\t\tt.Maximized = true\n\t\t}\n\t}()\n\n}\n\nfunc (t *XdgToplevel) XdgToplevel_unset_maximized(\n\ts protocols.ClientState,\n\tobjectID protocols.ObjectID[protocols.XdgToplevel],\n) {\n\tgo func() {\n\t\tif shouldChange := t.stateConfiguration(s, objectID, false, t.Fullscreen); shouldChange {\n\t\t\tt.Maximized = false\n\t\t}\n\t}()\n}\n\nfunc (t *XdgToplevel) XdgToplevel_set_fullscreen(\n\ts protocols.ClientState,\n\tobjectID protocols.ObjectID[protocols.XdgToplevel],\n\t_ *protocols.ObjectID[protocols.WlOutput],\n) {\n\tgo func() {\n\t\tif shouldChange := t.stateConfiguration(s, objectID, t.Maximized, true); shouldChange {\n\t\t\tt.Fullscreen = true\n\t\t}\n\t}()\n}\n\nfunc (t *XdgToplevel) XdgToplevel_unset_fullscreen(\n\ts protocols.ClientState,\n\tobjectID protocols.ObjectID[protocols.XdgToplevel],\n) {\n\tgo func() {\n\t\tif shouldChange := t.stateConfiguration(s, objectID, t.Maximized, false); shouldChange {\n\t\t\tt.Fullscreen = false\n\t\t}\n\t}()\n}\n\nfunc (t *XdgToplevel) XdgToplevel_set_minimized(\n\t_ protocols.ClientState,\n\t_ protocols.ObjectID[protocols.XdgToplevel],\n) {\n\t// TODO: Implement minimize behavior if desired\n}\n\nfunc (t *XdgToplevel) OnBind(\n\tcs protocols.ClientState,\n\t_ protocols.AnyObjectID,\n\t_ string,\n\tnewId_any protocols.AnyObjectID,\n\tversion uint32,\n) {\n\t// No-op\n}\n\nfunc (t *XdgToplevel) stateConfiguration(\n\ts protocols.ClientState,\n\tobjectID protocols.ObjectID[protocols.XdgToplevel],\n\tmaximized bool,\n\tfullscreen bool,\n) bool {\n\t// const data = s.get_role_data_from_role(object_id, \"xdg_toplevel\");\n\t// if (!data) {\n\t//   return false;\n\t// }\n\n\t// Ensure the role resolves to a wl_surface\n\tsurface := GetSurfaceFromRole(s, objectID)\n\tif surface == nil {\n\t\treturn false\n\t}\n\tif surface.XdgSurfaceState == nil {\n\t\treturn false\n\t}\n\n\txdg_surface_State := GetXdgSurfaceObject(s, *surface.XdgSurfaceState)\n\n\tif xdg_surface_State == nil {\n\t\treturn false\n\t}\n\n\tvar states []protocols.XdgToplevelState_enum\n\tif maximized {\n\t\tstates = append(states, protocols.XdgToplevelState_enum_maximized)\n\t}\n\tif fullscreen {\n\t\tstates = append(states, protocols.XdgToplevelState_enum_fullscreen)\n\t}\n\n\tprotocols.XdgToplevel_configure(\n\t\ts,\n\t\tobjectID,\n\t\tint32(VirtualMonitorSize.Width),\n\t\tint32(VirtualMonitorSize.Height),\n\t\tToBytes(states),\n\t)\n\txdg_surface_State.configure(s)\n\n\treturn true\n}\n\nfunc MakeXdgToplevel() *protocols.XdgToplevel {\n\treturn &protocols.XdgToplevel{\n\t\tDelegate: &XdgToplevel{},\n\t}\n}\n"
  },
  {
    "path": "wayland/xdg_wm_base.go",
    "content": "package wayland\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/mmulet/term.everything/wayland/protocols\"\n)\n\ntype XdgWmBase struct {\n\tVersion uint32\n}\n\nfunc (x *XdgWmBase) XdgWmBase_destroy(\n\t_ protocols.ClientState,\n\t_ protocols.ObjectID[protocols.XdgWmBase],\n) bool {\n\treturn true\n}\n\nfunc (x *XdgWmBase) XdgWmBase_create_positioner(\n\ts protocols.ClientState,\n\t_ protocols.ObjectID[protocols.XdgWmBase],\n\tid protocols.ObjectID[protocols.XdgPositioner],\n) {\n\tAddObject(s, id, MakeXdgPositioner())\n}\n\nfunc (x *XdgWmBase) XdgWmBase_get_xdg_surface(\n\ts protocols.ClientState,\n\tobjectID protocols.ObjectID[protocols.XdgWmBase],\n\txdgSurfaceID protocols.ObjectID[protocols.XdgSurface],\n\tsurfaceID protocols.ObjectID[protocols.WlSurface],\n) {\n\tsurface := GetWlSurfaceObject(s, surfaceID)\n\tif surface == nil {\n\t\tSendError(s, objectID, protocols.XdgWmBaseError_enum_role, \"surface not found\")\n\t\treturn\n\t}\n\n\tif surface.Role != nil {\n\t\t/**\n\t\t * It is illegal to create an xdg_surface for a wl_surface which already has\n\t\t * a assigned role\n\t\t */\n\t\tfmt.Printf(\"XdgWmBase_get_xdg_surface: surface@%d already has a role\\n\", surfaceID)\n\t\tSendError(s,\n\t\t\tobjectID,\n\t\t\tprotocols.XdgWmBaseError_enum_role,\n\t\t\t\"surface already has a role\",\n\t\t)\n\t\treturn\n\t}\n\n\tsurface.XdgSurfaceState = &xdgSurfaceID\n\n\t// surface.xdg_surface_state = {\n\t//   on_configure: new Map(),\n\t//   latest_configure_serial: 0,\n\t//   xdg_surface_id: xdg_surface_id,\n\t//   window_geometry: { x: 0, y: 0, width: 0, height: 0 },\n\t// };\n\n\tRegisterRoleToSurface(s, xdgSurfaceID, surfaceID)\n\n\tAddObject(s, xdgSurfaceID, MakeXdgSurface(x.Version, xdgSurfaceID))\n}\n\nfunc (x *XdgWmBase) XdgWmBase_pong(\n\t_ protocols.ClientState,\n\t_ protocols.ObjectID[protocols.XdgWmBase],\n\t_ uint32,\n) {\n\t// no-op\n}\n\nfunc (x *XdgWmBase) OnBind(\n\t_ protocols.ClientState,\n\t_ protocols.AnyObjectID,\n\t_ string,\n\t_ protocols.AnyObjectID,\n\tversion uint32,\n) {\n\tx.Version = version\n}\n\nfunc MakeXdgWmBase() *protocols.XdgWmBase {\n\treturn &protocols.XdgWmBase{\n\t\tDelegate: &XdgWmBase{\n\t\t\tVersion: 1,\n\t\t},\n\t}\n}\n"
  },
  {
    "path": "wayland/xwayland-keyboard-grab-unstable-v1.xml.helper.go",
    "content": "// Code generated by `cmd/protocols`; DO NOT EDIT.\n\npackage wayland\n"
  },
  {
    "path": "wayland/xwayland-shell-v1.xml.helper.go",
    "content": "// Code generated by `cmd/protocols`; DO NOT EDIT.\n\npackage wayland\n"
  },
  {
    "path": "wayland/xwayland_shell_v1.go",
    "content": "// Assuming surface.Role has a Data field that can be set to nil\npackage wayland\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/mmulet/term.everything/wayland/protocols\"\n)\n\ntype XwaylandShellV1 struct {\n}\n\nfunc (x *XwaylandShellV1) XwaylandShellV1_destroy(\n\ts protocols.ClientState,\n\tobject_id protocols.ObjectID[protocols.XwaylandShellV1],\n) bool {\n\treturn true\n}\n\nfunc (x *XwaylandShellV1) XwaylandShellV1_get_xwayland_surface(\n\ts protocols.ClientState,\n\tobject_id protocols.ObjectID[protocols.XwaylandShellV1],\n\tid protocols.ObjectID[protocols.XwaylandSurfaceV1],\n\tsurface_id protocols.ObjectID[protocols.WlSurface],\n) {\n\tsurface := GetWlSurfaceObject(s, surface_id)\n\tif surface == nil {\n\t\tfmt.Printf(\"xwayland_shell_v1_get_xwayland_surface: surface not found\\n\")\n\t\tSendError(\n\t\t\ts,\n\t\t\tobject_id,\n\t\t\tprotocols.XwaylandShellV1Error_enum_role,\n\t\t\t\"surface not found\",\n\t\t)\n\t\treturn\n\t}\n\n\tif surface.Role == nil {\n\t\tsurface.Role = &SurfaceRoleXWaylandSurface{}\n\t}\n\n\tsurfaceRole, ok := surface.Role.(*SurfaceRoleXWaylandSurface)\n\tif !ok {\n\t\tfmt.Printf(\"xwayland_shell_v1_get_xwayland_surface: surface has wrong role type\\n\")\n\t\tSendError(\n\t\t\ts,\n\t\t\tobject_id,\n\t\t\tprotocols.XwaylandShellV1Error_enum_role,\n\t\t\t\"surface already has a role\",\n\t\t)\n\t\treturn\n\t}\n\n\txwayland_surface := surfaceRole.Data\n\tif xwayland_surface != nil {\n\t\tSendError(\n\t\t\ts,\n\t\t\tobject_id,\n\t\t\tprotocols.XwaylandShellV1Error_enum_role,\n\t\t\t\"surface already has a role\",\n\t\t)\n\t\treturn\n\t}\n\tAddObject(s, id, MakeXwaylandSurfaceV1())\n}\n\nfunc (x *XwaylandShellV1) OnBind(\n\t_s protocols.ClientState,\n\t_name protocols.AnyObjectID,\n\t_interface_ string,\n\t_new_id protocols.AnyObjectID,\n\t_version_number uint32,\n) {\n}\n\nfunc MakeXwaylandShellV1() *protocols.XwaylandShellV1 {\n\treturn &protocols.XwaylandShellV1{\n\t\tDelegate: &XwaylandShellV1{},\n\t}\n}\n"
  },
  {
    "path": "wayland/xwayland_surface_v1.go",
    "content": "package wayland\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/mmulet/term.everything/wayland/protocols\"\n)\n\ntype XwaylandSurfaceV1 struct {\n}\n\nfunc (x *XwaylandSurfaceV1) XwaylandSurfaceV1_set_serial(\n\t_s protocols.ClientState,\n\t_object_id protocols.ObjectID[protocols.XwaylandSurfaceV1],\n\t_serial_lo uint32,\n\t_serial_hi uint32,\n) {\n\t/** @TODO: Implement XwaylandSurfaceV1_set_serial */\n}\n\nfunc (x *XwaylandSurfaceV1) XwaylandSurfaceV1_destroy(\n\ts protocols.ClientState,\n\tobject_id protocols.ObjectID[protocols.XwaylandSurfaceV1],\n) bool {\n\tsurface := GetSurfaceFromRole(s, object_id)\n\n\tif surface == nil || surface.Role == nil {\n\t\tfmt.Printf(\"XwaylandSurfaceV1_destroy: surface not found\")\n\t\treturn true\n\t}\n\tif role, ok := surface.Role.(*SurfaceRoleXWaylandSurface); ok {\n\t\trole.Data = nil\n\t}\n\treturn true\n}\n\nfunc (x *XwaylandSurfaceV1) XwaylandSurfaceV1_on_bind(\n\t_s protocols.ClientState,\n\t_name protocols.AnyObjectID,\n\t_interface_ string,\n\t_new_id protocols.AnyObjectID,\n\t_version_number uint32,\n) {\n}\n\nfunc (x *XwaylandSurfaceV1) OnBind(\n\tcs protocols.ClientState,\n\t_ protocols.AnyObjectID,\n\t_ string,\n\tnewId_any protocols.AnyObjectID,\n\tversion uint32,\n) {\n}\n\nfunc MakeXwaylandSurfaceV1() *protocols.XwaylandSurfaceV1 {\n\treturn &protocols.XwaylandSurfaceV1{\n\t\tDelegate: &XwaylandSurfaceV1{},\n\t}\n}\n"
  },
  {
    "path": "wayland/zwp_xwayland_keyboard_grab_manager_v1.go",
    "content": "package wayland\n\nimport (\n\t\"github.com/mmulet/term.everything/wayland/protocols\"\n)\n\ntype ZwpXwaylandKeyboardGrabManagerV1 struct {\n}\n\nfunc (m *ZwpXwaylandKeyboardGrabManagerV1) ZwpXwaylandKeyboardGrabManagerV1_destroy(\n\ts protocols.ClientState,\n\tobject_id protocols.ObjectID[protocols.ZwpXwaylandKeyboardGrabManagerV1],\n) bool {\n\ts.RemoveGlobalZwpXwaylandKeyboardGrabManagerV1Bind(object_id)\n\treturn true\n}\n\nfunc (m *ZwpXwaylandKeyboardGrabManagerV1) ZwpXwaylandKeyboardGrabManagerV1_grab_keyboard(\n\ts protocols.ClientState,\n\t_object_id protocols.ObjectID[protocols.ZwpXwaylandKeyboardGrabManagerV1],\n\tid protocols.ObjectID[protocols.ZwpXwaylandKeyboardGrabV1],\n\t_surface protocols.ObjectID[protocols.WlSurface],\n\t_seat protocols.ObjectID[protocols.WlSeat],\n) {\n\tAddObject(s, id, MakeZwpXwaylandKeyboardGrabV1())\n\t/**\n\t * @TODO grab the keyboard\n\t */\n}\n\nfunc (m *ZwpXwaylandKeyboardGrabManagerV1) OnBind(\n\t_s protocols.ClientState,\n\t_name protocols.AnyObjectID,\n\t_interface_ string,\n\t_new_id protocols.AnyObjectID,\n\t_version_number uint32,\n) {\n}\n\nfunc MakeZwpXwaylandKeyboardGrabManagerV1() *protocols.ZwpXwaylandKeyboardGrabManagerV1 {\n\treturn &protocols.ZwpXwaylandKeyboardGrabManagerV1{\n\t\tDelegate: &ZwpXwaylandKeyboardGrabManagerV1{},\n\t}\n}\n"
  },
  {
    "path": "wayland/zwp_xwayland_keyboard_grab_v1.go",
    "content": "package wayland\n\nimport (\n\t\"github.com/mmulet/term.everything/wayland/protocols\"\n)\n\ntype ZwpXwaylandKeyboardGrabV1 struct {\n}\n\nfunc (g *ZwpXwaylandKeyboardGrabV1) ZwpXwaylandKeyboardGrabV1_destroy(\n\t_ protocols.ClientState,\n\t_ protocols.ObjectID[protocols.ZwpXwaylandKeyboardGrabV1],\n) bool {\n\t/**\n\t * @TODO ungrab the keyboard\n\t */\n\treturn true\n}\n\nfunc (g *ZwpXwaylandKeyboardGrabV1) OnBind(\n\t_ protocols.ClientState,\n\t_ protocols.AnyObjectID,\n\t_ string,\n\t_ protocols.AnyObjectID,\n\t_ uint32,\n) {\n}\n\nfunc MakeZwpXwaylandKeyboardGrabV1() *protocols.ZwpXwaylandKeyboardGrabV1 {\n\treturn &protocols.ZwpXwaylandKeyboardGrabV1{\n\t\tDelegate: &ZwpXwaylandKeyboardGrabV1{},\n\t}\n}\n"
  },
  {
    "path": "wayland/zxdg_decoration_manager_v1.go",
    "content": "package wayland\n\nimport (\n\t\"github.com/mmulet/term.everything/wayland/protocols\"\n)\n\ntype ZxdgDecorationManagerV1 struct{}\n\nfunc (z *ZxdgDecorationManagerV1) ZxdgDecorationManagerV1_destroy(\n\ts protocols.ClientState,\n\tobject_id protocols.ObjectID[protocols.ZxdgDecorationManagerV1],\n) bool {\n\treturn true\n}\n\nfunc (z *ZxdgDecorationManagerV1) ZxdgDecorationManagerV1_get_toplevel_decoration(\n\ts protocols.ClientState,\n\t_ protocols.ObjectID[protocols.ZxdgDecorationManagerV1],\n\tdecoration_id protocols.ObjectID[protocols.ZxdgToplevelDecorationV1],\n\ttoplevel protocols.ObjectID[protocols.XdgToplevel],\n) {\n\tAddObject(s, decoration_id, MakeZxdgToplevelDecorationV1(toplevel))\n\tprotocols.ZxdgToplevelDecorationV1_configure(s, decoration_id, protocols.ZxdgToplevelDecorationV1Mode_enum_server_side)\n}\n\nfunc (z *ZxdgDecorationManagerV1) OnBind(\n\t_ protocols.ClientState,\n\t_ protocols.AnyObjectID,\n\t_ string,\n\t_ protocols.AnyObjectID,\n\t_ uint32,\n) {\n\t// no-op\n}\n\nfunc MakeZxdgDecorationManagerV1() *protocols.ZxdgDecorationManagerV1 {\n\treturn &protocols.ZxdgDecorationManagerV1{\n\t\tDelegate: &ZxdgDecorationManagerV1{},\n\t}\n}\n"
  },
  {
    "path": "wayland/zxdg_toplevel_decoration_v1.go",
    "content": "package wayland\n\nimport (\n\t\"github.com/mmulet/term.everything/wayland/protocols\"\n)\n\ntype ZxdgToplevelDecorationV1 struct {\n\tXdgToplevel protocols.ObjectID[protocols.XdgToplevel]\n}\n\nfunc (z *ZxdgToplevelDecorationV1) ZxdgToplevelDecorationV1_destroy(\n\t_ protocols.ClientState,\n\t_ protocols.ObjectID[protocols.ZxdgToplevelDecorationV1],\n) bool {\n\treturn true\n}\n\nfunc (z *ZxdgToplevelDecorationV1) ZxdgToplevelDecorationV1_set_mode(\n\ts protocols.ClientState,\n\t_ protocols.ObjectID[protocols.ZxdgToplevelDecorationV1],\n\t_mode protocols.ZxdgToplevelDecorationV1Mode_enum,\n) {\n\tsurface := GetSurfaceFromRole(s, z.XdgToplevel)\n\tif surface == nil {\n\t\treturn\n\t}\n\tif surface.XdgSurfaceState == nil {\n\t\treturn\n\t}\n\txdgSurf := GetXdgSurfaceObject(s, *surface.XdgSurfaceState)\n\tif xdgSurf == nil {\n\t\treturn\n\t}\n\txdgSurfaceID := xdgSurf.XdgSurfaceID\n\txdgSurf.LatestSerial += 1\n\tprotocols.XdgSurface_configure(s, xdgSurfaceID, xdgSurf.LatestSerial)\n}\n\nfunc (z *ZxdgToplevelDecorationV1) ZxdgToplevelDecorationV1_unset_mode(\n\ts protocols.ClientState,\n\t_ protocols.ObjectID[protocols.ZxdgToplevelDecorationV1],\n) {\n\tsurface := GetSurfaceFromRole(s, z.XdgToplevel)\n\tif surface == nil {\n\t\treturn\n\t}\n\tif surface.XdgSurfaceState == nil {\n\t\treturn\n\t}\n\txdgSurf := GetXdgSurfaceObject(s, *surface.XdgSurfaceState)\n\tif xdgSurf == nil {\n\t\treturn\n\t}\n\txdgSurfaceID := xdgSurf.XdgSurfaceID\n\txdgSurf.LatestSerial += 1\n\tprotocols.XdgSurface_configure(s, xdgSurfaceID, xdgSurf.LatestSerial)\n}\n\nfunc (z *ZxdgToplevelDecorationV1) OnBind(\n\t_ protocols.ClientState,\n\t_ protocols.AnyObjectID,\n\t_ string,\n\t_ protocols.AnyObjectID,\n\t_ uint32,\n) {\n\t// no-op\n}\n\nfunc MakeZxdgToplevelDecorationV1(xdgToplevel protocols.ObjectID[protocols.XdgToplevel]) *protocols.ZxdgToplevelDecorationV1 {\n\treturn &protocols.ZxdgToplevelDecorationV1{\n\t\tDelegate: &ZxdgToplevelDecorationV1{\n\t\t\tXdgToplevel: xdgToplevel,\n\t\t},\n\t}\n}\n"
  }
]