From 59f0ec4867396e10e84f55846d900b49b15b1a2c Mon Sep 17 00:00:00 2001 From: Jonathan DeMasi Date: Wed, 25 Feb 2026 22:11:22 -0700 Subject: [PATCH] init --- LICENSE | 793 +++++++ Makefile | 55 + README.md | 3 + config.def.h | 43 + config.h | 43 + dwl-ipc-unstable-v2-protocol.c | 71 + dwl-ipc-unstable-v2-protocol.h | 483 +++++ dwl-ipc-unstable-v2-protocol.o | Bin 0 -> 7048 bytes dwlb.1 | 324 +++ dwlb.c | 2006 +++++++++++++++++ dwlb.o | Bin 0 -> 146200 bytes protocols/dwl-ipc-unstable-v2.xml | 181 ++ protocols/wlr-layer-shell-unstable-v1.xml | 390 ++++ screenshot1.png | Bin 0 -> 18524 bytes screenshot2.png | Bin 0 -> 17753 bytes utf8.h | 55 + wlr-layer-shell-unstable-v1-protocol.c | 94 + wlr-layer-shell-unstable-v1-protocol.h | 706 ++++++ wlr-layer-shell-unstable-v1-protocol.o | Bin 0 -> 6728 bytes xdg-output-unstable-v1-protocol.c | 79 + xdg-output-unstable-v1-protocol.h | 415 ++++ xdg-output-unstable-v1-protocol.o | Bin 0 -> 5856 bytes xdg-shell-protocol.c | 184 ++ xdg-shell-protocol.h | 2384 +++++++++++++++++++++ xdg-shell-protocol.o | Bin 0 -> 11872 bytes 25 files changed, 8309 insertions(+) create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 README.md create mode 100644 config.def.h create mode 100644 config.h create mode 100644 dwl-ipc-unstable-v2-protocol.c create mode 100644 dwl-ipc-unstable-v2-protocol.h create mode 100644 dwl-ipc-unstable-v2-protocol.o create mode 100644 dwlb.1 create mode 100644 dwlb.c create mode 100644 dwlb.o create mode 100644 protocols/dwl-ipc-unstable-v2.xml create mode 100644 protocols/wlr-layer-shell-unstable-v1.xml create mode 100644 screenshot1.png create mode 100644 screenshot2.png create mode 100644 utf8.h create mode 100644 wlr-layer-shell-unstable-v1-protocol.c create mode 100644 wlr-layer-shell-unstable-v1-protocol.h create mode 100644 wlr-layer-shell-unstable-v1-protocol.o create mode 100644 xdg-output-unstable-v1-protocol.c create mode 100644 xdg-output-unstable-v1-protocol.h create mode 100644 xdg-output-unstable-v1-protocol.o create mode 100644 xdg-shell-protocol.c create mode 100644 xdg-shell-protocol.h create mode 100644 xdg-shell-protocol.o diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..ec87e85 --- /dev/null +++ b/LICENSE @@ -0,0 +1,793 @@ +dwlb - bar for dwl + +Copyright © 2023 kolunmi + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +--- + +dtao - dzen for Wayland + +Copyright © 2021 Devin J. Pohly and dtao team + +See also the license information in dtao.c. + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +---- + +Portions of the code labeled [dzen] are derived from the original dzen2 and +used under the following license: + +MIT/X Consortium License + +(C)opyright MMVII Robert Manea + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +---- + +Portions of the code labeled [wlroots] are derived from wlroots and used under +the following license: + +Copyright (c) 2017, 2018 Drew DeVault +Copyright (c) 2014 Jari Vetoniemi + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +---- + +Portions of the code labeled [swaywm] are derived from sway and are used under +the following license: + +Copyright (c) 2016-2017 Drew DeVault + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +---- + +Portions of the code labeled [wayland-book] are derived from example code found +in The Wayland Protocol by Drew DeVault (https://wayland-book.com/). The book +is available under CC-BY-SA 4.0, and the author indicates that code examples may +be used under CC0. + +---- + + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is 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. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When 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. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "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. + + To "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. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "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. + + To "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. + + An 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. + + 1. Source Code. + + The "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. + + A "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. + + The "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. + + The "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. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All 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. + + You 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. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No 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. + + When 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. + + 4. Conveying Verbatim Copies. + + You 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. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You 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: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + 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". + + 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. + + 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. + + A 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. + + 6. Conveying Non-Source Forms. + + You 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: + + 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. + + 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. + + 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. + + 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. + + 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. + + A 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. + + A "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. + + "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. + + If 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). + + The 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. + + Corresponding 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. + + 7. Additional Terms. + + "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. + + When 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. + + Notwithstanding 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: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + 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 + + 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 + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + 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. + + All 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. + + If 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. + + Additional 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. + + 8. Termination. + + You 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). + + However, 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. + + Moreover, 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. + + Termination 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. + + 9. Acceptance Not Required for Having Copies. + + You 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. + + 10. Automatic Licensing of Downstream Recipients. + + Each 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. + + An "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. + + You 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. + + 11. Patents. + + A "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". + + A 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. + + Each 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. + + In 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. + + If 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. + + If, 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. + + A 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. + + Nothing 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. + + 12. No Surrender of Others' Freedom. + + If 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. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding 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 Affero 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 special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU 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. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU 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 General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU 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. + + Later 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. + + 15. Disclaimer of Warranty. + + THERE 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. + + 16. Limitation of Liability. + + IN 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. + + 17. Interpretation of Sections 15 and 16. + + If 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. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If 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. + + To 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. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You 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 GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..52d2f2d --- /dev/null +++ b/Makefile @@ -0,0 +1,55 @@ +BINS = dwlb +MANS = dwlb.1 + +PREFIX ?= /usr/local +CFLAGS += -Wall -Wextra -Wno-unused-parameter -Wno-format-truncation -g + +all: $(BINS) + +config.h: + cp config.def.h $@ + +clean: + $(RM) $(BINS) $(addsuffix .o,$(BINS)) + +install: all + install -D -t $(PREFIX)/bin $(BINS) + install -D -m0644 -t $(PREFIX)/share/man/man1 $(MANS) + +WAYLAND_PROTOCOLS=$(shell pkg-config --variable=pkgdatadir wayland-protocols) +WAYLAND_SCANNER=$(shell pkg-config --variable=wayland_scanner wayland-scanner) + +xdg-shell-protocol.h: + $(WAYLAND_SCANNER) client-header $(WAYLAND_PROTOCOLS)/stable/xdg-shell/xdg-shell.xml $@ +xdg-shell-protocol.c: + $(WAYLAND_SCANNER) private-code $(WAYLAND_PROTOCOLS)/stable/xdg-shell/xdg-shell.xml $@ +xdg-shell-protocol.o: xdg-shell-protocol.h + +xdg-output-unstable-v1-protocol.h: + $(WAYLAND_SCANNER) client-header $(WAYLAND_PROTOCOLS)/unstable/xdg-output/xdg-output-unstable-v1.xml $@ +xdg-output-unstable-v1-protocol.c: + $(WAYLAND_SCANNER) private-code $(WAYLAND_PROTOCOLS)/unstable/xdg-output/xdg-output-unstable-v1.xml $@ +xdg-output-unstable-v1-protocol.o: xdg-output-unstable-v1-protocol.h + +wlr-layer-shell-unstable-v1-protocol.h: + $(WAYLAND_SCANNER) client-header protocols/wlr-layer-shell-unstable-v1.xml $@ +wlr-layer-shell-unstable-v1-protocol.c: + $(WAYLAND_SCANNER) private-code protocols/wlr-layer-shell-unstable-v1.xml $@ +wlr-layer-shell-unstable-v1-protocol.o: wlr-layer-shell-unstable-v1-protocol.h + +dwl-ipc-unstable-v2-protocol.h: + $(WAYLAND_SCANNER) client-header protocols/dwl-ipc-unstable-v2.xml $@ +dwl-ipc-unstable-v2-protocol.c: + $(WAYLAND_SCANNER) private-code protocols/dwl-ipc-unstable-v2.xml $@ +dwl-ipc-unstable-v2-protocol.o: dwl-ipc-unstable-v2-protocol.h + +dwlb.o: utf8.h config.h xdg-shell-protocol.h xdg-output-unstable-v1-protocol.h wlr-layer-shell-unstable-v1-protocol.h dwl-ipc-unstable-v2-protocol.h + +# Protocol dependencies +dwlb: xdg-shell-protocol.o xdg-output-unstable-v1-protocol.o wlr-layer-shell-unstable-v1-protocol.o dwl-ipc-unstable-v2-protocol.o + +# Library dependencies +dwlb: CFLAGS+=$(shell pkg-config --cflags wayland-client wayland-cursor fcft pixman-1) +dwlb: LDLIBS+=$(shell pkg-config --libs wayland-client wayland-cursor fcft pixman-1) -lrt + +.PHONY: all clean install diff --git a/README.md b/README.md new file mode 100644 index 0000000..12f648b --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# dwlb + +My config for dwlb - very simple, functional. No reliance on ipc diff --git a/config.def.h b/config.def.h new file mode 100644 index 0000000..131a857 --- /dev/null +++ b/config.def.h @@ -0,0 +1,43 @@ +#define HEX_COLOR(hex) \ + { .red = ((hex >> 24) & 0xff) * 257, \ + .green = ((hex >> 16) & 0xff) * 257, \ + .blue = ((hex >> 8) & 0xff) * 257, \ + .alpha = (hex & 0xff) * 257 } + +// use ipc functionality +static bool ipc = false; +// initially hide all bars +static bool hidden = false; +// initially draw all bars at the bottom +static bool bottom = false; +// hide vacant tags +static bool hide_vacant = false; +// vertical pixel padding above and below text +static uint32_t vertical_padding = 1; +// allow in-line color commands in status text +static bool status_commands = true; +// center title text +static bool center_title = false; +// use title space as status text element +static bool custom_title = false; +// title color use active colors +static bool active_color_title = true; +// scale +static uint32_t buffer_scale = 1; +// font +static char *fontstr = "monospace:size=16"; +// tag names +static char *tags_names[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; + +// set 16-bit colors for bar +// use either pixman_color_t struct or HEX_COLOR macro for 8-bit colors +static pixman_color_t active_fg_color = HEX_COLOR(0xeeeeeeff); +static pixman_color_t active_bg_color = HEX_COLOR(0x005577ff); +static pixman_color_t occupied_fg_color = HEX_COLOR(0xeeeeeeff); +static pixman_color_t occupied_bg_color = HEX_COLOR(0x005577ff); +static pixman_color_t inactive_fg_color = HEX_COLOR(0xbbbbbbff); +static pixman_color_t inactive_bg_color = HEX_COLOR(0x222222ff); +static pixman_color_t urgent_fg_color = HEX_COLOR(0x222222ff); +static pixman_color_t urgent_bg_color = HEX_COLOR(0xeeeeeeff); +static pixman_color_t middle_bg_color = HEX_COLOR(0x222222ff); +static pixman_color_t middle_bg_color_selected = HEX_COLOR(0x005577ff); diff --git a/config.h b/config.h new file mode 100644 index 0000000..99f8d73 --- /dev/null +++ b/config.h @@ -0,0 +1,43 @@ +#define HEX_COLOR(hex) \ + { .red = ((hex >> 24) & 0xff) * 257, \ + .green = ((hex >> 16) & 0xff) * 257, \ + .blue = ((hex >> 8) & 0xff) * 257, \ + .alpha = (hex & 0xff) * 257 } + +// use ipc functionality +static bool ipc = false; +// initially hide all bars +static bool hidden = false; +// initially draw all bars at the bottom +static bool bottom = false; +// hide vacant tags +static bool hide_vacant = false; +// vertical pixel padding above and below text +static uint32_t vertical_padding = 1; +// allow in-line color commands in status text +static bool status_commands = true; +// center title text +static bool center_title = true; +// use title space as status text element +static bool custom_title = false; +// title color use active colors +static bool active_color_title = true; +// scale +static uint32_t buffer_scale = 1; +// font +static char *fontstr = "monospace:size=16"; +// tag names +static char *tags_names[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; + +// set 16-bit colors for bar +// use either pixman_color_t struct or HEX_COLOR macro for 8-bit colors +static pixman_color_t active_fg_color = HEX_COLOR(0xeeeeeeff); +static pixman_color_t active_bg_color = HEX_COLOR(0x005577ff); +static pixman_color_t occupied_fg_color = HEX_COLOR(0xeeeeeeff); +static pixman_color_t occupied_bg_color = HEX_COLOR(0x005577ff); +static pixman_color_t inactive_fg_color = HEX_COLOR(0xbbbbbbff); +static pixman_color_t inactive_bg_color = HEX_COLOR(0x222222ff); +static pixman_color_t urgent_fg_color = HEX_COLOR(0x222222ff); +static pixman_color_t urgent_bg_color = HEX_COLOR(0xeeeeeeff); +static pixman_color_t middle_bg_color = HEX_COLOR(0x222222ff); +static pixman_color_t middle_bg_color_selected = HEX_COLOR(0x005577ff); diff --git a/dwl-ipc-unstable-v2-protocol.c b/dwl-ipc-unstable-v2-protocol.c new file mode 100644 index 0000000..a2337e6 --- /dev/null +++ b/dwl-ipc-unstable-v2-protocol.c @@ -0,0 +1,71 @@ +/* Generated by wayland-scanner 1.24.0 */ + +#include +#include +#include +#include "wayland-util.h" + +#ifndef __has_attribute +# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */ +#endif + +#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4) +#define WL_PRIVATE __attribute__ ((visibility("hidden"))) +#else +#define WL_PRIVATE +#endif + +extern const struct wl_interface wl_output_interface; +extern const struct wl_interface zdwl_ipc_output_v2_interface; + +static const struct wl_interface *dwl_ipc_unstable_v2_types[] = { + NULL, + NULL, + NULL, + NULL, + &zdwl_ipc_output_v2_interface, + &wl_output_interface, +}; + +static const struct wl_message zdwl_ipc_manager_v2_requests[] = { + { "release", "", dwl_ipc_unstable_v2_types + 0 }, + { "get_output", "no", dwl_ipc_unstable_v2_types + 4 }, +}; + +static const struct wl_message zdwl_ipc_manager_v2_events[] = { + { "tags", "u", dwl_ipc_unstable_v2_types + 0 }, + { "layout", "s", dwl_ipc_unstable_v2_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface zdwl_ipc_manager_v2_interface = { + "zdwl_ipc_manager_v2", 2, + 2, zdwl_ipc_manager_v2_requests, + 2, zdwl_ipc_manager_v2_events, +}; + +static const struct wl_message zdwl_ipc_output_v2_requests[] = { + { "release", "", dwl_ipc_unstable_v2_types + 0 }, + { "set_tags", "uu", dwl_ipc_unstable_v2_types + 0 }, + { "set_client_tags", "uu", dwl_ipc_unstable_v2_types + 0 }, + { "set_layout", "u", dwl_ipc_unstable_v2_types + 0 }, +}; + +static const struct wl_message zdwl_ipc_output_v2_events[] = { + { "toggle_visibility", "", dwl_ipc_unstable_v2_types + 0 }, + { "active", "u", dwl_ipc_unstable_v2_types + 0 }, + { "tag", "uuuu", dwl_ipc_unstable_v2_types + 0 }, + { "layout", "u", dwl_ipc_unstable_v2_types + 0 }, + { "title", "s", dwl_ipc_unstable_v2_types + 0 }, + { "appid", "s", dwl_ipc_unstable_v2_types + 0 }, + { "layout_symbol", "s", dwl_ipc_unstable_v2_types + 0 }, + { "frame", "", dwl_ipc_unstable_v2_types + 0 }, + { "fullscreen", "2u", dwl_ipc_unstable_v2_types + 0 }, + { "floating", "2u", dwl_ipc_unstable_v2_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface zdwl_ipc_output_v2_interface = { + "zdwl_ipc_output_v2", 2, + 4, zdwl_ipc_output_v2_requests, + 10, zdwl_ipc_output_v2_events, +}; + diff --git a/dwl-ipc-unstable-v2-protocol.h b/dwl-ipc-unstable-v2-protocol.h new file mode 100644 index 0000000..bac1f23 --- /dev/null +++ b/dwl-ipc-unstable-v2-protocol.h @@ -0,0 +1,483 @@ +/* Generated by wayland-scanner 1.24.0 */ + +#ifndef DWL_IPC_UNSTABLE_V2_CLIENT_PROTOCOL_H +#define DWL_IPC_UNSTABLE_V2_CLIENT_PROTOCOL_H + +#include +#include +#include "wayland-client.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @page page_dwl_ipc_unstable_v2 The dwl_ipc_unstable_v2 protocol + * inter-proccess-communication about dwl's state + * + * @section page_desc_dwl_ipc_unstable_v2 Description + * + * This protocol allows clients to update and get updates from dwl. + * + * Warning! The protocol described in this file is experimental and + * backward incompatible changes may be made. Backward compatible + * changes may be added together with the corresponding interface + * version bump. + * Backward incompatible changes are done by bumping the version + * number in the protocol and interface names and resetting the + * interface version. Once the protocol is to be declared stable, + * the 'z' prefix and the version number in the protocol and + * interface names are removed and the interface version number is + * reset. + * + * @section page_ifaces_dwl_ipc_unstable_v2 Interfaces + * - @subpage page_iface_zdwl_ipc_manager_v2 - manage dwl state + * - @subpage page_iface_zdwl_ipc_output_v2 - control dwl output + */ +struct wl_output; +struct zdwl_ipc_manager_v2; +struct zdwl_ipc_output_v2; + +#ifndef ZDWL_IPC_MANAGER_V2_INTERFACE +#define ZDWL_IPC_MANAGER_V2_INTERFACE +/** + * @page page_iface_zdwl_ipc_manager_v2 zdwl_ipc_manager_v2 + * @section page_iface_zdwl_ipc_manager_v2_desc Description + * + * This interface is exposed as a global in wl_registry. + * + * Clients can use this interface to get a dwl_ipc_output. + * After binding the client will recieve the dwl_ipc_manager.tags and dwl_ipc_manager.layout events. + * The dwl_ipc_manager.tags and dwl_ipc_manager.layout events expose tags and layouts to the client. + * @section page_iface_zdwl_ipc_manager_v2_api API + * See @ref iface_zdwl_ipc_manager_v2. + */ +/** + * @defgroup iface_zdwl_ipc_manager_v2 The zdwl_ipc_manager_v2 interface + * + * This interface is exposed as a global in wl_registry. + * + * Clients can use this interface to get a dwl_ipc_output. + * After binding the client will recieve the dwl_ipc_manager.tags and dwl_ipc_manager.layout events. + * The dwl_ipc_manager.tags and dwl_ipc_manager.layout events expose tags and layouts to the client. + */ +extern const struct wl_interface zdwl_ipc_manager_v2_interface; +#endif +#ifndef ZDWL_IPC_OUTPUT_V2_INTERFACE +#define ZDWL_IPC_OUTPUT_V2_INTERFACE +/** + * @page page_iface_zdwl_ipc_output_v2 zdwl_ipc_output_v2 + * @section page_iface_zdwl_ipc_output_v2_desc Description + * + * Observe and control a dwl output. + * + * Events are double-buffered: + * Clients should cache events and redraw when a dwl_ipc_output.frame event is sent. + * + * Request are not double-buffered: + * The compositor will update immediately upon request. + * @section page_iface_zdwl_ipc_output_v2_api API + * See @ref iface_zdwl_ipc_output_v2. + */ +/** + * @defgroup iface_zdwl_ipc_output_v2 The zdwl_ipc_output_v2 interface + * + * Observe and control a dwl output. + * + * Events are double-buffered: + * Clients should cache events and redraw when a dwl_ipc_output.frame event is sent. + * + * Request are not double-buffered: + * The compositor will update immediately upon request. + */ +extern const struct wl_interface zdwl_ipc_output_v2_interface; +#endif + +/** + * @ingroup iface_zdwl_ipc_manager_v2 + * @struct zdwl_ipc_manager_v2_listener + */ +struct zdwl_ipc_manager_v2_listener { + /** + * Announces tag amount + * + * This event is sent after binding. A roundtrip after binding + * guarantees the client recieved all tags. + */ + void (*tags)(void *data, + struct zdwl_ipc_manager_v2 *zdwl_ipc_manager_v2, + uint32_t amount); + /** + * Announces a layout + * + * This event is sent after binding. A roundtrip after binding + * guarantees the client recieved all layouts. + */ + void (*layout)(void *data, + struct zdwl_ipc_manager_v2 *zdwl_ipc_manager_v2, + const char *name); +}; + +/** + * @ingroup iface_zdwl_ipc_manager_v2 + */ +static inline int +zdwl_ipc_manager_v2_add_listener(struct zdwl_ipc_manager_v2 *zdwl_ipc_manager_v2, + const struct zdwl_ipc_manager_v2_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) zdwl_ipc_manager_v2, + (void (**)(void)) listener, data); +} + +#define ZDWL_IPC_MANAGER_V2_RELEASE 0 +#define ZDWL_IPC_MANAGER_V2_GET_OUTPUT 1 + +/** + * @ingroup iface_zdwl_ipc_manager_v2 + */ +#define ZDWL_IPC_MANAGER_V2_TAGS_SINCE_VERSION 1 +/** + * @ingroup iface_zdwl_ipc_manager_v2 + */ +#define ZDWL_IPC_MANAGER_V2_LAYOUT_SINCE_VERSION 1 + +/** + * @ingroup iface_zdwl_ipc_manager_v2 + */ +#define ZDWL_IPC_MANAGER_V2_RELEASE_SINCE_VERSION 1 +/** + * @ingroup iface_zdwl_ipc_manager_v2 + */ +#define ZDWL_IPC_MANAGER_V2_GET_OUTPUT_SINCE_VERSION 1 + +/** @ingroup iface_zdwl_ipc_manager_v2 */ +static inline void +zdwl_ipc_manager_v2_set_user_data(struct zdwl_ipc_manager_v2 *zdwl_ipc_manager_v2, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) zdwl_ipc_manager_v2, user_data); +} + +/** @ingroup iface_zdwl_ipc_manager_v2 */ +static inline void * +zdwl_ipc_manager_v2_get_user_data(struct zdwl_ipc_manager_v2 *zdwl_ipc_manager_v2) +{ + return wl_proxy_get_user_data((struct wl_proxy *) zdwl_ipc_manager_v2); +} + +static inline uint32_t +zdwl_ipc_manager_v2_get_version(struct zdwl_ipc_manager_v2 *zdwl_ipc_manager_v2) +{ + return wl_proxy_get_version((struct wl_proxy *) zdwl_ipc_manager_v2); +} + +/** @ingroup iface_zdwl_ipc_manager_v2 */ +static inline void +zdwl_ipc_manager_v2_destroy(struct zdwl_ipc_manager_v2 *zdwl_ipc_manager_v2) +{ + wl_proxy_destroy((struct wl_proxy *) zdwl_ipc_manager_v2); +} + +/** + * @ingroup iface_zdwl_ipc_manager_v2 + * + * Indicates that the client will not the dwl_ipc_manager object anymore. + * Objects created through this instance are not affected. + */ +static inline void +zdwl_ipc_manager_v2_release(struct zdwl_ipc_manager_v2 *zdwl_ipc_manager_v2) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zdwl_ipc_manager_v2, + ZDWL_IPC_MANAGER_V2_RELEASE, NULL, wl_proxy_get_version((struct wl_proxy *) zdwl_ipc_manager_v2), WL_MARSHAL_FLAG_DESTROY); +} + +/** + * @ingroup iface_zdwl_ipc_manager_v2 + * + * Get a dwl_ipc_outout for the specified wl_output. + */ +static inline struct zdwl_ipc_output_v2 * +zdwl_ipc_manager_v2_get_output(struct zdwl_ipc_manager_v2 *zdwl_ipc_manager_v2, struct wl_output *output) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) zdwl_ipc_manager_v2, + ZDWL_IPC_MANAGER_V2_GET_OUTPUT, &zdwl_ipc_output_v2_interface, wl_proxy_get_version((struct wl_proxy *) zdwl_ipc_manager_v2), 0, NULL, output); + + return (struct zdwl_ipc_output_v2 *) id; +} + +#ifndef ZDWL_IPC_OUTPUT_V2_TAG_STATE_ENUM +#define ZDWL_IPC_OUTPUT_V2_TAG_STATE_ENUM +enum zdwl_ipc_output_v2_tag_state { + /** + * no state + */ + ZDWL_IPC_OUTPUT_V2_TAG_STATE_NONE = 0, + /** + * tag is active + */ + ZDWL_IPC_OUTPUT_V2_TAG_STATE_ACTIVE = 1, + /** + * tag has at least one urgent client + */ + ZDWL_IPC_OUTPUT_V2_TAG_STATE_URGENT = 2, +}; +#endif /* ZDWL_IPC_OUTPUT_V2_TAG_STATE_ENUM */ + +/** + * @ingroup iface_zdwl_ipc_output_v2 + * @struct zdwl_ipc_output_v2_listener + */ +struct zdwl_ipc_output_v2_listener { + /** + * Toggle client visibilty + * + * Indicates the client should hide or show themselves. If the + * client is visible then hide, if hidden then show. + */ + void (*toggle_visibility)(void *data, + struct zdwl_ipc_output_v2 *zdwl_ipc_output_v2); + /** + * Update the selected output. + * + * Indicates if the output is active. Zero is invalid, nonzero is + * valid. + */ + void (*active)(void *data, + struct zdwl_ipc_output_v2 *zdwl_ipc_output_v2, + uint32_t active); + /** + * Update the state of a tag. + * + * Indicates that a tag has been updated. + * @param tag Index of the tag + * @param state The state of the tag. + * @param clients The number of clients in the tag. + * @param focused If there is a focused client. Nonzero being valid, zero being invalid. + */ + void (*tag)(void *data, + struct zdwl_ipc_output_v2 *zdwl_ipc_output_v2, + uint32_t tag, + uint32_t state, + uint32_t clients, + uint32_t focused); + /** + * Update the layout. + * + * Indicates a new layout is selected. + * @param layout Index of the layout. + */ + void (*layout)(void *data, + struct zdwl_ipc_output_v2 *zdwl_ipc_output_v2, + uint32_t layout); + /** + * Update the title. + * + * Indicates the title has changed. + * @param title The new title name. + */ + void (*title)(void *data, + struct zdwl_ipc_output_v2 *zdwl_ipc_output_v2, + const char *title); + /** + * Update the appid. + * + * Indicates the appid has changed. + * @param appid The new appid. + */ + void (*appid)(void *data, + struct zdwl_ipc_output_v2 *zdwl_ipc_output_v2, + const char *appid); + /** + * Update the current layout symbol + * + * Indicates the layout has changed. Since layout symbols are + * dynamic. As opposed to the zdwl_ipc_manager.layout event, this + * should take precendence when displaying. You can ignore the + * zdwl_ipc_output.layout event. + * @param layout The new layout + */ + void (*layout_symbol)(void *data, + struct zdwl_ipc_output_v2 *zdwl_ipc_output_v2, + const char *layout); + /** + * The update sequence is done. + * + * Indicates that a sequence of status updates have finished and + * the client should redraw. + */ + void (*frame)(void *data, + struct zdwl_ipc_output_v2 *zdwl_ipc_output_v2); + /** + * Update fullscreen status + * + * Indicates if the selected client on this output is fullscreen. + * @param is_fullscreen If the selected client is fullscreen. Nonzero is valid, zero invalid + * @since 2 + */ + void (*fullscreen)(void *data, + struct zdwl_ipc_output_v2 *zdwl_ipc_output_v2, + uint32_t is_fullscreen); + /** + * Update the floating status + * + * Indicates if the selected client on this output is floating. + * @param is_floating If the selected client is floating. Nonzero is valid, zero invalid + * @since 2 + */ + void (*floating)(void *data, + struct zdwl_ipc_output_v2 *zdwl_ipc_output_v2, + uint32_t is_floating); +}; + +/** + * @ingroup iface_zdwl_ipc_output_v2 + */ +static inline int +zdwl_ipc_output_v2_add_listener(struct zdwl_ipc_output_v2 *zdwl_ipc_output_v2, + const struct zdwl_ipc_output_v2_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) zdwl_ipc_output_v2, + (void (**)(void)) listener, data); +} + +#define ZDWL_IPC_OUTPUT_V2_RELEASE 0 +#define ZDWL_IPC_OUTPUT_V2_SET_TAGS 1 +#define ZDWL_IPC_OUTPUT_V2_SET_CLIENT_TAGS 2 +#define ZDWL_IPC_OUTPUT_V2_SET_LAYOUT 3 + +/** + * @ingroup iface_zdwl_ipc_output_v2 + */ +#define ZDWL_IPC_OUTPUT_V2_TOGGLE_VISIBILITY_SINCE_VERSION 1 +/** + * @ingroup iface_zdwl_ipc_output_v2 + */ +#define ZDWL_IPC_OUTPUT_V2_ACTIVE_SINCE_VERSION 1 +/** + * @ingroup iface_zdwl_ipc_output_v2 + */ +#define ZDWL_IPC_OUTPUT_V2_TAG_SINCE_VERSION 1 +/** + * @ingroup iface_zdwl_ipc_output_v2 + */ +#define ZDWL_IPC_OUTPUT_V2_LAYOUT_SINCE_VERSION 1 +/** + * @ingroup iface_zdwl_ipc_output_v2 + */ +#define ZDWL_IPC_OUTPUT_V2_TITLE_SINCE_VERSION 1 +/** + * @ingroup iface_zdwl_ipc_output_v2 + */ +#define ZDWL_IPC_OUTPUT_V2_APPID_SINCE_VERSION 1 +/** + * @ingroup iface_zdwl_ipc_output_v2 + */ +#define ZDWL_IPC_OUTPUT_V2_LAYOUT_SYMBOL_SINCE_VERSION 1 +/** + * @ingroup iface_zdwl_ipc_output_v2 + */ +#define ZDWL_IPC_OUTPUT_V2_FRAME_SINCE_VERSION 1 +/** + * @ingroup iface_zdwl_ipc_output_v2 + */ +#define ZDWL_IPC_OUTPUT_V2_FULLSCREEN_SINCE_VERSION 2 +/** + * @ingroup iface_zdwl_ipc_output_v2 + */ +#define ZDWL_IPC_OUTPUT_V2_FLOATING_SINCE_VERSION 2 + +/** + * @ingroup iface_zdwl_ipc_output_v2 + */ +#define ZDWL_IPC_OUTPUT_V2_RELEASE_SINCE_VERSION 1 +/** + * @ingroup iface_zdwl_ipc_output_v2 + */ +#define ZDWL_IPC_OUTPUT_V2_SET_TAGS_SINCE_VERSION 1 +/** + * @ingroup iface_zdwl_ipc_output_v2 + */ +#define ZDWL_IPC_OUTPUT_V2_SET_CLIENT_TAGS_SINCE_VERSION 1 +/** + * @ingroup iface_zdwl_ipc_output_v2 + */ +#define ZDWL_IPC_OUTPUT_V2_SET_LAYOUT_SINCE_VERSION 1 + +/** @ingroup iface_zdwl_ipc_output_v2 */ +static inline void +zdwl_ipc_output_v2_set_user_data(struct zdwl_ipc_output_v2 *zdwl_ipc_output_v2, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) zdwl_ipc_output_v2, user_data); +} + +/** @ingroup iface_zdwl_ipc_output_v2 */ +static inline void * +zdwl_ipc_output_v2_get_user_data(struct zdwl_ipc_output_v2 *zdwl_ipc_output_v2) +{ + return wl_proxy_get_user_data((struct wl_proxy *) zdwl_ipc_output_v2); +} + +static inline uint32_t +zdwl_ipc_output_v2_get_version(struct zdwl_ipc_output_v2 *zdwl_ipc_output_v2) +{ + return wl_proxy_get_version((struct wl_proxy *) zdwl_ipc_output_v2); +} + +/** @ingroup iface_zdwl_ipc_output_v2 */ +static inline void +zdwl_ipc_output_v2_destroy(struct zdwl_ipc_output_v2 *zdwl_ipc_output_v2) +{ + wl_proxy_destroy((struct wl_proxy *) zdwl_ipc_output_v2); +} + +/** + * @ingroup iface_zdwl_ipc_output_v2 + * + * Indicates to that the client no longer needs this dwl_ipc_output. + */ +static inline void +zdwl_ipc_output_v2_release(struct zdwl_ipc_output_v2 *zdwl_ipc_output_v2) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zdwl_ipc_output_v2, + ZDWL_IPC_OUTPUT_V2_RELEASE, NULL, wl_proxy_get_version((struct wl_proxy *) zdwl_ipc_output_v2), WL_MARSHAL_FLAG_DESTROY); +} + +/** + * @ingroup iface_zdwl_ipc_output_v2 + */ +static inline void +zdwl_ipc_output_v2_set_tags(struct zdwl_ipc_output_v2 *zdwl_ipc_output_v2, uint32_t tagmask, uint32_t toggle_tagset) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zdwl_ipc_output_v2, + ZDWL_IPC_OUTPUT_V2_SET_TAGS, NULL, wl_proxy_get_version((struct wl_proxy *) zdwl_ipc_output_v2), 0, tagmask, toggle_tagset); +} + +/** + * @ingroup iface_zdwl_ipc_output_v2 + * + * The tags are updated as follows: + * new_tags = (current_tags AND and_tags) XOR xor_tags + */ +static inline void +zdwl_ipc_output_v2_set_client_tags(struct zdwl_ipc_output_v2 *zdwl_ipc_output_v2, uint32_t and_tags, uint32_t xor_tags) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zdwl_ipc_output_v2, + ZDWL_IPC_OUTPUT_V2_SET_CLIENT_TAGS, NULL, wl_proxy_get_version((struct wl_proxy *) zdwl_ipc_output_v2), 0, and_tags, xor_tags); +} + +/** + * @ingroup iface_zdwl_ipc_output_v2 + */ +static inline void +zdwl_ipc_output_v2_set_layout(struct zdwl_ipc_output_v2 *zdwl_ipc_output_v2, uint32_t index) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zdwl_ipc_output_v2, + ZDWL_IPC_OUTPUT_V2_SET_LAYOUT, NULL, wl_proxy_get_version((struct wl_proxy *) zdwl_ipc_output_v2), 0, index); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/dwl-ipc-unstable-v2-protocol.o b/dwl-ipc-unstable-v2-protocol.o new file mode 100644 index 0000000000000000000000000000000000000000..cec3b61d6cb779e5665fe7c6ebf3a713a3eb4399 GIT binary patch literal 7048 zcmeHLdr*|u6~DWyh{$7cP*9>SY7`RKBE)A#!$Sp>Pz(~aHtc@8e7kO4cGul+d1w;Q zF^GZ&Ypv8^gN_Pg+h7=Nqjnk;jf}4t?Za0SYt?3~6OATn)Ha>7d(Q6l1}2&IpZw9^ z%+B|n-~F9)&v)NSfNLCN?GP_je^eW85mX=o74K|nAP$oGftL!$Er!kML82mb~@7-*-$quBT z44oCH)oPaw{)Y^7ME!BbUca@v{2EtSd4 z;`qCsIjq5){Aoi<-yf(M^Zf{5{~zBUK!5b%(h1|<0W{}y*l}c6 zHgAwjMx$)JYGi7?HsSb9{Rby%!s8~N%Z!;gV6mm7f8)`x=#_=qEe-j`ryG*BYt~1M z>|S%&T#yxar2CM1oF=P(P15enf$7>fy+_XV1HENB<&(!Yu z>C%+(CAq0t#qVdG`KtEC0q@)$)^t*1scw9^-!IgbYIXhWn)8OvD`DX$ax!*4t2+N{ zoo7MjsVjYwwCW`XlO=6^#P-pw?)=8gp>drh(Z%H~X+^(L@wpXA`O%{^o@W{(UQTK) zT(fOpa$CcgZq2>5wVV6w+}diaO-oO`wPMJwR##Zjwb-Uv1tHhRrf%FBW+5eFabk_uJz-2##mn#%F>~;RjNmk5%7S|Q2B@vff=h-jZjBv0zv#=O5Yp# zjqy=7=eWB|7k;(qfy(;S=A{?13#NYY=Y^-jkAzu12#sC&=)uFRn-@;~apIo(@_8@q z2^qA5-E95W%^kz`C}A6y>v9q_ua2&ZnRjOF(1C*@XLg<_y_DIo&wOjcj1{ipq38DA zU(=+y@oM~nLrrV9UfW-^{LA4HhL%fRrhjPunq7Tm$mlOW&R*YoOEq%wYsbbf)SUeH zuf8hikoP>lVc}1|Ub6GtOOJk5|JH|(^&R!cLlb`VX8igyj~LYjX&=kUFCd(yAhZuwou;RUhN z+RK*J8J2B2SQBWEz1U9FK9$XHG+d0R(S@^D+9oVXC>kD}U)Dcn^~Hbox#KZZtjcSz zYYkg4^5Ce8CFYN6rQHjsW$1_Re{R&#=+7c%6&JPt{$by0^UdFw27fs9@Oj(muF>~fudDvBIxCUoWM@y&CFT?qC+WtG*Qe>n>C#fuCZwjNPWH`hov(`-%PA;kYNqPs z=er7R%Ck2>c^~%q*FBYMo>)QrfI3wipUOFESO{kYp<(@k24adYPLQWK^N{!N`7FS@ zk?%x*BRic-3#_Y& z$RA;>$0+AfUxPZ*v(gHCip^zC@j5(;WU|XC*Vn|y%}tbmNMICLdFjT{*70ODiN=JSC#q@!_5dOES@q95_F zd;<#c2|SG8r|+S8M{x+2{p5kWm%zhrOyez{ z)APIZ2#yb@Z)J>);dqGu2HMXFJhd;aLzK^4%qL6GSD>9I@SD)4^_=3UF%GRO0Uq0{ zM2NEk^|HW!j{FjVk3zmu;B9Er{HA&jBVQ}%?_r#JfzL$y=K{YO_1grV@Q%R0je0l- z0Vtmrkf;5Ec#3~X(C4F`_65?9LH-Lt??ju{f6}L;J{+IKA4h$Pz@I^WqQK`PKS$tq zA^!^U@ZjgyGC>dZ16FZ*eqW~bkn%i!-e zl>6ke$!j&(92O_j``;y#$t{;ZQ7pM7hgA;L;B&Ft95T6h6gRyB?YGU&vNGABFulX6 z$oiau;uMb}nHQsNb$InIx6>uNl`8!9{{^rf!w{hUBhdI0fx{($1oRL7@8HLG^@s5W zd&__8Kki%Vr}0Ff^F1LM_faul9S&mhhrh95|D=78?isM(K%4Mu0>Fh8oT7>lV*9~; z0=RE{KMHe&z+(Q{z2skr`M2QW1Np-(UCbZuA-<}p08xht(f&^mWWIR|?IO0{ZCo65 zP{^3Cez=Q~KeeB|m-^e#Z!1-dAb$evi(;Ds^6Z)5$bRDfv1`srLjAQ|NW`y0HA{_o*} zK=&4c=)a%*Nq|Vkzl7*ML7;l++0{$?!KL+_z|HGIT=Pn=-|9H6Xvw{%whrPQe{}$|j+P?{+|9=1tZOFp_ literal 0 HcmV?d00001 diff --git a/dwlb.1 b/dwlb.1 new file mode 100644 index 0000000..0ef5c30 --- /dev/null +++ b/dwlb.1 @@ -0,0 +1,324 @@ +.TH DWLB 1 2023 Linux "User's Reference Manuals" +. +.SH NAME +dwlb \- feature-complete bar for dwl +. +.SH SYNOPSIS +. +.SY dwlb +.RI [ OPTIONS\~ \&.\|.\|.\&] +.YS +. +.SH DESCRIPTION +. +.B dwlb +is a feature-complete status bar for +.IR dwl . +. +.SH USAGE +. +Pass +.B dwlb +as an argument to +.IR dwl 's +.B -s +flag. +This will populate +each connected output with a bar. +. +.PP +For example: +.IP +.EX +dwl \-s \(aqdwlb \-font "monospace:size=16"\(aq +.EE +. +.SS IPC +. +.PP +If +.I dwl +is patched appropriately, +.B dwlb +is capable of communicating directly with +.IR dwl . +When IPC is enabled with +.BR \-ipc , +.B dwlb +does not read from +.IR stdin , +and clicking tags functions as you would expect. +IPC can be disabled with +.BR \-no\-ipc . +. +.SS Commands +. +Command options send instructions +to existing instances of +.BR dwlb . +All commands take at least one argument +to specify a bar on which to operate. +This may be +.I zxdg_output_v1 +name, +"all" to affect all outputs, +or "selected" for the current output. +. +.PP +The +.B \-status +and +.B \-title +commands are used to write status text. +The text may contain in-line commands +in the following format: +.IR \(hacmd(argument) . +. +.TP +.BR \(hafg \c +.BI ( HEXCOLOR ) +Sets foreground color to +.IR HEXCOLOR . +.TP +.BR \(habg \c +.BI ( HEXCOLOR ) +Sets background color to +.IR HEXCOLOR . +.TP +.BR \(halm \c +.BI ( SHELLCOMMAND ) +Begins or terminates left mouse button region with action +.IR SHELLCOMMAND . +.TP +.BR \(hamm \c +.BI ( SHELLCOMMAND ) +Begins or terminates middle mouse button region with action +.IR SHELLCOMMAND . +.TP +.BR \(harm \c +.BI ( SHELLCOMMAND ) +Begins or terminates right mouse button region with action +.IR SHELLCOMMAND . +. +.PP +In this example, +clicking the text highlighted in red +will spawn the foot terminal. +. +.IP +.EX +dwlb \-status all \(aqtext \(habg(ff0000)\(halm(foot)text\(habg()\(halm() text\(aq +.EE +. +.PP +A color command with no argument reverts to the default value. +.B \(ha\(ha +represents a single +.B \(ha +character. +Status commands can be disabled with +.BR \-no\-status\-commands . +. +.SS Scaling +. +.PP +If you use scaling in Wayland, +you can specify +.B buffer_scale +through config file or by passing it as an option +(only integer values): +. +.IP +.EX +dwlb \-scale 2 +.EE +. +.PP +This will render both surface and a cursor with 2\(mu detail. +If your monitor is set to 1.25 or 1.5 scaling, +setting scale to 2 will also work as compositor +will downscale the buffer properly. +. +.SS Someblocks +. +.PP +To use +.IR someblocks , +or any program that outputs to +.IR stdout , +with +.BR dwlb , +use this one-liner: +. +.IP +.EX +someblocks \-p | dwlb \-status\-stdin all +.EE +. +.SH OPTIONS +. +.SS IPC +. +.TP +.B \-ipc +Allow commands to be sent to +.I dwl +.RI ( dwl +Must be patched) +.TP +.B \-no\-ipc +Disable ipc +. +.SS Configuration +. +.TP +.B \-hidden +Bars will initially be hidden +.TP +.B \-no\-hidden +Bars will not initially be hidden +.TP +.B \-bottom +Bars will initially be drawn at the bottom +.TP +.B \-no\-bottom +Bars will initially be drawn at the top +.TP +.B \-hide\-vacant\-tags +Do not display empty and inactive tags +.TP +.B \-no\-hide\-vacant\-tags +Display empty and inactive tags +.TP +.B \-status\-commands +Enable in-line commands in status text +.TP +.B \-no\-status\-commands +Disable in-line commands in status text +.TP +.B \-center\-title +Center title text on bar +.TP +.B \-no\-center\-title +Do not center title text on bar +.TP +.B \-custom\-title +Do not display window title and +Treat the area as another status text element; +see +.B \-title +command +.TP +.B \-no\-custom\-title +Display current window title as normal +.TP +.BR \-font \~\c +.I FONT +Specify a font +.TP +.BR \-tags \~\c +.IR NUMBER \~\c +.IR FIRST \&.\|.\|.\& LAST +If ipc is disabled, specify custom tag names +.TP +.BR \-vertical\-padding \~\c +.I PIXELS +Specify vertical pixel padding above and below text +.TP +.BR \-active\-fg\-color \~\c +.I COLOR +Specify text color of active tags or monitors +.TP +.BR \-active\-bg\-color \~\c +.I COLOR +Specify background color of active tags or monitors +.TP +.BR \-occupied\-fg\-color \~\c +.I COLOR +Specify text color of occupied tags +.TP +.BR \-occupied\-bg\-color \~\c +.I COLOR +Specify background color of occupied tags +.TP +.BR \-inactive\-fg\-color \~\c +.I COLOR +Specify text color of inactive tags or monitors +.TP +.BR \-inactive\-bg\-color \~\c +.I COLOR +Specify background color of inactive tags or monitors +.TP +.BR \-urgent\-fg\-color \~\c +.I COLOR +Specify text color of urgent tags +.TP +.BR \-urgent\-bg\-color \~\c +.I COLOR +Specify background color of urgent tags +.TP +.BR \-scale \~\c +.I BUFFER_SCALE +Specify buffer scale value for integer scaling +. +.SS Commands +. +.TP +.BR \-status \~\c +.I OUTPUT\~TEXT +Set status text +.TP +.BR \-status\-stdin \~\c +.I OUTPUT +Set status text from stdin +.TP +.BR \-title \~\c +.I OUTPUT\~TEXT +Set title text, +if +.B \-custom\-title +Is enabled +.TP +.BR \-show \~\c +.I OUTPUT +Show bar +.TP +.BR \-hide \~\c +.I OUTPUT +Hide bar +.TP +.BR \-toggle\-visibility \~\c +.I OUTPUT +Toggle bar visibility +.TP +.BR \-set\-top \~\c +.I OUTPUT +Draw bar at the top +.TP +.BR \-set\-bottom \~\c +.I OUTPUT +Draw bar at the bottom +.TP +.BR \-toggle\-location \~\c +.I OUTPUT +Toggle bar location +. +.SS Others +. +.TP +.B \-v +Get version information +.TP +.B \-h +View this help text +. +.SH SEE ALSO +. +.BR dwl (1), +.BR someblocks (1) +. +.SH AUTHOR +. +.UR https://\:github\:.com/\:kolunmi +kolumni +.UE diff --git a/dwlb.c b/dwlb.c new file mode 100644 index 0000000..faab2d9 --- /dev/null +++ b/dwlb.c @@ -0,0 +1,2006 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "utf8.h" +#include "xdg-shell-protocol.h" +#include "xdg-output-unstable-v1-protocol.h" +#include "wlr-layer-shell-unstable-v1-protocol.h" +#include "dwl-ipc-unstable-v2-protocol.h" + +#define DIE(fmt, ...) \ + do { \ + cleanup(); \ + fprintf(stderr, fmt "\n", ##__VA_ARGS__); \ + exit(1); \ + } while (0) +#define EDIE(fmt, ...) \ + DIE(fmt ": %s", ##__VA_ARGS__, strerror(errno)); + +#define MIN(a, b) \ + ((a) < (b) ? (a) : (b)) +#define MAX(a, b) \ + ((a) > (b) ? (a) : (b)) +#define LENGTH(x) \ + (sizeof x / sizeof x[0]) + +#define ARRAY_INIT_CAP 16 +#define ARRAY_EXPAND(arr, len, cap, inc) \ + do { \ + uint32_t new_len, new_cap; \ + new_len = (len) + (inc); \ + if (new_len > (cap)) { \ + new_cap = new_len * 2; \ + if (new_cap < ARRAY_INIT_CAP) \ + new_cap = ARRAY_INIT_CAP; \ + if (!((arr) = realloc((arr), sizeof(*(arr)) * new_cap))) \ + EDIE("realloc"); \ + (cap) = new_cap; \ + } \ + (len) = new_len; \ + } while (0) +#define ARRAY_APPEND(arr, len, cap, ptr) \ + do { \ + ARRAY_EXPAND((arr), (len), (cap), 1); \ + (ptr) = &(arr)[(len) - 1]; \ + } while (0) + +#define PROGRAM "dwlb" +#define VERSION "0.2" +#define USAGE \ + "usage: dwlb [OPTIONS]\n" \ + "Ipc\n" \ + " -ipc allow commands to be sent to dwl (dwl must be patched)\n" \ + " -no-ipc disable ipc\n" \ + "Bar Config\n" \ + " -hidden bars will initially be hidden\n" \ + " -no-hidden bars will not initially be hidden\n" \ + " -bottom bars will initially be drawn at the bottom\n" \ + " -no-bottom bars will initially be drawn at the top\n" \ + " -hide-vacant-tags do not display empty and inactive tags\n" \ + " -no-hide-vacant-tags display empty and inactive tags\n" \ + " -status-commands enable in-line commands in status text\n" \ + " -no-status-commands disable in-line commands in status text\n" \ + " -center-title center title text on bar\n" \ + " -no-center-title do not center title text on bar\n" \ + " -custom-title do not display window title and treat the area as another status text element; see -title command\n" \ + " -no-custom-title display current window title as normal\n" \ + " -active-color-title title colors will use active colors\n" \ + " -no-active-color-title title colors will use inactive colors\n" \ + " -font [FONT] specify a font\n" \ + " -tags [NUMBER] [FIRST]...[LAST] if ipc is disabled, specify custom tag names. If NUMBER is 0, then no tag names should be given \n" \ + " -vertical-padding [PIXELS] specify vertical pixel padding above and below text\n" \ + " -active-fg-color [COLOR] specify text color of active tags or monitors\n" \ + " -active-bg-color [COLOR] specify background color of active tags or monitors\n" \ + " -occupied-fg-color [COLOR] specify text color of occupied tags\n" \ + " -occupied-bg-color [COLOR] specify background color of occupied tags\n" \ + " -inactive-fg-color [COLOR] specify text color of inactive tags or monitors\n" \ + " -inactive-bg-color [COLOR] specify background color of inactive tags or monitors\n" \ + " -urgent-fg-color [COLOR] specify text color of urgent tags\n" \ + " -urgent-bg-color [COLOR] specify background color of urgent tags\n" \ + " -middle-bg-color [COLOR] specify background color of the color in the middle of the bar\n" \ + " -middle-bg-color-selected [COLOR] specify background color of the color in the middle of the bar, when selected\n" \ + " -scale [BUFFER_SCALE] specify buffer scale value for integer scaling\n" \ + "Commands\n" \ + " -target-socket [SOCKET-NAME] set the socket to send command to. Sockets can be found in `$XDG_RUNTIME_DIR/dwlb/`\n"\ + " -status [OUTPUT] [TEXT] set status text\n" \ + " -status-stdin [OUTPUT] set status text from stdin\n" \ + " -title [OUTPUT] [TEXT] set title text, if -custom-title is enabled\n" \ + " -show [OUTPUT] show bar\n" \ + " -hide [OUTPUT] hide bar\n" \ + " -toggle-visibility [OUTPUT] toggle bar visibility\n" \ + " -set-top [OUTPUT] draw bar at the top\n" \ + " -set-bottom [OUTPUT] draw bar at the bottom\n" \ + " -toggle-location [OUTPUT] toggle bar location\n" \ + "Other\n" \ + " -v get version information\n" \ + " -h view this help text\n" + +#define TEXT_MAX 2048 + +enum { WheelUp, WheelDown }; + +typedef struct { + pixman_color_t color; + bool bg; + char *start; +} Color; + +typedef struct { + uint32_t btn; + uint32_t x1; + uint32_t x2; + char command[128]; +} Button; + +typedef struct { + char text[TEXT_MAX]; + Color *colors; + uint32_t colors_l, colors_c; + Button *buttons; + uint32_t buttons_l, buttons_c; +} CustomText; + +typedef struct { + struct wl_output *wl_output; + struct wl_surface *wl_surface; + struct zwlr_layer_surface_v1 *layer_surface; + struct zxdg_output_v1 *xdg_output; + struct zdwl_ipc_output_v2 *dwl_wm_output; + + uint32_t registry_name; + char *xdg_output_name; + + bool configured; + uint32_t width, height; + uint32_t textpadding; + uint32_t stride, bufsize; + + uint32_t mtags, ctags, urg, sel; + char *layout, *window_title; + uint32_t layout_idx, last_layout_idx; + CustomText title, status; + + bool hidden, bottom; + bool redraw; + + struct wl_list link; +} Bar; + +typedef struct { + struct wl_seat *wl_seat; + struct wl_pointer *wl_pointer; + uint32_t registry_name; + + Bar *bar; + uint32_t pointer_x, pointer_y; + uint32_t pointer_button; + + struct wl_list link; +} Seat; + +static int sock_fd; +static char socketdir[256]; +static char *socketpath; +static char sockbuf[4096]; + +static char *stdinbuf; +static size_t stdinbuf_cap; + +static struct wl_display *display; +static struct wl_compositor *compositor; +static struct wl_shm *shm; +static struct zwlr_layer_shell_v1 *layer_shell; +static struct zxdg_output_manager_v1 *output_manager; + +static struct zdwl_ipc_manager_v2 *dwl_wm; +static struct wl_cursor_image *cursor_image; +static struct wl_surface *cursor_surface; + +static struct wl_list bar_list, seat_list; + +static char **tags; +static uint32_t tags_l, tags_c; +static char **layouts; +static uint32_t layouts_l, layouts_c; + +static struct fcft_font *font; +static uint32_t height, textpadding, buffer_scale; + +static bool run_display; + +#include "config.h" + +static void +wl_buffer_release(void *data, struct wl_buffer *wl_buffer) +{ + /* Sent by the compositor when it's no longer using this buffer */ + wl_buffer_destroy(wl_buffer); +} + +static const struct wl_buffer_listener wl_buffer_listener = { + .release = wl_buffer_release, +}; + +/* Shared memory support function adapted from [wayland-book] */ +static int +allocate_shm_file(size_t size) +{ + int fd = memfd_create("surface", MFD_CLOEXEC); + if (fd == -1) + return -1; + int ret; + do { + ret = ftruncate(fd, size); + } while (ret == -1 && errno == EINTR); + if (ret == -1) { + close(fd); + return -1; + } + return fd; +} + +static uint32_t +draw_text(char *text, + uint32_t x, + uint32_t y, + pixman_image_t *foreground, + pixman_image_t *foreground_mask, + pixman_image_t *background, + pixman_color_t *fg_color, + pixman_color_t *bg_color, + uint32_t max_x, + uint32_t buf_height, + uint32_t padding, + Color *colors, + uint32_t colors_l) +{ + if (!text || !*text || !max_x) + return x; + + uint32_t ix = x, nx; + + if ((nx = x + padding) + padding >= max_x) + return x; + x = nx; + + bool draw_fg = foreground && fg_color; + bool draw_bg = background && bg_color; + + pixman_image_t *fg_mask_fill; + pixman_color_t *cur_fg_color; + pixman_color_t *cur_bg_color; + if (draw_fg) { + cur_fg_color = fg_color; + fg_mask_fill= pixman_image_create_solid_fill(&(pixman_color_t){0xFFFF,0xFFFF,0xFFFF,0xFFFF}); + } + if (draw_bg) + cur_bg_color = bg_color; + + uint32_t color_ind = 0, codepoint, state = UTF8_ACCEPT, last_cp = 0; + for (char *p = text; *p; p++) { + /* Check for new colors */ + if (state == UTF8_ACCEPT && colors && (draw_fg || draw_bg)) { + while (color_ind < colors_l && p == colors[color_ind].start) { + if (colors[color_ind].bg) { + if (draw_bg) + cur_bg_color = &colors[color_ind].color; + } else if (draw_fg) { + cur_fg_color = &colors[color_ind].color; + } + color_ind++; + } + } + + /* Returns nonzero if more bytes are needed */ + if (utf8decode(&state, &codepoint, *p)) + continue; + + /* Turn off subpixel rendering, which complicates things when + * mixed with alpha channels */ + const struct fcft_glyph *glyph = fcft_rasterize_char_utf32(font, codepoint, FCFT_SUBPIXEL_NONE); + if (!glyph) + continue; + + /* Adjust x position based on kerning with previous glyph */ + long kern = 0; + if (last_cp) + fcft_kerning(font, last_cp, codepoint, &kern, NULL); + if ((nx = x + kern + glyph->advance.x) + padding > max_x) + break; + last_cp = codepoint; + x += kern; + + if (draw_fg) { + /* Detect and handle pre-rendered glyphs (e.g. emoji) */ + if (pixman_image_get_format(glyph->pix) == PIXMAN_a8r8g8b8) { + pixman_image_composite32( + PIXMAN_OP_OVER, glyph->pix, NULL, foreground, 0, 0, 0, 0, + x + glyph->x, y - glyph->y, glyph->width, glyph->height); + } else { + pixman_image_fill_boxes(PIXMAN_OP_OVER, foreground, + cur_fg_color, 1, &(pixman_box32_t){ + .x1 = x, .x2 = nx, + .y1 = 0, .y2 = buf_height + }); + } + pixman_image_composite32( + PIXMAN_OP_OVER, glyph->pix, fg_mask_fill, foreground_mask, 0, 0, 0, 0, + x + glyph->x, y - glyph->y, glyph->width, glyph->height); + } + + if (draw_bg) { + pixman_image_fill_boxes(PIXMAN_OP_OVER, background, + cur_bg_color, 1, &(pixman_box32_t){ + .x1 = x, .x2 = nx, + .y1 = 0, .y2 = buf_height + }); + } + + /* increment pen position */ + x = nx; + } + + if (draw_fg) + pixman_image_unref(fg_mask_fill); + if (!last_cp) + return ix; + + nx = x + padding; + if (draw_bg) { + /* Fill padding background */ + pixman_image_fill_boxes(PIXMAN_OP_OVER, background, + bg_color, 1, &(pixman_box32_t){ + .x1 = ix, .x2 = ix + padding, + .y1 = 0, .y2 = buf_height + }); + pixman_image_fill_boxes(PIXMAN_OP_OVER, background, + bg_color, 1, &(pixman_box32_t){ + .x1 = x, .x2 = nx, + .y1 = 0, .y2 = buf_height + }); + } + + return nx; +} + +#define TEXT_WIDTH(text, maxwidth, padding) \ + draw_text(text, 0, 0, NULL, NULL, NULL, NULL, NULL, maxwidth, 0, padding, NULL, 0) + +static int +draw_frame(Bar *bar) +{ + /* Allocate buffer to be attached to the surface */ + int fd = allocate_shm_file(bar->bufsize); + if (fd == -1) + return -1; + + uint32_t *data = mmap(NULL, bar->bufsize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (data == MAP_FAILED) { + close(fd); + return -1; + } + + struct wl_shm_pool *pool = wl_shm_create_pool(shm, fd, bar->bufsize); + struct wl_buffer *buffer = wl_shm_pool_create_buffer(pool, 0, bar->width, bar->height, bar->stride, WL_SHM_FORMAT_ARGB8888); + wl_buffer_add_listener(buffer, &wl_buffer_listener, NULL); + wl_shm_pool_destroy(pool); + close(fd); + + /* Pixman image corresponding to main buffer */ + pixman_image_t *final = pixman_image_create_bits(PIXMAN_a8r8g8b8, bar->width, bar->height, data, bar->width * 4); + + /* Text background and foreground layers */ + pixman_image_t *foreground = pixman_image_create_bits(PIXMAN_a8r8g8b8, bar->width, bar->height, NULL, bar->width * 4); + pixman_image_t *foreground_mask = pixman_image_create_bits(PIXMAN_a8, bar->width, bar->height, NULL, bar->width * 4); + pixman_image_t *background = pixman_image_create_bits(PIXMAN_a8r8g8b8, bar->width, bar->height, NULL, bar->width * 4); + + /* Draw on images */ + uint32_t x = 0; + uint32_t y = (bar->height + font->ascent - font->descent) / 2; + uint32_t boxs = font->height / 9; + uint32_t boxw = font->height / 6 + 2; + + for (uint32_t i = 0; i < tags_l; i++) { + const bool active = bar->mtags & 1 << i; + const bool occupied = bar->ctags & 1 << i; + const bool urgent = bar->urg & 1 << i; + + if (hide_vacant && !active && !occupied && !urgent) + continue; + + pixman_color_t *fg_color = urgent ? &urgent_fg_color : (active ? &active_fg_color : (occupied ? &occupied_fg_color : &inactive_fg_color)); + pixman_color_t *bg_color = urgent ? &urgent_bg_color : (active ? &active_bg_color : (occupied ? &occupied_bg_color : &inactive_bg_color)); + + if (!hide_vacant && occupied) { + pixman_image_fill_boxes(PIXMAN_OP_SRC, foreground, + fg_color, 1, &(pixman_box32_t){ + .x1 = x + boxs, .x2 = x + boxs + boxw, + .y1 = boxs, .y2 = boxs + boxw + }); + pixman_image_fill_boxes(PIXMAN_OP_SRC, foreground_mask, + &(pixman_color_t){0xFFFF,0xFFFF,0xFFFF,0xFFFF}, + 1, &(pixman_box32_t){ + .x1 = x + boxs, .x2 = x + boxs + boxw, + .y1 = boxs, .y2 = boxs + boxw + }); + if ((!bar->sel || !active) && boxw >= 3) { + /* Make box hollow */ + pixman_image_fill_boxes(PIXMAN_OP_SRC, foreground, + &(pixman_color_t){ 0 }, + 1, &(pixman_box32_t){ + .x1 = x + boxs + 1, .x2 = x + boxs + boxw - 1, + .y1 = boxs + 1, .y2 = boxs + boxw - 1 + }); + pixman_image_fill_boxes(PIXMAN_OP_SRC, foreground_mask, + &(pixman_color_t){ 0 }, + 1, &(pixman_box32_t){ + .x1 = x + boxs + 1, .x2 = x + boxs + boxw - 1, + .y1 = boxs + 1, .y2 = boxs + boxw - 1 + }); + } + } + + x = draw_text(tags[i], x, y, foreground, foreground_mask, background, fg_color, bg_color, + bar->width, bar->height, bar->textpadding, NULL, 0); + } + + x = draw_text(bar->layout, x, y, foreground, foreground_mask, background, + &inactive_fg_color, &inactive_bg_color, bar->width, + bar->height, bar->textpadding, NULL, 0); + + uint32_t status_width = TEXT_WIDTH(bar->status.text, bar->width - x, bar->textpadding); + draw_text(bar->status.text, bar->width - status_width, y, foreground, foreground_mask, + background, &inactive_fg_color, &inactive_bg_color, + bar->width, bar->height, bar->textpadding, + bar->status.colors, bar->status.colors_l); + + uint32_t nx; + if (center_title) { + uint32_t title_width = TEXT_WIDTH(custom_title ? bar->title.text : bar->window_title, bar->width - status_width - x, 0); + nx = MAX(x, MIN((bar->width - title_width) / 2, bar->width - status_width - title_width)); + } else { + nx = MIN(x + bar->textpadding, bar->width - status_width); + } + pixman_image_fill_boxes(PIXMAN_OP_SRC, background, + bar->sel ? &middle_bg_color_selected : &middle_bg_color, 1, + &(pixman_box32_t){ + .x1 = x, .x2 = nx, + .y1 = 0, .y2 = bar->height + }); + x = nx; + + x = draw_text(custom_title ? bar->title.text : bar->window_title, + x, y, foreground, foreground_mask, background, + (bar->sel && active_color_title) ? &active_fg_color : &inactive_fg_color, + (bar->sel && active_color_title) ? &active_bg_color : &inactive_bg_color, + bar->width - status_width, bar->height, 0, + custom_title ? bar->title.colors : NULL, + custom_title ? bar->title.colors_l : 0); + + pixman_image_fill_boxes(PIXMAN_OP_SRC, background, + bar->sel ? &middle_bg_color_selected : &middle_bg_color, 1, + &(pixman_box32_t){ + .x1 = x, .x2 = bar->width - status_width, + .y1 = 0, .y2 = bar->height + }); + + /* Draw background and foreground on bar */ + pixman_image_composite32(PIXMAN_OP_OVER, background, NULL, final, 0, 0, 0, 0, 0, 0, bar->width, bar->height); + pixman_image_set_alpha_map(foreground, foreground_mask, 0, 0); + pixman_image_composite32(PIXMAN_OP_OVER, foreground, foreground_mask, final, 0, 0, 0, 0, 0, 0, bar->width, bar->height); + + pixman_image_unref(foreground); + pixman_image_unref(foreground_mask); + pixman_image_unref(background); + pixman_image_unref(final); + + munmap(data, bar->bufsize); + + wl_surface_set_buffer_scale(bar->wl_surface, buffer_scale); + wl_surface_attach(bar->wl_surface, buffer, 0, 0); + wl_surface_damage_buffer(bar->wl_surface, 0, 0, bar->width, bar->height); + wl_surface_commit(bar->wl_surface); + + return 0; +} + +/* Layer-surface setup adapted from layer-shell example in [wlroots] */ +static void +layer_surface_configure(void *data, struct zwlr_layer_surface_v1 *surface, + uint32_t serial, uint32_t w, uint32_t h) +{ + w = w * buffer_scale; + h = h * buffer_scale; + + zwlr_layer_surface_v1_ack_configure(surface, serial); + + Bar *bar = (Bar *)data; + + if (bar->configured && w == bar->width && h == bar->height) + return; + + bar->width = w; + bar->height = h; + bar->stride = bar->width * 4; + bar->bufsize = bar->stride * bar->height; + bar->configured = true; + + draw_frame(bar); +} + +static void +layer_surface_closed(void *data, struct zwlr_layer_surface_v1 *surface) +{ +} + +static const struct zwlr_layer_surface_v1_listener layer_surface_listener = { + .configure = layer_surface_configure, + .closed = layer_surface_closed, +}; + +static void +cleanup(void) +{ + if (socketpath) + unlink(socketpath); +} + +static void +output_name(void *data, struct zxdg_output_v1 *xdg_output, const char *name) +{ + Bar *bar = (Bar *)data; + + if (bar->xdg_output_name) + free(bar->xdg_output_name); + if (!(bar->xdg_output_name = strdup(name))) + EDIE("strdup"); +} + +static void +output_logical_position(void *data, struct zxdg_output_v1 *xdg_output, + int32_t x, int32_t y) +{ +} + +static void +output_logical_size(void *data, struct zxdg_output_v1 *xdg_output, + int32_t width, int32_t height) +{ +} + +static void +output_done(void *data, struct zxdg_output_v1 *xdg_output) +{ +} + +static void +output_description(void *data, struct zxdg_output_v1 *xdg_output, + const char *description) +{ +} + +static const struct zxdg_output_v1_listener output_listener = { + .name = output_name, + .logical_position = output_logical_position, + .logical_size = output_logical_size, + .done = output_done, + .description = output_description +}; + +static void +shell_command(char *command) +{ + if (fork() == 0) { + setsid(); + execl("/bin/sh", "sh", "-c", command, NULL); + exit(EXIT_SUCCESS); + } +} + +static void +pointer_enter(void *data, struct wl_pointer *pointer, + uint32_t serial, struct wl_surface *surface, + wl_fixed_t surface_x, wl_fixed_t surface_y) +{ + Seat *seat = (Seat *)data; + + seat->bar = NULL; + Bar *bar; + wl_list_for_each(bar, &bar_list, link) { + if (bar->wl_surface == surface) { + seat->bar = bar; + break; + } + } + + if (!cursor_image) { + const char *size_str = getenv("XCURSOR_SIZE"); + int size = size_str ? atoi(size_str) : 0; + if (size == 0) + size = 24; + struct wl_cursor_theme *cursor_theme = wl_cursor_theme_load(getenv("XCURSOR_THEME"), size * buffer_scale, shm); + cursor_image = wl_cursor_theme_get_cursor(cursor_theme, "left_ptr")->images[0]; + cursor_surface = wl_compositor_create_surface(compositor); + wl_surface_set_buffer_scale(cursor_surface, buffer_scale); + wl_surface_attach(cursor_surface, wl_cursor_image_get_buffer(cursor_image), 0, 0); + wl_surface_commit(cursor_surface); + } + wl_pointer_set_cursor(pointer, serial, cursor_surface, + cursor_image->hotspot_x, + cursor_image->hotspot_y); +} + +static void +pointer_leave(void *data, struct wl_pointer *pointer, + uint32_t serial, struct wl_surface *surface) +{ + Seat *seat = (Seat *)data; + + seat->bar = NULL; +} + +static void +pointer_button(void *data, struct wl_pointer *pointer, uint32_t serial, + uint32_t time, uint32_t button, uint32_t state) +{ + Seat *seat = (Seat *)data; + + seat->pointer_button = state == WL_POINTER_BUTTON_STATE_PRESSED ? button : 0; +} + +static void +pointer_motion(void *data, struct wl_pointer *pointer, uint32_t time, + wl_fixed_t surface_x, wl_fixed_t surface_y) +{ + Seat *seat = (Seat *)data; + + seat->pointer_x = wl_fixed_to_int(surface_x); + seat->pointer_y = wl_fixed_to_int(surface_y); +} + +static void +pointer_frame(void *data, struct wl_pointer *pointer) +{ + Seat *seat = (Seat *)data; + + if (!seat->pointer_button || !seat->bar) + return; + + uint32_t x = 0, i = 0; + do { + if (hide_vacant) { + const bool active = seat->bar->mtags & 1 << i; + const bool occupied = seat->bar->ctags & 1 << i; + const bool urgent = seat->bar->urg & 1 << i; + if (!active && !occupied && !urgent) + continue; + } + x += TEXT_WIDTH(tags[i], seat->bar->width - x, seat->bar->textpadding) / buffer_scale; + } while (seat->pointer_x >= x && ++i < tags_l); + + if (i < tags_l) { + /* Clicked on tags */ + if (ipc) { + if (seat->pointer_button == BTN_LEFT) + zdwl_ipc_output_v2_set_tags(seat->bar->dwl_wm_output, 1 << i, 1); + else if (seat->pointer_button == BTN_MIDDLE) + zdwl_ipc_output_v2_set_tags(seat->bar->dwl_wm_output, ~0, 1); + else if (seat->pointer_button == BTN_RIGHT) + zdwl_ipc_output_v2_set_tags(seat->bar->dwl_wm_output, seat->bar->mtags ^ (1 << i), 0); + } + } else if (seat->pointer_x < (x += TEXT_WIDTH(seat->bar->layout, seat->bar->width - x, seat->bar->textpadding))) { + /* Clicked on layout */ + if (ipc) { + if (seat->pointer_button == BTN_LEFT) + zdwl_ipc_output_v2_set_layout(seat->bar->dwl_wm_output, seat->bar->last_layout_idx); + else if (seat->pointer_button == BTN_RIGHT) + zdwl_ipc_output_v2_set_layout(seat->bar->dwl_wm_output, 2); + } + } else { + uint32_t status_x = seat->bar->width / buffer_scale - TEXT_WIDTH(seat->bar->status.text, seat->bar->width - x, seat->bar->textpadding) / buffer_scale; + if (seat->pointer_x < status_x) { + /* Clicked on title */ + if (custom_title) { + if (center_title) { + uint32_t title_width = TEXT_WIDTH(seat->bar->title.text, status_x - x, 0); + x = MAX(x, MIN((seat->bar->width - title_width) / 2, status_x - title_width)); + } else { + x = MIN(x + seat->bar->textpadding, status_x); + } + for (i = 0; i < seat->bar->title.buttons_l; i++) { + if (seat->pointer_button == seat->bar->title.buttons[i].btn + && seat->pointer_x >= x + seat->bar->title.buttons[i].x1 + && seat->pointer_x < x + seat->bar->title.buttons[i].x2) { + shell_command(seat->bar->title.buttons[i].command); + break; + } + } + } + } else { + /* Clicked on status */ + for (i = 0; i < seat->bar->status.buttons_l; i++) { + + if (seat->pointer_button == seat->bar->status.buttons[i].btn + && seat->pointer_x >= status_x + seat->bar->textpadding + seat->bar->status.buttons[i].x1 / buffer_scale + && seat->pointer_x < status_x + seat->bar->textpadding + seat->bar->status.buttons[i].x2 / buffer_scale) { + shell_command(seat->bar->status.buttons[i].command); + break; + } + } + } + } + + seat->pointer_button = 0; +} + +static void +pointer_axis(void *data, struct wl_pointer *pointer, + uint32_t time, uint32_t axis, wl_fixed_t value) +{ +} + +static void +pointer_axis_discrete(void *data, struct wl_pointer *pointer, + uint32_t axis, int32_t discrete) +{ + uint32_t i; + uint32_t btn = discrete < 0 ? WheelUp : WheelDown; + Seat *seat = (Seat *)data; + + if (!seat->bar) + return; + + uint32_t status_x = seat->bar->width / buffer_scale - TEXT_WIDTH(seat->bar->status.text, seat->bar->width, seat->bar->textpadding) / buffer_scale; + if (seat->pointer_x > status_x) { + /* Clicked on status */ + for (i = 0; i < seat->bar->status.buttons_l; i++) { + if (btn == seat->bar->status.buttons[i].btn + && seat->pointer_x >= status_x + seat->bar->textpadding + seat->bar->status.buttons[i].x1 / buffer_scale + && seat->pointer_x < status_x + seat->bar->textpadding + seat->bar->status.buttons[i].x2 / buffer_scale) { + shell_command(seat->bar->status.buttons[i].command); + break; + } + } + } +} + +static void +pointer_axis_source(void *data, struct wl_pointer *pointer, + uint32_t axis_source) +{ +} + +static void +pointer_axis_stop(void *data, struct wl_pointer *pointer, + uint32_t time, uint32_t axis) +{ +} + +static void +pointer_axis_value120(void *data, struct wl_pointer *pointer, + uint32_t axis, int32_t discrete) +{ +} + +static const struct wl_pointer_listener pointer_listener = { + .axis = pointer_axis, + .axis_discrete = pointer_axis_discrete, + .axis_source = pointer_axis_source, + .axis_stop = pointer_axis_stop, + .axis_value120 = pointer_axis_value120, + .button = pointer_button, + .enter = pointer_enter, + .frame = pointer_frame, + .leave = pointer_leave, + .motion = pointer_motion, +}; + +static void +seat_capabilities(void *data, struct wl_seat *wl_seat, + uint32_t capabilities) +{ + Seat *seat = (Seat *)data; + + uint32_t has_pointer = capabilities & WL_SEAT_CAPABILITY_POINTER; + if (has_pointer && !seat->wl_pointer) { + seat->wl_pointer = wl_seat_get_pointer(seat->wl_seat); + wl_pointer_add_listener(seat->wl_pointer, &pointer_listener, seat); + } else if (!has_pointer && seat->wl_pointer) { + wl_pointer_destroy(seat->wl_pointer); + seat->wl_pointer = NULL; + } +} + +static void +seat_name(void *data, struct wl_seat *wl_seat, const char *name) +{ +} + +static const struct wl_seat_listener seat_listener = { + .capabilities = seat_capabilities, + .name = seat_name, +}; + +static void +show_bar(Bar *bar) +{ + bar->wl_surface = wl_compositor_create_surface(compositor); + if (!bar->wl_surface) + DIE("Could not create wl_surface"); + + bar->layer_surface = zwlr_layer_shell_v1_get_layer_surface(layer_shell, bar->wl_surface, bar->wl_output, + ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM, PROGRAM); + if (!bar->layer_surface) + DIE("Could not create layer_surface"); + zwlr_layer_surface_v1_add_listener(bar->layer_surface, &layer_surface_listener, bar); + + zwlr_layer_surface_v1_set_size(bar->layer_surface, 0, bar->height / buffer_scale); + zwlr_layer_surface_v1_set_anchor(bar->layer_surface, + (bar->bottom ? ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM : ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP) + | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT + | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT); + zwlr_layer_surface_v1_set_exclusive_zone(bar->layer_surface, bar->height / buffer_scale); + wl_surface_commit(bar->wl_surface); + + bar->hidden = false; +} + +static void +hide_bar(Bar *bar) +{ + zwlr_layer_surface_v1_destroy(bar->layer_surface); + wl_surface_destroy(bar->wl_surface); + + bar->configured = false; + bar->hidden = true; +} + +static void +dwl_wm_tags(void *data, struct zdwl_ipc_manager_v2 *dwl_wm, + uint32_t amount) +{ + if (!tags && !(tags = malloc(amount * sizeof(char *)))) + EDIE("malloc"); + uint32_t i = tags_l; + ARRAY_EXPAND(tags, tags_l, tags_c, MAX(0, (int)amount - (int)tags_l)); + for (; i < amount; i++) + if (!(tags[i] = strdup(tags_names[MIN(i, LENGTH(tags_names)-1)]))) + EDIE("strdup"); +} + +static void +dwl_wm_layout(void *data, struct zdwl_ipc_manager_v2 *dwl_wm, + const char *name) +{ + char **ptr; + ARRAY_APPEND(layouts, layouts_l, layouts_c, ptr); + if (!(*ptr = strdup(name))) + EDIE("strdup"); +} + +static const struct zdwl_ipc_manager_v2_listener dwl_wm_listener = { + .tags = dwl_wm_tags, + .layout = dwl_wm_layout +}; + +static void +dwl_wm_output_toggle_visibility(void *data, struct zdwl_ipc_output_v2 *dwl_wm_output) +{ + Bar *bar = (Bar *)data; + + if (bar->hidden) + show_bar(bar); + else + hide_bar(bar); +} + +static void +dwl_wm_output_active(void *data, struct zdwl_ipc_output_v2 *dwl_wm_output, + uint32_t active) +{ + Bar *bar = (Bar *)data; + + if (active != bar->sel) + bar->sel = active; +} + +static void +dwl_wm_output_tag(void *data, struct zdwl_ipc_output_v2 *dwl_wm_output, + uint32_t tag, uint32_t state, uint32_t clients, uint32_t focused) +{ + Bar *bar = (Bar *)data; + + if (state & ZDWL_IPC_OUTPUT_V2_TAG_STATE_ACTIVE) + bar->mtags |= 1 << tag; + else + bar->mtags &= ~(1 << tag); + if (clients > 0) + bar->ctags |= 1 << tag; + else + bar->ctags &= ~(1 << tag); + if (state & ZDWL_IPC_OUTPUT_V2_TAG_STATE_URGENT) + bar->urg |= 1 << tag; + else + bar->urg &= ~(1 << tag); +} + +static void +dwl_wm_output_layout(void *data, struct zdwl_ipc_output_v2 *dwl_wm_output, + uint32_t layout) +{ + Bar *bar = (Bar *)data; + + bar->last_layout_idx = bar->layout_idx; + bar->layout_idx = layout; +} + +static void +dwl_wm_output_title(void *data, struct zdwl_ipc_output_v2 *dwl_wm_output, + const char *title) +{ + if (custom_title) + return; + + Bar *bar = (Bar *)data; + + if (bar->window_title) + free(bar->window_title); + if (!(bar->window_title = strdup(title))) + EDIE("strdup"); +} + +static void +dwl_wm_output_appid(void *data, struct zdwl_ipc_output_v2 *dwl_wm_output, + const char *appid) +{ +} + +static void +dwl_wm_output_layout_symbol(void *data, struct zdwl_ipc_output_v2 *dwl_wm_output, + const char *layout) +{ + Bar *bar = (Bar *)data; + + if (layouts[bar->layout_idx]) + free(layouts[bar->layout_idx]); + if (!(layouts[bar->layout_idx] = strdup(layout))) + EDIE("strdup"); + bar->layout = layouts[bar->layout_idx]; +} + +static void +dwl_wm_output_frame(void *data, struct zdwl_ipc_output_v2 *dwl_wm_output) +{ + Bar *bar = (Bar *)data; + bar->redraw = true; +} + +static void +dwl_wm_output_fullscreen(void *data, struct zdwl_ipc_output_v2 *dwl_wm_output, + uint32_t is_fullscreen) +{ +} + +static void +dwl_wm_output_floating(void *data, struct zdwl_ipc_output_v2 *dwl_wm_output, + uint32_t is_floating) +{ +} + +static const struct zdwl_ipc_output_v2_listener dwl_wm_output_listener = { + .toggle_visibility = dwl_wm_output_toggle_visibility, + .active = dwl_wm_output_active, + .tag = dwl_wm_output_tag, + .layout = dwl_wm_output_layout, + .title = dwl_wm_output_title, + .appid = dwl_wm_output_appid, + .layout_symbol = dwl_wm_output_layout_symbol, + .frame = dwl_wm_output_frame, + .fullscreen = dwl_wm_output_fullscreen, + .floating = dwl_wm_output_floating +}; + +static void +setup_bar(Bar *bar) +{ + bar->height = height * buffer_scale; + bar->textpadding = textpadding; + bar->bottom = bottom; + bar->hidden = hidden; + + bar->xdg_output = zxdg_output_manager_v1_get_xdg_output(output_manager, bar->wl_output); + if (!bar->xdg_output) + DIE("Could not create xdg_output"); + zxdg_output_v1_add_listener(bar->xdg_output, &output_listener, bar); + + if (ipc) { + bar->dwl_wm_output = zdwl_ipc_manager_v2_get_output(dwl_wm, bar->wl_output); + if (!bar->dwl_wm_output) + DIE("Could not create dwl_wm_output"); + zdwl_ipc_output_v2_add_listener(bar->dwl_wm_output, &dwl_wm_output_listener, bar); + } + + if (!bar->hidden) + show_bar(bar); +} + +static void +handle_global(void *data, struct wl_registry *registry, + uint32_t name, const char *interface, uint32_t version) +{ + if (!strcmp(interface, wl_compositor_interface.name)) { + compositor = wl_registry_bind(registry, name, &wl_compositor_interface, 4); + } else if (!strcmp(interface, wl_shm_interface.name)) { + shm = wl_registry_bind(registry, name, &wl_shm_interface, 1); + } else if (!strcmp(interface, zwlr_layer_shell_v1_interface.name)) { + layer_shell = wl_registry_bind(registry, name, &zwlr_layer_shell_v1_interface, 1); + } else if (!strcmp(interface, zxdg_output_manager_v1_interface.name)) { + output_manager = wl_registry_bind(registry, name, &zxdg_output_manager_v1_interface, 2); + } else if (!strcmp(interface, zdwl_ipc_manager_v2_interface.name)) { + if (ipc) { + dwl_wm = wl_registry_bind(registry, name, &zdwl_ipc_manager_v2_interface, 2); + zdwl_ipc_manager_v2_add_listener(dwl_wm, &dwl_wm_listener, NULL); + } + } else if (!strcmp(interface, wl_output_interface.name)) { + Bar *bar = calloc(1, sizeof(Bar)); + if (!bar) + EDIE("calloc"); + bar->registry_name = name; + bar->wl_output = wl_registry_bind(registry, name, &wl_output_interface, 1); + if (run_display) + setup_bar(bar); + wl_list_insert(&bar_list, &bar->link); + } else if (!strcmp(interface, wl_seat_interface.name)) { + Seat *seat = calloc(1, sizeof(Seat)); + if (!seat) + EDIE("calloc"); + seat->registry_name = name; + seat->wl_seat = wl_registry_bind(registry, name, &wl_seat_interface, 7); + wl_seat_add_listener(seat->wl_seat, &seat_listener, seat); + wl_list_insert(&seat_list, &seat->link); + } +} + +static void +teardown_bar(Bar *bar) +{ + if (bar->status.colors) + free(bar->status.colors); + if (bar->status.buttons) + free(bar->status.buttons); + if (bar->title.colors) + free(bar->title.colors); + if (bar->title.buttons) + free(bar->title.buttons); + if (bar->window_title) + free(bar->window_title); + if (!ipc && bar->layout) + free(bar->layout); + if (ipc) + zdwl_ipc_output_v2_destroy(bar->dwl_wm_output); + if (bar->xdg_output_name) + free(bar->xdg_output_name); + if (!bar->hidden) { + zwlr_layer_surface_v1_destroy(bar->layer_surface); + wl_surface_destroy(bar->wl_surface); + } + zxdg_output_v1_destroy(bar->xdg_output); + wl_output_destroy(bar->wl_output); + free(bar); +} + +static void +teardown_seat(Seat *seat) +{ + if (seat->wl_pointer) + wl_pointer_destroy(seat->wl_pointer); + wl_seat_destroy(seat->wl_seat); + free(seat); +} + +static void +handle_global_remove(void *data, struct wl_registry *registry, uint32_t name) +{ + Bar *bar; + Seat *seat; + + wl_list_for_each(bar, &bar_list, link) { + if (bar->registry_name == name) { + wl_list_remove(&bar->link); + teardown_bar(bar); + return; + } + } + wl_list_for_each(seat, &seat_list, link) { + if (seat->registry_name == name) { + wl_list_remove(&seat->link); + teardown_seat(seat); + return; + } + } +} + +static const struct wl_registry_listener registry_listener = { + .global = handle_global, + .global_remove = handle_global_remove +}; + +static int +advance_word(char **beg, char **end) +{ + for (*beg = *end; **beg == ' '; (*beg)++); + for (*end = *beg; **end && **end != ' '; (*end)++); + if (!**end) + /* last word */ + return -1; + **end = '\0'; + (*end)++; + return 0; +} + +#define ADVANCE() advance_word(&wordbeg, &wordend) +#define ADVANCE_IF_LAST_CONT() if (ADVANCE() == -1) continue +#define ADVANCE_IF_LAST_RET() if (ADVANCE() == -1) return + +static void +read_stdin(void) +{ + size_t len = 0; + for (;;) { + ssize_t rv = read(STDIN_FILENO, stdinbuf + len, stdinbuf_cap - len); + if (rv == -1) { + if (errno == EWOULDBLOCK) + break; + EDIE("read"); + } + if (rv == 0) { + run_display = false; + return; + } + + if ((len += rv) > stdinbuf_cap / 2) + if (!(stdinbuf = realloc(stdinbuf, (stdinbuf_cap *= 2)))) + EDIE("realloc"); + } + + char *linebeg, *lineend; + char *wordbeg, *wordend; + + for (linebeg = stdinbuf; + (lineend = memchr(linebeg, '\n', stdinbuf + len - linebeg)); + linebeg = lineend) { + *lineend++ = '\0'; + wordend = linebeg; + + ADVANCE_IF_LAST_CONT(); + + Bar *it, *bar = NULL; + wl_list_for_each(it, &bar_list, link) { + if (it->xdg_output_name && !strcmp(wordbeg, it->xdg_output_name)) { + bar = it; + break; + } + } + if (!bar) + continue; + + ADVANCE_IF_LAST_CONT(); + + uint32_t val; + if (!strcmp(wordbeg, "tags")) { + ADVANCE_IF_LAST_CONT(); + if ((val = atoi(wordbeg)) != bar->ctags) { + bar->ctags = val; + bar->redraw = true; + } + ADVANCE_IF_LAST_CONT(); + if ((val = atoi(wordbeg)) != bar->mtags) { + bar->mtags = val; + bar->redraw = true; + } + ADVANCE_IF_LAST_CONT(); + /* skip sel */ + ADVANCE(); + if ((val = atoi(wordbeg)) != bar->urg) { + bar->urg = val; + bar->redraw = true; + } + } else if (!strcmp(wordbeg, "layout")) { + if (bar->layout) + free(bar->layout); + if (!(bar->layout = strdup(wordend))) + EDIE("strdup"); + bar->redraw = true; + } else if (!strcmp(wordbeg, "title")) { + if (custom_title) + continue; + if (bar->window_title) + free(bar->window_title); + if (!(bar->window_title = strdup(wordend))) + EDIE("strdup"); + bar->redraw = true; + } else if (!strcmp(wordbeg, "selmon")) { + ADVANCE(); + if ((val = atoi(wordbeg)) != bar->sel) { + bar->sel = val; + bar->redraw = true; + } + } + } +} + +static void +set_top(Bar *bar) +{ + if (!bar->hidden) { + zwlr_layer_surface_v1_set_anchor(bar->layer_surface, + ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP + | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT + | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT); + bar->redraw = true; + } + bar->bottom = false; +} + +static void +set_bottom(Bar *bar) +{ + if (!bar->hidden) { + zwlr_layer_surface_v1_set_anchor(bar->layer_surface, + ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM + | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT + | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT); + bar->redraw = true; + } + bar->bottom = true; +} + +/* Color parsing logic adapted from [sway] */ +static int +parse_color(const char *str, pixman_color_t *clr) +{ + if (*str == '#') + str++; + int len = strlen(str); + + // Disallows "0x" prefix that strtoul would ignore + if ((len != 6 && len != 8) || !isxdigit(str[0]) || !isxdigit(str[1])) + return -1; + + char *ptr; + uint32_t parsed = strtoul(str, &ptr, 16); + if (*ptr) + return -1; + + if (len == 8) { + clr->alpha = (parsed & 0xff) * 0x101; + parsed >>= 8; + } else { + clr->alpha = 0xffff; + } + clr->red = ((parsed >> 16) & 0xff) * 0x101; + clr->green = ((parsed >> 8) & 0xff) * 0x101; + clr->blue = ((parsed >> 0) & 0xff) * 0x101; + return 0; +} + +static void +parse_into_customtext(CustomText *ct, char *text) +{ + ct->colors_l = ct->buttons_l = 0; + + if (status_commands) { + uint32_t codepoint; + uint32_t state = UTF8_ACCEPT; + uint32_t last_cp = 0; + uint32_t x = 0; + size_t str_pos = 0; + + Button *left_button = NULL; + Button *middle_button = NULL; + Button *right_button = NULL; + Button *scrollup_button = NULL; + Button *scrolldown_button = NULL; + + for (char *p = text; *p && str_pos < sizeof(ct->text) - 1; p++) { + if (state == UTF8_ACCEPT && *p == '^') { + p++; + if (*p != '^') { + char *arg, *end; + if (!(arg = strchr(p, '(')) || !(end = strchr(arg + 1, ')'))) + continue; + *arg++ = '\0'; + *end = '\0'; + + if (!strcmp(p, "bg")) { + Color *color; + ARRAY_APPEND(ct->colors, ct->colors_l, ct->colors_c, color); + if (!*arg) + color->color = inactive_bg_color; + else + parse_color(arg, &color->color); + color->bg = true; + color->start = ct->text + str_pos; + } else if (!strcmp(p, "fg")) { + Color *color; + ARRAY_APPEND(ct->colors, ct->colors_l, ct->colors_c, color); + if (!*arg) + color->color = inactive_fg_color; + else + parse_color(arg, &color->color); + color->bg = false; + color->start = ct->text + str_pos; + } else if (!strcmp(p, "lm")) { + if (left_button) { + left_button->x2 = x; + left_button = NULL; + } else if (*arg) { + ARRAY_APPEND(ct->buttons, ct->buttons_l, ct->buttons_c, left_button); + left_button->btn = BTN_LEFT; + snprintf(left_button->command, sizeof left_button->command, "%s", arg); + left_button->x1 = x; + } + } else if (!strcmp(p, "mm")) { + if (middle_button) { + middle_button->x2 = x; + middle_button = NULL; + } else if (*arg) { + ARRAY_APPEND(ct->buttons, ct->buttons_l, ct->buttons_c, middle_button); + middle_button->btn = BTN_MIDDLE; + snprintf(middle_button->command, sizeof middle_button->command, "%s", arg); + middle_button->x1 = x; + } + } else if (!strcmp(p, "rm")) { + if (right_button) { + right_button->x2 = x; + right_button = NULL; + } else if (*arg) { + ARRAY_APPEND(ct->buttons, ct->buttons_l, ct->buttons_c, right_button); + right_button->btn = BTN_RIGHT; + snprintf(right_button->command, sizeof right_button->command, "%s", arg); + right_button->x1 = x; + } + } else if (!strcmp(p, "us")) { + if (scrollup_button) { + scrollup_button->x2 = x; + scrollup_button = NULL; + } else if (*arg) { + ARRAY_APPEND(ct->buttons, ct->buttons_l, ct->buttons_c, scrollup_button); + scrollup_button->btn = WheelUp; + snprintf(scrollup_button->command, sizeof scrollup_button->command, "%s", arg); + scrollup_button->x1 = x; + } + } else if (!strcmp(p, "ds")) { + if (scrolldown_button) { + scrolldown_button->x2 = x; + scrolldown_button = NULL; + } else if (*arg) { + ARRAY_APPEND(ct->buttons, ct->buttons_l, ct->buttons_c, scrolldown_button); + scrolldown_button->btn = WheelDown; + snprintf(scrolldown_button->command, sizeof scrolldown_button->command, "%s", arg); + scrolldown_button->x1 = x; + } + } + + *--arg = '('; + *end = ')'; + + p = end; + continue; + } + } + + ct->text[str_pos++] = *p; + + if (utf8decode(&state, &codepoint, *p)) + continue; + + const struct fcft_glyph *glyph = fcft_rasterize_char_utf32(font, codepoint, FCFT_SUBPIXEL_NONE); + if (!glyph) + continue; + + long kern = 0; + if (last_cp) + fcft_kerning(font, last_cp, codepoint, &kern, NULL); + last_cp = codepoint; + + x += kern + glyph->advance.x; + } + + if (left_button) + left_button->x2 = x; + if (middle_button) + middle_button->x2 = x; + if (right_button) + right_button->x2 = x; + if (scrollup_button) + scrollup_button->x2 = x; + if (scrolldown_button) + scrolldown_button->x2 = x; + + + ct->text[str_pos] = '\0'; + } else { + snprintf(ct->text, sizeof ct->text, "%s", text); + } +} + +static void +copy_customtext(CustomText *from, CustomText *to) +{ + snprintf(to->text, sizeof to->text, "%s", from->text); + to->colors_l = to->buttons_l = 0; + for (uint32_t i = 0; i < from->colors_l; i++) { + Color *color; + ARRAY_APPEND(to->colors, to->colors_l, to->colors_c, color); + color->color = from->colors[i].color; + color->bg = from->colors[i].bg; + color->start = from->colors[i].start - (char *)&from->text + (char *)&to->text; + } + for (uint32_t i = 0; i < from->buttons_l; i++) { + Button *button; + ARRAY_APPEND(to->buttons, to->buttons_l, to->buttons_c, button); + *button = from->buttons[i]; + } +} + +static void +read_socket(void) +{ + int cli_fd; + if ((cli_fd = accept(sock_fd, NULL, 0)) == -1) + EDIE("accept"); + ssize_t len = recv(cli_fd, sockbuf, sizeof sockbuf - 1, 0); + if (len == -1) + EDIE("recv"); + close(cli_fd); + if (len == 0) + return; + sockbuf[len] = '\0'; + + char *wordbeg, *wordend; + wordend = (char *)&sockbuf; + + ADVANCE_IF_LAST_RET(); + + Bar *bar = NULL, *it; + bool all = false; + + if (!strcmp(wordbeg, "all")) { + all = true; + } else if (!strcmp(wordbeg, "selected")) { + wl_list_for_each(it, &bar_list, link) { + if (it->sel) { + bar = it; + break; + } + } + } else { + wl_list_for_each(it, &bar_list, link) { + if (it->xdg_output_name && !strcmp(wordbeg, it->xdg_output_name)) { + bar = it; + break; + } + } + } + + if (!all && !bar) + return; + + ADVANCE(); + + if (!strcmp(wordbeg, "status")) { + if (!*wordend) + return; + if (all) { + Bar *first = NULL; + wl_list_for_each(bar, &bar_list, link) { + if (first) { + copy_customtext(&first->status, &bar->status); + } else { + parse_into_customtext(&bar->status, wordend); + first = bar; + } + bar->redraw = true; + } + } else { + parse_into_customtext(&bar->status, wordend); + bar->redraw = true; + } + } else if (!strcmp(wordbeg, "title")) { + if (!custom_title || !*wordend) + return; + if (all) { + Bar *first = NULL; + wl_list_for_each(bar, &bar_list, link) { + if (first) { + copy_customtext(&first->title, &bar->title); + } else { + parse_into_customtext(&bar->title, wordend); + first = bar; + } + bar->redraw = true; + } + } else { + parse_into_customtext(&bar->title, wordend); + bar->redraw = true; + } + } else if (!strcmp(wordbeg, "show")) { + if (all) { + wl_list_for_each(bar, &bar_list, link) + if (bar->hidden) + show_bar(bar); + } else { + if (bar->hidden) + show_bar(bar); + } + } else if (!strcmp(wordbeg, "hide")) { + if (all) { + wl_list_for_each(bar, &bar_list, link) + if (!bar->hidden) + hide_bar(bar); + } else { + if (!bar->hidden) + hide_bar(bar); + } + } else if (!strcmp(wordbeg, "toggle-visibility")) { + if (all) { + wl_list_for_each(bar, &bar_list, link) + if (bar->hidden) + show_bar(bar); + else + hide_bar(bar); + } else { + if (bar->hidden) + show_bar(bar); + else + hide_bar(bar); + } + } else if (!strcmp(wordbeg, "set-top")) { + if (all) { + wl_list_for_each(bar, &bar_list, link) + if (bar->bottom) + set_top(bar); + + } else { + if (bar->bottom) + set_top(bar); + } + } else if (!strcmp(wordbeg, "set-bottom")) { + if (all) { + wl_list_for_each(bar, &bar_list, link) + if (!bar->bottom) + set_bottom(bar); + + } else { + if (!bar->bottom) + set_bottom(bar); + } + } else if (!strcmp(wordbeg, "toggle-location")) { + if (all) { + wl_list_for_each(bar, &bar_list, link) + if (bar->bottom) + set_top(bar); + else + set_bottom(bar); + } else { + if (bar->bottom) + set_top(bar); + else + set_bottom(bar); + } + } +} + +static void +event_loop(void) +{ + int wl_fd = wl_display_get_fd(display); + + while (run_display) { + fd_set rfds; + FD_ZERO(&rfds); + FD_SET(wl_fd, &rfds); + FD_SET(sock_fd, &rfds); + if (!ipc) + FD_SET(STDIN_FILENO, &rfds); + + wl_display_flush(display); + + if (select(MAX(sock_fd, wl_fd) + 1, &rfds, NULL, NULL, NULL) == -1) { + if (errno == EINTR) + continue; + else + EDIE("select"); + } + + if (FD_ISSET(wl_fd, &rfds)) + if (wl_display_dispatch(display) == -1) + break; + if (FD_ISSET(sock_fd, &rfds)) + read_socket(); + if (!ipc && FD_ISSET(STDIN_FILENO, &rfds)) + read_stdin(); + + Bar *bar; + wl_list_for_each(bar, &bar_list, link) { + if (bar->redraw) { + if (!bar->hidden) + draw_frame(bar); + bar->redraw = false; + } + } + } +} + +static void +client_send_command(struct sockaddr_un *sock_address, const char *output, + const char *cmd, const char *data, const char *target_socket) +{ + DIR *dir; + if (!(dir = opendir(socketdir))) + EDIE("Could not open directory '%s'", socketdir); + + if (data) + snprintf(sockbuf, sizeof sockbuf, "%s %s %s", output, cmd, data); + else + snprintf(sockbuf, sizeof sockbuf, "%s %s", output, cmd); + + size_t len = strlen(sockbuf); + + struct dirent *de; + bool newfd = true; + + /* Send data to all dwlb instances */ + while ((de = readdir(dir))) { + if (!strncmp(de->d_name, "dwlb-", 5)) { + if (!target_socket || !strncmp(de -> d_name, target_socket, 6)){ + if (newfd && (sock_fd = socket(AF_UNIX, SOCK_STREAM, 1)) == -1) + EDIE("socket"); + snprintf(sock_address->sun_path, sizeof sock_address->sun_path, "%s/%s", socketdir, de->d_name); + if (connect(sock_fd, (struct sockaddr *) sock_address, sizeof(*sock_address)) == -1) { + newfd = false; + continue; + } + if (send(sock_fd, sockbuf, len, 0) == -1) + fprintf(stderr, "Could not send status data to '%s'\n", sock_address->sun_path); + close(sock_fd); + newfd = true; + } + } + } + + closedir(dir); +} + +void +sig_handler(int sig) +{ + if (sig == SIGINT || sig == SIGHUP || sig == SIGTERM) + run_display = false; +} + +int +main(int argc, char **argv) +{ + char *xdgruntimedir; + struct sockaddr_un sock_address; + Bar *bar, *bar2; + Seat *seat, *seat2; + + /* Establish socket directory */ + if (!(xdgruntimedir = getenv("XDG_RUNTIME_DIR"))) + DIE("Could not retrieve XDG_RUNTIME_DIR"); + snprintf(socketdir, sizeof socketdir, "%s/dwlb", xdgruntimedir); + if (mkdir(socketdir, S_IRWXU) == -1) + if (errno != EEXIST) + EDIE("Could not create directory '%s'", socketdir); + sock_address.sun_family = AF_UNIX; + + /* Parse options */ + char *target_socket = NULL; + int i = 1; + if (argc > 1 && !strcmp(argv[1], "-target-socket")) { + if (2 >= argc) { + DIE("Option -socket requires an argument"); + } + target_socket = argv[2]; + i += 2; + } + for (; i < argc; i++) { + if (!strcmp(argv[i], "-status")) { + if (++i + 1 >= argc) + DIE("Option -status requires two arguments"); + client_send_command(&sock_address, argv[i], "status", argv[i + 1], target_socket); + return 0; + } else if (!strcmp(argv[i], "-status-stdin")) { + if (++i >= argc) + DIE("Option -status-stdin requires an argument"); + char *status = malloc(TEXT_MAX * sizeof(char)); + while (fgets(status, TEXT_MAX-1, stdin)) { + status[strlen(status)-1] = '\0'; + client_send_command(&sock_address, argv[i], "status", status, target_socket); + } + free(status); + return 0; + } else if (!strcmp(argv[i], "-title")) { + if (++i + 1 >= argc) + DIE("Option -title requires two arguments"); + client_send_command(&sock_address, argv[i], "title", argv[i + 1], target_socket); + return 0; + } else if (!strcmp(argv[i], "-show")) { + if (++i >= argc) + DIE("Option -show requires an argument"); + client_send_command(&sock_address, argv[i], "show", NULL, target_socket); + return 0; + } else if (!strcmp(argv[i], "-hide")) { + if (++i >= argc) + DIE("Option -hide requires an argument"); + client_send_command(&sock_address, argv[i], "hide", NULL, target_socket); + return 0; + } else if (!strcmp(argv[i], "-toggle-visibility")) { + if (++i >= argc) + DIE("Option -toggle requires an argument"); + client_send_command(&sock_address, argv[i], "toggle-visibility", NULL, target_socket); + return 0; + } else if (!strcmp(argv[i], "-set-top")) { + if (++i >= argc) + DIE("Option -set-top requires an argument"); + client_send_command(&sock_address, argv[i], "set-top", NULL, target_socket); + return 0; + } else if (!strcmp(argv[i], "-set-bottom")) { + if (++i >= argc) + DIE("Option -set-bottom requires an argument"); + client_send_command(&sock_address, argv[i], "set-bottom", NULL, target_socket); + return 0; + } else if (!strcmp(argv[i], "-toggle-location")) { + if (++i >= argc) + DIE("Option -toggle-location requires an argument"); + client_send_command(&sock_address, argv[i], "toggle-location", NULL, target_socket); + return 0; + } else if (!strcmp(argv[i], "-ipc")) { + ipc = true; + } else if (!strcmp(argv[i], "-no-ipc")) { + ipc = false; + } else if (!strcmp(argv[i], "-hide-vacant-tags")) { + hide_vacant = true; + } else if (!strcmp(argv[i], "-no-hide-vacant-tags")) { + hide_vacant = false; + } else if (!strcmp(argv[i], "-bottom")) { + bottom = true; + } else if (!strcmp(argv[i], "-no-bottom")) { + bottom = false; + } else if (!strcmp(argv[i], "-hidden")) { + hidden = true; + } else if (!strcmp(argv[i], "-no-hidden")) { + hidden = false; + } else if (!strcmp(argv[i], "-status-commands")) { + status_commands = true; + } else if (!strcmp(argv[i], "-no-status-commands")) { + status_commands = false; + } else if (!strcmp(argv[i], "-center-title")) { + center_title = true; + } else if (!strcmp(argv[i], "-no-center-title")) { + center_title = false; + } else if (!strcmp(argv[i], "-custom-title")) { + custom_title = true; + } else if (!strcmp(argv[i], "-no-custom-title")) { + custom_title = false; + } else if (!strcmp(argv[i], "-active-color-title")) { + active_color_title = true; + } else if (!strcmp(argv[i], "-no-active-color-title")) { + active_color_title = false; + } else if (!strcmp(argv[i], "-font")) { + if (++i >= argc) + DIE("Option -font requires an argument"); + fontstr = argv[i]; + } else if (!strcmp(argv[i], "-vertical-padding")) { + if (++i >= argc) + DIE("Option -vertical-padding requires an argument"); + vertical_padding = MAX(MIN(atoi(argv[i]), 100), 0); + } else if (!strcmp(argv[i], "-active-fg-color")) { + if (++i >= argc) + DIE("Option -active-fg-color requires an argument"); + if (parse_color(argv[i], &active_fg_color) == -1) + DIE("malformed color string"); + } else if (!strcmp(argv[i], "-active-bg-color")) { + if (++i >= argc) + DIE("Option -active-bg-color requires an argument"); + if (parse_color(argv[i], &active_bg_color) == -1) + DIE("malformed color string"); + } else if (!strcmp(argv[i], "-occupied-fg-color")) { + if (++i >= argc) + DIE("Option -occupied-fg-color requires an argument"); + if (parse_color(argv[i], &occupied_fg_color) == -1) + DIE("malformed color string"); + } else if (!strcmp(argv[i], "-occupied-bg-color")) { + if (++i >= argc) + DIE("Option -occupied-bg-color requires an argument"); + if (parse_color(argv[i], &occupied_bg_color) == -1) + DIE("malformed color string"); + } else if (!strcmp(argv[i], "-inactive-fg-color")) { + if (++i >= argc) + DIE("Option -inactive-fg-color requires an argument"); + if (parse_color(argv[i], &inactive_fg_color) == -1) + DIE("malformed color string"); + } else if (!strcmp(argv[i], "-inactive-bg-color")) { + if (++i >= argc) + DIE("Option -inactive-bg-color requires an argument"); + if (parse_color(argv[i], &inactive_bg_color) == -1) + DIE("malformed color string"); + } else if (!strcmp(argv[i], "-urgent-fg-color")) { + if (++i >= argc) + DIE("Option -urgent-fg-color requires an argument"); + if (parse_color(argv[i], &urgent_fg_color) == -1) + DIE("malformed color string"); + } else if (!strcmp(argv[i], "-urgent-bg-color")) { + if (++i >= argc) + DIE("Option -urgent-bg-color requires an argument"); + if (parse_color(argv[i], &urgent_bg_color) == -1) + DIE("malformed color string"); + } else if (!strcmp(argv[i], "-middle-bg-color-selected")) { + if (++i >= argc) + DIE("Option -middle-bg-color-selected requires an argument"); + if (parse_color(argv[i], &middle_bg_color_selected) == -1) + DIE("malformed color string"); + } else if (!strcmp(argv[i], "-middle-bg-color")) { + if (++i >= argc) + DIE("Option -middle-bg-color requires an argument"); + if (parse_color(argv[i], &middle_bg_color) == -1) + DIE("malformed color string"); + } else if (!strcmp(argv[i], "-tags")) { + if (++i >= argc) + DIE("Option -tags requires at least one argument"); + int v; + if ((v = atoi(argv[i])) < 0 || i + v >= argc) + DIE("-tags: invalid arguments"); + if (tags) { + for (uint32_t j = 0; j < tags_l; j++) + free(tags[j]); + free(tags); + } + if (!(tags = malloc(v * sizeof(char *)))) + EDIE("malloc"); + for (int j = 0; j < v; j++) + if (!(tags[j] = strdup(argv[i + 1 + j]))) + EDIE("strdup"); + tags_l = tags_c = v; + i += v; + } else if (!strcmp(argv[i], "-scale")) { + if (++i >= argc) + DIE("Option -scale requires an argument"); + buffer_scale = strtoul(argv[i], &argv[i] + strlen(argv[i]), 10); + } else if (!strcmp(argv[i], "-v")) { + fprintf(stderr, PROGRAM " " VERSION "\n"); + return 0; + } else if (!strcmp(argv[i], "-h")) { + fprintf(stderr, USAGE); + return 0; + } else { + DIE("Option '%s' not recognized\n" USAGE, argv[i]); + } + } + + /* Set up display and protocols */ + display = wl_display_connect(NULL); + if (!display) + DIE("Failed to create display"); + + wl_list_init(&bar_list); + wl_list_init(&seat_list); + + struct wl_registry *registry = wl_display_get_registry(display); + wl_registry_add_listener(registry, ®istry_listener, NULL); + wl_display_roundtrip(display); + if (!compositor || !shm || !layer_shell || !output_manager || (ipc && !dwl_wm)) + DIE("Compositor does not support all needed protocols"); + + /* Load selected font */ + fcft_init(FCFT_LOG_COLORIZE_AUTO, 0, FCFT_LOG_CLASS_ERROR); + fcft_set_scaling_filter(FCFT_SCALING_FILTER_LANCZOS3); + + unsigned int dpi = 96 * buffer_scale; + char buf[10]; + snprintf(buf, sizeof buf, "dpi=%u", dpi); + if (!(font = fcft_from_name(1, (const char *[]) {fontstr}, buf))) + DIE("Could not load font"); + textpadding = font->height / 2; + height = font->height / buffer_scale + vertical_padding * 2; + + /* Configure tag names */ + if (!ipc && !tags) { + if (!(tags = malloc(LENGTH(tags_names) * sizeof(char *)))) + EDIE("malloc"); + tags_l = tags_c = LENGTH(tags_names); + for (uint32_t i = 0; i < tags_l; i++) + if (!(tags[i] = strdup(tags_names[i]))) + EDIE("strdup"); + } + + /* Setup bars */ + wl_list_for_each(bar, &bar_list, link) + setup_bar(bar); + wl_display_roundtrip(display); + + if (!ipc) { + /* Configure stdin */ + if (fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK) == -1) + EDIE("fcntl"); + + /* Allocate stdin buffer */ + if (!(stdinbuf = malloc(1024))) + EDIE("malloc"); + stdinbuf_cap = 1024; + } + + /* Set up socket */ + bool found = false; + for (uint32_t i = 0; i < 50; i++) { + if ((sock_fd = socket(AF_UNIX, SOCK_STREAM, 1)) == -1) + DIE("socket"); + snprintf(sock_address.sun_path, sizeof sock_address.sun_path, "%s/dwlb-%i", socketdir, i); + if (connect(sock_fd, (struct sockaddr *)&sock_address, sizeof sock_address) == -1) { + found = true; + break; + } + close(sock_fd); + } + if (!found) + DIE("Could not secure a socket path"); + + socketpath = (char *)&sock_address.sun_path; + unlink(socketpath); + if (bind(sock_fd, (struct sockaddr *)&sock_address, sizeof sock_address) == -1) + EDIE("bind"); + if (listen(sock_fd, SOMAXCONN) == -1) + EDIE("listen"); + fcntl(sock_fd, F_SETFD, FD_CLOEXEC | fcntl(sock_fd, F_GETFD)); + + /* Set up signals */ + signal(SIGINT, sig_handler); + signal(SIGHUP, sig_handler); + signal(SIGTERM, sig_handler); + signal(SIGCHLD, SIG_IGN); + + /* Run */ + run_display = true; + event_loop(); + + /* Clean everything up */ + close(sock_fd); + unlink(socketpath); + + if (!ipc) + free(stdinbuf); + + if (tags) { + for (uint32_t i = 0; i < tags_l; i++) + free(tags[i]); + free(tags); + } + if (layouts) { + for (uint32_t i = 0; i < layouts_l; i++) + free(layouts[i]); + free(layouts); + } + + wl_list_for_each_safe(bar, bar2, &bar_list, link) + teardown_bar(bar); + wl_list_for_each_safe(seat, seat2, &seat_list, link) + teardown_seat(seat); + + zwlr_layer_shell_v1_destroy(layer_shell); + zxdg_output_manager_v1_destroy(output_manager); + if (ipc) + zdwl_ipc_manager_v2_destroy(dwl_wm); + + fcft_destroy(font); + fcft_fini(); + + wl_shm_destroy(shm); + wl_compositor_destroy(compositor); + wl_registry_destroy(registry); + wl_display_disconnect(display); + + return 0; +} diff --git a/dwlb.o b/dwlb.o new file mode 100644 index 0000000000000000000000000000000000000000..68ea67d5e6ac63acb3b88e72b2665661d38c3956 GIT binary patch literal 146200 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 e-f*qM0t3I3$;;yxn&->?J~I{`xc + + + + This protocol allows clients to update and get updates from dwl. + + Warning! The protocol described in this file is experimental and + backward incompatible changes may be made. Backward compatible + changes may be added together with the corresponding interface + version bump. + Backward incompatible changes are done by bumping the version + number in the protocol and interface names and resetting the + interface version. Once the protocol is to be declared stable, + the 'z' prefix and the version number in the protocol and + interface names are removed and the interface version number is + reset. + + + + + This interface is exposed as a global in wl_registry. + + Clients can use this interface to get a dwl_ipc_output. + After binding the client will recieve the dwl_ipc_manager.tags and dwl_ipc_manager.layout events. + The dwl_ipc_manager.tags and dwl_ipc_manager.layout events expose tags and layouts to the client. + + + + + Indicates that the client will not the dwl_ipc_manager object anymore. + Objects created through this instance are not affected. + + + + + + Get a dwl_ipc_outout for the specified wl_output. + + + + + + + + This event is sent after binding. + A roundtrip after binding guarantees the client recieved all tags. + + + + + + + This event is sent after binding. + A roundtrip after binding guarantees the client recieved all layouts. + + + + + + + + Observe and control a dwl output. + + Events are double-buffered: + Clients should cache events and redraw when a dwl_ipc_output.frame event is sent. + + Request are not double-buffered: + The compositor will update immediately upon request. + + + + + + + + + + + Indicates to that the client no longer needs this dwl_ipc_output. + + + + + + Indicates the client should hide or show themselves. + If the client is visible then hide, if hidden then show. + + + + + + Indicates if the output is active. Zero is invalid, nonzero is valid. + + + + + + + Indicates that a tag has been updated. + + + + + + + + + + Indicates a new layout is selected. + + + + + + + Indicates the title has changed. + + + + + + + Indicates the appid has changed. + + + + + + + Indicates the layout has changed. Since layout symbols are dynamic. + As opposed to the zdwl_ipc_manager.layout event, this should take precendence when displaying. + You can ignore the zdwl_ipc_output.layout event. + + + + + + + Indicates that a sequence of status updates have finished and the client should redraw. + + + + + + + + + + + + The tags are updated as follows: + new_tags = (current_tags AND and_tags) XOR xor_tags + + + + + + + + + + + + + + Indicates if the selected client on this output is fullscreen. + + + + + + + Indicates if the selected client on this output is floating. + + + + + diff --git a/protocols/wlr-layer-shell-unstable-v1.xml b/protocols/wlr-layer-shell-unstable-v1.xml new file mode 100644 index 0000000..d62fd51 --- /dev/null +++ b/protocols/wlr-layer-shell-unstable-v1.xml @@ -0,0 +1,390 @@ + + + + Copyright © 2017 Drew DeVault + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that copyright notice and this permission + notice appear in supporting documentation, and that the name of + the copyright holders not be used in advertising or publicity + pertaining to distribution of the software without specific, + written prior permission. The copyright holders make no + representations about the suitability of this software for any + purpose. It is provided "as is" without express or implied + warranty. + + THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF + THIS SOFTWARE. + + + + + Clients can use this interface to assign the surface_layer role to + wl_surfaces. Such surfaces are assigned to a "layer" of the output and + rendered with a defined z-depth respective to each other. They may also be + anchored to the edges and corners of a screen and specify input handling + semantics. This interface should be suitable for the implementation of + many desktop shell components, and a broad number of other applications + that interact with the desktop. + + + + + Create a layer surface for an existing surface. This assigns the role of + layer_surface, or raises a protocol error if another role is already + assigned. + + Creating a layer surface from a wl_surface which has a buffer attached + or committed is a client error, and any attempts by a client to attach + or manipulate a buffer prior to the first layer_surface.configure call + must also be treated as errors. + + After creating a layer_surface object and setting it up, the client + must perform an initial commit without any buffer attached. + The compositor will reply with a layer_surface.configure event. + The client must acknowledge it and is then allowed to attach a buffer + to map the surface. + + You may pass NULL for output to allow the compositor to decide which + output to use. Generally this will be the one that the user most + recently interacted with. + + Clients can specify a namespace that defines the purpose of the layer + surface. + + + + + + + + + + + + + + + + + These values indicate which layers a surface can be rendered in. They + are ordered by z depth, bottom-most first. Traditional shell surfaces + will typically be rendered between the bottom and top layers. + Fullscreen shell surfaces are typically rendered at the top layer. + Multiple surfaces can share a single layer, and ordering within a + single layer is undefined. + + + + + + + + + + + + + This request indicates that the client will not use the layer_shell + object any more. Objects that have been created through this instance + are not affected. + + + + + + + An interface that may be implemented by a wl_surface, for surfaces that + are designed to be rendered as a layer of a stacked desktop-like + environment. + + Layer surface state (layer, size, anchor, exclusive zone, + margin, interactivity) is double-buffered, and will be applied at the + time wl_surface.commit of the corresponding wl_surface is called. + + Attaching a null buffer to a layer surface unmaps it. + + Unmapping a layer_surface means that the surface cannot be shown by the + compositor until it is explicitly mapped again. The layer_surface + returns to the state it had right after layer_shell.get_layer_surface. + The client can re-map the surface by performing a commit without any + buffer attached, waiting for a configure event and handling it as usual. + + + + + Sets the size of the surface in surface-local coordinates. The + compositor will display the surface centered with respect to its + anchors. + + If you pass 0 for either value, the compositor will assign it and + inform you of the assignment in the configure event. You must set your + anchor to opposite edges in the dimensions you omit; not doing so is a + protocol error. Both values are 0 by default. + + Size is double-buffered, see wl_surface.commit. + + + + + + + + Requests that the compositor anchor the surface to the specified edges + and corners. If two orthogonal edges are specified (e.g. 'top' and + 'left'), then the anchor point will be the intersection of the edges + (e.g. the top left corner of the output); otherwise the anchor point + will be centered on that edge, or in the center if none is specified. + + Anchor is double-buffered, see wl_surface.commit. + + + + + + + Requests that the compositor avoids occluding an area with other + surfaces. The compositor's use of this information is + implementation-dependent - do not assume that this region will not + actually be occluded. + + A positive value is only meaningful if the surface is anchored to one + edge or an edge and both perpendicular edges. If the surface is not + anchored, anchored to only two perpendicular edges (a corner), anchored + to only two parallel edges or anchored to all edges, a positive value + will be treated the same as zero. + + A positive zone is the distance from the edge in surface-local + coordinates to consider exclusive. + + Surfaces that do not wish to have an exclusive zone may instead specify + how they should interact with surfaces that do. If set to zero, the + surface indicates that it would like to be moved to avoid occluding + surfaces with a positive exclusive zone. If set to -1, the surface + indicates that it would not like to be moved to accommodate for other + surfaces, and the compositor should extend it all the way to the edges + it is anchored to. + + For example, a panel might set its exclusive zone to 10, so that + maximized shell surfaces are not shown on top of it. A notification + might set its exclusive zone to 0, so that it is moved to avoid + occluding the panel, but shell surfaces are shown underneath it. A + wallpaper or lock screen might set their exclusive zone to -1, so that + they stretch below or over the panel. + + The default value is 0. + + Exclusive zone is double-buffered, see wl_surface.commit. + + + + + + + Requests that the surface be placed some distance away from the anchor + point on the output, in surface-local coordinates. Setting this value + for edges you are not anchored to has no effect. + + The exclusive zone includes the margin. + + Margin is double-buffered, see wl_surface.commit. + + + + + + + + + + Types of keyboard interaction possible for layer shell surfaces. The + rationale for this is twofold: (1) some applications are not interested + in keyboard events and not allowing them to be focused can improve the + desktop experience; (2) some applications will want to take exclusive + keyboard focus. + + + + + This value indicates that this surface is not interested in keyboard + events and the compositor should never assign it the keyboard focus. + + This is the default value, set for newly created layer shell surfaces. + + This is useful for e.g. desktop widgets that display information or + only have interaction with non-keyboard input devices. + + + + + Request exclusive keyboard focus if this surface is above the shell surface layer. + + For the top and overlay layers, the seat will always give + exclusive keyboard focus to the top-most layer which has keyboard + interactivity set to exclusive. If this layer contains multiple + surfaces with keyboard interactivity set to exclusive, the compositor + determines the one receiving keyboard events in an implementation- + defined manner. In this case, no guarantee is made when this surface + will receive keyboard focus (if ever). + + For the bottom and background layers, the compositor is allowed to use + normal focus semantics. + + This setting is mainly intended for applications that need to ensure + they receive all keyboard events, such as a lock screen or a password + prompt. + + + + + This requests the compositor to allow this surface to be focused and + unfocused by the user in an implementation-defined manner. The user + should be able to unfocus this surface even regardless of the layer + it is on. + + Typically, the compositor will want to use its normal mechanism to + manage keyboard focus between layer shell surfaces with this setting + and regular toplevels on the desktop layer (e.g. click to focus). + Nevertheless, it is possible for a compositor to require a special + interaction to focus or unfocus layer shell surfaces (e.g. requiring + a click even if focus follows the mouse normally, or providing a + keybinding to switch focus between layers). + + This setting is mainly intended for desktop shell components (e.g. + panels) that allow keyboard interaction. Using this option can allow + implementing a desktop shell that can be fully usable without the + mouse. + + + + + + + Set how keyboard events are delivered to this surface. By default, + layer shell surfaces do not receive keyboard events; this request can + be used to change this. + + This setting is inherited by child surfaces set by the get_popup + request. + + Layer surfaces receive pointer, touch, and tablet events normally. If + you do not want to receive them, set the input region on your surface + to an empty region. + + Keyboard interactivity is double-buffered, see wl_surface.commit. + + + + + + + This assigns an xdg_popup's parent to this layer_surface. This popup + should have been created via xdg_surface::get_popup with the parent set + to NULL, and this request must be invoked before committing the popup's + initial state. + + See the documentation of xdg_popup for more details about what an + xdg_popup is and how it is used. + + + + + + + When a configure event is received, if a client commits the + surface in response to the configure event, then the client + must make an ack_configure request sometime before the commit + request, passing along the serial of the configure event. + + If the client receives multiple configure events before it + can respond to one, it only has to ack the last configure event. + + A client is not required to commit immediately after sending + an ack_configure request - it may even ack_configure several times + before its next surface commit. + + A client may send multiple ack_configure requests before committing, but + only the last request sent before a commit indicates which configure + event the client really is responding to. + + + + + + + This request destroys the layer surface. + + + + + + The configure event asks the client to resize its surface. + + Clients should arrange their surface for the new states, and then send + an ack_configure request with the serial sent in this configure event at + some point before committing the new surface. + + The client is free to dismiss all but the last configure event it + received. + + The width and height arguments specify the size of the window in + surface-local coordinates. + + The size is a hint, in the sense that the client is free to ignore it if + it doesn't resize, pick a smaller size (to satisfy aspect ratio or + resize in steps of NxM pixels). If the client picks a smaller size and + is anchored to two opposite anchors (e.g. 'top' and 'bottom'), the + surface will be centered on this axis. + + If the width or height arguments are zero, it means the client should + decide its own window dimension. + + + + + + + + + The closed event is sent by the compositor when the surface will no + longer be shown. The output may have been destroyed or the user may + have asked for it to be removed. Further changes to the surface will be + ignored. The client should destroy the resource after receiving this + event, and create a new surface if they so choose. + + + + + + + + + + + + + + + + + + + + + + Change the layer that the surface is rendered on. + + Layer is double-buffered, see wl_surface.commit. + + + + + diff --git a/screenshot1.png b/screenshot1.png new file mode 100644 index 0000000000000000000000000000000000000000..025634c107b455a67573de63e3332b6eb25a9a23 GIT binary patch literal 18524 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%0D}k9WDI*QZv83zaP_jBtu$G4$Z~Y^-HY_ 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 Zz6~-*HEKk(_`j~)%S)?B6-k=<{~uJkZ}0#B literal 0 HcmV?d00001 diff --git a/utf8.h b/utf8.h new file mode 100644 index 0000000..c7db188 --- /dev/null +++ b/utf8.h @@ -0,0 +1,55 @@ +// Copyright (c) 2008-2009 Bjoern Hoehrmann +// See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details. + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#include + +#define UTF8_ACCEPT 0 +#define UTF8_REJECT 1 + +static const uint8_t utf8d[] = { + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 00..1f + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 20..3f + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 40..5f + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 60..7f + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, // 80..9f + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, // a0..bf + 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // c0..df + 0xa,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x4,0x3,0x3, // e0..ef + 0xb,0x6,0x6,0x6,0x5,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8, // f0..ff + 0x0,0x1,0x2,0x3,0x5,0x8,0x7,0x1,0x1,0x1,0x4,0x6,0x1,0x1,0x1,0x1, // s0..s0 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,1, // s1..s2 + 1,2,1,1,1,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1, // s3..s4 + 1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1, // s5..s6 + 1,3,1,1,1,1,1,3,1,3,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // s7..s8 +}; + +static inline uint32_t +utf8decode(uint32_t *state, uint32_t *codep, uint8_t byte) +{ + uint32_t type = utf8d[byte]; + + *codep = (*state != UTF8_ACCEPT) ? + (byte & 0x3fu) | (*codep << 6) : + (0xff >> type) & (byte); + + *state = utf8d[256 + *state*16 + type]; + return *state; +} diff --git a/wlr-layer-shell-unstable-v1-protocol.c b/wlr-layer-shell-unstable-v1-protocol.c new file mode 100644 index 0000000..0d5fa31 --- /dev/null +++ b/wlr-layer-shell-unstable-v1-protocol.c @@ -0,0 +1,94 @@ +/* Generated by wayland-scanner 1.24.0 */ + +/* + * Copyright © 2017 Drew DeVault + * + * Permission to use, copy, modify, distribute, and sell this + * software and its documentation for any purpose is hereby granted + * without fee, provided that the above copyright notice appear in + * all copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of + * the copyright holders not be used in advertising or publicity + * pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied + * warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF + * THIS SOFTWARE. + */ + +#include +#include +#include +#include "wayland-util.h" + +#ifndef __has_attribute +# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */ +#endif + +#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4) +#define WL_PRIVATE __attribute__ ((visibility("hidden"))) +#else +#define WL_PRIVATE +#endif + +extern const struct wl_interface wl_output_interface; +extern const struct wl_interface wl_surface_interface; +extern const struct wl_interface xdg_popup_interface; +extern const struct wl_interface zwlr_layer_surface_v1_interface; + +static const struct wl_interface *wlr_layer_shell_unstable_v1_types[] = { + NULL, + NULL, + NULL, + NULL, + &zwlr_layer_surface_v1_interface, + &wl_surface_interface, + &wl_output_interface, + NULL, + NULL, + &xdg_popup_interface, +}; + +static const struct wl_message zwlr_layer_shell_v1_requests[] = { + { "get_layer_surface", "no?ous", wlr_layer_shell_unstable_v1_types + 4 }, + { "destroy", "3", wlr_layer_shell_unstable_v1_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface zwlr_layer_shell_v1_interface = { + "zwlr_layer_shell_v1", 4, + 2, zwlr_layer_shell_v1_requests, + 0, NULL, +}; + +static const struct wl_message zwlr_layer_surface_v1_requests[] = { + { "set_size", "uu", wlr_layer_shell_unstable_v1_types + 0 }, + { "set_anchor", "u", wlr_layer_shell_unstable_v1_types + 0 }, + { "set_exclusive_zone", "i", wlr_layer_shell_unstable_v1_types + 0 }, + { "set_margin", "iiii", wlr_layer_shell_unstable_v1_types + 0 }, + { "set_keyboard_interactivity", "u", wlr_layer_shell_unstable_v1_types + 0 }, + { "get_popup", "o", wlr_layer_shell_unstable_v1_types + 9 }, + { "ack_configure", "u", wlr_layer_shell_unstable_v1_types + 0 }, + { "destroy", "", wlr_layer_shell_unstable_v1_types + 0 }, + { "set_layer", "2u", wlr_layer_shell_unstable_v1_types + 0 }, +}; + +static const struct wl_message zwlr_layer_surface_v1_events[] = { + { "configure", "uuu", wlr_layer_shell_unstable_v1_types + 0 }, + { "closed", "", wlr_layer_shell_unstable_v1_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface zwlr_layer_surface_v1_interface = { + "zwlr_layer_surface_v1", 4, + 9, zwlr_layer_surface_v1_requests, + 2, zwlr_layer_surface_v1_events, +}; + diff --git a/wlr-layer-shell-unstable-v1-protocol.h b/wlr-layer-shell-unstable-v1-protocol.h new file mode 100644 index 0000000..847e201 --- /dev/null +++ b/wlr-layer-shell-unstable-v1-protocol.h @@ -0,0 +1,706 @@ +/* Generated by wayland-scanner 1.24.0 */ + +#ifndef WLR_LAYER_SHELL_UNSTABLE_V1_CLIENT_PROTOCOL_H +#define WLR_LAYER_SHELL_UNSTABLE_V1_CLIENT_PROTOCOL_H + +#include +#include +#include "wayland-client.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @page page_wlr_layer_shell_unstable_v1 The wlr_layer_shell_unstable_v1 protocol + * @section page_ifaces_wlr_layer_shell_unstable_v1 Interfaces + * - @subpage page_iface_zwlr_layer_shell_v1 - create surfaces that are layers of the desktop + * - @subpage page_iface_zwlr_layer_surface_v1 - layer metadata interface + * @section page_copyright_wlr_layer_shell_unstable_v1 Copyright + *
+ *
+ * Copyright © 2017 Drew DeVault
+ *
+ * Permission to use, copy, modify, distribute, and sell this
+ * software and its documentation for any purpose is hereby granted
+ * without fee, provided that the above copyright notice appear in
+ * all copies and that both that copyright notice and this permission
+ * notice appear in supporting documentation, and that the name of
+ * the copyright holders not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ * THIS SOFTWARE.
+ * 
+ */ +struct wl_output; +struct wl_surface; +struct xdg_popup; +struct zwlr_layer_shell_v1; +struct zwlr_layer_surface_v1; + +#ifndef ZWLR_LAYER_SHELL_V1_INTERFACE +#define ZWLR_LAYER_SHELL_V1_INTERFACE +/** + * @page page_iface_zwlr_layer_shell_v1 zwlr_layer_shell_v1 + * @section page_iface_zwlr_layer_shell_v1_desc Description + * + * Clients can use this interface to assign the surface_layer role to + * wl_surfaces. Such surfaces are assigned to a "layer" of the output and + * rendered with a defined z-depth respective to each other. They may also be + * anchored to the edges and corners of a screen and specify input handling + * semantics. This interface should be suitable for the implementation of + * many desktop shell components, and a broad number of other applications + * that interact with the desktop. + * @section page_iface_zwlr_layer_shell_v1_api API + * See @ref iface_zwlr_layer_shell_v1. + */ +/** + * @defgroup iface_zwlr_layer_shell_v1 The zwlr_layer_shell_v1 interface + * + * Clients can use this interface to assign the surface_layer role to + * wl_surfaces. Such surfaces are assigned to a "layer" of the output and + * rendered with a defined z-depth respective to each other. They may also be + * anchored to the edges and corners of a screen and specify input handling + * semantics. This interface should be suitable for the implementation of + * many desktop shell components, and a broad number of other applications + * that interact with the desktop. + */ +extern const struct wl_interface zwlr_layer_shell_v1_interface; +#endif +#ifndef ZWLR_LAYER_SURFACE_V1_INTERFACE +#define ZWLR_LAYER_SURFACE_V1_INTERFACE +/** + * @page page_iface_zwlr_layer_surface_v1 zwlr_layer_surface_v1 + * @section page_iface_zwlr_layer_surface_v1_desc Description + * + * An interface that may be implemented by a wl_surface, for surfaces that + * are designed to be rendered as a layer of a stacked desktop-like + * environment. + * + * Layer surface state (layer, size, anchor, exclusive zone, + * margin, interactivity) is double-buffered, and will be applied at the + * time wl_surface.commit of the corresponding wl_surface is called. + * + * Attaching a null buffer to a layer surface unmaps it. + * + * Unmapping a layer_surface means that the surface cannot be shown by the + * compositor until it is explicitly mapped again. The layer_surface + * returns to the state it had right after layer_shell.get_layer_surface. + * The client can re-map the surface by performing a commit without any + * buffer attached, waiting for a configure event and handling it as usual. + * @section page_iface_zwlr_layer_surface_v1_api API + * See @ref iface_zwlr_layer_surface_v1. + */ +/** + * @defgroup iface_zwlr_layer_surface_v1 The zwlr_layer_surface_v1 interface + * + * An interface that may be implemented by a wl_surface, for surfaces that + * are designed to be rendered as a layer of a stacked desktop-like + * environment. + * + * Layer surface state (layer, size, anchor, exclusive zone, + * margin, interactivity) is double-buffered, and will be applied at the + * time wl_surface.commit of the corresponding wl_surface is called. + * + * Attaching a null buffer to a layer surface unmaps it. + * + * Unmapping a layer_surface means that the surface cannot be shown by the + * compositor until it is explicitly mapped again. The layer_surface + * returns to the state it had right after layer_shell.get_layer_surface. + * The client can re-map the surface by performing a commit without any + * buffer attached, waiting for a configure event and handling it as usual. + */ +extern const struct wl_interface zwlr_layer_surface_v1_interface; +#endif + +#ifndef ZWLR_LAYER_SHELL_V1_ERROR_ENUM +#define ZWLR_LAYER_SHELL_V1_ERROR_ENUM +enum zwlr_layer_shell_v1_error { + /** + * wl_surface has another role + */ + ZWLR_LAYER_SHELL_V1_ERROR_ROLE = 0, + /** + * layer value is invalid + */ + ZWLR_LAYER_SHELL_V1_ERROR_INVALID_LAYER = 1, + /** + * wl_surface has a buffer attached or committed + */ + ZWLR_LAYER_SHELL_V1_ERROR_ALREADY_CONSTRUCTED = 2, +}; +#endif /* ZWLR_LAYER_SHELL_V1_ERROR_ENUM */ + +#ifndef ZWLR_LAYER_SHELL_V1_LAYER_ENUM +#define ZWLR_LAYER_SHELL_V1_LAYER_ENUM +/** + * @ingroup iface_zwlr_layer_shell_v1 + * available layers for surfaces + * + * These values indicate which layers a surface can be rendered in. They + * are ordered by z depth, bottom-most first. Traditional shell surfaces + * will typically be rendered between the bottom and top layers. + * Fullscreen shell surfaces are typically rendered at the top layer. + * Multiple surfaces can share a single layer, and ordering within a + * single layer is undefined. + */ +enum zwlr_layer_shell_v1_layer { + ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND = 0, + ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM = 1, + ZWLR_LAYER_SHELL_V1_LAYER_TOP = 2, + ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY = 3, +}; +#endif /* ZWLR_LAYER_SHELL_V1_LAYER_ENUM */ + +#define ZWLR_LAYER_SHELL_V1_GET_LAYER_SURFACE 0 +#define ZWLR_LAYER_SHELL_V1_DESTROY 1 + + +/** + * @ingroup iface_zwlr_layer_shell_v1 + */ +#define ZWLR_LAYER_SHELL_V1_GET_LAYER_SURFACE_SINCE_VERSION 1 +/** + * @ingroup iface_zwlr_layer_shell_v1 + */ +#define ZWLR_LAYER_SHELL_V1_DESTROY_SINCE_VERSION 3 + +/** @ingroup iface_zwlr_layer_shell_v1 */ +static inline void +zwlr_layer_shell_v1_set_user_data(struct zwlr_layer_shell_v1 *zwlr_layer_shell_v1, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) zwlr_layer_shell_v1, user_data); +} + +/** @ingroup iface_zwlr_layer_shell_v1 */ +static inline void * +zwlr_layer_shell_v1_get_user_data(struct zwlr_layer_shell_v1 *zwlr_layer_shell_v1) +{ + return wl_proxy_get_user_data((struct wl_proxy *) zwlr_layer_shell_v1); +} + +static inline uint32_t +zwlr_layer_shell_v1_get_version(struct zwlr_layer_shell_v1 *zwlr_layer_shell_v1) +{ + return wl_proxy_get_version((struct wl_proxy *) zwlr_layer_shell_v1); +} + +/** + * @ingroup iface_zwlr_layer_shell_v1 + * + * Create a layer surface for an existing surface. This assigns the role of + * layer_surface, or raises a protocol error if another role is already + * assigned. + * + * Creating a layer surface from a wl_surface which has a buffer attached + * or committed is a client error, and any attempts by a client to attach + * or manipulate a buffer prior to the first layer_surface.configure call + * must also be treated as errors. + * + * After creating a layer_surface object and setting it up, the client + * must perform an initial commit without any buffer attached. + * The compositor will reply with a layer_surface.configure event. + * The client must acknowledge it and is then allowed to attach a buffer + * to map the surface. + * + * You may pass NULL for output to allow the compositor to decide which + * output to use. Generally this will be the one that the user most + * recently interacted with. + * + * Clients can specify a namespace that defines the purpose of the layer + * surface. + */ +static inline struct zwlr_layer_surface_v1 * +zwlr_layer_shell_v1_get_layer_surface(struct zwlr_layer_shell_v1 *zwlr_layer_shell_v1, struct wl_surface *surface, struct wl_output *output, uint32_t layer, const char *namespace) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) zwlr_layer_shell_v1, + ZWLR_LAYER_SHELL_V1_GET_LAYER_SURFACE, &zwlr_layer_surface_v1_interface, wl_proxy_get_version((struct wl_proxy *) zwlr_layer_shell_v1), 0, NULL, surface, output, layer, namespace); + + return (struct zwlr_layer_surface_v1 *) id; +} + +/** + * @ingroup iface_zwlr_layer_shell_v1 + * + * This request indicates that the client will not use the layer_shell + * object any more. Objects that have been created through this instance + * are not affected. + */ +static inline void +zwlr_layer_shell_v1_destroy(struct zwlr_layer_shell_v1 *zwlr_layer_shell_v1) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zwlr_layer_shell_v1, + ZWLR_LAYER_SHELL_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwlr_layer_shell_v1), WL_MARSHAL_FLAG_DESTROY); +} + +#ifndef ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_ENUM +#define ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_ENUM +/** + * @ingroup iface_zwlr_layer_surface_v1 + * types of keyboard interaction possible for a layer shell surface + * + * Types of keyboard interaction possible for layer shell surfaces. The + * rationale for this is twofold: (1) some applications are not interested + * in keyboard events and not allowing them to be focused can improve the + * desktop experience; (2) some applications will want to take exclusive + * keyboard focus. + */ +enum zwlr_layer_surface_v1_keyboard_interactivity { + /** + * no keyboard focus is possible + * + * This value indicates that this surface is not interested in + * keyboard events and the compositor should never assign it the + * keyboard focus. + * + * This is the default value, set for newly created layer shell + * surfaces. + * + * This is useful for e.g. desktop widgets that display information + * or only have interaction with non-keyboard input devices. + */ + ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE = 0, + /** + * request exclusive keyboard focus + * + * Request exclusive keyboard focus if this surface is above the + * shell surface layer. + * + * For the top and overlay layers, the seat will always give + * exclusive keyboard focus to the top-most layer which has + * keyboard interactivity set to exclusive. If this layer contains + * multiple surfaces with keyboard interactivity set to exclusive, + * the compositor determines the one receiving keyboard events in + * an implementation- defined manner. In this case, no guarantee is + * made when this surface will receive keyboard focus (if ever). + * + * For the bottom and background layers, the compositor is allowed + * to use normal focus semantics. + * + * This setting is mainly intended for applications that need to + * ensure they receive all keyboard events, such as a lock screen + * or a password prompt. + */ + ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE = 1, + /** + * request regular keyboard focus semantics + * + * This requests the compositor to allow this surface to be + * focused and unfocused by the user in an implementation-defined + * manner. The user should be able to unfocus this surface even + * regardless of the layer it is on. + * + * Typically, the compositor will want to use its normal mechanism + * to manage keyboard focus between layer shell surfaces with this + * setting and regular toplevels on the desktop layer (e.g. click + * to focus). Nevertheless, it is possible for a compositor to + * require a special interaction to focus or unfocus layer shell + * surfaces (e.g. requiring a click even if focus follows the mouse + * normally, or providing a keybinding to switch focus between + * layers). + * + * This setting is mainly intended for desktop shell components + * (e.g. panels) that allow keyboard interaction. Using this option + * can allow implementing a desktop shell that can be fully usable + * without the mouse. + * @since 4 + */ + ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_ON_DEMAND = 2, +}; +/** + * @ingroup iface_zwlr_layer_surface_v1 + */ +#define ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_ON_DEMAND_SINCE_VERSION 4 +#endif /* ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_ENUM */ + +#ifndef ZWLR_LAYER_SURFACE_V1_ERROR_ENUM +#define ZWLR_LAYER_SURFACE_V1_ERROR_ENUM +enum zwlr_layer_surface_v1_error { + /** + * provided surface state is invalid + */ + ZWLR_LAYER_SURFACE_V1_ERROR_INVALID_SURFACE_STATE = 0, + /** + * size is invalid + */ + ZWLR_LAYER_SURFACE_V1_ERROR_INVALID_SIZE = 1, + /** + * anchor bitfield is invalid + */ + ZWLR_LAYER_SURFACE_V1_ERROR_INVALID_ANCHOR = 2, + /** + * keyboard interactivity is invalid + */ + ZWLR_LAYER_SURFACE_V1_ERROR_INVALID_KEYBOARD_INTERACTIVITY = 3, +}; +#endif /* ZWLR_LAYER_SURFACE_V1_ERROR_ENUM */ + +#ifndef ZWLR_LAYER_SURFACE_V1_ANCHOR_ENUM +#define ZWLR_LAYER_SURFACE_V1_ANCHOR_ENUM +enum zwlr_layer_surface_v1_anchor { + /** + * the top edge of the anchor rectangle + */ + ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP = 1, + /** + * the bottom edge of the anchor rectangle + */ + ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM = 2, + /** + * the left edge of the anchor rectangle + */ + ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT = 4, + /** + * the right edge of the anchor rectangle + */ + ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT = 8, +}; +#endif /* ZWLR_LAYER_SURFACE_V1_ANCHOR_ENUM */ + +/** + * @ingroup iface_zwlr_layer_surface_v1 + * @struct zwlr_layer_surface_v1_listener + */ +struct zwlr_layer_surface_v1_listener { + /** + * suggest a surface change + * + * The configure event asks the client to resize its surface. + * + * Clients should arrange their surface for the new states, and + * then send an ack_configure request with the serial sent in this + * configure event at some point before committing the new surface. + * + * The client is free to dismiss all but the last configure event + * it received. + * + * The width and height arguments specify the size of the window in + * surface-local coordinates. + * + * The size is a hint, in the sense that the client is free to + * ignore it if it doesn't resize, pick a smaller size (to satisfy + * aspect ratio or resize in steps of NxM pixels). If the client + * picks a smaller size and is anchored to two opposite anchors + * (e.g. 'top' and 'bottom'), the surface will be centered on this + * axis. + * + * If the width or height arguments are zero, it means the client + * should decide its own window dimension. + */ + void (*configure)(void *data, + struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, + uint32_t serial, + uint32_t width, + uint32_t height); + /** + * surface should be closed + * + * The closed event is sent by the compositor when the surface + * will no longer be shown. The output may have been destroyed or + * the user may have asked for it to be removed. Further changes to + * the surface will be ignored. The client should destroy the + * resource after receiving this event, and create a new surface if + * they so choose. + */ + void (*closed)(void *data, + struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1); +}; + +/** + * @ingroup iface_zwlr_layer_surface_v1 + */ +static inline int +zwlr_layer_surface_v1_add_listener(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, + const struct zwlr_layer_surface_v1_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) zwlr_layer_surface_v1, + (void (**)(void)) listener, data); +} + +#define ZWLR_LAYER_SURFACE_V1_SET_SIZE 0 +#define ZWLR_LAYER_SURFACE_V1_SET_ANCHOR 1 +#define ZWLR_LAYER_SURFACE_V1_SET_EXCLUSIVE_ZONE 2 +#define ZWLR_LAYER_SURFACE_V1_SET_MARGIN 3 +#define ZWLR_LAYER_SURFACE_V1_SET_KEYBOARD_INTERACTIVITY 4 +#define ZWLR_LAYER_SURFACE_V1_GET_POPUP 5 +#define ZWLR_LAYER_SURFACE_V1_ACK_CONFIGURE 6 +#define ZWLR_LAYER_SURFACE_V1_DESTROY 7 +#define ZWLR_LAYER_SURFACE_V1_SET_LAYER 8 + +/** + * @ingroup iface_zwlr_layer_surface_v1 + */ +#define ZWLR_LAYER_SURFACE_V1_CONFIGURE_SINCE_VERSION 1 +/** + * @ingroup iface_zwlr_layer_surface_v1 + */ +#define ZWLR_LAYER_SURFACE_V1_CLOSED_SINCE_VERSION 1 + +/** + * @ingroup iface_zwlr_layer_surface_v1 + */ +#define ZWLR_LAYER_SURFACE_V1_SET_SIZE_SINCE_VERSION 1 +/** + * @ingroup iface_zwlr_layer_surface_v1 + */ +#define ZWLR_LAYER_SURFACE_V1_SET_ANCHOR_SINCE_VERSION 1 +/** + * @ingroup iface_zwlr_layer_surface_v1 + */ +#define ZWLR_LAYER_SURFACE_V1_SET_EXCLUSIVE_ZONE_SINCE_VERSION 1 +/** + * @ingroup iface_zwlr_layer_surface_v1 + */ +#define ZWLR_LAYER_SURFACE_V1_SET_MARGIN_SINCE_VERSION 1 +/** + * @ingroup iface_zwlr_layer_surface_v1 + */ +#define ZWLR_LAYER_SURFACE_V1_SET_KEYBOARD_INTERACTIVITY_SINCE_VERSION 1 +/** + * @ingroup iface_zwlr_layer_surface_v1 + */ +#define ZWLR_LAYER_SURFACE_V1_GET_POPUP_SINCE_VERSION 1 +/** + * @ingroup iface_zwlr_layer_surface_v1 + */ +#define ZWLR_LAYER_SURFACE_V1_ACK_CONFIGURE_SINCE_VERSION 1 +/** + * @ingroup iface_zwlr_layer_surface_v1 + */ +#define ZWLR_LAYER_SURFACE_V1_DESTROY_SINCE_VERSION 1 +/** + * @ingroup iface_zwlr_layer_surface_v1 + */ +#define ZWLR_LAYER_SURFACE_V1_SET_LAYER_SINCE_VERSION 2 + +/** @ingroup iface_zwlr_layer_surface_v1 */ +static inline void +zwlr_layer_surface_v1_set_user_data(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) zwlr_layer_surface_v1, user_data); +} + +/** @ingroup iface_zwlr_layer_surface_v1 */ +static inline void * +zwlr_layer_surface_v1_get_user_data(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1) +{ + return wl_proxy_get_user_data((struct wl_proxy *) zwlr_layer_surface_v1); +} + +static inline uint32_t +zwlr_layer_surface_v1_get_version(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1) +{ + return wl_proxy_get_version((struct wl_proxy *) zwlr_layer_surface_v1); +} + +/** + * @ingroup iface_zwlr_layer_surface_v1 + * + * Sets the size of the surface in surface-local coordinates. The + * compositor will display the surface centered with respect to its + * anchors. + * + * If you pass 0 for either value, the compositor will assign it and + * inform you of the assignment in the configure event. You must set your + * anchor to opposite edges in the dimensions you omit; not doing so is a + * protocol error. Both values are 0 by default. + * + * Size is double-buffered, see wl_surface.commit. + */ +static inline void +zwlr_layer_surface_v1_set_size(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, uint32_t width, uint32_t height) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zwlr_layer_surface_v1, + ZWLR_LAYER_SURFACE_V1_SET_SIZE, NULL, wl_proxy_get_version((struct wl_proxy *) zwlr_layer_surface_v1), 0, width, height); +} + +/** + * @ingroup iface_zwlr_layer_surface_v1 + * + * Requests that the compositor anchor the surface to the specified edges + * and corners. If two orthogonal edges are specified (e.g. 'top' and + * 'left'), then the anchor point will be the intersection of the edges + * (e.g. the top left corner of the output); otherwise the anchor point + * will be centered on that edge, or in the center if none is specified. + * + * Anchor is double-buffered, see wl_surface.commit. + */ +static inline void +zwlr_layer_surface_v1_set_anchor(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, uint32_t anchor) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zwlr_layer_surface_v1, + ZWLR_LAYER_SURFACE_V1_SET_ANCHOR, NULL, wl_proxy_get_version((struct wl_proxy *) zwlr_layer_surface_v1), 0, anchor); +} + +/** + * @ingroup iface_zwlr_layer_surface_v1 + * + * Requests that the compositor avoids occluding an area with other + * surfaces. The compositor's use of this information is + * implementation-dependent - do not assume that this region will not + * actually be occluded. + * + * A positive value is only meaningful if the surface is anchored to one + * edge or an edge and both perpendicular edges. If the surface is not + * anchored, anchored to only two perpendicular edges (a corner), anchored + * to only two parallel edges or anchored to all edges, a positive value + * will be treated the same as zero. + * + * A positive zone is the distance from the edge in surface-local + * coordinates to consider exclusive. + * + * Surfaces that do not wish to have an exclusive zone may instead specify + * how they should interact with surfaces that do. If set to zero, the + * surface indicates that it would like to be moved to avoid occluding + * surfaces with a positive exclusive zone. If set to -1, the surface + * indicates that it would not like to be moved to accommodate for other + * surfaces, and the compositor should extend it all the way to the edges + * it is anchored to. + * + * For example, a panel might set its exclusive zone to 10, so that + * maximized shell surfaces are not shown on top of it. A notification + * might set its exclusive zone to 0, so that it is moved to avoid + * occluding the panel, but shell surfaces are shown underneath it. A + * wallpaper or lock screen might set their exclusive zone to -1, so that + * they stretch below or over the panel. + * + * The default value is 0. + * + * Exclusive zone is double-buffered, see wl_surface.commit. + */ +static inline void +zwlr_layer_surface_v1_set_exclusive_zone(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, int32_t zone) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zwlr_layer_surface_v1, + ZWLR_LAYER_SURFACE_V1_SET_EXCLUSIVE_ZONE, NULL, wl_proxy_get_version((struct wl_proxy *) zwlr_layer_surface_v1), 0, zone); +} + +/** + * @ingroup iface_zwlr_layer_surface_v1 + * + * Requests that the surface be placed some distance away from the anchor + * point on the output, in surface-local coordinates. Setting this value + * for edges you are not anchored to has no effect. + * + * The exclusive zone includes the margin. + * + * Margin is double-buffered, see wl_surface.commit. + */ +static inline void +zwlr_layer_surface_v1_set_margin(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, int32_t top, int32_t right, int32_t bottom, int32_t left) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zwlr_layer_surface_v1, + ZWLR_LAYER_SURFACE_V1_SET_MARGIN, NULL, wl_proxy_get_version((struct wl_proxy *) zwlr_layer_surface_v1), 0, top, right, bottom, left); +} + +/** + * @ingroup iface_zwlr_layer_surface_v1 + * + * Set how keyboard events are delivered to this surface. By default, + * layer shell surfaces do not receive keyboard events; this request can + * be used to change this. + * + * This setting is inherited by child surfaces set by the get_popup + * request. + * + * Layer surfaces receive pointer, touch, and tablet events normally. If + * you do not want to receive them, set the input region on your surface + * to an empty region. + * + * Keyboard interactivity is double-buffered, see wl_surface.commit. + */ +static inline void +zwlr_layer_surface_v1_set_keyboard_interactivity(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, uint32_t keyboard_interactivity) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zwlr_layer_surface_v1, + ZWLR_LAYER_SURFACE_V1_SET_KEYBOARD_INTERACTIVITY, NULL, wl_proxy_get_version((struct wl_proxy *) zwlr_layer_surface_v1), 0, keyboard_interactivity); +} + +/** + * @ingroup iface_zwlr_layer_surface_v1 + * + * This assigns an xdg_popup's parent to this layer_surface. This popup + * should have been created via xdg_surface::get_popup with the parent set + * to NULL, and this request must be invoked before committing the popup's + * initial state. + * + * See the documentation of xdg_popup for more details about what an + * xdg_popup is and how it is used. + */ +static inline void +zwlr_layer_surface_v1_get_popup(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, struct xdg_popup *popup) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zwlr_layer_surface_v1, + ZWLR_LAYER_SURFACE_V1_GET_POPUP, NULL, wl_proxy_get_version((struct wl_proxy *) zwlr_layer_surface_v1), 0, popup); +} + +/** + * @ingroup iface_zwlr_layer_surface_v1 + * + * When a configure event is received, if a client commits the + * surface in response to the configure event, then the client + * must make an ack_configure request sometime before the commit + * request, passing along the serial of the configure event. + * + * If the client receives multiple configure events before it + * can respond to one, it only has to ack the last configure event. + * + * A client is not required to commit immediately after sending + * an ack_configure request - it may even ack_configure several times + * before its next surface commit. + * + * A client may send multiple ack_configure requests before committing, but + * only the last request sent before a commit indicates which configure + * event the client really is responding to. + */ +static inline void +zwlr_layer_surface_v1_ack_configure(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, uint32_t serial) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zwlr_layer_surface_v1, + ZWLR_LAYER_SURFACE_V1_ACK_CONFIGURE, NULL, wl_proxy_get_version((struct wl_proxy *) zwlr_layer_surface_v1), 0, serial); +} + +/** + * @ingroup iface_zwlr_layer_surface_v1 + * + * This request destroys the layer surface. + */ +static inline void +zwlr_layer_surface_v1_destroy(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zwlr_layer_surface_v1, + ZWLR_LAYER_SURFACE_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwlr_layer_surface_v1), WL_MARSHAL_FLAG_DESTROY); +} + +/** + * @ingroup iface_zwlr_layer_surface_v1 + * + * Change the layer that the surface is rendered on. + * + * Layer is double-buffered, see wl_surface.commit. + */ +static inline void +zwlr_layer_surface_v1_set_layer(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, uint32_t layer) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zwlr_layer_surface_v1, + ZWLR_LAYER_SURFACE_V1_SET_LAYER, NULL, wl_proxy_get_version((struct wl_proxy *) zwlr_layer_surface_v1), 0, layer); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/wlr-layer-shell-unstable-v1-protocol.o b/wlr-layer-shell-unstable-v1-protocol.o new file mode 100644 index 0000000000000000000000000000000000000000..4107632a32f7fb719938271635c609faae740857 GIT binary patch literal 6728 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 Hi1z;i!PEoF literal 0 HcmV?d00001 diff --git a/xdg-output-unstable-v1-protocol.c b/xdg-output-unstable-v1-protocol.c new file mode 100644 index 0000000..ca28cfc --- /dev/null +++ b/xdg-output-unstable-v1-protocol.c @@ -0,0 +1,79 @@ +/* Generated by wayland-scanner 1.24.0 */ + +/* + * Copyright © 2017 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include "wayland-util.h" + +#ifndef __has_attribute +# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */ +#endif + +#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4) +#define WL_PRIVATE __attribute__ ((visibility("hidden"))) +#else +#define WL_PRIVATE +#endif + +extern const struct wl_interface wl_output_interface; +extern const struct wl_interface zxdg_output_v1_interface; + +static const struct wl_interface *xdg_output_unstable_v1_types[] = { + NULL, + NULL, + &zxdg_output_v1_interface, + &wl_output_interface, +}; + +static const struct wl_message zxdg_output_manager_v1_requests[] = { + { "destroy", "", xdg_output_unstable_v1_types + 0 }, + { "get_xdg_output", "no", xdg_output_unstable_v1_types + 2 }, +}; + +WL_PRIVATE const struct wl_interface zxdg_output_manager_v1_interface = { + "zxdg_output_manager_v1", 3, + 2, zxdg_output_manager_v1_requests, + 0, NULL, +}; + +static const struct wl_message zxdg_output_v1_requests[] = { + { "destroy", "", xdg_output_unstable_v1_types + 0 }, +}; + +static const struct wl_message zxdg_output_v1_events[] = { + { "logical_position", "ii", xdg_output_unstable_v1_types + 0 }, + { "logical_size", "ii", xdg_output_unstable_v1_types + 0 }, + { "done", "", xdg_output_unstable_v1_types + 0 }, + { "name", "2s", xdg_output_unstable_v1_types + 0 }, + { "description", "2s", xdg_output_unstable_v1_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface zxdg_output_v1_interface = { + "zxdg_output_v1", 3, + 1, zxdg_output_v1_requests, + 5, zxdg_output_v1_events, +}; + diff --git a/xdg-output-unstable-v1-protocol.h b/xdg-output-unstable-v1-protocol.h new file mode 100644 index 0000000..40e11ef --- /dev/null +++ b/xdg-output-unstable-v1-protocol.h @@ -0,0 +1,415 @@ +/* Generated by wayland-scanner 1.24.0 */ + +#ifndef XDG_OUTPUT_UNSTABLE_V1_CLIENT_PROTOCOL_H +#define XDG_OUTPUT_UNSTABLE_V1_CLIENT_PROTOCOL_H + +#include +#include +#include "wayland-client.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @page page_xdg_output_unstable_v1 The xdg_output_unstable_v1 protocol + * Protocol to describe output regions + * + * @section page_desc_xdg_output_unstable_v1 Description + * + * This protocol aims at describing outputs in a way which is more in line + * with the concept of an output on desktop oriented systems. + * + * Some information are more specific to the concept of an output for + * a desktop oriented system and may not make sense in other applications, + * such as IVI systems for example. + * + * Typically, the global compositor space on a desktop system is made of + * a contiguous or overlapping set of rectangular regions. + * + * The logical_position and logical_size events defined in this protocol + * might provide information identical to their counterparts already + * available from wl_output, in which case the information provided by this + * protocol should be preferred to their equivalent in wl_output. The goal is + * to move the desktop specific concepts (such as output location within the + * global compositor space, etc.) out of the core wl_output protocol. + * + * Warning! The protocol described in this file is experimental and + * backward incompatible changes may be made. Backward compatible + * changes may be added together with the corresponding interface + * version bump. + * Backward incompatible changes are done by bumping the version + * number in the protocol and interface names and resetting the + * interface version. Once the protocol is to be declared stable, + * the 'z' prefix and the version number in the protocol and + * interface names are removed and the interface version number is + * reset. + * + * @section page_ifaces_xdg_output_unstable_v1 Interfaces + * - @subpage page_iface_zxdg_output_manager_v1 - manage xdg_output objects + * - @subpage page_iface_zxdg_output_v1 - compositor logical output region + * @section page_copyright_xdg_output_unstable_v1 Copyright + *
+ *
+ * Copyright © 2017 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ * 
+ */ +struct wl_output; +struct zxdg_output_manager_v1; +struct zxdg_output_v1; + +#ifndef ZXDG_OUTPUT_MANAGER_V1_INTERFACE +#define ZXDG_OUTPUT_MANAGER_V1_INTERFACE +/** + * @page page_iface_zxdg_output_manager_v1 zxdg_output_manager_v1 + * @section page_iface_zxdg_output_manager_v1_desc Description + * + * A global factory interface for xdg_output objects. + * @section page_iface_zxdg_output_manager_v1_api API + * See @ref iface_zxdg_output_manager_v1. + */ +/** + * @defgroup iface_zxdg_output_manager_v1 The zxdg_output_manager_v1 interface + * + * A global factory interface for xdg_output objects. + */ +extern const struct wl_interface zxdg_output_manager_v1_interface; +#endif +#ifndef ZXDG_OUTPUT_V1_INTERFACE +#define ZXDG_OUTPUT_V1_INTERFACE +/** + * @page page_iface_zxdg_output_v1 zxdg_output_v1 + * @section page_iface_zxdg_output_v1_desc Description + * + * An xdg_output describes part of the compositor geometry. + * + * This typically corresponds to a monitor that displays part of the + * compositor space. + * + * For objects version 3 onwards, after all xdg_output properties have been + * sent (when the object is created and when properties are updated), a + * wl_output.done event is sent. This allows changes to the output + * properties to be seen as atomic, even if they happen via multiple events. + * @section page_iface_zxdg_output_v1_api API + * See @ref iface_zxdg_output_v1. + */ +/** + * @defgroup iface_zxdg_output_v1 The zxdg_output_v1 interface + * + * An xdg_output describes part of the compositor geometry. + * + * This typically corresponds to a monitor that displays part of the + * compositor space. + * + * For objects version 3 onwards, after all xdg_output properties have been + * sent (when the object is created and when properties are updated), a + * wl_output.done event is sent. This allows changes to the output + * properties to be seen as atomic, even if they happen via multiple events. + */ +extern const struct wl_interface zxdg_output_v1_interface; +#endif + +#define ZXDG_OUTPUT_MANAGER_V1_DESTROY 0 +#define ZXDG_OUTPUT_MANAGER_V1_GET_XDG_OUTPUT 1 + + +/** + * @ingroup iface_zxdg_output_manager_v1 + */ +#define ZXDG_OUTPUT_MANAGER_V1_DESTROY_SINCE_VERSION 1 +/** + * @ingroup iface_zxdg_output_manager_v1 + */ +#define ZXDG_OUTPUT_MANAGER_V1_GET_XDG_OUTPUT_SINCE_VERSION 1 + +/** @ingroup iface_zxdg_output_manager_v1 */ +static inline void +zxdg_output_manager_v1_set_user_data(struct zxdg_output_manager_v1 *zxdg_output_manager_v1, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) zxdg_output_manager_v1, user_data); +} + +/** @ingroup iface_zxdg_output_manager_v1 */ +static inline void * +zxdg_output_manager_v1_get_user_data(struct zxdg_output_manager_v1 *zxdg_output_manager_v1) +{ + return wl_proxy_get_user_data((struct wl_proxy *) zxdg_output_manager_v1); +} + +static inline uint32_t +zxdg_output_manager_v1_get_version(struct zxdg_output_manager_v1 *zxdg_output_manager_v1) +{ + return wl_proxy_get_version((struct wl_proxy *) zxdg_output_manager_v1); +} + +/** + * @ingroup iface_zxdg_output_manager_v1 + * + * Using this request a client can tell the server that it is not + * going to use the xdg_output_manager object anymore. + * + * Any objects already created through this instance are not affected. + */ +static inline void +zxdg_output_manager_v1_destroy(struct zxdg_output_manager_v1 *zxdg_output_manager_v1) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zxdg_output_manager_v1, + ZXDG_OUTPUT_MANAGER_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zxdg_output_manager_v1), WL_MARSHAL_FLAG_DESTROY); +} + +/** + * @ingroup iface_zxdg_output_manager_v1 + * + * This creates a new xdg_output object for the given wl_output. + */ +static inline struct zxdg_output_v1 * +zxdg_output_manager_v1_get_xdg_output(struct zxdg_output_manager_v1 *zxdg_output_manager_v1, struct wl_output *output) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) zxdg_output_manager_v1, + ZXDG_OUTPUT_MANAGER_V1_GET_XDG_OUTPUT, &zxdg_output_v1_interface, wl_proxy_get_version((struct wl_proxy *) zxdg_output_manager_v1), 0, NULL, output); + + return (struct zxdg_output_v1 *) id; +} + +/** + * @ingroup iface_zxdg_output_v1 + * @struct zxdg_output_v1_listener + */ +struct zxdg_output_v1_listener { + /** + * position of the output within the global compositor space + * + * The position event describes the location of the wl_output + * within the global compositor space. + * + * The logical_position event is sent after creating an xdg_output + * (see xdg_output_manager.get_xdg_output) and whenever the + * location of the output changes within the global compositor + * space. + * @param x x position within the global compositor space + * @param y y position within the global compositor space + */ + void (*logical_position)(void *data, + struct zxdg_output_v1 *zxdg_output_v1, + int32_t x, + int32_t y); + /** + * size of the output in the global compositor space + * + * The logical_size event describes the size of the output in the + * global compositor space. + * + * Most regular Wayland clients should not pay attention to the + * logical size and would rather rely on xdg_shell interfaces. + * + * Some clients such as Xwayland, however, need this to configure + * their surfaces in the global compositor space as the compositor + * may apply a different scale from what is advertised by the + * output scaling property (to achieve fractional scaling, for + * example). + * + * For example, for a wl_output mode 3840×2160 and a scale factor + * 2: + * + * - A compositor not scaling the monitor viewport in its + * compositing space will advertise a logical size of 3840×2160, + * + * - A compositor scaling the monitor viewport with scale factor 2 + * will advertise a logical size of 1920×1080, + * + * - A compositor scaling the monitor viewport using a fractional + * scale of 1.5 will advertise a logical size of 2560×1440. + * + * For example, for a wl_output mode 1920×1080 and a 90 degree + * rotation, the compositor will advertise a logical size of + * 1080x1920. + * + * The logical_size event is sent after creating an xdg_output (see + * xdg_output_manager.get_xdg_output) and whenever the logical size + * of the output changes, either as a result of a change in the + * applied scale or because of a change in the corresponding output + * mode(see wl_output.mode) or transform (see wl_output.transform). + * @param width width in global compositor space + * @param height height in global compositor space + */ + void (*logical_size)(void *data, + struct zxdg_output_v1 *zxdg_output_v1, + int32_t width, + int32_t height); + /** + * all information about the output have been sent + * + * This event is sent after all other properties of an xdg_output + * have been sent. + * + * This allows changes to the xdg_output properties to be seen as + * atomic, even if they happen via multiple events. + * + * For objects version 3 onwards, this event is deprecated. + * Compositors are not required to send it anymore and must send + * wl_output.done instead. + * @deprecated Deprecated since version 3 + */ + void (*done)(void *data, + struct zxdg_output_v1 *zxdg_output_v1); + /** + * name of this output + * + * Many compositors will assign names to their outputs, show them + * to the user, allow them to be configured by name, etc. The + * client may wish to know this name as well to offer the user + * similar behaviors. + * + * The naming convention is compositor defined, but limited to + * alphanumeric characters and dashes (-). Each name is unique + * among all wl_output globals, but if a wl_output global is + * destroyed the same name may be reused later. The names will also + * remain consistent across sessions with the same hardware and + * software configuration. + * + * Examples of names include 'HDMI-A-1', 'WL-1', 'X11-1', etc. + * However, do not assume that the name is a reflection of an + * underlying DRM connector, X11 connection, etc. + * + * The name event is sent after creating an xdg_output (see + * xdg_output_manager.get_xdg_output). This event is only sent once + * per xdg_output, and the name does not change over the lifetime + * of the wl_output global. + * + * This event is deprecated, instead clients should use + * wl_output.name. Compositors must still support this event. + * @param name output name + * @since 2 + */ + void (*name)(void *data, + struct zxdg_output_v1 *zxdg_output_v1, + const char *name); + /** + * human-readable description of this output + * + * Many compositors can produce human-readable descriptions of + * their outputs. The client may wish to know this description as + * well, to communicate the user for various purposes. + * + * The description is a UTF-8 string with no convention defined for + * its contents. Examples might include 'Foocorp 11" Display' or + * 'Virtual X11 output via :1'. + * + * The description event is sent after creating an xdg_output (see + * xdg_output_manager.get_xdg_output) and whenever the description + * changes. The description is optional, and may not be sent at + * all. + * + * For objects of version 2 and lower, this event is only sent once + * per xdg_output, and the description does not change over the + * lifetime of the wl_output global. + * + * This event is deprecated, instead clients should use + * wl_output.description. Compositors must still support this + * event. + * @param description output description + * @since 2 + */ + void (*description)(void *data, + struct zxdg_output_v1 *zxdg_output_v1, + const char *description); +}; + +/** + * @ingroup iface_zxdg_output_v1 + */ +static inline int +zxdg_output_v1_add_listener(struct zxdg_output_v1 *zxdg_output_v1, + const struct zxdg_output_v1_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) zxdg_output_v1, + (void (**)(void)) listener, data); +} + +#define ZXDG_OUTPUT_V1_DESTROY 0 + +/** + * @ingroup iface_zxdg_output_v1 + */ +#define ZXDG_OUTPUT_V1_LOGICAL_POSITION_SINCE_VERSION 1 +/** + * @ingroup iface_zxdg_output_v1 + */ +#define ZXDG_OUTPUT_V1_LOGICAL_SIZE_SINCE_VERSION 1 +/** + * @ingroup iface_zxdg_output_v1 + */ +#define ZXDG_OUTPUT_V1_DONE_SINCE_VERSION 1 +/** + * @ingroup iface_zxdg_output_v1 + */ +#define ZXDG_OUTPUT_V1_NAME_SINCE_VERSION 2 +/** + * @ingroup iface_zxdg_output_v1 + */ +#define ZXDG_OUTPUT_V1_DESCRIPTION_SINCE_VERSION 2 + +/** + * @ingroup iface_zxdg_output_v1 + */ +#define ZXDG_OUTPUT_V1_DESTROY_SINCE_VERSION 1 + +/** @ingroup iface_zxdg_output_v1 */ +static inline void +zxdg_output_v1_set_user_data(struct zxdg_output_v1 *zxdg_output_v1, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) zxdg_output_v1, user_data); +} + +/** @ingroup iface_zxdg_output_v1 */ +static inline void * +zxdg_output_v1_get_user_data(struct zxdg_output_v1 *zxdg_output_v1) +{ + return wl_proxy_get_user_data((struct wl_proxy *) zxdg_output_v1); +} + +static inline uint32_t +zxdg_output_v1_get_version(struct zxdg_output_v1 *zxdg_output_v1) +{ + return wl_proxy_get_version((struct wl_proxy *) zxdg_output_v1); +} + +/** + * @ingroup iface_zxdg_output_v1 + * + * Using this request a client can tell the server that it is not + * going to use the xdg_output object anymore. + */ +static inline void +zxdg_output_v1_destroy(struct zxdg_output_v1 *zxdg_output_v1) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zxdg_output_v1, + ZXDG_OUTPUT_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zxdg_output_v1), WL_MARSHAL_FLAG_DESTROY); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/xdg-output-unstable-v1-protocol.o b/xdg-output-unstable-v1-protocol.o new file mode 100644 index 0000000000000000000000000000000000000000..05fdefb822ba5a73235a89065a081cd4b407d728 GIT binary patch literal 5856 zcmdT|dsLLi6`$QD@|Gn0+NVEgFFNk(2|2CiL(2#`>`P|yRiEKD;gn* zuL24d6SW0xiQ+3wF*Y^EMp0r#im6r7N(hk<6Qs6L$)mRPBt5fxFFQMR&*`y$^>>bb zbANO1ojZ3Pcb1xr?1gffj38uWK5~eyDp|~{2{DM0#-=xD z%oS2ug+xqdQtcEqrGiN?h!#y{JTaOLB|5>VDKlG3q!P18{3{{!g!*mb{;3mW@;AqgnkT6BgYtya`t(-OH# z8TtFas(#m7>lc!IWkJy6zN?B0y_?SY1g>AEY;DNa&S;2L)@}2Du)FR(U2bZ~+3qv) zctxsrZA{04`$MZ_iyl^56R)nD6tZUK&I__)^NwawuT^TbU&t*53BsJD!Yp-a{;AYU z|Ja!0`^J~kcV18w*EB8n+$Arrk=HM&?bmb;`}p-{rnJwL^~Xk7pH6vy*dykmNBQa4 zIA#5my-{Ry|MmsD^<;c$X1{E&S6IXA5rg~G84Z5D2U8v^*moo~rfzXqM^{{5l=^G) zhEdOFjs~?~%@t<0_l&DwiS_Fp5gu&~`r@?%*OC;Lcl(rbKhpJKpT7A z6CGE&&&OOn)7aNOcTJEONQ{kB_ivavs4{QDCd*o#|Q2j&t& z?jv3#k!}Q;Y<#jm{m^O1>_qs)?w8BLXj z()iQAH@;?TUfNdu@%fcA^f5Q`Uj0>DS<4e)vDFQ&=l5-GpSPm$FKr*!pLyxelZBUe zEhrdyIy3j%#PB{+3BedGKiNnSa=^9N46SYA6fwp#yDez%Xe>4QJ*{@LX0;7y~sp$DF|Ds~7# zv%8L`+<1Q4D+iUc}^Rj=^`OC2t>uQ77KEKdLGSkxLL_}xi=Ep?D zC#e!t@ev8?gvZng>SW?U2#K&SF(H|``9w}+os>h!K*qS;f%bcl+uz--Utu4`6%W~S z;T(y^fKZT0*mQw{c)G|GwC2bdUJV*r;LAV`fv*ktpEEK-LA?`Ia$qYVBv9^2A|S!h!0#vIu3qRpLiHWBmQ3gqo8A!TsG)HcCaWYA8O6BD z__#8QSu*R)MwO0gK$X>?hNd!JBdsnItu8gvS#&iPvAjaGO0NBt?s>6NH2tS`iAfSI z#ez;GRYnZK$+6{`8QQ5pff=P~VzZ9xO8EfD9Sg_4bOJ9q{z8yDIUfCVGd%0(BEwTZPl0@e<8fX?4A1(x&hXSv0m!#FekI6v7@qZG zPYjb!dT&s8(S$KP`cX1G>j%#-=Go{lCu&BYt}m`@3diF*;ka(pN7BFA3_zMSK~0vYFrC4A|JJzr}${XX!&iP2~8&n8ZP56G>IKHkj~Cpdk)2hK72?D_qS)2I2M zxXtO~xt7CZXg6EG@TEiTv9?e=X#d}FzUaBe`oW%4%Hw&!cMtVL`Bh+_#QE6*@*IwD z0hy?*t4k%Jh^VZR#qoU(Tasv#h)OR=0#OxNtwd!Jje=dKEuylR9epme%3@X-%{qbh z+ttOQ3WKJ^RBR?HM_VW=vWS%~-GW6h8N`VZ>?Xz%lZYl($%0KvJ7k@?v{W=nL}fBd zqAD{tKh7!%x>X<>Ockm!i@8j+NUL$K{{!g#O4kzC4}t5%1GdEkBEjDId&z6BIDqk5fPo>l(h3X#Jq$vuB(F&)phy2;lRV zG)+>l_!N9iw2+=Zn{^b`$?|@Ce5^Y5ep(f#W0J zjPY~uri((~HyqE8Pk%SvZT)Ite5~(ue0tyVL&kmPxE&VMF;%E$9D{ZkDvaMzMK6WSpUz_5Ww628!DfbMgRZ+ literal 0 HcmV?d00001 diff --git a/xdg-shell-protocol.c b/xdg-shell-protocol.c new file mode 100644 index 0000000..5a50433 --- /dev/null +++ b/xdg-shell-protocol.c @@ -0,0 +1,184 @@ +/* Generated by wayland-scanner 1.24.0 */ + +/* + * Copyright © 2008-2013 Kristian Høgsberg + * Copyright © 2013 Rafael Antognolli + * Copyright © 2013 Jasper St. Pierre + * Copyright © 2010-2013 Intel Corporation + * Copyright © 2015-2017 Samsung Electronics Co., Ltd + * Copyright © 2015-2017 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include "wayland-util.h" + +#ifndef __has_attribute +# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */ +#endif + +#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4) +#define WL_PRIVATE __attribute__ ((visibility("hidden"))) +#else +#define WL_PRIVATE +#endif + +extern const struct wl_interface wl_output_interface; +extern const struct wl_interface wl_seat_interface; +extern const struct wl_interface wl_surface_interface; +extern const struct wl_interface xdg_popup_interface; +extern const struct wl_interface xdg_positioner_interface; +extern const struct wl_interface xdg_surface_interface; +extern const struct wl_interface xdg_toplevel_interface; + +static const struct wl_interface *xdg_shell_types[] = { + NULL, + NULL, + NULL, + NULL, + &xdg_positioner_interface, + &xdg_surface_interface, + &wl_surface_interface, + &xdg_toplevel_interface, + &xdg_popup_interface, + &xdg_surface_interface, + &xdg_positioner_interface, + &xdg_toplevel_interface, + &wl_seat_interface, + NULL, + NULL, + NULL, + &wl_seat_interface, + NULL, + &wl_seat_interface, + NULL, + NULL, + &wl_output_interface, + &wl_seat_interface, + NULL, + &xdg_positioner_interface, + NULL, +}; + +static const struct wl_message xdg_wm_base_requests[] = { + { "destroy", "", xdg_shell_types + 0 }, + { "create_positioner", "n", xdg_shell_types + 4 }, + { "get_xdg_surface", "no", xdg_shell_types + 5 }, + { "pong", "u", xdg_shell_types + 0 }, +}; + +static const struct wl_message xdg_wm_base_events[] = { + { "ping", "u", xdg_shell_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface xdg_wm_base_interface = { + "xdg_wm_base", 7, + 4, xdg_wm_base_requests, + 1, xdg_wm_base_events, +}; + +static const struct wl_message xdg_positioner_requests[] = { + { "destroy", "", xdg_shell_types + 0 }, + { "set_size", "ii", xdg_shell_types + 0 }, + { "set_anchor_rect", "iiii", xdg_shell_types + 0 }, + { "set_anchor", "u", xdg_shell_types + 0 }, + { "set_gravity", "u", xdg_shell_types + 0 }, + { "set_constraint_adjustment", "u", xdg_shell_types + 0 }, + { "set_offset", "ii", xdg_shell_types + 0 }, + { "set_reactive", "3", xdg_shell_types + 0 }, + { "set_parent_size", "3ii", xdg_shell_types + 0 }, + { "set_parent_configure", "3u", xdg_shell_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface xdg_positioner_interface = { + "xdg_positioner", 7, + 10, xdg_positioner_requests, + 0, NULL, +}; + +static const struct wl_message xdg_surface_requests[] = { + { "destroy", "", xdg_shell_types + 0 }, + { "get_toplevel", "n", xdg_shell_types + 7 }, + { "get_popup", "n?oo", xdg_shell_types + 8 }, + { "set_window_geometry", "iiii", xdg_shell_types + 0 }, + { "ack_configure", "u", xdg_shell_types + 0 }, +}; + +static const struct wl_message xdg_surface_events[] = { + { "configure", "u", xdg_shell_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface xdg_surface_interface = { + "xdg_surface", 7, + 5, xdg_surface_requests, + 1, xdg_surface_events, +}; + +static const struct wl_message xdg_toplevel_requests[] = { + { "destroy", "", xdg_shell_types + 0 }, + { "set_parent", "?o", xdg_shell_types + 11 }, + { "set_title", "s", xdg_shell_types + 0 }, + { "set_app_id", "s", xdg_shell_types + 0 }, + { "show_window_menu", "ouii", xdg_shell_types + 12 }, + { "move", "ou", xdg_shell_types + 16 }, + { "resize", "ouu", xdg_shell_types + 18 }, + { "set_max_size", "ii", xdg_shell_types + 0 }, + { "set_min_size", "ii", xdg_shell_types + 0 }, + { "set_maximized", "", xdg_shell_types + 0 }, + { "unset_maximized", "", xdg_shell_types + 0 }, + { "set_fullscreen", "?o", xdg_shell_types + 21 }, + { "unset_fullscreen", "", xdg_shell_types + 0 }, + { "set_minimized", "", xdg_shell_types + 0 }, +}; + +static const struct wl_message xdg_toplevel_events[] = { + { "configure", "iia", xdg_shell_types + 0 }, + { "close", "", xdg_shell_types + 0 }, + { "configure_bounds", "4ii", xdg_shell_types + 0 }, + { "wm_capabilities", "5a", xdg_shell_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface xdg_toplevel_interface = { + "xdg_toplevel", 7, + 14, xdg_toplevel_requests, + 4, xdg_toplevel_events, +}; + +static const struct wl_message xdg_popup_requests[] = { + { "destroy", "", xdg_shell_types + 0 }, + { "grab", "ou", xdg_shell_types + 22 }, + { "reposition", "3ou", xdg_shell_types + 24 }, +}; + +static const struct wl_message xdg_popup_events[] = { + { "configure", "iiii", xdg_shell_types + 0 }, + { "popup_done", "", xdg_shell_types + 0 }, + { "repositioned", "3u", xdg_shell_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface xdg_popup_interface = { + "xdg_popup", 7, + 3, xdg_popup_requests, + 3, xdg_popup_events, +}; + diff --git a/xdg-shell-protocol.h b/xdg-shell-protocol.h new file mode 100644 index 0000000..5a2ed89 --- /dev/null +++ b/xdg-shell-protocol.h @@ -0,0 +1,2384 @@ +/* Generated by wayland-scanner 1.24.0 */ + +#ifndef XDG_SHELL_CLIENT_PROTOCOL_H +#define XDG_SHELL_CLIENT_PROTOCOL_H + +#include +#include +#include "wayland-client.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @page page_xdg_shell The xdg_shell protocol + * @section page_ifaces_xdg_shell Interfaces + * - @subpage page_iface_xdg_wm_base - create desktop-style surfaces + * - @subpage page_iface_xdg_positioner - child surface positioner + * - @subpage page_iface_xdg_surface - desktop user interface surface base interface + * - @subpage page_iface_xdg_toplevel - toplevel surface + * - @subpage page_iface_xdg_popup - short-lived, popup surfaces for menus + * @section page_copyright_xdg_shell Copyright + *
+ *
+ * Copyright © 2008-2013 Kristian Høgsberg
+ * Copyright © 2013      Rafael Antognolli
+ * Copyright © 2013      Jasper St. Pierre
+ * Copyright © 2010-2013 Intel Corporation
+ * Copyright © 2015-2017 Samsung Electronics Co., Ltd
+ * Copyright © 2015-2017 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ * 
+ */ +struct wl_output; +struct wl_seat; +struct wl_surface; +struct xdg_popup; +struct xdg_positioner; +struct xdg_surface; +struct xdg_toplevel; +struct xdg_wm_base; + +#ifndef XDG_WM_BASE_INTERFACE +#define XDG_WM_BASE_INTERFACE +/** + * @page page_iface_xdg_wm_base xdg_wm_base + * @section page_iface_xdg_wm_base_desc Description + * + * The xdg_wm_base interface is exposed as a global object enabling clients + * to turn their wl_surfaces into windows in a desktop environment. It + * defines the basic functionality needed for clients and the compositor to + * create windows that can be dragged, resized, maximized, etc, as well as + * creating transient windows such as popup menus. + * @section page_iface_xdg_wm_base_api API + * See @ref iface_xdg_wm_base. + */ +/** + * @defgroup iface_xdg_wm_base The xdg_wm_base interface + * + * The xdg_wm_base interface is exposed as a global object enabling clients + * to turn their wl_surfaces into windows in a desktop environment. It + * defines the basic functionality needed for clients and the compositor to + * create windows that can be dragged, resized, maximized, etc, as well as + * creating transient windows such as popup menus. + */ +extern const struct wl_interface xdg_wm_base_interface; +#endif +#ifndef XDG_POSITIONER_INTERFACE +#define XDG_POSITIONER_INTERFACE +/** + * @page page_iface_xdg_positioner xdg_positioner + * @section page_iface_xdg_positioner_desc Description + * + * The xdg_positioner provides a collection of rules for the placement of a + * child surface relative to a parent surface. Rules can be defined to ensure + * the child surface remains within the visible area's borders, and to + * specify how the child surface changes its position, such as sliding along + * an axis, or flipping around a rectangle. These positioner-created rules are + * constrained by the requirement that a child surface must intersect with or + * be at least partially adjacent to its parent surface. + * + * See the various requests for details about possible rules. + * + * At the time of the request, the compositor makes a copy of the rules + * specified by the xdg_positioner. Thus, after the request is complete the + * xdg_positioner object can be destroyed or reused; further changes to the + * object will have no effect on previous usages. + * + * For an xdg_positioner object to be considered complete, it must have a + * non-zero size set by set_size, and a non-zero anchor rectangle set by + * set_anchor_rect. Passing an incomplete xdg_positioner object when + * positioning a surface raises an invalid_positioner error. + * @section page_iface_xdg_positioner_api API + * See @ref iface_xdg_positioner. + */ +/** + * @defgroup iface_xdg_positioner The xdg_positioner interface + * + * The xdg_positioner provides a collection of rules for the placement of a + * child surface relative to a parent surface. Rules can be defined to ensure + * the child surface remains within the visible area's borders, and to + * specify how the child surface changes its position, such as sliding along + * an axis, or flipping around a rectangle. These positioner-created rules are + * constrained by the requirement that a child surface must intersect with or + * be at least partially adjacent to its parent surface. + * + * See the various requests for details about possible rules. + * + * At the time of the request, the compositor makes a copy of the rules + * specified by the xdg_positioner. Thus, after the request is complete the + * xdg_positioner object can be destroyed or reused; further changes to the + * object will have no effect on previous usages. + * + * For an xdg_positioner object to be considered complete, it must have a + * non-zero size set by set_size, and a non-zero anchor rectangle set by + * set_anchor_rect. Passing an incomplete xdg_positioner object when + * positioning a surface raises an invalid_positioner error. + */ +extern const struct wl_interface xdg_positioner_interface; +#endif +#ifndef XDG_SURFACE_INTERFACE +#define XDG_SURFACE_INTERFACE +/** + * @page page_iface_xdg_surface xdg_surface + * @section page_iface_xdg_surface_desc Description + * + * An interface that may be implemented by a wl_surface, for + * implementations that provide a desktop-style user interface. + * + * It provides a base set of functionality required to construct user + * interface elements requiring management by the compositor, such as + * toplevel windows, menus, etc. The types of functionality are split into + * xdg_surface roles. + * + * Creating an xdg_surface does not set the role for a wl_surface. In order + * to map an xdg_surface, the client must create a role-specific object + * using, e.g., get_toplevel, get_popup. The wl_surface for any given + * xdg_surface can have at most one role, and may not be assigned any role + * not based on xdg_surface. + * + * A role must be assigned before any other requests are made to the + * xdg_surface object. + * + * The client must call wl_surface.commit on the corresponding wl_surface + * for the xdg_surface state to take effect. + * + * Creating an xdg_surface from a wl_surface which has a buffer attached or + * committed is a client error, and any attempts by a client to attach or + * manipulate a buffer prior to the first xdg_surface.configure call must + * also be treated as errors. + * + * After creating a role-specific object and setting it up (e.g. by sending + * the title, app ID, size constraints, parent, etc), the client must + * perform an initial commit without any buffer attached. The compositor + * will reply with initial wl_surface state such as + * wl_surface.preferred_buffer_scale followed by an xdg_surface.configure + * event. The client must acknowledge it and is then allowed to attach a + * buffer to map the surface. + * + * Mapping an xdg_surface-based role surface is defined as making it + * possible for the surface to be shown by the compositor. Note that + * a mapped surface is not guaranteed to be visible once it is mapped. + * + * For an xdg_surface to be mapped by the compositor, the following + * conditions must be met: + * (1) the client has assigned an xdg_surface-based role to the surface + * (2) the client has set and committed the xdg_surface state and the + * role-dependent state to the surface + * (3) the client has committed a buffer to the surface + * + * A newly-unmapped surface is considered to have met condition (1) out + * of the 3 required conditions for mapping a surface if its role surface + * has not been destroyed, i.e. the client must perform the initial commit + * again before attaching a buffer. + * @section page_iface_xdg_surface_api API + * See @ref iface_xdg_surface. + */ +/** + * @defgroup iface_xdg_surface The xdg_surface interface + * + * An interface that may be implemented by a wl_surface, for + * implementations that provide a desktop-style user interface. + * + * It provides a base set of functionality required to construct user + * interface elements requiring management by the compositor, such as + * toplevel windows, menus, etc. The types of functionality are split into + * xdg_surface roles. + * + * Creating an xdg_surface does not set the role for a wl_surface. In order + * to map an xdg_surface, the client must create a role-specific object + * using, e.g., get_toplevel, get_popup. The wl_surface for any given + * xdg_surface can have at most one role, and may not be assigned any role + * not based on xdg_surface. + * + * A role must be assigned before any other requests are made to the + * xdg_surface object. + * + * The client must call wl_surface.commit on the corresponding wl_surface + * for the xdg_surface state to take effect. + * + * Creating an xdg_surface from a wl_surface which has a buffer attached or + * committed is a client error, and any attempts by a client to attach or + * manipulate a buffer prior to the first xdg_surface.configure call must + * also be treated as errors. + * + * After creating a role-specific object and setting it up (e.g. by sending + * the title, app ID, size constraints, parent, etc), the client must + * perform an initial commit without any buffer attached. The compositor + * will reply with initial wl_surface state such as + * wl_surface.preferred_buffer_scale followed by an xdg_surface.configure + * event. The client must acknowledge it and is then allowed to attach a + * buffer to map the surface. + * + * Mapping an xdg_surface-based role surface is defined as making it + * possible for the surface to be shown by the compositor. Note that + * a mapped surface is not guaranteed to be visible once it is mapped. + * + * For an xdg_surface to be mapped by the compositor, the following + * conditions must be met: + * (1) the client has assigned an xdg_surface-based role to the surface + * (2) the client has set and committed the xdg_surface state and the + * role-dependent state to the surface + * (3) the client has committed a buffer to the surface + * + * A newly-unmapped surface is considered to have met condition (1) out + * of the 3 required conditions for mapping a surface if its role surface + * has not been destroyed, i.e. the client must perform the initial commit + * again before attaching a buffer. + */ +extern const struct wl_interface xdg_surface_interface; +#endif +#ifndef XDG_TOPLEVEL_INTERFACE +#define XDG_TOPLEVEL_INTERFACE +/** + * @page page_iface_xdg_toplevel xdg_toplevel + * @section page_iface_xdg_toplevel_desc Description + * + * This interface defines an xdg_surface role which allows a surface to, + * among other things, set window-like properties such as maximize, + * fullscreen, and minimize, set application-specific metadata like title and + * id, and well as trigger user interactive operations such as interactive + * resize and move. + * + * A xdg_toplevel by default is responsible for providing the full intended + * visual representation of the toplevel, which depending on the window + * state, may mean things like a title bar, window controls and drop shadow. + * + * Unmapping an xdg_toplevel means that the surface cannot be shown + * by the compositor until it is explicitly mapped again. + * All active operations (e.g., move, resize) are canceled and all + * attributes (e.g. title, state, stacking, ...) are discarded for + * an xdg_toplevel surface when it is unmapped. The xdg_toplevel returns to + * the state it had right after xdg_surface.get_toplevel. The client + * can re-map the toplevel by performing a commit without any buffer + * attached, waiting for a configure event and handling it as usual (see + * xdg_surface description). + * + * Attaching a null buffer to a toplevel unmaps the surface. + * @section page_iface_xdg_toplevel_api API + * See @ref iface_xdg_toplevel. + */ +/** + * @defgroup iface_xdg_toplevel The xdg_toplevel interface + * + * This interface defines an xdg_surface role which allows a surface to, + * among other things, set window-like properties such as maximize, + * fullscreen, and minimize, set application-specific metadata like title and + * id, and well as trigger user interactive operations such as interactive + * resize and move. + * + * A xdg_toplevel by default is responsible for providing the full intended + * visual representation of the toplevel, which depending on the window + * state, may mean things like a title bar, window controls and drop shadow. + * + * Unmapping an xdg_toplevel means that the surface cannot be shown + * by the compositor until it is explicitly mapped again. + * All active operations (e.g., move, resize) are canceled and all + * attributes (e.g. title, state, stacking, ...) are discarded for + * an xdg_toplevel surface when it is unmapped. The xdg_toplevel returns to + * the state it had right after xdg_surface.get_toplevel. The client + * can re-map the toplevel by performing a commit without any buffer + * attached, waiting for a configure event and handling it as usual (see + * xdg_surface description). + * + * Attaching a null buffer to a toplevel unmaps the surface. + */ +extern const struct wl_interface xdg_toplevel_interface; +#endif +#ifndef XDG_POPUP_INTERFACE +#define XDG_POPUP_INTERFACE +/** + * @page page_iface_xdg_popup xdg_popup + * @section page_iface_xdg_popup_desc Description + * + * A popup surface is a short-lived, temporary surface. It can be used to + * implement for example menus, popovers, tooltips and other similar user + * interface concepts. + * + * A popup can be made to take an explicit grab. See xdg_popup.grab for + * details. + * + * When the popup is dismissed, a popup_done event will be sent out, and at + * the same time the surface will be unmapped. See the xdg_popup.popup_done + * event for details. + * + * Explicitly destroying the xdg_popup object will also dismiss the popup and + * unmap the surface. Clients that want to dismiss the popup when another + * surface of their own is clicked should dismiss the popup using the destroy + * request. + * + * A newly created xdg_popup will be stacked on top of all previously created + * xdg_popup surfaces associated with the same xdg_toplevel. + * + * The parent of an xdg_popup must be mapped (see the xdg_surface + * description) before the xdg_popup itself. + * + * The client must call wl_surface.commit on the corresponding wl_surface + * for the xdg_popup state to take effect. + * @section page_iface_xdg_popup_api API + * See @ref iface_xdg_popup. + */ +/** + * @defgroup iface_xdg_popup The xdg_popup interface + * + * A popup surface is a short-lived, temporary surface. It can be used to + * implement for example menus, popovers, tooltips and other similar user + * interface concepts. + * + * A popup can be made to take an explicit grab. See xdg_popup.grab for + * details. + * + * When the popup is dismissed, a popup_done event will be sent out, and at + * the same time the surface will be unmapped. See the xdg_popup.popup_done + * event for details. + * + * Explicitly destroying the xdg_popup object will also dismiss the popup and + * unmap the surface. Clients that want to dismiss the popup when another + * surface of their own is clicked should dismiss the popup using the destroy + * request. + * + * A newly created xdg_popup will be stacked on top of all previously created + * xdg_popup surfaces associated with the same xdg_toplevel. + * + * The parent of an xdg_popup must be mapped (see the xdg_surface + * description) before the xdg_popup itself. + * + * The client must call wl_surface.commit on the corresponding wl_surface + * for the xdg_popup state to take effect. + */ +extern const struct wl_interface xdg_popup_interface; +#endif + +#ifndef XDG_WM_BASE_ERROR_ENUM +#define XDG_WM_BASE_ERROR_ENUM +enum xdg_wm_base_error { + /** + * given wl_surface has another role + */ + XDG_WM_BASE_ERROR_ROLE = 0, + /** + * xdg_wm_base was destroyed before children + */ + XDG_WM_BASE_ERROR_DEFUNCT_SURFACES = 1, + /** + * the client tried to map or destroy a non-topmost popup + */ + XDG_WM_BASE_ERROR_NOT_THE_TOPMOST_POPUP = 2, + /** + * the client specified an invalid popup parent surface + */ + XDG_WM_BASE_ERROR_INVALID_POPUP_PARENT = 3, + /** + * the client provided an invalid surface state + */ + XDG_WM_BASE_ERROR_INVALID_SURFACE_STATE = 4, + /** + * the client provided an invalid positioner + */ + XDG_WM_BASE_ERROR_INVALID_POSITIONER = 5, + /** + * the client didn’t respond to a ping event in time + */ + XDG_WM_BASE_ERROR_UNRESPONSIVE = 6, +}; +#endif /* XDG_WM_BASE_ERROR_ENUM */ + +/** + * @ingroup iface_xdg_wm_base + * @struct xdg_wm_base_listener + */ +struct xdg_wm_base_listener { + /** + * check if the client is alive + * + * The ping event asks the client if it's still alive. Pass the + * serial specified in the event back to the compositor by sending + * a "pong" request back with the specified serial. See + * xdg_wm_base.pong. + * + * Compositors can use this to determine if the client is still + * alive. It's unspecified what will happen if the client doesn't + * respond to the ping request, or in what timeframe. Clients + * should try to respond in a reasonable amount of time. The + * “unresponsive” error is provided for compositors that wish + * to disconnect unresponsive clients. + * + * A compositor is free to ping in any way it wants, but a client + * must always respond to any xdg_wm_base object it created. + * @param serial pass this to the pong request + */ + void (*ping)(void *data, + struct xdg_wm_base *xdg_wm_base, + uint32_t serial); +}; + +/** + * @ingroup iface_xdg_wm_base + */ +static inline int +xdg_wm_base_add_listener(struct xdg_wm_base *xdg_wm_base, + const struct xdg_wm_base_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) xdg_wm_base, + (void (**)(void)) listener, data); +} + +#define XDG_WM_BASE_DESTROY 0 +#define XDG_WM_BASE_CREATE_POSITIONER 1 +#define XDG_WM_BASE_GET_XDG_SURFACE 2 +#define XDG_WM_BASE_PONG 3 + +/** + * @ingroup iface_xdg_wm_base + */ +#define XDG_WM_BASE_PING_SINCE_VERSION 1 + +/** + * @ingroup iface_xdg_wm_base + */ +#define XDG_WM_BASE_DESTROY_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_wm_base + */ +#define XDG_WM_BASE_CREATE_POSITIONER_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_wm_base + */ +#define XDG_WM_BASE_GET_XDG_SURFACE_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_wm_base + */ +#define XDG_WM_BASE_PONG_SINCE_VERSION 1 + +/** @ingroup iface_xdg_wm_base */ +static inline void +xdg_wm_base_set_user_data(struct xdg_wm_base *xdg_wm_base, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) xdg_wm_base, user_data); +} + +/** @ingroup iface_xdg_wm_base */ +static inline void * +xdg_wm_base_get_user_data(struct xdg_wm_base *xdg_wm_base) +{ + return wl_proxy_get_user_data((struct wl_proxy *) xdg_wm_base); +} + +static inline uint32_t +xdg_wm_base_get_version(struct xdg_wm_base *xdg_wm_base) +{ + return wl_proxy_get_version((struct wl_proxy *) xdg_wm_base); +} + +/** + * @ingroup iface_xdg_wm_base + * + * Destroy this xdg_wm_base object. + * + * Destroying a bound xdg_wm_base object while there are surfaces + * still alive created by this xdg_wm_base object instance is illegal + * and will result in a defunct_surfaces error. + */ +static inline void +xdg_wm_base_destroy(struct xdg_wm_base *xdg_wm_base) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_wm_base, + XDG_WM_BASE_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_wm_base), WL_MARSHAL_FLAG_DESTROY); +} + +/** + * @ingroup iface_xdg_wm_base + * + * Create a positioner object. A positioner object is used to position + * surfaces relative to some parent surface. See the interface description + * and xdg_surface.get_popup for details. + */ +static inline struct xdg_positioner * +xdg_wm_base_create_positioner(struct xdg_wm_base *xdg_wm_base) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) xdg_wm_base, + XDG_WM_BASE_CREATE_POSITIONER, &xdg_positioner_interface, wl_proxy_get_version((struct wl_proxy *) xdg_wm_base), 0, NULL); + + return (struct xdg_positioner *) id; +} + +/** + * @ingroup iface_xdg_wm_base + * + * This creates an xdg_surface for the given surface. While xdg_surface + * itself is not a role, the corresponding surface may only be assigned + * a role extending xdg_surface, such as xdg_toplevel or xdg_popup. It is + * illegal to create an xdg_surface for a wl_surface which already has an + * assigned role and this will result in a role error. + * + * This creates an xdg_surface for the given surface. An xdg_surface is + * used as basis to define a role to a given surface, such as xdg_toplevel + * or xdg_popup. It also manages functionality shared between xdg_surface + * based surface roles. + * + * See the documentation of xdg_surface for more details about what an + * xdg_surface is and how it is used. + */ +static inline struct xdg_surface * +xdg_wm_base_get_xdg_surface(struct xdg_wm_base *xdg_wm_base, struct wl_surface *surface) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) xdg_wm_base, + XDG_WM_BASE_GET_XDG_SURFACE, &xdg_surface_interface, wl_proxy_get_version((struct wl_proxy *) xdg_wm_base), 0, NULL, surface); + + return (struct xdg_surface *) id; +} + +/** + * @ingroup iface_xdg_wm_base + * + * A client must respond to a ping event with a pong request or + * the client may be deemed unresponsive. See xdg_wm_base.ping + * and xdg_wm_base.error.unresponsive. + */ +static inline void +xdg_wm_base_pong(struct xdg_wm_base *xdg_wm_base, uint32_t serial) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_wm_base, + XDG_WM_BASE_PONG, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_wm_base), 0, serial); +} + +#ifndef XDG_POSITIONER_ERROR_ENUM +#define XDG_POSITIONER_ERROR_ENUM +enum xdg_positioner_error { + /** + * invalid input provided + */ + XDG_POSITIONER_ERROR_INVALID_INPUT = 0, +}; +#endif /* XDG_POSITIONER_ERROR_ENUM */ + +#ifndef XDG_POSITIONER_ANCHOR_ENUM +#define XDG_POSITIONER_ANCHOR_ENUM +enum xdg_positioner_anchor { + XDG_POSITIONER_ANCHOR_NONE = 0, + XDG_POSITIONER_ANCHOR_TOP = 1, + XDG_POSITIONER_ANCHOR_BOTTOM = 2, + XDG_POSITIONER_ANCHOR_LEFT = 3, + XDG_POSITIONER_ANCHOR_RIGHT = 4, + XDG_POSITIONER_ANCHOR_TOP_LEFT = 5, + XDG_POSITIONER_ANCHOR_BOTTOM_LEFT = 6, + XDG_POSITIONER_ANCHOR_TOP_RIGHT = 7, + XDG_POSITIONER_ANCHOR_BOTTOM_RIGHT = 8, +}; +#endif /* XDG_POSITIONER_ANCHOR_ENUM */ + +#ifndef XDG_POSITIONER_GRAVITY_ENUM +#define XDG_POSITIONER_GRAVITY_ENUM +enum xdg_positioner_gravity { + XDG_POSITIONER_GRAVITY_NONE = 0, + XDG_POSITIONER_GRAVITY_TOP = 1, + XDG_POSITIONER_GRAVITY_BOTTOM = 2, + XDG_POSITIONER_GRAVITY_LEFT = 3, + XDG_POSITIONER_GRAVITY_RIGHT = 4, + XDG_POSITIONER_GRAVITY_TOP_LEFT = 5, + XDG_POSITIONER_GRAVITY_BOTTOM_LEFT = 6, + XDG_POSITIONER_GRAVITY_TOP_RIGHT = 7, + XDG_POSITIONER_GRAVITY_BOTTOM_RIGHT = 8, +}; +#endif /* XDG_POSITIONER_GRAVITY_ENUM */ + +#ifndef XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_ENUM +#define XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_ENUM +/** + * @ingroup iface_xdg_positioner + * constraint adjustments + * + * The constraint adjustment value define ways the compositor will adjust + * the position of the surface, if the unadjusted position would result + * in the surface being partly constrained. + * + * Whether a surface is considered 'constrained' is left to the compositor + * to determine. For example, the surface may be partly outside the + * compositor's defined 'work area', thus necessitating the child surface's + * position be adjusted until it is entirely inside the work area. + * + * The adjustments can be combined, according to a defined precedence: 1) + * Flip, 2) Slide, 3) Resize. + */ +enum xdg_positioner_constraint_adjustment { + /** + * don't move the child surface when constrained + * + * Don't alter the surface position even if it is constrained on + * some axis, for example partially outside the edge of an output. + */ + XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_NONE = 0, + /** + * move along the x axis until unconstrained + * + * Slide the surface along the x axis until it is no longer + * constrained. + * + * First try to slide towards the direction of the gravity on the x + * axis until either the edge in the opposite direction of the + * gravity is unconstrained or the edge in the direction of the + * gravity is constrained. + * + * Then try to slide towards the opposite direction of the gravity + * on the x axis until either the edge in the direction of the + * gravity is unconstrained or the edge in the opposite direction + * of the gravity is constrained. + */ + XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_X = 1, + /** + * move along the y axis until unconstrained + * + * Slide the surface along the y axis until it is no longer + * constrained. + * + * First try to slide towards the direction of the gravity on the y + * axis until either the edge in the opposite direction of the + * gravity is unconstrained or the edge in the direction of the + * gravity is constrained. + * + * Then try to slide towards the opposite direction of the gravity + * on the y axis until either the edge in the direction of the + * gravity is unconstrained or the edge in the opposite direction + * of the gravity is constrained. + */ + XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_Y = 2, + /** + * invert the anchor and gravity on the x axis + * + * Invert the anchor and gravity on the x axis if the surface is + * constrained on the x axis. For example, if the left edge of the + * surface is constrained, the gravity is 'left' and the anchor is + * 'left', change the gravity to 'right' and the anchor to 'right'. + * + * If the adjusted position also ends up being constrained, the + * resulting position of the flip_x adjustment will be the one + * before the adjustment. + */ + XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_X = 4, + /** + * invert the anchor and gravity on the y axis + * + * Invert the anchor and gravity on the y axis if the surface is + * constrained on the y axis. For example, if the bottom edge of + * the surface is constrained, the gravity is 'bottom' and the + * anchor is 'bottom', change the gravity to 'top' and the anchor + * to 'top'. + * + * The adjusted position is calculated given the original anchor + * rectangle and offset, but with the new flipped anchor and + * gravity values. + * + * If the adjusted position also ends up being constrained, the + * resulting position of the flip_y adjustment will be the one + * before the adjustment. + */ + XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_Y = 8, + /** + * horizontally resize the surface + * + * Resize the surface horizontally so that it is completely + * unconstrained. + */ + XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_RESIZE_X = 16, + /** + * vertically resize the surface + * + * Resize the surface vertically so that it is completely + * unconstrained. + */ + XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_RESIZE_Y = 32, +}; +#endif /* XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_ENUM */ + +#define XDG_POSITIONER_DESTROY 0 +#define XDG_POSITIONER_SET_SIZE 1 +#define XDG_POSITIONER_SET_ANCHOR_RECT 2 +#define XDG_POSITIONER_SET_ANCHOR 3 +#define XDG_POSITIONER_SET_GRAVITY 4 +#define XDG_POSITIONER_SET_CONSTRAINT_ADJUSTMENT 5 +#define XDG_POSITIONER_SET_OFFSET 6 +#define XDG_POSITIONER_SET_REACTIVE 7 +#define XDG_POSITIONER_SET_PARENT_SIZE 8 +#define XDG_POSITIONER_SET_PARENT_CONFIGURE 9 + + +/** + * @ingroup iface_xdg_positioner + */ +#define XDG_POSITIONER_DESTROY_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_positioner + */ +#define XDG_POSITIONER_SET_SIZE_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_positioner + */ +#define XDG_POSITIONER_SET_ANCHOR_RECT_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_positioner + */ +#define XDG_POSITIONER_SET_ANCHOR_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_positioner + */ +#define XDG_POSITIONER_SET_GRAVITY_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_positioner + */ +#define XDG_POSITIONER_SET_CONSTRAINT_ADJUSTMENT_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_positioner + */ +#define XDG_POSITIONER_SET_OFFSET_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_positioner + */ +#define XDG_POSITIONER_SET_REACTIVE_SINCE_VERSION 3 +/** + * @ingroup iface_xdg_positioner + */ +#define XDG_POSITIONER_SET_PARENT_SIZE_SINCE_VERSION 3 +/** + * @ingroup iface_xdg_positioner + */ +#define XDG_POSITIONER_SET_PARENT_CONFIGURE_SINCE_VERSION 3 + +/** @ingroup iface_xdg_positioner */ +static inline void +xdg_positioner_set_user_data(struct xdg_positioner *xdg_positioner, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) xdg_positioner, user_data); +} + +/** @ingroup iface_xdg_positioner */ +static inline void * +xdg_positioner_get_user_data(struct xdg_positioner *xdg_positioner) +{ + return wl_proxy_get_user_data((struct wl_proxy *) xdg_positioner); +} + +static inline uint32_t +xdg_positioner_get_version(struct xdg_positioner *xdg_positioner) +{ + return wl_proxy_get_version((struct wl_proxy *) xdg_positioner); +} + +/** + * @ingroup iface_xdg_positioner + * + * Notify the compositor that the xdg_positioner will no longer be used. + */ +static inline void +xdg_positioner_destroy(struct xdg_positioner *xdg_positioner) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner, + XDG_POSITIONER_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), WL_MARSHAL_FLAG_DESTROY); +} + +/** + * @ingroup iface_xdg_positioner + * + * Set the size of the surface that is to be positioned with the positioner + * object. The size is in surface-local coordinates and corresponds to the + * window geometry. See xdg_surface.set_window_geometry. + * + * If a zero or negative size is set the invalid_input error is raised. + */ +static inline void +xdg_positioner_set_size(struct xdg_positioner *xdg_positioner, int32_t width, int32_t height) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner, + XDG_POSITIONER_SET_SIZE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), 0, width, height); +} + +/** + * @ingroup iface_xdg_positioner + * + * Specify the anchor rectangle within the parent surface that the child + * surface will be placed relative to. The rectangle is relative to the + * window geometry as defined by xdg_surface.set_window_geometry of the + * parent surface. + * + * When the xdg_positioner object is used to position a child surface, the + * anchor rectangle may not extend outside the window geometry of the + * positioned child's parent surface. + * + * If a negative size is set the invalid_input error is raised. + */ +static inline void +xdg_positioner_set_anchor_rect(struct xdg_positioner *xdg_positioner, int32_t x, int32_t y, int32_t width, int32_t height) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner, + XDG_POSITIONER_SET_ANCHOR_RECT, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), 0, x, y, width, height); +} + +/** + * @ingroup iface_xdg_positioner + * + * Defines the anchor point for the anchor rectangle. The specified anchor + * is used derive an anchor point that the child surface will be + * positioned relative to. If a corner anchor is set (e.g. 'top_left' or + * 'bottom_right'), the anchor point will be at the specified corner; + * otherwise, the derived anchor point will be centered on the specified + * edge, or in the center of the anchor rectangle if no edge is specified. + */ +static inline void +xdg_positioner_set_anchor(struct xdg_positioner *xdg_positioner, uint32_t anchor) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner, + XDG_POSITIONER_SET_ANCHOR, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), 0, anchor); +} + +/** + * @ingroup iface_xdg_positioner + * + * Defines in what direction a surface should be positioned, relative to + * the anchor point of the parent surface. If a corner gravity is + * specified (e.g. 'bottom_right' or 'top_left'), then the child surface + * will be placed towards the specified gravity; otherwise, the child + * surface will be centered over the anchor point on any axis that had no + * gravity specified. If the gravity is not in the ‘gravity’ enum, an + * invalid_input error is raised. + */ +static inline void +xdg_positioner_set_gravity(struct xdg_positioner *xdg_positioner, uint32_t gravity) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner, + XDG_POSITIONER_SET_GRAVITY, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), 0, gravity); +} + +/** + * @ingroup iface_xdg_positioner + * + * Specify how the window should be positioned if the originally intended + * position caused the surface to be constrained, meaning at least + * partially outside positioning boundaries set by the compositor. The + * adjustment is set by constructing a bitmask describing the adjustment to + * be made when the surface is constrained on that axis. + * + * If no bit for one axis is set, the compositor will assume that the child + * surface should not change its position on that axis when constrained. + * + * If more than one bit for one axis is set, the order of how adjustments + * are applied is specified in the corresponding adjustment descriptions. + * + * The default adjustment is none. + */ +static inline void +xdg_positioner_set_constraint_adjustment(struct xdg_positioner *xdg_positioner, uint32_t constraint_adjustment) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner, + XDG_POSITIONER_SET_CONSTRAINT_ADJUSTMENT, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), 0, constraint_adjustment); +} + +/** + * @ingroup iface_xdg_positioner + * + * Specify the surface position offset relative to the position of the + * anchor on the anchor rectangle and the anchor on the surface. For + * example if the anchor of the anchor rectangle is at (x, y), the surface + * has the gravity bottom|right, and the offset is (ox, oy), the calculated + * surface position will be (x + ox, y + oy). The offset position of the + * surface is the one used for constraint testing. See + * set_constraint_adjustment. + * + * An example use case is placing a popup menu on top of a user interface + * element, while aligning the user interface element of the parent surface + * with some user interface element placed somewhere in the popup surface. + */ +static inline void +xdg_positioner_set_offset(struct xdg_positioner *xdg_positioner, int32_t x, int32_t y) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner, + XDG_POSITIONER_SET_OFFSET, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), 0, x, y); +} + +/** + * @ingroup iface_xdg_positioner + * + * When set reactive, the surface is reconstrained if the conditions used + * for constraining changed, e.g. the parent window moved. + * + * If the conditions changed and the popup was reconstrained, an + * xdg_popup.configure event is sent with updated geometry, followed by an + * xdg_surface.configure event. + */ +static inline void +xdg_positioner_set_reactive(struct xdg_positioner *xdg_positioner) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner, + XDG_POSITIONER_SET_REACTIVE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), 0); +} + +/** + * @ingroup iface_xdg_positioner + * + * Set the parent window geometry the compositor should use when + * positioning the popup. The compositor may use this information to + * determine the future state the popup should be constrained using. If + * this doesn't match the dimension of the parent the popup is eventually + * positioned against, the behavior is undefined. + * + * The arguments are given in the surface-local coordinate space. + */ +static inline void +xdg_positioner_set_parent_size(struct xdg_positioner *xdg_positioner, int32_t parent_width, int32_t parent_height) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner, + XDG_POSITIONER_SET_PARENT_SIZE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), 0, parent_width, parent_height); +} + +/** + * @ingroup iface_xdg_positioner + * + * Set the serial of an xdg_surface.configure event this positioner will be + * used in response to. The compositor may use this information together + * with set_parent_size to determine what future state the popup should be + * constrained using. + */ +static inline void +xdg_positioner_set_parent_configure(struct xdg_positioner *xdg_positioner, uint32_t serial) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner, + XDG_POSITIONER_SET_PARENT_CONFIGURE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), 0, serial); +} + +#ifndef XDG_SURFACE_ERROR_ENUM +#define XDG_SURFACE_ERROR_ENUM +enum xdg_surface_error { + /** + * Surface was not fully constructed + */ + XDG_SURFACE_ERROR_NOT_CONSTRUCTED = 1, + /** + * Surface was already constructed + */ + XDG_SURFACE_ERROR_ALREADY_CONSTRUCTED = 2, + /** + * Attaching a buffer to an unconfigured surface + */ + XDG_SURFACE_ERROR_UNCONFIGURED_BUFFER = 3, + /** + * Invalid serial number when acking a configure event + */ + XDG_SURFACE_ERROR_INVALID_SERIAL = 4, + /** + * Width or height was zero or negative + */ + XDG_SURFACE_ERROR_INVALID_SIZE = 5, + /** + * Surface was destroyed before its role object + */ + XDG_SURFACE_ERROR_DEFUNCT_ROLE_OBJECT = 6, +}; +#endif /* XDG_SURFACE_ERROR_ENUM */ + +/** + * @ingroup iface_xdg_surface + * @struct xdg_surface_listener + */ +struct xdg_surface_listener { + /** + * suggest a surface change + * + * The configure event marks the end of a configure sequence. A + * configure sequence is a set of one or more events configuring + * the state of the xdg_surface, including the final + * xdg_surface.configure event. + * + * Where applicable, xdg_surface surface roles will during a + * configure sequence extend this event as a latched state sent as + * events before the xdg_surface.configure event. Such events + * should be considered to make up a set of atomically applied + * configuration states, where the xdg_surface.configure commits + * the accumulated state. + * + * Clients should arrange their surface for the new states, and + * then send an ack_configure request with the serial sent in this + * configure event at some point before committing the new surface. + * + * If the client receives multiple configure events before it can + * respond to one, it is free to discard all but the last event it + * received. + * @param serial serial of the configure event + */ + void (*configure)(void *data, + struct xdg_surface *xdg_surface, + uint32_t serial); +}; + +/** + * @ingroup iface_xdg_surface + */ +static inline int +xdg_surface_add_listener(struct xdg_surface *xdg_surface, + const struct xdg_surface_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) xdg_surface, + (void (**)(void)) listener, data); +} + +#define XDG_SURFACE_DESTROY 0 +#define XDG_SURFACE_GET_TOPLEVEL 1 +#define XDG_SURFACE_GET_POPUP 2 +#define XDG_SURFACE_SET_WINDOW_GEOMETRY 3 +#define XDG_SURFACE_ACK_CONFIGURE 4 + +/** + * @ingroup iface_xdg_surface + */ +#define XDG_SURFACE_CONFIGURE_SINCE_VERSION 1 + +/** + * @ingroup iface_xdg_surface + */ +#define XDG_SURFACE_DESTROY_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_surface + */ +#define XDG_SURFACE_GET_TOPLEVEL_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_surface + */ +#define XDG_SURFACE_GET_POPUP_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_surface + */ +#define XDG_SURFACE_SET_WINDOW_GEOMETRY_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_surface + */ +#define XDG_SURFACE_ACK_CONFIGURE_SINCE_VERSION 1 + +/** @ingroup iface_xdg_surface */ +static inline void +xdg_surface_set_user_data(struct xdg_surface *xdg_surface, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) xdg_surface, user_data); +} + +/** @ingroup iface_xdg_surface */ +static inline void * +xdg_surface_get_user_data(struct xdg_surface *xdg_surface) +{ + return wl_proxy_get_user_data((struct wl_proxy *) xdg_surface); +} + +static inline uint32_t +xdg_surface_get_version(struct xdg_surface *xdg_surface) +{ + return wl_proxy_get_version((struct wl_proxy *) xdg_surface); +} + +/** + * @ingroup iface_xdg_surface + * + * Destroy the xdg_surface object. An xdg_surface must only be destroyed + * after its role object has been destroyed, otherwise + * a defunct_role_object error is raised. + */ +static inline void +xdg_surface_destroy(struct xdg_surface *xdg_surface) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_surface, + XDG_SURFACE_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_surface), WL_MARSHAL_FLAG_DESTROY); +} + +/** + * @ingroup iface_xdg_surface + * + * This creates an xdg_toplevel object for the given xdg_surface and gives + * the associated wl_surface the xdg_toplevel role. + * + * See the documentation of xdg_toplevel for more details about what an + * xdg_toplevel is and how it is used. + */ +static inline struct xdg_toplevel * +xdg_surface_get_toplevel(struct xdg_surface *xdg_surface) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) xdg_surface, + XDG_SURFACE_GET_TOPLEVEL, &xdg_toplevel_interface, wl_proxy_get_version((struct wl_proxy *) xdg_surface), 0, NULL); + + return (struct xdg_toplevel *) id; +} + +/** + * @ingroup iface_xdg_surface + * + * This creates an xdg_popup object for the given xdg_surface and gives + * the associated wl_surface the xdg_popup role. + * + * If null is passed as a parent, a parent surface must be specified using + * some other protocol, before committing the initial state. + * + * See the documentation of xdg_popup for more details about what an + * xdg_popup is and how it is used. + */ +static inline struct xdg_popup * +xdg_surface_get_popup(struct xdg_surface *xdg_surface, struct xdg_surface *parent, struct xdg_positioner *positioner) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) xdg_surface, + XDG_SURFACE_GET_POPUP, &xdg_popup_interface, wl_proxy_get_version((struct wl_proxy *) xdg_surface), 0, NULL, parent, positioner); + + return (struct xdg_popup *) id; +} + +/** + * @ingroup iface_xdg_surface + * + * The window geometry of a surface is its "visible bounds" from the + * user's perspective. Client-side decorations often have invisible + * portions like drop-shadows which should be ignored for the + * purposes of aligning, placing and constraining windows. Note that + * in some situations, compositors may clip rendering to the window + * geometry, so the client should avoid putting functional elements + * outside of it. + * + * The window geometry is double-buffered state, see wl_surface.commit. + * + * When maintaining a position, the compositor should treat the (x, y) + * coordinate of the window geometry as the top left corner of the window. + * A client changing the (x, y) window geometry coordinate should in + * general not alter the position of the window. + * + * Once the window geometry of the surface is set, it is not possible to + * unset it, and it will remain the same until set_window_geometry is + * called again, even if a new subsurface or buffer is attached. + * + * If never set, the value is the full bounds of the surface, + * including any subsurfaces. This updates dynamically on every + * commit. This unset is meant for extremely simple clients. + * + * The arguments are given in the surface-local coordinate space of + * the wl_surface associated with this xdg_surface, and may extend outside + * of the wl_surface itself to mark parts of the subsurface tree as part of + * the window geometry. + * + * When applied, the effective window geometry will be the set window + * geometry clamped to the bounding rectangle of the combined + * geometry of the surface of the xdg_surface and the associated + * subsurfaces. + * + * The effective geometry will not be recalculated unless a new call to + * set_window_geometry is done and the new pending surface state is + * subsequently applied. + * + * The width and height of the effective window geometry must be + * greater than zero. Setting an invalid size will raise an + * invalid_size error. + */ +static inline void +xdg_surface_set_window_geometry(struct xdg_surface *xdg_surface, int32_t x, int32_t y, int32_t width, int32_t height) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_surface, + XDG_SURFACE_SET_WINDOW_GEOMETRY, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_surface), 0, x, y, width, height); +} + +/** + * @ingroup iface_xdg_surface + * + * When a configure event is received, if a client commits the + * surface in response to the configure event, then the client + * must make an ack_configure request sometime before the commit + * request, passing along the serial of the configure event. + * + * For instance, for toplevel surfaces the compositor might use this + * information to move a surface to the top left only when the client has + * drawn itself for the maximized or fullscreen state. + * + * If the client receives multiple configure events before it + * can respond to one, it only has to ack the last configure event. + * Acking a configure event that was never sent raises an invalid_serial + * error. + * + * A client is not required to commit immediately after sending + * an ack_configure request - it may even ack_configure several times + * before its next surface commit. + * + * A client may send multiple ack_configure requests before committing, but + * only the last request sent before a commit indicates which configure + * event the client really is responding to. + * + * Sending an ack_configure request consumes the serial number sent with + * the request, as well as serial numbers sent by all configure events + * sent on this xdg_surface prior to the configure event referenced by + * the committed serial. + * + * It is an error to issue multiple ack_configure requests referencing a + * serial from the same configure event, or to issue an ack_configure + * request referencing a serial from a configure event issued before the + * event identified by the last ack_configure request for the same + * xdg_surface. Doing so will raise an invalid_serial error. + */ +static inline void +xdg_surface_ack_configure(struct xdg_surface *xdg_surface, uint32_t serial) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_surface, + XDG_SURFACE_ACK_CONFIGURE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_surface), 0, serial); +} + +#ifndef XDG_TOPLEVEL_ERROR_ENUM +#define XDG_TOPLEVEL_ERROR_ENUM +enum xdg_toplevel_error { + /** + * provided value is not a valid variant of the resize_edge enum + */ + XDG_TOPLEVEL_ERROR_INVALID_RESIZE_EDGE = 0, + /** + * invalid parent toplevel + */ + XDG_TOPLEVEL_ERROR_INVALID_PARENT = 1, + /** + * client provided an invalid min or max size + */ + XDG_TOPLEVEL_ERROR_INVALID_SIZE = 2, +}; +#endif /* XDG_TOPLEVEL_ERROR_ENUM */ + +#ifndef XDG_TOPLEVEL_RESIZE_EDGE_ENUM +#define XDG_TOPLEVEL_RESIZE_EDGE_ENUM +/** + * @ingroup iface_xdg_toplevel + * edge values for resizing + * + * These values are used to indicate which edge of a surface + * is being dragged in a resize operation. + */ +enum xdg_toplevel_resize_edge { + XDG_TOPLEVEL_RESIZE_EDGE_NONE = 0, + XDG_TOPLEVEL_RESIZE_EDGE_TOP = 1, + XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM = 2, + XDG_TOPLEVEL_RESIZE_EDGE_LEFT = 4, + XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT = 5, + XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT = 6, + XDG_TOPLEVEL_RESIZE_EDGE_RIGHT = 8, + XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT = 9, + XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT = 10, +}; +#endif /* XDG_TOPLEVEL_RESIZE_EDGE_ENUM */ + +#ifndef XDG_TOPLEVEL_STATE_ENUM +#define XDG_TOPLEVEL_STATE_ENUM +/** + * @ingroup iface_xdg_toplevel + * types of state on the surface + * + * The different state values used on the surface. This is designed for + * state values like maximized, fullscreen. It is paired with the + * configure event to ensure that both the client and the compositor + * setting the state can be synchronized. + * + * States set in this way are double-buffered, see wl_surface.commit. + */ +enum xdg_toplevel_state { + /** + * the surface is maximized + * the surface is maximized + * + * The surface is maximized. The window geometry specified in the + * configure event must be obeyed by the client, or the + * xdg_wm_base.invalid_surface_state error is raised. + * + * The client should draw without shadow or other decoration + * outside of the window geometry. + */ + XDG_TOPLEVEL_STATE_MAXIMIZED = 1, + /** + * the surface is fullscreen + * the surface is fullscreen + * + * The surface is fullscreen. The window geometry specified in + * the configure event is a maximum; the client cannot resize + * beyond it. For a surface to cover the whole fullscreened area, + * the geometry dimensions must be obeyed by the client. For more + * details, see xdg_toplevel.set_fullscreen. + */ + XDG_TOPLEVEL_STATE_FULLSCREEN = 2, + /** + * the surface is being resized + * the surface is being resized + * + * The surface is being resized. The window geometry specified in + * the configure event is a maximum; the client cannot resize + * beyond it. Clients that have aspect ratio or cell sizing + * configuration can use a smaller size, however. + */ + XDG_TOPLEVEL_STATE_RESIZING = 3, + /** + * the surface is now activated + * the surface is now activated + * + * Client window decorations should be painted as if the window + * is active. Do not assume this means that the window actually has + * keyboard or pointer focus. + */ + XDG_TOPLEVEL_STATE_ACTIVATED = 4, + /** + * the surface’s left edge is tiled + * + * The window is currently in a tiled layout and the left edge is + * considered to be adjacent to another part of the tiling grid. + * + * The client should draw without shadow or other decoration + * outside of the window geometry on the left edge. + * @since 2 + */ + XDG_TOPLEVEL_STATE_TILED_LEFT = 5, + /** + * the surface’s right edge is tiled + * + * The window is currently in a tiled layout and the right edge + * is considered to be adjacent to another part of the tiling grid. + * + * The client should draw without shadow or other decoration + * outside of the window geometry on the right edge. + * @since 2 + */ + XDG_TOPLEVEL_STATE_TILED_RIGHT = 6, + /** + * the surface’s top edge is tiled + * + * The window is currently in a tiled layout and the top edge is + * considered to be adjacent to another part of the tiling grid. + * + * The client should draw without shadow or other decoration + * outside of the window geometry on the top edge. + * @since 2 + */ + XDG_TOPLEVEL_STATE_TILED_TOP = 7, + /** + * the surface’s bottom edge is tiled + * + * The window is currently in a tiled layout and the bottom edge + * is considered to be adjacent to another part of the tiling grid. + * + * The client should draw without shadow or other decoration + * outside of the window geometry on the bottom edge. + * @since 2 + */ + XDG_TOPLEVEL_STATE_TILED_BOTTOM = 8, + /** + * surface repaint is suspended + * + * The surface is currently not ordinarily being repainted; for + * example because its content is occluded by another window, or + * its outputs are switched off due to screen locking. + * @since 6 + */ + XDG_TOPLEVEL_STATE_SUSPENDED = 9, + /** + * the surface’s left edge is constrained + * + * The left edge of the window is currently constrained, meaning + * it shouldn't attempt to resize from that edge. It can for + * example mean it's tiled next to a monitor edge on the + * constrained side of the window. + * @since 7 + */ + XDG_TOPLEVEL_STATE_CONSTRAINED_LEFT = 10, + /** + * the surface’s right edge is constrained + * + * The right edge of the window is currently constrained, meaning + * it shouldn't attempt to resize from that edge. It can for + * example mean it's tiled next to a monitor edge on the + * constrained side of the window. + * @since 7 + */ + XDG_TOPLEVEL_STATE_CONSTRAINED_RIGHT = 11, + /** + * the surface’s top edge is constrained + * + * The top edge of the window is currently constrained, meaning + * it shouldn't attempt to resize from that edge. It can for + * example mean it's tiled next to a monitor edge on the + * constrained side of the window. + * @since 7 + */ + XDG_TOPLEVEL_STATE_CONSTRAINED_TOP = 12, + /** + * the surface’s bottom edge is constrained + * + * The bottom edge of the window is currently constrained, + * meaning it shouldn't attempt to resize from that edge. It can + * for example mean it's tiled next to a monitor edge on the + * constrained side of the window. + * @since 7 + */ + XDG_TOPLEVEL_STATE_CONSTRAINED_BOTTOM = 13, +}; +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_STATE_TILED_LEFT_SINCE_VERSION 2 +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_STATE_TILED_RIGHT_SINCE_VERSION 2 +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_STATE_TILED_TOP_SINCE_VERSION 2 +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_STATE_TILED_BOTTOM_SINCE_VERSION 2 +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_STATE_SUSPENDED_SINCE_VERSION 6 +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_STATE_CONSTRAINED_LEFT_SINCE_VERSION 7 +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_STATE_CONSTRAINED_RIGHT_SINCE_VERSION 7 +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_STATE_CONSTRAINED_TOP_SINCE_VERSION 7 +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_STATE_CONSTRAINED_BOTTOM_SINCE_VERSION 7 +#endif /* XDG_TOPLEVEL_STATE_ENUM */ + +#ifndef XDG_TOPLEVEL_WM_CAPABILITIES_ENUM +#define XDG_TOPLEVEL_WM_CAPABILITIES_ENUM +enum xdg_toplevel_wm_capabilities { + /** + * show_window_menu is available + */ + XDG_TOPLEVEL_WM_CAPABILITIES_WINDOW_MENU = 1, + /** + * set_maximized and unset_maximized are available + */ + XDG_TOPLEVEL_WM_CAPABILITIES_MAXIMIZE = 2, + /** + * set_fullscreen and unset_fullscreen are available + */ + XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN = 3, + /** + * set_minimized is available + */ + XDG_TOPLEVEL_WM_CAPABILITIES_MINIMIZE = 4, +}; +#endif /* XDG_TOPLEVEL_WM_CAPABILITIES_ENUM */ + +/** + * @ingroup iface_xdg_toplevel + * @struct xdg_toplevel_listener + */ +struct xdg_toplevel_listener { + /** + * suggest a surface change + * + * This configure event asks the client to resize its toplevel + * surface or to change its state. The configured state should not + * be applied immediately. See xdg_surface.configure for details. + * + * The width and height arguments specify a hint to the window + * about how its surface should be resized in window geometry + * coordinates. See set_window_geometry. + * + * If the width or height arguments are zero, it means the client + * should decide its own window dimension. This may happen when the + * compositor needs to configure the state of the surface but + * doesn't have any information about any previous or expected + * dimension. + * + * The states listed in the event specify how the width/height + * arguments should be interpreted, and possibly how it should be + * drawn. + * + * Clients must send an ack_configure in response to this event. + * See xdg_surface.configure and xdg_surface.ack_configure for + * details. + */ + void (*configure)(void *data, + struct xdg_toplevel *xdg_toplevel, + int32_t width, + int32_t height, + struct wl_array *states); + /** + * surface wants to be closed + * + * The close event is sent by the compositor when the user wants + * the surface to be closed. This should be equivalent to the user + * clicking the close button in client-side decorations, if your + * application has any. + * + * This is only a request that the user intends to close the + * window. The client may choose to ignore this request, or show a + * dialog to ask the user to save their data, etc. + */ + void (*close)(void *data, + struct xdg_toplevel *xdg_toplevel); + /** + * recommended window geometry bounds + * + * The configure_bounds event may be sent prior to a + * xdg_toplevel.configure event to communicate the bounds a window + * geometry size is recommended to constrain to. + * + * The passed width and height are in surface coordinate space. If + * width and height are 0, it means bounds is unknown and + * equivalent to as if no configure_bounds event was ever sent for + * this surface. + * + * The bounds can for example correspond to the size of a monitor + * excluding any panels or other shell components, so that a + * surface isn't created in a way that it cannot fit. + * + * The bounds may change at any point, and in such a case, a new + * xdg_toplevel.configure_bounds will be sent, followed by + * xdg_toplevel.configure and xdg_surface.configure. + * @since 4 + */ + void (*configure_bounds)(void *data, + struct xdg_toplevel *xdg_toplevel, + int32_t width, + int32_t height); + /** + * compositor capabilities + * + * This event advertises the capabilities supported by the + * compositor. If a capability isn't supported, clients should hide + * or disable the UI elements that expose this functionality. For + * instance, if the compositor doesn't advertise support for + * minimized toplevels, a button triggering the set_minimized + * request should not be displayed. + * + * The compositor will ignore requests it doesn't support. For + * instance, a compositor which doesn't advertise support for + * minimized will ignore set_minimized requests. + * + * Compositors must send this event once before the first + * xdg_surface.configure event. When the capabilities change, + * compositors must send this event again and then send an + * xdg_surface.configure event. + * + * The configured state should not be applied immediately. See + * xdg_surface.configure for details. + * + * The capabilities are sent as an array of 32-bit unsigned + * integers in native endianness. + * @param capabilities array of 32-bit capabilities + * @since 5 + */ + void (*wm_capabilities)(void *data, + struct xdg_toplevel *xdg_toplevel, + struct wl_array *capabilities); +}; + +/** + * @ingroup iface_xdg_toplevel + */ +static inline int +xdg_toplevel_add_listener(struct xdg_toplevel *xdg_toplevel, + const struct xdg_toplevel_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) xdg_toplevel, + (void (**)(void)) listener, data); +} + +#define XDG_TOPLEVEL_DESTROY 0 +#define XDG_TOPLEVEL_SET_PARENT 1 +#define XDG_TOPLEVEL_SET_TITLE 2 +#define XDG_TOPLEVEL_SET_APP_ID 3 +#define XDG_TOPLEVEL_SHOW_WINDOW_MENU 4 +#define XDG_TOPLEVEL_MOVE 5 +#define XDG_TOPLEVEL_RESIZE 6 +#define XDG_TOPLEVEL_SET_MAX_SIZE 7 +#define XDG_TOPLEVEL_SET_MIN_SIZE 8 +#define XDG_TOPLEVEL_SET_MAXIMIZED 9 +#define XDG_TOPLEVEL_UNSET_MAXIMIZED 10 +#define XDG_TOPLEVEL_SET_FULLSCREEN 11 +#define XDG_TOPLEVEL_UNSET_FULLSCREEN 12 +#define XDG_TOPLEVEL_SET_MINIMIZED 13 + +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_CONFIGURE_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_CLOSE_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_CONFIGURE_BOUNDS_SINCE_VERSION 4 +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_WM_CAPABILITIES_SINCE_VERSION 5 + +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_DESTROY_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_SET_PARENT_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_SET_TITLE_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_SET_APP_ID_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_SHOW_WINDOW_MENU_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_MOVE_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_RESIZE_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_SET_MAX_SIZE_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_SET_MIN_SIZE_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_SET_MAXIMIZED_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_UNSET_MAXIMIZED_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_SET_FULLSCREEN_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_UNSET_FULLSCREEN_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_SET_MINIMIZED_SINCE_VERSION 1 + +/** @ingroup iface_xdg_toplevel */ +static inline void +xdg_toplevel_set_user_data(struct xdg_toplevel *xdg_toplevel, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) xdg_toplevel, user_data); +} + +/** @ingroup iface_xdg_toplevel */ +static inline void * +xdg_toplevel_get_user_data(struct xdg_toplevel *xdg_toplevel) +{ + return wl_proxy_get_user_data((struct wl_proxy *) xdg_toplevel); +} + +static inline uint32_t +xdg_toplevel_get_version(struct xdg_toplevel *xdg_toplevel) +{ + return wl_proxy_get_version((struct wl_proxy *) xdg_toplevel); +} + +/** + * @ingroup iface_xdg_toplevel + * + * This request destroys the role surface and unmaps the surface; + * see "Unmapping" behavior in interface section for details. + */ +static inline void +xdg_toplevel_destroy(struct xdg_toplevel *xdg_toplevel) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel, + XDG_TOPLEVEL_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), WL_MARSHAL_FLAG_DESTROY); +} + +/** + * @ingroup iface_xdg_toplevel + * + * Set the "parent" of this surface. This surface should be stacked + * above the parent surface and all other ancestor surfaces. + * + * Parent surfaces should be set on dialogs, toolboxes, or other + * "auxiliary" surfaces, so that the parent is raised when the dialog + * is raised. + * + * Setting a null parent for a child surface unsets its parent. Setting + * a null parent for a surface which currently has no parent is a no-op. + * + * Only mapped surfaces can have child surfaces. Setting a parent which + * is not mapped is equivalent to setting a null parent. If a surface + * becomes unmapped, its children's parent is set to the parent of + * the now-unmapped surface. If the now-unmapped surface has no parent, + * its children's parent is unset. If the now-unmapped surface becomes + * mapped again, its parent-child relationship is not restored. + * + * The parent toplevel must not be one of the child toplevel's + * descendants, and the parent must be different from the child toplevel, + * otherwise the invalid_parent protocol error is raised. + */ +static inline void +xdg_toplevel_set_parent(struct xdg_toplevel *xdg_toplevel, struct xdg_toplevel *parent) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel, + XDG_TOPLEVEL_SET_PARENT, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0, parent); +} + +/** + * @ingroup iface_xdg_toplevel + * + * Set a short title for the surface. + * + * This string may be used to identify the surface in a task bar, + * window list, or other user interface elements provided by the + * compositor. + * + * The string must be encoded in UTF-8. + */ +static inline void +xdg_toplevel_set_title(struct xdg_toplevel *xdg_toplevel, const char *title) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel, + XDG_TOPLEVEL_SET_TITLE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0, title); +} + +/** + * @ingroup iface_xdg_toplevel + * + * Set an application identifier for the surface. + * + * The app ID identifies the general class of applications to which + * the surface belongs. The compositor can use this to group multiple + * surfaces together, or to determine how to launch a new application. + * + * For D-Bus activatable applications, the app ID is used as the D-Bus + * service name. + * + * The compositor shell will try to group application surfaces together + * by their app ID. As a best practice, it is suggested to select app + * ID's that match the basename of the application's .desktop file. + * For example, "org.freedesktop.FooViewer" where the .desktop file is + * "org.freedesktop.FooViewer.desktop". + * + * Like other properties, a set_app_id request can be sent after the + * xdg_toplevel has been mapped to update the property. + * + * See the desktop-entry specification [0] for more details on + * application identifiers and how they relate to well-known D-Bus + * names and .desktop files. + * + * [0] https://standards.freedesktop.org/desktop-entry-spec/ + */ +static inline void +xdg_toplevel_set_app_id(struct xdg_toplevel *xdg_toplevel, const char *app_id) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel, + XDG_TOPLEVEL_SET_APP_ID, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0, app_id); +} + +/** + * @ingroup iface_xdg_toplevel + * + * Clients implementing client-side decorations might want to show + * a context menu when right-clicking on the decorations, giving the + * user a menu that they can use to maximize or minimize the window. + * + * This request asks the compositor to pop up such a window menu at + * the given position, relative to the local surface coordinates of + * the parent surface. There are no guarantees as to what menu items + * the window menu contains, or even if a window menu will be drawn + * at all. + * + * This request must be used in response to some sort of user action + * like a button press, key press, or touch down event. + */ +static inline void +xdg_toplevel_show_window_menu(struct xdg_toplevel *xdg_toplevel, struct wl_seat *seat, uint32_t serial, int32_t x, int32_t y) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel, + XDG_TOPLEVEL_SHOW_WINDOW_MENU, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0, seat, serial, x, y); +} + +/** + * @ingroup iface_xdg_toplevel + * + * Start an interactive, user-driven move of the surface. + * + * This request must be used in response to some sort of user action + * like a button press, key press, or touch down event. The passed + * serial is used to determine the type of interactive move (touch, + * pointer, etc). + * + * The server may ignore move requests depending on the state of + * the surface (e.g. fullscreen or maximized), or if the passed serial + * is no longer valid. + * + * If triggered, the surface will lose the focus of the device + * (wl_pointer, wl_touch, etc) used for the move. It is up to the + * compositor to visually indicate that the move is taking place, such as + * updating a pointer cursor, during the move. There is no guarantee + * that the device focus will return when the move is completed. + */ +static inline void +xdg_toplevel_move(struct xdg_toplevel *xdg_toplevel, struct wl_seat *seat, uint32_t serial) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel, + XDG_TOPLEVEL_MOVE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0, seat, serial); +} + +/** + * @ingroup iface_xdg_toplevel + * + * Start a user-driven, interactive resize of the surface. + * + * This request must be used in response to some sort of user action + * like a button press, key press, or touch down event. The passed + * serial is used to determine the type of interactive resize (touch, + * pointer, etc). + * + * The server may ignore resize requests depending on the state of + * the surface (e.g. fullscreen or maximized). + * + * If triggered, the client will receive configure events with the + * "resize" state enum value and the expected sizes. See the "resize" + * enum value for more details about what is required. The client + * must also acknowledge configure events using "ack_configure". After + * the resize is completed, the client will receive another "configure" + * event without the resize state. + * + * If triggered, the surface also will lose the focus of the device + * (wl_pointer, wl_touch, etc) used for the resize. It is up to the + * compositor to visually indicate that the resize is taking place, + * such as updating a pointer cursor, during the resize. There is no + * guarantee that the device focus will return when the resize is + * completed. + * + * The edges parameter specifies how the surface should be resized, and + * is one of the values of the resize_edge enum. Values not matching + * a variant of the enum will cause the invalid_resize_edge protocol error. + * The compositor may use this information to update the surface position + * for example when dragging the top left corner. The compositor may also + * use this information to adapt its behavior, e.g. choose an appropriate + * cursor image. + */ +static inline void +xdg_toplevel_resize(struct xdg_toplevel *xdg_toplevel, struct wl_seat *seat, uint32_t serial, uint32_t edges) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel, + XDG_TOPLEVEL_RESIZE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0, seat, serial, edges); +} + +/** + * @ingroup iface_xdg_toplevel + * + * Set a maximum size for the window. + * + * The client can specify a maximum size so that the compositor does + * not try to configure the window beyond this size. + * + * The width and height arguments are in window geometry coordinates. + * See xdg_surface.set_window_geometry. + * + * Values set in this way are double-buffered, see wl_surface.commit. + * + * The compositor can use this information to allow or disallow + * different states like maximize or fullscreen and draw accurate + * animations. + * + * Similarly, a tiling window manager may use this information to + * place and resize client windows in a more effective way. + * + * The client should not rely on the compositor to obey the maximum + * size. The compositor may decide to ignore the values set by the + * client and request a larger size. + * + * If never set, or a value of zero in the request, means that the + * client has no expected maximum size in the given dimension. + * As a result, a client wishing to reset the maximum size + * to an unspecified state can use zero for width and height in the + * request. + * + * Requesting a maximum size to be smaller than the minimum size of + * a surface is illegal and will result in an invalid_size error. + * + * The width and height must be greater than or equal to zero. Using + * strictly negative values for width or height will result in a + * invalid_size error. + */ +static inline void +xdg_toplevel_set_max_size(struct xdg_toplevel *xdg_toplevel, int32_t width, int32_t height) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel, + XDG_TOPLEVEL_SET_MAX_SIZE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0, width, height); +} + +/** + * @ingroup iface_xdg_toplevel + * + * Set a minimum size for the window. + * + * The client can specify a minimum size so that the compositor does + * not try to configure the window below this size. + * + * The width and height arguments are in window geometry coordinates. + * See xdg_surface.set_window_geometry. + * + * Values set in this way are double-buffered, see wl_surface.commit. + * + * The compositor can use this information to allow or disallow + * different states like maximize or fullscreen and draw accurate + * animations. + * + * Similarly, a tiling window manager may use this information to + * place and resize client windows in a more effective way. + * + * The client should not rely on the compositor to obey the minimum + * size. The compositor may decide to ignore the values set by the + * client and request a smaller size. + * + * If never set, or a value of zero in the request, means that the + * client has no expected minimum size in the given dimension. + * As a result, a client wishing to reset the minimum size + * to an unspecified state can use zero for width and height in the + * request. + * + * Requesting a minimum size to be larger than the maximum size of + * a surface is illegal and will result in an invalid_size error. + * + * The width and height must be greater than or equal to zero. Using + * strictly negative values for width and height will result in a + * invalid_size error. + */ +static inline void +xdg_toplevel_set_min_size(struct xdg_toplevel *xdg_toplevel, int32_t width, int32_t height) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel, + XDG_TOPLEVEL_SET_MIN_SIZE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0, width, height); +} + +/** + * @ingroup iface_xdg_toplevel + * + * Maximize the surface. + * + * After requesting that the surface should be maximized, the compositor + * will respond by emitting a configure event. Whether this configure + * actually sets the window maximized is subject to compositor policies. + * The client must then update its content, drawing in the configured + * state. The client must also acknowledge the configure when committing + * the new content (see ack_configure). + * + * It is up to the compositor to decide how and where to maximize the + * surface, for example which output and what region of the screen should + * be used. + * + * If the surface was already maximized, the compositor will still emit + * a configure event with the "maximized" state. + * + * If the surface is in a fullscreen state, this request has no direct + * effect. It may alter the state the surface is returned to when + * unmaximized unless overridden by the compositor. + */ +static inline void +xdg_toplevel_set_maximized(struct xdg_toplevel *xdg_toplevel) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel, + XDG_TOPLEVEL_SET_MAXIMIZED, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0); +} + +/** + * @ingroup iface_xdg_toplevel + * + * Unmaximize the surface. + * + * After requesting that the surface should be unmaximized, the compositor + * will respond by emitting a configure event. Whether this actually + * un-maximizes the window is subject to compositor policies. + * If available and applicable, the compositor will include the window + * geometry dimensions the window had prior to being maximized in the + * configure event. The client must then update its content, drawing it in + * the configured state. The client must also acknowledge the configure + * when committing the new content (see ack_configure). + * + * It is up to the compositor to position the surface after it was + * unmaximized; usually the position the surface had before maximizing, if + * applicable. + * + * If the surface was already not maximized, the compositor will still + * emit a configure event without the "maximized" state. + * + * If the surface is in a fullscreen state, this request has no direct + * effect. It may alter the state the surface is returned to when + * unmaximized unless overridden by the compositor. + */ +static inline void +xdg_toplevel_unset_maximized(struct xdg_toplevel *xdg_toplevel) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel, + XDG_TOPLEVEL_UNSET_MAXIMIZED, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0); +} + +/** + * @ingroup iface_xdg_toplevel + * + * Make the surface fullscreen. + * + * After requesting that the surface should be fullscreened, the + * compositor will respond by emitting a configure event. Whether the + * client is actually put into a fullscreen state is subject to compositor + * policies. The client must also acknowledge the configure when + * committing the new content (see ack_configure). + * + * The output passed by the request indicates the client's preference as + * to which display it should be set fullscreen on. If this value is NULL, + * it's up to the compositor to choose which display will be used to map + * this surface. + * + * If the surface doesn't cover the whole output, the compositor will + * position the surface in the center of the output and compensate with + * with border fill covering the rest of the output. The content of the + * border fill is undefined, but should be assumed to be in some way that + * attempts to blend into the surrounding area (e.g. solid black). + * + * If the fullscreened surface is not opaque, the compositor must make + * sure that other screen content not part of the same surface tree (made + * up of subsurfaces, popups or similarly coupled surfaces) are not + * visible below the fullscreened surface. + */ +static inline void +xdg_toplevel_set_fullscreen(struct xdg_toplevel *xdg_toplevel, struct wl_output *output) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel, + XDG_TOPLEVEL_SET_FULLSCREEN, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0, output); +} + +/** + * @ingroup iface_xdg_toplevel + * + * Make the surface no longer fullscreen. + * + * After requesting that the surface should be unfullscreened, the + * compositor will respond by emitting a configure event. + * Whether this actually removes the fullscreen state of the client is + * subject to compositor policies. + * + * Making a surface unfullscreen sets states for the surface based on the following: + * * the state(s) it may have had before becoming fullscreen + * * any state(s) decided by the compositor + * * any state(s) requested by the client while the surface was fullscreen + * + * The compositor may include the previous window geometry dimensions in + * the configure event, if applicable. + * + * The client must also acknowledge the configure when committing the new + * content (see ack_configure). + */ +static inline void +xdg_toplevel_unset_fullscreen(struct xdg_toplevel *xdg_toplevel) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel, + XDG_TOPLEVEL_UNSET_FULLSCREEN, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0); +} + +/** + * @ingroup iface_xdg_toplevel + * + * Request that the compositor minimize your surface. There is no + * way to know if the surface is currently minimized, nor is there + * any way to unset minimization on this surface. + * + * If you are looking to throttle redrawing when minimized, please + * instead use the wl_surface.frame event for this, as this will + * also work with live previews on windows in Alt-Tab, Expose or + * similar compositor features. + */ +static inline void +xdg_toplevel_set_minimized(struct xdg_toplevel *xdg_toplevel) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel, + XDG_TOPLEVEL_SET_MINIMIZED, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0); +} + +#ifndef XDG_POPUP_ERROR_ENUM +#define XDG_POPUP_ERROR_ENUM +enum xdg_popup_error { + /** + * tried to grab after being mapped + */ + XDG_POPUP_ERROR_INVALID_GRAB = 0, +}; +#endif /* XDG_POPUP_ERROR_ENUM */ + +/** + * @ingroup iface_xdg_popup + * @struct xdg_popup_listener + */ +struct xdg_popup_listener { + /** + * configure the popup surface + * + * This event asks the popup surface to configure itself given + * the configuration. The configured state should not be applied + * immediately. See xdg_surface.configure for details. + * + * The x and y arguments represent the position the popup was + * placed at given the xdg_positioner rule, relative to the upper + * left corner of the window geometry of the parent surface. + * + * For version 2 or older, the configure event for an xdg_popup is + * only ever sent once for the initial configuration. Starting with + * version 3, it may be sent again if the popup is setup with an + * xdg_positioner with set_reactive requested, or in response to + * xdg_popup.reposition requests. + * @param x x position relative to parent surface window geometry + * @param y y position relative to parent surface window geometry + * @param width window geometry width + * @param height window geometry height + */ + void (*configure)(void *data, + struct xdg_popup *xdg_popup, + int32_t x, + int32_t y, + int32_t width, + int32_t height); + /** + * popup interaction is done + * + * The popup_done event is sent out when a popup is dismissed by + * the compositor. The client should destroy the xdg_popup object + * at this point. + */ + void (*popup_done)(void *data, + struct xdg_popup *xdg_popup); + /** + * signal the completion of a repositioned request + * + * The repositioned event is sent as part of a popup + * configuration sequence, together with xdg_popup.configure and + * lastly xdg_surface.configure to notify the completion of a + * reposition request. + * + * The repositioned event is to notify about the completion of a + * xdg_popup.reposition request. The token argument is the token + * passed in the xdg_popup.reposition request. + * + * Immediately after this event is emitted, xdg_popup.configure and + * xdg_surface.configure will be sent with the updated size and + * position, as well as a new configure serial. + * + * The client should optionally update the content of the popup, + * but must acknowledge the new popup configuration for the new + * position to take effect. See xdg_surface.ack_configure for + * details. + * @param token reposition request token + * @since 3 + */ + void (*repositioned)(void *data, + struct xdg_popup *xdg_popup, + uint32_t token); +}; + +/** + * @ingroup iface_xdg_popup + */ +static inline int +xdg_popup_add_listener(struct xdg_popup *xdg_popup, + const struct xdg_popup_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) xdg_popup, + (void (**)(void)) listener, data); +} + +#define XDG_POPUP_DESTROY 0 +#define XDG_POPUP_GRAB 1 +#define XDG_POPUP_REPOSITION 2 + +/** + * @ingroup iface_xdg_popup + */ +#define XDG_POPUP_CONFIGURE_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_popup + */ +#define XDG_POPUP_POPUP_DONE_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_popup + */ +#define XDG_POPUP_REPOSITIONED_SINCE_VERSION 3 + +/** + * @ingroup iface_xdg_popup + */ +#define XDG_POPUP_DESTROY_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_popup + */ +#define XDG_POPUP_GRAB_SINCE_VERSION 1 +/** + * @ingroup iface_xdg_popup + */ +#define XDG_POPUP_REPOSITION_SINCE_VERSION 3 + +/** @ingroup iface_xdg_popup */ +static inline void +xdg_popup_set_user_data(struct xdg_popup *xdg_popup, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) xdg_popup, user_data); +} + +/** @ingroup iface_xdg_popup */ +static inline void * +xdg_popup_get_user_data(struct xdg_popup *xdg_popup) +{ + return wl_proxy_get_user_data((struct wl_proxy *) xdg_popup); +} + +static inline uint32_t +xdg_popup_get_version(struct xdg_popup *xdg_popup) +{ + return wl_proxy_get_version((struct wl_proxy *) xdg_popup); +} + +/** + * @ingroup iface_xdg_popup + * + * This destroys the popup. Explicitly destroying the xdg_popup + * object will also dismiss the popup, and unmap the surface. + * + * If this xdg_popup is not the "topmost" popup, the + * xdg_wm_base.not_the_topmost_popup protocol error will be sent. + */ +static inline void +xdg_popup_destroy(struct xdg_popup *xdg_popup) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_popup, + XDG_POPUP_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_popup), WL_MARSHAL_FLAG_DESTROY); +} + +/** + * @ingroup iface_xdg_popup + * + * This request makes the created popup take an explicit grab. An explicit + * grab will be dismissed when the user dismisses the popup, or when the + * client destroys the xdg_popup. This can be done by the user clicking + * outside the surface, using the keyboard, or even locking the screen + * through closing the lid or a timeout. + * + * If the compositor denies the grab, the popup will be immediately + * dismissed. + * + * This request must be used in response to some sort of user action like a + * button press, key press, or touch down event. The serial number of the + * event should be passed as 'serial'. + * + * The parent of a grabbing popup must either be an xdg_toplevel surface or + * another xdg_popup with an explicit grab. If the parent is another + * xdg_popup it means that the popups are nested, with this popup now being + * the topmost popup. + * + * Nested popups must be destroyed in the reverse order they were created + * in, e.g. the only popup you are allowed to destroy at all times is the + * topmost one. + * + * When compositors choose to dismiss a popup, they may dismiss every + * nested grabbing popup as well. When a compositor dismisses popups, it + * will follow the same dismissing order as required from the client. + * + * If the topmost grabbing popup is destroyed, the grab will be returned to + * the parent of the popup, if that parent previously had an explicit grab. + * + * If the parent is a grabbing popup which has already been dismissed, this + * popup will be immediately dismissed. If the parent is a popup that did + * not take an explicit grab, an error will be raised. + * + * During a popup grab, the client owning the grab will receive pointer + * and touch events for all their surfaces as normal (similar to an + * "owner-events" grab in X11 parlance), while the top most grabbing popup + * will always have keyboard focus. + */ +static inline void +xdg_popup_grab(struct xdg_popup *xdg_popup, struct wl_seat *seat, uint32_t serial) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_popup, + XDG_POPUP_GRAB, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_popup), 0, seat, serial); +} + +/** + * @ingroup iface_xdg_popup + * + * Reposition an already-mapped popup. The popup will be placed given the + * details in the passed xdg_positioner object, and a + * xdg_popup.repositioned followed by xdg_popup.configure and + * xdg_surface.configure will be emitted in response. Any parameters set + * by the previous positioner will be discarded. + * + * The passed token will be sent in the corresponding + * xdg_popup.repositioned event. The new popup position will not take + * effect until the corresponding configure event is acknowledged by the + * client. See xdg_popup.repositioned for details. The token itself is + * opaque, and has no other special meaning. + * + * If multiple reposition requests are sent, the compositor may skip all + * but the last one. + * + * If the popup is repositioned in response to a configure event for its + * parent, the client should send an xdg_positioner.set_parent_configure + * and possibly an xdg_positioner.set_parent_size request to allow the + * compositor to properly constrain the popup. + * + * If the popup is repositioned together with a parent that is being + * resized, but not in response to a configure event, the client should + * send an xdg_positioner.set_parent_size request. + */ +static inline void +xdg_popup_reposition(struct xdg_popup *xdg_popup, struct xdg_positioner *positioner, uint32_t token) +{ + wl_proxy_marshal_flags((struct wl_proxy *) xdg_popup, + XDG_POPUP_REPOSITION, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_popup), 0, positioner, token); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/xdg-shell-protocol.o b/xdg-shell-protocol.o new file mode 100644 index 0000000000000000000000000000000000000000..5962166ca9f2c34e18216a658ebfe2cd8962481f GIT binary patch literal 11872 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 MLR<)48ci<$4^MSf?EnA( literal 0 HcmV?d00001