wl-mirror-0.16.5/0000755000175000017500000000000014646472005012257 5ustar yrlfyrlfwl-mirror-0.16.5/CMakeLists.txt0000644000175000017500000000376714646471773015047 0ustar yrlfyrlfcmake_minimum_required(VERSION 3.18) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) project(wl-mirror C) # options option(INSTALL_EXAMPLE_SCRIPTS "install wl-mirror example scripts" OFF) option(INSTALL_DOCUMENTATION "install wl-mirror manual pages" OFF) # wayland protocols needed by wl-mirror option(FORCE_SYSTEM_WL_PROTOCOLS "force use of system wayland-protocols" OFF) option(FORCE_SYSTEM_WLR_PROTOCOLS "force use of system wlr-protocols" OFF) set(WL_PROTOCOL_DIR "/usr/share/wayland-protocols/" CACHE STRING "wayland-protocols directory") set(WLR_PROTOCOL_DIR "/usr/share/wlr-protocols/" CACHE STRING "wlr-protocols directory") set(PROTOCOLS "stable/xdg-shell/xdg-shell.xml" "stable/viewporter/viewporter.xml" "staging/fractional-scale/fractional-scale-v1.xml" "unstable/xdg-output/xdg-output-unstable-v1.xml" "unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml" "unstable/wlr-export-dmabuf-unstable-v1.xml" "unstable/wlr-screencopy-unstable-v1.xml" ) # required dependencies add_subdirectory(deps) # wayland protocol wrapper generation with wayland-scanner add_subdirectory(proto) # shader file embedding add_subdirectory(glsl) # version embedding add_subdirectory(version) # manual pages add_subdirectory(man) if (${BUILD_DOCUMENTATION}) build_scdoc_man_page(wl-mirror 1) build_scdoc_man_page(wl-present 1) endif() # main target file(GLOB sources CONFIGURE_DEPENDS src/*.c) add_executable(wl-mirror ${sources}) target_compile_options(wl-mirror PRIVATE -Wall -Wextra) target_include_directories(wl-mirror PRIVATE include/) target_link_libraries(wl-mirror PRIVATE deps protocols shaders version) # installation rules include(GNUInstallDirs) install(TARGETS wl-mirror DESTINATION "${CMAKE_INSTALL_BINDIR}") if (${INSTALL_EXAMPLE_SCRIPTS}) install(PROGRAMS scripts/wl-present DESTINATION "${CMAKE_INSTALL_BINDIR}") endif() if (${INSTALL_DOCUMENTATION}) install_scdoc_man_page(wl-mirror 1) if (${INSTALL_EXAMPLE_SCRIPTS}) install_scdoc_man_page(wl-present 1) endif() endif() wl-mirror-0.16.5/LICENSE0000644000175000017500000010451514646471773013305 0ustar yrlfyrlf 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 . wl-mirror-0.16.5/README.md0000644000175000017500000002071614646471773013557 0ustar yrlfyrlf# `wl-mirror` - a simple Wayland output mirror client `wl-mirror` attempts to provide a solution to sway's lack of output mirroring by mirroring an output onto a client surface. ## Features - Mirror an output onto a resizable window - Mirror an output onto another output by fullscreening the window - Reacts to changes in output scale (including fractional scaling) - Preserves aspect ratio - Corrects for flipped or rotated outputs - Supports custom flips or rotations - Supports mirroring custom regions of outputs - Supports receiving additional options on stdin for changing the mirrored screen or region on the fly (works best when used with [pipectl](https://github.com/Ferdi265/pipectl)) ![demo screenshot](https://user-images.githubusercontent.com/4077106/141605347-37ba690c-f885-422a-93a6-81d5a48bee13.png) ## Usage ``` usage: wl-mirror [options] options: -h, --help show this help -V, --version print version -v, --verbose enable debug logging --no-verbose disable debug logging (default) -c, --show-cursor show the cursor on the mirrored screen (default) --no-show-cursor don't show the cursor on the mirrored screen -i, --invert-colors invert colors in the mirrored screen --no-invert-colors don't invert colors in the mirrored screen (default) -f, --freeze freeze the current image on the screen --unfreeze resume the screen capture after a freeze --toggle-freeze toggle freeze state of screen capture -F, --fullscreen open wl-mirror as fullscreen --no-fullscreen open wl-mirror as a window (default) --fullscreen-output O open wl-mirror as fullscreen on output O --no-fullscreen-output open wl-mirror as fullscreen on the current output (default) -s f, --scaling fit scale to fit (default) -s c, --scaling cover scale to cover, cropping if needed -s e, --scaling exact only scale to exact multiples of the output size -s l, --scaling linear use linear scaling (default) -s n, --scaling nearest use nearest neighbor scaling -b B --backend B use a specific backend for capturing the screen -t T, --transform T apply custom transform T -r R, --region R capture custom region R --no-region capture the entire output (default) -S, --stream accept a stream of additional options on stdin backends: - auto automatically try the backends in order and use the first that works (default) - dmabuf use the wlr-export-dmabuf-unstable-v1 protocol to capture outputs - screencopy use the wlr-screencopy-unstable-v1 protocol to capture outputs transforms: transforms are specified as a dash-separated list of flips followed by a rotation flips are applied before rotations - normal no transformation - flipX, flipY flip the X or Y coordinate - 0cw, 90cw, 180cw, 270cw apply a clockwise rotation - 0ccw, 90ccw, 180ccw, 270ccw apply a counter-clockwise rotation the following transformation options are provided for compatibility with sway output transforms - flipped flip the X coordinate - 0, 90, 180, 270 apply a clockwise rotation regions: regions are specified in the format used by the slurp utility - ', x [output]' on start, the region is translated into output coordinates when the output moves, the captured region moves with it when a region is specified, the argument is optional stream mode: in stream mode, wl-mirror interprets lines on stdin as additional command line options - arguments can be quoted with single or double quotes, but every argument must be fully quoted or fully unquoted - unquoted arguments are split on whitespace - no escape sequences are implemented ``` The [`scripts/`](scripts/) folder contains examples on how `wl-mirror` can be used. - [`wl-present`](scripts/wl-present) is a small script to demonstrate the use of the `-S` option to interactively present on Sway. This script is especially useful when binding the `wl-present` subcommands to keyboard shortcuts. See example below - [`release.sh`](scripts/release.sh) Generates a release tar ball for the currently checked out commit if there's a release tag on it. ### Sway Keybindings Example The following keybindings shortcuts can be used in your sway config. ``` mode "present" { # command starts mirroring bindsym m mode "default"; exec wl-present mirror # these commands modify an already running mirroring window bindsym o mode "default"; exec wl-present set-output bindsym r mode "default"; exec wl-present set-region bindsym Shift+r mode "default"; exec wl-present unset-region bindsym s mode "default"; exec wl-present set-scaling bindsym f mode "default"; exec wl-present toggle-freeze bindsym c mode "default"; exec wl-present custom # return to default mode bindsym Return mode "default" bindsym Escape mode "default" } bindsym $mod+p mode "present" ``` This requires `wl-mirror`, the `wl-present` script, `pipectl` (optional), slurp, and one of `wofi`, `wmenu`, `rofi`, or `dmenu`. ### Kanshi Configuration Example The following [kanshi](https://git.sr.ht/~emersion/kanshi) profile will launch wl-mirror in fullscreen on an external output mirroring your internal output when switched to with `kanshictl switch mirror-hdmi` or when selected automatically. ``` profile mirror-hdmi { output eDP-1 enable mode 1920x1080 position 0,0 output HDMI-A-1 enable mode 1920x1080 position 1920,0 exec wl-present mirror eDP-1 --fullscreen-output HDMI-A-1 --fullscreen # alternatively, for wl-mirror < 0.16.4 # exec wl-present mirror eDP-1 & sleep .5; wl-present fullscreen-output HDMI-A-1; wl-present fullscreen } ``` ## Installation `wl-mirror` is already packaged in many distros and can be installed via the package manager: [![Packaging Status](https://repology.org/badge/vertical-allrepos/wl-mirror.svg?columns=3)](https://repology.org/project/wl-mirror/versions) ## Supported Wayland Compositors `wl-mirror` should work on all Wayland compositors based on wlroots, such as sway or hyprland. `wl-mirror` currently does not work on KDE and Gnome, due to `wl-mirror` not supporting the XDG Desktop Portal screen sharing protocol. This is being worked on (see issues [#16](https://github.com/Ferdi265/wl-mirror/issues/16) and [#17](https://github.com/Ferdi265/wl-mirror/issues/17)). ## Dependencies - `CMake` - `pkg-config` - `libwayland-client` - `libwayland-egl` - `libEGL` - `libGLESv2` - `epoll-shim` (on systems that do not have `epoll`, e.g. FreeBSD) - `wayland-scanner` - `scdoc` (for manual pages, see `INSTALL_DOCUMENTATION`) ## Script Dependencies - `pipectl` (optional for `scripts/wl-present`) - `slurp` (`scripts/wl-present`) - `wofi`, `wmenu`, `rofi` or `dmenu` (`scripts/wl-present`) ## Building - Install Dependencies - Clone Submodules (`git submodule update --init`) - Run `cmake -B build` - Run `cmake --build build` ## CMake Options - `INSTALL_EXAMPLE_SCRIPTS`: also install example scripts (default `OFF`) - `INSTALL_DOCUMENTATION`: also build and install manual pages (default `OFF`) - `FORCE_SYSTEM_WL_PROTOCOLS`: always use system-installed wayland-protocols, do not use submodules (default `OFF`) - `FORCE_SYSTEM_WLR_PROTOCOLS`: always use system-installed wlr-protocols, do not use submodules (default `OFF`) - `WL_PROTOCOL_DIR`: directory where system-installed wayland-protocols are located (default `/usr/share/wayland-protocols`) - `WLR_PROTOCOL_DIR`: directory where system-installed wlr-protocols are located (default `/usr/share/wlr-protocols`) ## Files - `src/main.c`: main entrypoint - `src/options.c`: CLI and stream option parsing - `src/wayland.c`: Wayland and `xdg_surface` boilerplate - `src/egl.c`: EGL boilerplate - `src/mirror.c`: output mirroring code - `src/mirror-dmabuf.c`: wlr-export-dmabuf-unstable-v1 backend code - `src/mirror-screencopy.c`: wlr-screencopy-unstable-v1 backend code - `src/transform.c`: matrix transformation code - `src/event.c`: event loop - `src/stream.c`: asynchronous option stream input ## License This project is licensed under the GNU GPL version 3.0 or later (SPDX [GPL-3.0-or-later](https://spdx.org/licenses/GPL-3.0-or-later.html)). The full license text can also be found in the [LICENSE](/LICENSE) file. wl-mirror-0.16.5/deps/0000755000175000017500000000000014646471773013225 5ustar yrlfyrlfwl-mirror-0.16.5/deps/CMakeLists.txt0000644000175000017500000000322414646471773015766 0ustar yrlfyrlffind_package(PkgConfig REQUIRED) add_library(deps INTERFACE) add_library(proto_deps INTERFACE) # helper function for finding one of a list of packages function(do_pkg_search_module name) pkg_search_module(${name} ${ARGN}) set(module_name "${${name}_MODULE_NAME}") set(module_version "${${name}_VERSION}") message(STATUS " Found ${module_name}, version ${module_version}") endfunction() # required dependencies find_library(MATH_LIBRARY m REQUIRED) pkg_check_modules(WaylandClient REQUIRED IMPORTED_TARGET "wayland-client") pkg_check_modules(WaylandEGL REQUIRED IMPORTED_TARGET "wayland-egl") pkg_check_modules(EGL REQUIRED IMPORTED_TARGET "egl") pkg_check_modules(GLESv2 REQUIRED IMPORTED_TARGET "glesv2") pkg_check_modules(WaylandScanner REQUIRED "wayland-scanner") pkg_get_variable(WAYLAND_SCANNER "wayland-scanner" "wayland_scanner") set(WAYLAND_SCANNER "${WAYLAND_SCANNER}" PARENT_SCOPE) # man dependencies if (${INSTALL_DOCUMENTATION}) pkg_check_modules(SCDOC REQUIRED "scdoc") else() pkg_check_modules(SCDOC "scdoc") endif() pkg_get_variable(SCDOC "scdoc" "scdoc") set(SCDOC "${SCDOC}" PARENT_SCOPE) # link dependencies target_link_libraries(deps INTERFACE ${MATH_LIBRARY} PkgConfig::WaylandClient PkgConfig::WaylandEGL PkgConfig::EGL PkgConfig::GLESv2 ) target_link_libraries(proto_deps INTERFACE PkgConfig::WaylandClient ) # check for epoll support in libc include(CheckSymbolExists) check_symbol_exists("epoll_wait" "sys/epoll.h" has-epoll) if(NOT has-epoll) # use epoll-shim to provide epoll pkg_check_modules(EPoll REQUIRED IMPORTED_TARGET "epoll-shim") target_link_libraries(deps INTERFACE PkgConfig::EPoll) endif() wl-mirror-0.16.5/glsl/0000755000175000017500000000000014646471773013233 5ustar yrlfyrlfwl-mirror-0.16.5/glsl/CMakeLists.txt0000644000175000017500000000230614646471773015774 0ustar yrlfyrlfadd_library(shaders STATIC) target_include_directories(shaders INTERFACE "${CMAKE_CURRENT_BINARY_DIR}/include/") file(GLOB shaders CONFIGURE_DEPENDS "*.glsl") foreach(shader ${shaders}) get_filename_component(shader-base "${shader}" NAME_WE) set(shader-template "${CMAKE_CURRENT_SOURCE_DIR}/embed.c.in") set(shader-header "${CMAKE_CURRENT_BINARY_DIR}/include/glsl_${shader-base}.h") set(shader-source "${CMAKE_CURRENT_BINARY_DIR}/src/glsl_${shader-base}.c") message(STATUS "embedding ${shader-base}.glsl") add_custom_command( OUTPUT "${shader-source}" MAIN_DEPENDENCY "${shader}" COMMAND "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_SOURCE_DIR}/embed.cmake" "${shader}" "${shader-template}" "${shader-source}" ) add_custom_target(gen-${shader-base} DEPENDS "${shader-source}") set(FILENAME "${shader-base}") set(DATA "${shader-data}") configure_file(embed.h.in "${shader-header}" @ONLY) set_source_files_properties("${shader-header}" PROPERTIES GENERATED 1) set_source_files_properties("${shader-source}" PROPERTIES GENERATED 1) add_dependencies(shaders gen-${shader-base}) target_sources(shaders PRIVATE "${shader-source}") endforeach() wl-mirror-0.16.5/glsl/embed.c.in0000644000175000017500000000006514646471773015061 0ustar yrlfyrlfconst char glsl_@FILENAME@[] = { @DATA@ 0 }; wl-mirror-0.16.5/glsl/embed.cmake0000644000175000017500000000126314646471773015313 0ustar yrlfyrlfif(NOT ${CMAKE_ARGC} EQUAL 6) message(FATAL_ERROR "usage: cmake -P embed.cmake ") endif() set(shader "${CMAKE_ARGV3}") set(shader-template "${CMAKE_ARGV4}") set(shader-source "${CMAKE_ARGV5}") get_filename_component(shader-base "${shader}" NAME_WE) file(READ ${shader} shader-data HEX) string(REPEAT "[0-9a-f]" 2 byte-regex) string(REPEAT "[0-9a-f]" 16 line-regex) string(REGEX REPLACE "(${line-regex})" "\\1\n " shader-data "${shader-data}") string(REGEX REPLACE "(${byte-regex})" "0x\\1, " shader-data "${shader-data}") set(FILENAME "${shader-base}") set(DATA "${shader-data}") configure_file("${shader-template}" "${shader-source}" @ONLY) wl-mirror-0.16.5/glsl/embed.h.in0000644000175000017500000000016414646471773015066 0ustar yrlfyrlf#ifndef WL_MIRROR_GLSL_@FILENAME@_ #define WL_MIRROR_GLSL_@FILENAME@_ extern const char glsl_@FILENAME@[]; #endif wl-mirror-0.16.5/glsl/fragment_shader.glsl0000644000175000017500000000054114646471773017247 0ustar yrlfyrlf#version 100 precision mediump float; uniform sampler2D uTexture; uniform bool uInvertColors; varying vec2 vTexCoord; void main() { vec4 color = texture2D(uTexture, vTexCoord); if (uInvertColors) { gl_FragColor = vec4(1.0 - color.r, 1.0 - color.g, 1.0 - color.b, 1.0); } else { gl_FragColor = vec4(color.rgb, 1.0); } } wl-mirror-0.16.5/glsl/vertex_shader.glsl0000644000175000017500000000041014646471773016754 0ustar yrlfyrlf#version 100 precision mediump float; uniform mat3 uTexTransform; attribute vec2 aPosition; attribute vec2 aTexCoord; varying vec2 vTexCoord; void main() { gl_Position = vec4(aPosition, 0.0, 1.0); vTexCoord = (uTexTransform * vec3(aTexCoord, 1.0)).xy; } wl-mirror-0.16.5/include/0000755000175000017500000000000014646471773013715 5ustar yrlfyrlfwl-mirror-0.16.5/include/context.h0000644000175000017500000000075614646471773015562 0ustar yrlfyrlf#ifndef WL_MIRROR_CONTEXT_H_ #define WL_MIRROR_CONTEXT_H_ #include #include #include #include "log.h" #include "options.h" #include "event.h" #include "stream.h" #include "wayland.h" #include "egl.h" #include "mirror.h" typedef struct ctx { ctx_opt_t opt; ctx_event_t event; ctx_stream_t stream; ctx_wl_t wl; ctx_egl_t egl; ctx_mirror_t mirror; } ctx_t; noreturn void exit_fail(ctx_t * ctx); void cleanup(ctx_t * ctx); #endif wl-mirror-0.16.5/include/egl.h0000644000175000017500000000262014646471773014635 0ustar yrlfyrlf#ifndef WL_MIRROR_EGL_H_ #define WL_MIRROR_EGL_H_ #include #include #include #include #include #include struct ctx; #define MAX_PLANES 4 typedef struct { uint32_t width; uint32_t height; uint32_t drm_format; size_t planes; int * fds; uint32_t * offsets; uint32_t * strides; uint64_t modifier; } dmabuf_t; typedef struct ctx_egl { EGLDisplay display; EGLContext context; EGLConfig config; EGLSurface surface; struct wl_egl_window * window; // extension functions PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES; // texture size uint32_t width; uint32_t height; uint32_t format; // gl objects GLuint vbo; GLuint texture; GLuint freeze_texture; GLuint freeze_framebuffer; GLuint shader_program; GLint texture_transform_uniform; GLint invert_colors_uniform; // state flags bool texture_region_aware; bool texture_initialized; bool initialized; } ctx_egl_t; void init_egl(struct ctx * ctx); void draw_texture(struct ctx * ctx); void resize_viewport(struct ctx * ctx); void resize_window(struct ctx * ctx); void update_uniforms(struct ctx * ctx); void freeze_framebuffer(struct ctx * ctx); bool dmabuf_to_texture(struct ctx * ctx, dmabuf_t * dmabuf); void cleanup_egl(struct ctx * ctx); #endif wl-mirror-0.16.5/include/event.h0000644000175000017500000000140514646471773015207 0ustar yrlfyrlf#ifndef WL_MIRROR_EVENT_H_ #define WL_MIRROR_EVENT_H_ #include #include #include struct ctx; typedef struct event_handler { struct event_handler * next; int fd; int events; int timeout_ms; void (*on_event)(struct ctx * ctx); void (*on_each)(struct ctx * ctx); } event_handler_t; typedef struct ctx_event { int pollfd; event_handler_t * handlers; bool initialized; } ctx_event_t; void init_event(struct ctx * ctx); void cleanup_event(struct ctx * ctx); void event_add_fd(struct ctx * ctx, event_handler_t * handler); void event_change_fd(struct ctx * ctx, event_handler_t * handler); void event_remove_fd(struct ctx * ctx, event_handler_t * handler); void event_loop(struct ctx * ctx); #endif wl-mirror-0.16.5/include/log.h0000644000175000017500000000051314646471773014646 0ustar yrlfyrlf#ifndef WL_MIRROR_LOG_H_ #define WL_MIRROR_LOG_H_ #include #define log_debug(ctx, fmt, ...) if ((ctx)->opt.verbose) fprintf(stderr, "debug: " fmt, ##__VA_ARGS__) #define log_warn(fmt, ...) fprintf(stderr, "warning: " fmt, ##__VA_ARGS__) #define log_error(fmt, ...) fprintf(stderr, "error: " fmt, ##__VA_ARGS__) #endif wl-mirror-0.16.5/include/mirror-backends.h0000644000175000017500000000063214646471773017151 0ustar yrlfyrlf#ifndef WL_MIRROR_MIRROR_BACKENDS_H_ #define WL_MIRROR_MIRROR_BACKENDS_H_ #include struct ctx; #define MIRROR_BACKEND_FATAL_FAILCOUNT 10 typedef struct mirror_backend { void (*do_capture)(struct ctx * ctx); void (*do_cleanup)(struct ctx * ctx); size_t fail_count; } mirror_backend_t; void init_mirror_dmabuf(struct ctx * ctx); void init_mirror_screencopy(struct ctx * ctx); #endif wl-mirror-0.16.5/include/mirror-dmabuf.h0000644000175000017500000000125414646471773016636 0ustar yrlfyrlf#ifndef WL_MIRROR_MIRROR_DMABUF_H_ #define WL_MIRROR_MIRROR_DMABUF_H_ #include #include "wlr-export-dmabuf-unstable-v1.h" #include "mirror.h" #include "egl.h" typedef enum { STATE_WAIT_FRAME, STATE_WAIT_OBJECTS, STATE_WAIT_READY, STATE_READY, STATE_CANCELED } dmabuf_state_t; typedef struct { mirror_backend_t header; // dmabuf frame object struct zwlr_export_dmabuf_frame_v1 * dmabuf_frame; // frame data uint32_t x; uint32_t y; uint32_t buffer_flags; uint32_t frame_flags; dmabuf_t dmabuf; // dmabuf state flags dmabuf_state_t state; uint32_t processed_objects; } dmabuf_mirror_backend_t; #endif wl-mirror-0.16.5/include/mirror-screencopy.h0000644000175000017500000000162014646471773017547 0ustar yrlfyrlf#ifndef WL_MIRROR_MIRROR_SCREENCOPY_H_ #define WL_MIRROR_MIRROR_SCREENCOPY_H_ #include #include "mirror.h" #include "wlr-screencopy-unstable-v1.h" #include typedef enum { STATE_WAIT_BUFFER, STATE_WAIT_BUFFER_DONE, STATE_WAIT_FLAGS, STATE_WAIT_READY, STATE_READY, STATE_CANCELED } screencopy_state_t; typedef struct { mirror_backend_t header; // shm state int shm_fd; size_t shm_size; void * shm_addr; // wl_shm objects struct wl_shm_pool * shm_pool; struct wl_buffer * shm_buffer; // screencopy frame object struct zwlr_screencopy_frame_v1 * screencopy_frame; // frame data uint32_t frame_width; uint32_t frame_height; uint32_t frame_stride; uint32_t frame_format; uint32_t frame_flags; // screencopy state flags screencopy_state_t state; } screencopy_mirror_backend_t; #endif wl-mirror-0.16.5/include/mirror.h0000644000175000017500000000152414646471773015402 0ustar yrlfyrlf#ifndef WL_MIRROR_MIRROR_H_ #define WL_MIRROR_MIRROR_H_ #include #include #include #include #include #include "transform.h" #include "mirror-backends.h" struct ctx; struct output_list_node; typedef struct ctx_mirror { struct output_list_node * current_target; struct wl_callback * frame_callback; region_t current_region; bool invert_y; // backend data mirror_backend_t * backend; size_t auto_backend_index; // state flags bool initialized; } ctx_mirror_t; void init_mirror(struct ctx * ctx); void init_mirror_backend(struct ctx * ctx); void output_removed(struct ctx * ctx, struct output_list_node * node); void update_title(struct ctx * ctx); void backend_fail(struct ctx * ctx); void cleanup_mirror(struct ctx * ctx); #endif wl-mirror-0.16.5/include/options.h0000644000175000017500000000250314646471773015561 0ustar yrlfyrlf#ifndef WL_MIRROR_OPTIONS_H_ #define WL_MIRROR_OPTIONS_H_ #include #include #include "transform.h" struct ctx; struct output_list_node; typedef enum { SCALE_FIT, SCALE_COVER, SCALE_EXACT } scale_t; typedef enum { SCALE_FILTER_LINEAR, SCALE_FILTER_NEAREST, } scale_filter_t; typedef enum { BACKEND_AUTO, BACKEND_DMABUF, BACKEND_SCREENCOPY } backend_t; typedef struct ctx_opt { bool verbose; bool stream; bool show_cursor; bool invert_colors; bool freeze; bool has_region; bool fullscreen; scale_t scaling; scale_filter_t scaling_filter; backend_t backend; transform_t transform; region_t region; char * output; char * fullscreen_output; } ctx_opt_t; void init_opt(struct ctx * ctx); void cleanup_opt(struct ctx * ctx); bool parse_scaling_opt(scale_t * scaling, scale_filter_t * scaling_filter, const char * scaling_arg); bool parse_transform_opt(transform_t * transform, const char * transform_arg); bool parse_region_opt(region_t * region, char ** output, const char * region_arg); bool find_output_opt(struct ctx * ctx, struct output_list_node ** output_handle, region_t * region_handle); void usage_opt(struct ctx * ctx); void version_opt(struct ctx * ctx); void parse_opt(struct ctx * ctx, int argc, char ** argv); #endif wl-mirror-0.16.5/include/stream.h0000644000175000017500000000066614646471773015371 0ustar yrlfyrlf#ifndef WL_MIRROR_STREAM_H_ #define WL_MIRROR_STREAM_H_ #include #include #include "event.h" struct ctx; typedef struct ctx_stream { char * line; size_t line_len; size_t line_cap; char ** args; size_t args_len; size_t args_cap; event_handler_t event_handler; bool initialized; } ctx_stream_t; void init_stream(struct ctx * ctx); void cleanup_stream(struct ctx * ctx); #endif wl-mirror-0.16.5/include/transform.h0000644000175000017500000000266114646471773016106 0ustar yrlfyrlf#ifndef WL_MIRROR_TRANSFORM_H_ #define WL_MIRROR_TRANSFORM_H_ #include #include #include "linux-dmabuf-unstable-v1.h" typedef enum { ROT_CW_0, ROT_CW_90, ROT_CW_180, ROT_CW_270, ROT_NORMAL = ROT_CW_0, ROT_CCW_0 = ROT_CW_0, ROT_CCW_90 = ROT_CW_270, ROT_CCW_180 = ROT_CW_180, ROT_CCW_270 = ROT_CW_90 } rotation_t; typedef struct { rotation_t rotation; bool flip_x; bool flip_y; } transform_t; typedef struct { uint32_t x; uint32_t y; uint32_t width; uint32_t height; } region_t; typedef struct { float data[3][3]; } mat3_t; void mat3_identity(mat3_t * mat); void mat3_transpose(mat3_t * mat); void mat3_mul(const mat3_t * mul, mat3_t * dest); void mat3_apply_transform(mat3_t * mat, transform_t transform); void mat3_apply_region_transform(mat3_t * mat, const region_t * region, const region_t * output); void mat3_apply_output_transform(mat3_t * mat, enum wl_output_transform transform); void mat3_apply_invert_y(mat3_t * mat, bool invert_y); void viewport_apply_transform(uint32_t * width, uint32_t * height, transform_t transform); void viewport_apply_output_transform(uint32_t * width, uint32_t * height, enum wl_output_transform transform); bool region_contains(const region_t * region, const region_t * output); void region_scale(region_t * region, double scale); void region_clamp(region_t * region, const region_t * output); #endif wl-mirror-0.16.5/include/util.h0000644000175000017500000000020214646471773015035 0ustar yrlfyrlf#ifndef WL_MIRROR_UTIL_H_ #define WL_MIRROR_UTIL_H_ #define ARRAY_LENGTH(arr) ((sizeof ((arr))) / (sizeof (((arr))[0]))) #endif wl-mirror-0.16.5/include/wayland.h0000644000175000017500000000514214646471773015527 0ustar yrlfyrlf#ifndef WL_MIRROR_WAYLAND_H_ #define WL_MIRROR_WAYLAND_H_ #include #include #include "event.h" #include "viewporter.h" #include "fractional-scale-v1.h" #include "xdg-shell.h" #include "xdg-output-unstable-v1.h" #include "wlr-export-dmabuf-unstable-v1.h" #include "wlr-screencopy-unstable-v1.h" struct ctx; typedef struct output_list_node { struct output_list_node * next; struct ctx * ctx; char * name; struct wl_output * output; struct zxdg_output_v1 * xdg_output; uint32_t output_id; int32_t x; int32_t y; int32_t width; int32_t height; int32_t scale; enum wl_output_transform transform; } output_list_node_t; typedef struct seat_list_node { struct seat_list_node * next; struct ctx * ctx; struct wl_seat * seat; uint32_t seat_id; } seat_list_node_t; typedef struct ctx_wl { struct wl_display * display; struct wl_registry * registry; // registry objects struct wl_compositor * compositor; struct wp_viewporter * viewporter; struct wp_fractional_scale_manager_v1 * fractional_scale_manager; struct xdg_wm_base * wm_base; struct zxdg_output_manager_v1 * output_manager; // registry ids uint32_t compositor_id; uint32_t viewporter_id; uint32_t fractional_scale_manager_id; uint32_t wm_base_id; uint32_t output_manager_id; // dmabuf backend objects struct zwlr_export_dmabuf_manager_v1 * dmabuf_manager; uint32_t dmabuf_manager_id; // screencopy backend objects struct wl_shm * shm; struct zwlr_screencopy_manager_v1 * screencopy_manager; uint32_t shm_id; uint32_t screencopy_manager_id; // output list output_list_node_t * outputs; seat_list_node_t * seats; // surface objects struct wl_surface * surface; struct wp_viewport * viewport; struct wp_fractional_scale_v1 * fractional_scale; struct xdg_surface * xdg_surface; struct xdg_toplevel * xdg_toplevel; // buffer size output_list_node_t * current_output; uint32_t width; uint32_t height; double scale; // event handler event_handler_t event_handler; // state flags uint32_t last_surface_serial; bool xdg_surface_configured; bool xdg_toplevel_configured; bool configured; bool closing; bool initialized; } ctx_wl_t; void init_wl(struct ctx * ctx); void set_window_title(struct ctx * ctx, const char * title); void set_window_fullscreen(struct ctx * ctx); void unset_window_fullscreen(struct ctx * ctx); void update_window_scale(struct ctx * ctx, double scale, bool is_fractional); void cleanup_wl(struct ctx * ctx); #endif wl-mirror-0.16.5/man/0000755000175000017500000000000014646471773013045 5ustar yrlfyrlfwl-mirror-0.16.5/man/CMakeLists.txt0000644000175000017500000000151314646471773015605 0ustar yrlfyrlf# determine if documentation can be built if (${SCDOC_FOUND}) set(BUILD_DOCUMENTATION ON PARENT_SCOPE) else() set(BUILD_DOCUMENTATION OFF PARENT_SCOPE) endif() function(build_scdoc_man_page name section) file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/man/") set(man-src "${CMAKE_SOURCE_DIR}/man/${name}.${section}.scd") set(man-bin "${CMAKE_BINARY_DIR}/man/${name}.${section}") add_custom_command( OUTPUT "${man-bin}" MAIN_DEPENDENCY "${man-src}" COMMAND "${SCDOC}" < "${man-src}" > "${man-bin}" ) add_custom_target(gen-man-${name}-${section} ALL DEPENDS "${man-bin}") endfunction() function(install_scdoc_man_page name section) set(man-bin "${CMAKE_BINARY_DIR}/man/${name}.${section}") install(FILES "${man-bin}" DESTINATION "${CMAKE_INSTALL_MANDIR}/man${section}/") endfunction() wl-mirror-0.16.5/man/wl-mirror.1.scd0000644000175000017500000001013114646471773015625 0ustar yrlfyrlfwl-mirror(1) # NAME wl-mirror - a simple Wayland output mirror client # SYNOPSIS *wl-mirror* [-h,-V,-v,-c,-i,-f,-s S,-b B,-t T,-r R,-S] # OPTIONS *-h, --help* Show help message and exit. *-V, --version* Show version information and exit. *-v, --verbose* * --no-verbose* Enable or disable debug logging. *-c, --show-cursor* * --no-show-cursor* Show the cursor on the mirrored surface (enabled by default). *-i, --invert-colors* * --no-invert-colors* Invert colors on the mirrored surface. *-f, --freeze* * --unfreeze* * --toggle-freeze* Freeze, unfreeze, or toggle freezing of the current image on the screen. *-F, --fullscreen* * --no-fullscreen* Open as a fullscreen window, or make the current window fullscreen in stream mode. * --fullscreen-output O* * --no-fullscreen-output* Set a different output to fullscreen on (default is the current output). *-s f, --scaling fit* Scale to fit and if necessary add letterboxing (enabled by default). *-s c, --scaling cover* Scale to cover and if necessary crop the image. *-s e, --scaling exact* Use exact multiple scaling and if necessary add letterboxing. *-s l, --scaling linear* Use linear scaling (enabled by default). *-s n, --scaling nearest* Use nearest-neighbor scaling. *-b B, --backend B* Use a specific screen capture backend, see *BACKENDS*. *-t T, --transform T* Apply custom transform (rotation and flipping), see *TRANSFORMS*. *-r R, --region R* Capture custom screen region R, see *REGIONS*. *-S, --stream* Accept a stream of additional options on stdin, see *STREAM MODE*. # BACKENDS *auto* Automatically try backends in order and use the first that works (enabled by default). The next backend is selected automatically when the current backend fails to capture a frame 10 times in a row. *dmabuf* Use the *wlr-export-dmabuf-unstable-v1* protocol to capture outputs (requires wlroots). This backend keeps the image data on the GPU and does not need expensive copies to the CPU and back. *screencopy* Use the *wlr-screencopy-unstable-v1* protocol to capture outputs (requires wlroots) This backend passes the image data via shared memory on the CPU, but may have better compatibility with complex GPU driver configurations (e.g., multi GPU). # TRANSFORMS Transforms are specified as a dash-separated list of flips followed by a rotation amount. Flips are applied before rotations, both flips and rotations are optional. Custom transformations are applied after adjusting for the wayland output transform, so that if no custom transformations are applied, the mirrored surface is displayed right-side-up. *normal* No transformation (default transformation). *flipX, flipY* Flip the X or Y coordinate of the image, i.e. *flipX* means the mirrored surface has left and right swapped. *0cw, 90cw, 180cw, 270cw* Apply a clockwise rotation. *0ccw, 90ccw, 180ccw, 270ccw* Apply a counter-clockwise rotation. The following transformation options are provided for compatibility with *sway-output*(5) transforms: *flipped* Same as *flipX*. *0, 90, 180, 270* Same as *0cw, 90cw, 180cw, 270cw*. # REGIONS Regions are specified in the format used by the *slurp*(1) utility: '*x*,*y* *width*x*height* [*output*]' When processing the region option, the region is translated into output coordinates, so when the output moves, the captured region moves with it. When a region is specified, the *output* positional argument is optional. # STREAM MODE In stream mode, *wl-mirror* interprets lines on stdin as additional command line options. - Arguments can be quoted with single or double quotes, but every argument must be fully quoted. - Unquoted arguments are split on whitespace. - No escape sequences are implemented. Option lines on stdin are processed asynchronously, and can override all options and the captured output. Stream mode is used by *wl-present*(1) to add interactive controls to *wl-mirror*. # AUTHORS Maintained by Ferdinand Bachmann . More information on *wl-mirror* can be found at . # SEE ALSO *wl-present*(1) *slurp*(1) *sway-output*(5) wl-mirror-0.16.5/man/wl-present.1.scd0000644000175000017500000000550114646471773016000 0ustar yrlfyrlfwl-present(1) # NAME wl-present - an interactive client for *wl-mirror*(1) # SYNOPSIS *wl-present* [args...] # DESCRIPTION *wl-present* is an wrapper around *wl-mirror*(1) that uses its streaming mode together with *pipectl*(1) to interactively control what is being captured. The subcommands of *wl-present* are intended to be mapped to keyboard shortcuts in your wayland compositor for easy access. # COMMANDS *help* Show help message and exit. *mirror* [OUTPUT] [OPTIONS] Start *wl-mirror*(1) capturing OUTPUT. If no output is given, *slurp*(1) is used to select the output or region to capture. If any additional OPTIONS are specified, they are passed on to *wl-mirror*. *set-output* [OUTPUT] Set the captured output of a running *wl-present* session. If no output is given, *slurp*(1) is used to select the output to capture. *set-region* [REGION] *unset-region* Set the captured region of a running *wl-present* session. If no region is given, *slurp*(1) us used to select a region to capture. *set-scaling* [SCALING] Set the scaling mode of a running *wl-present* session. If no region is given, *dmenu*(1) (or a compatible replacement) is used to select a scaling mode. *freeze*, *unfreeze*, *toggle-freeze* Set the freeze state of a running *wl-present* session. *fullscreen* *unfullscreen* Set the fullscreen state of a running *wl-present* session. *fullscreen-output* [OUTPUT] *no-fullscreen-output* Set the fullscreen target output of a running *wl-present* session. *custom* [OPTIONS] Send custom options to a running *wl-present* session. If no options are given, *dmenu*(1) (or a compatible replacement) are used to select an option. # ENVIRONMENT VARIABLES *WL_PRESENT_DMENU* Overrides the used dmenu implementation. When set, this command is used to select options instead of the default. When unset, *wl-present* attempts to use *wofi*(1), *wmenu*(1), *fuzzel*(1), *rofi*(1), and *dmenu*(1), in this order. Example: WL_PRESENT_DMENU="rofi -dmenu -p present" *WL_PRESENT_PIPECTL* Overrides the used pipectl implementation. When set, this command is used to pipe options to *wl-mirror*(1) instead of the default. When unset, *wl-present* attempts to use *pipectl*(1) or an included pipectl shim written in bash if pipectl is not available. *WL_PRESENT_SLURP* Overrides the used slurp implementation and options. When set, this command is used to select regions and outputs instead of the default. When unset, *wl-present* attempts to use *slurp*(1) without any additional options. Example: WL_PRESENT_SLURP="slurp -c #859900 -w 2" # AUTHORS Maintained by Ferdinand Bachmann . More information on *wl-mirror* can be found at . # SEE ALSO *wl-mirror*(1) *pipectl*(1) *slurp*(1) *wofi*(1) *wmenu*(1) *fuzzel*(1) *rofi*(1) *dmenu*(1) wl-mirror-0.16.5/proto/0000755000175000017500000000000014646471773013435 5ustar yrlfyrlfwl-mirror-0.16.5/proto/CMakeLists.txt0000644000175000017500000000637114646471773016204 0ustar yrlfyrlf# detect wayland-protocols location set(wl-protocols-found FALSE) if(NOT ${FORCE_SYSTEM_WL_PROTOCOLS} AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/wayland-protocols/.git") message(STATUS "using wayland-protocols from submodule") set(WL_PROTOCOL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/wayland-protocols/") set(wl-protocols-found TRUE) endif() if (NOT ${wl-protocols-found} AND IS_DIRECTORY ${WL_PROTOCOL_DIR}) message(STATUS "using system wayland-protocols at ${WL_PROTOCOL_DIR}") set(wl-protocols-found TRUE) endif() if (NOT ${wl-protocols-found}) message(STATUS "error: wayland-protocols not found") endif() # detect wlr-protocols location set(wlr-protocols-found FALSE) if(NOT ${FORCE_SYSTEM_WLR_PROTOCOLS} AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/wlr-protocols/.git") message(STATUS "using wlr-protocols from submodule") set(WLR_PROTOCOL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/wlr-protocols/") set(wlr-protocols-found TRUE) endif() if (NOT ${wlr-protocols-found} AND IS_DIRECTORY ${WLR_PROTOCOL_DIR}) message(STATUS "using system wlr-protocols at ${WLR_PROTOCOL_DIR}") set(wlr-protocols-found TRUE) endif() if (NOT ${wlr-protocols-found}) message(STATUS "error: wlr-protocols not found") endif() if (NOT ${wl-protocols-found} OR NOT ${wlr-protocols-found}) message(FATAL_ERROR "wayland-protocols or wlr-protocols not found") endif() # wayland protocol wrapper generation with wayland-scanner set(protocols-found TRUE) add_library(protocols STATIC) target_include_directories(protocols INTERFACE "${CMAKE_CURRENT_BINARY_DIR}/include/") target_link_libraries(protocols PRIVATE proto_deps) foreach(proto ${PROTOCOLS}) get_filename_component(proto-base "${proto}" NAME_WE) set(wl-proto-file "${WL_PROTOCOL_DIR}/${proto}") set(wlr-proto-file "${WLR_PROTOCOL_DIR}/${proto}") if(EXISTS ${wl-proto-file}) message(STATUS "using ${proto} from wayland-protocols") set(proto-file ${wl-proto-file}) elseif(EXISTS ${wlr-proto-file}) message(STATUS "using ${proto} from wlr-protocols") set(proto-file ${wlr-proto-file}) else() message(STATUS "error: protocol ${proto} not found") set(protocols-found FALSE) endif() set(proto-header "${CMAKE_CURRENT_BINARY_DIR}/include/${proto-base}.h") set(proto-source "${CMAKE_CURRENT_BINARY_DIR}/src/${proto-base}.c") file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/include/") file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/src/") add_custom_command( OUTPUT "${proto-header}" MAIN_DEPENDENCY "${proto-file}" COMMAND "${WAYLAND_SCANNER}" client-header "${proto-file}" "${proto-header}" ) add_custom_command( OUTPUT "${proto-source}" MAIN_DEPENDENCY "${proto-file}" COMMAND "${WAYLAND_SCANNER}" private-code "${proto-file}" "${proto-source}" ) add_custom_target(gen-${proto-base} DEPENDS "${proto-header}" "${proto-source}") set_source_files_properties("${proto-header}" PROPERTIES GENERATED 1) set_source_files_properties("${proto-source}" PROPERTIES GENERATED 1) add_dependencies(protocols gen-${proto-base}) target_sources(protocols PRIVATE "${proto-source}") endforeach() if(NOT ${protocols-found}) message(FATAL_ERROR "some protocols could not be found") endif() wl-mirror-0.16.5/proto/wayland-protocols/0000755000175000017500000000000014646472005017103 5ustar yrlfyrlfwl-mirror-0.16.5/proto/wayland-protocols/.editorconfig0000644000175000017500000000011014646472005021550 0ustar yrlfyrlfroot = true [*.xml] indent_style = space indent_size = 2 tab_width = 8 wl-mirror-0.16.5/proto/wayland-protocols/.gitlab-ci.yml0000644000175000017500000000311414646472005021536 0ustar yrlfyrlf.templates_sha: &template_sha fb33e1b244ec2a0b8edf8ee5590a96369c3b4666 include: - project: 'freedesktop/ci-templates' ref: *template_sha file: '/templates/debian.yml' - project: 'freedesktop/ci-templates' ref: *template_sha file: '/templates/ci-fairy.yml' stages: - review - containers-build - test variables: FDO_UPSTREAM_REPO: wayland/wayland-protocols workflow: rules: - if: $CI_PIPELINE_SOURCE == 'merge_request_event' - if: $CI_PIPELINE_SOURCE == 'push' .debian: variables: FDO_DISTRIBUTION_VERSION: bullseye FDO_DISTRIBUTION_PACKAGES: 'build-essential pkg-config meson git ca-certificates libffi-dev libexpat1-dev libxml2-dev' FDO_DISTRIBUTION_TAG: '2022-01-19.0' FDO_DISTRIBUTION_EXEC: 'env FDO_CI_CONCURRENT=${FDO_CI_CONCURRENT} ./.gitlab-ci/debian-install.sh' check-commit: extends: - .fdo.ci-fairy stage: review script: - ci-fairy check-commits --signed-off-by --junit-xml=results.xml variables: GIT_DEPTH: 100 rules: - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' when: always - when: never artifacts: reports: junit: results.xml container_build: extends: - .debian - .fdo.container-build@debian stage: containers-build variables: GIT_STRATEGY: none test-meson: stage: test extends: - .debian - .fdo.distribution-image@debian script: - meson build - ninja -C build - meson test -C build - ninja -C build install artifacts: name: wayland-protocols-$CI_COMMIT_SHA when: always paths: - $CI_PROJECT_DIR/build/meson-logs wl-mirror-0.16.5/proto/wayland-protocols/.gitlab-ci/0000755000175000017500000000000014646472005021014 5ustar yrlfyrlfwl-mirror-0.16.5/proto/wayland-protocols/.gitlab-ci/debian-install.sh0000755000175000017500000000060214646472005024237 0ustar yrlfyrlf#!/bin/sh -eux # Note: don't forget to bump FDO_DISTRIBUTION_TAG when editing this file! git clone --branch 1.20.0 --depth=1 https://gitlab.freedesktop.org/wayland/wayland cd wayland/ git show -s HEAD meson build/ -Dtests=false -Ddocumentation=false ninja -j${FDO_CI_CONCURRENT:-4} -C build/ install cd .. rm -rf wayland/ echo "/usr/local/lib" >/etc/ld.so.conf.d/local.conf ldconfig wl-mirror-0.16.5/proto/wayland-protocols/.gitlab/0000755000175000017500000000000014646472005020423 5ustar yrlfyrlfwl-mirror-0.16.5/proto/wayland-protocols/.gitlab/merge_request_templates/0000755000175000017500000000000014646472005025350 5ustar yrlfyrlfwl-mirror-0.16.5/proto/wayland-protocols/.gitlab/merge_request_templates/New protocol.md0000644000175000017500000000031214646472005030241 0ustar yrlfyrlf #### Requirements for merging - [ ] Review - [ ] Implementations - [ ] ACKs from members /label ~"New Protocol" ~"In 30 day discussion period" ~"Needs acks" ~"Needs implementations" ~"Needs review" wl-mirror-0.16.5/proto/wayland-protocols/.mailmap0000644000175000017500000000030014646472005020515 0ustar yrlfyrlfFaith Ekstrand Faith Ekstrand Faith Ekstrand wl-mirror-0.16.5/proto/wayland-protocols/COPYING0000644000175000017500000000273614646472005020146 0ustar yrlfyrlfCopyright © 2008-2013 Kristian Høgsberg Copyright © 2010-2013 Intel Corporation Copyright © 2013 Rafael Antognolli Copyright © 2013 Jasper St. Pierre Copyright © 2014 Jonas Ådahl Copyright © 2014 Jason Ekstrand Copyright © 2014-2015 Collabora, Ltd. Copyright © 2015 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. --- The above is the version of the MIT "Expat" License used by X.org: http://cgit.freedesktop.org/xorg/xserver/tree/COPYING wl-mirror-0.16.5/proto/wayland-protocols/GOVERNANCE.md0000644000175000017500000001630414646472005021060 0ustar yrlfyrlf# wayland-protocols governance This document governs the maintenance of wayland-protocols and serves to outline the broader process for standardization of protocol extensions in the Wayland ecosystem. ## 1. Membership Membership in wayland-protocols is offered to stakeholders in the Wayland ecosystem who have an interest in participating in protocol extension standardization. ### 1.1. Membership requirements 1. Membership is extended to projects, rather than individuals. 2. Members represent general-purpose projects with a stake in multiple Wayland protocols (e.g. compositors, GUI toolkits, etc), rather than special-purpose applications with a stake in only one or two. 3. Each project must provide one or two named individuals as points-of-contact for that project who can be reached to discuss protocol-related matters. 4. During a vote, if two points-of-contact for the same member disagree, the member's vote is considered blank. ### 1.2. Becoming a member 1. New members who meet the criteria outlined in 1.1 are established by invitation from an existing member. Projects hoping to join should reach out to an existing member asking for this invitation. 2. New members shall write to the wayland-devel mailing list stating their intention of joining and their sponsor. 3. The sponsor shall respond acknowledging their sponsorship of the membership. 4. A 14 day discussion period for comments from wayland-protocols members will be held. 5. At the conclusion of the discussion period, the new membership is established unless their application was NACKed by a 1/2 majority of all existing members. ### 1.3. Ceasing membership 1. A member may step down by writing their intention to do so to the wayland-devel mailing list. 2. A removal vote may be called for by an existing member by posting to the wayland-devel mailing list. This begins a 14 day voting & discussion period. 3. At the conclusion of the voting period, the member is removed if the votes total 2/3rds of all current members. 4. Removed members are not eligible to apply for membership again for a period of 1 year. 5. Following a failed vote, the member who called for the vote cannot call for a re-vote or propose any other removal for 90 days. ## 2. Protocols ### 2.1. Protocol namespaces 1. Namespaces are implemented in practice by prefixing each interface name in a protocol definition (XML) with the namespace name, and an underscore (e.g. "xdg_wm_base"). 2. Protocols in a namespace may optionally use the namespace followed by a dash in the name (e.g. "xdg-shell"). 3. The "xdg" namespace is established for protocols letting clients configure its surfaces as "windows", allowing clients to affect how they are managed. 4. The "wp" namespace is established for protocols generally useful to Wayland implementations (i.e. "plumbing" protocols). 5. The "ext" namespace is established as a general catch-all for protocols that fit into no other namespace. ### 2.2. Protocol inclusion requirements 1. All protocols found in the "xdg" and "wp" namespaces at the time of writing are grandfathered into their respective namespace without further discussion. 2. Protocols in the "xdg" and "wp" namespace are eligible for inclusion only if ACKed by at least 3 members. 3. Protocols in the "xdg" and "wp" namespace are ineligible for inclusion if if NACKed by any member. 4. Protocols in the "xdg" and "wp" namespaces must have at least 3 open-source implementations (either 1 client + 2 servers, or 2 clients + 1 server) to be eligible for inclusion. 5. Protocols in the "ext" namespace are eligible for inclusion only if ACKed by at least 2 members. 6. Protocols in the "ext" namespace must have at least one open-source client & one open-source server implementation to be eligible for inclusion. 7. "Open-source" is defined as distributed with an Open Source Initiative approved license. ### 2.3. Introducing new protocols 1. A new protocol may be proposed by submitting a merge request to the wayland-protocols Gitlab repository. 2. Protocol proposal posts must include justification for their inclusion in their namespace per the requirements outlined in section 2.2. 3. An indefinite discussion period for comments from wayland-protocols members will be held, with a minimum duration of 30 days. Protocols which require a certain level of implementation status, ACKs from members, and so on, should use this time to acquire them. 4. When the proposed protocol meets all requirements for inclusion per section 2.2, and the minimum discussion period has elapsed, the sponsoring member may merge their changes in the wayland-protocol repository. 5. Amendments to existing protocols may be proposed by the same process, with no minimum discussion period. 6. Declaring a protocol stable may be proposed by the same process, with the regular 30 day minimum discussion period. ## 3. Protocol adoption documentation ### 3.1. Adoption website 1. This section is informational. 2. A website will be made available for interested parties to browse the implementation status of protocols included in wayland-protocols. 3. A statement from each member of wayland-protocols will be included on the site. 4. Each protocol will be listed along with its approval status from each member. 5. The approval statuses are: 1. NACK, or "negative acknowledgement", meaning that the member is opposed to the protocol in principle. 2. NOPP, or "no opposition", meaning that the member is not opposed to the protocol in principle, but does not provide an implementation. 3. ACK, or "acknowledged", meaning that the member supports the protocol in principle, but does not provide an implementation. 4. IMPL, or "implemented", meaning that the member supports the protocol and provides an implementation. 6. Each member may write a short statement expanding on the rationale for their approval status, which will be included on the site. 7. A supplementary list of implementations will also be provided on the site, which may include implementations supported by non-members. ### 3.2. Changes to the adoption website 1. This section is informational. 2. A new protocol is added to the website by the sponsoring member at the conclusion of the discussion period (section 2.3.3). 3. During the discussion period (section 2.3.3), interested parties may express their approval status on the Gitlab merge request. The default approval status for members who do not participate in the discussion is "NOPP". 4. Members may change their acknowledgement status or support statement at any time after the discussion period (section 2.3.3) has closed by simply merging their update in the wayland-protocols repository. ## 4. Amending this document 1. An amendment to this document may be proposed any member by submitting a merge request on Gitlab. 2. A 30 day discussion period for comments from wayland-protocols members will be held. 3. At the conclusion of the discussion period, an amendment will become effective if it's ACKed by at least 2/3rds of all wayland-protocols members, and NACKed by none. The sponsoring member may merge their change to the wayland-protocols repository at this point. wl-mirror-0.16.5/proto/wayland-protocols/MEMBERS.md0000644000175000017500000000150214646472005020515 0ustar yrlfyrlf# wayland-protocols members - EFL/Enlightenment: Mike Blumenkrantz (@zmike) - GTK/Mutter: Jonas Ådahl (@jadahl), Carlos Garnacho (@carlosg) - KWin: Vlad Zahorodnii (@zzag), David Edmundson (@davidedmundson) - Mir: Christopher James Halse Rogers (@RAOF), Alan Griffiths - Qt: Eskil Abrahamsen Blomfeldt (@eskilblomfeldt) - Smithay/Cosmic: Victoria Brekenfeld (@drakulix), - Weston: Pekka Paalanen (@pq), Daniel Stone (@daniels) - wlroots/Sway: Simon Ser (@emersion), Simon Zeni (@bl4ckb0ne) wl-mirror-0.16.5/proto/wayland-protocols/README.md0000644000175000017500000002450514646472005020370 0ustar yrlfyrlf# Wayland protocols wayland-protocols contains Wayland protocols that add functionality not available in the Wayland core protocol. Such protocols either add completely new functionality, or extend the functionality of some other protocol either in Wayland core, or some other protocol in wayland-protocols. A protocol in wayland-protocols consists of a directory containing a set of XML files containing the protocol specification, and a README file containing detailed state and a list of maintainers. ## Protocol phases Protocols in general has three phases: the development phase, the testing phase, and the stable phase. In the development phase, a protocol is not officially part of wayland-protocols, but is actively being developed, for example by iterating over it in a [merge request](https://gitlab.freedesktop.org/wayland/wayland-protocols/merge_requests), or planning it in an [issue](https://gitlab.freedesktop.org/wayland/wayland-protocols/issues). During this phase, patches for clients and compositors are written as a test vehicle. Such patches must not be merged in clients and compositors, because the protocol can still change. When a protocol has reached a stage where it is ready for wider adoption, and after the [GOVERNANCE section 2.3](GOVERNANCE.md#2.3-introducing-new-protocols) requirements have been met, it enters the "testing" phase. At this point, the protocol is added to `staging/` directory of wayland-protocols and made part of a release. What this means is that implementation is encouraged in clients and compositors where the functionality it specifies is wanted. Extensions in staging cannot have backward incompatible changes, in that sense they are equal to stable extensions. However, they may be completely replaced with a new major version, or a different protocol extension all together, if design flaws are found in the testing phase. After a staging protocol has been sufficiently tested in the wild and proven adequate, its maintainers and the community at large may declare it "stable", meaning it is unexpected to become superseded by a new major version. ## Deprecation A protocol may be deprecated, if it has been replaced by some other protocol, or declared undesirable for some other reason. No more changes will be made to a deprecated protocol. ## Legacy protocol phases An "unstable" protocol refers to a protocol categorization policy previously used by wayland-protocols, where protocols initially placed in the `unstable/` directory had certain naming conventions were applied, requiring a backward incompatible change to be declared "stable". During this phase, protocol extension interface names were in addition to the major version postfix also prefixed with `z` to distinguish from stable protocols. ## Protocol directory tree structure Depending on which stage a protocol is in, the protocol is placed within the toplevel directory containing the protocols with the same stage. Stable protocols are placed in the `stable/` directory, staging protocols are placed in the `staging/` directory, and deprecated protocols are placed in the `deprecated/` directory. Unstable protocols (see [Legacy protocol phases](#legacy-protocol-phases)) can be found in the `unstable/` directory, but new ones should never be placed here. ## Protocol development procedure To propose a new protocol, create a GitLab merge request adding the relevant files and Makefile.am entry to the repository with the explanation and motivation in the commit message. Protocols are organized in namespaces describing their scope ("wp", "xdg" and "ext"). There are different requirements for each namespace, see [GOVERNANCE section 2](GOVERNANCE.md#2-protocols) for more information. If the new protocol is just an idea, open an issue on the GitLab issue tracker. If the protocol isn't ready for complete review yet and is an RFC, create a merge request and add the "WIP:" prefix in the title. To propose changes to existing protocols, create a GitLab merge request. Please include a `Signed-off-by` line at the end of the commit to certify that you wrote it or otherwise have the right to pass it on as an open-source patch. See the [Developer Certificate of Origin](https://developercertificate.org/) for a formal definition. ## Interface naming convention All protocols should avoid using generic namespaces or no namespaces in the protocol interface names in order to minimize risk that the generated C API collides with other C API. Interface names that may collide with interface names from other protocols should also be avoided. For generic protocols not limited to certain configurations (such as specific desktop environment or operating system) the `wp_` prefix should be used on all interfaces in the protocol. For protocols allowing clients to configure how their windows are managed, the `xdg_` prefix should be used. For operating system specific protocols, the interfaces should be prefixed with both `wp_` and the operating system, for example `wp_linux_`, or `wp_freebsd_`, etc. For more information about namespaces, see [GOVERNANCE section 2.1 ](GOVERNANCE.md#21-protocol-namespaces). Each new protocol XML file must include a major version postfix, starting with `-v1`. The purpose of this postfix is to make it possible to distinguish between backward incompatible major versions of the same protocol. The interfaces in the protocol XML file should as well have the same major version postfix in their names. For example, the protocol `foo-bar` may have a XML file `foo-bar/foo-bar-v1.xml`, consisting of the interface `wp_foo_bar_v1`, corresponding to the major version 1, as well as the newer version `foo-bar/foo-bar-v2.xml` consisting of the interface `wp_foo_bar_v2`, corresponding to the major version 2. ## Include a disclaimer Include the following disclaimer: ``` Warning! The protocol described in this file is currently in the testing phase. Backward compatible changes may be added together with the corresponding interface version bump. Backward incompatible changes can only be done by creating a new major version of the extension. ``` ## Use of RFC 2119 keywords Descriptions of all new protocols must use (in lowercase) and adhere to the proper meaning of the keywords described in [RFC 2119](https://www.rfc-editor.org/info/rfc2119). All protocol descriptions that follow the guidelines in RFC 2119 must incorporate the following text in their toplevel protocol description section: ``` The key words "must", "must not", "required", "shall", "shall not", "should", "should not", "recommended", "may", and "optional" in this document are to be interpreted as described in IETF RFC 2119. ``` Note that not all existing protocol descriptions conform to RFC 2119. Protocol maintainers are encouraged to audit their descriptions, update them as needed to follow RFC 2119 guidelines, and mark them as conformant in the way described in the previous paragraph. ## Backward compatible protocol changes A protocol may receive backward compatible additions and changes. This is to be done in the general Wayland way, using `version` and `since` XML element attributes. ## Backward incompatible protocol changes While not preferred, a protocol may at any stage, especially during the testing phase, when it is located in the `staging/` directory, see backward incompatible changes. Assuming a backward incompatible change is needed, the procedure for how to do so is the following: - Make a copy of the XML file with the major version increased by 1. - Increase the major version number in the protocol XML by 1. - Increase the major version number in all of the interfaces in the XML by 1. - Reset the interface version number (interface version attribute) of all the interfaces to 1. - Remove all of the `since` attributes. ## Declaring a protocol stable Once it has been concluded that a protocol been proven adequate in production, and that it is deemed unlikely to receive any backward incompatible changes, it may be declared stable. The procedure of doing this is the following: - Create a new directory in the `stable/` toplevel directory with the same name as the protocol directory in the `staging/` directory. - Copy the final version of the XML that is the version that was decided to be declared stable into the new directory. The target name should be the same name as the protocol directory but with the `.xml` suffix. - Remove the disclaimer about the protocol being in the testing phase. - Update the `README` file in the staging directory and create a new `README` file in the new directory. - Replace the disclaimer in the protocol files left in the staging/ directory with the following: ``` Disclaimer: This protocol extension has been marked stable. This copy is no longer used and only retained for backwards compatibility. The canonical version can be found in the stable/ directory. ``` Note that the major version of the stable protocol extension, as well as all the interface versions and names, must remain unchanged. There are other requirements for declaring a protocol stable, see [GOVERNANCE section 2.3](GOVERNANCE.md#23-introducing-new-protocols). ## Releases Each release of wayland-protocols finalizes the version of the protocols to their state they had at that time. ## Gitlab conventions ### Triaging merge requests New merge requests should be triaged. Doing so requires the one doing the triage to add a set of initial labels: ~"New Protocol" - For a new protocol being added. If it's an amendment to an existing protocol, apply the label of the corresponding protocol instead. If none exist, create it. ~"Needs acks" - If the protocol needs one or more acknowledgements. ~"Needs implementations" - If there are not enough implementations of the protocol. ~"Needs review" - If the protocol is in need of review. ~"In 30 day discussion period" - If the protocol needs a 30 day discussion period. For the meaning and requirement of acknowledgments and available implementations, see the GOVERNANCE.md document. ### Managing merge requests When merge requests get their needed feedback and items, remove the corresponding label that marks it as needing something. For example, if a merge request receives all the required acknowledgments, remove the ~"Needs acks" label, or if 30 days passed since opening, remove any ~"In 30 day discussion period" label. ### Nacking a merge request If the inclusion of a merge request is denied due to one or more Nacks, add the ~Nacked label. wl-mirror-0.16.5/proto/wayland-protocols/meson.build0000644000175000017500000000617714646472005021260 0ustar yrlfyrlfproject('wayland-protocols', version: '1.32', meson_version: '>= 0.55.0', license: 'MIT/Expat', ) wayland_protocols_version = meson.project_version() fs = import('fs') stable_protocols = [ 'presentation-time', 'viewporter', 'xdg-shell', ] unstable_protocols = { 'fullscreen-shell': ['v1'], 'idle-inhibit': ['v1'], 'input-method': ['v1'], 'input-timestamps': ['v1'], 'keyboard-shortcuts-inhibit': ['v1'], 'linux-dmabuf': ['v1'], 'linux-explicit-synchronization': ['v1'], 'pointer-constraints': ['v1'], 'pointer-gestures': ['v1'], 'primary-selection': ['v1'], 'relative-pointer': ['v1'], 'tablet': ['v1', 'v2'], 'text-input': ['v1', 'v3'], 'xdg-decoration': ['v1'], 'xdg-foreign': ['v1', 'v2'], 'xdg-output': ['v1'], 'xdg-shell': ['v5', 'v6'], 'xwayland-keyboard-grab': ['v1'], } staging_protocols = { 'content-type': ['v1'], 'cursor-shape': ['v1'], 'drm-lease': ['v1'], 'ext-foreign-toplevel-list': ['v1'], 'ext-idle-notify': ['v1'], 'ext-session-lock': ['v1'], 'fractional-scale': ['v1'], 'security-context': ['v1'], 'single-pixel-buffer': ['v1'], 'tearing-control': ['v1'], 'xdg-activation': ['v1'], 'xwayland-shell': ['v1'], } protocol_files = [] foreach name : stable_protocols protocol_files += ['stable/@0@/@0@.xml'.format(name)] endforeach foreach name : staging_protocols.keys() foreach version : staging_protocols.get(name) protocol_files += [ 'staging/@0@/@0@-@1@.xml'.format(name, version) ] endforeach endforeach foreach name : unstable_protocols.keys() foreach version : unstable_protocols.get(name) protocol_files += [ 'unstable/@0@/@0@-unstable-@1@.xml'.format(name, version) ] endforeach endforeach # Check that each protocol has a README foreach protocol_file : protocol_files dir = fs.parent(protocol_file) if not fs.is_file(dir + '/README') error('Missing README in @0@'.format(protocol_file)) endif endforeach foreach protocol_file : protocol_files protocol_install_dir = fs.parent(join_paths( get_option('datadir'), 'wayland-protocols', protocol_file, )) install_data( protocol_file, install_dir: protocol_install_dir, ) endforeach wayland_protocols_srcdir = meson.current_source_dir() pkgconfig_configuration = configuration_data() pkgconfig_configuration.set('prefix', get_option('prefix')) pkgconfig_configuration.set('datarootdir', '${prefix}/@0@'.format(get_option('datadir'))) pkgconfig_configuration.set('abs_top_srcdir', wayland_protocols_srcdir) pkgconfig_configuration.set('PACKAGE', 'wayland-protocols') pkgconfig_configuration.set('WAYLAND_PROTOCOLS_VERSION', wayland_protocols_version) pkg_install_dir = join_paths(get_option('datadir'), 'pkgconfig') configure_file( input: 'wayland-protocols.pc.in', output: 'wayland-protocols.pc', configuration: pkgconfig_configuration, install_dir: pkg_install_dir, ) configure_file( input: 'wayland-protocols-uninstalled.pc.in', output: 'wayland-protocols-uninstalled.pc', configuration: pkgconfig_configuration, ) wayland_protocols = declare_dependency( variables: { 'pkgdatadir': wayland_protocols_srcdir, }, ) meson.override_dependency('wayland-protocols', wayland_protocols) if get_option('tests') subdir('tests') endif wl-mirror-0.16.5/proto/wayland-protocols/meson_options.txt0000644000175000017500000000014314646472005022536 0ustar yrlfyrlfoption('tests', type: 'boolean', value: true, description: 'Build the tests') wl-mirror-0.16.5/proto/wayland-protocols/stable/0000755000175000017500000000000014646472005020355 5ustar yrlfyrlfwl-mirror-0.16.5/proto/wayland-protocols/stable/presentation-time/0000755000175000017500000000000014646472005024024 5ustar yrlfyrlfwl-mirror-0.16.5/proto/wayland-protocols/stable/presentation-time/README0000644000175000017500000000013214646472005024700 0ustar yrlfyrlfPresentation time protocol Maintainers: Pekka Paalanen wl-mirror-0.16.5/proto/wayland-protocols/stable/presentation-time/presentation-time.xml0000644000175000017500000003054614646472005030225 0ustar yrlfyrlf Copyright © 2013-2014 Collabora, Ltd. 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. The main feature of this interface is accurate presentation timing feedback to ensure smooth video playback while maintaining audio/video synchronization. Some features use the concept of a presentation clock, which is defined in the presentation.clock_id event. A content update for a wl_surface is submitted by a wl_surface.commit request. Request 'feedback' associates with the wl_surface.commit and provides feedback on the content update, particularly the final realized presentation time. When the final realized presentation time is available, e.g. after a framebuffer flip completes, the requested presentation_feedback.presented events are sent. The final presentation time can differ from the compositor's predicted display update time and the update's target time, especially when the compositor misses its target vertical blanking period. These fatal protocol errors may be emitted in response to illegal presentation requests. Informs the server that the client will no longer be using this protocol object. Existing objects created by this object are not affected. Request presentation feedback for the current content submission on the given surface. This creates a new presentation_feedback object, which will deliver the feedback information once. If multiple presentation_feedback objects are created for the same submission, they will all deliver the same information. For details on what information is returned, see the presentation_feedback interface. This event tells the client in which clock domain the compositor interprets the timestamps used by the presentation extension. This clock is called the presentation clock. The compositor sends this event when the client binds to the presentation interface. The presentation clock does not change during the lifetime of the client connection. The clock identifier is platform dependent. On Linux/glibc, the identifier value is one of the clockid_t values accepted by clock_gettime(). clock_gettime() is defined by POSIX.1-2001. Timestamps in this clock domain are expressed as tv_sec_hi, tv_sec_lo, tv_nsec triples, each component being an unsigned 32-bit value. Whole seconds are in tv_sec which is a 64-bit value combined from tv_sec_hi and tv_sec_lo, and the additional fractional part in tv_nsec as nanoseconds. Hence, for valid timestamps tv_nsec must be in [0, 999999999]. Note that clock_id applies only to the presentation clock, and implies nothing about e.g. the timestamps used in the Wayland core protocol input events. Compositors should prefer a clock which does not jump and is not slewed e.g. by NTP. The absolute value of the clock is irrelevant. Precision of one millisecond or better is recommended. Clients must be able to query the current clock value directly, not by asking the compositor. A presentation_feedback object returns an indication that a wl_surface content update has become visible to the user. One object corresponds to one content update submission (wl_surface.commit). There are two possible outcomes: the content update is presented to the user, and a presentation timestamp delivered; or, the user did not see the content update because it was superseded or its surface destroyed, and the content update is discarded. Once a presentation_feedback object has delivered a 'presented' or 'discarded' event it is automatically destroyed. As presentation can be synchronized to only one output at a time, this event tells which output it was. This event is only sent prior to the presented event. As clients may bind to the same global wl_output multiple times, this event is sent for each bound instance that matches the synchronized output. If a client has not bound to the right wl_output global at all, this event is not sent. These flags provide information about how the presentation of the related content update was done. The intent is to help clients assess the reliability of the feedback and the visual quality with respect to possible tearing and timings. The presentation was synchronized to the "vertical retrace" by the display hardware such that tearing does not happen. Relying on software scheduling is not acceptable for this flag. If presentation is done by a copy to the active frontbuffer, then it must guarantee that tearing cannot happen. The display hardware provided measurements that the hardware driver converted into a presentation timestamp. Sampling a clock in software is not acceptable for this flag. The display hardware signalled that it started using the new image content. The opposite of this is e.g. a timer being used to guess when the display hardware has switched to the new image content. The presentation of this update was done zero-copy. This means the buffer from the client was given to display hardware as is, without copying it. Compositing with OpenGL counts as copying, even if textured directly from the client buffer. Possible zero-copy cases include direct scanout of a fullscreen surface and a surface on a hardware overlay. The associated content update was displayed to the user at the indicated time (tv_sec_hi/lo, tv_nsec). For the interpretation of the timestamp, see presentation.clock_id event. The timestamp corresponds to the time when the content update turned into light the first time on the surface's main output. Compositors may approximate this from the framebuffer flip completion events from the system, and the latency of the physical display path if known. This event is preceded by all related sync_output events telling which output's refresh cycle the feedback corresponds to, i.e. the main output for the surface. Compositors are recommended to choose the output containing the largest part of the wl_surface, or keeping the output they previously chose. Having a stable presentation output association helps clients predict future output refreshes (vblank). The 'refresh' argument gives the compositor's prediction of how many nanoseconds after tv_sec, tv_nsec the very next output refresh may occur. This is to further aid clients in predicting future refreshes, i.e., estimating the timestamps targeting the next few vblanks. If such prediction cannot usefully be done, the argument is zero. If the output does not have a constant refresh rate, explicit video mode switches excluded, then the refresh argument must be zero. The 64-bit value combined from seq_hi and seq_lo is the value of the output's vertical retrace counter when the content update was first scanned out to the display. This value must be compatible with the definition of MSC in GLX_OML_sync_control specification. Note, that if the display path has a non-zero latency, the time instant specified by this counter may differ from the timestamp's. If the output does not have a concept of vertical retrace or a refresh cycle, or the output device is self-refreshing without a way to query the refresh count, then the arguments seq_hi and seq_lo must be zero. The content update was never displayed to the user. wl-mirror-0.16.5/proto/wayland-protocols/stable/viewporter/0000755000175000017500000000000014646472005022563 5ustar yrlfyrlfwl-mirror-0.16.5/proto/wayland-protocols/stable/viewporter/README0000644000175000017500000000023714646472005023445 0ustar yrlfyrlfViewporter: cropping and scaling extension for surface contents Previously known as wl_scaler. Maintainers: Pekka Paalanen wl-mirror-0.16.5/proto/wayland-protocols/stable/viewporter/viewporter.xml0000644000175000017500000002005014646472005025510 0ustar yrlfyrlf Copyright © 2013-2016 Collabora, Ltd. 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. The global interface exposing surface cropping and scaling capabilities is used to instantiate an interface extension for a wl_surface object. This extended interface will then allow cropping and scaling the surface contents, effectively disconnecting the direct relationship between the buffer and the surface size. Informs the server that the client will not be using this protocol object anymore. This does not affect any other objects, wp_viewport objects included. Instantiate an interface extension for the given wl_surface to crop and scale its content. If the given wl_surface already has a wp_viewport object associated, the viewport_exists protocol error is raised. An additional interface to a wl_surface object, which allows the client to specify the cropping and scaling of the surface contents. This interface works with two concepts: the source rectangle (src_x, src_y, src_width, src_height), and the destination size (dst_width, dst_height). The contents of the source rectangle are scaled to the destination size, and content outside the source rectangle is ignored. This state is double-buffered, and is applied on the next wl_surface.commit. The two parts of crop and scale state are independent: the source rectangle, and the destination size. Initially both are unset, that is, no scaling is applied. The whole of the current wl_buffer is used as the source, and the surface size is as defined in wl_surface.attach. If the destination size is set, it causes the surface size to become dst_width, dst_height. The source (rectangle) is scaled to exactly this size. This overrides whatever the attached wl_buffer size is, unless the wl_buffer is NULL. If the wl_buffer is NULL, the surface has no content and therefore no size. Otherwise, the size is always at least 1x1 in surface local coordinates. If the source rectangle is set, it defines what area of the wl_buffer is taken as the source. If the source rectangle is set and the destination size is not set, then src_width and src_height must be integers, and the surface size becomes the source rectangle size. This results in cropping without scaling. If src_width or src_height are not integers and destination size is not set, the bad_size protocol error is raised when the surface state is applied. The coordinate transformations from buffer pixel coordinates up to the surface-local coordinates happen in the following order: 1. buffer_transform (wl_surface.set_buffer_transform) 2. buffer_scale (wl_surface.set_buffer_scale) 3. crop and scale (wp_viewport.set*) This means, that the source rectangle coordinates of crop and scale are given in the coordinates after the buffer transform and scale, i.e. in the coordinates that would be the surface-local coordinates if the crop and scale was not applied. If src_x or src_y are negative, the bad_value protocol error is raised. Otherwise, if the source rectangle is partially or completely outside of the non-NULL wl_buffer, then the out_of_buffer protocol error is raised when the surface state is applied. A NULL wl_buffer does not raise the out_of_buffer error. If the wl_surface associated with the wp_viewport is destroyed, all wp_viewport requests except 'destroy' raise the protocol error no_surface. If the wp_viewport object is destroyed, the crop and scale state is removed from the wl_surface. The change will be applied on the next wl_surface.commit. The associated wl_surface's crop and scale state is removed. The change is applied on the next wl_surface.commit. Set the source rectangle of the associated wl_surface. See wp_viewport for the description, and relation to the wl_buffer size. If all of x, y, width and height are -1.0, the source rectangle is unset instead. Any other set of values where width or height are zero or negative, or x or y are negative, raise the bad_value protocol error. The crop and scale state is double-buffered state, and will be applied on the next wl_surface.commit. Set the destination size of the associated wl_surface. See wp_viewport for the description, and relation to the wl_buffer size. If width is -1 and height is -1, the destination size is unset instead. Any other pair of values for width and height that contains zero or negative values raises the bad_value protocol error. The crop and scale state is double-buffered state, and will be applied on the next wl_surface.commit. wl-mirror-0.16.5/proto/wayland-protocols/stable/xdg-shell/0000755000175000017500000000000014646472005022244 5ustar yrlfyrlfwl-mirror-0.16.5/proto/wayland-protocols/stable/xdg-shell/README0000644000175000017500000000016414646472005023125 0ustar yrlfyrlfxdg shell protocol Maintainers: Jonas Ådahl Mike Blumenkrantz wl-mirror-0.16.5/proto/wayland-protocols/stable/xdg-shell/xdg-shell.xml0000644000175000017500000016600214646472005024662 0ustar yrlfyrlf 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. 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. 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. 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. 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. 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. 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. 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. Notify the compositor that the xdg_positioner will no longer be used. 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. 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. 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. 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. 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. Don't alter the surface position even if it is constrained on some axis, for example partially outside the edge of an output. 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. 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. 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. 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. Resize the surface horizontally so that it is completely unconstrained. Resize the surface vertically so that it is completely unconstrained. 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. 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. 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. 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. 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. 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, 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. 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. 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. 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. 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. The window geometry is double buffered, and will be applied at the time wl_surface.commit of the corresponding wl_surface is called. 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. 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. 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. 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. 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 perfoming 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. This request destroys the role surface and unmaps the surface; see "Unmapping" behavior in interface section for details. 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. 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. 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/ 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. 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. These values are used to indicate which edge of a surface is being dragged in a resize operation. 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. 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. They will get applied on the next commit. 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. 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. 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. 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. 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 window is currently in a tiled layout and the right edge is considered to be adjacent to another part of the tiling grid. 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 window is currently in a tiled layout and the bottom edge is considered to be adjacent to another part of the tiling grid. 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. 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. They will get applied on the next 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. 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. They will get applied on the next 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. 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. 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. 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. 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). 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. wl-mirror-0.16.5/proto/wayland-protocols/staging/0000755000175000017500000000000014646472005020537 5ustar yrlfyrlfwl-mirror-0.16.5/proto/wayland-protocols/staging/content-type/0000755000175000017500000000000014646472005023170 5ustar yrlfyrlfwl-mirror-0.16.5/proto/wayland-protocols/staging/content-type/README0000644000175000017500000000017014646472005024046 0ustar yrlfyrlfContent type hint protocol Maintainers: Emmanuel Gil Peyrot Xaver Hugl wl-mirror-0.16.5/proto/wayland-protocols/staging/content-type/content-type-v1.xml0000644000175000017500000001315514646472005026674 0ustar yrlfyrlf Copyright © 2021 Emmanuel Gil Peyrot Copyright © 2022 Xaver Hugl 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. This interface allows a client to describe the kind of content a surface will display, to allow the compositor to optimize its behavior for it. Warning! The protocol described in this file is currently in the testing phase. Backward compatible changes may be added together with the corresponding interface version bump. Backward incompatible changes can only be done by creating a new major version of the extension. Destroy the content type manager. This doesn't destroy objects created with the manager. Create a new content type object associated with the given surface. Creating a wp_content_type_v1 from a wl_surface which already has one attached is a client error: already_constructed. The content type object allows the compositor to optimize for the kind of content shown on the surface. A compositor may for example use it to set relevant drm properties like "content type". The client may request to switch to another content type at any time. When the associated surface gets destroyed, this object becomes inert and the client should destroy it. Switch back to not specifying the content type of this surface. This is equivalent to setting the content type to none, including double buffering semantics. See set_content_type for details. These values describe the available content types for a surface. The content type none means that either the application has no data about the content type, or that the content doesn't fit into one of the other categories. The content type photo describes content derived from digital still pictures and may be presented with minimal processing. The content type video describes a video or animation and may be presented with more accurate timing to avoid stutter. Where scaling is needed, scaling methods more appropriate for video may be used. The content type game describes a running game. Its content may be presented with reduced latency. Set the surface content type. This informs the compositor that the client believes it is displaying buffers matching this content type. This is purely a hint for the compositor, which can be used to adjust its behavior or hardware settings to fit the presented content best. The content type is double-buffered state, see wl_surface.commit for details. wl-mirror-0.16.5/proto/wayland-protocols/staging/cursor-shape/0000755000175000017500000000000014646472005023152 5ustar yrlfyrlfwl-mirror-0.16.5/proto/wayland-protocols/staging/cursor-shape/README0000644000175000017500000000010414646472005024025 0ustar yrlfyrlfcursor-shape protocol Maintainers: Simon Ser wl-mirror-0.16.5/proto/wayland-protocols/staging/cursor-shape/cursor-shape-v1.xml0000644000175000017500000002003014646472005026626 0ustar yrlfyrlf Copyright 2018 The Chromium Authors Copyright 2023 Simon Ser 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. This global offers an alternative, optional way to set cursor images. This new way uses enumerated cursors instead of a wl_surface like wl_pointer.set_cursor does. Warning! The protocol described in this file is currently in the testing phase. Backward compatible changes may be added together with the corresponding interface version bump. Backward incompatible changes can only be done by creating a new major version of the extension. Destroy the cursor shape manager. Obtain a wp_cursor_shape_device_v1 for a wl_pointer object. Obtain a wp_cursor_shape_device_v1 for a zwp_tablet_tool_v2 object. This interface advertises the list of supported cursor shapes for a device, and allows clients to set the cursor shape. This enum describes cursor shapes. The names are taken from the CSS W3C specification: https://w3c.github.io/csswg-drafts/css-ui/#cursor Destroy the cursor shape device. The device cursor shape remains unchanged. Sets the device cursor to the specified shape. The compositor will change the cursor image based on the specified shape. The cursor actually changes only if the input device focus is one of the requesting client's surfaces. If any, the previous cursor image (surface or shape) is replaced. The "shape" argument must be a valid enum entry, otherwise the invalid_shape protocol error is raised. This is similar to the wl_pointer.set_cursor and zwp_tablet_tool_v2.set_cursor requests, but this request accepts a shape instead of contents in the form of a surface. Clients can mix set_cursor and set_shape requests. The serial parameter must match the latest wl_pointer.enter or zwp_tablet_tool_v2.proximity_in serial number sent to the client. Otherwise the request will be ignored. wl-mirror-0.16.5/proto/wayland-protocols/staging/drm-lease/0000755000175000017500000000000014646472005022410 5ustar yrlfyrlfwl-mirror-0.16.5/proto/wayland-protocols/staging/drm-lease/README0000644000175000017500000000020514646472005023265 0ustar yrlfyrlfLinux DRM lease Maintainers: Drew DeVault Marius Vlad Xaver Hugl wl-mirror-0.16.5/proto/wayland-protocols/staging/drm-lease/drm-lease-v1.xml0000644000175000017500000003560214646472005025335 0ustar yrlfyrlf Copyright © 2018 NXP Copyright © 2019 Status Research & Development GmbH. Copyright © 2021 Xaver Hugl 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. This protocol is used by Wayland compositors which act as Direct Renderering Manager (DRM) masters to lease DRM resources to Wayland clients. The compositor will advertise one wp_drm_lease_device_v1 global for each DRM node. Some time after a client binds to the wp_drm_lease_device_v1 global, the compositor will send a drm_fd event followed by zero, one or more connector events. After all currently available connectors have been sent, the compositor will send a wp_drm_lease_device_v1.done event. When the list of connectors available for lease changes the compositor will send wp_drm_lease_device_v1.connector events for added connectors and wp_drm_lease_connector_v1.withdrawn events for removed connectors, followed by a wp_drm_lease_device_v1.done event. The compositor will indicate when a device is gone by removing the global via a wl_registry.global_remove event. Upon receiving this event, the client should destroy any matching wp_drm_lease_device_v1 object. To destroy a wp_drm_lease_device_v1 object, the client must first issue a release request. Upon receiving this request, the compositor will immediately send a released event and destroy the object. The client must continue to process and discard drm_fd and connector events until it receives the released event. Upon receiving the released event, the client can safely cleanup any client-side resources. Warning! The protocol described in this file is currently in the testing phase. Backward compatible changes may be added together with the corresponding interface version bump. Backward incompatible changes can only be done by creating a new major version of the extension. Creates a lease request object. See the documentation for wp_drm_lease_request_v1 for details. Indicates the client no longer wishes to use this object. In response the compositor will immediately send the released event and destroy this object. It can however not guarantee that the client won't receive connector events before the released event. The client must not send any requests after this one, doing so will raise a wl_display error. Existing connectors, lease request and leases will not be affected. The compositor will send this event when the wp_drm_lease_device_v1 global is bound, although there are no guarantees as to how long this takes - the compositor might need to wait until regaining DRM master. The included fd is a non-master DRM file descriptor opened for this device and the compositor must not authenticate it. The purpose of this event is to give the client the ability to query DRM and discover information which may help them pick the appropriate DRM device or select the appropriate connectors therein. The compositor will use this event to advertise connectors available for lease by clients. This object may be passed into a lease request to indicate the client would like to lease that connector, see wp_drm_lease_request_v1.request_connector for details. While the compositor will make a best effort to not send disconnected connectors, no guarantees can be made. The compositor must send the drm_fd event before sending connectors. After the drm_fd event it will send all available connectors but may send additional connectors at any time. The compositor will send this event to indicate that it has sent all currently available connectors after the client binds to the global or when it updates the connector list, for example on hotplug, drm master change or when a leased connector becomes available again. It will similarly send this event to group wp_drm_lease_connector_v1.withdrawn events of connectors of this device. This event is sent in response to the release request and indicates that the compositor is done sending connector events. The compositor will destroy this object immediately after sending the event and it will become invalid. The client should release any resources associated with this device after receiving this event. Represents a DRM connector which is available for lease. These objects are created via wp_drm_lease_device_v1.connector events, and should be passed to lease requests via wp_drm_lease_request_v1.request_connector. Immediately after the wp_drm_lease_connector_v1 object is created the compositor will send a name, a description, a connector_id and a done event. When the description is updated the compositor will send a description event followed by a done event. The compositor sends this event once the connector is created to indicate the name of this connector. This will not change for the duration of the Wayland session, but is not guaranteed to be consistent between sessions. If the compositor supports wl_output version 4 and this connector corresponds to a wl_output, the compositor should use the same name as for the wl_output. The compositor sends this event once the connector is created to provide a human-readable description for this connector, which may be presented to the user. The compositor may send this event multiple times over the lifetime of this object to reflect changes in the description. The compositor sends this event once the connector is created to indicate the DRM object ID which represents the underlying connector that is being offered. Note that the final lease may include additional object IDs, such as CRTCs and planes. This event is sent after all properties of a connector have been sent. This allows changes to the properties to be seen as atomic even if they happen via multiple events. Sent to indicate that the compositor will no longer honor requests for DRM leases which include this connector. The client may still issue a lease request including this connector, but the compositor will send wp_drm_lease_v1.finished without issuing a lease fd. Compositors are encouraged to send this event when they lose access to connector, for example when the connector is hot-unplugged, when the connector gets leased to a client or when the compositor loses DRM master. The client may send this request to indicate that it will not use this connector. Clients are encouraged to send this after receiving the "withdrawn" event so that the server can release the resources associated with this connector offer. Neither existing lease requests nor leases will be affected. A client that wishes to lease DRM resources will attach the list of connectors advertised with wp_drm_lease_device_v1.connector that they wish to lease, then use wp_drm_lease_request_v1.submit to submit the request. Indicates that the client would like to lease the given connector. This is only used as a suggestion, the compositor may choose to include any resources in the lease it issues, or change the set of leased resources at any time. Compositors are however encouraged to include the requested connector and other resources necessary to drive the connected output in the lease. Requesting a connector that was created from a different lease device than this lease request raises the wrong_device error. Requesting a connector twice will raise the duplicate_connector error. Submits the lease request and creates a new wp_drm_lease_v1 object. After calling submit the compositor will immediately destroy this object, issuing any more requests will cause a wl_diplay error. The compositor doesn't make any guarantees about the events of the lease object, clients cannot expect an immediate response. Not requesting any connectors before submitting the lease request will raise the empty_lease error. A DRM lease object is used to transfer the DRM file descriptor to the client and manage the lifetime of the lease. Some time after the wp_drm_lease_v1 object is created, the compositor will reply with the lease request's result. If the lease request is granted, the compositor will send a lease_fd event. If the lease request is denied, the compositor will send a finished event without a lease_fd event. This event returns a file descriptor suitable for use with DRM-related ioctls. The client should use drmModeGetLease to enumerate the DRM objects which have been leased to them. The compositor guarantees it will not use the leased DRM objects itself until it sends the finished event. If the compositor cannot or will not grant a lease for the requested connectors, it will not send this event, instead sending the finished event. The compositor will send this event at most once during this objects lifetime. The compositor uses this event to either reject a lease request, or if it previously sent a lease_fd, to notify the client that the lease has been revoked. If the client requires a new lease, they should destroy this object and submit a new lease request. The compositor will send no further events for this object after sending the finish event. Compositors should revoke the lease when any of the leased resources become unavailable, namely when a hot-unplug occurs or when the compositor loses DRM master. The client should send this to indicate that it no longer wishes to use this lease. The compositor should use drmModeRevokeLease on the appropriate file descriptor, if necessary. wl-mirror-0.16.5/proto/wayland-protocols/staging/ext-foreign-toplevel-list/0000755000175000017500000000000014646472005025567 5ustar yrlfyrlfwl-mirror-0.16.5/proto/wayland-protocols/staging/ext-foreign-toplevel-list/README0000644000175000017500000000010414646472005026442 0ustar yrlfyrlfForeign toplevel list protocol Maintainers: i509VCB ././@LongLink0000644000000000000000000000015400000000000011603 Lustar rootrootwl-mirror-0.16.5/proto/wayland-protocols/staging/ext-foreign-toplevel-list/ext-foreign-toplevel-list-v1.xmlwl-mirror-0.16.5/proto/wayland-protocols/staging/ext-foreign-toplevel-list/ext-foreign-toplevel-list0000644000175000017500000002345514646472005032553 0ustar yrlfyrlf Copyright © 2018 Ilia Bozhinov Copyright © 2020 Isaac Freund Copyright © 2022 wb9688 Copyright © 2023 i509VCB 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. The purpose of this protocol is to provide protocol object handles for toplevels, possibly originating from another client. This protocol is intentionally minimalistic and expects additional functionality (e.g. creating a screencopy source from a toplevel handle, getting information about the state of the toplevel) to be implemented in extension protocols. The compositor may choose to restrict this protocol to a special client launched by the compositor itself or expose it to all clients, this is compositor policy. The key words "must", "must not", "required", "shall", "shall not", "should", "should not", "recommended", "may", and "optional" in this document are to be interpreted as described in IETF RFC 2119. Warning! The protocol described in this file is currently in the testing phase. Backward compatible changes may be added together with the corresponding interface version bump. Backward incompatible changes can only be done by creating a new major version of the extension. A toplevel is defined as a surface with a role similar to xdg_toplevel. XWayland surfaces may be treated like toplevels in this protocol. After a client binds the ext_foreign_toplevel_list_v1, each mapped toplevel window will be sent using the ext_foreign_toplevel_list_v1.toplevel event. Clients which only care about the current state can perform a roundtrip after binding this global. For each instance of ext_foreign_toplevel_list_v1, the compositor must create a new ext_foreign_toplevel_handle_v1 object for each mapped toplevel. If a compositor implementation sends the ext_foreign_toplevel_list_v1.finished event after the global is bound, the compositor must not send any ext_foreign_toplevel_list_v1.toplevel events. This event is emitted whenever a new toplevel window is created. It is emitted for all toplevels, regardless of the app that has created them. All initial properties of the toplevel (identifier, title, app_id) will be sent immediately after this event using the corresponding events for ext_foreign_toplevel_handle_v1. The compositor will use the ext_foreign_toplevel_handle_v1.done event to indicate when all data has been sent. This event indicates that the compositor is done sending events to this object. The client should should destroy the object. See ext_foreign_toplevel_list_v1.destroy for more information. The compositor must not send any more toplevel events after this event. This request indicates that the client no longer wishes to receive events for new toplevels. The Wayland protocol is asynchronous, meaning the compositor may send further toplevel events until the stop request is processed. The client should wait for a ext_foreign_toplevel_list_v1.finished event before destroying this object. This request should be called either when the client will no longer use the ext_foreign_toplevel_list_v1 or after the finished event has been received to allow destruction of the object. If a client wishes to destroy this object it should send a ext_foreign_toplevel_list_v1.stop request and wait for a ext_foreign_toplevel_list_v1.finished event, then destroy the handles and then this object. A ext_foreign_toplevel_handle_v1 object represents a mapped toplevel window. A single app may have multiple mapped toplevels. This request should be used when the client will no longer use the handle or after the closed event has been received to allow destruction of the object. When a handle is destroyed, a new handle may not be created by the server until the toplevel is unmapped and then remapped. Destroying a toplevel handle is not recommended unless the client is cleaning up child objects before destroying the ext_foreign_toplevel_list_v1 object, the toplevel was closed or the toplevel handle will not be used in the future. Other protocols which extend the ext_foreign_toplevel_handle_v1 interface should require destructors for extension interfaces be called before allowing the toplevel handle to be destroyed. The server will emit no further events on the ext_foreign_toplevel_handle_v1 after this event. Any requests received aside from the destroy request must be ignored. Upon receiving this event, the client should destroy the handle. Other protocols which extend the ext_foreign_toplevel_handle_v1 interface must also ignore requests other than destructors. This event is sent after all changes in the toplevel state have been sent. This allows changes to the ext_foreign_toplevel_handle_v1 properties to be atomically applied. Other protocols which extend the ext_foreign_toplevel_handle_v1 interface may use this event to also atomically apply any pending state. This event must not be sent after the ext_foreign_toplevel_handle_v1.closed event. The title of the toplevel has changed. The configured state must not be applied immediately. See ext_foreign_toplevel_handle_v1.done for details. The app id of the toplevel has changed. The configured state must not be applied immediately. See ext_foreign_toplevel_handle_v1.done for details. This identifier is used to check if two or more toplevel handles belong to the same toplevel. The identifier is useful for command line tools or privileged clients which may need to reference an exact toplevel across processes or instances of the ext_foreign_toplevel_list_v1 global. The compositor must only send this event when the handle is created. The identifier must be unique per toplevel and it's handles. Two different toplevels must not have the same identifier. The identifier is only valid as long as the toplevel is mapped. If the toplevel is unmapped the identifier must not be reused. An identifier must not be reused by the compositor to ensure there are no races when sharing identifiers between processes. An identifier is a string that contains up to 32 printable ASCII bytes. An identifier must not be an empty string. It is recommended that a compositor includes an opaque generation value in identifiers. How the generation value is used when generating the identifier is implementation dependent. wl-mirror-0.16.5/proto/wayland-protocols/staging/ext-idle-notify/0000755000175000017500000000000014646472005023560 5ustar yrlfyrlfwl-mirror-0.16.5/proto/wayland-protocols/staging/ext-idle-notify/README0000644000175000017500000000010314646472005024432 0ustar yrlfyrlfidle_notify protocol Maintainers: Simon Ser wl-mirror-0.16.5/proto/wayland-protocols/staging/ext-idle-notify/ext-idle-notify-v1.xml0000644000175000017500000001065214646472005027653 0ustar yrlfyrlf Copyright © 2015 Martin Gräßlin Copyright © 2022 Simon Ser 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. This interface allows clients to monitor user idle status. After binding to this global, clients can create ext_idle_notification_v1 objects to get notified when the user is idle for a given amount of time. Destroy the manager object. All objects created via this interface remain valid. Create a new idle notification object. The notification object has a minimum timeout duration and is tied to a seat. The client will be notified if the seat is inactive for at least the provided timeout. See ext_idle_notification_v1 for more details. A zero timeout is valid and means the client wants to be notified as soon as possible when the seat is inactive. This interface is used by the compositor to send idle notification events to clients. Initially the notification object is not idle. The notification object becomes idle when no user activity has happened for at least the timeout duration, starting from the creation of the notification object. User activity may include input events or a presence sensor, but is compositor-specific. If an idle inhibitor is active (e.g. another client has created a zwp_idle_inhibitor_v1 on a visible surface), the compositor must not make the notification object idle. When the notification object becomes idle, an idled event is sent. When user activity starts again, the notification object stops being idle, a resumed event is sent and the timeout is restarted. Destroy the notification object. This event is sent when the notification object becomes idle. It's a compositor protocol error to send this event twice without a resumed event in-between. This event is sent when the notification object stops being idle. It's a compositor protocol error to send this event twice without an idled event in-between. It's a compositor protocol error to send this event prior to any idled event. wl-mirror-0.16.5/proto/wayland-protocols/staging/ext-session-lock/0000755000175000017500000000000014646472005023746 5ustar yrlfyrlfwl-mirror-0.16.5/proto/wayland-protocols/staging/ext-session-lock/README0000644000175000017500000000011414646472005024622 0ustar yrlfyrlfext session lock protocol Maintainers: Isaac Freund wl-mirror-0.16.5/proto/wayland-protocols/staging/ext-session-lock/ext-session-lock-v1.xml0000644000175000017500000003731014646472005030227 0ustar yrlfyrlf Copyright 2021 Isaac Freund 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. This protocol allows for a privileged Wayland client to lock the session and display arbitrary graphics while the session is locked. The compositor may choose to restrict this protocol to a special client launched by the compositor itself or expose it to all privileged clients, this is compositor policy. The client is responsible for performing authentication and informing the compositor when the session should be unlocked. If the client dies while the session is locked the session remains locked, possibly permanently depending on compositor policy. The key words "must", "must not", "required", "shall", "shall not", "should", "should not", "recommended", "may", and "optional" in this document are to be interpreted as described in IETF RFC 2119. Warning! The protocol described in this file is currently in the testing phase. Backward compatible changes may be added together with the corresponding interface version bump. Backward incompatible changes can only be done by creating a new major version of the extension. This interface is used to request that the session be locked. This informs the compositor that the session lock manager object will no longer be used. Existing objects created through this interface remain valid. This request creates a session lock and asks the compositor to lock the session. The compositor will send either the ext_session_lock_v1.locked or ext_session_lock_v1.finished event on the created object in response to this request. In response to the creation of this object the compositor must send either the locked or finished event. The locked event indicates that the session is locked. This means that the compositor must stop rendering and providing input to normal clients. Instead the compositor must blank all outputs with an opaque color such that their normal content is fully hidden. The only surfaces that should be rendered while the session is locked are the lock surfaces created through this interface and optionally, at the compositor's discretion, special privileged surfaces such as input methods or portions of desktop shell UIs. The locked event must not be sent until a new "locked" frame (either from a session lock surface or the compositor blanking the output) has been presented on all outputs and no security sensitive normal/unlocked content is possibly visible. The finished event should be sent immediately on creation of this object if the compositor decides that the locked event will not be sent. The compositor may wait for the client to create and render session lock surfaces before sending the locked event to avoid displaying intermediate blank frames. However, it must impose a reasonable time limit if waiting and send the locked event as soon as the hard requirements described above can be met if the time limit expires. Clients should immediately create lock surfaces for all outputs on creation of this object to make this possible. This behavior of the locked event is required in order to prevent possible race conditions with clients that wish to suspend the system or similar after locking the session. Without these semantics, clients triggering a suspend after receiving the locked event would race with the first "locked" frame being presented and normal/unlocked frames might be briefly visible as the system is resumed if the suspend operation wins the race. If the client dies while the session is locked, the compositor must not unlock the session in response. It is acceptable for the session to be permanently locked if this happens. The compositor may choose to continue to display the lock surfaces the client had mapped before it died or alternatively fall back to a solid color, this is compositor policy. Compositors may also allow a secure way to recover the session, the details of this are compositor policy. Compositors may allow a new client to create a ext_session_lock_v1 object and take responsibility for unlocking the session, they may even start a new lock client instance automatically. This informs the compositor that the lock object will no longer be used. Existing objects created through this interface remain valid. After this request is made, lock surfaces created through this object should be destroyed by the client as they will no longer be used by the compositor. It is a protocol error to make this request if the locked event was sent, the unlock_and_destroy request must be used instead. This client is now responsible for displaying graphics while the session is locked and deciding when to unlock the session. The locked event must not be sent until a new "locked" frame has been presented on all outputs and no security sensitive normal/unlocked content is possibly visible. If this event is sent, making the destroy request is a protocol error, the lock object must be destroyed using the unlock_and_destroy request. The compositor has decided that the session lock should be destroyed as it will no longer be used by the compositor. Exactly when this event is sent is compositor policy, but it must never be sent more than once for a given session lock object. This might be sent because there is already another ext_session_lock_v1 object held by a client, or the compositor has decided to deny the request to lock the session for some other reason. This might also be sent because the compositor implements some alternative, secure way to authenticate and unlock the session. The finished event should be sent immediately on creation of this object if the compositor decides that the locked event will not be sent. If the locked event is sent on creation of this object the finished event may still be sent at some later time in this object's lifetime. This is compositor policy. Upon receiving this event, the client should make either the destroy request or the unlock_and_destroy request, depending on whether or not the locked event was received on this object. The client is expected to create lock surfaces for all outputs currently present and any new outputs as they are advertised. These won't be displayed by the compositor unless the lock is successful and the locked event is sent. Providing a wl_surface which already has a role or already has a buffer attached or committed is a protocol error, as is attaching/committing a buffer before the first ext_session_lock_surface_v1.configure event. Attempting to create more than one lock surface for a given output is a duplicate_output protocol error. This request indicates that the session should be unlocked, for example because the user has entered their password and it has been verified by the client. This request also informs the compositor that the lock object will no longer be used and should be destroyed. Existing objects created through this interface remain valid. After this request is made, lock surfaces created through this object should be destroyed by the client as they will no longer be used by the compositor. It is a protocol error to make this request if the locked event has not been sent. In that case, the lock object must be destroyed using the destroy request. Note that a correct client that wishes to exit directly after unlocking the session must use the wl_display.sync request to ensure the server receives and processes the unlock_and_destroy request. Otherwise there is no guarantee that the server has unlocked the session due to the asynchronous nature of the Wayland protocol. For example, the server might terminate the client with a protocol error before it processes the unlock_and_destroy request. The client may use lock surfaces to display a screensaver, render a dialog to enter a password and unlock the session, or however else it sees fit. On binding this interface the compositor will immediately send the first configure event. After making the ack_configure request in response to this event the client should attach and commit the first buffer. Committing the surface before acking the first configure is a protocol error. Committing the surface with a null buffer at any time is a protocol error. The compositor is free to handle keyboard/pointer focus for lock surfaces however it chooses. A reasonable way to do this would be to give the first lock surface created keyboard focus and change keyboard focus if the user clicks on other surfaces. This informs the compositor that the lock surface object will no longer be used. It is recommended for a lock client to destroy lock surfaces if their corresponding wl_output global is removed. If a lock surface on an active output is destroyed before the ext_session_lock_v1.unlock_and_destroy event is sent, the compositor must fall back to rendering a solid color. 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. Sending an ack_configure request consumes the configure event referenced by the given serial, as well as all older configure events sent on this object. It is a protocol error to issue multiple ack_configure requests referencing the same configure event or to issue an ack_configure request referencing a configure event older than the last configure event acked for a given lock surface. This event is sent once on binding the interface and may be sent again at the compositor's discretion, for example if output geometry changes. The width and height are in surface-local coordinates and are exact requirements. Failing to match these surface dimensions in the next commit after acking a configure is a protocol error. wl-mirror-0.16.5/proto/wayland-protocols/staging/fractional-scale/0000755000175000017500000000000014646472005023746 5ustar yrlfyrlfwl-mirror-0.16.5/proto/wayland-protocols/staging/fractional-scale/README0000644000175000017500000000010614646472005024623 0ustar yrlfyrlfwp fractional scale protocol Maintainers: Kenny Levinsen wl-mirror-0.16.5/proto/wayland-protocols/staging/fractional-scale/fractional-scale-v1.xml0000644000175000017500000001103414646472005030222 0ustar yrlfyrlf Copyright © 2022 Kenny Levinsen 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. This protocol allows a compositor to suggest for surfaces to render at fractional scales. A client can submit scaled content by utilizing wp_viewport. This is done by creating a wp_viewport object for the surface and setting the destination rectangle to the surface size before the scale factor is applied. The buffer size is calculated by multiplying the surface size by the intended scale. The wl_surface buffer scale should remain set to 1. If a surface has a surface-local size of 100 px by 50 px and wishes to submit buffers with a scale of 1.5, then a buffer of 150px by 75 px should be used and the wp_viewport destination rectangle should be 100 px by 50 px. For toplevel surfaces, the size is rounded halfway away from zero. The rounding algorithm for subsurface position and size is not defined. A global interface for requesting surfaces to use fractional scales. Informs the server that the client will not be using this protocol object anymore. This does not affect any other objects, wp_fractional_scale_v1 objects included. Create an add-on object for the the wl_surface to let the compositor request fractional scales. If the given wl_surface already has a wp_fractional_scale_v1 object associated, the fractional_scale_exists protocol error is raised. An additional interface to a wl_surface object which allows the compositor to inform the client of the preferred scale. Destroy the fractional scale object. When this object is destroyed, preferred_scale events will no longer be sent. Notification of a new preferred scale for this surface that the compositor suggests that the client should use. The sent scale is the numerator of a fraction with a denominator of 120. wl-mirror-0.16.5/proto/wayland-protocols/staging/security-context/0000755000175000017500000000000014646472005024070 5ustar yrlfyrlfwl-mirror-0.16.5/proto/wayland-protocols/staging/security-context/README0000644000175000017500000000011014646472005024740 0ustar yrlfyrlfsecurity_context protocol Maintainers: Simon Ser wl-mirror-0.16.5/proto/wayland-protocols/staging/security-context/engines.md0000644000175000017500000000063114646472005026042 0ustar yrlfyrlf# security-context-v1 engines This document describes how some specific engine implementations populate the metadata in security-context-v1. ## [Flatpak] * `sandbox_engine` is always set to `flatpak`. * `app_id` is the Flatpak application ID (in reverse-DNS style). It is always set. * `instance_id` is the Flatpak instance ID of the running sandbox. It is always set. [Flatpak]: https://flatpak.org/ wl-mirror-0.16.5/proto/wayland-protocols/staging/security-context/security-context-v1.xml0000644000175000017500000001667514646472005030506 0ustar yrlfyrlf Copyright © 2021 Simon Ser 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. This interface allows a client to register a new Wayland connection to the compositor and attach a security context to it. This is intended to be used by sandboxes. Sandbox engines attach a security context to all connections coming from inside the sandbox. The compositor can then restrict the features that the sandboxed connections can use. Compositors should forbid nesting multiple security contexts by not exposing wp_security_context_manager_v1 global to clients with a security context attached, or by sending the nested protocol error. Nested security contexts are dangerous because they can potentially allow privilege escalation of a sandboxed client. Warning! The protocol described in this file is currently in the testing phase. Backward compatible changes may be added together with the corresponding interface version bump. Backward incompatible changes can only be done by creating a new major version of the extension. Destroy the manager. This doesn't destroy objects created with the manager. Creates a new security context with a socket listening FD. The compositor will accept new client connections on listen_fd. listen_fd must be ready to accept new connections when this request is sent by the client. In other words, the client must call bind(2) and listen(2) before sending the FD. close_fd is a FD closed by the client when the compositor should stop accepting new connections on listen_fd. The compositor must continue to accept connections on listen_fd when the Wayland client which created the security context disconnects. The security context allows a client to register a new client and attach security context metadata to the connections. When both are set, the combination of the application ID and the sandbox engine must uniquely identify an application. The same application ID will be used across instances (e.g. if the application is restarted, or if the application is started multiple times). When both are set, the combination of the instance ID and the sandbox engine must uniquely identify a running instance of an application. Destroy the security context object. Attach a unique sandbox engine name to the security context. A list of well-known engines is maintained at: https://gitlab.freedesktop.org/wayland/wayland-protocols/-/blob/main/staging/security-context/engines.md It is a protocol error to call this request twice. The already_set error is sent in this case. Attach an application ID to the security context. The application ID is an opaque, sandbox-specific identifier for an application. See the well-known engines document for more details: https://gitlab.freedesktop.org/wayland/wayland-protocols/-/blob/main/staging/security-context/engines.md The compositor may use the application ID to group clients belonging to the same security context application. Whether this request is optional or not depends on the sandbox engine used. It is a protocol error to call this request twice. The already_set error is sent in this case. Attach an instance ID to the security context. The instance ID is an opaque, sandbox-specific identifier for a running instance of an application. See the well-known engines document for more details: https://gitlab.freedesktop.org/wayland/wayland-protocols/-/blob/main/staging/security-context/engines.md Whether this request is optional or not depends on the sandbox engine used. It is a protocol error to call this request twice. The already_set error is sent in this case. Atomically register the new client and attach the security context metadata. It's a protocol error to send any request other than "destroy" after this request. In this case, the already_used error is sent. wl-mirror-0.16.5/proto/wayland-protocols/staging/single-pixel-buffer/0000755000175000017500000000000014646472005024406 5ustar yrlfyrlfwl-mirror-0.16.5/proto/wayland-protocols/staging/single-pixel-buffer/README0000644000175000017500000000011314646472005025261 0ustar yrlfyrlfSingle-pixel buffer protocol Maintainers: Simon Ser wl-mirror-0.16.5/proto/wayland-protocols/staging/single-pixel-buffer/single-pixel-buffer-v1.xml0000644000175000017500000000617314646472005031332 0ustar yrlfyrlf Copyright © 2022 Simon Ser 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. This protocol extension allows clients to create single-pixel buffers. Compositors supporting this protocol extension should also support the viewporter protocol extension. Clients may use viewporter to scale a single-pixel buffer to a desired size. Warning! The protocol described in this file is currently in the testing phase. Backward compatible changes may be added together with the corresponding interface version bump. Backward incompatible changes can only be done by creating a new major version of the extension. The wp_single_pixel_buffer_manager_v1 interface is a factory for single-pixel buffers. Destroy the wp_single_pixel_buffer_manager_v1 object. The child objects created via this interface are unaffected. Create a single-pixel buffer from four 32-bit RGBA values. Unless specified in another protocol extension, the RGBA values use pre-multiplied alpha. The width and height of the buffer are 1. wl-mirror-0.16.5/proto/wayland-protocols/staging/tearing-control/0000755000175000017500000000000014646472005023646 5ustar yrlfyrlfwl-mirror-0.16.5/proto/wayland-protocols/staging/tearing-control/README0000644000175000017500000000011114646472005024517 0ustar yrlfyrlfTearing control protocol Maintainers: Xaver Hugl wl-mirror-0.16.5/proto/wayland-protocols/staging/tearing-control/tearing-control-v1.xml0000644000175000017500000001270214646472005030025 0ustar yrlfyrlf Copyright © 2021 Xaver Hugl 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. For some use cases like games or drawing tablets it can make sense to reduce latency by accepting tearing with the use of asynchronous page flips. This global is a factory interface, allowing clients to inform which type of presentation the content of their surfaces is suitable for. Graphics APIs like EGL or Vulkan, that manage the buffer queue and commits of a wl_surface themselves, are likely to be using this extension internally. If a client is using such an API for a wl_surface, it should not directly use this extension on that surface, to avoid raising a tearing_control_exists protocol error. Warning! The protocol described in this file is currently in the testing phase. Backward compatible changes may be added together with the corresponding interface version bump. Backward incompatible changes can only be done by creating a new major version of the extension. Destroy this tearing control factory object. Other objects, including wp_tearing_control_v1 objects created by this factory, are not affected by this request. Instantiate an interface extension for the given wl_surface to request asynchronous page flips for presentation. If the given wl_surface already has a wp_tearing_control_v1 object associated, the tearing_control_exists protocol error is raised. An additional interface to a wl_surface object, which allows the client to hint to the compositor if the content on the surface is suitable for presentation with tearing. The default presentation hint is vsync. See presentation_hint for more details. This enum provides information for if submitted frames from the client may be presented with tearing. The content of this surface is meant to be synchronized to the vertical blanking period. This should not result in visible tearing and may result in a delay before a surface commit is presented. The content of this surface is meant to be presented with minimal latency and tearing is acceptable. Set the presentation hint for the associated wl_surface. This state is double-buffered and is applied on the next wl_surface.commit. The compositor is free to dynamically respect or ignore this hint based on various conditions like hardware capabilities, surface state and user preferences. Destroy this surface tearing object and revert the presentation hint to vsync. The change will be applied on the next wl_surface.commit. wl-mirror-0.16.5/proto/wayland-protocols/staging/xdg-activation/0000755000175000017500000000000014646472005023460 5ustar yrlfyrlfwl-mirror-0.16.5/proto/wayland-protocols/staging/xdg-activation/README0000644000175000017500000000011414646472005024334 0ustar yrlfyrlfXDG Activation protocol Maintainers: Aleix Pol Gonzalez wl-mirror-0.16.5/proto/wayland-protocols/staging/xdg-activation/x11-interoperation.rst0000644000175000017500000000516714646472005027674 0ustar yrlfyrlfInteroperation with X11 ======================= *This document is non-normative.* The former `X11 Startup notification protocol `_ defines the use of the ``DESKTOP_STARTUP_ID`` environment variable to propagate startup sequences ("activation tokens" in this protocol) between launcher and launchee. These startup sequence IDs are defined as a globally unique string with a ``[unique]_TIME[timestamp]`` format, where the ID as a whole is used for startup notification and the timestamp is used for focus requests and focus stealing prevention. In order to observe mixed usage scenarios where Wayland and X11 clients might be launching each other, it is possible for a compositor to manage a shared pool of activation tokens. Scenario 1. Wayland client spawns X11 client -------------------------------------------- 1. Wayland client requests token. 2. Wayland client spawns X11 client, sets ``$DESKTOP_STARTUP_ID`` in its environment with the token string. 3. X11 client starts. 4. X11 client sends startup-notification ``remove`` message with the activation ``$DESKTOP_STARTUP_ID`` content. 5. Compositor receives startup notification message, matches ID with the common pool. 6. The startup feedback is finished. 7. X11 client requests focus. 8. Compositor applies internal policies to allow/deny focus switch. Scenario 2. X11 client spawns Wayland client -------------------------------------------- 1. X11 client builds a "globally unique" ID 2. X11 client sends startup-notification ``new`` message with the ID. 3. Compositor receives startup notification message, adds the ID to the common pool. 4. X11 client spawns Wayland client, sets ``$DESKTOP_STARTUP_ID`` in its environment. 5. Wayland client starts. 6. Wayland client requests surface activation with the activation token, as received from ``$DESKTOP_STARTUP_ID``. 7. Compositor receives the request, matches ID with the common pool 8. The startup feedback is finished. 9. Compositor applies internal policies to allow/deny focus switch. Caveats ------- - For legacy reasons, the usage of ``$DESKTOP_STARTUP_ID`` (even if as a fallback) should be observed in compositors and clients that are concerned with X11 interoperation. - Depending on the X11 startup-notification implementation in use by the compositor, the usage of the ``_TIME[timestamp]`` suffix may be mandatory for its correct behavior in the first scenario, the startup-notification reference library is one such implementation. Compositors may work this around by adding a matching suffix to the generated activation tokens. wl-mirror-0.16.5/proto/wayland-protocols/staging/xdg-activation/xdg-activation-v1.xml0000644000175000017500000002147014646472005027453 0ustar yrlfyrlf Copyright © 2020 Aleix Pol Gonzalez <aleixpol@kde.org> Copyright © 2020 Carlos Garnacho <carlosg@gnome.org> 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. The way for a client to pass focus to another toplevel is as follows. The client that intends to activate another toplevel uses the xdg_activation_v1.get_activation_token request to get an activation token. This token is then forwarded to the client, which is supposed to activate one of its surfaces, through a separate band of communication. One established way of doing this is through the XDG_ACTIVATION_TOKEN environment variable of a newly launched child process. The child process should unset the environment variable again right after reading it out in order to avoid propagating it to other child processes. Another established way exists for Applications implementing the D-Bus interface org.freedesktop.Application, which should get their token under activation-token on their platform_data. In general activation tokens may be transferred across clients through means not described in this protocol. The client to be activated will then pass the token it received to the xdg_activation_v1.activate request. The compositor can then use this token to decide how to react to the activation request. The token the activating client gets may be ineffective either already at the time it receives it, for example if it was not focused, for focus stealing prevention. The activating client will have no way to discover the validity of the token, and may still forward it to the to be activated client. The created activation token may optionally get information attached to it that can be used by the compositor to identify the application that we intend to activate. This can for example be used to display a visual hint about what application is being started. Warning! The protocol described in this file is currently in the testing phase. Backward compatible changes may be added together with the corresponding interface version bump. Backward incompatible changes can only be done by creating a new major version of the extension. A global interface used for informing the compositor about applications being activated or started, or for applications to request to be activated. Notify the compositor that the xdg_activation object will no longer be used. The child objects created via this interface are unaffected and should be destroyed separately. Creates an xdg_activation_token_v1 object that will provide the initiating client with a unique token for this activation. This token should be offered to the clients to be activated. Requests surface activation. It's up to the compositor to display this information as desired, for example by placing the surface above the rest. The compositor may know who requested this by checking the activation token and might decide not to follow through with the activation if it's considered unwanted. Compositors can ignore unknown activation tokens when an invalid token is passed. An object for setting up a token and receiving a token handle that can be passed as an activation token to another client. The object is created using the xdg_activation_v1.get_activation_token request. This object should then be populated with the app_id, surface and serial information and committed. The compositor shall then issue a done event with the token. In case the request's parameters are invalid, the compositor will provide an invalid token. Provides information about the seat and serial event that requested the token. The serial can come from an input or focus event. For instance, if a click triggers the launch of a third-party client, the launcher client should send a set_serial request with the serial and seat from the wl_pointer.button event. Some compositors might refuse to activate toplevels when the token doesn't have a valid and recent enough event serial. Must be sent before commit. This information is optional. The requesting client can specify an app_id to associate the token being created with it. Must be sent before commit. This information is optional. This request sets the surface requesting the activation. Note, this is different from the surface that will be activated. Some compositors might refuse to activate toplevels when the token doesn't have a requesting surface. Must be sent before commit. This information is optional. Requests an activation token based on the different parameters that have been offered through set_serial, set_surface and set_app_id. The 'done' event contains the unique token of this activation request and notifies that the provider is done. Notify the compositor that the xdg_activation_token_v1 object will no longer be used. The received token stays valid. wl-mirror-0.16.5/proto/wayland-protocols/staging/xwayland-shell/0000755000175000017500000000000014646472005023473 5ustar yrlfyrlfwl-mirror-0.16.5/proto/wayland-protocols/staging/xwayland-shell/README0000644000175000017500000000010714646472005024351 0ustar yrlfyrlfXwayland shell protocol Maintainers: Joshua Ashton wl-mirror-0.16.5/proto/wayland-protocols/staging/xwayland-shell/xwayland-shell-v1.xml0000644000175000017500000001672614646472005027511 0ustar yrlfyrlf Copyright © 2022 Joshua Ashton 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. This protocol adds a xwayland_surface role which allows an Xwayland server to associate an X11 window to a wl_surface. Before this protocol, this would be done via the Xwayland server providing the wl_surface's resource id via the a client message with the WL_SURFACE_ID atom on the X window. This was problematic as a race could occur if the wl_surface associated with a WL_SURFACE_ID for a window was destroyed before the client message was processed by the compositor and another surface (or other object) had taken its id due to recycling. This protocol solves the problem by moving the X11 window to wl_surface association step to the Wayland side, which means that the association cannot happen out-of-sync with the resource lifetime of the wl_surface. This protocol avoids duplicating the race on the other side by adding a non-zero monotonic serial number which is entirely unique that is set on both the wl_surface (via. xwayland_surface_v1's set_serial method) and the X11 window (via. the `WL_SURFACE_SERIAL` client message) that can be used to associate them, and synchronize the two timelines. The key words "must", "must not", "required", "shall", "shall not", "should", "should not", "recommended", "may", and "optional" in this document are to be interpreted as described in IETF RFC 2119. Warning! The protocol described in this file is currently in the testing phase. Backward compatible changes may be added together with the corresponding interface version bump. Backward incompatible changes can only be done by creating a new major version of the extension. xwayland_shell_v1 is a singleton global object that provides the ability to create a xwayland_surface_v1 object for a given wl_surface. This interface is intended to be bound by the Xwayland server. A compositor must not allow clients other than Xwayland to bind to this interface. A compositor should hide this global from other clients' wl_registry. A client the compositor does not consider to be an Xwayland server attempting to bind this interface will result in an implementation-defined error. An Xwayland server that has bound this interface must not set the `WL_SURFACE_ID` atom on a window. Destroy the xwayland_shell_v1 object. The child objects created via this interface are unaffected. Create an xwayland_surface_v1 interface for a given wl_surface object and gives it the xwayland_surface role. It is illegal to create an xwayland_surface_v1 for a wl_surface which already has an assigned role and this will result in the `role` protocol error. See the documentation of xwayland_surface_v1 for more details about what an xwayland_surface_v1 is and how it is used. An Xwayland surface is a surface managed by an Xwayland server. It is used for associating surfaces to Xwayland windows. The Xwayland server associated with actions in this interface is determined by the Wayland client making the request. The client must call wl_surface.commit on the corresponding wl_surface for the xwayland_surface_v1 state to take effect. Associates an Xwayland window to a wl_surface. The association state is double-buffered and will be applied at the time wl_surface.commit of the corresponding wl_surface is called. The `serial_lo` and `serial_hi` parameters specify a non-zero monotonic serial number which is entirely unique and provided by the Xwayland server equal to the serial value provided by a client message with a message type of the `WL_SURFACE_SERIAL` atom on the X11 window for this surface to be associated to. The serial value in the `WL_SURFACE_SERIAL` client message is specified as having the lo-bits specified in `l[0]` and the hi-bits specified in `l[1]`. If the serial value provided by `serial_lo` and `serial_hi` is not valid, the `invalid_serial` protocol error will be raised. An X11 window may be associated with multiple surfaces throughout its lifespan. (eg. unmapping and remapping a window). For each wl_surface, this state must not be committed more than once, otherwise the `already_associated` protocol error will be raised. Destroy the xwayland_surface_v1 object. Any already existing associations are unaffected by this action. wl-mirror-0.16.5/proto/wayland-protocols/tests/0000755000175000017500000000000014646472005020245 5ustar yrlfyrlfwl-mirror-0.16.5/proto/wayland-protocols/tests/build-cxx.cc.in0000644000175000017500000000032514646472005023060 0ustar yrlfyrlf#include "@PROTOCOL_CLIENT_INCLUDE_FILE@" #include "@PROTOCOL_SERVER_INCLUDE_FILE@" /* This is a build-test only */ using namespace std; int main(int argc, char **argv) { (void)argc; (void)argv; return 0; } wl-mirror-0.16.5/proto/wayland-protocols/tests/build-pedantic.c.in0000644000175000017500000000027714646472005023710 0ustar yrlfyrlf#include "@PROTOCOL_CLIENT_INCLUDE_FILE@" #include "@PROTOCOL_SERVER_INCLUDE_FILE@" /* This is a build-test only */ int main(int argc, char **argv) { (void)argc; (void)argv; return 0; } wl-mirror-0.16.5/proto/wayland-protocols/tests/meson.build0000644000175000017500000000663614646472005022422 0ustar yrlfyrlfprog_scan_sh = find_program('scan.sh') dep_scanner = dependency('wayland-scanner', version: '>=1.20.0', native: true, fallback: 'wayland') prog_scanner = find_program(dep_scanner.get_variable(pkgconfig: 'wayland_scanner', internal: 'wayland_scanner')) libwayland = [ dependency('wayland-client'), dependency('wayland-server'), ] # Check that each protocol passes through the scanner foreach protocol_file : protocol_files protocol_path = join_paths(wayland_protocols_srcdir, protocol_file) test_name = 'scan-@0@'.format(protocol_file.underscorify()) test(test_name, prog_scan_sh, args: protocol_path, env: [ 'SCANNER=@0@'.format(prog_scanner.full_path()), ] ) endforeach # Check buildability add_languages('c', 'cpp', native: false) replace = find_program('replace.py') extra_linker_flags = meson.get_compiler('c').get_supported_link_arguments([ '-Wl,--unresolved-symbols=ignore-all', ]) foreach protocol_file : protocol_files xml_file = fs.name(protocol_file) xml_components = xml_file.split('.') protocol_base_file_name = xml_components[0] protocol_path = files(join_paths(wayland_protocols_srcdir, protocol_file)) client_header_path = '@0@-client.h'.format(protocol_base_file_name) server_header_path = '@0@-server.h'.format(protocol_base_file_name) code_path = '@0@-code.c'.format(protocol_base_file_name) client_header = custom_target( client_header_path, output: client_header_path, input: protocol_path, command: [ prog_scanner, '--strict', 'client-header', '@INPUT@', '@OUTPUT@', ], install: false, ) server_header = custom_target( server_header_path, output: server_header_path, input: protocol_path, command: [ prog_scanner, '--strict', 'server-header', '@INPUT@', '@OUTPUT@', ], install: false, ) code = custom_target( code_path, output: code_path, input: protocol_path, command: [ prog_scanner, '--strict', 'private-code', '@INPUT@', '@OUTPUT@', ], install: false, ) replace_command = [ replace, '@INPUT@', '@OUTPUT@', 'PROTOCOL_CLIENT_INCLUDE_FILE', client_header.full_path(), 'PROTOCOL_SERVER_INCLUDE_FILE', server_header.full_path(), ] # Check that header can be included by a pedantic C99 compiler test_name = 'test-build-pedantic-@0@'.format(protocol_file.underscorify()) test_name_source = '@0@.c'.format(test_name) test_source = custom_target( test_name_source, input: 'build-pedantic.c.in', output: test_name_source, command: replace_command, ) pedantic_test_executable = executable( test_name, [ test_source, client_header, server_header, code ], link_args: extra_linker_flags, dependencies: libwayland, c_args: [ '-std=c99', '-pedantic', '-Wall', '-Werror' ], install: false, ) test(test_name, pedantic_test_executable) # Check that the header if not protocol_file.contains('xdg-foreign-unstable-v1') test_name = 'test-build-cxx-@0@'.format(protocol_file.underscorify()) test_name_source = '@0@.cc'.format(test_name) test_source = custom_target( test_name_source, input: 'build-cxx.cc.in', output: test_name_source, command: replace_command, ) cxx_test_executable = executable( test_name, [ test_source, client_header, server_header, ], link_args: extra_linker_flags, dependencies: libwayland, cpp_args: [ '-Wall', '-Werror', ], install: false, ) test(test_name, cxx_test_executable) endif endforeach wl-mirror-0.16.5/proto/wayland-protocols/tests/replace.py0000755000175000017500000000064014646472005022235 0ustar yrlfyrlf#!/usr/bin/env python3 import sys execpath, inpath, outpath, *dict_list = sys.argv dictonary = {} while dict_list: key, value, *rest = dict_list dictonary[key] = value dict_list = rest infile = open(inpath, 'r') outfile = open(outpath, 'w') buf = infile.read() infile.close() for key, value in dictonary.items(): buf = buf.replace('@{}@'.format(key), value) outfile.write(buf) outfile.close() wl-mirror-0.16.5/proto/wayland-protocols/tests/scan.sh0000755000175000017500000000043314646472005021530 0ustar yrlfyrlf#!/bin/sh -e if [ "x$SCANNER" = "x" ] ; then echo "No scanner present, test skipped." 1>&2 exit 77 fi $SCANNER client-header --strict $1 /dev/null $SCANNER server-header --strict $1 /dev/null $SCANNER private-code --strict $1 /dev/null $SCANNER public-code --strict $1 /dev/null wl-mirror-0.16.5/proto/wayland-protocols/unstable/0000755000175000017500000000000014646472005020720 5ustar yrlfyrlfwl-mirror-0.16.5/proto/wayland-protocols/unstable/fullscreen-shell/0000755000175000017500000000000014646472005024167 5ustar yrlfyrlfwl-mirror-0.16.5/proto/wayland-protocols/unstable/fullscreen-shell/README0000644000175000017500000000011614646472005025045 0ustar yrlfyrlfFullscreen shell protocol Maintainers: Jason Ekstrand wl-mirror-0.16.5/proto/wayland-protocols/unstable/fullscreen-shell/fullscreen-shell-unstable-v1.xml0000644000175000017500000002776014646472005032333 0ustar yrlfyrlf Copyright © 2016 Yong Bakos Copyright © 2015 Jason Ekstrand Copyright © 2015 Jonas Ådahl 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. Displays a single surface per output. This interface provides a mechanism for a single client to display simple full-screen surfaces. While there technically may be multiple clients bound to this interface, only one of those clients should be shown at a time. To present a surface, the client uses either the present_surface or present_surface_for_mode requests. Presenting a surface takes effect on the next wl_surface.commit. See the individual requests for details about scaling and mode switches. The client can have at most one surface per output at any time. Requesting a surface to be presented on an output that already has a surface replaces the previously presented surface. Presenting a null surface removes its content and effectively disables the output. Exactly what happens when an output is "disabled" is compositor-specific. The same surface may be presented on multiple outputs simultaneously. Once a surface is presented on an output, it stays on that output until either the client removes it or the compositor destroys the output. This way, the client can update the output's contents by simply attaching a new buffer. 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. Release the binding from the wl_fullscreen_shell interface. This destroys the server-side object and frees this binding. If the client binds to wl_fullscreen_shell multiple times, it may wish to free some of those bindings. Various capabilities that can be advertised by the compositor. They are advertised one-at-a-time when the wl_fullscreen_shell interface is bound. See the wl_fullscreen_shell.capability event for more details. ARBITRARY_MODES: This is a hint to the client that indicates that the compositor is capable of setting practically any mode on its outputs. If this capability is provided, wl_fullscreen_shell.present_surface_for_mode will almost never fail and clients should feel free to set whatever mode they like. If the compositor does not advertise this, it may still support some modes that are not advertised through wl_global.mode but it is less likely. CURSOR_PLANE: This is a hint to the client that indicates that the compositor can handle a cursor surface from the client without actually compositing. This may be because of a hardware cursor plane or some other mechanism. If the compositor does not advertise this capability then setting wl_pointer.cursor may degrade performance or be ignored entirely. If CURSOR_PLANE is not advertised, it is recommended that the client draw its own cursor and set wl_pointer.cursor(NULL). Advertises a single capability of the compositor. When the wl_fullscreen_shell interface is bound, this event is emitted once for each capability advertised. Valid capabilities are given by the wl_fullscreen_shell.capability enum. If clients want to take advantage of any of these capabilities, they should use a wl_display.sync request immediately after binding to ensure that they receive all the capability events. Hints to indicate to the compositor how to deal with a conflict between the dimensions of the surface and the dimensions of the output. The compositor is free to ignore this parameter. Present a surface on the given output. If the output is null, the compositor will present the surface on whatever display (or displays) it thinks best. In particular, this may replace any or all surfaces currently presented so it should not be used in combination with placing surfaces on specific outputs. The method parameter is a hint to the compositor for how the surface is to be presented. In particular, it tells the compositor how to handle a size mismatch between the presented surface and the output. The compositor is free to ignore this parameter. The "zoom", "zoom_crop", and "stretch" methods imply a scaling operation on the surface. This will override any kind of output scaling, so the buffer_scale property of the surface is effectively ignored. This request gives the surface the role of a fullscreen shell surface. If the surface already has another role, it raises a role protocol error. Presents a surface on the given output for a particular mode. If the current size of the output differs from that of the surface, the compositor will attempt to change the size of the output to match the surface. The result of the mode-switch operation will be returned via the provided wl_fullscreen_shell_mode_feedback object. If the current output mode matches the one requested or if the compositor successfully switches the mode to match the surface, then the mode_successful event will be sent and the output will contain the contents of the given surface. If the compositor cannot match the output size to the surface size, the mode_failed will be sent and the output will contain the contents of the previously presented surface (if any). If another surface is presented on the given output before either of these has a chance to happen, the present_cancelled event will be sent. Due to race conditions and other issues unknown to the client, no mode-switch operation is guaranteed to succeed. However, if the mode is one advertised by wl_output.mode or if the compositor advertises the ARBITRARY_MODES capability, then the client should expect that the mode-switch operation will usually succeed. If the size of the presented surface changes, the resulting output is undefined. The compositor may attempt to change the output mode to compensate. However, there is no guarantee that a suitable mode will be found and the client has no way to be notified of success or failure. The framerate parameter specifies the desired framerate for the output in mHz. The compositor is free to ignore this parameter. A value of 0 indicates that the client has no preference. If the value of wl_output.scale differs from wl_surface.buffer_scale, then the compositor may choose a mode that matches either the buffer size or the surface size. In either case, the surface will fill the output. This request gives the surface the role of a fullscreen shell surface. If the surface already has another role, it raises a role protocol error. These errors can be emitted in response to wl_fullscreen_shell requests. This event indicates that the attempted mode switch operation was successful. A surface of the size requested in the mode switch will fill the output without scaling. Upon receiving this event, the client should destroy the wl_fullscreen_shell_mode_feedback object. This event indicates that the attempted mode switch operation failed. This may be because the requested output mode is not possible or it may mean that the compositor does not want to allow it. Upon receiving this event, the client should destroy the wl_fullscreen_shell_mode_feedback object. This event indicates that the attempted mode switch operation was cancelled. Most likely this is because the client requested a second mode switch before the first one completed. Upon receiving this event, the client should destroy the wl_fullscreen_shell_mode_feedback object. wl-mirror-0.16.5/proto/wayland-protocols/unstable/idle-inhibit/0000755000175000017500000000000014646472005023261 5ustar yrlfyrlfwl-mirror-0.16.5/proto/wayland-protocols/unstable/idle-inhibit/README0000644000175000017500000000012714646472005024141 0ustar yrlfyrlfScreensaver inhibition protocol Maintainers: Bryce Harrington wl-mirror-0.16.5/proto/wayland-protocols/unstable/idle-inhibit/idle-inhibit-unstable-v1.xml0000644000175000017500000000766114646472005030515 0ustar yrlfyrlf Copyright © 2015 Samsung Electronics Co., Ltd 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. This interface permits inhibiting the idle behavior such as screen blanking, locking, and screensaving. The client binds the idle manager globally, then creates idle-inhibitor objects for each surface. 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. Destroy the inhibit manager. Create a new inhibitor object associated with the given surface. An idle inhibitor prevents the output that the associated surface is visible on from being set to a state where it is not visually usable due to lack of user interaction (e.g. blanked, dimmed, locked, set to power save, etc.) Any screensaver processes are also blocked from displaying. If the surface is destroyed, unmapped, becomes occluded, loses visibility, or otherwise becomes not visually relevant for the user, the idle inhibitor will not be honored by the compositor; if the surface subsequently regains visibility the inhibitor takes effect once again. Likewise, the inhibitor isn't honored if the system was already idled at the time the inhibitor was established, although if the system later de-idles and re-idles the inhibitor will take effect. Remove the inhibitor effect from the associated wl_surface. wl-mirror-0.16.5/proto/wayland-protocols/unstable/input-method/0000755000175000017500000000000014646472005023335 5ustar yrlfyrlfwl-mirror-0.16.5/proto/wayland-protocols/unstable/input-method/README0000644000175000017500000000011214646472005024207 0ustar yrlfyrlfInput method protocol Maintainers: Jan Arne Petersen wl-mirror-0.16.5/proto/wayland-protocols/unstable/input-method/input-method-unstable-v1.xml0000644000175000017500000003052114646472005030634 0ustar yrlfyrlf Copyright © 2012, 2013 Intel Corporation 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. Corresponds to a text input on the input method side. An input method context is created on text input activation on the input method side. It allows receiving information about the text input from the application via events. Input method contexts do not keep state after deactivation and should be destroyed after deactivation is handled. Text is generally UTF-8 encoded, indices and lengths are in bytes. Serials are used to synchronize the state between the text input and an input method. New serials are sent by the text input in the commit_state request and are used by the input method to indicate the known text input state in events like preedit_string, commit_string, and keysym. The text input can then ignore events from the input method which are based on an outdated state (for example after a reset). 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. Send the commit string text for insertion to the application. The text to commit could be either just a single character after a key press or the result of some composing (pre-edit). It could be also an empty text when some text should be removed (see delete_surrounding_text) or when the input cursor should be moved (see cursor_position). Any previously set composing text will be removed. Send the pre-edit string text to the application text input. The commit text can be used to replace the pre-edit text on reset (for example on unfocus). Previously sent preedit_style and preedit_cursor requests are also processed by the text_input. Set the styling information on composing text. The style is applied for length in bytes from index relative to the beginning of the composing text (as byte offset). Multiple styles can be applied to a composing text. This request should be sent before sending a preedit_string request. Set the cursor position inside the composing text (as byte offset) relative to the start of the composing text. When index is negative no cursor should be displayed. This request should be sent before sending a preedit_string request. Remove the surrounding text. This request will be handled on the text_input side directly following a commit_string request. Set the cursor and anchor to a new position. Index is the new cursor position in bytes (when >= 0 this is relative to the end of the inserted text, otherwise it is relative to the beginning of the inserted text). Anchor is the new anchor position in bytes (when >= 0 this is relative to the end of the inserted text, otherwise it is relative to the beginning of the inserted text). When there should be no selected text, anchor should be the same as index. This request will be handled on the text_input side directly following a commit_string request. Notify when a key event was sent. Key events should not be used for normal text input operations, which should be done with commit_string, delete_surrounding_text, etc. The key event follows the wl_keyboard key event convention. Sym is an XKB keysym, state is a wl_keyboard key_state. Allow an input method to receive hardware keyboard input and process key events to generate text events (with pre-edit) over the wire. This allows input methods which compose multiple key events for inputting text like it is done for CJK languages. Forward a wl_keyboard::key event to the client that was not processed by the input method itself. Should be used when filtering key events with grab_keyboard. The arguments should be the ones from the wl_keyboard::key event. For generating custom key events use the keysym request instead. Forward a wl_keyboard::modifiers event to the client that was not processed by the input method itself. Should be used when filtering key events with grab_keyboard. The arguments should be the ones from the wl_keyboard::modifiers event. The plain surrounding text around the input position. Cursor is the position in bytes within the surrounding text relative to the beginning of the text. Anchor is the position in bytes of the selection anchor within the surrounding text relative to the beginning of the text. If there is no selected text then anchor is the same as cursor. An input method object is responsible for composing text in response to input from hardware or virtual keyboards. There is one input method object per seat. On activate there is a new input method context object created which allows the input method to communicate with the text input. A text input was activated. Creates an input method context object which allows communication with the text input. The text input corresponding to the context argument was deactivated. The input method context should be destroyed after deactivation is handled. Only one client can bind this interface at a time. Set the input_panel_surface type to keyboard. A keyboard surface is only shown when a text input is active. Set the input_panel_surface to be an overlay panel. This is shown near the input cursor above the application window when a text input is active. wl-mirror-0.16.5/proto/wayland-protocols/unstable/input-timestamps/0000755000175000017500000000000014646472005024243 5ustar yrlfyrlfwl-mirror-0.16.5/proto/wayland-protocols/unstable/input-timestamps/README0000644000175000017500000000016314646472005025123 0ustar yrlfyrlfHigh-resolution timestamps for input events. Maintainers: Alexandros Frantzis wl-mirror-0.16.5/proto/wayland-protocols/unstable/input-timestamps/input-timestamps-unstable-v1.xml0000644000175000017500000001573114646472005032456 0ustar yrlfyrlf Copyright © 2017 Collabora, Ltd. 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. This protocol specifies a way for a client to request and receive high-resolution timestamps for input events. 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. A global interface used for requesting high-resolution timestamps for input events. Informs the server that the client will no longer be using this protocol object. Existing objects created by this object are not affected. Creates a new input timestamps object that represents a subscription to high-resolution timestamp events for all wl_keyboard events that carry a timestamp. If the associated wl_keyboard object is invalidated, either through client action (e.g. release) or server-side changes, the input timestamps object becomes inert and the client should destroy it by calling zwp_input_timestamps_v1.destroy. Creates a new input timestamps object that represents a subscription to high-resolution timestamp events for all wl_pointer events that carry a timestamp. If the associated wl_pointer object is invalidated, either through client action (e.g. release) or server-side changes, the input timestamps object becomes inert and the client should destroy it by calling zwp_input_timestamps_v1.destroy. Creates a new input timestamps object that represents a subscription to high-resolution timestamp events for all wl_touch events that carry a timestamp. If the associated wl_touch object becomes invalid, either through client action (e.g. release) or server-side changes, the input timestamps object becomes inert and the client should destroy it by calling zwp_input_timestamps_v1.destroy. Provides high-resolution timestamp events for a set of subscribed input events. The set of subscribed input events is determined by the zwp_input_timestamps_manager_v1 request used to create this object. Informs the server that the client will no longer be using this protocol object. After the server processes the request, no more timestamp events will be emitted. The timestamp event is associated with the first subsequent input event carrying a timestamp which belongs to the set of input events this object is subscribed to. The timestamp provided by this event is a high-resolution version of the timestamp argument of the associated input event. The provided timestamp is in the same clock domain and is at least as accurate as the associated input event timestamp. The timestamp is expressed as tv_sec_hi, tv_sec_lo, tv_nsec triples, each component being an unsigned 32-bit value. Whole seconds are in tv_sec which is a 64-bit value combined from tv_sec_hi and tv_sec_lo, and the additional fractional part in tv_nsec as nanoseconds. Hence, for valid timestamps tv_nsec must be in [0, 999999999]. wl-mirror-0.16.5/proto/wayland-protocols/unstable/keyboard-shortcuts-inhibit/0000755000175000017500000000000014646472005026200 5ustar yrlfyrlfwl-mirror-0.16.5/proto/wayland-protocols/unstable/keyboard-shortcuts-inhibit/README0000644000175000017500000000013214646472005027054 0ustar yrlfyrlfCompositor shortcuts inhibit protocol Maintainers: Olivier Fourdan ././@LongLink0000644000000000000000000000017000000000000011601 Lustar rootrootwl-mirror-0.16.5/proto/wayland-protocols/unstable/keyboard-shortcuts-inhibit/keyboard-shortcuts-inhibit-unstable-v1.xmlwl-mirror-0.16.5/proto/wayland-protocols/unstable/keyboard-shortcuts-inhibit/keyboard-shortcuts-inhi0000644000175000017500000001476514646472005032721 0ustar yrlfyrlf 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. This protocol specifies a way for a client to request the compositor to ignore its own keyboard shortcuts for a given seat, so that all key events from that seat get forwarded to a surface. 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. A global interface used for inhibiting the compositor keyboard shortcuts. Destroy the keyboard shortcuts inhibitor manager. Create a new keyboard shortcuts inhibitor object associated with the given surface for the given seat. If shortcuts are already inhibited for the specified seat and surface, a protocol error "already_inhibited" is raised by the compositor. A keyboard shortcuts inhibitor instructs the compositor to ignore its own keyboard shortcuts when the associated surface has keyboard focus. As a result, when the surface has keyboard focus on the given seat, it will receive all key events originating from the specified seat, even those which would normally be caught by the compositor for its own shortcuts. The Wayland compositor is however under no obligation to disable all of its shortcuts, and may keep some special key combo for its own use, including but not limited to one allowing the user to forcibly restore normal keyboard events routing in the case of an unwilling client. The compositor may also use the same key combo to reactivate an existing shortcut inhibitor that was previously deactivated on user request. When the compositor restores its own keyboard shortcuts, an "inactive" event is emitted to notify the client that the keyboard shortcuts inhibitor is not effectively active for the surface and seat any more, and the client should not expect to receive all keyboard events. When the keyboard shortcuts inhibitor is inactive, the client has no way to forcibly reactivate the keyboard shortcuts inhibitor. The user can chose to re-enable a previously deactivated keyboard shortcuts inhibitor using any mechanism the compositor may offer, in which case the compositor will send an "active" event to notify the client. If the surface is destroyed, unmapped, or loses the seat's keyboard focus, the keyboard shortcuts inhibitor becomes irrelevant and the compositor will restore its own keyboard shortcuts but no "inactive" event is emitted in this case. Remove the keyboard shortcuts inhibitor from the associated wl_surface. This event indicates that the shortcut inhibitor is active. The compositor sends this event every time compositor shortcuts are inhibited on behalf of the surface. When active, the client may receive input events normally reserved by the compositor (see zwp_keyboard_shortcuts_inhibitor_v1). This occurs typically when the initial request "inhibit_shortcuts" first becomes active or when the user instructs the compositor to re-enable and existing shortcuts inhibitor using any mechanism offered by the compositor. This event indicates that the shortcuts inhibitor is inactive, normal shortcuts processing is restored by the compositor. wl-mirror-0.16.5/proto/wayland-protocols/unstable/linux-dmabuf/0000755000175000017500000000000014646472005023313 5ustar yrlfyrlfwl-mirror-0.16.5/proto/wayland-protocols/unstable/linux-dmabuf/README0000644000175000017500000000017214646472005024173 0ustar yrlfyrlfLinux DMA-BUF protocol Maintainers: Pekka Paalanen Daniel Stone wl-mirror-0.16.5/proto/wayland-protocols/unstable/linux-dmabuf/feedback.rst0000644000175000017500000002455014646472005025577 0ustar yrlfyrlf.. Copyright 2021 Simon Ser .. contents:: linux-dmabuf feedback introduction ================================== linux-dmabuf feedback allows compositors and clients to negotiate optimal buffer allocation parameters. This document will assume that the compositor is using a rendering API such as OpenGL or Vulkan and KMS as the presentation API: even if linux-dmabuf feedback isn't restricted to this use-case, it's the most common. linux-dmabuf feedback introduces the following concepts: 1. A main device. This is the render device that the compositor is using to perform composition. Compositors should always be able to display a buffer submitted by a client, so this device can be used as a fallback in case none of the more optimized code-paths work. Clients should allocate buffers such that they can be imported and textured from the main device. 2. One or more tranches. Each tranche consists of a target device, allocation flags and a set of format/modifier pairs. A tranche can be seen as a set of formats/modifier pairs that are compatible with the target device. A tranche can have the ``scanout`` flag. It means that the target device is a KMS device, and that buffers allocated with one of the format/modifier pairs in the tranche are eligible for direct scanout. Clients should use the tranches in order to allocate buffers with the most appropriate format/modifier and also to avoid allocating in private device memory when cross-device operations are going to happen. linux-dmabuf feedback implementation notes ========================================== This section contains recommendations for client and compositor implementations. For clients ----------- Clients are expected to either pick a fixed DRM format beforehand, or perform the following steps repeatedly until they find a suitable format. Basic clients may only support static buffer allocation on startup. These clients should do the following: 1. Send a ``get_default_feedback`` request to get global feedback. 2. Select the device indicated by ``main_device`` for allocation. 3. For each tranche: 1. If ``tranche_target_device`` doesn't match the allocation device, ignore the tranche. 2. Accumulate allocation flags from ``tranche_flags``. 3. Accumulate format/modifier pairs received via ``tranche_formats`` in a list. 4. When the ``tranche_done`` event is received, try to allocate the buffer with the accumulated list of modifiers and allocation flags. If that fails, proceed with the next tranche. If that succeeds, stop the loop. 4. Destroy the feedback object. Tranches are ordered by preference: the more optimized tranches come first. As such, clients should use the first tranche that happens to work. Some clients may have already selected the device they want to use beforehand. These clients can ignore the ``main_device`` event, and ignore tranches whose ``tranche_target_device`` doesn't match the selected device. Such clients need to be prepared for the ``wp_linux_buffer_params.create`` request to potentially fail. If the client allocates a buffer without specifying explicit modifiers on a device different from the one indicated by ``main_device``, then the client must force a linear layout. Some clients might support re-negotiating the buffer format/modifier on the fly. These clients should send a ``get_surface_feedback`` request and keep the feedback object alive after the initial allocation. Each time a new set of feedback parameters is received (ended by the ``done`` event), they should perform the same steps as basic clients described above. They should detect when the optimal allocation parameters didn't change (same format/modifier/flags) to avoid needlessly re-allocating their buffers. Some clients might additionally support switching the device used for allocations on the fly. Such clients should send a ``get_surface_feedback`` request. For each tranche, select the device indicated by ``tranche_target_device`` for allocation. Accumulate allocation flags (received via ``tranche_flags``) and format/modifier pairs (received via ``tranche_formats``) as usual. When the ``tranche_done`` event is received, try to allocate the buffer with the accumulated list of modifiers and the allocation flags. Try to import the resulting buffer by sending a ``wp_linux_buffer_params.create`` request (this might fail). Repeat with each tranche until an allocation and import succeeds. Each time a new set of feedback parameters is received, they should perform these steps again. They should detect when the optimal allocation parameters didn't change (same device/format/modifier/flags) to avoid needlessly re-allocating their buffers. For compositors --------------- Basic compositors may only support texturing the DMA-BUFs via a rendering API such as OpenGL or Vulkan. Such compositors can send a single tranche as a reply to both ``get_default_feedback`` and ``get_surface_feedback``. Set the ``main_device`` to the rendering device. Send the tranche with ``tranche_target_device`` set to the rendering device and all of the DRM format/modifier pairs supported by the rendering API. Do not set the ``scanout`` flag in the ``tranche_flags`` event. Some compositors may support direct scan-out for full-screen surfaces. These compositors can re-send the feedback parameters when a surface becomes full-screen or leaves full-screen mode if the client has used the ``get_surface_feedback`` request. The non-full-screen feedback parameters are the same as basic compositors described above. The full-screen feedback parameters have two tranches: one with the format/modifier pairs supported by the KMS plane, with the ``scanout`` flag set in the ``tranche_flags`` event and with ``tranche_target_device`` set to the KMS scan-out device; the other with the rest of the format/modifier pairs (supported for texturing, but not for scan-out), without the ``scanout`` flag set in the ``tranche_flags`` event, and with the ``tranche_target_device`` set to the rendering device. Some compositors may support direct scan-out for all surfaces. These compositors can send two tranches for surfaces that become candidates for direct scan-out, similarly to compositors supporting direct scan-out for fullscreen surfaces. When a surface stops being a candidate for direct scan-out, compositors should re-send the feedback parameters optimized for texturing only. The way candidates for direct scan-out are selected is compositor policy, a possible implementation is to select as many surfaces as there are available hardware planes, starting from surfaces closer to the eye. Some compositors may support multiple devices at the same time. If the compositor supports rendering with a fixed device and direct scan-out on a secondary device, it may send a separate tranche for surfaces displayed on the secondary device that are candidates for direct scan-out. The ``tranche_target_device`` for this tranche will be the secondary device and will not match the ``main_device``. Some compositors may support switching their rendering device at runtime or changing their rendering device depending on the surface. When the rendering device changes for a surface, such compositors may re-send the feedback parameters with a different ``main_device``. However there is a risk that clients don't support switching their device at runtime and continue using the previous device. For this reason, compositors should always have a fallback rendering device that they initially send as ``main_device``, such that these clients use said fallback device. Compositors should not change the ``main_device`` on-the-fly when explicit modifiers are not supported, because there's a risk of importing buffers with an implicit non-linear modifier as a linear buffer, resulting in misinterpreted buffer contents. Compositors should not send feedback parameters if they don't have a fallback path. For instance, compositors shouldn't send a format/modifier supported for direct scan-out but not supported by the rendering API for texturing. Compositors can decide to use multiple tranches to describe the allocation parameters optimized for texturing. For example, if there are formats which have a fast texturing path and formats which have a slower texturing path, the compositor can decide to expose two separate tranches. Compositors can decide to use intermediate tranches to describe code-paths slower than direct scan-out but faster than texturing. For instance, a compositor could insert an intermediate tranche if it's possible to use a mem2mem device to convert buffers to be able to use scan-out. ``dev_t`` encoding ================== The protocol carries ``dev_t`` values on the wire using arrays. A compositor written in C can encode the values as follows: .. code-block:: c struct stat drm_node_stat; struct wl_array dev_array = { .size = sizeof(drm_node_stat.st_rdev), .data = &drm_node_stat.st_rdev, }; A client can decode the values as follows: .. code-block:: c dev_t dev; assert(dev_array->size == sizeof(dev)); memcpy(&dev, dev_array->data, sizeof(dev)); Because two DRM nodes can refer to the same DRM device while having different ``dev_t`` values, clients should use ``drmDevicesEqual`` to compare two devices. ``format_table`` encoding ========================= The ``format_table`` event carries a file descriptor containing a list of format + modifier pairs. The list is an array of pairs which can be accessed with this C structure definition: .. code-block:: c struct dmabuf_format_modifier { uint32_t format; uint32_t pad; /* unused */ uint64_t modifier; }; Integration with other APIs =========================== - libdrm: ``drmGetDeviceFromDevId`` returns a ``drmDevice`` from a device ID. - EGL: the `EGL_EXT_device_drm_render_node`_ extension may be used to query the DRM device render node used by a given EGL display. When unavailable, the older `EGL_EXT_device_drm`_ extension may be used as a fallback. - Vulkan: the `VK_EXT_physical_device_drm`_ extension may be used to query the DRM device used by a given ``VkPhysicalDevice``. .. _EGL_EXT_device_drm: https://www.khronos.org/registry/EGL/extensions/EXT/EGL_EXT_device_drm.txt .. _EGL_EXT_device_drm_render_node: https://www.khronos.org/registry/EGL/extensions/EXT/EGL_EXT_device_drm_render_node.txt .. _VK_EXT_physical_device_drm: https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VK_EXT_physical_device_drm.html wl-mirror-0.16.5/proto/wayland-protocols/unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml0000644000175000017500000007011614646472005030574 0ustar yrlfyrlf Copyright © 2014, 2015 Collabora, Ltd. 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. Following the interfaces from: https://www.khronos.org/registry/egl/extensions/EXT/EGL_EXT_image_dma_buf_import.txt https://www.khronos.org/registry/EGL/extensions/EXT/EGL_EXT_image_dma_buf_import_modifiers.txt and the Linux DRM sub-system's AddFb2 ioctl. This interface offers ways to create generic dmabuf-based wl_buffers. Clients can use the get_surface_feedback request to get dmabuf feedback for a particular surface. If the client wants to retrieve feedback not tied to a surface, they can use the get_default_feedback request. The following are required from clients: - Clients must ensure that either all data in the dma-buf is coherent for all subsequent read access or that coherency is correctly handled by the underlying kernel-side dma-buf implementation. - Don't make any more attachments after sending the buffer to the compositor. Making more attachments later increases the risk of the compositor not being able to use (re-import) an existing dmabuf-based wl_buffer. The underlying graphics stack must ensure the following: - The dmabuf file descriptors relayed to the server will stay valid for the whole lifetime of the wl_buffer. This means the server may at any time use those fds to import the dmabuf into any kernel sub-system that might accept it. However, when the underlying graphics stack fails to deliver the promise, because of e.g. a device hot-unplug which raises internal errors, after the wl_buffer has been successfully created the compositor must not raise protocol errors to the client when dmabuf import later fails. To create a wl_buffer from one or more dmabufs, a client creates a zwp_linux_dmabuf_params_v1 object with a zwp_linux_dmabuf_v1.create_params request. All planes required by the intended format are added with the 'add' request. Finally, a 'create' or 'create_immed' request is issued, which has the following outcome depending on the import success. The 'create' request, - on success, triggers a 'created' event which provides the final wl_buffer to the client. - on failure, triggers a 'failed' event to convey that the server cannot use the dmabufs received from the client. For the 'create_immed' request, - on success, the server immediately imports the added dmabufs to create a wl_buffer. No event is sent from the server in this case. - on failure, the server can choose to either: - terminate the client by raising a fatal error. - mark the wl_buffer as failed, and send a 'failed' event to the client. If the client uses a failed wl_buffer as an argument to any request, the behaviour is compositor implementation-defined. For all DRM formats and unless specified in another protocol extension, pre-multiplied alpha is used for pixel values. 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. Objects created through this interface, especially wl_buffers, will remain valid. This temporary object is used to collect multiple dmabuf handles into a single batch to create a wl_buffer. It can only be used once and should be destroyed after a 'created' or 'failed' event has been received. This event advertises one buffer format that the server supports. All the supported formats are advertised once when the client binds to this interface. A roundtrip after binding guarantees that the client has received all supported formats. For the definition of the format codes, see the zwp_linux_buffer_params_v1::create request. Starting version 4, the format event is deprecated and must not be sent by compositors. Instead, use get_default_feedback or get_surface_feedback. This event advertises the formats that the server supports, along with the modifiers supported for each format. All the supported modifiers for all the supported formats are advertised once when the client binds to this interface. A roundtrip after binding guarantees that the client has received all supported format-modifier pairs. For legacy support, DRM_FORMAT_MOD_INVALID (that is, modifier_hi == 0x00ffffff and modifier_lo == 0xffffffff) is allowed in this event. It indicates that the server can support the format with an implicit modifier. When a plane has DRM_FORMAT_MOD_INVALID as its modifier, it is as if no explicit modifier is specified. The effective modifier will be derived from the dmabuf. A compositor that sends valid modifiers and DRM_FORMAT_MOD_INVALID for a given format supports both explicit modifiers and implicit modifiers. For the definition of the format and modifier codes, see the zwp_linux_buffer_params_v1::create and zwp_linux_buffer_params_v1::add requests. Starting version 4, the modifier event is deprecated and must not be sent by compositors. Instead, use get_default_feedback or get_surface_feedback. This request creates a new wp_linux_dmabuf_feedback object not bound to a particular surface. This object will deliver feedback about dmabuf parameters to use if the client doesn't support per-surface feedback (see get_surface_feedback). This request creates a new wp_linux_dmabuf_feedback object for the specified wl_surface. This object will deliver feedback about dmabuf parameters to use for buffers attached to this surface. If the surface is destroyed before the wp_linux_dmabuf_feedback object, the feedback object becomes inert. This temporary object is a collection of dmabufs and other parameters that together form a single logical buffer. The temporary object may eventually create one wl_buffer unless cancelled by destroying it before requesting 'create'. Single-planar formats only require one dmabuf, however multi-planar formats may require more than one dmabuf. For all formats, an 'add' request must be called once per plane (even if the underlying dmabuf fd is identical). You must use consecutive plane indices ('plane_idx' argument for 'add') from zero to the number of planes used by the drm_fourcc format code. All planes required by the format must be given exactly once, but can be given in any order. Each plane index can be set only once. Cleans up the temporary data sent to the server for dmabuf-based wl_buffer creation. This request adds one dmabuf to the set in this zwp_linux_buffer_params_v1. The 64-bit unsigned value combined from modifier_hi and modifier_lo is the dmabuf layout modifier. DRM AddFB2 ioctl calls this the fb modifier, which is defined in drm_mode.h of Linux UAPI. This is an opaque token. Drivers use this token to express tiling, compression, etc. driver-specific modifications to the base format defined by the DRM fourcc code. Starting from version 4, the invalid_format protocol error is sent if the format + modifier pair was not advertised as supported. This request raises the PLANE_IDX error if plane_idx is too large. The error PLANE_SET is raised if attempting to set a plane that was already set. This asks for creation of a wl_buffer from the added dmabuf buffers. The wl_buffer is not created immediately but returned via the 'created' event if the dmabuf sharing succeeds. The sharing may fail at runtime for reasons a client cannot predict, in which case the 'failed' event is triggered. The 'format' argument is a DRM_FORMAT code, as defined by the libdrm's drm_fourcc.h. The Linux kernel's DRM sub-system is the authoritative source on how the format codes should work. The 'flags' is a bitfield of the flags defined in enum "flags". 'y_invert' means the that the image needs to be y-flipped. Flag 'interlaced' means that the frame in the buffer is not progressive as usual, but interlaced. An interlaced buffer as supported here must always contain both top and bottom fields. The top field always begins on the first pixel row. The temporal ordering between the two fields is top field first, unless 'bottom_first' is specified. It is undefined whether 'bottom_first' is ignored if 'interlaced' is not set. This protocol does not convey any information about field rate, duration, or timing, other than the relative ordering between the two fields in one buffer. A compositor may have to estimate the intended field rate from the incoming buffer rate. It is undefined whether the time of receiving wl_surface.commit with a new buffer attached, applying the wl_surface state, wl_surface.frame callback trigger, presentation, or any other point in the compositor cycle is used to measure the frame or field times. There is no support for detecting missed or late frames/fields/buffers either, and there is no support whatsoever for cooperating with interlaced compositor output. The composited image quality resulting from the use of interlaced buffers is explicitly undefined. A compositor may use elaborate hardware features or software to deinterlace and create progressive output frames from a sequence of interlaced input buffers, or it may produce substandard image quality. However, compositors that cannot guarantee reasonable image quality in all cases are recommended to just reject all interlaced buffers. Any argument errors, including non-positive width or height, mismatch between the number of planes and the format, bad format, bad offset or stride, may be indicated by fatal protocol errors: INCOMPLETE, INVALID_FORMAT, INVALID_DIMENSIONS, OUT_OF_BOUNDS. Dmabuf import errors in the server that are not obvious client bugs are returned via the 'failed' event as non-fatal. This allows attempting dmabuf sharing and falling back in the client if it fails. This request can be sent only once in the object's lifetime, after which the only legal request is destroy. This object should be destroyed after issuing a 'create' request. Attempting to use this object after issuing 'create' raises ALREADY_USED protocol error. It is not mandatory to issue 'create'. If a client wants to cancel the buffer creation, it can just destroy this object. This event indicates that the attempted buffer creation was successful. It provides the new wl_buffer referencing the dmabuf(s). Upon receiving this event, the client should destroy the zwp_linux_buffer_params_v1 object. This event indicates that the attempted buffer creation has failed. It usually means that one of the dmabuf constraints has not been fulfilled. Upon receiving this event, the client should destroy the zwp_linux_buffer_params_v1 object. This asks for immediate creation of a wl_buffer by importing the added dmabufs. In case of import success, no event is sent from the server, and the wl_buffer is ready to be used by the client. Upon import failure, either of the following may happen, as seen fit by the implementation: - the client is terminated with one of the following fatal protocol errors: - INCOMPLETE, INVALID_FORMAT, INVALID_DIMENSIONS, OUT_OF_BOUNDS, in case of argument errors such as mismatch between the number of planes and the format, bad format, non-positive width or height, or bad offset or stride. - INVALID_WL_BUFFER, in case the cause for failure is unknown or plaform specific. - the server creates an invalid wl_buffer, marks it as failed and sends a 'failed' event to the client. The result of using this invalid wl_buffer as an argument in any request by the client is defined by the compositor implementation. This takes the same arguments as a 'create' request, and obeys the same restrictions. This object advertises dmabuf parameters feedback. This includes the preferred devices and the supported formats/modifiers. The parameters are sent once when this object is created and whenever they change. The done event is always sent once after all parameters have been sent. When a single parameter changes, all parameters are re-sent by the compositor. Compositors can re-send the parameters when the current client buffer allocations are sub-optimal. Compositors should not re-send the parameters if re-allocating the buffers would not result in a more optimal configuration. In particular, compositors should avoid sending the exact same parameters multiple times in a row. The tranche_target_device and tranche_formats events are grouped by tranches of preference. For each tranche, a tranche_target_device, one tranche_flags and one or more tranche_formats events are sent, followed by a tranche_done event finishing the list. The tranches are sent in descending order of preference. All formats and modifiers in the same tranche have the same preference. To send parameters, the compositor sends one main_device event, tranches (each consisting of one tranche_target_device event, one tranche_flags event, tranche_formats events and then a tranche_done event), then one done event. Using this request a client can tell the server that it is not going to use the wp_linux_dmabuf_feedback object anymore. This event is sent after all parameters of a wp_linux_dmabuf_feedback object have been sent. This allows changes to the wp_linux_dmabuf_feedback parameters to be seen as atomic, even if they happen via multiple events. This event provides a file descriptor which can be memory-mapped to access the format and modifier table. The table contains a tightly packed array of consecutive format + modifier pairs. Each pair is 16 bytes wide. It contains a format as a 32-bit unsigned integer, followed by 4 bytes of unused padding, and a modifier as a 64-bit unsigned integer. The native endianness is used. The client must map the file descriptor in read-only private mode. Compositors are not allowed to mutate the table file contents once this event has been sent. Instead, compositors must create a new, separate table file and re-send feedback parameters. Compositors are allowed to store duplicate format + modifier pairs in the table. This event advertises the main device that the server prefers to use when direct scan-out to the target device isn't possible. The advertised main device may be different for each wp_linux_dmabuf_feedback object, and may change over time. There is exactly one main device. The compositor must send at least one preference tranche with tranche_target_device equal to main_device. Clients need to create buffers that the main device can import and read from, otherwise creating the dmabuf wl_buffer will fail (see the wp_linux_buffer_params.create and create_immed requests for details). The main device will also likely be kept active by the compositor, so clients can use it instead of waking up another device for power savings. In general the device is a DRM node. The DRM node type (primary vs. render) is unspecified. Clients must not rely on the compositor sending a particular node type. Clients cannot check two devices for equality by comparing the dev_t value. If explicit modifiers are not supported and the client performs buffer allocations on a different device than the main device, then the client must force the buffer to have a linear layout. This event splits tranche_target_device and tranche_formats events in preference tranches. It is sent after a set of tranche_target_device and tranche_formats events; it represents the end of a tranche. The next tranche will have a lower preference. This event advertises the target device that the server prefers to use for a buffer created given this tranche. The advertised target device may be different for each preference tranche, and may change over time. There is exactly one target device per tranche. The target device may be a scan-out device, for example if the compositor prefers to directly scan-out a buffer created given this tranche. The target device may be a rendering device, for example if the compositor prefers to texture from said buffer. The client can use this hint to allocate the buffer in a way that makes it accessible from the target device, ideally directly. The buffer must still be accessible from the main device, either through direct import or through a potentially more expensive fallback path. If the buffer can't be directly imported from the main device then clients must be prepared for the compositor changing the tranche priority or making wl_buffer creation fail (see the wp_linux_buffer_params.create and create_immed requests for details). If the device is a DRM node, the DRM node type (primary vs. render) is unspecified. Clients must not rely on the compositor sending a particular node type. Clients cannot check two devices for equality by comparing the dev_t value. This event is tied to a preference tranche, see the tranche_done event. This event advertises the format + modifier combinations that the compositor supports. It carries an array of indices, each referring to a format + modifier pair in the last received format table (see the format_table event). Each index is a 16-bit unsigned integer in native endianness. For legacy support, DRM_FORMAT_MOD_INVALID is an allowed modifier. It indicates that the server can support the format with an implicit modifier. When a buffer has DRM_FORMAT_MOD_INVALID as its modifier, it is as if no explicit modifier is specified. The effective modifier will be derived from the dmabuf. A compositor that sends valid modifiers and DRM_FORMAT_MOD_INVALID for a given format supports both explicit modifiers and implicit modifiers. Compositors must not send duplicate format + modifier pairs within the same tranche or across two different tranches with the same target device and flags. This event is tied to a preference tranche, see the tranche_done event. For the definition of the format and modifier codes, see the wp_linux_buffer_params.create request. This event sets tranche-specific flags. The scanout flag is a hint that direct scan-out may be attempted by the compositor on the target device if the client appropriately allocates a buffer. How to allocate a buffer that can be scanned out on the target device is implementation-defined. This event is tied to a preference tranche, see the tranche_done event. wl-mirror-0.16.5/proto/wayland-protocols/unstable/linux-explicit-synchronization/0000755000175000017500000000000014646472005027135 5ustar yrlfyrlfwl-mirror-0.16.5/proto/wayland-protocols/unstable/linux-explicit-synchronization/README0000644000175000017500000000023714646472005030017 0ustar yrlfyrlfLinux explicit synchronization (dma-fence) protocol Maintainers: Daniel Stone Alexandros Frantzis ././@LongLink0000644000000000000000000000020000000000000011573 Lustar rootrootwl-mirror-0.16.5/proto/wayland-protocols/unstable/linux-explicit-synchronization/linux-explicit-synchronization-unstable-v1.xmlwl-mirror-0.16.5/proto/wayland-protocols/unstable/linux-explicit-synchronization/linux-explicit-sync0000644000175000017500000002717514646472005033024 0ustar yrlfyrlf Copyright 2016 The Chromium Authors. Copyright 2017 Intel Corporation Copyright 2018 Collabora, Ltd 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. This global is a factory interface, allowing clients to request explicit synchronization for buffers on a per-surface basis. See zwp_linux_surface_synchronization_v1 for more information. This interface is derived from Chromium's zcr_linux_explicit_synchronization_v1. 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. Destroy this explicit synchronization factory object. Other objects, including zwp_linux_surface_synchronization_v1 objects created by this factory, shall not be affected by this request. Instantiate an interface extension for the given wl_surface to provide explicit synchronization. If the given wl_surface already has an explicit synchronization object associated, the synchronization_exists protocol error is raised. Graphics APIs, like EGL or Vulkan, that manage the buffer queue and commits of a wl_surface themselves, are likely to be using this extension internally. If a client is using such an API for a wl_surface, it should not directly use this extension on that surface, to avoid raising a synchronization_exists protocol error. This object implements per-surface explicit synchronization. Synchronization refers to co-ordination of pipelined operations performed on buffers. Most GPU clients will schedule an asynchronous operation to render to the buffer, then immediately send the buffer to the compositor to be attached to a surface. In implicit synchronization, ensuring that the rendering operation is complete before the compositor displays the buffer is an implementation detail handled by either the kernel or userspace graphics driver. By contrast, in explicit synchronization, dma_fence objects mark when the asynchronous operations are complete. When submitting a buffer, the client provides an acquire fence which will be waited on before the compositor accesses the buffer. The Wayland server, through a zwp_linux_buffer_release_v1 object, will inform the client with an event which may be accompanied by a release fence, when the compositor will no longer access the buffer contents due to the specific commit that requested the release event. Each surface can be associated with only one object of this interface at any time. In version 1 of this interface, explicit synchronization is only guaranteed to be supported for buffers created with any version of the wp_linux_dmabuf buffer factory. Version 2 additionally guarantees explicit synchronization support for opaque EGL buffers, which is a type of platform specific buffers described in the EGL_WL_bind_wayland_display extension. Compositors are free to support explicit synchronization for additional buffer types. Destroy this explicit synchronization object. Any fence set by this object with set_acquire_fence since the last commit will be discarded by the server. Any fences set by this object before the last commit are not affected. zwp_linux_buffer_release_v1 objects created by this object are not affected by this request. Set the acquire fence that must be signaled before the compositor may sample from the buffer attached with wl_surface.attach. The fence is a dma_fence kernel object. The acquire fence is double-buffered state, and will be applied on the next wl_surface.commit request for the associated surface. Thus, it applies only to the buffer that is attached to the surface at commit time. If the provided fd is not a valid dma_fence fd, then an INVALID_FENCE error is raised. If a fence has already been attached during the same commit cycle, a DUPLICATE_FENCE error is raised. If the associated wl_surface was destroyed, a NO_SURFACE error is raised. If at surface commit time the attached buffer does not support explicit synchronization, an UNSUPPORTED_BUFFER error is raised. If at surface commit time there is no buffer attached, a NO_BUFFER error is raised. Create a listener for the release of the buffer attached by the client with wl_surface.attach. See zwp_linux_buffer_release_v1 documentation for more information. The release object is double-buffered state, and will be associated with the buffer that is attached to the surface at wl_surface.commit time. If a zwp_linux_buffer_release_v1 object has already been requested for the surface in the same commit cycle, a DUPLICATE_RELEASE error is raised. If the associated wl_surface was destroyed, a NO_SURFACE error is raised. If at surface commit time there is no buffer attached, a NO_BUFFER error is raised. This object is instantiated in response to a zwp_linux_surface_synchronization_v1.get_release request. It provides an alternative to wl_buffer.release events, providing a unique release from a single wl_surface.commit request. The release event also supports explicit synchronization, providing a fence FD for the client to synchronize against. Exactly one event, either a fenced_release or an immediate_release, will be emitted for the wl_surface.commit request. The compositor can choose release by release which event it uses. This event does not replace wl_buffer.release events; servers are still required to send those events. Once a buffer release object has delivered a 'fenced_release' or an 'immediate_release' event it is automatically destroyed. Sent when the compositor has finalised its usage of the associated buffer for the relevant commit, providing a dma_fence which will be signaled when all operations by the compositor on that buffer for that commit have finished. Once the fence has signaled, and assuming the associated buffer is not pending release from other wl_surface.commit requests, no additional explicit or implicit synchronization is required to safely reuse or destroy the buffer. This event destroys the zwp_linux_buffer_release_v1 object. Sent when the compositor has finalised its usage of the associated buffer for the relevant commit, and either performed no operations using it, or has a guarantee that all its operations on that buffer for that commit have finished. Once this event is received, and assuming the associated buffer is not pending release from other wl_surface.commit requests, no additional explicit or implicit synchronization is required to safely reuse or destroy the buffer. This event destroys the zwp_linux_buffer_release_v1 object. wl-mirror-0.16.5/proto/wayland-protocols/unstable/pointer-constraints/0000755000175000017500000000000014646472005024745 5ustar yrlfyrlfwl-mirror-0.16.5/proto/wayland-protocols/unstable/pointer-constraints/README0000644000175000017500000000011314646472005025620 0ustar yrlfyrlfPointer constraints protocol Maintainers: Jonas Ådahl ././@LongLink0000644000000000000000000000015200000000000011601 Lustar rootrootwl-mirror-0.16.5/proto/wayland-protocols/unstable/pointer-constraints/pointer-constraints-unstable-v1.xmlwl-mirror-0.16.5/proto/wayland-protocols/unstable/pointer-constraints/pointer-constraints-unstable-v0000644000175000017500000003613314646472005033001 0ustar yrlfyrlf Copyright © 2014 Jonas Ådahl Copyright © 2015 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. This protocol specifies a set of interfaces used for adding constraints to the motion of a pointer. Possible constraints include confining pointer motions to a given region, or locking it to its current position. In order to constrain the pointer, a client must first bind the global interface "wp_pointer_constraints" which, if a compositor supports pointer constraints, is exposed by the registry. Using the bound global object, the client uses the request that corresponds to the type of constraint it wants to make. See wp_pointer_constraints for more details. 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. The global interface exposing pointer constraining functionality. It exposes two requests: lock_pointer for locking the pointer to its position, and confine_pointer for locking the pointer to a region. The lock_pointer and confine_pointer requests create the objects wp_locked_pointer and wp_confined_pointer respectively, and the client can use these objects to interact with the lock. For any surface, only one lock or confinement may be active across all wl_pointer objects of the same seat. If a lock or confinement is requested when another lock or confinement is active or requested on the same surface and with any of the wl_pointer objects of the same seat, an 'already_constrained' error will be raised. These errors can be emitted in response to wp_pointer_constraints requests. These values represent different lifetime semantics. They are passed as arguments to the factory requests to specify how the constraint lifetimes should be managed. A oneshot pointer constraint will never reactivate once it has been deactivated. See the corresponding deactivation event (wp_locked_pointer.unlocked and wp_confined_pointer.unconfined) for details. A persistent pointer constraint may again reactivate once it has been deactivated. See the corresponding deactivation event (wp_locked_pointer.unlocked and wp_confined_pointer.unconfined) for details. Used by the client to notify the server that it will no longer use this pointer constraints object. The lock_pointer request lets the client request to disable movements of the virtual pointer (i.e. the cursor), effectively locking the pointer to a position. This request may not take effect immediately; in the future, when the compositor deems implementation-specific constraints are satisfied, the pointer lock will be activated and the compositor sends a locked event. The protocol provides no guarantee that the constraints are ever satisfied, and does not require the compositor to send an error if the constraints cannot ever be satisfied. It is thus possible to request a lock that will never activate. There may not be another pointer constraint of any kind requested or active on the surface for any of the wl_pointer objects of the seat of the passed pointer when requesting a lock. If there is, an error will be raised. See general pointer lock documentation for more details. The intersection of the region passed with this request and the input region of the surface is used to determine where the pointer must be in order for the lock to activate. It is up to the compositor whether to warp the pointer or require some kind of user interaction for the lock to activate. If the region is null the surface input region is used. A surface may receive pointer focus without the lock being activated. The request creates a new object wp_locked_pointer which is used to interact with the lock as well as receive updates about its state. See the the description of wp_locked_pointer for further information. Note that while a pointer is locked, the wl_pointer objects of the corresponding seat will not emit any wl_pointer.motion events, but relative motion events will still be emitted via wp_relative_pointer objects of the same seat. wl_pointer.axis and wl_pointer.button events are unaffected. The confine_pointer request lets the client request to confine the pointer cursor to a given region. This request may not take effect immediately; in the future, when the compositor deems implementation- specific constraints are satisfied, the pointer confinement will be activated and the compositor sends a confined event. The intersection of the region passed with this request and the input region of the surface is used to determine where the pointer must be in order for the confinement to activate. It is up to the compositor whether to warp the pointer or require some kind of user interaction for the confinement to activate. If the region is null the surface input region is used. The request will create a new object wp_confined_pointer which is used to interact with the confinement as well as receive updates about its state. See the the description of wp_confined_pointer for further information. The wp_locked_pointer interface represents a locked pointer state. While the lock of this object is active, the wl_pointer objects of the associated seat will not emit any wl_pointer.motion events. This object will send the event 'locked' when the lock is activated. Whenever the lock is activated, it is guaranteed that the locked surface will already have received pointer focus and that the pointer will be within the region passed to the request creating this object. To unlock the pointer, send the destroy request. This will also destroy the wp_locked_pointer object. If the compositor decides to unlock the pointer the unlocked event is sent. See wp_locked_pointer.unlock for details. When unlocking, the compositor may warp the cursor position to the set cursor position hint. If it does, it will not result in any relative motion events emitted via wp_relative_pointer. If the surface the lock was requested on is destroyed and the lock is not yet activated, the wp_locked_pointer object is now defunct and must be destroyed. Destroy the locked pointer object. If applicable, the compositor will unlock the pointer. Set the cursor position hint relative to the top left corner of the surface. If the client is drawing its own cursor, it should update the position hint to the position of its own cursor. A compositor may use this information to warp the pointer upon unlock in order to avoid pointer jumps. The cursor position hint is double buffered. The new hint will only take effect when the associated surface gets it pending state applied. See wl_surface.commit for details. Set a new region used to lock the pointer. The new lock region is double-buffered. The new lock region will only take effect when the associated surface gets its pending state applied. See wl_surface.commit for details. For details about the lock region, see wp_locked_pointer. Notification that the pointer lock of the seat's pointer is activated. Notification that the pointer lock of the seat's pointer is no longer active. If this is a oneshot pointer lock (see wp_pointer_constraints.lifetime) this object is now defunct and should be destroyed. If this is a persistent pointer lock (see wp_pointer_constraints.lifetime) this pointer lock may again reactivate in the future. The wp_confined_pointer interface represents a confined pointer state. This object will send the event 'confined' when the confinement is activated. Whenever the confinement is activated, it is guaranteed that the surface the pointer is confined to will already have received pointer focus and that the pointer will be within the region passed to the request creating this object. It is up to the compositor to decide whether this requires some user interaction and if the pointer will warp to within the passed region if outside. To unconfine the pointer, send the destroy request. This will also destroy the wp_confined_pointer object. If the compositor decides to unconfine the pointer the unconfined event is sent. The wp_confined_pointer object is at this point defunct and should be destroyed. Destroy the confined pointer object. If applicable, the compositor will unconfine the pointer. Set a new region used to confine the pointer. The new confine region is double-buffered. The new confine region will only take effect when the associated surface gets its pending state applied. See wl_surface.commit for details. If the confinement is active when the new confinement region is applied and the pointer ends up outside of newly applied region, the pointer may warped to a position within the new confinement region. If warped, a wl_pointer.motion event will be emitted, but no wp_relative_pointer.relative_motion event. The compositor may also, instead of using the new region, unconfine the pointer. For details about the confine region, see wp_confined_pointer. Notification that the pointer confinement of the seat's pointer is activated. Notification that the pointer confinement of the seat's pointer is no longer active. If this is a oneshot pointer confinement (see wp_pointer_constraints.lifetime) this object is now defunct and should be destroyed. If this is a persistent pointer confinement (see wp_pointer_constraints.lifetime) this pointer confinement may again reactivate in the future. wl-mirror-0.16.5/proto/wayland-protocols/unstable/pointer-gestures/0000755000175000017500000000000014646472005024237 5ustar yrlfyrlfwl-mirror-0.16.5/proto/wayland-protocols/unstable/pointer-gestures/README0000644000175000017500000000011414646472005025113 0ustar yrlfyrlfPointer gestures protocol Maintainers: Carlos Garnacho wl-mirror-0.16.5/proto/wayland-protocols/unstable/pointer-gestures/pointer-gestures-unstable-v1.xml0000644000175000017500000002612114646472005032441 0ustar yrlfyrlf A global interface to provide semantic touchpad gestures for a given pointer. Three gestures are currently supported: swipe, pinch, and hold. Pinch and swipe gestures follow a three-stage cycle: begin, update, end, hold gestures follow a two-stage cycle: begin and end. All gestures are identified by a unique id. 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. Create a swipe gesture object. See the wl_pointer_gesture_swipe interface for details. Create a pinch gesture object. See the wl_pointer_gesture_pinch interface for details. Destroy the pointer gesture object. Swipe, pinch and hold objects created via this gesture object remain valid. Create a hold gesture object. See the wl_pointer_gesture_hold interface for details. A swipe gesture object notifies a client about a multi-finger swipe gesture detected on an indirect input device such as a touchpad. The gesture is usually initiated by multiple fingers moving in the same direction but once initiated the direction may change. The precise conditions of when such a gesture is detected are implementation-dependent. A gesture consists of three stages: begin, update (optional) and end. There cannot be multiple simultaneous hold, pinch or swipe gestures on a same pointer/seat, how compositors prevent these situations is implementation-dependent. A gesture may be cancelled by the compositor or the hardware. Clients should not consider performing permanent or irreversible actions until the end of a gesture has been received. This event is sent when a multi-finger swipe gesture is detected on the device. This event is sent when a multi-finger swipe gesture changes the position of the logical center. The dx and dy coordinates are relative coordinates of the logical center of the gesture compared to the previous event. This event is sent when a multi-finger swipe gesture ceases to be valid. This may happen when one or more fingers are lifted or the gesture is cancelled. When a gesture is cancelled, the client should undo state changes caused by this gesture. What causes a gesture to be cancelled is implementation-dependent. A pinch gesture object notifies a client about a multi-finger pinch gesture detected on an indirect input device such as a touchpad. The gesture is usually initiated by multiple fingers moving towards each other or away from each other, or by two or more fingers rotating around a logical center of gravity. The precise conditions of when such a gesture is detected are implementation-dependent. A gesture consists of three stages: begin, update (optional) and end. There cannot be multiple simultaneous hold, pinch or swipe gestures on a same pointer/seat, how compositors prevent these situations is implementation-dependent. A gesture may be cancelled by the compositor or the hardware. Clients should not consider performing permanent or irreversible actions until the end of a gesture has been received. This event is sent when a multi-finger pinch gesture is detected on the device. This event is sent when a multi-finger pinch gesture changes the position of the logical center, the rotation or the relative scale. The dx and dy coordinates are relative coordinates in the surface coordinate space of the logical center of the gesture. The scale factor is an absolute scale compared to the pointer_gesture_pinch.begin event, e.g. a scale of 2 means the fingers are now twice as far apart as on pointer_gesture_pinch.begin. The rotation is the relative angle in degrees clockwise compared to the previous pointer_gesture_pinch.begin or pointer_gesture_pinch.update event. This event is sent when a multi-finger pinch gesture ceases to be valid. This may happen when one or more fingers are lifted or the gesture is cancelled. When a gesture is cancelled, the client should undo state changes caused by this gesture. What causes a gesture to be cancelled is implementation-dependent. A hold gesture object notifies a client about a single- or multi-finger hold gesture detected on an indirect input device such as a touchpad. The gesture is usually initiated by one or more fingers being held down without significant movement. The precise conditions of when such a gesture is detected are implementation-dependent. In particular, this gesture may be used to cancel kinetic scrolling. A hold gesture consists of two stages: begin and end. Unlike pinch and swipe there is no update stage. There cannot be multiple simultaneous hold, pinch or swipe gestures on a same pointer/seat, how compositors prevent these situations is implementation-dependent. A gesture may be cancelled by the compositor or the hardware. Clients should not consider performing permanent or irreversible actions until the end of a gesture has been received. This event is sent when a hold gesture is detected on the device. This event is sent when a hold gesture ceases to be valid. This may happen when the holding fingers are lifted or the gesture is cancelled, for example if the fingers move past an implementation-defined threshold, the finger count changes or the hold gesture changes into a different type of gesture. When a gesture is cancelled, the client may need to undo state changes caused by this gesture. What causes a gesture to be cancelled is implementation-dependent. wl-mirror-0.16.5/proto/wayland-protocols/unstable/primary-selection/0000755000175000017500000000000014646472005024366 5ustar yrlfyrlfwl-mirror-0.16.5/proto/wayland-protocols/unstable/primary-selection/README0000644000175000017500000000011114646472005025237 0ustar yrlfyrlfPrimary selection protocol Maintainers: Simon Ser ././@LongLink0000644000000000000000000000014600000000000011604 Lustar rootrootwl-mirror-0.16.5/proto/wayland-protocols/unstable/primary-selection/primary-selection-unstable-v1.xmlwl-mirror-0.16.5/proto/wayland-protocols/unstable/primary-selection/primary-selection-unstable-v1.xm0000644000175000017500000002434514646472005032551 0ustar yrlfyrlf Copyright © 2015, 2016 Red Hat 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. This protocol provides the ability to have a primary selection device to match that of the X server. This primary selection is a shortcut to the common clipboard selection, where text just needs to be selected in order to allow copying it elsewhere. The de facto way to perform this action is the middle mouse button, although it is not limited to this one. Clients wishing to honor primary selection should create a primary selection source and set it as the selection through wp_primary_selection_device.set_selection whenever the text selection changes. In order to minimize calls in pointer-driven text selection, it should happen only once after the operation finished. Similarly, a NULL source should be set when text is unselected. wp_primary_selection_offer objects are first announced through the wp_primary_selection_device.data_offer event. Immediately after this event, the primary data offer will emit wp_primary_selection_offer.offer events to let know of the mime types being offered. When the primary selection changes, the client with the keyboard focus will receive wp_primary_selection_device.selection events. Only the client with the keyboard focus will receive such events with a non-NULL wp_primary_selection_offer. Across keyboard focus changes, previously focused clients will receive wp_primary_selection_device.events with a NULL wp_primary_selection_offer. In order to request the primary selection data, the client must pass a recent serial pertaining to the press event that is triggering the operation, if the compositor deems the serial valid and recent, the wp_primary_selection_source.send event will happen in the other end to let the transfer begin. The client owning the primary selection should write the requested data, and close the file descriptor immediately. If the primary selection owner client disappeared during the transfer, the client reading the data will receive a wp_primary_selection_device.selection event with a NULL wp_primary_selection_offer, the client should take this as a hint to finish the reads related to the no longer existing offer. The primary selection owner should be checking for errors during writes, merely cancelling the ongoing transfer if any happened. The primary selection device manager is a singleton global object that provides access to the primary selection. It allows to create wp_primary_selection_source objects, as well as retrieving the per-seat wp_primary_selection_device objects. Create a new primary selection source. Create a new data device for a given seat. Destroy the primary selection device manager. Replaces the current selection. The previous owner of the primary selection will receive a wp_primary_selection_source.cancelled event. To unset the selection, set the source to NULL. Introduces a new wp_primary_selection_offer object that may be used to receive the current primary selection. Immediately following this event, the new wp_primary_selection_offer object will send wp_primary_selection_offer.offer events to describe the offered mime types. The wp_primary_selection_device.selection event is sent to notify the client of a new primary selection. This event is sent after the wp_primary_selection.data_offer event introducing this object, and after the offer has announced its mimetypes through wp_primary_selection_offer.offer. The data_offer is valid until a new offer or NULL is received or until the client loses keyboard focus. The client must destroy the previous selection data_offer, if any, upon receiving this event. Destroy the primary selection device. A wp_primary_selection_offer represents an offer to transfer the contents of the primary selection clipboard to the client. Similar to wl_data_offer, the offer also describes the mime types that the data can be converted to and provides the mechanisms for transferring the data directly to the client. To transfer the contents of the primary selection clipboard, the client issues this request and indicates the mime type that it wants to receive. The transfer happens through the passed file descriptor (typically created with the pipe system call). The source client writes the data in the mime type representation requested and then closes the file descriptor. The receiving client reads from the read end of the pipe until EOF and closes its end, at which point the transfer is complete. Destroy the primary selection offer. Sent immediately after creating announcing the wp_primary_selection_offer through wp_primary_selection_device.data_offer. One event is sent per offered mime type. The source side of a wp_primary_selection_offer, it provides a way to describe the offered data and respond to requests to transfer the requested contents of the primary selection clipboard. This request adds a mime type to the set of mime types advertised to targets. Can be called several times to offer multiple types. Destroy the primary selection source. Request for the current primary selection contents from the client. Send the specified mime type over the passed file descriptor, then close it. This primary selection source is no longer valid. The client should clean up and destroy this primary selection source. wl-mirror-0.16.5/proto/wayland-protocols/unstable/relative-pointer/0000755000175000017500000000000014646472005024211 5ustar yrlfyrlfwl-mirror-0.16.5/proto/wayland-protocols/unstable/relative-pointer/README0000644000175000017500000000011014646472005025061 0ustar yrlfyrlfRelative pointer protocol Maintainers: Jonas Ådahl wl-mirror-0.16.5/proto/wayland-protocols/unstable/relative-pointer/relative-pointer-unstable-v1.xml0000644000175000017500000001467014646472005032373 0ustar yrlfyrlf Copyright © 2014 Jonas Ådahl Copyright © 2015 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. This protocol specifies a set of interfaces used for making clients able to receive relative pointer events not obstructed by barriers (such as the monitor edge or other pointer barriers). To start receiving relative pointer events, a client must first bind the global interface "wp_relative_pointer_manager" which, if a compositor supports relative pointer motion events, is exposed by the registry. After having created the relative pointer manager proxy object, the client uses it to create the actual relative pointer object using the "get_relative_pointer" request given a wl_pointer. The relative pointer motion events will then, when applicable, be transmitted via the proxy of the newly created relative pointer object. See the documentation of the relative pointer interface for more details. 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. A global interface used for getting the relative pointer object for a given pointer. Used by the client to notify the server that it will no longer use this relative pointer manager object. Create a relative pointer interface given a wl_pointer object. See the wp_relative_pointer interface for more details. A wp_relative_pointer object is an extension to the wl_pointer interface used for emitting relative pointer events. It shares the same focus as wl_pointer objects of the same seat and will only emit events when it has focus. Relative x/y pointer motion from the pointer of the seat associated with this object. A relative motion is in the same dimension as regular wl_pointer motion events, except they do not represent an absolute position. For example, moving a pointer from (x, y) to (x', y') would have the equivalent relative motion (x' - x, y' - y). If a pointer motion caused the absolute pointer position to be clipped by for example the edge of the monitor, the relative motion is unaffected by the clipping and will represent the unclipped motion. This event also contains non-accelerated motion deltas. The non-accelerated delta is, when applicable, the regular pointer motion delta as it was before having applied motion acceleration and other transformations such as normalization. Note that the non-accelerated delta does not represent 'raw' events as they were read from some device. Pointer motion acceleration is device- and configuration-specific and non-accelerated deltas and accelerated deltas may have the same value on some devices. Relative motions are not coupled to wl_pointer.motion events, and can be sent in combination with such events, but also independently. There may also be scenarios where wl_pointer.motion is sent, but there is no relative motion. The order of an absolute and relative motion event originating from the same physical motion is not guaranteed. If the client needs button events or focus state, it can receive them from a wl_pointer object of the same seat that the wp_relative_pointer object is associated with. wl-mirror-0.16.5/proto/wayland-protocols/unstable/tablet/0000755000175000017500000000000014646472005022173 5ustar yrlfyrlfwl-mirror-0.16.5/proto/wayland-protocols/unstable/tablet/README0000644000175000017500000000011014646472005023043 0ustar yrlfyrlfTablet protocol Maintainers: Peter Hutterer wl-mirror-0.16.5/proto/wayland-protocols/unstable/tablet/tablet-unstable-v1.xml0000644000175000017500000007016414646472005026337 0ustar yrlfyrlf Copyright 2014 © Stephen "Lyude" Chandler Paul Copyright 2015-2016 © 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. This description provides a high-level overview of the interplay between the interfaces defined this protocol. For details, see the protocol specification. More than one tablet may exist, and device-specifics matter. Tablets are not represented by a single virtual device like wl_pointer. A client binds to the tablet manager object which is just a proxy object. From that, the client requests wp_tablet_manager.get_tablet_seat(wl_seat) and that returns the actual interface that has all the tablets. With this indirection, we can avoid merging wp_tablet into the actual Wayland protocol, a long-term benefit. The wp_tablet_seat sends a "tablet added" event for each tablet connected. That event is followed by descriptive events about the hardware; currently that includes events for name, vid/pid and a wp_tablet.path event that describes a local path. This path can be used to uniquely identify a tablet or get more information through libwacom. Emulated or nested tablets can skip any of those, e.g. a virtual tablet may not have a vid/pid. The sequence of descriptive events is terminated by a wp_tablet.done event to signal that a client may now finalize any initialization for that tablet. Events from tablets require a tool in proximity. Tools are also managed by the tablet seat; a "tool added" event is sent whenever a tool is new to the compositor. That event is followed by a number of descriptive events about the hardware; currently that includes capabilities, hardware id and serial number, and tool type. Similar to the tablet interface, a wp_tablet_tool.done event is sent to terminate that initial sequence. Any event from a tool happens on the wp_tablet_tool interface. When the tool gets into proximity of the tablet, a proximity_in event is sent on the wp_tablet_tool interface, listing the tablet and the surface. That event is followed by a motion event with the coordinates. After that, it's the usual motion, axis, button, etc. events. The protocol's serialisation means events are grouped by wp_tablet_tool.frame events. Two special events (that don't exist in X) are down and up. They signal "tip touching the surface". For tablets without real proximity detection, the sequence is: proximity_in, motion, down, frame. When the tool leaves proximity, a proximity_out event is sent. If any button is still down, a button release event is sent before this proximity event. These button events are sent in the same frame as the proximity event to signal to the client that the buttons were held when the tool left proximity. If the tool moves out of the surface but stays in proximity (i.e. between windows), compositor-specific grab policies apply. This usually means that the proximity-out is delayed until all buttons are released. Moving a tool physically from one tablet to the other has no real effect on the protocol, since we already have the tool object from the "tool added" event. All the information is already there and the proximity events on both tablets are all a client needs to reconstruct what happened. Some extra axes are normalized, i.e. the client knows the range as specified in the protocol (e.g. [0, 65535]), the granularity however is unknown. The current normalized axes are pressure, distance, and slider. Other extra axes are in physical units as specified in the protocol. The current extra axes with physical units are tilt, rotation and wheel rotation. Since tablets work independently of the pointer controlled by the mouse, the focus handling is independent too and controlled by proximity. The wp_tablet_tool.set_cursor request sets a tool-specific cursor. This cursor surface may be the same as the mouse cursor, and it may be the same across tools but it is possible to be more fine-grained. For example, a client may set different cursors for the pen and eraser. Tools are generally independent of tablets and it is compositor-specific policy when a tool can be removed. Common approaches will likely include some form of removing a tool when all tablets the tool was used on are removed. 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. An object that provides access to the graphics tablets available on this system. All tablets are associated with a seat, to get access to the actual tablets, use wp_tablet_manager.get_tablet_seat. Get the wp_tablet_seat object for the given seat. This object provides access to all graphics tablets in this seat. Destroy the wp_tablet_manager object. Objects created from this object are unaffected and should be destroyed separately. An object that provides access to the graphics tablets available on this seat. After binding to this interface, the compositor sends a set of wp_tablet_seat.tablet_added and wp_tablet_seat.tool_added events. Destroy the wp_tablet_seat object. Objects created from this object are unaffected and should be destroyed separately. This event is sent whenever a new tablet becomes available on this seat. This event only provides the object id of the tablet, any static information about the tablet (device name, vid/pid, etc.) is sent through the wp_tablet interface. This event is sent whenever a tool that has not previously been used with a tablet comes into use. This event only provides the object id of the tool; any static information about the tool (capabilities, type, etc.) is sent through the wp_tablet_tool interface. An object that represents a physical tool that has been, or is currently in use with a tablet in this seat. Each wp_tablet_tool object stays valid until the client destroys it; the compositor reuses the wp_tablet_tool object to indicate that the object's respective physical tool has come into proximity of a tablet again. A wp_tablet_tool object's relation to a physical tool depends on the tablet's ability to report serial numbers. If the tablet supports this capability, then the object represents a specific physical tool and can be identified even when used on multiple tablets. A tablet tool has a number of static characteristics, e.g. tool type, hardware_serial and capabilities. These capabilities are sent in an event sequence after the wp_tablet_seat.tool_added event before any actual events from this tool. This initial event sequence is terminated by a wp_tablet_tool.done event. Tablet tool events are grouped by wp_tablet_tool.frame events. Any events received before a wp_tablet_tool.frame event should be considered part of the same hardware state change. Sets the surface of the cursor used for this tool on the given tablet. This request only takes effect if the tool is in proximity of one of the requesting client's surfaces or the surface parameter is the current pointer surface. If there was a previous surface set with this request it is replaced. If surface is NULL, the cursor image is hidden. The parameters hotspot_x and hotspot_y define the position of the pointer surface relative to the pointer location. Its top-left corner is always at (x, y) - (hotspot_x, hotspot_y), where (x, y) are the coordinates of the pointer location, in surface-local coordinates. On surface.attach requests to the pointer surface, hotspot_x and hotspot_y are decremented by the x and y parameters passed to the request. Attach must be confirmed by wl_surface.commit as usual. The hotspot can also be updated by passing the currently set pointer surface to this request with new values for hotspot_x and hotspot_y. The current and pending input regions of the wl_surface are cleared, and wl_surface.set_input_region is ignored until the wl_surface is no longer used as the cursor. When the use as a cursor ends, the current and pending input regions become undefined, and the wl_surface is unmapped. This request gives the surface the role of a cursor. The role assigned by this request is the same as assigned by wl_pointer.set_cursor meaning the same surface can be used both as a wl_pointer cursor and a wp_tablet cursor. If the surface already has another role, it raises a protocol error. The surface may be used on multiple tablets and across multiple seats. This destroys the client's resource for this tool object. Describes the physical type of a tool. The physical type of a tool generally defines its base usage. The mouse tool represents a mouse-shaped tool that is not a relative device but bound to the tablet's surface, providing absolute coordinates. The lens tool is a mouse-shaped tool with an attached lens to provide precision focus. The tool type is the high-level type of the tool and usually decides the interaction expected from this tool. This event is sent in the initial burst of events before the wp_tablet_tool.done event. If the physical tool can be identified by a unique 64-bit serial number, this event notifies the client of this serial number. If multiple tablets are available in the same seat and the tool is uniquely identifiable by the serial number, that tool may move between tablets. Otherwise, if the tool has no serial number and this event is missing, the tool is tied to the tablet it first comes into proximity with. Even if the physical tool is used on multiple tablets, separate wp_tablet_tool objects will be created, one per tablet. This event is sent in the initial burst of events before the wp_tablet_tool.done event. This event notifies the client of a hardware id available on this tool. The hardware id is a device-specific 64-bit id that provides extra information about the tool in use, beyond the wl_tool.type enumeration. The format of the id is specific to tablets made by Wacom Inc. For example, the hardware id of a Wacom Grip Pen (a stylus) is 0x802. This event is sent in the initial burst of events before the wp_tablet_tool.done event. Describes extra capabilities on a tablet. Any tool must provide x and y values, extra axes are device-specific. This event notifies the client of any capabilities of this tool, beyond the main set of x/y axes and tip up/down detection. One event is sent for each extra capability available on this tool. This event is sent in the initial burst of events before the wp_tablet_tool.done event. This event signals the end of the initial burst of descriptive events. A client may consider the static description of the tool to be complete and finalize initialization of the tool. This event is sent when the tool is removed from the system and will send no further events. Should the physical tool come back into proximity later, a new wp_tablet_tool object will be created. It is compositor-dependent when a tool is removed. A compositor may remove a tool on proximity out, tablet removal or any other reason. A compositor may also keep a tool alive until shutdown. If the tool is currently in proximity, a proximity_out event will be sent before the removed event. See wp_tablet_tool.proximity_out for the handling of any buttons logically down. When this event is received, the client must wp_tablet_tool.destroy the object. Notification that this tool is focused on a certain surface. This event can be received when the tool has moved from one surface to another, or when the tool has come back into proximity above the surface. If any button is logically down when the tool comes into proximity, the respective button event is sent after the proximity_in event but within the same frame as the proximity_in event. Notification that this tool has either left proximity, or is no longer focused on a certain surface. When the tablet tool leaves proximity of the tablet, button release events are sent for each button that was held down at the time of leaving proximity. These events are sent before the proximity_out event but within the same wp_tablet.frame. If the tool stays within proximity of the tablet, but the focus changes from one surface to another, a button release event may not be sent until the button is actually released or the tool leaves the proximity of the tablet. Sent whenever the tablet tool comes in contact with the surface of the tablet. If the tool is already in contact with the tablet when entering the input region, the client owning said region will receive a wp_tablet.proximity_in event, followed by a wp_tablet.down event and a wp_tablet.frame event. Note that this event describes logical contact, not physical contact. On some devices, a compositor may not consider a tool in logical contact until a minimum physical pressure threshold is exceeded. Sent whenever the tablet tool stops making contact with the surface of the tablet, or when the tablet tool moves out of the input region and the compositor grab (if any) is dismissed. If the tablet tool moves out of the input region while in contact with the surface of the tablet and the compositor does not have an ongoing grab on the surface, the client owning said region will receive a wp_tablet.up event, followed by a wp_tablet.proximity_out event and a wp_tablet.frame event. If the compositor has an ongoing grab on this device, this event sequence is sent whenever the grab is dismissed in the future. Note that this event describes logical contact, not physical contact. On some devices, a compositor may not consider a tool out of logical contact until physical pressure falls below a specific threshold. Sent whenever a tablet tool moves. Sent whenever the pressure axis on a tool changes. The value of this event is normalized to a value between 0 and 65535. Note that pressure may be nonzero even when a tool is not in logical contact. See the down and up events for more details. Sent whenever the distance axis on a tool changes. The value of this event is normalized to a value between 0 and 65535. Note that distance may be nonzero even when a tool is not in logical contact. See the down and up events for more details. Sent whenever one or both of the tilt axes on a tool change. Each tilt value is in 0.01 of a degree, relative to the z-axis of the tablet. The angle is positive when the top of a tool tilts along the positive x or y axis. Sent whenever the z-rotation axis on the tool changes. The rotation value is in 0.01 of a degree clockwise from the tool's logical neutral position. Sent whenever the slider position on the tool changes. The value is normalized between -65535 and 65535, with 0 as the logical neutral position of the slider. The slider is available on e.g. the Wacom Airbrush tool. Sent whenever the wheel on the tool emits an event. This event contains two values for the same axis change. The degrees value is in 0.01 of a degree in the same orientation as the wl_pointer.vertical_scroll axis. The clicks value is in discrete logical clicks of the mouse wheel. This value may be zero if the movement of the wheel was less than one logical click. Clients should choose either value and avoid mixing degrees and clicks. The compositor may accumulate values smaller than a logical click and emulate click events when a certain threshold is met. Thus, wl_tablet_tool.wheel events with non-zero clicks values may have different degrees values. Describes the physical state of a button that produced the button event. Sent whenever a button on the tool is pressed or released. If a button is held down when the tool moves in or out of proximity, button events are generated by the compositor. See wp_tablet_tool.proximity_in and wp_tablet_tool.proximity_out for details. Marks the end of a series of axis and/or button updates from the tablet. The Wayland protocol requires axis updates to be sent sequentially, however all events within a frame should be considered one hardware event. The wp_tablet interface represents one graphics tablet device. The tablet interface itself does not generate events; all events are generated by wp_tablet_tool objects when in proximity above a tablet. A tablet has a number of static characteristics, e.g. device name and pid/vid. These capabilities are sent in an event sequence after the wp_tablet_seat.tablet_added event. This initial event sequence is terminated by a wp_tablet.done event. This destroys the client's resource for this tablet object. This event is sent in the initial burst of events before the wp_tablet.done event. This event is sent in the initial burst of events before the wp_tablet.done event. A system-specific device path that indicates which device is behind this wp_tablet. This information may be used to gather additional information about the device, e.g. through libwacom. A device may have more than one device path. If so, multiple wp_tablet.path events are sent. A device may be emulated and not have a device path, and in that case this event will not be sent. The format of the path is unspecified, it may be a device node, a sysfs path, or some other identifier. It is up to the client to identify the string provided. This event is sent in the initial burst of events before the wp_tablet.done event. This event is sent immediately to signal the end of the initial burst of descriptive events. A client may consider the static description of the tablet to be complete and finalize initialization of the tablet. Sent when the tablet has been removed from the system. When a tablet is removed, some tools may be removed. When this event is received, the client must wp_tablet.destroy the object. wl-mirror-0.16.5/proto/wayland-protocols/unstable/tablet/tablet-unstable-v2.xml0000644000175000017500000014500214646472005026332 0ustar yrlfyrlf Copyright 2014 © Stephen "Lyude" Chandler Paul Copyright 2015-2016 © 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. This description provides a high-level overview of the interplay between the interfaces defined this protocol. For details, see the protocol specification. More than one tablet may exist, and device-specifics matter. Tablets are not represented by a single virtual device like wl_pointer. A client binds to the tablet manager object which is just a proxy object. From that, the client requests wp_tablet_manager.get_tablet_seat(wl_seat) and that returns the actual interface that has all the tablets. With this indirection, we can avoid merging wp_tablet into the actual Wayland protocol, a long-term benefit. The wp_tablet_seat sends a "tablet added" event for each tablet connected. That event is followed by descriptive events about the hardware; currently that includes events for name, vid/pid and a wp_tablet.path event that describes a local path. This path can be used to uniquely identify a tablet or get more information through libwacom. Emulated or nested tablets can skip any of those, e.g. a virtual tablet may not have a vid/pid. The sequence of descriptive events is terminated by a wp_tablet.done event to signal that a client may now finalize any initialization for that tablet. Events from tablets require a tool in proximity. Tools are also managed by the tablet seat; a "tool added" event is sent whenever a tool is new to the compositor. That event is followed by a number of descriptive events about the hardware; currently that includes capabilities, hardware id and serial number, and tool type. Similar to the tablet interface, a wp_tablet_tool.done event is sent to terminate that initial sequence. Any event from a tool happens on the wp_tablet_tool interface. When the tool gets into proximity of the tablet, a proximity_in event is sent on the wp_tablet_tool interface, listing the tablet and the surface. That event is followed by a motion event with the coordinates. After that, it's the usual motion, axis, button, etc. events. The protocol's serialisation means events are grouped by wp_tablet_tool.frame events. Two special events (that don't exist in X) are down and up. They signal "tip touching the surface". For tablets without real proximity detection, the sequence is: proximity_in, motion, down, frame. When the tool leaves proximity, a proximity_out event is sent. If any button is still down, a button release event is sent before this proximity event. These button events are sent in the same frame as the proximity event to signal to the client that the buttons were held when the tool left proximity. If the tool moves out of the surface but stays in proximity (i.e. between windows), compositor-specific grab policies apply. This usually means that the proximity-out is delayed until all buttons are released. Moving a tool physically from one tablet to the other has no real effect on the protocol, since we already have the tool object from the "tool added" event. All the information is already there and the proximity events on both tablets are all a client needs to reconstruct what happened. Some extra axes are normalized, i.e. the client knows the range as specified in the protocol (e.g. [0, 65535]), the granularity however is unknown. The current normalized axes are pressure, distance, and slider. Other extra axes are in physical units as specified in the protocol. The current extra axes with physical units are tilt, rotation and wheel rotation. Since tablets work independently of the pointer controlled by the mouse, the focus handling is independent too and controlled by proximity. The wp_tablet_tool.set_cursor request sets a tool-specific cursor. This cursor surface may be the same as the mouse cursor, and it may be the same across tools but it is possible to be more fine-grained. For example, a client may set different cursors for the pen and eraser. Tools are generally independent of tablets and it is compositor-specific policy when a tool can be removed. Common approaches will likely include some form of removing a tool when all tablets the tool was used on are removed. 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. An object that provides access to the graphics tablets available on this system. All tablets are associated with a seat, to get access to the actual tablets, use wp_tablet_manager.get_tablet_seat. Get the wp_tablet_seat object for the given seat. This object provides access to all graphics tablets in this seat. Destroy the wp_tablet_manager object. Objects created from this object are unaffected and should be destroyed separately. An object that provides access to the graphics tablets available on this seat. After binding to this interface, the compositor sends a set of wp_tablet_seat.tablet_added and wp_tablet_seat.tool_added events. Destroy the wp_tablet_seat object. Objects created from this object are unaffected and should be destroyed separately. This event is sent whenever a new tablet becomes available on this seat. This event only provides the object id of the tablet, any static information about the tablet (device name, vid/pid, etc.) is sent through the wp_tablet interface. This event is sent whenever a tool that has not previously been used with a tablet comes into use. This event only provides the object id of the tool; any static information about the tool (capabilities, type, etc.) is sent through the wp_tablet_tool interface. This event is sent whenever a new pad is known to the system. Typically, pads are physically attached to tablets and a pad_added event is sent immediately after the wp_tablet_seat.tablet_added. However, some standalone pad devices logically attach to tablets at runtime, and the client must wait for wp_tablet_pad.enter to know the tablet a pad is attached to. This event only provides the object id of the pad. All further features (buttons, strips, rings) are sent through the wp_tablet_pad interface. An object that represents a physical tool that has been, or is currently in use with a tablet in this seat. Each wp_tablet_tool object stays valid until the client destroys it; the compositor reuses the wp_tablet_tool object to indicate that the object's respective physical tool has come into proximity of a tablet again. A wp_tablet_tool object's relation to a physical tool depends on the tablet's ability to report serial numbers. If the tablet supports this capability, then the object represents a specific physical tool and can be identified even when used on multiple tablets. A tablet tool has a number of static characteristics, e.g. tool type, hardware_serial and capabilities. These capabilities are sent in an event sequence after the wp_tablet_seat.tool_added event before any actual events from this tool. This initial event sequence is terminated by a wp_tablet_tool.done event. Tablet tool events are grouped by wp_tablet_tool.frame events. Any events received before a wp_tablet_tool.frame event should be considered part of the same hardware state change. Sets the surface of the cursor used for this tool on the given tablet. This request only takes effect if the tool is in proximity of one of the requesting client's surfaces or the surface parameter is the current pointer surface. If there was a previous surface set with this request it is replaced. If surface is NULL, the cursor image is hidden. The parameters hotspot_x and hotspot_y define the position of the pointer surface relative to the pointer location. Its top-left corner is always at (x, y) - (hotspot_x, hotspot_y), where (x, y) are the coordinates of the pointer location, in surface-local coordinates. On surface.attach requests to the pointer surface, hotspot_x and hotspot_y are decremented by the x and y parameters passed to the request. Attach must be confirmed by wl_surface.commit as usual. The hotspot can also be updated by passing the currently set pointer surface to this request with new values for hotspot_x and hotspot_y. The current and pending input regions of the wl_surface are cleared, and wl_surface.set_input_region is ignored until the wl_surface is no longer used as the cursor. When the use as a cursor ends, the current and pending input regions become undefined, and the wl_surface is unmapped. This request gives the surface the role of a wp_tablet_tool cursor. A surface may only ever be used as the cursor surface for one wp_tablet_tool. If the surface already has another role or has previously been used as cursor surface for a different tool, a protocol error is raised. This destroys the client's resource for this tool object. Describes the physical type of a tool. The physical type of a tool generally defines its base usage. The mouse tool represents a mouse-shaped tool that is not a relative device but bound to the tablet's surface, providing absolute coordinates. The lens tool is a mouse-shaped tool with an attached lens to provide precision focus. The tool type is the high-level type of the tool and usually decides the interaction expected from this tool. This event is sent in the initial burst of events before the wp_tablet_tool.done event. If the physical tool can be identified by a unique 64-bit serial number, this event notifies the client of this serial number. If multiple tablets are available in the same seat and the tool is uniquely identifiable by the serial number, that tool may move between tablets. Otherwise, if the tool has no serial number and this event is missing, the tool is tied to the tablet it first comes into proximity with. Even if the physical tool is used on multiple tablets, separate wp_tablet_tool objects will be created, one per tablet. This event is sent in the initial burst of events before the wp_tablet_tool.done event. This event notifies the client of a hardware id available on this tool. The hardware id is a device-specific 64-bit id that provides extra information about the tool in use, beyond the wl_tool.type enumeration. The format of the id is specific to tablets made by Wacom Inc. For example, the hardware id of a Wacom Grip Pen (a stylus) is 0x802. This event is sent in the initial burst of events before the wp_tablet_tool.done event. Describes extra capabilities on a tablet. Any tool must provide x and y values, extra axes are device-specific. This event notifies the client of any capabilities of this tool, beyond the main set of x/y axes and tip up/down detection. One event is sent for each extra capability available on this tool. This event is sent in the initial burst of events before the wp_tablet_tool.done event. This event signals the end of the initial burst of descriptive events. A client may consider the static description of the tool to be complete and finalize initialization of the tool. This event is sent when the tool is removed from the system and will send no further events. Should the physical tool come back into proximity later, a new wp_tablet_tool object will be created. It is compositor-dependent when a tool is removed. A compositor may remove a tool on proximity out, tablet removal or any other reason. A compositor may also keep a tool alive until shutdown. If the tool is currently in proximity, a proximity_out event will be sent before the removed event. See wp_tablet_tool.proximity_out for the handling of any buttons logically down. When this event is received, the client must wp_tablet_tool.destroy the object. Notification that this tool is focused on a certain surface. This event can be received when the tool has moved from one surface to another, or when the tool has come back into proximity above the surface. If any button is logically down when the tool comes into proximity, the respective button event is sent after the proximity_in event but within the same frame as the proximity_in event. Notification that this tool has either left proximity, or is no longer focused on a certain surface. When the tablet tool leaves proximity of the tablet, button release events are sent for each button that was held down at the time of leaving proximity. These events are sent before the proximity_out event but within the same wp_tablet.frame. If the tool stays within proximity of the tablet, but the focus changes from one surface to another, a button release event may not be sent until the button is actually released or the tool leaves the proximity of the tablet. Sent whenever the tablet tool comes in contact with the surface of the tablet. If the tool is already in contact with the tablet when entering the input region, the client owning said region will receive a wp_tablet.proximity_in event, followed by a wp_tablet.down event and a wp_tablet.frame event. Note that this event describes logical contact, not physical contact. On some devices, a compositor may not consider a tool in logical contact until a minimum physical pressure threshold is exceeded. Sent whenever the tablet tool stops making contact with the surface of the tablet, or when the tablet tool moves out of the input region and the compositor grab (if any) is dismissed. If the tablet tool moves out of the input region while in contact with the surface of the tablet and the compositor does not have an ongoing grab on the surface, the client owning said region will receive a wp_tablet.up event, followed by a wp_tablet.proximity_out event and a wp_tablet.frame event. If the compositor has an ongoing grab on this device, this event sequence is sent whenever the grab is dismissed in the future. Note that this event describes logical contact, not physical contact. On some devices, a compositor may not consider a tool out of logical contact until physical pressure falls below a specific threshold. Sent whenever a tablet tool moves. Sent whenever the pressure axis on a tool changes. The value of this event is normalized to a value between 0 and 65535. Note that pressure may be nonzero even when a tool is not in logical contact. See the down and up events for more details. Sent whenever the distance axis on a tool changes. The value of this event is normalized to a value between 0 and 65535. Note that distance may be nonzero even when a tool is not in logical contact. See the down and up events for more details. Sent whenever one or both of the tilt axes on a tool change. Each tilt value is in degrees, relative to the z-axis of the tablet. The angle is positive when the top of a tool tilts along the positive x or y axis. Sent whenever the z-rotation axis on the tool changes. The rotation value is in degrees clockwise from the tool's logical neutral position. Sent whenever the slider position on the tool changes. The value is normalized between -65535 and 65535, with 0 as the logical neutral position of the slider. The slider is available on e.g. the Wacom Airbrush tool. Sent whenever the wheel on the tool emits an event. This event contains two values for the same axis change. The degrees value is in the same orientation as the wl_pointer.vertical_scroll axis. The clicks value is in discrete logical clicks of the mouse wheel. This value may be zero if the movement of the wheel was less than one logical click. Clients should choose either value and avoid mixing degrees and clicks. The compositor may accumulate values smaller than a logical click and emulate click events when a certain threshold is met. Thus, wl_tablet_tool.wheel events with non-zero clicks values may have different degrees values. Describes the physical state of a button that produced the button event. Sent whenever a button on the tool is pressed or released. If a button is held down when the tool moves in or out of proximity, button events are generated by the compositor. See wp_tablet_tool.proximity_in and wp_tablet_tool.proximity_out for details. Marks the end of a series of axis and/or button updates from the tablet. The Wayland protocol requires axis updates to be sent sequentially, however all events within a frame should be considered one hardware event. The wp_tablet interface represents one graphics tablet device. The tablet interface itself does not generate events; all events are generated by wp_tablet_tool objects when in proximity above a tablet. A tablet has a number of static characteristics, e.g. device name and pid/vid. These capabilities are sent in an event sequence after the wp_tablet_seat.tablet_added event. This initial event sequence is terminated by a wp_tablet.done event. This destroys the client's resource for this tablet object. This event is sent in the initial burst of events before the wp_tablet.done event. This event is sent in the initial burst of events before the wp_tablet.done event. A system-specific device path that indicates which device is behind this wp_tablet. This information may be used to gather additional information about the device, e.g. through libwacom. A device may have more than one device path. If so, multiple wp_tablet.path events are sent. A device may be emulated and not have a device path, and in that case this event will not be sent. The format of the path is unspecified, it may be a device node, a sysfs path, or some other identifier. It is up to the client to identify the string provided. This event is sent in the initial burst of events before the wp_tablet.done event. This event is sent immediately to signal the end of the initial burst of descriptive events. A client may consider the static description of the tablet to be complete and finalize initialization of the tablet. Sent when the tablet has been removed from the system. When a tablet is removed, some tools may be removed. When this event is received, the client must wp_tablet.destroy the object. A circular interaction area, such as the touch ring on the Wacom Intuos Pro series tablets. Events on a ring are logically grouped by the wl_tablet_pad_ring.frame event. Request that the compositor use the provided feedback string associated with this ring. This request should be issued immediately after a wp_tablet_pad_group.mode_switch event from the corresponding group is received, or whenever the ring is mapped to a different action. See wp_tablet_pad_group.mode_switch for more details. Clients are encouraged to provide context-aware descriptions for the actions associated with the ring; compositors may use this information to offer visual feedback about the button layout (eg. on-screen displays). The provided string 'description' is a UTF-8 encoded string to be associated with this ring, and is considered user-visible; general internationalization rules apply. The serial argument will be that of the last wp_tablet_pad_group.mode_switch event received for the group of this ring. Requests providing other serials than the most recent one will be ignored. This destroys the client's resource for this ring object. Describes the source types for ring events. This indicates to the client how a ring event was physically generated; a client may adjust the user interface accordingly. For example, events from a "finger" source may trigger kinetic scrolling. Source information for ring events. This event does not occur on its own. It is sent before a wp_tablet_pad_ring.frame event and carries the source information for all events within that frame. The source specifies how this event was generated. If the source is wp_tablet_pad_ring.source.finger, a wp_tablet_pad_ring.stop event will be sent when the user lifts the finger off the device. This event is optional. If the source is unknown for an interaction, no event is sent. Sent whenever the angle on a ring changes. The angle is provided in degrees clockwise from the logical north of the ring in the pad's current rotation. Stop notification for ring events. For some wp_tablet_pad_ring.source types, a wp_tablet_pad_ring.stop event is sent to notify a client that the interaction with the ring has terminated. This enables the client to implement kinetic scrolling. See the wp_tablet_pad_ring.source documentation for information on when this event may be generated. Any wp_tablet_pad_ring.angle events with the same source after this event should be considered as the start of a new interaction. Indicates the end of a set of ring events that logically belong together. A client is expected to accumulate the data in all events within the frame before proceeding. All wp_tablet_pad_ring events before a wp_tablet_pad_ring.frame event belong logically together. For example, on termination of a finger interaction on a ring the compositor will send a wp_tablet_pad_ring.source event, a wp_tablet_pad_ring.stop event and a wp_tablet_pad_ring.frame event. A wp_tablet_pad_ring.frame event is sent for every logical event group, even if the group only contains a single wp_tablet_pad_ring event. Specifically, a client may get a sequence: angle, frame, angle, frame, etc. A linear interaction area, such as the strips found in Wacom Cintiq models. Events on a strip are logically grouped by the wl_tablet_pad_strip.frame event. Requests the compositor to use the provided feedback string associated with this strip. This request should be issued immediately after a wp_tablet_pad_group.mode_switch event from the corresponding group is received, or whenever the strip is mapped to a different action. See wp_tablet_pad_group.mode_switch for more details. Clients are encouraged to provide context-aware descriptions for the actions associated with the strip, and compositors may use this information to offer visual feedback about the button layout (eg. on-screen displays). The provided string 'description' is a UTF-8 encoded string to be associated with this ring, and is considered user-visible; general internationalization rules apply. The serial argument will be that of the last wp_tablet_pad_group.mode_switch event received for the group of this strip. Requests providing other serials than the most recent one will be ignored. This destroys the client's resource for this strip object. Describes the source types for strip events. This indicates to the client how a strip event was physically generated; a client may adjust the user interface accordingly. For example, events from a "finger" source may trigger kinetic scrolling. Source information for strip events. This event does not occur on its own. It is sent before a wp_tablet_pad_strip.frame event and carries the source information for all events within that frame. The source specifies how this event was generated. If the source is wp_tablet_pad_strip.source.finger, a wp_tablet_pad_strip.stop event will be sent when the user lifts their finger off the device. This event is optional. If the source is unknown for an interaction, no event is sent. Sent whenever the position on a strip changes. The position is normalized to a range of [0, 65535], the 0-value represents the top-most and/or left-most position of the strip in the pad's current rotation. Stop notification for strip events. For some wp_tablet_pad_strip.source types, a wp_tablet_pad_strip.stop event is sent to notify a client that the interaction with the strip has terminated. This enables the client to implement kinetic scrolling. See the wp_tablet_pad_strip.source documentation for information on when this event may be generated. Any wp_tablet_pad_strip.position events with the same source after this event should be considered as the start of a new interaction. Indicates the end of a set of events that represent one logical hardware strip event. A client is expected to accumulate the data in all events within the frame before proceeding. All wp_tablet_pad_strip events before a wp_tablet_pad_strip.frame event belong logically together. For example, on termination of a finger interaction on a strip the compositor will send a wp_tablet_pad_strip.source event, a wp_tablet_pad_strip.stop event and a wp_tablet_pad_strip.frame event. A wp_tablet_pad_strip.frame event is sent for every logical event group, even if the group only contains a single wp_tablet_pad_strip event. Specifically, a client may get a sequence: position, frame, position, frame, etc. A pad group describes a distinct (sub)set of buttons, rings and strips present in the tablet. The criteria of this grouping is usually positional, eg. if a tablet has buttons on the left and right side, 2 groups will be presented. The physical arrangement of groups is undisclosed and may change on the fly. Pad groups will announce their features during pad initialization. Between the corresponding wp_tablet_pad.group event and wp_tablet_pad_group.done, the pad group will announce the buttons, rings and strips contained in it, plus the number of supported modes. Modes are a mechanism to allow multiple groups of actions for every element in the pad group. The number of groups and available modes in each is persistent across device plugs. The current mode is user-switchable, it will be announced through the wp_tablet_pad_group.mode_switch event both whenever it is switched, and after wp_tablet_pad.enter. The current mode logically applies to all elements in the pad group, although it is at clients' discretion whether to actually perform different actions, and/or issue the respective .set_feedback requests to notify the compositor. See the wp_tablet_pad_group.mode_switch event for more details. Destroy the wp_tablet_pad_group object. Objects created from this object are unaffected and should be destroyed separately. Sent on wp_tablet_pad_group initialization to announce the available buttons in the group. Button indices start at 0, a button may only be in one group at a time. This event is first sent in the initial burst of events before the wp_tablet_pad_group.done event. Some buttons are reserved by the compositor. These buttons may not be assigned to any wp_tablet_pad_group. Compositors may broadcast this event in the case of changes to the mapping of these reserved buttons. If the compositor happens to reserve all buttons in a group, this event will be sent with an empty array. Sent on wp_tablet_pad_group initialization to announce available rings. One event is sent for each ring available on this pad group. This event is sent in the initial burst of events before the wp_tablet_pad_group.done event. Sent on wp_tablet_pad initialization to announce available strips. One event is sent for each strip available on this pad group. This event is sent in the initial burst of events before the wp_tablet_pad_group.done event. Sent on wp_tablet_pad_group initialization to announce that the pad group may switch between modes. A client may use a mode to store a specific configuration for buttons, rings and strips and use the wl_tablet_pad_group.mode_switch event to toggle between these configurations. Mode indices start at 0. Switching modes is compositor-dependent. See the wp_tablet_pad_group.mode_switch event for more details. This event is sent in the initial burst of events before the wp_tablet_pad_group.done event. This event is only sent when more than more than one mode is available. This event is sent immediately to signal the end of the initial burst of descriptive events. A client may consider the static description of the tablet to be complete and finalize initialization of the tablet group. Notification that the mode was switched. A mode applies to all buttons, rings and strips in a group simultaneously, but a client is not required to assign different actions for each mode. For example, a client may have mode-specific button mappings but map the ring to vertical scrolling in all modes. Mode indices start at 0. Switching modes is compositor-dependent. The compositor may provide visual cues to the client about the mode, e.g. by toggling LEDs on the tablet device. Mode-switching may be software-controlled or controlled by one or more physical buttons. For example, on a Wacom Intuos Pro, the button inside the ring may be assigned to switch between modes. The compositor will also send this event after wp_tablet_pad.enter on each group in order to notify of the current mode. Groups that only feature one mode will use mode=0 when emitting this event. If a button action in the new mode differs from the action in the previous mode, the client should immediately issue a wp_tablet_pad.set_feedback request for each changed button. If a ring or strip action in the new mode differs from the action in the previous mode, the client should immediately issue a wp_tablet_ring.set_feedback or wp_tablet_strip.set_feedback request for each changed ring or strip. A pad device is a set of buttons, rings and strips usually physically present on the tablet device itself. Some exceptions exist where the pad device is physically detached, e.g. the Wacom ExpressKey Remote. Pad devices have no axes that control the cursor and are generally auxiliary devices to the tool devices used on the tablet surface. A pad device has a number of static characteristics, e.g. the number of rings. These capabilities are sent in an event sequence after the wp_tablet_seat.pad_added event before any actual events from this pad. This initial event sequence is terminated by a wp_tablet_pad.done event. All pad features (buttons, rings and strips) are logically divided into groups and all pads have at least one group. The available groups are notified through the wp_tablet_pad.group event; the compositor will emit one event per group before emitting wp_tablet_pad.done. Groups may have multiple modes. Modes allow clients to map multiple actions to a single pad feature. Only one mode can be active per group, although different groups may have different active modes. Requests the compositor to use the provided feedback string associated with this button. This request should be issued immediately after a wp_tablet_pad_group.mode_switch event from the corresponding group is received, or whenever a button is mapped to a different action. See wp_tablet_pad_group.mode_switch for more details. Clients are encouraged to provide context-aware descriptions for the actions associated with each button, and compositors may use this information to offer visual feedback on the button layout (e.g. on-screen displays). Button indices start at 0. Setting the feedback string on a button that is reserved by the compositor (i.e. not belonging to any wp_tablet_pad_group) does not generate an error but the compositor is free to ignore the request. The provided string 'description' is a UTF-8 encoded string to be associated with this ring, and is considered user-visible; general internationalization rules apply. The serial argument will be that of the last wp_tablet_pad_group.mode_switch event received for the group of this button. Requests providing other serials than the most recent one will be ignored. Destroy the wp_tablet_pad object. Objects created from this object are unaffected and should be destroyed separately. Sent on wp_tablet_pad initialization to announce available groups. One event is sent for each pad group available. This event is sent in the initial burst of events before the wp_tablet_pad.done event. At least one group will be announced. A system-specific device path that indicates which device is behind this wp_tablet_pad. This information may be used to gather additional information about the device, e.g. through libwacom. The format of the path is unspecified, it may be a device node, a sysfs path, or some other identifier. It is up to the client to identify the string provided. This event is sent in the initial burst of events before the wp_tablet_pad.done event. Sent on wp_tablet_pad initialization to announce the available buttons. This event is sent in the initial burst of events before the wp_tablet_pad.done event. This event is only sent when at least one button is available. This event signals the end of the initial burst of descriptive events. A client may consider the static description of the pad to be complete and finalize initialization of the pad. Describes the physical state of a button that caused the button event. Sent whenever the physical state of a button changes. Notification that this pad is focused on the specified surface. Notification that this pad is no longer focused on the specified surface. Sent when the pad has been removed from the system. When a tablet is removed its pad(s) will be removed too. When this event is received, the client must destroy all rings, strips and groups that were offered by this pad, and issue wp_tablet_pad.destroy the pad itself. wl-mirror-0.16.5/proto/wayland-protocols/unstable/text-input/0000755000175000017500000000000014646472005023041 5ustar yrlfyrlfwl-mirror-0.16.5/proto/wayland-protocols/unstable/text-input/README0000644000175000017500000000011014646472005023711 0ustar yrlfyrlfText input protocol Maintainers: Jan Arne Petersen wl-mirror-0.16.5/proto/wayland-protocols/unstable/text-input/text-input-unstable-v1.xml0000644000175000017500000003770014646472005030052 0ustar yrlfyrlf Copyright © 2012, 2013 Intel Corporation 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. An object used for text input. Adds support for text input and input methods to applications. A text_input object is created from a wl_text_input_manager and corresponds typically to a text entry in an application. Requests are used to activate/deactivate the text_input object and set state information like surrounding and selected text or the content type. The information about entered text is sent to the text_input object via the pre-edit and commit events. Using this interface removes the need for applications to directly process hardware key events and compose text out of them. Text is generally UTF-8 encoded, indices and lengths are in bytes. Serials are used to synchronize the state between the text input and an input method. New serials are sent by the text input in the commit_state request and are used by the input method to indicate the known text input state in events like preedit_string, commit_string, and keysym. The text input can then ignore events from the input method which are based on an outdated state (for example after a reset). 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. Requests the text_input object to be activated (typically when the text entry gets focus). The seat argument is a wl_seat which maintains the focus for this activation. The surface argument is a wl_surface assigned to the text_input object and tracked for focus lost. The enter event is emitted on successful activation. Requests the text_input object to be deactivated (typically when the text entry lost focus). The seat argument is a wl_seat which was used for activation. Requests input panels (virtual keyboard) to show. Requests input panels (virtual keyboard) to hide. Should be called by an editor widget when the input state should be reset, for example after the text was changed outside of the normal input method flow. Sets the plain surrounding text around the input position. Text is UTF-8 encoded. Cursor is the byte offset within the surrounding text. Anchor is the byte offset of the selection anchor within the surrounding text. If there is no selected text anchor, then it is the same as cursor. Content hint is a bitmask to allow to modify the behavior of the text input. The content purpose allows to specify the primary purpose of a text input. This allows an input method to show special purpose input panels with extra characters or to disallow some characters. Sets the content purpose and content hint. While the purpose is the basic purpose of an input field, the hint flags allow to modify some of the behavior. When no content type is explicitly set, a normal content purpose with default hints (auto completion, auto correction, auto capitalization) should be assumed. Sets a specific language. This allows for example a virtual keyboard to show a language specific layout. The "language" argument is an RFC-3066 format language tag. It could be used for example in a word processor to indicate the language of the currently edited document or in an instant message application which tracks languages of contacts. Notify the text_input object when it received focus. Typically in response to an activate request. Notify the text_input object when it lost focus. Either in response to a deactivate request or when the assigned surface lost focus or was destroyed. Transfer an array of 0-terminated modifier names. The position in the array is the index of the modifier as used in the modifiers bitmask in the keysym event. Notify when the visibility state of the input panel changed. Notify when a new composing text (pre-edit) should be set around the current cursor position. Any previously set composing text should be removed. The commit text can be used to replace the preedit text on reset (for example on unfocus). The text input should also handle all preedit_style and preedit_cursor events occurring directly before preedit_string. Sets styling information on composing text. The style is applied for length bytes from index relative to the beginning of the composing text (as byte offset). Multiple styles can be applied to a composing text by sending multiple preedit_styling events. This event is handled as part of a following preedit_string event. Sets the cursor position inside the composing text (as byte offset) relative to the start of the composing text. When index is a negative number no cursor is shown. This event is handled as part of a following preedit_string event. Notify when text should be inserted into the editor widget. The text to commit could be either just a single character after a key press or the result of some composing (pre-edit). It could also be an empty text when some text should be removed (see delete_surrounding_text) or when the input cursor should be moved (see cursor_position). Any previously set composing text should be removed. Notify when the cursor or anchor position should be modified. This event should be handled as part of a following commit_string event. Notify when the text around the current cursor position should be deleted. Index is relative to the current cursor (in bytes). Length is the length of deleted text (in bytes). This event should be handled as part of a following commit_string event. Notify when a key event was sent. Key events should not be used for normal text input operations, which should be done with commit_string, delete_surrounding_text, etc. The key event follows the wl_keyboard key event convention. Sym is an XKB keysym, state a wl_keyboard key_state. Modifiers are a mask for effective modifiers (where the modifier indices are set by the modifiers_map event) Sets the language of the input text. The "language" argument is an RFC-3066 format language tag. Sets the text direction of input text. It is mainly needed for showing an input cursor on the correct side of the editor when there is no input done yet and making sure neutral direction text is laid out properly. A factory for text_input objects. This object is a global singleton. Creates a new text_input object. wl-mirror-0.16.5/proto/wayland-protocols/unstable/text-input/text-input-unstable-v3.xml0000644000175000017500000005176314646472005030061 0ustar yrlfyrlf Copyright © 2012, 2013 Intel Corporation Copyright © 2015, 2016 Jan Arne Petersen Copyright © 2017, 2018 Red Hat, Inc. Copyright © 2018 Purism SPC 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. This protocol allows compositors to act as input methods and to send text to applications. A text input object is used to manage state of what are typically text entry fields in the application. This document adheres to the RFC 2119 when using words like "must", "should", "may", etc. 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. The zwp_text_input_v3 interface represents text input and input methods associated with a seat. It provides enter/leave events to follow the text input focus for a seat. Requests are used to enable/disable the text-input object and set state information like surrounding and selected text or the content type. The information about the entered text is sent to the text-input object via the preedit_string and commit_string events. Text is valid UTF-8 encoded, indices and lengths are in bytes. Indices must not point to middle bytes inside a code point: they must either point to the first byte of a code point or to the end of the buffer. Lengths must be measured between two valid indices. Focus moving throughout surfaces will result in the emission of zwp_text_input_v3.enter and zwp_text_input_v3.leave events. The focused surface must commit zwp_text_input_v3.enable and zwp_text_input_v3.disable requests as the keyboard focus moves across editable and non-editable elements of the UI. Those two requests are not expected to be paired with each other, the compositor must be able to handle consecutive series of the same request. State is sent by the state requests (set_surrounding_text, set_content_type and set_cursor_rectangle) and a commit request. After an enter event or disable request all state information is invalidated and needs to be resent by the client. Destroy the wp_text_input object. Also disables all surfaces enabled through this wp_text_input object. Requests text input on the surface previously obtained from the enter event. This request must be issued every time the active text input changes to a new one, including within the current surface. Use zwp_text_input_v3.disable when there is no longer any input focus on the current surface. Clients must not enable more than one text input on the single seat and should disable the current text input before enabling the new one. At most one instance of text input may be in enabled state per instance, Requests to enable the another text input when some text input is active must be ignored by compositor. This request resets all state associated with previous enable, disable, set_surrounding_text, set_text_change_cause, set_content_type, and set_cursor_rectangle requests, as well as the state associated with preedit_string, commit_string, and delete_surrounding_text events. The set_surrounding_text, set_content_type and set_cursor_rectangle requests must follow if the text input supports the necessary functionality. State set with this request is double-buffered. It will get applied on the next zwp_text_input_v3.commit request, and stay valid until the next committed enable or disable request. The changes must be applied by the compositor after issuing a zwp_text_input_v3.commit request. Explicitly disable text input on the current surface (typically when there is no focus on any text entry inside the surface). State set with this request is double-buffered. It will get applied on the next zwp_text_input_v3.commit request. Sets the surrounding plain text around the input, excluding the preedit text. The client should notify the compositor of any changes in any of the values carried with this request, including changes caused by handling incoming text-input events as well as changes caused by other mechanisms like keyboard typing. If the client is unaware of the text around the cursor, it should not issue this request, to signify lack of support to the compositor. Text is UTF-8 encoded, and should include the cursor position, the complete selection and additional characters before and after them. There is a maximum length of wayland messages, so text can not be longer than 4000 bytes. Cursor is the byte offset of the cursor within text buffer. Anchor is the byte offset of the selection anchor within text buffer. If there is no selected text, anchor is the same as cursor. If any preedit text is present, it is replaced with a cursor for the purpose of this event. Values set with this request are double-buffered. They will get applied on the next zwp_text_input_v3.commit request, and stay valid until the next committed enable or disable request. The initial state for affected fields is empty, meaning that the text input does not support sending surrounding text. If the empty values get applied, subsequent attempts to change them may have no effect. Reason for the change of surrounding text or cursor posision. Tells the compositor why the text surrounding the cursor changed. Whenever the client detects an external change in text, cursor, or anchor posision, it must issue this request to the compositor. This request is intended to give the input method a chance to update the preedit text in an appropriate way, e.g. by removing it when the user starts typing with a keyboard. cause describes the source of the change. The value set with this request is double-buffered. It must be applied and reset to initial at the next zwp_text_input_v3.commit request. The initial value of cause is input_method. Content hint is a bitmask to allow to modify the behavior of the text input. The content purpose allows to specify the primary purpose of a text input. This allows an input method to show special purpose input panels with extra characters or to disallow some characters. Sets the content purpose and content hint. While the purpose is the basic purpose of an input field, the hint flags allow to modify some of the behavior. Values set with this request are double-buffered. They will get applied on the next zwp_text_input_v3.commit request. Subsequent attempts to update them may have no effect. The values remain valid until the next committed enable or disable request. The initial value for hint is none, and the initial value for purpose is normal. Marks an area around the cursor as a x, y, width, height rectangle in surface local coordinates. Allows the compositor to put a window with word suggestions near the cursor, without obstructing the text being input. If the client is unaware of the position of edited text, it should not issue this request, to signify lack of support to the compositor. Values set with this request are double-buffered. They will get applied on the next zwp_text_input_v3.commit request, and stay valid until the next committed enable or disable request. The initial values describing a cursor rectangle are empty. That means the text input does not support describing the cursor area. If the empty values get applied, subsequent attempts to change them may have no effect. Atomically applies state changes recently sent to the compositor. The commit request establishes and updates the state of the client, and must be issued after any changes to apply them. Text input state (enabled status, content purpose, content hint, surrounding text and change cause, cursor rectangle) is conceptually double-buffered within the context of a text input, i.e. between a committed enable request and the following committed enable or disable request. Protocol requests modify the pending state, as opposed to the current state in use by the input method. A commit request atomically applies all pending state, replacing the current state. After commit, the new pending state is as documented for each related request. Requests are applied in the order of arrival. Neither current nor pending state are modified unless noted otherwise. The compositor must count the number of commit requests coming from each zwp_text_input_v3 object and use the count as the serial in done events. Notification that this seat's text-input focus is on a certain surface. If client has created multiple text input objects, compositor must send this event to all of them. When the seat has the keyboard capability the text-input focus follows the keyboard focus. This event sets the current surface for the text-input object. Notification that this seat's text-input focus is no longer on a certain surface. The client should reset any preedit string previously set. The leave notification clears the current surface. It is sent before the enter notification for the new focus. After leave event, compositor must ignore requests from any text input instances until next enter event. When the seat has the keyboard capability the text-input focus follows the keyboard focus. Notify when a new composing text (pre-edit) should be set at the current cursor position. Any previously set composing text must be removed. Any previously existing selected text must be removed. The argument text contains the pre-edit string buffer. The parameters cursor_begin and cursor_end are counted in bytes relative to the beginning of the submitted text buffer. Cursor should be hidden when both are equal to -1. They could be represented by the client as a line if both values are the same, or as a text highlight otherwise. Values set with this event are double-buffered. They must be applied and reset to initial on the next zwp_text_input_v3.done event. The initial value of text is an empty string, and cursor_begin, cursor_end and cursor_hidden are all 0. Notify when text should be inserted into the editor widget. The text to commit could be either just a single character after a key press or the result of some composing (pre-edit). Values set with this event are double-buffered. They must be applied and reset to initial on the next zwp_text_input_v3.done event. The initial value of text is an empty string. Notify when the text around the current cursor position should be deleted. Before_length and after_length are the number of bytes before and after the current cursor index (excluding the selection) to delete. If a preedit text is present, in effect before_length is counted from the beginning of it, and after_length from its end (see done event sequence). Values set with this event are double-buffered. They must be applied and reset to initial on the next zwp_text_input_v3.done event. The initial values of both before_length and after_length are 0. Instruct the application to apply changes to state requested by the preedit_string, commit_string and delete_surrounding_text events. The state relating to these events is double-buffered, and each one modifies the pending state. This event replaces the current state with the pending state. The application must proceed by evaluating the changes in the following order: 1. Replace existing preedit string with the cursor. 2. Delete requested surrounding text. 3. Insert commit string with the cursor at its end. 4. Calculate surrounding text to send. 5. Insert new preedit text in cursor position. 6. Place cursor inside preedit text. The serial number reflects the last state of the zwp_text_input_v3 object known to the compositor. The value of the serial argument must be equal to the number of commit requests already issued on that object. When the client receives a done event with a serial different than the number of past commit requests, it must proceed with evaluating and applying the changes as normal, except it should not change the current state of the zwp_text_input_v3 object. All pending state requests (set_surrounding_text, set_content_type and set_cursor_rectangle) on the zwp_text_input_v3 object should be sent and committed after receiving a zwp_text_input_v3.done event with a matching serial. A factory for text-input objects. This object is a global singleton. Destroy the wp_text_input_manager object. Creates a new text-input object for a given seat. wl-mirror-0.16.5/proto/wayland-protocols/unstable/xdg-decoration/0000755000175000017500000000000014646472005023627 5ustar yrlfyrlfwl-mirror-0.16.5/proto/wayland-protocols/unstable/xdg-decoration/README0000644000175000017500000000010614646472005024504 0ustar yrlfyrlfxdg_decoration protocol Maintainers: Simon Ser wl-mirror-0.16.5/proto/wayland-protocols/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml0000644000175000017500000001566114646472005031430 0ustar yrlfyrlf Copyright © 2018 Simon Ser 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. This interface allows a compositor to announce support for server-side decorations. A window decoration is a set of window controls as deemed appropriate by the party managing them, such as user interface components used to move, resize and change a window's state. A client can use this protocol to request being decorated by a supporting compositor. If compositor and client do not negotiate the use of a server-side decoration using this protocol, clients continue to self-decorate as they see fit. 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. Destroy the decoration manager. This doesn't destroy objects created with the manager. Create a new decoration object associated with the given toplevel. Creating an xdg_toplevel_decoration from an xdg_toplevel 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_toplevel_decoration.configure event must also be treated as errors. The decoration object allows the compositor to toggle server-side window decorations for a toplevel surface. The client can request to switch to another mode. The xdg_toplevel_decoration object must be destroyed before its xdg_toplevel. Switch back to a mode without any server-side decorations at the next commit. These values describe window decoration modes. Set the toplevel surface decoration mode. This informs the compositor that the client prefers the provided decoration mode. After requesting a decoration mode, the compositor will respond by emitting an xdg_surface.configure event. The client should then update its content, drawing it without decorations if the received mode is server-side decorations. The client must also acknowledge the configure when committing the new content (see xdg_surface.ack_configure). The compositor can decide not to use the client's mode and enforce a different mode instead. Clients whose decoration mode depend on the xdg_toplevel state may send a set_mode request in response to an xdg_surface.configure event and wait for the next xdg_surface.configure event to prevent unwanted state. Such clients are responsible for preventing configure loops and must make sure not to send multiple successive set_mode requests with the same decoration mode. Unset the toplevel surface decoration mode. This informs the compositor that the client doesn't prefer a particular decoration mode. This request has the same semantics as set_mode. The configure event asks the client to change its decoration mode. The configured state should not be applied immediately. Clients must send an ack_configure in response to this event. See xdg_surface.configure and xdg_surface.ack_configure for details. A configure event can be sent at any time. The specified mode must be obeyed by the client. wl-mirror-0.16.5/proto/wayland-protocols/unstable/xdg-foreign/0000755000175000017500000000000014646472005023131 5ustar yrlfyrlfwl-mirror-0.16.5/proto/wayland-protocols/unstable/xdg-foreign/README0000644000175000017500000000010314646472005024003 0ustar yrlfyrlfxdg foreign protocol Maintainers: Jonas Ådahl wl-mirror-0.16.5/proto/wayland-protocols/unstable/xdg-foreign/xdg-foreign-unstable-v1.xml0000644000175000017500000002027614646472005030232 0ustar yrlfyrlf Copyright © 2015-2016 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. This protocol specifies a way for making it possible to reference a surface of a different client. With such a reference, a client can, by using the interfaces provided by this protocol, manipulate the relationship between its own surfaces and the surface of some other client. For example, stack some of its own surface above the other clients surface. In order for a client A to get a reference of a surface of client B, client B must first export its surface using xdg_exporter.export. Upon doing this, client B will receive a handle (a unique string) that it may share with client A in some way (for example D-Bus). After client A has received the handle from client B, it may use xdg_importer.import to create a reference to the surface client B just exported. See the corresponding requests for details. A possible use case for this is out-of-process dialogs. For example when a sandboxed client without file system access needs the user to select a file on the file system, given sandbox environment support, it can export its surface, passing the exported surface handle to an unsandboxed process that can show a file browser dialog and stack it above the sandboxed client's surface. 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. A global interface used for exporting surfaces that can later be imported using xdg_importer. Notify the compositor that the xdg_exporter object will no longer be used. The export request exports the passed surface so that it can later be imported via xdg_importer. When called, a new xdg_exported object will be created and xdg_exported.handle will be sent immediately. See the corresponding interface and event for details. A surface may be exported multiple times, and each exported handle may be used to create an xdg_imported multiple times. Only xdg_surface surfaces may be exported. A global interface used for importing surfaces exported by xdg_exporter. With this interface, a client can create a reference to a surface of another client. Notify the compositor that the xdg_importer object will no longer be used. The import request imports a surface from any client given a handle retrieved by exporting said surface using xdg_exporter.export. When called, a new xdg_imported object will be created. This new object represents the imported surface, and the importing client can manipulate its relationship using it. See xdg_imported for details. An xdg_exported object represents an exported reference to a surface. The exported surface may be referenced as long as the xdg_exported object not destroyed. Destroying the xdg_exported invalidates any relationship the importer may have established using xdg_imported. Revoke the previously exported surface. This invalidates any relationship the importer may have set up using the xdg_imported created given the handle sent via xdg_exported.handle. The handle event contains the unique handle of this exported surface reference. It may be shared with any client, which then can use it to import the surface by calling xdg_importer.import. A handle may be used to import the surface multiple times. An xdg_imported object represents an imported reference to surface exported by some client. A client can use this interface to manipulate relationships between its own surfaces and the imported surface. Notify the compositor that it will no longer use the xdg_imported object. Any relationship that may have been set up will at this point be invalidated. Set the imported surface as the parent of some surface of the client. The passed surface must be a toplevel xdg_surface. Calling this function sets up a surface to surface relation with the same stacking and positioning semantics as xdg_surface.set_parent. The imported surface handle has been destroyed and any relationship set up has been invalidated. This may happen for various reasons, for example if the exported surface or the exported surface handle has been destroyed, if the handle used for importing was invalid. wl-mirror-0.16.5/proto/wayland-protocols/unstable/xdg-foreign/xdg-foreign-unstable-v2.xml0000644000175000017500000002176614646472005030240 0ustar yrlfyrlf Copyright © 2015-2016 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. This protocol specifies a way for making it possible to reference a surface of a different client. With such a reference, a client can, by using the interfaces provided by this protocol, manipulate the relationship between its own surfaces and the surface of some other client. For example, stack some of its own surface above the other clients surface. In order for a client A to get a reference of a surface of client B, client B must first export its surface using xdg_exporter.export_toplevel. Upon doing this, client B will receive a handle (a unique string) that it may share with client A in some way (for example D-Bus). After client A has received the handle from client B, it may use xdg_importer.import_toplevel to create a reference to the surface client B just exported. See the corresponding requests for details. A possible use case for this is out-of-process dialogs. For example when a sandboxed client without file system access needs the user to select a file on the file system, given sandbox environment support, it can export its surface, passing the exported surface handle to an unsandboxed process that can show a file browser dialog and stack it above the sandboxed client's surface. 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. A global interface used for exporting surfaces that can later be imported using xdg_importer. Notify the compositor that the xdg_exporter object will no longer be used. These errors can be emitted in response to invalid xdg_exporter requests. The export_toplevel request exports the passed surface so that it can later be imported via xdg_importer. When called, a new xdg_exported object will be created and xdg_exported.handle will be sent immediately. See the corresponding interface and event for details. A surface may be exported multiple times, and each exported handle may be used to create an xdg_imported multiple times. Only xdg_toplevel equivalent surfaces may be exported, otherwise an invalid_surface protocol error is sent. A global interface used for importing surfaces exported by xdg_exporter. With this interface, a client can create a reference to a surface of another client. Notify the compositor that the xdg_importer object will no longer be used. The import_toplevel request imports a surface from any client given a handle retrieved by exporting said surface using xdg_exporter.export_toplevel. When called, a new xdg_imported object will be created. This new object represents the imported surface, and the importing client can manipulate its relationship using it. See xdg_imported for details. An xdg_exported object represents an exported reference to a surface. The exported surface may be referenced as long as the xdg_exported object not destroyed. Destroying the xdg_exported invalidates any relationship the importer may have established using xdg_imported. Revoke the previously exported surface. This invalidates any relationship the importer may have set up using the xdg_imported created given the handle sent via xdg_exported.handle. The handle event contains the unique handle of this exported surface reference. It may be shared with any client, which then can use it to import the surface by calling xdg_importer.import_toplevel. A handle may be used to import the surface multiple times. An xdg_imported object represents an imported reference to surface exported by some client. A client can use this interface to manipulate relationships between its own surfaces and the imported surface. These errors can be emitted in response to invalid xdg_imported requests. Notify the compositor that it will no longer use the xdg_imported object. Any relationship that may have been set up will at this point be invalidated. Set the imported surface as the parent of some surface of the client. The passed surface must be an xdg_toplevel equivalent, otherwise an invalid_surface protocol error is sent. Calling this function sets up a surface to surface relation with the same stacking and positioning semantics as xdg_toplevel.set_parent. The imported surface handle has been destroyed and any relationship set up has been invalidated. This may happen for various reasons, for example if the exported surface or the exported surface handle has been destroyed, if the handle used for importing was invalid. wl-mirror-0.16.5/proto/wayland-protocols/unstable/xdg-output/0000755000175000017500000000000014646472005023040 5ustar yrlfyrlfwl-mirror-0.16.5/proto/wayland-protocols/unstable/xdg-output/README0000644000175000017500000000011014646472005023710 0ustar yrlfyrlfxdg_output protocol Maintainers: Olivier Fourdan wl-mirror-0.16.5/proto/wayland-protocols/unstable/xdg-output/xdg-output-unstable-v1.xml0000644000175000017500000002271014646472005030043 0ustar yrlfyrlf 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. 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. A global factory interface for xdg_output objects. 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. This creates a new xdg_output object for the given wl_output. 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. Using this request a client can tell the server that it is not going to use the xdg_output object anymore. 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. 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). 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. 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. 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. wl-mirror-0.16.5/proto/wayland-protocols/unstable/xdg-shell/0000755000175000017500000000000014646472005022607 5ustar yrlfyrlfwl-mirror-0.16.5/proto/wayland-protocols/unstable/xdg-shell/README0000644000175000017500000000011314646472005023462 0ustar yrlfyrlfxdg shell protocol Maintainers: Jasper St. Pierre wl-mirror-0.16.5/proto/wayland-protocols/unstable/xdg-shell/xdg-shell-unstable-v5.xml0000644000175000017500000006625314646472005027377 0ustar yrlfyrlf Copyright © 2008-2013 Kristian Høgsberg Copyright © 2013 Rafael Antognolli Copyright © 2013 Jasper St. Pierre Copyright © 2010-2013 Intel Corporation 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. xdg_shell allows clients to turn a wl_surface into a "real window" which can be dragged, resized, stacked, and moved around by the user. Everything about this interface is suited towards traditional desktop environments. The 'current' member of this enum gives the version of the protocol. Implementations can compare this to the version they implement using static_assert to ensure the protocol and implementation versions match. Destroy this xdg_shell object. Destroying a bound xdg_shell object while there are surfaces still alive created by this xdg_shell object instance is illegal and will result in a protocol error. Negotiate the unstable version of the interface. This mechanism is in place to ensure client and server agree on the unstable versions of the protocol that they speak or exit cleanly if they don't agree. This request will go away once the xdg-shell protocol is stable. This creates an xdg_surface for the given surface and gives it the xdg_surface role. A wl_surface can only be given an xdg_surface role once. If get_xdg_surface is called with a wl_surface that already has an active xdg_surface associated with it, or if it had any other role, an error is raised. See the documentation of xdg_surface for more details about what an xdg_surface is and how it is used. This creates an xdg_popup for the given surface and gives it the xdg_popup role. A wl_surface can only be given an xdg_popup role once. If get_xdg_popup is called with a wl_surface that already has an active xdg_popup associated with it, or if it had any other role, an error is raised. This request must be used in response to some sort of user action like a button press, key press, or touch down event. See the documentation of xdg_popup for more details about what an xdg_popup is and how it is used. 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. 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. A compositor is free to ping in any way it wants, but a client must always respond to any xdg_shell object it created. A client must respond to a ping event with a pong request or the client may be deemed unresponsive. An interface that may be implemented by a wl_surface, for implementations that provide a desktop-style user interface. It provides requests to treat surfaces like windows, allowing to set properties like maximized, fullscreen, minimized, and to move and resize them, and associate metadata like title and app id. The client must call wl_surface.commit on the corresponding wl_surface for the xdg_surface state to take effect. Prior to committing the new state, it can set up initial configuration, such as maximizing or setting a window geometry. Even without attaching a buffer the compositor must respond to initial committed configuration, for instance sending a configure event with expected window geometry if the client maximized its surface during initialization. For a surface to be mapped by the compositor the client must have committed both an xdg_surface state and a buffer. Unmap and destroy the window. The window will be effectively hidden from the user's point of view, and all state like maximization, fullscreen, and so on, will be lost. Set the "parent" of this surface. This window should be stacked above a parent. The parent surface must be mapped as long as this surface is mapped. Parent windows should be set on dialogs, toolboxes, or other "auxiliary" surfaces, so that the parent is raised when the dialog is raised. 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. 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". 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] http://standards.freedesktop.org/desktop-entry-spec/ 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. This request must be used in response to some sort of user action like a button press, key press, or touch down event. 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. These values are used to indicate which edge of a surface is being dragged in a resize operation. 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. 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. 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. They will get applied on the next commit. Desktop environments may extend this enum by taking up a range of values and documenting the range they chose in this description. They are not required to document the values for the range that they chose. Ideally, any good extensions from a desktop environment should make its way into standardization into this enum. The current reserved ranges are: 0x0000 - 0x0FFF: xdg-shell core values, documented below. 0x1000 - 0x1FFF: GNOME 0x2000 - 0x2FFF: EFL The surface is maximized. The window geometry specified in the configure event must be obeyed by the client. The surface is fullscreen. The window geometry specified in the configure event must be obeyed by the client. 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. 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. The configure event asks the client to resize its surface or to change its state. 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 need 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 should arrange their surface for the new size and states, and then send a 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. 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, 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. 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. The compositor expects that the most recently received ack_configure request at the time of a commit indicates which configure event the client is responding to. The window geometry of a window 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. The window geometry is double buffered, and will be applied at the time wl_surface.commit of the corresponding wl_surface is called. Once the window geometry of the surface is set once, 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 mode is meant for extremely simple clients. If responding to a configure event, the window geometry in here must respect the sizing negotiations specified by the states in the configure event. The arguments are given in the surface local coordinate space of the wl_surface associated with this xdg_surface. The width and height must be greater than zero. Maximize the surface. After requesting that the surface should be maximized, the compositor will respond by emitting a configure event with the "maximized" state and the required window geometry. The client should then update its content, drawing it in a maximized state, i.e. without shadow or other decoration outside of the window geometry. 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. Note that unrelated compositor side state changes may cause configure events to be emitted at any time, meaning trying to match this request to a specific future configure event is futile. Unmaximize the surface. After requesting that the surface should be unmaximized, the compositor will respond by emitting a configure event without the "maximized" state. If available, the compositor will include the window geometry dimensions the window had prior to being maximized in the configure request. The client must then update its content, drawing it in a regular state, i.e. potentially with shadow, etc. 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. Note that unrelated compositor side state changes may cause configure events to be emitted at any time, meaning trying to match this request to a specific future configure event is futile. Make the surface fullscreen. You can specify an output that you would prefer to be fullscreen. 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 black borders filling the rest of the output. 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. 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 your window. The client may choose to ignore this request, or show a dialog to ask the user to save their data... A popup surface is a short-lived, temporary surface that can be used to implement menus. It takes an explicit grab on the surface that will be dismissed when the user dismisses the 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. When the popup is dismissed, a popup_done event will be sent out, and at the same time the surface will be unmapped. The xdg_popup object is now inert and cannot be reactivated, so clients should destroy it. Explicitly destroying the xdg_popup object will also dismiss the popup and unmap the surface. Clients will receive events for all their surfaces during this grab (which is an "owner-events" grab in X11 parlance). This is done so that users can navigate through submenus and other "nested" popup windows without having to dismiss the topmost popup. Clients that want to dismiss the popup when another surface of their own is clicked should dismiss the popup using the destroy request. The parent surface must have either an xdg_surface or xdg_popup role. Specifying an xdg_popup for the parent 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. If there is an existing popup when creating a new popup, the parent must be the current topmost popup. A parent surface must be mapped before the new popup is mapped. When compositors choose to dismiss a popup, they will likely dismiss every nested popup as well. When a compositor dismisses popups, it will follow the same dismissing order as required from the client. The x and y arguments passed when creating the popup object specify where the top left of the popup should be placed, relative to the local surface coordinates of the parent surface. See xdg_shell.get_xdg_popup. The client must call wl_surface.commit on the corresponding wl_surface for the xdg_popup state to take effect. For a surface to be mapped by the compositor the client must have committed both the xdg_popup state and a buffer. 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, a protocol error will be sent. 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. wl-mirror-0.16.5/proto/wayland-protocols/unstable/xdg-shell/xdg-shell-unstable-v6.xml0000644000175000017500000013254214646472005027373 0ustar yrlfyrlf Copyright © 2008-2013 Kristian Høgsberg Copyright © 2013 Rafael Antognolli Copyright © 2013 Jasper St. Pierre Copyright © 2010-2013 Intel Corporation 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. xdg_shell allows clients to turn a wl_surface into a "real window" which can be dragged, resized, stacked, and moved around by the user. Everything about this interface is suited towards traditional desktop environments. Destroy this xdg_shell object. Destroying a bound xdg_shell object while there are surfaces still alive created by this xdg_shell object instance is illegal and will result in a protocol error. 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. 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. 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. A client must respond to a ping event with a pong request or the client may be deemed unresponsive. See xdg_shell.ping. 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_shell.ping. 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. A compositor is free to ping in any way it wants, but a client must always respond to any xdg_shell object it created. 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 error. Notify the compositor that the xdg_positioner will no longer be used. 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. 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. The rectangle must be at least 1x1 large. 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 zero or negative size is set the invalid_input error is raised. Defines a set of edges for the anchor rectangle. These are used to derive an anchor point that the child surface will be positioned relative to. 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 position of the rectangle); 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. If two parallel anchor edges are specified (e.g. 'left' and 'right'), the invalid_input error is raised. Defines in what direction a surface should be positioned, relative to the anchor point of the parent surface. If two orthogonal gravities are specified (e.g. 'bottom' and 'right'), then the child surface will be placed in the specified direction; otherwise, the child surface will be centered over the anchor point on any axis that had no gravity specified. If two parallel gravities are specified (e.g. 'left' and 'right'), the invalid_input error is raised. 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. Don't alter the surface position even if it is constrained on some axis, for example partially outside the edge of a monitor. 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. 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. 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. 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'. If the adjusted position also ends up being constrained, the resulting position of the flip_y adjustment will be the one before the adjustment. Resize the surface horizontally so that it is completely unconstrained. Resize the surface vertically so that it is completely unconstrained. 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. 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. 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. For a 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 and (3) the client has committed a buffer to the surface. Destroy the xdg_surface object. An xdg_surface must only be destroyed after its role object has been destroyed. If the role object still exists when this request is issued, the zxdg_shell_v6.defunct_surfaces is raised. This creates an xdg_toplevel object for the given xdg_surface and gives the associated wl_surface the xdg_toplevel role. If the surface already had a role, the zxdg_shell_v6.role error is raised. See the documentation of xdg_toplevel for more details about what an xdg_toplevel is and how it is used. This creates an xdg_popup object for the given xdg_surface and gives the associated wl_surface the xdg_popup role. If the surface already had a role, the zxdg_shell_v6.role error is raised. See the documentation of xdg_popup for more details about what an xdg_popup is and how it is used. 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. The window geometry is double buffered, and will be applied at the time wl_surface.commit of the corresponding wl_surface is called. 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. The width and height must be greater than zero. Setting an invalid size will raise an error. 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. 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. 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. If an invalid serial is used, the zxdg_shell_v6.invalid_surface_state error is raised. 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. 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. Unmap and destroy the window. The window will be effectively hidden from the user's point of view, and all state like maximization, fullscreen, and so on, will be lost. Set the "parent" of this surface. This window should be stacked above a parent. The parent surface must be mapped as long as this surface is mapped. Parent windows should be set on dialogs, toolboxes, or other "auxiliary" surfaces, so that the parent is raised when the dialog is raised. 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. 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". 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] http://standards.freedesktop.org/desktop-entry-spec/ 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. This request must be used in response to some sort of user action like a button press, key press, or touch down event. 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. These values are used to indicate which edge of a surface is being dragged in a resize operation. 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. 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. 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. They will get applied on the next commit. The surface is maximized. The window geometry specified in the configure event must be obeyed by the client. If the window geometry is not obyed, the zxdg_shell_v6.invalid_surface_state error is raised. The surface is fullscreen. See set_fullscreen for more information. The surface is being resized. The window geometry specified in the configure event is a maximum; the client cannot resize beyond it. If the client attempts to resize above it, the zxdg_shell_v6.invalid_surface_state error is raised. Clients that have aspect ratio or cell sizing configuration can use a smaller size, however. 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. 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. They will get applied on the next 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 a protocol error. The width and height must be greater than or equal to zero. Using strictly negative values for width and height will result in the zxdg_shell_v6.invalid_surface_state error being raised. 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. They will get applied on the next 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 a protocol error. The width and height must be greater than or equal to zero. Using strictly negative values for width and height will result in the zxdg_shell_v6.invalid_surface_state error being raised. Maximize the surface. After requesting that the surface should be maximized, the compositor will respond by emitting a configure event with the "maximized" state and the required window geometry. The client should then update its content, drawing it in a maximized state, i.e. without shadow or other decoration outside of the window geometry. 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. Note that unrelated compositor side state changes may cause configure events to be emitted at any time, meaning trying to match this request to a specific future configure event is futile. Unmaximize the surface. After requesting that the surface should be unmaximized, the compositor will respond by emitting a configure event without the "maximized" state. If available, the compositor will include the window geometry dimensions the window had prior to being maximized in the configure request. The client must then update its content, drawing it in a regular state, i.e. potentially with shadow, etc. 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. Note that unrelated changes in the state of compositor may cause configure events to be emitted by the compositor between processing this request and emitting corresponding configure event, so trying to match the request with the event is futile. Make the surface fullscreen. You can specify an output that you would prefer to be fullscreen. 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 black borders filling the rest of the output. 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. 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. 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. 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. The parent surface must have either the xdg_toplevel or xdg_popup surface role. 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 x and y arguments passed when creating the popup object specify where the top left of the popup should be placed, relative to the local surface coordinates of the parent surface. See xdg_surface.get_popup. An xdg_popup must intersect with or be at least partially adjacent to its parent surface. The client must call wl_surface.commit on the corresponding wl_surface for the xdg_popup state to take effect. 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, a protocol error will be sent. 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. The parent of a grabbing popup must either be another xdg_popup with an active explicit grab, or an xdg_popup or xdg_toplevel, if there are no explicit grabs already taken. 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. 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. 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. wl-mirror-0.16.5/proto/wayland-protocols/unstable/xwayland-keyboard-grab/0000755000175000017500000000000014646472005025256 5ustar yrlfyrlfwl-mirror-0.16.5/proto/wayland-protocols/unstable/xwayland-keyboard-grab/README0000644000175000017500000000013014646472005026130 0ustar yrlfyrlfXwayland keyboard grabbing protocol Maintainers: Olivier Fourdan ././@LongLink0000644000000000000000000000016000000000000011600 Lustar rootrootwl-mirror-0.16.5/proto/wayland-protocols/unstable/xwayland-keyboard-grab/xwayland-keyboard-grab-unstable-v1.xmlwl-mirror-0.16.5/proto/wayland-protocols/unstable/xwayland-keyboard-grab/xwayland-keyboard-grab-unst0000644000175000017500000001274114646472005032533 0ustar yrlfyrlf 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. This protocol is application-specific to meet the needs of the X11 protocol through Xwayland. It provides a way for Xwayland to request all keyboard events to be forwarded to a surface even when the surface does not have keyboard focus. In the X11 protocol, a client may request an "active grab" on the keyboard. On success, all key events are reported only to the grabbing X11 client. For details, see XGrabKeyboard(3). The core Wayland protocol does not have a notion of an active keyboard grab. When running in Xwayland, X11 applications may acquire an active grab inside Xwayland but that cannot be translated to the Wayland compositor who may set the input focus to some other surface. In doing so, it breaks the X11 client assumption that all key events are reported to the grabbing client. This protocol specifies a way for Xwayland to request all keyboard be directed to the given surface. The protocol does not guarantee that the compositor will honor this request and it does not prescribe user interfaces on how to handle the respond. For example, a compositor may inform the user that all key events are now forwarded to the given client surface, or it may ask the user for permission to do so. Compositors are required to restrict access to this application specific protocol to Xwayland alone. 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. A global interface used for grabbing the keyboard. Destroy the keyboard grab manager. The grab_keyboard request asks for a grab of the keyboard, forcing the keyboard focus for the given seat upon the given surface. The protocol provides no guarantee that the grab is ever satisfied, and does not require the compositor to send an error if the grab cannot ever be satisfied. It is thus possible to request a keyboard grab that will never be effective. The protocol: * does not guarantee that the grab itself is applied for a surface, the grab request may be silently ignored by the compositor, * does not guarantee that any events are sent to this client even if the grab is applied to a surface, * does not guarantee that events sent to this client are exhaustive, a compositor may filter some events for its own consumption, * does not guarantee that events sent to this client are continuous, a compositor may change and reroute keyboard events while the grab is nominally active. A global interface used for grabbing the keyboard. Destroy the grabbed keyboard object. If applicable, the compositor will ungrab the keyboard. wl-mirror-0.16.5/proto/wayland-protocols/wayland-protocols-uninstalled.pc.in0000644000175000017500000000021614646472005026034 0ustar yrlfyrlfpkgdatadir=@abs_top_srcdir@ Name: Wayland Protocols Description: Wayland protocol files (not installed) Version: @WAYLAND_PROTOCOLS_VERSION@ wl-mirror-0.16.5/proto/wayland-protocols/wayland-protocols.pc.in0000644000175000017500000000030014646472005023506 0ustar yrlfyrlfprefix=@prefix@ datarootdir=@datarootdir@ pkgdatadir=${pc_sysrootdir}${datarootdir}/@PACKAGE@ Name: Wayland Protocols Description: Wayland protocol files Version: @WAYLAND_PROTOCOLS_VERSION@ wl-mirror-0.16.5/proto/wayland-protocols/.git/0000755000175000017500000000000014646472005017744 5ustar yrlfyrlfwl-mirror-0.16.5/proto/wlr-protocols/0000755000175000017500000000000014646472005016250 5ustar yrlfyrlfwl-mirror-0.16.5/proto/wlr-protocols/.build.yml0000644000175000017500000000025514646472005020152 0ustar yrlfyrlfimage: archlinux packages: - wayland sources: - https://gitlab.freedesktop.org/wlroots/wlr-protocols.git tasks: - protocols: | cd wlr-protocols make check wl-mirror-0.16.5/proto/wlr-protocols/.editorconfig0000644000175000017500000000031514646472005020724 0ustar yrlfyrlfroot = true [*] end_of_line = lf insert_final_newline = true charset = utf-8 indent_style = tab indent_size = 4 trim_trailing_whitespace = true [*.xml] indent_style = space indent_size = 2 tab_width = 8 wl-mirror-0.16.5/proto/wlr-protocols/.gitlab-ci.yml0000644000175000017500000000011614646472005020702 0ustar yrlfyrlfinclude: https://git.sr.ht/~emersion/dalligi/blob/master/templates/single.yml wl-mirror-0.16.5/proto/wlr-protocols/Makefile0000644000175000017500000000235614646472005017716 0ustar yrlfyrlfPREFIX=/usr DATADIR=$${datarootdir} DATAROOTDIR=$${prefix}/share unstable_protocols = \ unstable/wlr-data-control-unstable-v1.xml \ unstable/wlr-export-dmabuf-unstable-v1.xml \ unstable/wlr-foreign-toplevel-management-unstable-v1.xml \ unstable/wlr-gamma-control-unstable-v1.xml \ unstable/wlr-input-inhibitor-unstable-v1.xml \ unstable/wlr-layer-shell-unstable-v1.xml \ unstable/wlr-output-management-unstable-v1.xml \ unstable/wlr-output-power-management-unstable-v1.xml \ unstable/wlr-screencopy-unstable-v1.xml \ unstable/wlr-virtual-pointer-unstable-v1.xml check: $(unstable_protocols) ./check.sh $(unstable_protocols) clean: rm -f wlr-protocols.pc wlr-protocols.pc: wlr-protocols.pc.in sed \ -e 's:@prefix@:$(PREFIX):g' \ -e 's:@datadir@:$(DATADIR):g' \ -e 's:@datarootdir@:$(DATAROOTDIR):g' \ <$< >$@ install-unstable: $(unstable_protocols) mkdir -p $(DESTDIR)$(PREFIX)/share/wlr-protocols/unstable for protocol in $^ ; \ do \ install -Dm644 $$protocol \ $(DESTDIR)$(PREFIX)/share/wlr-protocols/$$protocol ; \ done install-pc: wlr-protocols.pc mkdir -p $(DESTDIR)$(PREFIX)/share/pkgconfig/ install -Dm644 wlr-protocols.pc \ $(DESTDIR)$(PREFIX)/share/pkgconfig/wlr-protocols.pc install: install-unstable install-pc wl-mirror-0.16.5/proto/wlr-protocols/README.md0000644000175000017500000000060114646472005017524 0ustar yrlfyrlf# wlr-protocols Wayland protocols designed for use in wlroots (and other compositors). ## Submitting changes to existing protocols Please submit a merge request on GitLab. ## Submitting new protocols New protocols should not be submitted to wlr-protocols. Instead, submit them to [wayland-protocols]. [wayland-protocols]: https://gitlab.freedesktop.org/wayland/wayland-protocols wl-mirror-0.16.5/proto/wlr-protocols/check.sh0000755000175000017500000000037614646472005017672 0ustar yrlfyrlf#!/bin/sh -eu for f in "$@" do echo >&2 "Checking $f" wayland-scanner -s client-header "$f" /dev/null wayland-scanner -s server-header "$f" /dev/null wayland-scanner -s public-code "$f" /dev/null wayland-scanner -s private-code "$f" /dev/null done wl-mirror-0.16.5/proto/wlr-protocols/unstable/0000755000175000017500000000000014646472005020065 5ustar yrlfyrlfwl-mirror-0.16.5/proto/wlr-protocols/unstable/wlr-data-control-unstable-v1.xml0000644000175000017500000002741614646472005026151 0ustar yrlfyrlf Copyright © 2018 Simon Ser Copyright © 2019 Ivan Molodetskikh 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. This protocol allows a privileged client to control data devices. In particular, the client will be able to manage the current selection and take the role of a clipboard manager. 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 a manager that allows creating per-seat data device controls. Create a new data source. Create a data device that can be used to manage a seat's selection. All objects created by the manager will still remain valid, until their appropriate destroy request has been called. This interface allows a client to manage a seat's selection. When the seat is destroyed, this object becomes inert. This request asks the compositor to set the selection to the data from the source on behalf of the client. The given source may not be used in any further set_selection or set_primary_selection requests. Attempting to use a previously used source is a protocol error. To unset the selection, set the source to NULL. Destroys the data device object. The data_offer event introduces a new wlr_data_control_offer object, which will subsequently be used in either the wlr_data_control_device.selection event (for the regular clipboard selections) or the wlr_data_control_device.primary_selection event (for the primary clipboard selections). Immediately following the wlr_data_control_device.data_offer event, the new data_offer object will send out wlr_data_control_offer.offer events to describe the MIME types it offers. The selection event is sent out to notify the client of a new wlr_data_control_offer for the selection for this device. The wlr_data_control_device.data_offer and the wlr_data_control_offer.offer events are sent out immediately before this event to introduce the data offer object. The selection event is sent to a client when a new selection is set. The wlr_data_control_offer is valid until a new wlr_data_control_offer or NULL is received. The client must destroy the previous selection wlr_data_control_offer, if any, upon receiving this event. The first selection event is sent upon binding the wlr_data_control_device object. This data control object is no longer valid and should be destroyed by the client. The primary_selection event is sent out to notify the client of a new wlr_data_control_offer for the primary selection for this device. The wlr_data_control_device.data_offer and the wlr_data_control_offer.offer events are sent out immediately before this event to introduce the data offer object. The primary_selection event is sent to a client when a new primary selection is set. The wlr_data_control_offer is valid until a new wlr_data_control_offer or NULL is received. The client must destroy the previous primary selection wlr_data_control_offer, if any, upon receiving this event. If the compositor supports primary selection, the first primary_selection event is sent upon binding the wlr_data_control_device object. This request asks the compositor to set the primary selection to the data from the source on behalf of the client. The given source may not be used in any further set_selection or set_primary_selection requests. Attempting to use a previously used source is a protocol error. To unset the primary selection, set the source to NULL. The compositor will ignore this request if it does not support primary selection. The wlr_data_control_source object is the source side of a wlr_data_control_offer. It is created by the source client in a data transfer and provides a way to describe the offered data and a way to respond to requests to transfer the data. This request adds a MIME type to the set of MIME types advertised to targets. Can be called several times to offer multiple types. Calling this after wlr_data_control_device.set_selection is a protocol error. Destroys the data source object. Request for data from the client. Send the data as the specified MIME type over the passed file descriptor, then close it. This data source is no longer valid. The data source has been replaced by another data source. The client should clean up and destroy this data source. A wlr_data_control_offer represents a piece of data offered for transfer by another client (the source client). The offer describes the different MIME types that the data can be converted to and provides the mechanism for transferring the data directly from the source client. To transfer the offered data, the client issues this request and indicates the MIME type it wants to receive. The transfer happens through the passed file descriptor (typically created with the pipe system call). The source client writes the data in the MIME type representation requested and then closes the file descriptor. The receiving client reads from the read end of the pipe until EOF and then closes its end, at which point the transfer is complete. This request may happen multiple times for different MIME types. Destroys the data offer object. Sent immediately after creating the wlr_data_control_offer object. One event per offered MIME type. wl-mirror-0.16.5/proto/wlr-protocols/unstable/wlr-export-dmabuf-unstable-v1.xml0000644000175000017500000002172714646472005026336 0ustar yrlfyrlf Copyright © 2018 Rostislav Pehlivanov 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. An interface to capture surfaces in an efficient way by exporting DMA-BUFs. 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 object is a manager with which to start capturing from sources. Capture the next frame of an entire output. All objects created by the manager will still remain valid, until their appropriate destroy request has been called. This object represents a single DMA-BUF frame. If the capture is successful, the compositor will first send a "frame" event, followed by one or several "object". When the frame is available for readout, the "ready" event is sent. If the capture failed, the "cancel" event is sent. This can happen anytime before the "ready" event. Once either a "ready" or a "cancel" event is received, the client should destroy the frame. Once an "object" event is received, the client is responsible for closing the associated file descriptor. All frames are read-only and may not be written into or altered. Special flags that should be respected by the client. Main event supplying the client with information about the frame. If the capture didn't fail, this event is always emitted first before any other events. This event is followed by a number of "object" as specified by the "num_objects" argument. Event which serves to supply the client with the file descriptors containing the data for each object. After receiving this event, the client must always close the file descriptor as soon as they're done with it and even if the frame fails. This event is sent as soon as the frame is presented, indicating it is available for reading. This event includes the time at which presentation happened at. The timestamp is expressed as tv_sec_hi, tv_sec_lo, tv_nsec triples, each component being an unsigned 32-bit value. Whole seconds are in tv_sec which is a 64-bit value combined from tv_sec_hi and tv_sec_lo, and the additional fractional part in tv_nsec as nanoseconds. Hence, for valid timestamps tv_nsec must be in [0, 999999999]. The seconds part may have an arbitrary offset at start. After receiving this event, the client should destroy this object. Indicates reason for cancelling the frame. If the capture failed or if the frame is no longer valid after the "frame" event has been emitted, this event will be used to inform the client to scrap the frame. If the failure is temporary, the client may capture again the same source. If the failure is permanent, any further attempts to capture the same source will fail again. After receiving this event, the client should destroy this object. Unreferences the frame. This request must be called as soon as its no longer used. It can be called at any time by the client. The client will still have to close any FDs it has been given. wl-mirror-0.16.5/proto/wlr-protocols/unstable/wlr-foreign-toplevel-management-unstable-v1.xml0000644000175000017500000002644414646472005031155 0ustar yrlfyrlf Copyright © 2018 Ilia Bozhinov 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. The purpose of this protocol is to enable the creation of taskbars and docks by providing them with a list of opened applications and letting them request certain actions on them, like maximizing, etc. After a client binds the zwlr_foreign_toplevel_manager_v1, each opened toplevel window will be sent via the toplevel event This event is emitted whenever a new toplevel window is created. It is emitted for all toplevels, regardless of the app that has created them. All initial details of the toplevel(title, app_id, states, etc.) will be sent immediately after this event via the corresponding events in zwlr_foreign_toplevel_handle_v1. Indicates the client no longer wishes to receive events for new toplevels. However the compositor may emit further toplevel_created events, until the finished event is emitted. The client must not send any more requests after this one. This event indicates that the compositor is done sending events to the zwlr_foreign_toplevel_manager_v1. The server will destroy the object immediately after sending this request, so it will become invalid and the client should free any resources associated with it. A zwlr_foreign_toplevel_handle_v1 object represents an opened toplevel window. Each app may have multiple opened toplevels. Each toplevel has a list of outputs it is visible on, conveyed to the client with the output_enter and output_leave events. This event is emitted whenever the title of the toplevel changes. This event is emitted whenever the app-id of the toplevel changes. This event is emitted whenever the toplevel becomes visible on the given output. A toplevel may be visible on multiple outputs. This event is emitted whenever the toplevel stops being visible on the given output. It is guaranteed that an entered-output event with the same output has been emitted before this event. Requests that the toplevel be maximized. If the maximized state actually changes, this will be indicated by the state event. Requests that the toplevel be unmaximized. If the maximized state actually changes, this will be indicated by the state event. Requests that the toplevel be minimized. If the minimized state actually changes, this will be indicated by the state event. Requests that the toplevel be unminimized. If the minimized state actually changes, this will be indicated by the state event. Request that this toplevel be activated on the given seat. There is no guarantee the toplevel will be actually activated. The different states that a toplevel can have. These have the same meaning as the states with the same names defined in xdg-toplevel This event is emitted immediately after the zlw_foreign_toplevel_handle_v1 is created and each time the toplevel state changes, either because of a compositor action or because of a request in this protocol. This event is sent after all changes in the toplevel state have been sent. This allows changes to the zwlr_foreign_toplevel_handle_v1 properties to be seen as atomic, even if they happen via multiple events. Send a request to the toplevel to close itself. The compositor would typically use a shell-specific method to carry out this request, for example by sending the xdg_toplevel.close event. However, this gives no guarantees the toplevel will actually be destroyed. If and when this happens, the zwlr_foreign_toplevel_handle_v1.closed event will be emitted. The rectangle of the surface specified in this request corresponds to the place where the app using this protocol represents the given toplevel. It can be used by the compositor as a hint for some operations, e.g minimizing. The client is however not required to set this, in which case the compositor is free to decide some default value. If the client specifies more than one rectangle, only the last one is considered. The dimensions are given in surface-local coordinates. Setting width=height=0 removes the already-set rectangle. This event means the toplevel has been destroyed. It is guaranteed there won't be any more events for this zwlr_foreign_toplevel_handle_v1. The toplevel itself becomes inert so any requests will be ignored except the destroy request. Destroys the zwlr_foreign_toplevel_handle_v1 object. This request should be called either when the client does not want to use the toplevel anymore or after the closed event to finalize the destruction of the object. Requests that the toplevel be fullscreened on the given output. If the fullscreen state and/or the outputs the toplevel is visible on actually change, this will be indicated by the state and output_enter/leave events. The output parameter is only a hint to the compositor. Also, if output is NULL, the compositor should decide which output the toplevel will be fullscreened on, if at all. Requests that the toplevel be unfullscreened. If the fullscreen state actually changes, this will be indicated by the state event. This event is emitted whenever the parent of the toplevel changes. No event is emitted when the parent handle is destroyed by the client. wl-mirror-0.16.5/proto/wlr-protocols/unstable/wlr-gamma-control-unstable-v1.xml0000644000175000017500000001260314646472005026312 0ustar yrlfyrlf Copyright © 2015 Giulio camuffo Copyright © 2018 Simon Ser 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. This protocol allows a privileged client to set the gamma tables for outputs. 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 a manager that allows creating per-output gamma controls. Create a gamma control that can be used to adjust gamma tables for the provided output. All objects created by the manager will still remain valid, until their appropriate destroy request has been called. This interface allows a client to adjust gamma tables for a particular output. The client will receive the gamma size, and will then be able to set gamma tables. At any time the compositor can send a failed event indicating that this object is no longer valid. There can only be at most one gamma control object per output, which has exclusive access to this particular output. When the gamma control object is destroyed, the gamma table is restored to its original value. Advertise the size of each gamma ramp. This event is sent immediately when the gamma control object is created. Set the gamma table. The file descriptor can be memory-mapped to provide the raw gamma table, which contains successive gamma ramps for the red, green and blue channels. Each gamma ramp is an array of 16-byte unsigned integers which has the same length as the gamma size. The file descriptor data must have the same length as three times the gamma size. This event indicates that the gamma control is no longer valid. This can happen for a number of reasons, including: - The output doesn't support gamma tables - Setting the gamma tables failed - Another client already has exclusive gamma control for this output - The compositor has transferred gamma control to another client Upon receiving this event, the client should destroy this object. Destroys the gamma control object. If the object is still valid, this restores the original gamma tables. wl-mirror-0.16.5/proto/wlr-protocols/unstable/wlr-input-inhibitor-unstable-v1.xml0000644000175000017500000000651414646472005026702 0ustar yrlfyrlf Copyright © 2018 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 prevent input events from being sent to any surfaces but its own, which is useful for example in lock screen software. It is assumed that access to this interface will be locked down to whitelisted clients by the compositor. Note! This protocol is deprecated and not intended for production use. For screen lockers, use the ext-session-lock-v1 protocol. Activates the input inhibitor. As long as the inhibitor is active, the compositor will not send input events to other clients. While this resource exists, input to clients other than the owner of the inhibitor resource will not receive input events. Any client which previously had focus will receive a leave event and will not be given focus again. The client that owns this resource will receive all input events normally. The compositor will also disable all of its own input processing (such as keyboard shortcuts) while the inhibitor is active. The compositor may continue to send input events to selected clients, such as an on-screen keyboard (via the input-method protocol). Destroy the inhibitor and allow other clients to receive input. wl-mirror-0.16.5/proto/wlr-protocols/unstable/wlr-layer-shell-unstable-v1.xml0000644000175000017500000004403614646472005026000 0ustar yrlfyrlf 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. wl-mirror-0.16.5/proto/wlr-protocols/unstable/wlr-output-management-unstable-v1.xml0000644000175000017500000006226614646472005027236 0ustar yrlfyrlf Copyright © 2019 Purism SPC 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. This protocol exposes interfaces to obtain and modify output device configuration. 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 a manager that allows reading and writing the current output device configuration. Output devices that display pixels (e.g. a physical monitor or a virtual output in a window) are represented as heads. Heads cannot be created nor destroyed by the client, but they can be enabled or disabled and their properties can be changed. Each head may have one or more available modes. Whenever a head appears (e.g. a monitor is plugged in), it will be advertised via the head event. Immediately after the output manager is bound, all current heads are advertised. Whenever a head's properties change, the relevant wlr_output_head events will be sent. Not all head properties will be sent: only properties that have changed need to. Whenever a head disappears (e.g. a monitor is unplugged), a wlr_output_head.finished event will be sent. After one or more heads appear, change or disappear, the done event will be sent. It carries a serial which can be used in a create_configuration request to update heads properties. The information obtained from this protocol should only be used for output configuration purposes. This protocol is not designed to be a generic output property advertisement protocol for regular clients. Instead, protocols such as xdg-output should be used. This event introduces a new head. This happens whenever a new head appears (e.g. a monitor is plugged in) or after the output manager is bound. This event is sent after all information has been sent after binding to the output manager object and after any subsequent changes. This applies to child head and mode objects as well. In other words, this event is sent whenever a head or mode is created or destroyed and whenever one of their properties has been changed. Not all state is re-sent each time the current configuration changes: only the actual changes are sent. This allows changes to the output configuration to be seen as atomic, even if they happen via multiple events. A serial is sent to be used in a future create_configuration request. Create a new output configuration object. This allows to update head properties. Indicates the client no longer wishes to receive events for output configuration changes. However the compositor may emit further events, until the finished event is emitted. The client must not send any more requests after this one. This event indicates that the compositor is done sending manager events. The compositor will destroy the object immediately after sending this event, so it will become invalid and the client should release any resources associated with it. A head is an output device. The difference between a wl_output object and a head is that heads are advertised even if they are turned off. A head object only advertises properties and cannot be used directly to change them. A head has some read-only properties: modes, name, description and physical_size. These cannot be changed by clients. Other properties can be updated via a wlr_output_configuration object. Properties sent via this interface are applied atomically via the wlr_output_manager.done event. No guarantees are made regarding the order in which properties are sent. This event describes the head name. The naming convention is compositor defined, but limited to alphanumeric characters and dashes (-). Each name is unique among all wlr_output_head objects, but if a wlr_output_head object 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. If the compositor implements the xdg-output protocol and this head is enabled, the xdg_output.name event must report the same name. The name event is sent after a wlr_output_head object is created. This event is only sent once per object, and the name does not change over the lifetime of the wlr_output_head object. This event describes a human-readable description of the head. 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'. However, do not assume that the name is a reflection of the make, model, serial of the underlying DRM connector or the display name of the underlying X11 connection, etc. If the compositor implements xdg-output and this head is enabled, the xdg_output.description must report the same description. The description event is sent after a wlr_output_head object is created. This event is only sent once per object, and the description does not change over the lifetime of the wlr_output_head object. This event describes the physical size of the head. This event is only sent if the head has a physical size (e.g. is not a projector or a virtual device). This event introduces a mode for this head. It is sent once per supported mode. This event describes whether the head is enabled. A disabled head is not mapped to a region of the global compositor space. When a head is disabled, some properties (current_mode, position, transform and scale) are irrelevant. This event describes the mode currently in use for this head. It is only sent if the output is enabled. This events describes the position of the head in the global compositor space. It is only sent if the output is enabled. This event describes the transformation currently applied to the head. It is only sent if the output is enabled. This events describes the scale of the head in the global compositor space. It is only sent if the output is enabled. This event indicates that the head is no longer available. The head object becomes inert. Clients should send a destroy request and release any resources associated with it. This event describes the manufacturer of the head. This must report the same make as the wl_output interface does in its geometry event. Together with the model and serial_number events the purpose is to allow clients to recognize heads from previous sessions and for example load head-specific configurations back. It is not guaranteed this event will be ever sent. A reason for that can be that the compositor does not have information about the make of the head or the definition of a make is not sensible in the current setup, for example in a virtual session. Clients can still try to identify the head by available information from other events but should be aware that there is an increased risk of false positives. It is not recommended to display the make string in UI to users. For that the string provided by the description event should be preferred. This event describes the model of the head. This must report the same model as the wl_output interface does in its geometry event. Together with the make and serial_number events the purpose is to allow clients to recognize heads from previous sessions and for example load head-specific configurations back. It is not guaranteed this event will be ever sent. A reason for that can be that the compositor does not have information about the model of the head or the definition of a model is not sensible in the current setup, for example in a virtual session. Clients can still try to identify the head by available information from other events but should be aware that there is an increased risk of false positives. It is not recommended to display the model string in UI to users. For that the string provided by the description event should be preferred. This event describes the serial number of the head. Together with the make and model events the purpose is to allow clients to recognize heads from previous sessions and for example load head- specific configurations back. It is not guaranteed this event will be ever sent. A reason for that can be that the compositor does not have information about the serial number of the head or the definition of a serial number is not sensible in the current setup. Clients can still try to identify the head by available information from other events but should be aware that there is an increased risk of false positives. It is not recommended to display the serial_number string in UI to users. For that the string provided by the description event should be preferred. This request indicates that the client will no longer use this head object. This event describes whether adaptive sync is currently enabled for the head or not. Adaptive sync is also known as Variable Refresh Rate or VRR. This object describes an output mode. Some heads don't support output modes, in which case modes won't be advertised. Properties sent via this interface are applied atomically via the wlr_output_manager.done event. No guarantees are made regarding the order in which properties are sent. This event describes the mode size. The size is given in physical hardware units of the output device. This is not necessarily the same as the output size in the global compositor space. For instance, the output may be scaled or transformed. This event describes the mode's fixed vertical refresh rate. It is only sent if the mode has a fixed refresh rate. This event advertises this mode as preferred. This event indicates that the mode is no longer available. The mode object becomes inert. Clients should send a destroy request and release any resources associated with it. This request indicates that the client will no longer use this mode object. This object is used by the client to describe a full output configuration. First, the client needs to setup the output configuration. Each head can be either enabled (and configured) or disabled. It is a protocol error to send two enable_head or disable_head requests with the same head. It is a protocol error to omit a head in a configuration. Then, the client can apply or test the configuration. The compositor will then reply with a succeeded, failed or cancelled event. Finally the client should destroy the configuration object. Enable a head. This request creates a head configuration object that can be used to change the head's properties. Disable a head. Apply the new output configuration. In case the configuration is successfully applied, there is no guarantee that the new output state matches completely the requested configuration. For instance, a compositor might round the scale if it doesn't support fractional scaling. After this request has been sent, the compositor must respond with an succeeded, failed or cancelled event. Sending a request that isn't the destructor is a protocol error. Test the new output configuration. The configuration won't be applied, but will only be validated. Even if the compositor succeeds to test a configuration, applying it may fail. After this request has been sent, the compositor must respond with an succeeded, failed or cancelled event. Sending a request that isn't the destructor is a protocol error. Sent after the compositor has successfully applied the changes or tested them. Upon receiving this event, the client should destroy this object. If the current configuration has changed, events to describe the changes will be sent followed by a wlr_output_manager.done event. Sent if the compositor rejects the changes or failed to apply them. The compositor should revert any changes made by the apply request that triggered this event. Upon receiving this event, the client should destroy this object. Sent if the compositor cancels the configuration because the state of an output changed and the client has outdated information (e.g. after an output has been hotplugged). The client can create a new configuration with a newer serial and try again. Upon receiving this event, the client should destroy this object. Using this request a client can tell the compositor that it is not going to use the configuration object anymore. Any changes to the outputs that have not been applied will be discarded. This request also destroys wlr_output_configuration_head objects created via this object. This object is used by the client to update a single head's configuration. It is a protocol error to set the same property twice. This request sets the head's mode. This request assigns a custom mode to the head. The size is given in physical hardware units of the output device. If set to zero, the refresh rate is unspecified. It is a protocol error to set both a mode and a custom mode. This request sets the head's position in the global compositor space. This request sets the head's transform. This request sets the head's scale. This request enables/disables adaptive sync. Adaptive sync is also known as Variable Refresh Rate or VRR. wl-mirror-0.16.5/proto/wlr-protocols/unstable/wlr-output-power-management-unstable-v1.xml0000644000175000017500000001273514646472005030364 0ustar yrlfyrlf Copyright © 2019 Purism SPC 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. This protocol allows clients to control power management modes of outputs that are currently part of the compositor space. The intent is to allow special clients like desktop shells to power down outputs when the system is idle. To modify outputs not currently part of the compositor space see wlr-output-management. 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 a manager that allows creating per-output power management mode controls. Create an output power management mode control that can be used to adjust the power management mode for a given output. All objects created by the manager will still remain valid, until their appropriate destroy request has been called. This object offers requests to set the power management mode of an output. Set an output's power save mode to the given mode. The mode change is effective immediately. If the output does not support the given mode a failed event is sent. Report the power management mode change of an output. The mode event is sent after an output changed its power management mode. The reason can be a client using set_mode or the compositor deciding to change an output's mode. This event is also sent immediately when the object is created so the client is informed about the current power management mode. This event indicates that the output power management mode control is no longer valid. This can happen for a number of reasons, including: - The output doesn't support power management - Another client already has exclusive power management mode control for this output - The output disappeared Upon receiving this event, the client should destroy this object. Destroys the output power management mode control object. wl-mirror-0.16.5/proto/wlr-protocols/unstable/wlr-screencopy-unstable-v1.xml0000644000175000017500000002366614646472005025737 0ustar yrlfyrlf Copyright © 2018 Simon Ser Copyright © 2019 Andri Yngvason 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. This protocol allows clients to ask the compositor to copy part of the screen content to a client buffer. 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 object is a manager which offers requests to start capturing from a source. Capture the next frame of an entire output. Capture the next frame of an output's region. The region is given in output logical coordinates, see xdg_output.logical_size. The region will be clipped to the output's extents. All objects created by the manager will still remain valid, until their appropriate destroy request has been called. This object represents a single frame. When created, a series of buffer events will be sent, each representing a supported buffer type. The "buffer_done" event is sent afterwards to indicate that all supported buffer types have been enumerated. The client will then be able to send a "copy" request. If the capture is successful, the compositor will send a "flags" followed by a "ready" event. For objects version 2 or lower, wl_shm buffers are always supported, ie. the "buffer" event is guaranteed to be sent. If the capture failed, the "failed" event is sent. This can happen anytime before the "ready" event. Once either a "ready" or a "failed" event is received, the client should destroy the frame. Provides information about wl_shm buffer parameters that need to be used for this frame. This event is sent once after the frame is created if wl_shm buffers are supported. Copy the frame to the supplied buffer. The buffer must have a the correct size, see zwlr_screencopy_frame_v1.buffer and zwlr_screencopy_frame_v1.linux_dmabuf. The buffer needs to have a supported format. If the frame is successfully copied, a "flags" and a "ready" events are sent. Otherwise, a "failed" event is sent. Provides flags about the frame. This event is sent once before the "ready" event. Called as soon as the frame is copied, indicating it is available for reading. This event includes the time at which presentation happened at. The timestamp is expressed as tv_sec_hi, tv_sec_lo, tv_nsec triples, each component being an unsigned 32-bit value. Whole seconds are in tv_sec which is a 64-bit value combined from tv_sec_hi and tv_sec_lo, and the additional fractional part in tv_nsec as nanoseconds. Hence, for valid timestamps tv_nsec must be in [0, 999999999]. The seconds part may have an arbitrary offset at start. After receiving this event, the client should destroy the object. This event indicates that the attempted frame copy has failed. After receiving this event, the client should destroy the object. Destroys the frame. This request can be sent at any time by the client. Same as copy, except it waits until there is damage to copy. This event is sent right before the ready event when copy_with_damage is requested. It may be generated multiple times for each copy_with_damage request. The arguments describe a box around an area that has changed since the last copy request that was derived from the current screencopy manager instance. The union of all regions received between the call to copy_with_damage and a ready event is the total damage since the prior ready event. Provides information about linux-dmabuf buffer parameters that need to be used for this frame. This event is sent once after the frame is created if linux-dmabuf buffers are supported. This event is sent once after all buffer events have been sent. The client should proceed to create a buffer of one of the supported types, and send a "copy" request. wl-mirror-0.16.5/proto/wlr-protocols/unstable/wlr-virtual-pointer-unstable-v1.xml0000644000175000017500000001535714646472005026727 0ustar yrlfyrlf Copyright © 2019 Josef Gajdusek 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. This protocol allows clients to emulate a physical pointer device. The requests are mostly mirror opposites of those specified in wl_pointer. The pointer has moved by a relative amount to the previous request. Values are in the global compositor space. The pointer has moved in an absolute coordinate frame. Value of x can range from 0 to x_extent, value of y can range from 0 to y_extent. A button was pressed or released. Scroll and other axis requests. Indicates the set of events that logically belong together. Source information for scroll and other axis. Stop notification for scroll and other axes. Discrete step information for scroll and other axes. This event allows the client to extend data normally sent using the axis event with discrete value. This object allows clients to create individual virtual pointer objects. Creates a new virtual pointer. The optional seat is a suggestion to the compositor. Creates a new virtual pointer. The seat and the output arguments are optional. If the seat argument is set, the compositor should assign the input device to the requested seat. If the output argument is set, the compositor should map the input device to the requested output. wl-mirror-0.16.5/proto/wlr-protocols/wlr-protocols.pc.in0000644000175000017500000000025714646472005022033 0ustar yrlfyrlfprefix=@prefix@ datarootdir=@datarootdir@ pkgdatadir=${pc_sysrootdir}@datadir@/wlr-protocols Name: wlroots Wayland protocols Description: Wayland protocol files Version: 1.0 wl-mirror-0.16.5/proto/wlr-protocols/.git/0000755000175000017500000000000014646472005017111 5ustar yrlfyrlfwl-mirror-0.16.5/scripts/0000755000175000017500000000000014646471773013761 5ustar yrlfyrlfwl-mirror-0.16.5/scripts/release.sh0000755000175000017500000000340414646471773015741 0ustar yrlfyrlf#!/bin/bash set -euo pipefail SCRIPTDIR=$(realpath "$(dirname "${BASH_SOURCE[0]}")") REPODIR=$(realpath "$SCRIPTDIR/..") TEMPDIR=$(mktemp -d) cleanup() { if [[ ! -z "$TEMPDIR" && -d "$TEMPDIR" ]]; then rm -rf "$TEMPDIR" fi } trap cleanup EXIT cd "$REPODIR" TAGS=( $(git tag -l --contains HEAD) ) NUM_TAGS="${#TAGS[@]}" if [[ $NUM_TAGS -eq 0 ]]; then echo "error: no tag on current commit" exit 1 elif [[ $NUM_TAGS -gt 1 ]]; then echo "error: multiple tags on current commit" echo "info: found tags ( ${TAGS[@]} )" exit 1 fi TAG="${TAGS[0]}" if [[ ! $TAG =~ v[0-9]+.[0-9]+.[0-9]+ ]]; then echo "error: tag does not match version regex" echo "info: tag was $TAG" exit 1 fi VERSION="${TAG##v}" echo ">> creating release $VERSION" echo "- cloning repo" cd "$TEMPDIR" git clone --recursive "$REPODIR" "wl-mirror-$VERSION" echo "- removing unneeded files" rm -rf "wl-mirror-$VERSION/.git" rm -rf "wl-mirror-$VERSION/.gitignore" rm -rf "wl-mirror-$VERSION/.gitmodules" rm -rf "wl-mirror-$VERSION/proto/wayland-protocols/.git" rm -rf "wl-mirror-$VERSION/proto/wlr-protocols/.git" mkdir -p "wl-mirror-$VERSION/proto/wayland-protocols/.git" mkdir -p "wl-mirror-$VERSION/proto/wlr-protocols/.git" echo "- adding version file" echo "$TAG" > "wl-mirror-$VERSION/version.txt" echo "- creating archive" tar caf "$REPODIR/wl-mirror-$VERSION.tar.gz" "wl-mirror-$VERSION/" if [[ ! -z "${SIGKEY+z}" ]]; then echo "- signing archive" gpg --yes -u "$SIGKEY" -o "$REPODIR/wl-mirror-$VERSION.tar.gz.asc" --armor --detach-sig "$REPODIR/wl-mirror-$VERSION.tar.gz" gpg --yes -o "$REPODIR/wl-mirror-$VERSION.tar.gz.sig" --dearmor "$REPODIR/wl-mirror-$VERSION.tar.gz.asc" else echo "- skipping signing archive (SIGKEY not set)" fi echo "- success" wl-mirror-0.16.5/scripts/wl-present0000755000175000017500000001207514646471773016014 0ustar yrlfyrlf#!/bin/bash usage() { echo "usage: wl-present [argument]" echo echo "start wl-mirror and control the mirrored output and region in a convenient way" echo echo "commands:" echo " help show this help" echo " mirror [output] [options] start wl-mirror on output [output] (default asks via slurp)" echo " set-output [output] set the recorded output (default asks via slurp)" echo " set-region [region] set the recorded region (default asks via slurp)" echo " unset-region unset the recorded region" echo " set-scaling [scale] set the scaling mode (default asks via rofi)" echo " freeze freeze the screen" echo " unfreeze resume the screen capture after freeze" echo " toggle-freeze toggle freeze state of screen capture" echo " fullscreen fullscreen the wl-mirror window" echo " unfullscreen unfullscreen the wl-mirror window" echo " fullscreen-output [output] set the output to fullscreen to (default asks via slurp)" echo " no-fullscreen-output set the output to fullscreen to the current output" echo " custom [options] send custom options to wl-mirror (default asks via rofi)" echo echo "dependencies:" echo " wl-mirror, bash, slurp, pipectl (optional), and either wofi, wmenu, rofi, fuzzel, or dmenu" echo echo "environment variables": echo " WL_PRESENT_DMENU overrides the used dmenu implementation" echo " WL_PRESENT_PIPECTL overrides the used pipectl implementation" echo " WL_PRESENT_SLURP overrides the used slurp implementation" exit 0 } if [[ -n "$WL_PRESENT_DMENU" ]]; then DMENU="$WL_PRESENT_DMENU" elif type -p wofi >/dev/null; then DMENU="wofi -d" elif type -p wmenu >/dev/null; then DMENU=wmenu elif type -p fuzzel >/dev/null; then DMENU="fuzzel -d" elif type -p rofi >/dev/null; then DMENU="rofi -dmenu" else DMENU=dmenu fi if [[ -n "$WL_PRESENT_PIPECTL" ]]; then PIPECTL="$WL_PRESENT_PIPECTL" elif type -p pipectl >/dev/null; then PIPECTL=pipectl else PIPECTL=pipectl-shim fi if [[ -n "$WL_PRESENT_SLURP" ]]; then SLURP="$WL_PRESENT_SLURP" else SLURP=slurp fi pipectl-shim() { PIPEPATH="${XDG_RUNTIME_DIR:-"${TMPDIR:-/tmp}"}" PIPENAME="pipectl.$(id -u).pipe" MODE= while [[ $# -gt 0 && "${1:0:1}" == "-" ]]; do opt="$1" shift case "$opt" in -n|--name) arg="$1"; shift; PIPENAME="pipectl.$(id -u).$arg.pipe";; -i) MODE=in;; -o) MODE=out;; esac done PIPE="$PIPEPATH/$PIPENAME" case "$MODE" in "in") test -p "$PIPE" && cat > "$PIPE";; "out") rm -f "$PIPE"; mkfifo "$PIPE"; tail -f "$PIPE"; rm -f "$PIPE";; esac } slurp-output() { $SLURP -or -f '%o' 2>/dev/null } slurp-region() { $SLURP 2>/dev/null } slurp-output-or-region() { $SLURP -o -f '%o|%x,%y %wx%h' 2>/dev/null } mirror() { if [[ "$#" -eq 0 || "$1" =~ ^- ]]; then OUTPUT_REGION=$(ask-output-or-region) IFS='|' read -r OUTPUT REGION <<< "$OUTPUT_REGION" mirror "$OUTPUT" -r "$REGION" "$@" return fi OUTPUT="$1" shift $PIPECTL -n wl-present -o | wl-mirror -S "$@" "$OUTPUT" } mirror-cmd() { $PIPECTL -n wl-present -i <<< "$1" } set-output() { mirror-cmd "$1" } set-region() { mirror-cmd "-r '$1'" } set-scaling() { mirror-cmd "-s $1" } set-fullscreen-output() { mirror-cmd "--fullscreen-output $1" } ask-output() { slurp-output [[ $? -ne 0 ]] && exit 1 } ask-region() { slurp-region [[ $? -ne 0 ]] && exit 1 } ask-output-or-region() { slurp-output-or-region [[ $? -ne 0 ]] && exit 1 } ask-scaling() { (echo fit; echo cover; echo exact; echo linear; echo nearest) | $DMENU -p "wl-present scaling" [[ $? -ne 0 ]] && exit 1 } ask-custom() { cat < #include #include #include #include #include #include #include "context.h" #include "egl.h" #include "transform.h" #include "glsl_vertex_shader.h" #include "glsl_fragment_shader.h" #include "util.h" // --- buffers --- const float vertex_array[] = { -1.0, -1.0, 0.0, 0.0, 1.0, -1.0, 1.0, 0.0, -1.0, 1.0, 0.0, 1.0, -1.0, 1.0, 0.0, 1.0, 1.0, -1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0 }; // --- has_extension --- static bool has_extension(const char * extension) { size_t ext_len = strlen(extension); // try to find extension in extension list const char * extensions = (const char *)glGetString(GL_EXTENSIONS); char * match = strstr(extensions, extension); // verify match was not a substring of another extension bool found = ( match != NULL && (match == extensions || match[-1] == ' ') && (match[ext_len] == '\0' || match[ext_len] == ' ') ); return found; } // --- init_egl --- void init_egl(ctx_t * ctx) { // initialize context structure ctx->egl.display = EGL_NO_DISPLAY; ctx->egl.context = EGL_NO_CONTEXT; ctx->egl.config = EGL_NO_CONFIG_KHR; ctx->egl.surface = EGL_NO_SURFACE; ctx->egl.window = EGL_NO_SURFACE; ctx->egl.glEGLImageTargetTexture2DOES = NULL; ctx->egl.width = 1; ctx->egl.height = 1; ctx->egl.format = 0; ctx->egl.vbo = 0; ctx->egl.texture = 0; ctx->egl.freeze_texture = 0; ctx->egl.freeze_framebuffer = 0; ctx->egl.shader_program = 0; ctx->egl.texture_transform_uniform = 0; ctx->egl.invert_colors_uniform = 0; ctx->egl.texture_region_aware = false; ctx->egl.texture_initialized = false; ctx->egl.initialized = true; // create egl display ctx->egl.display = eglGetDisplay((EGLNativeDisplayType)ctx->wl.display); if (ctx->egl.display == EGL_NO_DISPLAY) { log_error("egl::init(): failed to create EGL display\n"); exit_fail(ctx); } // initialize egl display and check egl version EGLint major, minor; if (eglInitialize(ctx->egl.display, &major, &minor) != EGL_TRUE) { log_error("egl::init(): failed to initialize EGL display\n"); exit_fail(ctx); } log_debug(ctx, "egl::init(): initialized EGL %d.%d\n", major, minor); // find an egl config with // - window support // - OpenGL ES 2.0 support // - RGB888 texture support EGLint num_configs; EGLint config_attribs[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_NONE }; if (eglChooseConfig(ctx->egl.display, config_attribs, &ctx->egl.config, 1, &num_configs) != EGL_TRUE) { log_error("egl::init(): failed to get EGL config\n"); exit_fail(ctx); } // default window size to 100x100 if not set if (ctx->wl.width == 0) ctx->wl.width = 100; if (ctx->wl.height == 0) ctx->wl.height = 100; // create egl window ctx->egl.window = wl_egl_window_create(ctx->wl.surface, ctx->wl.width, ctx->wl.height); if (ctx->egl.window == EGL_NO_SURFACE) { log_error("egl::init(): failed to create EGL window\n"); exit_fail(ctx); } // create egl surface ctx->egl.surface = eglCreateWindowSurface(ctx->egl.display, ctx->egl.config, (EGLNativeWindowType)ctx->egl.window, NULL); // create egl context with support for OpenGL ES 2.0 EGLint context_attribs[] = { EGL_CONTEXT_MAJOR_VERSION, 2, EGL_CONTEXT_MINOR_VERSION, 0, EGL_NONE }; ctx->egl.context = eglCreateContext(ctx->egl.display, ctx->egl.config, EGL_NO_CONTEXT, context_attribs); if (ctx->egl.context == EGL_NO_CONTEXT) { log_error("egl::init(): failed to create EGL context\n"); exit_fail(ctx); } // activate egl context if (eglMakeCurrent(ctx->egl.display, ctx->egl.surface, ctx->egl.surface, ctx->egl.context) != EGL_TRUE) { log_error("egl::init(): failed to activate EGL context\n"); exit_fail(ctx); } // check for needed extensions // - GL_OES_EGL_image: for converting EGLImages to GL textures if (!has_extension("GL_OES_EGL_image")) { log_error("egl::init(): missing EGL extension GL_OES_EGL_image\n"); exit_fail(ctx); } // get pointers to functions provided by extensions // - glEGLImageTargetTexture2DOES: for converting EGLImages to GL textures ctx->egl.glEGLImageTargetTexture2DOES = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)eglGetProcAddress("glEGLImageTargetTexture2DOES"); if (ctx->egl.glEGLImageTargetTexture2DOES == NULL) { log_error("egl::init(): failed to get pointer to glEGLImageTargetTexture2DOES\n"); exit_fail(ctx); } // create vertex buffer object glGenBuffers(1, &ctx->egl.vbo); glBindBuffer(GL_ARRAY_BUFFER, ctx->egl.vbo); glBufferData(GL_ARRAY_BUFFER, sizeof vertex_array, vertex_array, GL_STATIC_DRAW); // create texture and set scaling mode glGenTextures(1, &ctx->egl.texture); glBindTexture(GL_TEXTURE_2D, ctx->egl.texture); if (ctx->opt.scaling_filter == SCALE_FILTER_LINEAR) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } else { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); } // create freeze texture and set scaling mode glGenTextures(1, &ctx->egl.freeze_texture); glBindTexture(GL_TEXTURE_2D, ctx->egl.freeze_texture); if (ctx->opt.scaling_filter == SCALE_FILTER_LINEAR) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } else { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); } // create freeze framebuffer glGenFramebuffers(1, &ctx->egl.freeze_framebuffer); glBindFramebuffer(GL_FRAMEBUFFER, ctx->egl.freeze_framebuffer); glBindTexture(GL_TEXTURE_2D, ctx->egl.texture); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ctx->egl.texture, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0); // error log for shader compilation error messages GLint success; const char * shader_source = NULL; char errorLog[1024] = { 0 }; // compile vertex shader shader_source = glsl_vertex_shader; GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertex_shader, 1, &shader_source, NULL); glCompileShader(vertex_shader); glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &success); if (success != GL_TRUE) { glGetShaderInfoLog(vertex_shader, sizeof errorLog, NULL, errorLog); errorLog[strcspn(errorLog, "\n")] = '\0'; log_error("egl::init(): failed to compile vertex shader: %s\n", errorLog); glDeleteShader(vertex_shader); exit_fail(ctx); } // compile fragment shader shader_source = glsl_fragment_shader; GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragment_shader, 1, &shader_source, NULL); glCompileShader(fragment_shader); glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &success); if (success != GL_TRUE) { glGetShaderInfoLog(fragment_shader, sizeof errorLog, NULL, errorLog); errorLog[strcspn(errorLog, "\n")] = '\0'; log_error("egl::init(): failed to compile fragment shader: %s\n", errorLog); glDeleteShader(vertex_shader); glDeleteShader(fragment_shader); exit_fail(ctx); } // create shader program and get pointers to shader uniforms ctx->egl.shader_program = glCreateProgram(); glAttachShader(ctx->egl.shader_program, vertex_shader); glAttachShader(ctx->egl.shader_program, fragment_shader); glLinkProgram(ctx->egl.shader_program); glGetProgramiv(ctx->egl.shader_program, GL_LINK_STATUS, &success); if (success != GL_TRUE) { log_error("egl::init(): failed to link shader program\n"); glDeleteShader(vertex_shader); glDeleteShader(fragment_shader); glDeleteProgram(ctx->egl.shader_program); exit_fail(ctx); } ctx->egl.texture_transform_uniform = glGetUniformLocation(ctx->egl.shader_program, "uTexTransform"); ctx->egl.invert_colors_uniform = glGetUniformLocation(ctx->egl.shader_program, "uInvertColors"); glUseProgram(ctx->egl.shader_program); glDeleteShader(vertex_shader); glDeleteShader(fragment_shader); // set initial texture transform matrix mat3_t texture_transform; mat3_identity(&texture_transform); glUniformMatrix3fv(ctx->egl.texture_transform_uniform, 1, false, (float *)texture_transform.data); // set invert colors uniform bool invert_colors = ctx->opt.invert_colors; glUniform1i(ctx->egl.invert_colors_uniform, invert_colors); // set GL clear color to back and set GL vertex layout glClearColor(0.0, 0.0, 0.0, 1); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof (float), (void *)(0 * sizeof (float))); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof (float), (void *)(2 * sizeof (float))); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); // draw initial frame draw_texture(ctx); if (eglSwapBuffers(ctx->egl.display, ctx->egl.surface) != EGL_TRUE) { log_error("egl::init(): failed to swap buffers\n"); exit_fail(ctx); } } // --- draw_texture --- void draw_texture(ctx_t *ctx) { glBindTexture(GL_TEXTURE_2D, ctx->opt.freeze ? ctx->egl.freeze_texture : ctx->egl.texture); glClear(GL_COLOR_BUFFER_BIT); if (ctx->egl.texture_initialized) { glDrawArrays(GL_TRIANGLES, 0, 6); } } // --- resize_viewport void resize_viewport(ctx_t * ctx) { log_debug(ctx, "egl::resize_viewport(): resizing viewport\n"); uint32_t win_width = round(ctx->wl.width * ctx->wl.scale); uint32_t win_height = round(ctx->wl.height * ctx->wl.scale); uint32_t tex_width = ctx->egl.width; uint32_t tex_height = ctx->egl.height; uint32_t view_width = win_width; uint32_t view_height = win_height; // rotate texture dimensions by output transform if (ctx->egl.texture_initialized) { viewport_apply_output_transform(&tex_width, &tex_height, ctx->mirror.current_target->transform); } // clamp texture dimensions to specified region region_t output_region; region_t clamp_region; if (ctx->egl.texture_initialized && ctx->opt.has_region && !ctx->egl.texture_region_aware) { output_region = (region_t){ .x = 0, .y = 0, .width = tex_width, .height = tex_height }; clamp_region = ctx->mirror.current_region; // HACK: calculate effective output fractional scale // wayland doesn't provide this information double output_scale = (double)tex_width / ctx->mirror.current_target->width; region_scale(&clamp_region, output_scale); region_clamp(&clamp_region, &output_region); tex_width = clamp_region.width; tex_height = clamp_region.height; } // rotate texture dimensions by user transform viewport_apply_transform(&tex_width, &tex_height, ctx->opt.transform); // calculate aspect ratio double win_aspect = (double)win_width / win_height; double tex_aspect = (double)tex_width / tex_height; if (ctx->opt.scaling == SCALE_FIT) { // select biggest width or height that fits and preserves aspect ratio if (win_aspect > tex_aspect) { view_width = view_height * tex_aspect; } else if (win_aspect < tex_aspect) { view_height = view_width / tex_aspect; } } else if (ctx->opt.scaling == SCALE_COVER) { // select biggest width or height that covers and preserves aspect ratio if (win_aspect < tex_aspect) { view_width = view_height * tex_aspect; } else if (win_aspect > tex_aspect) { view_height = view_width / tex_aspect; } } else if (ctx->opt.scaling == SCALE_EXACT) { // select biggest fitting integer scale double width_scale = (double)win_width / tex_width; double height_scale = (double)win_height / tex_height; uint32_t upscale_factor = floorf(fminf(width_scale, height_scale)); uint32_t downscale_factor = ceilf(fmaxf(1 / width_scale, 1 / height_scale)); if (upscale_factor > 1) { log_debug(ctx, "egl::resize_viewport(): upscaling by factor = %d\n", upscale_factor); view_width = tex_width * upscale_factor; view_height = tex_height * upscale_factor; } else if (downscale_factor > 1) { log_debug(ctx, "egl::resize_viewport(): downscaling by factor = %d\n", downscale_factor); view_width = tex_width / downscale_factor; view_height = tex_height / downscale_factor; } else { view_width = tex_width; view_height = tex_height; } } log_debug(ctx, "egl::resize_viewport(): win_width = %d, win_height = %d\n", win_width, win_height); log_debug(ctx, "egl::resize_viewport(): view_width = %d, view_height = %d\n", view_width, view_height); // updating GL viewport log_debug(ctx, "egl::resize_viewport(): viewport %d, %d, %d, %d\n", (int32_t)(win_width - view_width) / 2, (int32_t)(win_height - view_height) / 2, view_width, view_height ); glViewport((int32_t)(win_width - view_width) / 2, (int32_t)(win_height - view_height) / 2, view_width, view_height); // recalculate texture transform mat3_t texture_transform; mat3_identity(&texture_transform); if (ctx->egl.texture_initialized) { // apply transformations in reverse order as we need to transform // from OpenGL space to texture space mat3_apply_invert_y(&texture_transform, true); mat3_apply_transform(&texture_transform, ctx->opt.transform); if (ctx->opt.has_region && !ctx->egl.texture_region_aware) { mat3_apply_region_transform(&texture_transform, &clamp_region, &output_region); } mat3_apply_output_transform(&texture_transform, ctx->mirror.current_target->transform); mat3_apply_invert_y(&texture_transform, ctx->mirror.invert_y); } // set texture transform matrix uniform // - GL matrices are stored in column-major order, so transpose the matrix mat3_transpose(&texture_transform); glUniformMatrix3fv(ctx->egl.texture_transform_uniform, 1, false, (float *)texture_transform.data); } // --- resize_window --- void resize_window(ctx_t * ctx) { uint32_t width = round(ctx->wl.width * ctx->wl.scale); uint32_t height = round(ctx->wl.height * ctx->wl.scale); log_debug(ctx, "egl::resize_window(): resizing EGL window to %dx%d\n", width, height); // resize window, then trigger viewport recalculation wl_egl_window_resize(ctx->egl.window, width, height, 0, 0); wp_viewport_set_source(ctx->wl.viewport, 0, 0, wl_fixed_from_int(width), wl_fixed_from_int(height)); resize_viewport(ctx); // redraw frame draw_texture(ctx); if (eglSwapBuffers(ctx->egl.display, ctx->egl.surface) != EGL_TRUE) { log_error("egl::resize_window(): failed to swap buffers\n"); exit_fail(ctx); } } // --- update_uniforms --- void update_uniforms(ctx_t * ctx) { // trigger viewport recalculation resize_viewport(ctx); // set invert colors uniform bool invert_colors = ctx->opt.invert_colors; glUniform1i(ctx->egl.invert_colors_uniform, invert_colors); // set texture scaling mode glBindTexture(GL_TEXTURE_2D, ctx->egl.texture); if (ctx->opt.scaling_filter == SCALE_FILTER_LINEAR) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } else { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); } glBindTexture(GL_TEXTURE_2D, ctx->egl.freeze_texture); if (ctx->opt.scaling_filter == SCALE_FILTER_LINEAR) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } else { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); } } // --- freeze_framebuffer --- void freeze_framebuffer(struct ctx * ctx) { glBindFramebuffer(GL_FRAMEBUFFER, ctx->egl.freeze_framebuffer); glBindTexture(GL_TEXTURE_2D, ctx->egl.freeze_texture); glCopyTexImage2D(GL_TEXTURE_2D, 0, ctx->egl.format, 0, 0, ctx->egl.width, ctx->egl.height, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0); } // --- dmabuf_to_texture --- static const EGLAttrib fd_attribs[] = { EGL_DMA_BUF_PLANE0_FD_EXT, EGL_DMA_BUF_PLANE1_FD_EXT, EGL_DMA_BUF_PLANE2_FD_EXT, EGL_DMA_BUF_PLANE3_FD_EXT }; _Static_assert(ARRAY_LENGTH(fd_attribs) == MAX_PLANES, "fd_attribs has incorrect length"); static const EGLAttrib offset_attribs[] = { EGL_DMA_BUF_PLANE0_OFFSET_EXT, EGL_DMA_BUF_PLANE1_OFFSET_EXT, EGL_DMA_BUF_PLANE2_OFFSET_EXT, EGL_DMA_BUF_PLANE3_OFFSET_EXT }; _Static_assert(ARRAY_LENGTH(offset_attribs) == MAX_PLANES, "offset_attribs has incorrect length"); static const EGLAttrib stride_attribs[] = { EGL_DMA_BUF_PLANE0_PITCH_EXT, EGL_DMA_BUF_PLANE1_PITCH_EXT, EGL_DMA_BUF_PLANE2_PITCH_EXT, EGL_DMA_BUF_PLANE3_PITCH_EXT }; _Static_assert(ARRAY_LENGTH(stride_attribs) == MAX_PLANES, "stride_attribs has incorrect length"); static const EGLAttrib modifier_low_attribs[] = { EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT, EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT, EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT, EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT }; _Static_assert(ARRAY_LENGTH(modifier_low_attribs) == MAX_PLANES, "modifier_low_attribs has incorrect length"); static const EGLAttrib modifier_high_attribs[] = { EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT, EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT, EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT, EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT }; _Static_assert(ARRAY_LENGTH(modifier_high_attribs) == MAX_PLANES, "modifier_high_attribs has incorrect length"); bool dmabuf_to_texture(ctx_t * ctx, dmabuf_t * dmabuf) { if (dmabuf->planes > MAX_PLANES) { log_error("egl::dmabuf_to_texture(): too many planes, got %zd, can support at most %d\n", dmabuf->planes, MAX_PLANES); return false; } int i = 0; EGLAttrib * image_attribs = malloc((6 + 10 * dmabuf->planes + 1) * sizeof (EGLAttrib)); if (image_attribs == NULL) { log_error("egl::dmabuf_to_texture(): failed to allocate EGL image attribs\n"); return false; } image_attribs[i++] = EGL_WIDTH; image_attribs[i++] = dmabuf->width; image_attribs[i++] = EGL_HEIGHT; image_attribs[i++] = dmabuf->height; image_attribs[i++] = EGL_LINUX_DRM_FOURCC_EXT; image_attribs[i++] = dmabuf->drm_format; for (size_t j = 0; j < dmabuf->planes; j++) { image_attribs[i++] = fd_attribs[j]; image_attribs[i++] = dmabuf->fds[j]; image_attribs[i++] = offset_attribs[j]; image_attribs[i++] = dmabuf->offsets[j]; image_attribs[i++] = stride_attribs[j]; image_attribs[i++] = dmabuf->strides[j]; image_attribs[i++] = modifier_low_attribs[j]; image_attribs[i++] = (uint32_t)dmabuf->modifier; image_attribs[i++] = modifier_high_attribs[j]; image_attribs[i++] = (uint32_t)(dmabuf->modifier >> 32); } image_attribs[i++] = EGL_NONE; // create EGLImage from dmabuf with attribute array EGLImage frame_image = eglCreateImage(ctx->egl.display, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, image_attribs); free(image_attribs); if (frame_image == EGL_NO_IMAGE) { log_error("egl::dmabuf_to_texture(): failed to create EGL image from dmabuf: error = %x\n", eglGetError()); return false; } // convert EGLImage to GL texture glBindTexture(GL_TEXTURE_2D, ctx->egl.texture); ctx->egl.glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, frame_image); // destroy temporary image eglDestroyImage(ctx->egl.display, frame_image); return true; } // --- cleanup_egl --- void cleanup_egl(ctx_t *ctx) { if (!ctx->egl.initialized) return; log_debug(ctx, "egl::cleanup(): destroying EGL objects\n"); if (ctx->egl.shader_program != 0) glDeleteProgram(ctx->egl.shader_program); if (ctx->egl.freeze_framebuffer != 0) glDeleteFramebuffers(1, &ctx->egl.freeze_framebuffer); if (ctx->egl.freeze_texture != 0) glDeleteTextures(1, &ctx->egl.freeze_texture); if (ctx->egl.texture != 0) glDeleteTextures(1, &ctx->egl.texture); if (ctx->egl.vbo != 0) glDeleteBuffers(1, &ctx->egl.vbo); if (ctx->egl.context != EGL_NO_CONTEXT) eglDestroyContext(ctx->egl.display, ctx->egl.context); if (ctx->egl.surface != EGL_NO_SURFACE) eglDestroySurface(ctx->egl.display, ctx->egl.surface); if (ctx->egl.window != EGL_NO_SURFACE) wl_egl_window_destroy(ctx->egl.window); if (ctx->egl.display != EGL_NO_DISPLAY) eglTerminate(ctx->egl.display); ctx->egl.initialized = false; } wl-mirror-0.16.5/src/event.c0000644000175000017500000000650014646471773014347 0ustar yrlfyrlf#include #include #include #include "context.h" #include "event.h" static void add_handler(ctx_t * ctx, event_handler_t * handler) { handler->next = ctx->event.handlers; ctx->event.handlers = handler; } static void remove_handler(ctx_t * ctx, int fd) { event_handler_t ** pcur = &ctx->event.handlers; event_handler_t * cur = *pcur; while (cur != NULL) { if (cur->fd == fd) { *pcur = cur->next; return; } pcur = &cur->next; cur = cur->next; } } static void call_each_handler(ctx_t * ctx) { event_handler_t * cur = ctx->event.handlers; while (cur != NULL) { if (cur->on_each != NULL) { cur->on_each(ctx); } cur = cur->next; } } static event_handler_t * min_timeout(ctx_t * ctx) { event_handler_t * min = NULL; event_handler_t * cur = ctx->event.handlers; while (cur != NULL) { if (cur->timeout_ms != -1) { if (min == NULL || cur->timeout_ms < min->timeout_ms) min = cur; } cur = cur->next; } return min; } void event_add_fd(ctx_t * ctx, event_handler_t * handler) { struct epoll_event event; event.events = handler->events; event.data.ptr = handler; if (epoll_ctl(ctx->event.pollfd, EPOLL_CTL_ADD, handler->fd, &event) == -1) { log_error("event::add_fd(): failed to add fd to epoll instance\n"); exit_fail(ctx); } add_handler(ctx, handler); } void event_change_fd(ctx_t * ctx, event_handler_t * handler) { struct epoll_event event; event.events = handler->events; event.data.ptr = handler; if (epoll_ctl(ctx->event.pollfd, EPOLL_CTL_MOD, handler->fd, &event) == -1) { log_error("event::change_fd(): failed to modify fd in epoll instance\n"); exit_fail(ctx); } } void event_remove_fd(ctx_t * ctx, event_handler_t * handler) { if (epoll_ctl(ctx->event.pollfd, EPOLL_CTL_DEL, handler->fd, NULL) == -1) { log_error("event::remove_fd(): failed to remove fd from epoll instance\n"); } remove_handler(ctx, handler->fd); handler->next = NULL; } #define MAX_EVENTS 10 void event_loop(ctx_t * ctx) { struct epoll_event events[MAX_EVENTS]; int num_events; event_handler_t * timeout_handler; int timeout_ms; timeout_handler = min_timeout(ctx); timeout_ms = timeout_handler == NULL ? -1 : timeout_handler->timeout_ms; while ((num_events = epoll_wait(ctx->event.pollfd, events, MAX_EVENTS, timeout_ms)) != -1 && !ctx->wl.closing) { for (int i = 0; i < num_events; i++) { event_handler_t * handler = (event_handler_t *)events[i].data.ptr; handler->on_event(ctx); } if (num_events == 0 && timeout_handler != NULL) { timeout_handler->on_event(ctx); } timeout_handler = min_timeout(ctx); timeout_ms = timeout_handler == NULL ? -1 : timeout_handler->timeout_ms; call_each_handler(ctx); } } void init_event(ctx_t * ctx) { ctx->event.pollfd = epoll_create(1); if (ctx->event.pollfd == -1) { log_error("event::init(): failed to create epoll instance\n"); exit_fail(ctx); return; } ctx->event.handlers = NULL; ctx->event.initialized = true; } void cleanup_event(ctx_t * ctx) { close(ctx->event.pollfd); } wl-mirror-0.16.5/src/main.c0000644000175000017500000000277614646471773014165 0ustar yrlfyrlf#include #include #include #include "context.h" #include "event.h" void cleanup(ctx_t * ctx) { log_debug(ctx, "main::cleanup(): deallocating resources\n"); if (ctx->mirror.initialized) cleanup_mirror(ctx); if (ctx->egl.initialized) cleanup_egl(ctx); if (ctx->wl.initialized) cleanup_wl(ctx); if (ctx->stream.initialized) cleanup_stream(ctx); if (ctx->event.initialized) cleanup_event(ctx); cleanup_opt(ctx); } noreturn void exit_fail(ctx_t * ctx) { cleanup(ctx); exit(1); } int main(int argc, char ** argv) { ctx_t ctx = { 0 }; ctx.event.initialized = false; ctx.stream.initialized = false; ctx.wl.initialized = false; ctx.egl.initialized = false; ctx.mirror.initialized = false; init_opt(&ctx); init_event(&ctx); if (argc > 0) { // skip program name argv++; argc--; } parse_opt(&ctx, argc, argv); log_debug(&ctx, "main::main(): initializing stream\n"); init_stream(&ctx); log_debug(&ctx, "main::main(): initializing wayland\n"); init_wl(&ctx); log_debug(&ctx, "main::main(): initializing EGL\n"); init_egl(&ctx); log_debug(&ctx, "main::main(): initializing mirror\n"); init_mirror(&ctx); log_debug(&ctx, "main::main(): initializing mirror backend\n"); init_mirror_backend(&ctx); log_debug(&ctx, "main::main(): entering event loop\n"); event_loop(&ctx); log_debug(&ctx, "main::main(): exiting event loop\n"); cleanup(&ctx); } wl-mirror-0.16.5/src/mirror-dmabuf.c0000644000175000017500000002627714646471773016011 0ustar yrlfyrlf#include #include #include #include "context.h" #include "mirror-dmabuf.h" #include #include "linux-dmabuf-unstable-v1.h" static void dmabuf_frame_cleanup(dmabuf_mirror_backend_t * backend) { // destroy dmabuf frame object if (backend->dmabuf_frame != NULL) { zwlr_export_dmabuf_frame_v1_destroy(backend->dmabuf_frame); backend->dmabuf_frame = NULL; } // close dmabuf file descriptors for (unsigned int i = 0; i < backend->dmabuf.planes; i++) { if (backend->dmabuf.fds[i] != -1) close(backend->dmabuf.fds[i]); } free(backend->dmabuf.fds); free(backend->dmabuf.offsets); free(backend->dmabuf.strides); backend->dmabuf.width = 0; backend->dmabuf.height = 0; backend->dmabuf.drm_format = 0; backend->dmabuf.planes = 0; backend->dmabuf.fds = NULL; backend->dmabuf.offsets = NULL; backend->dmabuf.strides = NULL; backend->dmabuf.modifier = 0; } static void backend_cancel(dmabuf_mirror_backend_t * backend) { log_error("mirror-dmabuf::backend_cancel(): cancelling capture due to error\n"); dmabuf_frame_cleanup(backend); backend->state = STATE_CANCELED; backend->header.fail_count++; } // --- dmabuf_frame event handlers --- static void on_frame( void * data, struct zwlr_export_dmabuf_frame_v1 * frame, uint32_t width, uint32_t height, uint32_t x, uint32_t y, uint32_t buffer_flags, uint32_t frame_flags, uint32_t format, uint32_t mod_high, uint32_t mod_low, uint32_t num_objects ) { ctx_t * ctx = (ctx_t *)data; dmabuf_mirror_backend_t * backend = (dmabuf_mirror_backend_t *)ctx->mirror.backend; log_debug(ctx, "mirror-dmabuf::on_frame(): received %dx%d frame with %d objects\n", width, height, num_objects); if (backend->state != STATE_WAIT_FRAME) { log_error("mirror-dmabuf::on_frame(): got frame while in state %d\n", backend->state); backend_cancel(backend); return; } else if (num_objects > MAX_PLANES) { log_error("mirror-dmabuf::on_frame(): got frame with more than %d objects\n", MAX_PLANES); backend_cancel(backend); return; } uint32_t unhandled_buffer_flags = buffer_flags & ~( ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_Y_INVERT ); if (unhandled_buffer_flags != 0) { log_warn("mirror-dmabuf::on_frame(): frame uses unhandled buffer flags, buffer_flags = {"); if (buffer_flags & ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_Y_INVERT) fprintf(stderr, "Y_INVERT, "); if (buffer_flags & ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_INTERLACED) fprintf(stderr, "INTERLACED, "); if (buffer_flags & ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_BOTTOM_FIRST) fprintf(stderr, "BOTTOM_FIRST, "); fprintf(stderr, "}\n"); } uint32_t unhandled_frame_flags = frame_flags & ~( ZWLR_EXPORT_DMABUF_FRAME_V1_FLAGS_TRANSIENT ); if (unhandled_frame_flags != 0) { log_warn("mirror-dmabuf::on_frame(): frame uses unhandled frame flags, frame_flags = {"); if (frame_flags & ZWLR_EXPORT_DMABUF_FRAME_V1_FLAGS_TRANSIENT) fprintf(stderr, "TRANSIENT, "); fprintf(stderr, "}\n"); } backend->dmabuf.planes = 0; backend->dmabuf.fds = malloc(num_objects * sizeof (int)); backend->dmabuf.offsets = malloc(num_objects * sizeof (uint32_t)); backend->dmabuf.strides = malloc(num_objects * sizeof (uint32_t)); backend->dmabuf.modifier = ((uint64_t)mod_high << 32) | mod_low; if (backend->dmabuf.fds == NULL || backend->dmabuf.offsets == NULL) { log_error("mirror-dmabuf::on_frame(): failed to allocate dmabuf storage\n"); backend_cancel(backend); return; } // save dmabuf frame info backend->x = x; backend->y = y; backend->buffer_flags = buffer_flags; backend->frame_flags = frame_flags; backend->dmabuf.width = width; backend->dmabuf.height = height; backend->dmabuf.drm_format = format; backend->dmabuf.planes = num_objects; log_debug(ctx, "mirror-dmabuf::on_frame(): w=%d h=%d gl_format=%x drm_format=%08x drm_modifier=%016lx\n", backend->dmabuf.width, backend->dmabuf.height, GL_RGB8_OES, backend->dmabuf.drm_format, backend->dmabuf.modifier ); for (size_t i = 0; i < num_objects; i++) { backend->dmabuf.fds[i] = -1; } // update dmabuf frame state machine backend->state = STATE_WAIT_OBJECTS; backend->processed_objects = 0; (void)frame; } static void on_object( void * data, struct zwlr_export_dmabuf_frame_v1 * frame, uint32_t index, int32_t fd, uint32_t size, uint32_t offset, uint32_t stride, uint32_t plane_index ) { ctx_t * ctx = (ctx_t *)data; dmabuf_mirror_backend_t * backend = (dmabuf_mirror_backend_t *)ctx->mirror.backend; log_debug(ctx, "mirror-dmabuf::on_object(): fd=%d offset=% 10d stride=% 10d\n", fd, offset, stride ); if (backend->state != STATE_WAIT_OBJECTS) { log_error("mirror-dmabuf::on_object(): got object while in state %d\n", backend->state); close(fd); backend_cancel(backend); return; } else if (index >= backend->dmabuf.planes) { log_error("mirror-dmabuf::on_object(): got object with out-of-bounds index %d\n", index); close(fd); backend_cancel(backend); return; } backend->dmabuf.fds[index] = fd; backend->dmabuf.offsets[index] = offset; backend->dmabuf.strides[index] = stride; backend->processed_objects++; if (backend->processed_objects == backend->dmabuf.planes) { backend->state = STATE_WAIT_READY; } (void)frame; (void)size; (void)plane_index; } static void on_ready( void * data, struct zwlr_export_dmabuf_frame_v1 * frame, uint32_t sec_hi, uint32_t sec_lo, uint32_t nsec ) { ctx_t * ctx = (ctx_t *)data; dmabuf_mirror_backend_t * backend = (dmabuf_mirror_backend_t *)ctx->mirror.backend; log_debug(ctx, "mirror-dmabuf::on_ready(): frame is ready\n"); if (backend->state != STATE_WAIT_READY) { log_error("dmabuf_frame: got ready while in state %d\n", backend->state); backend_cancel(backend); return; } if (!dmabuf_to_texture(ctx, &backend->dmabuf)) { log_error("mirror-dmabuf::on_ready(): failed to import dmabuf\n"); backend_cancel(backend); } ctx->egl.format = GL_RGB8_OES; // FIXME: find out actual format ctx->egl.texture_region_aware = false; ctx->egl.texture_initialized = true; // set buffer flags only if changed bool invert_y = backend->buffer_flags & ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_Y_INVERT; if (ctx->mirror.invert_y != invert_y) { ctx->mirror.invert_y = invert_y; update_uniforms(ctx); } // set texture size and aspect ratio only if changed if (backend->dmabuf.width != ctx->egl.width || backend->dmabuf.height != ctx->egl.height) { ctx->egl.width = backend->dmabuf.width; ctx->egl.height = backend->dmabuf.height; resize_viewport(ctx); } dmabuf_frame_cleanup(backend); backend->state = STATE_READY; backend->header.fail_count = 0; (void)frame; (void)sec_hi; (void)sec_lo; (void)nsec; } static void on_cancel( void * data, struct zwlr_export_dmabuf_frame_v1 * frame, enum zwlr_export_dmabuf_frame_v1_cancel_reason reason ) { ctx_t * ctx = (ctx_t *)data; dmabuf_mirror_backend_t * backend = (dmabuf_mirror_backend_t *)ctx->mirror.backend; log_debug(ctx, "mirror-dmabuf::on_cancel(): frame was canceled\n"); dmabuf_frame_cleanup(backend); backend->state = STATE_CANCELED; switch (reason) { case ZWLR_EXPORT_DMABUF_FRAME_V1_CANCEL_REASON_PERMANENT: log_error("mirror-dmabuf::on_cancel(): permanent cancellation\n"); backend->header.fail_count++; break; case ZWLR_EXPORT_DMABUF_FRAME_V1_CANCEL_REASON_TEMPORARY: log_error("mirror-dmabuf::on_cancel(): temporary cancellation\n"); backend->header.fail_count++; break; case ZWLR_EXPORT_DMABUF_FRAME_V1_CANCEL_REASON_RESIZING: log_debug(ctx, "mirror-dmabuf::on_cancel(): cancellation due to output resize\n"); break; default: log_error("mirror-dmabuf::on_cancel(): unknown cancellation reason %d\n", reason); backend->header.fail_count++; break; } (void)frame; } static const struct zwlr_export_dmabuf_frame_v1_listener dmabuf_frame_listener = { .frame = on_frame, .object = on_object, .ready = on_ready, .cancel = on_cancel }; // --- backend event handlers --- static void do_capture(ctx_t * ctx) { dmabuf_mirror_backend_t * backend = (dmabuf_mirror_backend_t *)ctx->mirror.backend; if (backend->state == STATE_READY || backend->state == STATE_CANCELED) { // clear frame state for next frame backend->x = 0; backend->y = 0; backend->buffer_flags = 0; backend->frame_flags = 0; dmabuf_frame_cleanup(backend); backend->state = STATE_WAIT_FRAME; backend->processed_objects = 0; // create wlr_dmabuf_export_frame backend->dmabuf_frame = zwlr_export_dmabuf_manager_v1_capture_output( ctx->wl.dmabuf_manager, ctx->opt.show_cursor, ctx->mirror.current_target->output ); if (backend->dmabuf_frame == NULL) { log_error("mirror-dmabuf::do_capture(): failed to create wlr_dmabuf_export_frame\n"); backend_fail(ctx); return; } // add wlr_dmabuf_export_frame event listener // - for frame event // - for object event // - for ready event // - for cancel event zwlr_export_dmabuf_frame_v1_add_listener(backend->dmabuf_frame, &dmabuf_frame_listener, (void *)ctx); } } static void do_cleanup(ctx_t * ctx) { dmabuf_mirror_backend_t * backend = (dmabuf_mirror_backend_t *)ctx->mirror.backend; log_debug(ctx, "mirror-dmabuf::do_cleanup(): destroying mirror-dmabuf objects\n"); dmabuf_frame_cleanup(backend); free(backend); ctx->mirror.backend = NULL; } // --- init_mirror_dmabuf --- void init_mirror_dmabuf(ctx_t * ctx) { // check for required protocols if (ctx->wl.dmabuf_manager == NULL) { log_error("mirror-dmabuf::init(): missing wlr_export_dmabuf_manager protocol\n"); return; } // allocate backend context structure dmabuf_mirror_backend_t * backend = calloc(1, sizeof (dmabuf_mirror_backend_t)); if (backend == NULL) { log_error("mirror-dmabuf::init(): failed to allocate backend state\n"); return; } // initialize context structure backend->header.do_capture = do_capture; backend->header.do_cleanup = do_cleanup; backend->header.fail_count = 0; backend->dmabuf_frame = NULL; backend->x = 0; backend->y = 0; backend->buffer_flags = 0; backend->frame_flags = 0; backend->dmabuf.width = 0; backend->dmabuf.height = 0; backend->dmabuf.drm_format = 0; backend->dmabuf.planes = 0; backend->dmabuf.fds = NULL; backend->dmabuf.offsets = NULL; backend->dmabuf.strides = NULL; backend->dmabuf.modifier = 0; backend->state = STATE_READY; backend->processed_objects = 0; // set backend object as current backend ctx->mirror.backend = (mirror_backend_t *)backend; } wl-mirror-0.16.5/src/mirror-screencopy.c0000644000175000017500000003622114646471773016713 0ustar yrlfyrlf#define _GNU_SOURCE #include #include #include #include "context.h" #include "mirror-screencopy.h" #include #include #include #include #include static void backend_cancel(screencopy_mirror_backend_t * backend) { log_error("mirror-screencopy::backend_cancel(): cancelling capture due to error\n"); // destroy screencopy frame object zwlr_screencopy_frame_v1_destroy(backend->screencopy_frame); backend->screencopy_frame = NULL; backend->state = STATE_CANCELED; backend->header.fail_count++; } typedef struct { uint32_t shm_format; uint32_t bpp; GLint gl_format; GLint gl_type; } shm_gl_format_t; static const shm_gl_format_t shm_gl_formats[] = { { .shm_format = WL_SHM_FORMAT_ARGB8888, .bpp = 32, .gl_format = GL_BGRA_EXT, .gl_type = GL_UNSIGNED_BYTE, }, { .shm_format = WL_SHM_FORMAT_XRGB8888, .bpp = 32, .gl_format = GL_BGRA_EXT, .gl_type = GL_UNSIGNED_BYTE, }, { .shm_format = WL_SHM_FORMAT_XBGR8888, .bpp = 32, .gl_format = GL_RGBA, .gl_type = GL_UNSIGNED_BYTE, }, { .shm_format = WL_SHM_FORMAT_ABGR8888, .bpp = 32, .gl_format = GL_RGBA, .gl_type = GL_UNSIGNED_BYTE, }, { .shm_format = WL_SHM_FORMAT_BGR888, .bpp = 24, .gl_format = GL_RGB, .gl_type = GL_UNSIGNED_BYTE, }, { .shm_format = WL_SHM_FORMAT_RGBX4444, .bpp = 16, .gl_format = GL_RGBA, .gl_type = GL_UNSIGNED_SHORT_4_4_4_4, }, { .shm_format = WL_SHM_FORMAT_RGBA4444, .bpp = 16, .gl_format = GL_RGBA, .gl_type = GL_UNSIGNED_SHORT_4_4_4_4, }, { .shm_format = WL_SHM_FORMAT_RGBX5551, .bpp = 16, .gl_format = GL_RGBA, .gl_type = GL_UNSIGNED_SHORT_5_5_5_1, }, { .shm_format = WL_SHM_FORMAT_RGBA5551, .bpp = 16, .gl_format = GL_RGBA, .gl_type = GL_UNSIGNED_SHORT_5_5_5_1, }, { .shm_format = WL_SHM_FORMAT_RGB565, .bpp = 16, .gl_format = GL_RGB, .gl_type = GL_UNSIGNED_SHORT_5_6_5, }, { .shm_format = WL_SHM_FORMAT_XBGR2101010, .bpp = 32, .gl_format = GL_RGBA, .gl_type = GL_UNSIGNED_INT_2_10_10_10_REV_EXT, }, { .shm_format = WL_SHM_FORMAT_ABGR2101010, .bpp = 32, .gl_format = GL_RGBA, .gl_type = GL_UNSIGNED_INT_2_10_10_10_REV_EXT, }, { .shm_format = WL_SHM_FORMAT_XBGR16161616F, .bpp = 64, .gl_format = GL_RGBA, .gl_type = GL_HALF_FLOAT_OES, }, { .shm_format = WL_SHM_FORMAT_ABGR16161616F, .bpp = 64, .gl_format = GL_RGBA, .gl_type = GL_HALF_FLOAT_OES, }, { .shm_format = -1U, .bpp = -1U, .gl_format = -1, .gl_type = -1 } }; static const shm_gl_format_t * shm_gl_format_from_shm(uint32_t shm_format) { const shm_gl_format_t * format = shm_gl_formats; while (format->shm_format != -1U) { if (format->shm_format == shm_format) { return format; } format++; } return NULL; } // --- screencopy_frame event handlers --- static void on_buffer( void * data, struct zwlr_screencopy_frame_v1 * frame, uint32_t format, uint32_t width, uint32_t height, uint32_t stride ) { ctx_t * ctx = (ctx_t *)data; screencopy_mirror_backend_t * backend = (screencopy_mirror_backend_t *)ctx->mirror.backend; log_debug(ctx, "mirror-screencopy::on_buffer(): received buffer offer for %dx%d+%d frame\n", width, height, stride); if (backend->state != STATE_WAIT_BUFFER) { log_error("mirror-screencopy::on_buffer(): got buffer event while in state %d\n", backend->state); backend_cancel(backend); return; } size_t new_size = stride * height; if (new_size > backend->shm_size) { if (backend->shm_buffer != NULL) { wl_buffer_destroy(backend->shm_buffer); backend->shm_buffer = NULL; } if (ftruncate(backend->shm_fd, new_size) == -1) { log_error("mirror-screencopy::on_buffer(): failed to grow shm buffer\n"); backend_cancel(backend); return; } #if __linux__ void * new_addr = mremap(backend->shm_addr, backend->shm_size, new_size, MREMAP_MAYMOVE); if (new_addr == MAP_FAILED) { log_error("mirror-screencopy::on_buffer(): failed to remap shm buffer\n"); backend_cancel(backend); return; } #else void * new_addr = mmap(NULL, new_size, PROT_READ | PROT_WRITE, MAP_SHARED, backend->shm_fd, 0); if (new_addr == MAP_FAILED) { log_error("mirror-screencopy::on_buffer(): failed to map new shm buffer\n"); backend_cancel(backend); return; } else { munmap(backend->shm_addr, backend->shm_size); } #endif backend->shm_addr = new_addr; backend->shm_size = new_size; wl_shm_pool_resize(backend->shm_pool, new_size); } bool new_buffer_needed = backend->frame_width != width || backend->frame_height != height || backend->frame_stride != stride || backend->frame_format != format; if (backend->shm_buffer != NULL && new_buffer_needed) { wl_buffer_destroy(backend->shm_buffer); backend->shm_buffer = NULL; } if (backend->shm_buffer == NULL) { backend->shm_buffer = wl_shm_pool_create_buffer( backend->shm_pool, 0, width, height, stride, format ); if (backend->shm_buffer == NULL) { log_error("mirror-screencopy::on_buffer(): failed to create wl_buffer\n"); backend_cancel(backend); return; } } backend->frame_width = width; backend->frame_height = height; backend->frame_stride = stride; backend->frame_format = format; backend->state = STATE_WAIT_BUFFER_DONE; (void)frame; } static void on_linux_dmabuf( void * data, struct zwlr_screencopy_frame_v1 * frame, uint32_t format, uint32_t width, uint32_t height ) { (void)data; (void)frame; (void)format; (void)width; (void)height; } static void on_buffer_done( void * data, struct zwlr_screencopy_frame_v1 * frame ) { ctx_t * ctx = (ctx_t *)data; screencopy_mirror_backend_t * backend = (screencopy_mirror_backend_t *)ctx->mirror.backend; log_debug(ctx, "mirror-screencopy::on_buffer_done(): received buffer done event\n"); if (backend->state != STATE_WAIT_BUFFER_DONE) { log_error("mirror-screencopy::on_buffer_done(): received buffer_done without supported buffer offer\n"); backend_cancel(backend); return; } backend->state = STATE_WAIT_FLAGS; zwlr_screencopy_frame_v1_copy(backend->screencopy_frame, backend->shm_buffer); (void)frame; } static void on_damage( void * data, struct zwlr_screencopy_frame_v1 * frame, uint32_t x, uint32_t y, uint32_t width, uint32_t height ) { (void)data; (void)frame; (void)x; (void)y; (void)width; (void)height; } static void on_flags( void * data, struct zwlr_screencopy_frame_v1 * frame, uint32_t flags ) { ctx_t * ctx = (ctx_t *)data; screencopy_mirror_backend_t * backend = (screencopy_mirror_backend_t *)ctx->mirror.backend; log_debug(ctx, "mirror-screencopy::on_flags(): received flags event\n"); if (backend->state != STATE_WAIT_FLAGS) { log_error("mirror-screencopy::on_flags(): received unexpected flags event\n"); backend_cancel(backend); return; } backend->frame_flags = flags; backend->state = STATE_WAIT_READY; (void)frame; } static void on_ready( void * data, struct zwlr_screencopy_frame_v1 * frame, uint32_t sec_hi, uint32_t sec_lo, uint32_t nsec ) { ctx_t * ctx = (ctx_t *)data; screencopy_mirror_backend_t * backend = (screencopy_mirror_backend_t *)ctx->mirror.backend; if (ctx->opt.verbose) { log_debug(ctx, "mirror-screencopy::on_ready(): received ready event with width: %d, height: %d, stride: %d, format: %c%c%c%c\n", backend->frame_width, backend->frame_height, backend->frame_stride, (backend->frame_format >> 24) & 0xff, (backend->frame_format >> 16) & 0xff, (backend->frame_format >> 8) & 0xff, (backend->frame_format >> 0) & 0xff ); } // find correct texture format const shm_gl_format_t * format = shm_gl_format_from_shm(backend->frame_format); if (format == NULL) { log_error("mirror-screencopy::on_ready(): failed to find GL format for shm format\n"); backend_fail(ctx); return; } // store frame data into texture glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, backend->frame_stride / (format->bpp / 8)); glTexImage2D(GL_TEXTURE_2D, 0, format->gl_format, backend->frame_width, backend->frame_height, 0, format->gl_format, format->gl_type, backend->shm_addr ); glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, 0); ctx->egl.format = format->gl_format; ctx->egl.texture_region_aware = true; ctx->egl.texture_initialized = true; // set buffer flags bool invert_y = backend->frame_flags & ZWLR_SCREENCOPY_FRAME_V1_FLAGS_Y_INVERT; if (ctx->mirror.invert_y != invert_y) { ctx->mirror.invert_y = invert_y; update_uniforms(ctx); } // set texture size and aspect ratio only if changed if (backend->frame_width != ctx->egl.width || backend->frame_height != ctx->egl.height) { ctx->egl.width = backend->frame_width; ctx->egl.height = backend->frame_height; resize_viewport(ctx); } zwlr_screencopy_frame_v1_destroy(backend->screencopy_frame); backend->screencopy_frame = NULL; backend->state = STATE_READY; backend->header.fail_count = 0; (void)frame; (void)sec_hi; (void)sec_lo; (void)nsec; } static void on_failed( void * data, struct zwlr_screencopy_frame_v1 * frame ) { ctx_t * ctx = (ctx_t *)data; screencopy_mirror_backend_t * backend = (screencopy_mirror_backend_t *)ctx->mirror.backend; log_debug(ctx, "mirror-screencopy::on_failed(): received cancel event\n"); backend_cancel(backend); (void)frame; } static const struct zwlr_screencopy_frame_v1_listener screencopy_frame_listener = { .buffer = on_buffer, .linux_dmabuf = on_linux_dmabuf, .buffer_done = on_buffer_done, .damage = on_damage, .flags = on_flags, .ready = on_ready, .failed = on_failed }; // --- backend event handlers --- static void do_capture(ctx_t * ctx) { screencopy_mirror_backend_t * backend = (screencopy_mirror_backend_t *)ctx->mirror.backend; if (backend->state == STATE_READY || backend->state == STATE_CANCELED) { // clear frame state for next frame backend->frame_flags = 0; backend->state = STATE_WAIT_BUFFER; // create screencopy_frame if (ctx->opt.has_region) { backend->screencopy_frame = zwlr_screencopy_manager_v1_capture_output_region( ctx->wl.screencopy_manager, ctx->opt.show_cursor, ctx->mirror.current_target->output, ctx->mirror.current_target->x + ctx->mirror.current_region.x, ctx->mirror.current_target->y + ctx->mirror.current_region.y, ctx->mirror.current_region.width, ctx->mirror.current_region.height ); } else { backend->screencopy_frame = zwlr_screencopy_manager_v1_capture_output( ctx->wl.screencopy_manager, ctx->opt.show_cursor, ctx->mirror.current_target->output ); } if (backend->screencopy_frame == NULL) { log_error("do_capture: failed to create wlr_screencopy_frame\n"); backend_fail(ctx); } // add screencopy_frame event listener // - for buffer event // - for buffer_done event // - for flags event // - for ready event // - for failed event zwlr_screencopy_frame_v1_add_listener(backend->screencopy_frame, &screencopy_frame_listener, (void *)ctx); } } static void do_cleanup(ctx_t * ctx) { screencopy_mirror_backend_t * backend = (screencopy_mirror_backend_t *)ctx->mirror.backend; log_debug(ctx, "mirror-screencopy::do_cleanup(): destroying mirror-screencopy objects\n"); if (backend->screencopy_frame != NULL) zwlr_screencopy_frame_v1_destroy(backend->screencopy_frame); if (backend->shm_buffer != NULL) wl_buffer_destroy(backend->shm_buffer); if (backend->shm_pool != NULL) wl_shm_pool_destroy(backend->shm_pool); if (backend->shm_addr != NULL) munmap(backend->shm_addr, backend->shm_size); if (backend->shm_fd != -1) close(backend->shm_fd); free(backend); ctx->mirror.backend = NULL; } // --- init_mirror_screencopy --- void init_mirror_screencopy(ctx_t * ctx) { // check for required protocols if (ctx->wl.shm == NULL) { log_error("mirror-screencopy::init(): missing wl_shm protocol\n"); return; } else if (ctx->wl.screencopy_manager == NULL) { log_error("mirror-screencopy::init(): missing wlr_screencopy protocol\n"); return; } // allocate backend context structure screencopy_mirror_backend_t * backend = calloc(1, sizeof (screencopy_mirror_backend_t)); if (backend == NULL) { log_error("mirror-screencopy::init(): failed to allocate backend state\n"); return; } // initialize context structure backend->header.do_capture = do_capture; backend->header.do_cleanup = do_cleanup; backend->header.fail_count = 0; backend->shm_fd = -1; backend->shm_size = 0; backend->shm_addr = NULL; backend->shm_pool = NULL; backend->shm_buffer = NULL; backend->screencopy_frame = NULL; backend->frame_width = 0; backend->frame_height = 0; backend->frame_stride = 0; backend->frame_format = 0; backend->frame_flags = 0; backend->state = STATE_READY; // set backend object as current backend ctx->mirror.backend = (mirror_backend_t *)backend; // create shm fd backend->shm_fd = memfd_create("wl_shm_buffer", 0); if (backend->shm_fd == -1) { log_error("mirror-screencopy::init(): failed to create shm buffer\n"); backend_fail(ctx); } // resize shm fd to nonempty size backend->shm_size = 1; if (ftruncate(backend->shm_fd, backend->shm_size) == -1) { log_error("mirror-screencopy::init(): failed to resize shm buffer\n"); backend_fail(ctx); } // map shm fd backend->shm_addr = mmap(NULL, backend->shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, backend->shm_fd, 0); if (backend->shm_addr == MAP_FAILED) { backend->shm_addr = NULL; log_error("mirror-screencopy::init(): failed to map shm buffer\n"); backend_fail(ctx); } // create shm pool from shm fd backend->shm_pool = wl_shm_create_pool(ctx->wl.shm, backend->shm_fd, backend->shm_size); if (backend->shm_pool == NULL) { log_error("mirror-screencopy::init(): failed to create shm pool\n"); backend_fail(ctx); } } wl-mirror-0.16.5/src/mirror.c0000644000175000017500000001337514646471773014550 0ustar yrlfyrlf#define _GNU_SOURCE #include #include #include #include #include "context.h" #include #include "linux-dmabuf-unstable-v1.h" #include "mirror-backends.h" // --- frame_callback event handlers --- static const struct wl_callback_listener frame_callback_listener; static void on_frame( void * data, struct wl_callback * frame_callback, uint32_t msec ) { ctx_t * ctx = (ctx_t *)data; // destroy frame callback wl_callback_destroy(ctx->mirror.frame_callback); ctx->mirror.frame_callback = NULL; // don't attempt to render if window is already closing if (ctx->wl.closing) { return; } // add new frame callback listener // the wayland spec says you cannot reuse the old frame callback ctx->mirror.frame_callback = wl_surface_frame(ctx->wl.surface); wl_callback_add_listener(ctx->mirror.frame_callback, &frame_callback_listener, (void *)ctx); if (ctx->mirror.backend != NULL) { // check if backend failure count exceeded if (ctx->mirror.backend->fail_count >= MIRROR_BACKEND_FATAL_FAILCOUNT) { backend_fail(ctx); } if (!ctx->opt.freeze) { // request new screen capture from backend ctx->mirror.backend->do_capture(ctx); } } // wait for events // - screencapture events from backend wl_display_roundtrip(ctx->wl.display); // render frame, set swap interval to 0 to ensure nonblocking buffer swap draw_texture(ctx); eglSwapInterval(ctx->egl.display, 0); if (eglSwapBuffers(ctx->egl.display, ctx->egl.surface) != EGL_TRUE) { log_error("mirror::on_frame(): failed to swap buffers\n"); exit_fail(ctx); } (void)frame_callback; (void)msec; } static const struct wl_callback_listener frame_callback_listener = { .done = on_frame }; // --- init_mirror --- void init_mirror(ctx_t * ctx) { // initialize context structure ctx->mirror.current_target = NULL; ctx->mirror.frame_callback = NULL; ctx->mirror.current_region = (region_t){ .x = 0, .y = 0, .width = 0, .height = 0 }; ctx->mirror.invert_y = false; ctx->mirror.backend = NULL; ctx->mirror.auto_backend_index = 0; ctx->mirror.initialized = true; // finding target output if (!find_output_opt(ctx, &ctx->mirror.current_target, &ctx->mirror.current_region)) { log_error("mirror::init(): failed to find output\n"); exit_fail(ctx); } // update window title update_title(ctx); // add frame callback listener ctx->mirror.frame_callback = wl_surface_frame(ctx->wl.surface); wl_callback_add_listener(ctx->mirror.frame_callback, &frame_callback_listener, (void *)ctx); } // --- auto backend handler typedef struct { char * name; void (*init)(ctx_t * ctx); } fallback_backend_t; static fallback_backend_t auto_fallback_backends[] = { { "dmabuf", init_mirror_dmabuf }, { "screencopy", init_mirror_screencopy }, { NULL, NULL } }; static void auto_backend_fallback(ctx_t * ctx) { while (true) { // get next backend size_t index = ctx->mirror.auto_backend_index; fallback_backend_t * next_backend = &auto_fallback_backends[index]; if (next_backend->name == NULL) { log_error("mirror::auto_backend_fallback(): no working backend found, exiting\n"); exit_fail(ctx); } if (index > 0) { log_warn("mirror::auto_backend_fallback(): falling back to backend %s\n", next_backend->name); } else { log_debug(ctx, "mirror::auto_backend_fallback(): selecting backend %s\n", next_backend->name); } // uninitialize previous backend if (ctx->mirror.backend != NULL) ctx->mirror.backend->do_cleanup(ctx); // initialize next backend next_backend->init(ctx); // increment backend index for next attempt ctx->mirror.auto_backend_index++; // break if backend loading succeeded if (ctx->mirror.backend != NULL) break; } } // --- init_mirror_backend --- void init_mirror_backend(ctx_t * ctx) { if (ctx->mirror.backend != NULL) ctx->mirror.backend->do_cleanup(ctx); switch (ctx->opt.backend) { case BACKEND_AUTO: auto_backend_fallback(ctx); break; case BACKEND_DMABUF: init_mirror_dmabuf(ctx); break; case BACKEND_SCREENCOPY: init_mirror_screencopy(ctx); break; } if (ctx->mirror.backend == NULL) exit_fail(ctx); } // --- output_removed --- void output_removed(ctx_t * ctx, output_list_node_t * node) { if (!ctx->mirror.initialized) return; if (ctx->mirror.current_target == NULL) return; if (ctx->mirror.current_target != node) return; log_error("mirror::output_removed(): output disappeared, closing\n"); exit_fail(ctx); } // --- update_options_mirror --- void update_title(ctx_t * ctx) { char * title = NULL; int status = asprintf(&title, "Wayland Output Mirror for %s", ctx->mirror.current_target->name); if (status == -1) { log_error("mirror::update_title(): failed to format window title\n"); exit_fail(ctx); } set_window_title(ctx, title); free(title); } // --- backend_fail --- void backend_fail(ctx_t * ctx) { if (ctx->opt.backend == BACKEND_AUTO) { auto_backend_fallback(ctx); } else { exit_fail(ctx); } } // --- cleanup_mirror --- void cleanup_mirror(ctx_t * ctx) { if (!ctx->mirror.initialized) return; log_debug(ctx, "mirror::cleanup(): destroying mirror objects\n"); if (ctx->mirror.backend != NULL) ctx->mirror.backend->do_cleanup(ctx); if (ctx->mirror.frame_callback != NULL) wl_callback_destroy(ctx->mirror.frame_callback); ctx->mirror.initialized = false; } wl-mirror-0.16.5/src/options.c0000644000175000017500000006164114646471773014730 0ustar yrlfyrlf#include #include #include "context.h" #include "version.h" void init_opt(ctx_t * ctx) { ctx->opt.verbose = false; ctx->opt.stream = false; ctx->opt.show_cursor = true; ctx->opt.invert_colors = false; ctx->opt.freeze = false; ctx->opt.has_region = false; ctx->opt.fullscreen = false; ctx->opt.scaling = SCALE_FIT; ctx->opt.scaling_filter = SCALE_FILTER_LINEAR; ctx->opt.backend = BACKEND_AUTO; ctx->opt.transform = (transform_t){ .rotation = ROT_NORMAL, .flip_x = false, .flip_y = false }; ctx->opt.region = (region_t){ .x = 0, .y = 0, .width = 0, .height = 0 }; ctx->opt.output = NULL; ctx->opt.fullscreen_output = NULL; } void cleanup_opt(ctx_t * ctx) { if (ctx->opt.output != NULL) free(ctx->opt.output); if (ctx->opt.fullscreen_output != NULL) free(ctx ->opt.fullscreen_output); } bool parse_scaling_opt(scale_t * scaling, scale_filter_t * scaling_filter, const char * scaling_arg) { if (strcmp(scaling_arg, "f") == 0 || strcmp(scaling_arg, "fit") == 0) { *scaling = SCALE_FIT; return true; } else if (strcmp(scaling_arg, "c") == 0 || strcmp(scaling_arg, "cover") == 0) { *scaling = SCALE_COVER; return true; } else if (strcmp(scaling_arg, "e") == 0 || strcmp(scaling_arg, "exact") == 0) { *scaling = SCALE_EXACT; return true; } else if (strcmp(scaling_arg, "l") == 0 || strcmp(scaling_arg, "linear") == 0) { *scaling_filter = SCALE_FILTER_LINEAR; return true; } else if (strcmp(scaling_arg, "n") == 0 || strcmp(scaling_arg, "nearest") == 0) { *scaling_filter = SCALE_FILTER_NEAREST; return true; } else { return false; } } bool parse_backend_opt(backend_t * backend, const char * backend_arg) { if (strcmp(backend_arg, "auto") == 0) { *backend = BACKEND_AUTO; return true; } else if (strcmp(backend_arg, "dmabuf") == 0) { *backend = BACKEND_DMABUF; return true; } else if (strcmp(backend_arg, "screencopy") == 0) { *backend = BACKEND_SCREENCOPY; return true; } else { return false; } } bool parse_transform_opt(transform_t * transform, const char * transform_arg) { transform_t local_transform = { .rotation = ROT_NORMAL, .flip_x = false, .flip_y = false }; if (strcmp(transform_arg, "normal") == 0) { *transform = local_transform; return true; } char * transform_str = strdup(transform_arg); if (transform_str == NULL) { log_error("options::parse_transform_option(): failed to allocate copy of transform argument\n"); return false; } bool success = true; bool has_rotation = false; char * transform_spec = strtok(transform_str, "-"); while (transform_spec != NULL) { if (strcmp(transform_spec, "normal") == 0) { log_error("options::parse_transform_option(): %s must be the only transform specifier\n", transform_spec); success = false; break; } else if (strcmp(transform_spec, "flipX") == 0 || strcmp(transform_spec, "flipped") == 0) { if (local_transform.flip_x) { log_error("options::parse_transform_option(): duplicate flip specifier %s\n", transform_spec); success = false; break; } local_transform.flip_x = true; } else if (strcmp(transform_spec, "flipY") == 0) { if (local_transform.flip_y) { log_error("options::parse_transform_option(): duplicate flip specifier %s\n", transform_spec); success = false; break; } local_transform.flip_y = true; } else if (strcmp(transform_spec, "0") == 0 || strcmp(transform_spec, "0cw") == 0 || strcmp(transform_spec, "0ccw") == 0) { if (has_rotation) { log_error("options::parse_transform_option(): duplicate rotation specifier %s\n", transform_spec); success = false; break; } has_rotation = true; local_transform.rotation = ROT_NORMAL; } else if (strcmp(transform_spec, "90") == 0 || strcmp(transform_spec, "90cw") == 0 || strcmp(transform_spec, "270ccw") == 0) { if (has_rotation) { log_error("options::parse_transform_option(): duplicate rotation specifier %s\n", transform_spec); success = false; break; } has_rotation = true; local_transform.rotation = ROT_CW_90; } else if (strcmp(transform_spec, "180") == 0 || strcmp(transform_spec, "180cw") == 0 || strcmp(transform_spec, "180ccw") == 0) { if (has_rotation) { log_error("options::parse_transform_option(): duplicate rotation specifier %s\n", transform_spec); success = false; break; } has_rotation = true; local_transform.rotation = ROT_CW_180; } else if (strcmp(transform_spec, "270") == 0 || strcmp(transform_spec, "270cw") == 0 || strcmp(transform_spec, "90ccw") == 0) { if (has_rotation) { log_error("options::parse_transform_option(): duplicate rotation specifier %s\n", transform_spec); success = false; break; } has_rotation = true; local_transform.rotation = ROT_CW_270; } else { log_error("options::parse_transform_option(): invalid transform specifier %s\n", transform_spec); success = false; break; } transform_spec = strtok(NULL, "-"); } if (success) { *transform = local_transform; } free(transform_str); return success; } bool parse_region_opt(region_t * region, char ** output, const char * region_arg) { region_t local_region = { .x = 0, .y = 0, .width = 0, .height = 0 }; char * region_str = strdup(region_arg); if (region_str == NULL) { log_error("options::parse_region_option(): failed to allocate copy of region argument\n"); return false; } char * position = strtok(region_str, " "); char * size = strtok(NULL, " "); char * output_label = strtok(NULL, " "); if (position == NULL) { log_error("options::parse_region_option(): missing region position\n"); free(region_str); return false; } char * x = strtok(position, ","); char * y = strtok(NULL, ","); char * rest = strtok(NULL, ","); if (x == NULL) { log_error("options::parse_region_option(): missing x position\n"); free(region_str); return false; } else if (y == NULL) { log_error("options::parse_region_option(): missing y position\n"); free(region_str); return false; } else if (rest != NULL) { log_error("options::parse_region_option(): unexpected position component %s\n", rest); free(region_str); return false; } char * end = NULL; local_region.x = strtoul(x, &end, 10); if (*end != '\0') { log_error("options::parse_region_option(): invalid x position %s\n", x); free(region_str); return false; } end = NULL; local_region.y = strtoul(y, &end, 10); if (*end != '\0') { log_error("options::parse_region_option(): invalid y position %s\n", y); free(region_str); return false; } if (size == NULL) { log_error("options::parse_region_option(): missing size\n"); free(region_str); return false; } char * width = strtok(size, "x"); char * height = strtok(NULL, "x"); rest = strtok(NULL, "x"); if (width == NULL) { log_error("options::parse_region_option(): missing width\n"); free(region_str); return false; } else if (height == NULL) { log_error("options::parse_region_option(): missing height\n"); free(region_str); return false; } else if (rest != NULL) { log_error("options::parse_region_option(): unexpected size component %s\n", rest); free(region_str); return false; } end = NULL; local_region.width = strtoul(width, &end, 10); if (*end != '\0') { log_error("options::parse_region_option(): invalid width %s\n", width); free(region_str); return false; } else if (local_region.width == 0) { log_error("options::parse_region_option(): invalid width %d\n", local_region.width); free(region_str); return false; } end = NULL; local_region.height = strtoul(height, &end, 10); if (*end != '\0') { log_error("options::parse_region_option(): invalid height %s\n", height); free(region_str); return false; } else if (local_region.height == 0) { log_error("options::parse_region_option(): invalid height %d\n", local_region.height); free(region_str); return false; } if (output_label != NULL) { *output = strdup(output_label); if (*output == NULL) { log_error("options::parse_region_option(): failed to allocate copy of output name\n"); free(region_str); return false; } } *region = local_region; free(region_str); return true; } bool find_output_opt(ctx_t * ctx, output_list_node_t ** output_handle, region_t * region_handle) { char * output_name = ctx->opt.output; output_list_node_t * local_output_handle = NULL; region_t local_region = (region_t){ .x = 0, .y = 0, .width = 0, .height = 0 }; if (ctx->opt.output != NULL) { log_debug(ctx, "options::find_output(): searching for output by name\n"); output_list_node_t * cur = ctx->wl.outputs; while (cur != NULL) { if (cur->name != NULL && strcmp(cur->name, ctx->opt.output) == 0) { local_output_handle = cur; output_name = cur->name; break; } cur = cur->next; } } else if (ctx->opt.has_region) { log_debug(ctx, "options::find_output(): searching for output by region\n"); output_list_node_t * cur = ctx->wl.outputs; while (cur != NULL) { region_t output_region = { .x = cur->x, .y = cur->y, .width = cur->width, .height = cur->height }; if (region_contains(&ctx->opt.region, &output_region)) { local_output_handle = cur; output_name = cur->name; break; } cur = cur->next; } } if (local_output_handle == NULL && ctx->opt.output != NULL) { log_error("options::find_output(): output %s not found\n", ctx->opt.output); return false; } else if (local_output_handle == NULL && ctx->opt.has_region) { log_error("options::find_output(): output for region not found\n"); return false; } else if (local_output_handle == NULL) { log_error("options::find_output(): no output or region specified\n"); return false; } else { log_debug(ctx, "options::find_output(): found output with name %s\n", output_name); } if (ctx->opt.has_region) { log_debug(ctx, "options::find_output(): checking if region in output\n"); region_t output_region = { .x = local_output_handle->x, .y = local_output_handle->y, .width = local_output_handle->width, .height = local_output_handle->height }; if (!region_contains(&ctx->opt.region, &output_region)) { log_error("options::find_output(): output does not contain region\n"); return false; } log_debug(ctx, "options::find_output(): clamping region to output bounds\n"); local_region = ctx->opt.region; region_clamp(&local_region, &output_region); } *output_handle = local_output_handle; *region_handle = local_region; return true; } void usage_opt(ctx_t * ctx) { printf("usage: wl-mirror [options] \n"); printf("\n"); printf("options:\n"); printf(" -h, --help show this help\n"); printf(" -V, --version print version\n"); printf(" -v, --verbose enable debug logging\n"); printf(" --no-verbose disable debug logging (default)\n"); printf(" -c, --show-cursor show the cursor on the mirrored screen (default)\n"); printf(" --no-show-cursor don't show the cursor on the mirrored screen\n"); printf(" -i, --invert-colors invert colors in the mirrored screen\n"); printf(" --no-invert-colors don't invert colors in the mirrored screen (default)\n"); printf(" -f, --freeze freeze the current image on the screen\n"); printf(" --unfreeze resume the screen capture after a freeze\n"); printf(" --toggle-freeze toggle freeze state of screen capture\n"); printf(" -F, --fullscreen open wl-mirror as fullscreen\n"); printf(" --no-fullscreen open wl-mirror as a window (default)\n"); printf(" --fullscreen-output O open wl-mirror as fullscreen on output O\n"); printf(" --no-fullscreen-output open wl-mirror as fullscreen on the current output (default)\n"); printf(" -s f, --scaling fit scale to fit (default)\n"); printf(" -s c, --scaling cover scale to cover, cropping if needed\n"); printf(" -s e, --scaling exact only scale to exact multiples of the output size\n"); printf(" -s l, --scaling linear use linear scaling (default)\n"); printf(" -s n, --scaling nearest use nearest neighbor scaling\n"); printf(" -b B --backend B use a specific backend for capturing the screen\n"); printf(" -t T, --transform T apply custom transform T\n"); printf(" -r R, --region R capture custom region R\n"); printf(" --no-region capture the entire output (default)\n"); printf(" -S, --stream accept a stream of additional options on stdin\n"); printf("\n"); printf("backends:\n"); printf(" - auto automatically try the backends in order and use the first that works (default)\n"); printf(" - dmabuf use the wlr-export-dmabuf-unstable-v1 protocol to capture outputs\n"); printf(" - screencopy use the wlr-screencopy-unstable-v1 protocol to capture outputs\n"); printf("\n"); printf("transforms:\n"); printf(" transforms are specified as a dash-separated list of flips followed by a rotation\n"); printf(" flips are applied before rotations\n"); printf(" - normal no transformation\n"); printf(" - flipX, flipY flip the X or Y coordinate\n"); printf(" - 0cw, 90cw, 180cw, 270cw apply a clockwise rotation\n"); printf(" - 0ccw, 90ccw, 180ccw, 270ccw apply a counter-clockwise rotation\n"); printf(" the following transformation options are provided for compatibility with sway output transforms\n"); printf(" - flipped flip the X coordinate\n"); printf(" - 0, 90, 180, 270 apply a clockwise rotation\n"); printf("\n"); printf("regions:\n"); printf(" regions are specified in the format used by the slurp utility\n"); printf(" - ', x [output]'\n"); printf(" on start, the region is translated into output coordinates\n"); printf(" when the output moves, the captured region moves with it\n"); printf(" when a region is specified, the argument is optional\n"); printf("\n"); printf("stream mode:\n"); printf(" in stream mode, wl-mirror interprets lines on stdin as additional command line options\n"); printf(" - arguments can be quoted with single or double quotes, but every argument must be fully\n"); printf(" quoted or fully unquoted\n"); printf(" - unquoted arguments are split on whitespace\n"); printf(" - no escape sequences are implemented\n"); cleanup(ctx); exit(0); } void version_opt(ctx_t * ctx) { printf("wl-mirror %s\n", VERSION); cleanup(ctx); exit(0); } void parse_opt(ctx_t * ctx, int argc, char ** argv) { bool is_cli_args = !ctx->opt.stream; bool was_frozen = ctx->opt.freeze; bool was_fullscreen = ctx->opt.fullscreen; bool new_backend = false; bool new_region = false; bool new_output = false; bool new_fullscreen_output = false; char * region_output = NULL; char * arg_output = NULL; while (argc > 0 && argv[0][0] == '-') { if (is_cli_args && (strcmp(argv[0], "-h") == 0 || strcmp(argv[0], "--help") == 0)) { usage_opt(ctx); } else if (strcmp(argv[0], "-V") == 0 || strcmp(argv[0], "--version") == 0) { version_opt(ctx); } else if (strcmp(argv[0], "-v") == 0 || strcmp(argv[0], "--verbose") == 0) { ctx->opt.verbose = true; } else if (strcmp(argv[0], "--no-verbose") == 0) { ctx->opt.verbose = false; } else if (strcmp(argv[0], "-c") == 0 || strcmp(argv[0], "--show-cursor") == 0) { ctx->opt.show_cursor = true; } else if (strcmp(argv[0], "--no-show-cursor") == 0) { ctx->opt.show_cursor = false; } else if (strcmp(argv[0], "-n") == 0) { log_warn("options::parse(): -n is deprecated, use --no-show-cursor\n"); ctx->opt.show_cursor = false; } else if (strcmp(argv[0], "-i") == 0 || strcmp(argv[0], "--invert-colors") == 0) { ctx->opt.invert_colors = true; } else if (strcmp(argv[0], "--no-invert-colors") == 0) { ctx->opt.invert_colors = false; } else if (strcmp(argv[0], "-f") == 0 || strcmp(argv[0], "--freeze") == 0) { ctx->opt.freeze = true; } else if (strcmp(argv[0], "--unfreeze") == 0) { ctx->opt.freeze = false; } else if (strcmp(argv[0], "--toggle-freeze") == 0) { ctx->opt.freeze ^= 1; } else if (strcmp(argv[0], "-F") == 0 || strcmp(argv[0], "--fullscreen") == 0) { ctx->opt.fullscreen = true; } else if (strcmp(argv[0], "--no-fullscreen") == 0) { ctx->opt.fullscreen = false; } else if (strcmp(argv[0], "--fullscreen-output") == 0) { if (argc < 2) { log_error("options::parse(): option %s requires an argument\n", argv[0]); if (is_cli_args) exit_fail(ctx); } else { free(ctx->opt.fullscreen_output); ctx->opt.fullscreen = true; ctx->opt.fullscreen_output = strdup(argv[1]); new_fullscreen_output = true; argv++; argc--; } } else if (strcmp(argv[0], "--no-fullscreen-output") == 0) { free(ctx->opt.fullscreen_output); ctx->opt.fullscreen_output = NULL; new_fullscreen_output = true; } else if (strcmp(argv[0], "-s") == 0 || strcmp(argv[0], "--scaling") == 0) { if (argc < 2) { log_error("options::parse(): option %s requires an argument\n", argv[0]); if (is_cli_args) exit_fail(ctx); } else { if (!parse_scaling_opt(&ctx->opt.scaling, &ctx->opt.scaling_filter, argv[1])) { log_error("options::parse(): invalid scaling mode %s\n", argv[1]); if (is_cli_args) exit_fail(ctx); } argv++; argc--; } } else if (strcmp(argv[0], "-b") == 0 || strcmp(argv[0], "--backend") == 0) { if (argc < 2) { log_error("options::parse(): option %s requires an argument\n", argv[0]); if (is_cli_args) exit_fail(ctx); } else { if (!parse_backend_opt(&ctx->opt.backend, argv[1])) { log_error("options::parse(): invalid backend %s\n", argv[1]); if (is_cli_args) exit_fail(ctx); } new_backend = true; argv++; argc--; } } else if (strcmp(argv[0], "-t") == 0 || strcmp(argv[0], "--transform") == 0) { if (argc < 2) { log_error("options::parse(): option %s requires an argument\n", argv[0]); if (is_cli_args) exit_fail(ctx); } else { if (!parse_transform_opt(&ctx->opt.transform, argv[1])) { log_error("options::parse(): invalid transform %s\n", argv[1]); if (is_cli_args) exit_fail(ctx); } argv++; argc--; } } else if (strcmp(argv[0], "-r") == 0 || strcmp(argv[0], "--region") == 0) { if (argc < 2) { log_error("options::parse(): option %s requires an argument\n", argv[0]); if (is_cli_args) exit_fail(ctx); } else { char * new_region_output = NULL; if (!parse_region_opt(&ctx->opt.region, &new_region_output, argv[1])) { log_error("options::parse(): invalid region %s\n", argv[1]); if (is_cli_args) exit_fail(ctx); } else { ctx->opt.has_region = true; free(region_output); region_output = new_region_output; new_region = true; } argv++; argc--; } } else if (strcmp(argv[0], "--no-region") == 0) { ctx->opt.has_region = false; ctx->opt.region = (region_t){ .x = 0, .y = 0, .width = 0, .height = 0 }; } else if (strcmp(argv[0], "-S") == 0 || strcmp(argv[0], "--stream") == 0) { ctx->opt.stream = true; } else if (strcmp(argv[0], "--") == 0) { argv++; argc--; break; } else { log_error("options::parse(): invalid option %s\n", argv[0]); if (is_cli_args) exit_fail(ctx); } argv++; argc--; } if (argc > 0) { arg_output = strdup(argv[0]); if (arg_output == NULL) { log_error("options::parse(): failed to allocate copy of output name\n"); if (is_cli_args) exit_fail(ctx); } else { new_output = true; } } if (new_output || new_region) { free(ctx->opt.output); ctx->opt.output = NULL; } if (new_output && !new_region) { ctx->opt.has_region = false; ctx->opt.region = (region_t){ .x = 0, .y = 0, .width = 0, .height = 0 }; } if (!new_output && new_region && region_output == NULL) { // output implicitly defined by region ctx->opt.output = NULL; } else if (!new_output && new_region && region_output != NULL) { // output explicitly defined by region ctx->opt.output = region_output; } else if (new_output && new_region && region_output == NULL) { // output defined by argument // region must be in this output ctx->opt.output = arg_output; } else if (new_output && new_region && region_output != NULL) { // output defined by both region and argument // must be the same // region must be in this output if (strcmp(region_output, arg_output) != 0) { log_error("options::parse(): region and argument output differ: %s vs %s\n", region_output, arg_output); if (is_cli_args) exit_fail(ctx); } ctx->opt.output = region_output; } else if (new_output && !new_region) { // output defined by argument ctx->opt.output = arg_output; } else if (!new_output && !new_region && is_cli_args) { // no output or region specified usage_opt(ctx); } if ( ctx->opt.output != NULL && ctx->opt.fullscreen_output != NULL && strcmp(ctx->opt.output, ctx->opt.fullscreen_output) == 0 ) { log_error("options::parse(): fullscreen_output cannot be same as the output to be mirrored"); exit_fail(ctx); } if (argc > 1) { log_error("options::parse(): unexpected trailing arguments after output name\n"); if (is_cli_args) exit_fail(ctx); } if (!is_cli_args && ctx->opt.fullscreen && (!was_fullscreen || new_fullscreen_output)) { set_window_fullscreen(ctx); } else if (!is_cli_args && !ctx->opt.fullscreen && was_fullscreen) { unset_window_fullscreen(ctx); } output_list_node_t * target_output = NULL; region_t target_region = (region_t){ .x = 0, .y = 0, .width = 0, .height = 0 }; if (!is_cli_args && find_output_opt(ctx, &target_output, &target_region)) { ctx->mirror.current_target = target_output; ctx->mirror.current_region = target_region; } if (!is_cli_args && new_backend) { init_mirror_backend(ctx); } if (!is_cli_args && !was_frozen && ctx->opt.freeze) { freeze_framebuffer(ctx); } if (!is_cli_args) { update_uniforms(ctx); update_title(ctx); } } wl-mirror-0.16.5/src/stream.c0000644000175000017500000001214714646471773014525 0ustar yrlfyrlf#include #include #include #include #include #include #include "context.h" #define ARGS_MIN_CAP 8 static void args_push(ctx_t * ctx, char * arg) { if (ctx->stream.args_len == ctx->stream.args_cap) { size_t new_cap = ctx->stream.args_cap * 2; if (new_cap == 0) new_cap = ARGS_MIN_CAP; char ** new_args = realloc(ctx->stream.args, sizeof (char *) * new_cap); if (new_args == NULL) { log_error("event::args_push(): failed to grow args array for option stream line\n"); exit_fail(ctx); } ctx->stream.args = new_args; ctx->stream.args_cap = new_cap; } ctx->stream.args[ctx->stream.args_len++] = arg; } #define LINE_MIN_RESERVE 1024 static void line_reserve(ctx_t * ctx) { if (ctx->stream.line_cap - ctx->stream.line_len < LINE_MIN_RESERVE) { size_t new_cap = ctx->stream.line_cap * 2; if (new_cap == 0) new_cap = LINE_MIN_RESERVE; char * new_line = realloc(ctx->stream.line, sizeof (char) * new_cap); if (new_line == NULL) { log_error("event::line_reserve(): failed to grow line buffer for option stream line\n"); exit_fail(ctx); } ctx->stream.line = new_line; ctx->stream.line_cap = new_cap; } } enum parse_state { BEFORE_ARG, ARG_START, QUOTED_ARG, UNQUOTED_ARG }; static void on_line(ctx_t * ctx, char * line) { char * arg_start = NULL; char quote_char = '\0'; log_debug(ctx, "event::on_line(): got line '%s'\n", line); ctx->stream.args_len = 0; enum parse_state state = BEFORE_ARG; while (*line != '\0') { switch (state) { case BEFORE_ARG: if (isspace(*line)) { line++; } else { state = ARG_START; } break; case ARG_START: if (*line == '"' || *line == '\'') { quote_char = *line; line++; arg_start = line; state = QUOTED_ARG; } else { arg_start = line; state = UNQUOTED_ARG; } break; case QUOTED_ARG: if (*line != quote_char) { line++; } else { *line = '\0'; args_push(ctx, arg_start); line++; state = BEFORE_ARG; } break; case UNQUOTED_ARG: if (!isspace(*line)) { line++; } else { *line = '\0'; args_push(ctx, arg_start); line++; state = BEFORE_ARG; } break; } } if (state == QUOTED_ARG) { log_error("event::on_line(): unmatched quote in argument\n"); } if (state == QUOTED_ARG || state == UNQUOTED_ARG) { args_push(ctx, arg_start); } log_debug(ctx, "event::on_line(): parsed %zd arguments\n", ctx->stream.args_len); parse_opt(ctx, ctx->stream.args_len, ctx->stream.args); } static void on_stream_data(ctx_t * ctx) { while (true) { line_reserve(ctx); size_t cap = ctx->stream.line_cap; size_t len = ctx->stream.line_len; ssize_t num = read(STDIN_FILENO, ctx->stream.line + len, cap - len); if (num == -1 && errno == EWOULDBLOCK) { break; } else if (num == -1) { log_error("event::on_data(): failed to read data from stdin\n"); exit_fail(ctx); } else { ctx->stream.line_len += num; } } char * line = ctx->stream.line; size_t len = ctx->stream.line_len; for (size_t i = 0; i < len; i++) { if (line[i] == '\0') { line[i] = ' '; } else if (line[i] == '\n') { line[i] = '\0'; on_line(ctx, line); memmove(line, line + (i + 1), len - (i + 1)); ctx->stream.line_len -= i + 1; break; } } } void init_stream(ctx_t * ctx) { // initialize context structure ctx->stream.line = NULL; ctx->stream.line_len = 0; ctx->stream.line_cap = 0; ctx->stream.args = NULL; ctx->stream.args_len = 0; ctx->stream.args_cap = 0; ctx->stream.event_handler.next = NULL; ctx->stream.event_handler.fd = STDIN_FILENO; ctx->stream.event_handler.events = EPOLLIN; ctx->stream.event_handler.timeout_ms = -1; ctx->stream.event_handler.on_event = on_stream_data; ctx->stream.event_handler.on_each = NULL; if (ctx->opt.stream) { int flags = fcntl(STDIN_FILENO, F_GETFL, 0); flags |= O_NONBLOCK; fcntl(STDIN_FILENO, F_SETFL, flags); event_add_fd(ctx, &ctx->stream.event_handler); } ctx->stream.initialized = true; } void cleanup_stream(ctx_t * ctx) { free(ctx->stream.line); free(ctx->stream.args); if (ctx->opt.stream) { event_remove_fd(ctx, &ctx->stream.event_handler); } } wl-mirror-0.16.5/src/transform.c0000644000175000017500000001312014646471773015235 0ustar yrlfyrlf#include #include #include "transform.h" static const mat3_t mat_identity = { .data = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } }}; static const mat3_t mat_rot_ccw_90 = { .data = { { 0, 1, 0 }, { -1, 0, 1 }, { 0, 0, 1 } }}; static const mat3_t mat_rot_ccw_180 = { .data = { { -1, 0, 1 }, { 0, -1, 1 }, { 0, 0, 1 } }}; static const mat3_t mat_rot_ccw_270 = { .data = { { 0, -1, 1 }, { 1, 0, 0 }, { 0, 0, 1 } }}; static const mat3_t mat_flip_x = { .data = { { -1, 0, 1 }, { 0, 1, 0 }, { 0, 0, 1 } }}; static const mat3_t mat_flip_y = { .data = { { 1, 0, 0 }, { 0, -1, 1 }, { 0, 0, 1 } }}; void mat3_identity(mat3_t * mat) { *mat = mat_identity; } void mat3_transpose(mat3_t * mat) { for (size_t row = 0; row < 3; row++) { for (size_t col = row + 1; col < 3; col++) { float temp = mat->data[row][col]; mat->data[row][col] = mat->data[col][row]; mat->data[col][row] = temp; } } } void mat3_mul(const mat3_t * mul, mat3_t * dest) { mat3_t src = *dest; for (size_t row = 0; row < 3; row++) { for (size_t col = 0; col < 3; col++) { dest->data[row][col] = 0; for (size_t i = 0; i < 3; i++) { dest->data[row][col] += mul->data[row][i] * src.data[i][col]; } } } } void mat3_apply_transform(mat3_t * mat, transform_t transform) { // apply inverse transformation matrix as we need to transform // from OpenGL space to dmabuf space switch (transform.rotation) { case ROT_NORMAL: break; case ROT_CW_90: mat3_mul(&mat_rot_ccw_90, mat); break; case ROT_CW_180: mat3_mul(&mat_rot_ccw_180, mat); break; case ROT_CW_270: mat3_mul(&mat_rot_ccw_270, mat); break; } if (transform.flip_x) mat3_mul(&mat_flip_x, mat); if (transform.flip_y) mat3_mul(&mat_flip_y, mat); } void mat3_apply_region_transform(mat3_t * mat, const region_t * region, const region_t * output) { mat3_t region_transform; mat3_identity(®ion_transform); region_transform.data[0][2] = (float)region->x / output->width; region_transform.data[1][2] = (float)region->y / output->height; region_transform.data[0][0] = (float)region->width / output->width; region_transform.data[1][1] = (float)region->height / output->height; mat3_mul(®ion_transform, mat); } void mat3_apply_output_transform(mat3_t * mat, enum wl_output_transform transform) { // wl_output transform is already inverted switch (transform) { case WL_OUTPUT_TRANSFORM_NORMAL: break; case WL_OUTPUT_TRANSFORM_90: mat3_mul(&mat_rot_ccw_90, mat); break; case WL_OUTPUT_TRANSFORM_180: mat3_mul(&mat_rot_ccw_180, mat); break; case WL_OUTPUT_TRANSFORM_270: mat3_mul(&mat_rot_ccw_270, mat); break; case WL_OUTPUT_TRANSFORM_FLIPPED: mat3_mul(&mat_flip_x, mat); break; case WL_OUTPUT_TRANSFORM_FLIPPED_90: mat3_mul(&mat_flip_x, mat); mat3_mul(&mat_rot_ccw_90, mat); break; case WL_OUTPUT_TRANSFORM_FLIPPED_180: mat3_mul(&mat_flip_x, mat); mat3_mul(&mat_rot_ccw_180, mat); break; case WL_OUTPUT_TRANSFORM_FLIPPED_270: mat3_mul(&mat_flip_x, mat); mat3_mul(&mat_rot_ccw_270, mat); break; } } void mat3_apply_invert_y(mat3_t * mat, bool invert_y) { if (invert_y) { mat3_mul(&mat_flip_y, mat); } } void viewport_apply_transform(uint32_t * width, uint32_t * height, transform_t transform) { uint32_t w = *width; uint32_t h = *height; switch (transform.rotation) { case ROT_CCW_90: case ROT_CCW_270: *height = w; *width = h; break; default: break; } } void viewport_apply_output_transform(uint32_t * width, uint32_t * height, enum wl_output_transform transform) { uint32_t w = *width; uint32_t h = *height; switch (transform) { case WL_OUTPUT_TRANSFORM_90: case WL_OUTPUT_TRANSFORM_270: case WL_OUTPUT_TRANSFORM_FLIPPED_90: case WL_OUTPUT_TRANSFORM_FLIPPED_270: *height = w; *width = h; break; default: break; } } bool region_contains(const region_t * region, const region_t * output) { if (region->x + region->width <= output->x) return false; if (region->x >= output->x + output->width) return false; if (region->y + region->height <= output->y) return false; if (region->y >= output->y + output->height) return false; return true; } void region_scale(region_t * region, double scale) { region->x *= scale; region->y *= scale; region->width *= scale; region->height *= scale; } void region_clamp(region_t * region, const region_t * output) { if (region->x < output->x) { region->width -= output->x - region->x; region->x = 0; } else { region->x -= output->x; } if (region->x + region->width > output->width) { region->width = output->width - region->x; } if (region->y < output->y) { region->height -= output->y - region->y; region->y = 0; } else { region->y -= output->y; } if (region->y + region->height > output->height) { region->height = output->height - region->y; } } wl-mirror-0.16.5/src/wayland.c0000644000175000017500000007726314646471773014703 0ustar yrlfyrlf#include #include #include #include "context.h" // --- output event handlers --- static void on_output_geometry( void * data, struct wl_output * output, int32_t x, int32_t y, int32_t physical_width, int32_t physical_height, int32_t subpixel, const char * make, const char * model, int32_t transform ) { output_list_node_t * node = (output_list_node_t *)data; ctx_t * ctx = node->ctx; // update transform only if changed if (node->transform != (uint32_t)transform) { if (ctx->opt.verbose) { log_debug(ctx, "wayland::on_output_geometry(): updating output %s (transform = ", node->name); switch (transform) { case WL_OUTPUT_TRANSFORM_NORMAL: fprintf(stderr, "normal"); break; case WL_OUTPUT_TRANSFORM_90: fprintf(stderr, "90ccw"); break; case WL_OUTPUT_TRANSFORM_180: fprintf(stderr, "180ccw"); break; case WL_OUTPUT_TRANSFORM_270: fprintf(stderr, "270ccw"); break; case WL_OUTPUT_TRANSFORM_FLIPPED: fprintf(stderr, "flipX"); break; case WL_OUTPUT_TRANSFORM_FLIPPED_90: fprintf(stderr, "flipX-90ccw"); break; case WL_OUTPUT_TRANSFORM_FLIPPED_180: fprintf(stderr, "flipX-180ccw"); break; case WL_OUTPUT_TRANSFORM_FLIPPED_270: fprintf(stderr, "flipX-270ccw"); break; default: fprintf(stderr, "unknown"); break; } fprintf(stderr, ", id = %d)\n", node->output_id); } node->transform = transform; // update egl viewport only if this is the target output if (ctx->mirror.initialized && ctx->mirror.current_target->output == output) { resize_viewport(ctx); } } (void)x; (void)y; (void)physical_width; (void)physical_height; (void)subpixel; (void)make; (void)model; (void)transform; } static void on_output_mode( void * data, struct wl_output * output, uint32_t flags, int32_t width, int32_t height, int32_t refresh ) { (void)data; (void)output; (void)flags; (void)width; (void)height; (void)refresh; } static void on_output_scale( void * data, struct wl_output * output, int32_t scale ) { output_list_node_t * node = (output_list_node_t *)data; ctx_t * ctx = node->ctx; // update scale only if changed if (node->scale != scale) { log_debug(ctx, "wayland::on_output_scale(): updating output %s (scale = %d, id = %d)\n", node->name, scale, node->output_id); node->scale = scale; // update buffer scale only if this is the current output if (ctx->wl.current_output != NULL && ctx->wl.current_output->output == output) { log_debug(ctx, "wayland::on_output_scale(): updating window scale\n"); update_window_scale(ctx, scale, false); } } } static void on_output_done( void * data, struct wl_output * output ) { (void)data; (void)output; } static const struct wl_output_listener output_listener = { .geometry = on_output_geometry, .mode = on_output_mode, .scale = on_output_scale, .done = on_output_done }; // --- xdg_output event handlers --- static void on_xdg_output_description( void * data, struct zxdg_output_v1 * xdg_output, const char * description ) { (void)data; (void)xdg_output; (void)description; } static void on_xdg_output_logical_position( void * data, struct zxdg_output_v1 * xdg_output, int32_t x, int32_t y ) { output_list_node_t * node = (output_list_node_t *)data; ctx_t * ctx = node->ctx; // update position only if changed if (node->x != x || node->y != y) { log_debug(ctx, "wayland::on_xdg_output_logical_position(): updating output %s (position = %d,%d, id = %d)\n", node->name, x, y, node->output_id); node->x = x; node->y = y; } (void)xdg_output; } static void on_xdg_output_logical_size( void * data, struct zxdg_output_v1 * xdg_output, int32_t width, int32_t height ) { output_list_node_t * node = (output_list_node_t *)data; ctx_t * ctx = node->ctx; // update size only if changed if (node->width != width || node->height != height) { log_debug(ctx, "wayland::on_xdg_output_logical_size(): updating output %s (size = %dx%d, id = %d)\n", node->name, width, height, node->output_id); node->width = width; node->height = height; } (void)xdg_output; } static void on_xdg_output_name( void * data, struct zxdg_output_v1 * xdg_output, const char * name ) { output_list_node_t * node = (output_list_node_t *)data; ctx_t * ctx = node->ctx; // update name only if changed if (node->name == NULL || strcmp(node->name, name) != 0) { log_debug(ctx, "wayland::on_xdg_output_name(): updating output %s (id = %d)\n", name, node->output_id); // allocate copy of name since name is owned by libwayland free(node->name); node->name = strdup(name); if (node->name == NULL) { log_error("wayland::on_xdg_output_name(): failed to allocate output name\n"); exit_fail(ctx); } } (void)xdg_output; } static void on_xdg_output_done( void * data, struct zxdg_output_v1 * xdg_output ) { (void)data; (void)xdg_output; } static const struct zxdg_output_v1_listener xdg_output_listener = { .description = on_xdg_output_description, .logical_position = on_xdg_output_logical_position, .logical_size = on_xdg_output_logical_size, .name = on_xdg_output_name, .done = on_xdg_output_done }; // --- registry event handlers --- static void on_registry_add( void * data, struct wl_registry * registry, uint32_t id, const char * interface, uint32_t version ) { ctx_t * ctx = (ctx_t *)data; log_debug(ctx, "wayland::on_registry_add(): %s (version = %d, id = %d)\n", interface, version, id); // bind proxy object for each protocol we need // bind proxy object for each output if (strcmp(interface, wl_compositor_interface.name) == 0) { if (ctx->wl.compositor != NULL) { log_error("wayland::on_registry_add(): duplicate compositor\n"); exit_fail(ctx); } // bind compositor object ctx->wl.compositor = (struct wl_compositor *)wl_registry_bind( registry, id, &wl_compositor_interface, 4 ); ctx->wl.compositor_id = id; } else if (strcmp(interface, wp_viewporter_interface.name) == 0) { if (ctx->wl.viewporter != NULL) { log_error("wayland::on_registry_add(): duplicate wp_viewporter\n"); exit_fail(ctx); } // bind wp_viewporter object ctx->wl.viewporter = (struct wp_viewporter *)wl_registry_bind( registry, id, &wp_viewporter_interface, 1 ); } else if (strcmp(interface, wp_fractional_scale_manager_v1_interface.name) == 0) { if (ctx->wl.fractional_scale_manager != NULL) { log_error("wayland::on_registry_add(): duplicate wp_fractional_scale_manager\n"); exit_fail(ctx); } // bind wp_fractional_scale_manager_v1 object ctx->wl.fractional_scale_manager = (struct wp_fractional_scale_manager_v1 *)wl_registry_bind( registry, id, &wp_fractional_scale_manager_v1_interface, 1 ); } else if (strcmp(interface, xdg_wm_base_interface.name) == 0) { if (ctx->wl.wm_base != NULL) { log_error("wayland::on_registry_add(): duplicate wm_base\n"); exit_fail(ctx); } // bind wm_base object ctx->wl.wm_base = (struct xdg_wm_base *)wl_registry_bind( registry, id, &xdg_wm_base_interface, 2 ); ctx->wl.wm_base_id = id; } else if (strcmp(interface, zxdg_output_manager_v1_interface.name) == 0) { if (ctx->wl.output_manager != NULL) { log_error("wayland::on_registry_add(): duplicate output_manager\n"); exit_fail(ctx); } // bind output_manager object ctx->wl.output_manager = (struct zxdg_output_manager_v1 *)wl_registry_bind( registry, id, &zxdg_output_manager_v1_interface, 2 ); ctx->wl.output_manager_id = id; } else if (strcmp(interface, zwlr_export_dmabuf_manager_v1_interface.name) == 0) { if (ctx->wl.dmabuf_manager != NULL) { log_error("wayland::on_registry_add(): duplicate dmabuf_manager\n"); exit_fail(ctx); } // bind dmabuf manager object // - for mirror-dmabuf backend ctx->wl.dmabuf_manager = (struct zwlr_export_dmabuf_manager_v1 *)wl_registry_bind( registry, id, &zwlr_export_dmabuf_manager_v1_interface, 1 ); ctx->wl.dmabuf_manager_id = id; } else if (strcmp(interface, zwlr_screencopy_manager_v1_interface.name) == 0) { if (ctx->wl.screencopy_manager != NULL) { log_error("wayland::on_registry_add(): duplicate screencopy_manager\n"); exit_fail(ctx); } // bind screencopy manager object // - for mirror-screencopy backend ctx->wl.screencopy_manager = (struct zwlr_screencopy_manager_v1 *)wl_registry_bind( registry, id, &zwlr_screencopy_manager_v1_interface, 3 ); ctx->wl.screencopy_manager_id = id; } else if (strcmp(interface, wl_shm_interface.name) == 0) { if (ctx->wl.shm != NULL) { log_error("wayland::on_registry_add(): duplicate shm\n"); exit_fail(ctx); } // bind shm object // - for mirror-screencopy backend ctx->wl.shm = (struct wl_shm *)wl_registry_bind( registry, id, &wl_shm_interface, 1 ); ctx->wl.shm_id = id; } else if (strcmp(interface, wl_output_interface.name) == 0) { // allocate output node output_list_node_t * node = malloc(sizeof (output_list_node_t)); if (node == NULL) { log_error("wayland::on_registry_add(): failed to allocate output node\n"); exit_fail(ctx); } // initialize output node node->ctx = ctx; node->name = NULL; node->xdg_output = NULL; node->x = 0; node->y = 0; node->width = 0; node->height = 0; node->scale = 1; node->transform = 0; // prepend output node to output list node->next = ctx->wl.outputs; ctx->wl.outputs = node; // bind wl_output node->output = (struct wl_output *)wl_registry_bind( registry, id, &wl_output_interface, 3 ); node->output_id = id; // add output event listener // - for geometry event // - for scale event wl_output_add_listener(node->output, &output_listener, (void *)node); // check for xdg_output_manager // - sway always sends outputs after protocol extensions // - for simplicity, only this event order is supported if (ctx->wl.output_manager == NULL) { log_error("wayland::on_registry_add(): wl_output received before xdg_output_manager\n"); exit_fail(ctx); } // create xdg_output object node->xdg_output = (struct zxdg_output_v1 *)zxdg_output_manager_v1_get_xdg_output( ctx->wl.output_manager, node->output ); if (node->xdg_output == NULL) { log_error("wayland::on_registry_add(): failed to create xdg_output\n"); exit_fail(ctx); } // add xdg_output event listener // - for logical_position event // - for logical_size event // - for name event zxdg_output_v1_add_listener(node->xdg_output, &xdg_output_listener, (void *)node); } else if (strcmp(interface, wl_seat_interface.name) == 0) { // allocate seat node seat_list_node_t * node = malloc(sizeof (seat_list_node_t)); if (node == NULL) { log_error("wayland::on_registry_add(): failed to allocate seat node\n"); exit_fail(ctx); } // initialize seat node node->ctx = ctx; // prepend seat node to seat list node->next = ctx->wl.seats; ctx->wl.seats = node; // bind wl_seat node->seat = (struct wl_seat *)wl_registry_bind( registry, id, &wl_seat_interface, 1 ); node->seat_id = id; } (void)version; } static void on_registry_remove( void * data, struct wl_registry * registry, uint32_t id ) { ctx_t * ctx = (ctx_t *)data; // ensure protocols we need aren't removed // remove removed outputs from the output list if (id == ctx->wl.compositor_id) { log_error("wayland::on_registry_remove(): compositor disappeared\n"); exit_fail(ctx); } else if (id == ctx->wl.viewporter_id) { log_error("wayland::on_registry_remove(): viewporter disappeared\n"); exit_fail(ctx); } else if (id == ctx->wl.fractional_scale_manager_id) { log_error("wayland::on_registry_remove(): fractional_scale_manager disappeared\n"); exit_fail(ctx); } else if (id == ctx->wl.wm_base_id) { log_error("wayland::on_registry_remove(): wm_base disappeared\n"); exit_fail(ctx); } else if (id == ctx->wl.output_manager_id) { log_error("wayland::on_registry_remove(): output_manager disappeared\n"); exit_fail(ctx); } else if (id == ctx->wl.dmabuf_manager_id) { log_error("wayland::on_registry_remove(): dmabuf_manager disappeared\n"); exit_fail(ctx); } else { { output_list_node_t ** link = &ctx->wl.outputs; output_list_node_t * cur = ctx->wl.outputs; output_list_node_t * prev = NULL; while (cur != NULL) { if (id == cur->output_id) { log_debug(ctx, "wayland::on_registry_remove(): output %s removed (id = %d)\n", cur->name, id); // notify mirror code of removed outputs // - triggers exit if the target output disappears output_removed(ctx, cur); // remove output node from linked list *link = cur->next; prev = cur; cur = cur->next; // deallocate output node zxdg_output_v1_destroy(prev->xdg_output); wl_output_destroy(prev->output); free(prev->name); free(prev); // return because the removed object was found return; } else { link = &cur->next; cur = cur->next; } } } // output not found // id must have been a seat { seat_list_node_t ** link = &ctx->wl.seats; seat_list_node_t * cur = ctx->wl.seats; seat_list_node_t * prev = NULL; while (cur != NULL) { if (id == cur->seat_id) { log_debug(ctx, "wayland::on_registry_remove(): seat removed (id = %d)\n", id); // remove seat node from linked list *link = cur->next; prev = cur; cur = cur->next; // deallocate seat node wl_seat_destroy(prev->seat); free(prev); // return because the removed object was found return; } else { link = &cur->next; cur = cur->next; } } } } (void)registry; } static const struct wl_registry_listener registry_listener = { .global = on_registry_add, .global_remove = on_registry_remove }; // --- wm_base event handlers --- static void on_wm_base_ping( void * data, struct xdg_wm_base * xdg_wm_base, uint32_t serial ) { xdg_wm_base_pong(xdg_wm_base, serial); (void)data; } static const struct xdg_wm_base_listener wm_base_listener = { .ping = on_wm_base_ping }; // --- surface event handlers --- static void on_surface_enter( void * data, struct wl_surface * surface, struct wl_output * output ) { ctx_t * ctx = (ctx_t *)data; // find output list node for the entered output output_list_node_t * node = NULL; output_list_node_t * cur = ctx->wl.outputs; while (cur != NULL) { if (cur->output == output) { node = cur; break; } cur = cur->next; } // verify an output was found if (node == NULL) { // when multiple registries exist and different parts of the application // bind separately to the same wl_output, on_surface_enter will be called // multiple times. // // only one of those calls will give us an output in our list of outputs. // we should ignore all other calls, instead of bailing completely log_debug(ctx, "wayland::on_surface_enter(): entered output not in output list, possibly bound from another registry?\n"); return; } // update current output bool first_output = ctx->wl.current_output == NULL; ctx->wl.current_output = node; // set window fullscreen now if no specific output requested if (first_output && ctx->opt.fullscreen) { set_window_fullscreen(ctx); } log_debug(ctx, "wayland::on_surface_enter(): updating window scale\n"); update_window_scale(ctx, node->scale, false); (void)surface; } static void on_surface_leave( void * data, struct wl_surface * surface, struct wl_output * output ) { (void)data; (void)surface; (void)output; } static const struct wl_surface_listener surface_listener = { .enter = on_surface_enter, .leave = on_surface_leave }; // --- configure callbacks --- static void on_surface_configure_finished(ctx_t * ctx) { // acknowledge configure and commit surface to finish configure sequence log_debug(ctx, "wayland::on_surface_configure_finished(): window configured\n"); xdg_surface_ack_configure(ctx->wl.xdg_surface, ctx->wl.last_surface_serial); wl_surface_commit(ctx->wl.surface); // reset configure sequence state machine ctx->wl.xdg_surface_configured = false; ctx->wl.xdg_toplevel_configured = false; ctx->wl.configured = true; } // --- xdg_surface event handlers --- static void on_xdg_surface_configure( void * data, struct xdg_surface * xdg_surface, uint32_t serial ) { ctx_t * ctx = (ctx_t *)data; // save serial for configure acknowledgement ctx->wl.last_surface_serial = serial; // update configure sequence state machine ctx->wl.xdg_surface_configured = true; if (ctx->wl.xdg_surface_configured && ctx->wl.xdg_toplevel_configured) { on_surface_configure_finished(ctx); } (void)xdg_surface; } static const struct xdg_surface_listener xdg_surface_listener = { .configure = on_xdg_surface_configure, }; // --- xdg_toplevel event handlers --- static void on_xdg_toplevel_configure( void * data, struct xdg_toplevel * xdg_toplevel, int32_t width, int32_t height, struct wl_array * states ) { ctx_t * ctx = (ctx_t *)data; // set default size of 100x100 if compositor does not have a preference if (width == 0) width = 100; if (height == 0) height = 100; // check fullscreen state bool is_fullscreen = false; uint32_t * state; wl_array_for_each(state, states) { if (*state == XDG_TOPLEVEL_STATE_FULLSCREEN) { is_fullscreen = true; } } // reset fullscreen option if the window is not fullscreen // but only if have already had the chance to fullscreen on the current output if (is_fullscreen != ctx->opt.fullscreen && ctx->wl.current_output != NULL) { ctx->opt.fullscreen = is_fullscreen; } // update size only if changed if (ctx->wl.width != (uint32_t)width || ctx->wl.height != (uint32_t)height) { log_debug(ctx, "wayland::on_xdg_toplevel_configure(): window resized to %dx%d\n", width, height); ctx->wl.width = width; ctx->wl.height = height; // resize viewport wp_viewport_set_destination(ctx->wl.viewport, width, height); // resize window to reflect new surface size if (ctx->egl.initialized) { resize_window(ctx); } } // update configure sequence state machine ctx->wl.xdg_toplevel_configured = true; if (ctx->wl.xdg_surface_configured && ctx->wl.xdg_toplevel_configured) { on_surface_configure_finished(ctx); } (void)xdg_toplevel; (void)states; } static void on_xdg_toplevel_close( void * data, struct xdg_toplevel * xdg_toplevel ) { ctx_t * ctx = (ctx_t *)data; log_debug(ctx, "wayland::on_xdg_toplevel_close(): close request received\n"); ctx->wl.closing = true; (void)xdg_toplevel; } static const struct xdg_toplevel_listener xdg_toplevel_listener = { .configure = on_xdg_toplevel_configure, .close = on_xdg_toplevel_close }; static void on_loop_event(ctx_t * ctx) { if (wl_display_dispatch(ctx->wl.display) == -1) { ctx->wl.closing = true; } } static void on_loop_each(ctx_t * ctx) { wl_display_flush(ctx->wl.display); } // --- fractional scale event handlers --- static void on_fractional_scale_preferred_scale(void * data, struct wp_fractional_scale_v1 * fractional_scale, uint32_t scale_times_120) { ctx_t * ctx = (ctx_t *)data; double scale = scale_times_120 / 120.0; log_debug(ctx, "wayland::on_fractional_scale_preferred_scale(): scale = %.4f\n", scale); // fractionally scaled surfaces have buffer scale of 1 update_window_scale(ctx, scale, true); (void)fractional_scale; } static const struct wp_fractional_scale_v1_listener fractional_scale_listener = { .preferred_scale = on_fractional_scale_preferred_scale }; // --- find_output --- bool find_wl_output(ctx_t * ctx, char * output_name, struct wl_output ** output) { bool found = false; output_list_node_t * cur = ctx->wl.outputs; while (cur != NULL) { if (cur->name != NULL && strcmp(cur->name, output_name) == 0) { output_name = cur->name; break; } cur = cur->next; } if (cur != NULL) { found = true; *output = cur->output; } return found; } // --- init_wl --- void init_wl(ctx_t * ctx) { // initialize context structure ctx->wl.display = NULL; ctx->wl.registry = NULL; ctx->wl.compositor = NULL; ctx->wl.compositor_id = 0; ctx->wl.viewporter = NULL; ctx->wl.viewporter_id = 0; ctx->wl.fractional_scale_manager = NULL; ctx->wl.fractional_scale_manager_id = 0; ctx->wl.wm_base = NULL; ctx->wl.wm_base_id = 0; ctx->wl.output_manager = NULL; ctx->wl.output_manager_id = 0; ctx->wl.dmabuf_manager = NULL; ctx->wl.dmabuf_manager_id = 0; ctx->wl.shm = NULL; ctx->wl.shm_id = 0; ctx->wl.screencopy_manager = NULL; ctx->wl.screencopy_manager_id = 0; ctx->wl.outputs = NULL; ctx->wl.seats = NULL; ctx->wl.surface = NULL; ctx->wl.viewport = NULL; ctx->wl.fractional_scale = NULL; ctx->wl.xdg_surface = NULL; ctx->wl.xdg_toplevel = NULL; ctx->wl.current_output = NULL; ctx->wl.width = 0; ctx->wl.height = 0; ctx->wl.scale = 1.0; ctx->wl.event_handler.next = NULL; ctx->wl.event_handler.fd = -1; ctx->wl.event_handler.events = EPOLLIN; ctx->wl.event_handler.timeout_ms = -1; ctx->wl.event_handler.on_event = on_loop_event; ctx->wl.event_handler.on_each = on_loop_each; ctx->wl.last_surface_serial = 0; ctx->wl.xdg_surface_configured = false; ctx->wl.xdg_toplevel_configured = false; ctx->wl.configured = false; ctx->wl.closing = false; ctx->wl.initialized = true; // connect to display ctx->wl.display = wl_display_connect(NULL); if (ctx->wl.display == NULL) { log_error("wayland::init(): failed to connect to wayland\n"); exit_fail(ctx); } // register event loop ctx->wl.event_handler.fd = wl_display_get_fd(ctx->wl.display); event_add_fd(ctx, &ctx->wl.event_handler); // get registry handle ctx->wl.registry = wl_display_get_registry(ctx->wl.display); if (ctx->wl.registry == NULL) { log_error("wayland::init(): failed to get registry handle\n"); exit_fail(ctx); } // add registry event listener // - for add global event // - for remove global event wl_registry_add_listener(ctx->wl.registry, ®istry_listener, (void *)ctx); // wait for registry events // - expecting add global events for all required protocols // - expecting add global events for all outputs wl_display_roundtrip(ctx->wl.display); // check for missing required protocols if (ctx->wl.compositor == NULL) { log_error("wayland::init(): compositor missing\n"); exit_fail(ctx); } else if (ctx->wl.viewporter == NULL) { log_error("wayland::init(): viewporter missing\n"); exit_fail(ctx); } else if (ctx->wl.wm_base == NULL) { log_error("wayland::init(): wm_base missing\n"); exit_fail(ctx); } else if (ctx->wl.output_manager == NULL) { log_error("wayland::init(): output_manager missing\n"); exit_fail(ctx); } // add wm_base event listener // - for ping event xdg_wm_base_add_listener(ctx->wl.wm_base, &wm_base_listener, (void *)ctx); // create surface ctx->wl.surface = wl_compositor_create_surface(ctx->wl.compositor); if (ctx->wl.surface == NULL) { log_error("wayland::init(): failed to create surface\n"); exit_fail(ctx); } // add surface event listener // - for enter event // - for leave event wl_surface_add_listener(ctx->wl.surface, &surface_listener, (void *)ctx); // create viewport ctx->wl.viewport = wp_viewporter_get_viewport(ctx->wl.viewporter, ctx->wl.surface); if (ctx->wl.viewport == NULL) { log_error("wayland::init(): failed to create viewport\n"); exit_fail(ctx); } // create fractional scale if supported if (ctx->wl.fractional_scale_manager != NULL) { ctx->wl.fractional_scale = wp_fractional_scale_manager_v1_get_fractional_scale(ctx->wl.fractional_scale_manager, ctx->wl.surface); wp_fractional_scale_v1_add_listener(ctx->wl.fractional_scale, &fractional_scale_listener, (void *)ctx); } // create xdg surface ctx->wl.xdg_surface = xdg_wm_base_get_xdg_surface(ctx->wl.wm_base, ctx->wl.surface); if (ctx->wl.xdg_surface == NULL) { log_error("wayland::init(): failed to create xdg_surface\n"); exit_fail(ctx); } // add xdg surface event listener // - for configure event xdg_surface_add_listener(ctx->wl.xdg_surface, &xdg_surface_listener, (void *)ctx); // create xdg toplevel ctx->wl.xdg_toplevel = xdg_surface_get_toplevel(ctx->wl.xdg_surface); if (ctx->wl.xdg_toplevel == NULL) { log_error("wayland::init(): failed to create xdg_toplevel\n"); exit_fail(ctx); } // add xdg toplevel event listener // - for toplevel configure event // - for close event xdg_toplevel_add_listener(ctx->wl.xdg_toplevel, &xdg_toplevel_listener, (void *)ctx); // set xdg toplevel properties xdg_toplevel_set_app_id(ctx->wl.xdg_toplevel, "at.yrlf.wl_mirror"); xdg_toplevel_set_title(ctx->wl.xdg_toplevel, "Wayland Output Mirror"); // commit surface to trigger configure sequence wl_surface_commit(ctx->wl.surface); // wait for events // - expecting surface configure event // - expecting xdg toplevel configure event wl_display_roundtrip(ctx->wl.display); // set fullscreen on xdg_toplevel if (ctx->opt.fullscreen && ctx->opt.fullscreen_output != NULL) { set_window_fullscreen(ctx); } // check if surface is configured // - expecting surface to be configured at this point if (!ctx->wl.configured) { log_error("wayland::init(): surface not configured\n"); exit_fail(ctx); } } // --- set_window_title --- void set_window_title(ctx_t * ctx, const char * title) { xdg_toplevel_set_title(ctx->wl.xdg_toplevel, title); } // --- set_window_fullscreen --- void set_window_fullscreen(ctx_t * ctx) { struct wl_output * output = NULL; if (ctx->opt.fullscreen_output == NULL) { output = ctx->wl.current_output->output; } else if (!find_wl_output(ctx, ctx->opt.fullscreen_output, &output)) { log_error("wayland::init(): output %s not found\n", ctx->opt.fullscreen_output); exit_fail(ctx); } xdg_toplevel_set_fullscreen(ctx->wl.xdg_toplevel, output); } void unset_window_fullscreen(ctx_t * ctx) { xdg_toplevel_unset_fullscreen(ctx->wl.xdg_toplevel); } // --- update_window_scale void update_window_scale(ctx_t * ctx, double scale, bool is_fractional) { bool resize = false; // don't update scale from other sources if fractional scaling supported if (ctx->wl.fractional_scale != NULL && !is_fractional) return; if (ctx->wl.scale != scale) { log_debug(ctx, "wayland::update_window_scale(): setting window scale to %.4f\n", scale); ctx->wl.scale = scale; resize = true; } // resize egl window to reflect new scale if (resize && ctx->egl.initialized) { resize_window(ctx); } } // --- cleanup_wl --- void cleanup_wl(ctx_t *ctx) { if (!ctx->wl.initialized) return; log_debug(ctx, "wayland::cleanup(): destroying wayland objects\n"); // deregister event handler event_remove_fd(ctx, &ctx->wl.event_handler); { // free every output in output list output_list_node_t * cur = ctx->wl.outputs; output_list_node_t * prev = NULL; while (cur != NULL) { prev = cur; cur = cur->next; // deallocate output node zxdg_output_v1_destroy(prev->xdg_output); wl_output_destroy(prev->output); free(prev->name); free(prev); } ctx->wl.outputs = NULL; } { // free every seat in seat list seat_list_node_t * cur = ctx->wl.seats; seat_list_node_t * prev = NULL; while (cur != NULL) { prev = cur; cur = cur->next; // deallocate seat node wl_seat_destroy(prev->seat); free(prev); } ctx->wl.seats = NULL; } if (ctx->wl.dmabuf_manager != NULL) zwlr_export_dmabuf_manager_v1_destroy(ctx->wl.dmabuf_manager); if (ctx->wl.screencopy_manager != NULL) zwlr_screencopy_manager_v1_destroy(ctx->wl.screencopy_manager); if (ctx->wl.shm != NULL) wl_shm_destroy(ctx->wl.shm); if (ctx->wl.xdg_toplevel != NULL) xdg_toplevel_destroy(ctx->wl.xdg_toplevel); if (ctx->wl.xdg_surface != NULL) xdg_surface_destroy(ctx->wl.xdg_surface); if (ctx->wl.fractional_scale != NULL) wp_fractional_scale_v1_destroy(ctx->wl.fractional_scale); if (ctx->wl.viewport != NULL) wp_viewport_destroy(ctx->wl.viewport); if (ctx->wl.surface != NULL) wl_surface_destroy(ctx->wl.surface); if (ctx->wl.output_manager != NULL) zxdg_output_manager_v1_destroy(ctx->wl.output_manager); if (ctx->wl.wm_base != NULL) xdg_wm_base_destroy(ctx->wl.wm_base); if (ctx->wl.fractional_scale_manager != NULL) wp_fractional_scale_manager_v1_destroy(ctx->wl.fractional_scale_manager); if (ctx->wl.viewporter != NULL) wp_viewporter_destroy(ctx->wl.viewporter); if (ctx->wl.compositor != NULL) wl_compositor_destroy(ctx->wl.compositor); if (ctx->wl.registry != NULL) wl_registry_destroy(ctx->wl.registry); if (ctx->wl.display != NULL) wl_display_disconnect(ctx->wl.display); ctx->wl.initialized = false; } wl-mirror-0.16.5/version/0000755000175000017500000000000014646471773013757 5ustar yrlfyrlfwl-mirror-0.16.5/version/CMakeLists.txt0000644000175000017500000000104314646471773016515 0ustar yrlfyrlfadd_library(version INTERFACE) target_include_directories(version INTERFACE "${CMAKE_CURRENT_BINARY_DIR}/include/") set(version-header "${CMAKE_CURRENT_BINARY_DIR}/include/version.h") set(version-template "${CMAKE_CURRENT_SOURCE_DIR}/version.h.in") add_custom_target(gen-version COMMAND "${CMAKE_COMMAND}" "-DREPO_DIR=${CMAKE_SOURCE_DIR}" -P "${CMAKE_CURRENT_SOURCE_DIR}/version.cmake" "${version-header}" "${version-template}" ) set_source_files_properties("${version-header}" PROPERTIES GENERATED 1) add_dependencies(version gen-version) wl-mirror-0.16.5/version/version.cmake0000644000175000017500000000124314646471773016446 0ustar yrlfyrlfif(NOT ${CMAKE_ARGC} EQUAL 6 OR NOT DEFINED REPO_DIR) message(FATAL_ERROR "usage: cmake -DREPO_DIR= -P version.cmake ") endif() set(version-header "${CMAKE_ARGV4}") set(version-template "${CMAKE_ARGV5}") set(repo-dir "${REPO_DIR}") if(IS_DIRECTORY "${repo-dir}/.git") execute_process( COMMAND git describe --long --tags WORKING_DIRECTORY "${repo-dir}" OUTPUT_VARIABLE VERSION ) elseif(EXISTS "${repo-dir}/version.txt") file(READ "${repo-dir}/version.txt" VERSION) else() set(VERSION "") endif() string(STRIP "${VERSION}" VERSION) configure_file("${version-template}" "${version-header}" @ONLY) wl-mirror-0.16.5/version/version.h.in0000644000175000017500000000013714646471773016223 0ustar yrlfyrlf#ifndef WL_MIRROR_VERSION_H_ #define WL_MIRROR_VERSION_H_ #define VERSION "@VERSION@" #endif wl-mirror-0.16.5/version.txt0000644000175000017500000000001014646472005014474 0ustar yrlfyrlfv0.16.5