refactor(protocol)!: move protocol bindings to go-wayland-bindings
Remove protocol/, cmd/wlturbo-scanner, internal/scanner, the protocol migration doc and LICENSES/ (the LGPL text only covered the kdeserverdecoration XML, which moved with the bindings). wlturbo is now a pure client runtime: the root package and the wl/ shim. TestExternalConsumer, which compiled protocol/core tests in a separate module, is removed; the equivalent tests live in go-wayland-bindings. Registry bootstrap and BindNegotiated transport coverage is rewritten against the root package in registry_test.go. BREAKING CHANGE: github.com/bnema/wlturbo/protocol/<pkg> no longer exists. Import github.com/bnema/go-wayland-bindings/client/<pkg> instead. Renamed packages: core->wayland, datacontrol->extdatacontrol, drmsyncobj->linuxdrmsyncobj, extforeigntoplevel->extforeigntoplevellist, foreigntoplevel->wlrforeigntoplevelmanagement, idlenotify->extidlenotify, imagecapturesource->extimagecapturesource, imagecopycapture->extimagecopycapture, kdeserverdecoration->serverdecoration, layershell->wlrlayershell, outputmanagement->wlroutputmanagement, outputpower->wlroutputpowermanagement, presentation->presentationtime, screencopy->wlrscreencopy, shortcutsinhibit->keyboardshortcutsinhibit, workspace->extworkspace. All other package names are unchanged. The cmd/wlturbo-scanner generator is replaced by go-wayland-bindings' wlbgen.
- commit
- d9b2fda61758aa26bf90b608b0f79f9de6f26f06
- author
- brice · · 2026-10-01 05:48 UTC
- parent
- 089fa12
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
148 files · +135 -46447
D LICENSES/LGPL-2.1-or-later.txt +0 -176
| @@ -1,176 +0,0 @@ | |||
| 1 | - | GNU LESSER GENERAL PUBLIC LICENSE | |
| 2 | - | ||
| 3 | - | Version 2.1, February 1999 | |
| 4 | - | ||
| 5 | - | Copyright (C) 1991, 1999 Free Software Foundation, Inc. | |
| 6 | - | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
| 7 | - | ||
| 8 | - | Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. | |
| 9 | - | ||
| 10 | - | [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] | |
| 11 | - | ||
| 12 | - | Preamble | |
| 13 | - | ||
| 14 | - | The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. | |
| 15 | - | ||
| 16 | - | This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. | |
| 17 | - | ||
| 18 | - | When we speak of free software, we are referring to freedom of use, 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 this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. | |
| 19 | - | ||
| 20 | - | To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. | |
| 21 | - | ||
| 22 | - | For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. | |
| 23 | - | ||
| 24 | - | We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. | |
| 25 | - | ||
| 26 | - | To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. | |
| 27 | - | ||
| 28 | - | Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. | |
| 29 | - | ||
| 30 | - | Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. | |
| 31 | - | ||
| 32 | - | When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. | |
| 33 | - | ||
| 34 | - | We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. | |
| 35 | - | ||
| 36 | - | For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. | |
| 37 | - | ||
| 38 | - | In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. | |
| 39 | - | ||
| 40 | - | Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. | |
| 41 | - | ||
| 42 | - | The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. | |
| 43 | - | ||
| 44 | - | GNU LESSER GENERAL PUBLIC LICENSE | |
| 45 | - | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION | |
| 46 | - | ||
| 47 | - | 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". | |
| 48 | - | ||
| 49 | - | A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. | |
| 50 | - | ||
| 51 | - | The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) | |
| 52 | - | ||
| 53 | - | "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. | |
| 54 | - | ||
| 55 | - | Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. | |
| 56 | - | ||
| 57 | - | 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. | |
| 58 | - | ||
| 59 | - | You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. | |
| 60 | - | ||
| 61 | - | 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: | |
| 62 | - | ||
| 63 | - | a) The modified work must itself be a software library. | |
| 64 | - | ||
| 65 | - | b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. | |
| 66 | - | ||
| 67 | - | c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. | |
| 68 | - | ||
| 69 | - | d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. | |
| 70 | - | ||
| 71 | - | (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) | |
| 72 | - | ||
| 73 | - | These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. | |
| 74 | - | ||
| 75 | - | Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. | |
| 76 | - | ||
| 77 | - | In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. | |
| 78 | - | ||
| 79 | - | 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. | |
| 80 | - | ||
| 81 | - | Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. | |
| 82 | - | ||
| 83 | - | This option is useful when you wish to copy part of the code of the Library into a program that is not a library. | |
| 84 | - | ||
| 85 | - | 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. | |
| 86 | - | ||
| 87 | - | If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. | |
| 88 | - | ||
| 89 | - | 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. | |
| 90 | - | ||
| 91 | - | However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. | |
| 92 | - | ||
| 93 | - | When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. | |
| 94 | - | ||
| 95 | - | If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) | |
| 96 | - | ||
| 97 | - | Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. | |
| 98 | - | ||
| 99 | - | 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. | |
| 100 | - | ||
| 101 | - | You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: | |
| 102 | - | ||
| 103 | - | a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) | |
| 104 | - | ||
| 105 | - | b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. | |
| 106 | - | ||
| 107 | - | c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. | |
| 108 | - | ||
| 109 | - | d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. | |
| 110 | - | ||
| 111 | - | e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. | |
| 112 | - | ||
| 113 | - | For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. | |
| 114 | - | ||
| 115 | - | It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. | |
| 116 | - | ||
| 117 | - | 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: | |
| 118 | - | ||
| 119 | - | a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. | |
| 120 | - | ||
| 121 | - | b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. | |
| 122 | - | ||
| 123 | - | 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. | |
| 124 | - | ||
| 125 | - | 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. | |
| 126 | - | ||
| 127 | - | 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. | |
| 128 | - | ||
| 129 | - | 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), 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 distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. | |
| 130 | - | ||
| 131 | - | If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. | |
| 132 | - | ||
| 133 | - | It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. | |
| 134 | - | ||
| 135 | - | This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. | |
| 136 | - | ||
| 137 | - | 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. | |
| 138 | - | ||
| 139 | - | 13. The Free Software Foundation may publish revised and/or new versions of the Lesser 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. | |
| 140 | - | ||
| 141 | - | Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. | |
| 142 | - | ||
| 143 | - | 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. | |
| 144 | - | ||
| 145 | - | NO WARRANTY | |
| 146 | - | ||
| 147 | - | 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "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 LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. | |
| 148 | - | ||
| 149 | - | 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY 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 LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. | |
| 150 | - | ||
| 151 | - | END OF TERMS AND CONDITIONS | |
| 152 | - | ||
| 153 | - | How to Apply These Terms to Your New Libraries | |
| 154 | - | ||
| 155 | - | If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). | |
| 156 | - | ||
| 157 | - | To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. | |
| 158 | - | ||
| 159 | - | one line to give the library's name and an idea of what it does. | |
| 160 | - | Copyright (C) year name of author | |
| 161 | - | ||
| 162 | - | This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. | |
| 163 | - | ||
| 164 | - | This library 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 Lesser General Public License for more details. | |
| 165 | - | ||
| 166 | - | You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. | |
| 167 | - | ||
| 168 | - | You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: | |
| 169 | - | ||
| 170 | - | Yoyodyne, Inc., hereby disclaims all copyright interest in | |
| 171 | - | the library `Frob' (a library for tweaking knobs) written | |
| 172 | - | by James Random Hacker. | |
| 173 | - | ||
| 174 | - | signature of Ty Coon, 1 April 1990 | |
| 175 | - | Ty Coon, President of Vice | |
| 176 | - | That's all there is to it! | |
M README.md +16 -36
| @@ -1,38 +1,31 @@ | |||
| 1 | 1 | # WLTurbo - Wayland Client Library for Go | |
| 2 | 2 | ||
| 3 | - | A performance-focused Wayland client library that provides the foundational protocol implementation for building Wayland applications and libraries. | |
| 3 | + | A performance-focused Wayland client runtime for Go, the foundation for protocol bindings and Wayland applications. | |
| 4 | 4 | ||
| 5 | 5 | ## Overview | |
| 6 | 6 | ||
| 7 | - | WLTurbo is a low-level Wayland client library with generated core and extension bindings. Applications and higher-level libraries use it to communicate with any compositor that advertises the required protocols. | |
| 7 | + | WLTurbo is a low-level Wayland client runtime: connection, wire framing, descriptor passing, object lifecycle and the bootstrap registry. Protocol bindings are provided separately (see [Protocol bindings](#protocol-bindings)). | |
| 8 | 8 | ||
| 9 | 9 | ## Architecture | |
| 10 | 10 | ||
| 11 | 11 | WLTurbo provides the foundational Wayland client infrastructure: | |
| 12 | 12 | ||
| 13 | - | - **Core Protocol Objects**: Display, Registry, Compositor, Surface, Seat, Region | |
| 13 | + | - **Bootstrap Objects**: Display and Registry | |
| 14 | 14 | - **Event Dispatching**: Efficient routing of Wayland events to handlers | |
| 15 | 15 | - **Connection Management**: Unix socket communication with the compositor | |
| 16 | 16 | - **Memory Management**: Shared memory support via file descriptor passing | |
| 17 | 17 | ||
| 18 | - | Bindings handle wire messages and object lifecycle. Applications own rendering, input interpretation, capability fallbacks and desktop policy. WLTurbo provides client bindings, not compositor-side server implementations. | |
| 18 | + | Applications own rendering, input interpretation, capability fallbacks and desktop policy. WLTurbo is client-side only, not a compositor-side server implementation. | |
| 19 | 19 | ||
| 20 | - | ## Generated protocols | |
| 20 | + | ## Protocol bindings | |
| 21 | 21 | ||
| 22 | - | Packages under `protocol/` cover: | |
| 22 | + | Generated protocol bindings are not part of this module. They live in [github.com/bnema/go-wayland-bindings](https://github.com/bnema/go-wayland-bindings), one package per protocol under `client/<pkg>`, for example `client/wayland`, `client/xdgshell` and `client/wlrlayershell`: | |
| 23 | 23 | ||
| 24 | - | | Area | Packages | | |
| 25 | - | |---|---| | |
| 26 | - | | Core and windows | `core`, `xdgshell`, `xdgdecoration`, `xdgactivation` | | |
| 27 | - | | Buffers and scaling | `linuxdmabuf`, `drmsyncobj`, `viewporter`, `fractionalscale` | | |
| 28 | - | | Presentation and color | `presentation`, `tearingcontrol`, `fifo`, `committiming`, `contenttype`, `alphamodifier`, `colormanagement`, `colorrepresentation`, `drmlease` | | |
| 29 | - | | Input | `cursorshape`, `tablet`, `textinput`, `relativepointer`, `pointerconstraints`, `pointerwarp`, `shortcutsinhibit`, `virtualkeyboard`, `inputmethod` | | |
| 30 | - | | Clipboard | Core data-device, `primaryselection`, `datacontrol` (ext-data-control) | | |
| 31 | - | | Desktop and outputs | `layershell`, `xdgoutput`, `outputmanagement`, `outputpower`, `workspace`, `foreigntoplevel` (wlr), `extforeigntoplevel`, `extsessionlock`, `kdeserverdecoration` | | |
| 32 | - | | Idle | `idleinhibit`, `idlenotify` | | |
| 33 | - | | Capture | `screencopy` (wlr), `imagecapturesource`, `imagecopycapture` | | |
| 24 | + | ```go | |
| 25 | + | import "github.com/bnema/go-wayland-bindings/client/xdgshell" | |
| 26 | + | ``` | |
| 34 | 27 | ||
| 35 | - | Each package contains the upstream XML, generated Go bindings and a generation command. [Protocol sources](protocol/SOURCE.md) records pinned upstream revisions and checksums. A binding's presence does not imply that the compositor implements it. | |
| 28 | + | Those packages are built on this runtime. A binding's presence does not imply that the compositor implements it. | |
| 36 | 29 | ||
| 37 | 30 | After `display.Roundtrip()` discovers globals, call `display.Registry().BindNegotiated(interfaceName, supportedVersion, proxy)` to bind at the lesser of the advertised and supported versions. It returns the negotiated version; use `errors.Is(err, wlturbo.ErrGlobalNotFound)` to handle absent optional globals. | |
| 38 | 31 | ||
| @@ -41,8 +34,8 @@ After `display.Roundtrip()` discovers globals, call `display.Registry().BindNego | |||
| 41 | 34 | - **Stream framing**: messages split across or coalesced within socket reads are framed exactly; event bodies are not copied. | |
| 42 | 35 | - **Descriptor ownership**: received FDs belong to the event that declares them and are closed if a handler does not take them. | |
| 43 | 36 | - **Object lifecycle**: destroyed objects stay as zombies until `delete_id`, so events already in flight are dropped instead of failing the connection. | |
| 44 | - | - **Version checks**: generated requests newer than the bound object version return `ErrVersionTooLow` before anything is sent. | |
| 45 | - | - **Allocation-free numeric paths**: numeric generated requests without object creation or descriptors, and typed numeric events, do not allocate after warm-up; representative cases have allocation regression tests. Object creation, received strings and descriptors have separate allocation costs. | |
| 37 | + | - **Version checks**: requests newer than the bound object version return `ErrVersionTooLow` before anything is sent. | |
| 38 | + | - **Allocation-free numeric paths**: numeric requests sent with `Context.RequestArgs` without object creation or descriptors, and typed numeric events, do not allocate after warm-up. Object creation, received strings and descriptors have separate allocation costs. | |
| 46 | 39 | ||
| 47 | 40 | ## Quick Start | |
| 48 | 41 | ||
| @@ -76,22 +69,13 @@ For higher-level device control, [libwldevices-go](https://github.com/bnema/libw | |||
| 76 | 69 | ## Development checks | |
| 77 | 70 | ||
| 78 | 71 | ```sh | |
| 79 | - | GOWORK=off go generate ./... | |
| 80 | 72 | GOWORK=off go test ./... | |
| 81 | 73 | GOWORK=off go test -race ./... | |
| 82 | 74 | GOWORK=off go vet ./... | |
| 83 | - | GOWORK=off go test ./protocol -run '^$' -bench . -benchmem | |
| 84 | - | ``` | |
| 85 | - | ||
| 86 | - | Tests verify that checked-in bindings reproduce from the vendored XML. Socketpair tests exercise wire messages, versions, object lifecycle and file descriptors without a compositor. | |
| 87 | - | ||
| 88 | - | For isolated integration tests, build [NeferWL](https://github.com/bnema/neferwl) with its headless backend and pass its executable path: | |
| 89 | - | ||
| 90 | - | ```sh | |
| 91 | - | env GOWORK=off WLTURBO_HEADLESS=/path/to/neferwl go test ./protocol -run Headless -v -count=1 -timeout=90s | |
| 75 | + | GOWORK=off go test -run '^$' -bench . -benchmem | |
| 92 | 76 | ``` | |
| 93 | 77 | ||
| 94 | - | The tests start a separate compositor with temporary runtime/config directories and no terminal or Xwayland. They do not use the running desktop session. Headless tests do not validate physical display timing, DRM leasing or hardware HDR output. | |
| 78 | + | Socketpair tests exercise wire messages, versions, object lifecycle and file descriptors without a compositor. | |
| 95 | 79 | ||
| 96 | 80 | ## Requirements | |
| 97 | 81 | ||
| @@ -101,16 +85,12 @@ The tests start a separate compositor with temporary runtime/config directories | |||
| 101 | 85 | ||
| 102 | 86 | ## License | |
| 103 | 87 | ||
| 104 | - | The transport and scanner are MIT-licensed; see [LICENSE](LICENSE). | |
| 105 | - | Vendored protocol XML and generated bindings retain upstream notices and terms. | |
| 106 | - | In particular, `kdeserverdecoration` is LGPL-2.1-or-later. See | |
| 107 | - | [protocol sources](protocol/SOURCE.md), the generated file headers and the | |
| 108 | - | [included LGPL text](LICENSES/LGPL-2.1-or-later.txt). | |
| 88 | + | MIT; see [LICENSE](LICENSE). | |
| 109 | 89 | ||
| 110 | 90 | ## Contributing | |
| 111 | 91 | ||
| 112 | 92 | Contributions welcome! Areas of focus: | |
| 113 | 93 | - Performance improvements | |
| 114 | - | - Additional protocol object support | |
| 94 | + | - Transport correctness and hardening | |
| 115 | 95 | - Documentation and examples | |
| 116 | 96 | - Benchmark suite⏎̸ | |
M client.go +2 -2
| @@ -1,6 +1,6 @@ | |||
| 1 | 1 | // Package wlturbo is a Wayland client transport for Go: connection, framing, | |
| 2 | - | // descriptor passing, object lifecycle and the bootstrap registry. Protocol | |
| 3 | - | // bindings are generated into the protocol/ packages. | |
| 2 | + | // descriptor passing, object lifecycle and the bootstrap registry. Generated | |
| 3 | + | // protocol bindings live in github.com/bnema/go-wayland-bindings (client/). | |
| 4 | 4 | package wlturbo | |
| 5 | 5 | ||
| 6 | 6 | import ( | |
D cmd/wlturbo-scanner/main.go +0 -132
| @@ -1,132 +0,0 @@ | |||
| 1 | - | // Command wlturbo-scanner generates Go bindings from Wayland protocol XML files. | |
| 2 | - | // | |
| 3 | - | // Usage: | |
| 4 | - | // | |
| 5 | - | // wlturbo-scanner [flags] protocol.xml | |
| 6 | - | // | |
| 7 | - | // Flags: | |
| 8 | - | // | |
| 9 | - | // -o, --output Output file path (default: <protocol>_generated.go) | |
| 10 | - | // -p, --package Go package name (default: derived from protocol name) | |
| 11 | - | // -h, --help Show help | |
| 12 | - | // | |
| 13 | - | // Examples: | |
| 14 | - | // | |
| 15 | - | // # Generate bindings for virtual pointer protocol | |
| 16 | - | // wlturbo-scanner -o virtual_pointer.go ../wlr-protocols/unstable/wlr-virtual-pointer-unstable-v1.xml | |
| 17 | - | // | |
| 18 | - | // # Generate with custom package name | |
| 19 | - | // wlturbo-scanner -p vpointer -o vpointer.go protocol.xml | |
| 20 | - | package main | |
| 21 | - | ||
| 22 | - | import ( | |
| 23 | - | "flag" | |
| 24 | - | "fmt" | |
| 25 | - | "log" | |
| 26 | - | "os" | |
| 27 | - | "path/filepath" | |
| 28 | - | "strings" | |
| 29 | - | ||
| 30 | - | "github.com/bnema/wlturbo/internal/scanner" | |
| 31 | - | ) | |
| 32 | - | ||
| 33 | - | func main() { | |
| 34 | - | var ( | |
| 35 | - | outputPath string | |
| 36 | - | packageName string | |
| 37 | - | showHelp bool | |
| 38 | - | crossImports crossFlags | |
| 39 | - | ) | |
| 40 | - | ||
| 41 | - | flag.StringVar(&outputPath, "o", "", "Output file path") | |
| 42 | - | flag.StringVar(&outputPath, "output", "", "Output file path") | |
| 43 | - | flag.StringVar(&packageName, "p", "", "Go package name") | |
| 44 | - | flag.StringVar(&packageName, "package", "", "Go package name") | |
| 45 | - | flag.Var(&crossImports, "import", "Interface=Go import path (repeatable)") | |
| 46 | - | flag.BoolVar(&showHelp, "h", false, "Show help") | |
| 47 | - | flag.BoolVar(&showHelp, "help", false, "Show help") | |
| 48 | - | ||
| 49 | - | flag.Usage = func() { | |
| 50 | - | fmt.Fprintf(os.Stderr, "Usage: %s [flags] protocol.xml\n\n", os.Args[0]) | |
| 51 | - | fmt.Fprintf(os.Stderr, "Generates Go bindings from Wayland protocol XML files.\n\n") | |
| 52 | - | fmt.Fprintf(os.Stderr, "Flags:\n") | |
| 53 | - | flag.PrintDefaults() | |
| 54 | - | fmt.Fprintf(os.Stderr, "\nExamples:\n") | |
| 55 | - | fmt.Fprintf(os.Stderr, " # Generate bindings for virtual pointer protocol\n") | |
| 56 | - | fmt.Fprintf(os.Stderr, " %s -o virtual_pointer.go wlr-virtual-pointer-unstable-v1.xml\n\n", os.Args[0]) | |
| 57 | - | fmt.Fprintf(os.Stderr, " # Generate with custom package name\n") | |
| 58 | - | fmt.Fprintf(os.Stderr, " %s -p vpointer -o vpointer.go protocol.xml\n", os.Args[0]) | |
| 59 | - | } | |
| 60 | - | ||
| 61 | - | flag.Parse() | |
| 62 | - | ||
| 63 | - | if showHelp || flag.NArg() == 0 { | |
| 64 | - | flag.Usage() | |
| 65 | - | if showHelp { | |
| 66 | - | os.Exit(0) | |
| 67 | - | } | |
| 68 | - | os.Exit(1) | |
| 69 | - | } | |
| 70 | - | ||
| 71 | - | xmlPath := flag.Arg(0) | |
| 72 | - | ||
| 73 | - | // Derive output path if not specified | |
| 74 | - | if outputPath == "" { | |
| 75 | - | base := filepath.Base(xmlPath) | |
| 76 | - | base = strings.TrimSuffix(base, filepath.Ext(base)) | |
| 77 | - | outputPath = base + "_generated.go" | |
| 78 | - | } | |
| 79 | - | ||
| 80 | - | // Derive package name if not specified | |
| 81 | - | if packageName == "" { | |
| 82 | - | base := filepath.Base(xmlPath) | |
| 83 | - | base = strings.TrimSuffix(base, filepath.Ext(base)) | |
| 84 | - | ||
| 85 | - | // Clean up common prefixes/suffixes | |
| 86 | - | base = strings.TrimPrefix(base, "wlr-") | |
| 87 | - | base = strings.TrimPrefix(base, "zwlr-") | |
| 88 | - | base = strings.TrimSuffix(base, "-unstable-v1") | |
| 89 | - | base = strings.TrimSuffix(base, "-unstable-v2") | |
| 90 | - | base = strings.TrimSuffix(base, "-stable-v1") | |
| 91 | - | ||
| 92 | - | // Convert to valid Go package name | |
| 93 | - | packageName = strings.ReplaceAll(base, "-", "_") | |
| 94 | - | } | |
| 95 | - | ||
| 96 | - | // Create scanner | |
| 97 | - | s := scanner.NewScanner() | |
| 98 | - | s.CrossPackage = crossImports | |
| 99 | - | ||
| 100 | - | // Parse XML | |
| 101 | - | if err := s.ParseXML(xmlPath); err != nil { | |
| 102 | - | log.Fatalf("Failed to parse XML: %v", err) | |
| 103 | - | } | |
| 104 | - | ||
| 105 | - | // Generate code | |
| 106 | - | code, err := s.Generate(packageName) | |
| 107 | - | if err != nil { | |
| 108 | - | log.Fatalf("Failed to generate code: %v", err) | |
| 109 | - | } | |
| 110 | - | ||
| 111 | - | // Write output with secure permissions | |
| 112 | - | if err := os.WriteFile(outputPath, code, 0600); err != nil { | |
| 113 | - | log.Fatalf("Failed to write output: %v", err) | |
| 114 | - | } | |
| 115 | - | ||
| 116 | - | fmt.Printf("Generated %s (package %s)\n", outputPath, packageName) | |
| 117 | - | } | |
| 118 | - | ||
| 119 | - | type crossFlags map[string]string | |
| 120 | - | ||
| 121 | - | func (f *crossFlags) String() string { return fmt.Sprint(map[string]string(*f)) } | |
| 122 | - | func (f *crossFlags) Set(v string) error { | |
| 123 | - | parts := strings.SplitN(v, "=", 2) | |
| 124 | - | if len(parts) != 2 || parts[0] == "" || parts[1] == "" { | |
| 125 | - | return fmt.Errorf("-import must be interface=GoImportPath") | |
| 126 | - | } | |
| 127 | - | if *f == nil { | |
| 128 | - | *f = make(map[string]string) | |
| 129 | - | } | |
| 130 | - | (*f)[parts[0]] = parts[1] | |
| 131 | - | return nil | |
| 132 | - | } | |
D consumer_test.go +0 -63
| @@ -1,63 +0,0 @@ | |||
| 1 | - | //go:build linux | |
| 2 | - | ||
| 3 | - | package wlturbo | |
| 4 | - | ||
| 5 | - | import ( | |
| 6 | - | "os" | |
| 7 | - | "os/exec" | |
| 8 | - | "path/filepath" | |
| 9 | - | "testing" | |
| 10 | - | ) | |
| 11 | - | ||
| 12 | - | // Run the public socketpair integration against a separate module, with no | |
| 13 | - | // imports from internal/ and no worktree replacement outside its temp go.mod. | |
| 14 | - | func TestExternalConsumer(t *testing.T) { | |
| 15 | - | goBin, err := exec.LookPath("go") | |
| 16 | - | if err != nil { | |
| 17 | - | t.Skip("go executable unavailable: external module integration requires go") | |
| 18 | - | } | |
| 19 | - | root, err := os.Getwd() | |
| 20 | - | if err != nil { | |
| 21 | - | t.Fatal(err) | |
| 22 | - | } | |
| 23 | - | temp := t.TempDir() | |
| 24 | - | mod := "module example.com/wlturbo-consumer\n\ngo 1.27\n\nrequire github.com/bnema/wlturbo v0.0.0\nreplace github.com/bnema/wlturbo => " + root + "\n" | |
| 25 | - | if err := os.WriteFile(filepath.Join(temp, "go.mod"), []byte(mod), 0600); err != nil { | |
| 26 | - | t.Fatal(err) | |
| 27 | - | } | |
| 28 | - | source, err := os.ReadFile(filepath.Join(root, "protocol/core/core_test.go")) | |
| 29 | - | if err != nil { | |
| 30 | - | t.Fatal(err) | |
| 31 | - | } | |
| 32 | - | // The external module has no access to the package's test helpers except | |
| 33 | - | // the ones copied into this temporary module. Compile and exercise only | |
| 34 | - | // the public integration scenarios, including typed key, frame and release. | |
| 35 | - | if err := os.WriteFile(filepath.Join(temp, "consumer_test.go"), source, 0600); err != nil { | |
| 36 | - | t.Fatal(err) | |
| 37 | - | } | |
| 38 | - | // Keep the extension fake server in a separate package: both fixtures | |
| 39 | - | // independently own their socketpair helpers. | |
| 40 | - | extension, err := os.ReadFile(filepath.Join(root, "protocol/extensions_test.go")) | |
| 41 | - | if err != nil { | |
| 42 | - | t.Fatal(err) | |
| 43 | - | } | |
| 44 | - | if err := os.Mkdir(filepath.Join(temp, "extensions"), 0700); err != nil { | |
| 45 | - | t.Fatal(err) | |
| 46 | - | } | |
| 47 | - | if err := os.WriteFile(filepath.Join(temp, "extensions", "extensions_test.go"), extension, 0600); err != nil { | |
| 48 | - | t.Fatal(err) | |
| 49 | - | } | |
| 50 | - | negotiation, err := os.ReadFile(filepath.Join(root, "protocol/negotiation_test.go")) | |
| 51 | - | if err != nil { | |
| 52 | - | t.Fatal(err) | |
| 53 | - | } | |
| 54 | - | if err := os.WriteFile(filepath.Join(temp, "extensions", "negotiation_test.go"), negotiation, 0600); err != nil { | |
| 55 | - | t.Fatal(err) | |
| 56 | - | } | |
| 57 | - | cmd := exec.Command(goBin, "test", "-run", "TestGeneratedCoreOverSocketpair|TestBufferReleaseAndOfferChild|TestExtensionsOverSocketpair|TestAnnouncedVersionNegotiation", "./...") | |
| 58 | - | cmd.Dir = temp | |
| 59 | - | cmd.Env = append(os.Environ(), "GOWORK=off", "GOFLAGS=-mod=mod") | |
| 60 | - | if output, err := cmd.CombinedOutput(); err != nil { | |
| 61 | - | t.Fatalf("external consumer: %v\n%s", err, output) | |
| 62 | - | } | |
| 63 | - | } | |
D docs/protocol-migration.md +0 -40
| @@ -1,40 +0,0 @@ | |||
| 1 | - | # Canonical core / migration (v0.x) | |
| 2 | - | ||
| 3 | - | `protocol/core` replaces root-package and `wl` shim core object types. Bootstrap | |
| 4 | - | `Display`, `Registry`, `Context`, and `BaseProxy` remain in the root/`wl` | |
| 5 | - | transport. Bind globals using `core.NewCompositor(display.Context())`, | |
| 6 | - | `core.NewSeat(display.Context())`, etc. and `display.Registry().Bind(name, | |
| 7 | - | core.CompositorInterface, version, compositor)`. Requests create typed registered | |
| 8 | - | children (`seat.GetKeyboard()`, `surface.Frame()`, `shm.CreatePool()`) and | |
| 9 | - | server-side `new_id` events register concrete objects before invoking handlers. | |
| 10 | - | Do not overwrite registered objects with a second wrapper. | |
| 11 | - | ||
| 12 | - | Breaking changes: `wlturbo`/`wl` `Seat`, `Surface`, `Pointer`, `Keyboard`, | |
| 13 | - | `Touch`, `Output`, `Region`, `Compositor`, their constructors, and seat | |
| 14 | - | capability aliases have moved to `protocol/core`. Generated methods accept | |
| 15 | - | concrete core objects and return concrete children, not `wl.Object`. Legacy | |
| 16 | - | raw `Event.Fd()` is not for generated events; generated FD handlers receive | |
| 17 | - | `*wlturbo.OwnedFD` with `Take() (int,error)` or `Close()`; second and later | |
| 18 | - | handlers receive nil FD. On a successful full send a generated FD request | |
| 19 | - | closes the local descriptor; on error the caller keeps it. `Registry.BindID` | |
| 20 | - | remains for legacy callers but cannot register typed event dispatch: prefer | |
| 21 | - | `Bind` and generated constructors. Unrecognized custom-proxy event opcodes | |
| 22 | - | now fail unless declared via `Display.RegisterEventSignature`. | |
| 23 | - | ||
| 24 | - | The scanner accepts `-import wl_surface=github.com/bnema/wlturbo/protocol/core` | |
| 25 | - | (repeat for each external type); local XML definitions take precedence, then | |
| 26 | - | explicit external mapping, then only bootstrap display/registry. Generate with | |
| 27 | - | `GOWORK=off go generate ./...`; metadata and XML license are in | |
| 28 | - | `protocol/SOURCE.md`. Extension packages under `protocol/` use the same scanner | |
| 29 | - | and public core mappings; the generator carries no compositor policy. | |
| 30 | - | ||
| 31 | - | Generated requests use `Context.RequestArgs` with typed `Arg` values to avoid | |
| 32 | - | boxing numeric arguments. Custom proxies may use the same API; `Context.Request` | |
| 33 | - | and the raw send methods remain available. Both request APIs share version, | |
| 34 | - | child-object, destructor and descriptor lifecycle handling. Strings and arrays | |
| 35 | - | passed as arguments are borrowed until the synchronous request returns. | |
| 36 | - | ||
| 37 | - | For client code in compositor tests, replace handwritten protocol proxies with | |
| 38 | - | these generated constructors and typed handlers. Keep compositor-side server | |
| 39 | - | implementations in the compositor repository. Negotiate optional globals and | |
| 40 | - | handle their absence rather than testing the compositor's name. | |
D internal/scanner/license_test.go +0 -53
| @@ -1,53 +0,0 @@ | |||
| 1 | - | package scanner | |
| 2 | - | ||
| 3 | - | import ( | |
| 4 | - | "crypto/sha256" | |
| 5 | - | "fmt" | |
| 6 | - | "os" | |
| 7 | - | "strings" | |
| 8 | - | "testing" | |
| 9 | - | ) | |
| 10 | - | ||
| 11 | - | func TestIncludedLGPLLicense(t *testing.T) { | |
| 12 | - | content, err := os.ReadFile("../../LICENSES/LGPL-2.1-or-later.txt") | |
| 13 | - | if err != nil { | |
| 14 | - | t.Fatal(err) | |
| 15 | - | } | |
| 16 | - | const expected = "5749785c8bdefafcb5d798270ed0a967036fe2ca63dcedade1627565dfef81d2" | |
| 17 | - | if got := fmt.Sprintf("%x", sha256.Sum256(content)); got != expected { | |
| 18 | - | t.Fatalf("LGPL text checksum %s, want %s", got, expected) | |
| 19 | - | } | |
| 20 | - | } | |
| 21 | - | ||
| 22 | - | func TestGeneratedSourceRetainsProtocolLicense(t *testing.T) { | |
| 23 | - | for _, source := range []string{ | |
| 24 | - | "../../protocol/kdeserverdecoration/server-decoration.xml", | |
| 25 | - | "../../protocol/layershell/wlr-layer-shell-unstable-v1.xml", | |
| 26 | - | "../../protocol/wayland.xml", | |
| 27 | - | } { | |
| 28 | - | t.Run(source, func(t *testing.T) { | |
| 29 | - | s := NewScanner() | |
| 30 | - | if err := s.ParseXML(source); err != nil { | |
| 31 | - | t.Fatal(err) | |
| 32 | - | } | |
| 33 | - | s.CrossPackage = map[string]string{ | |
| 34 | - | "wl_surface": "github.com/bnema/wlturbo/protocol/core", | |
| 35 | - | "wl_output": "github.com/bnema/wlturbo/protocol/core", | |
| 36 | - | "xdg_popup": "github.com/bnema/wlturbo/protocol/xdgshell", | |
| 37 | - | } | |
| 38 | - | generated, err := s.Generate("core") | |
| 39 | - | if err != nil { | |
| 40 | - | t.Fatal(err) | |
| 41 | - | } | |
| 42 | - | header, _, ok := strings.Cut(string(generated), "\npackage core") | |
| 43 | - | if !ok { | |
| 44 | - | t.Fatal("package declaration missing") | |
| 45 | - | } | |
| 46 | - | for _, line := range strings.Split(strings.TrimSpace(s.protocol.Copyright), "\n") { | |
| 47 | - | if text := strings.TrimSpace(line); text != "" && !strings.Contains(header, text) { | |
| 48 | - | t.Errorf("upstream license line missing from header: %q", text) | |
| 49 | - | } | |
| 50 | - | } | |
| 51 | - | }) | |
| 52 | - | } | |
| 53 | - | } | |
D internal/scanner/protocols_test.go +0 -113
| @@ -1,113 +0,0 @@ | |||
| 1 | - | package scanner | |
| 2 | - | ||
| 3 | - | import ( | |
| 4 | - | "bytes" | |
| 5 | - | "os" | |
| 6 | - | "path/filepath" | |
| 7 | - | "strings" | |
| 8 | - | "testing" | |
| 9 | - | ) | |
| 10 | - | ||
| 11 | - | // Check every checked-in binding against its generation command, including | |
| 12 | - | // external type mappings. Regeneration must not depend on the host's XML files. | |
| 13 | - | func TestVendoredProtocolsReproduce(t *testing.T) { | |
| 14 | - | root := filepath.Join("..", "..", "protocol") | |
| 15 | - | referenced := make(map[string]bool) | |
| 16 | - | err := filepath.WalkDir(root, func(path string, entry os.DirEntry, err error) error { | |
| 17 | - | if err != nil { | |
| 18 | - | return err | |
| 19 | - | } | |
| 20 | - | if entry.IsDir() || entry.Name() != "generate.go" { | |
| 21 | - | return nil | |
| 22 | - | } | |
| 23 | - | content, err := os.ReadFile(path) | |
| 24 | - | if err != nil { | |
| 25 | - | return err | |
| 26 | - | } | |
| 27 | - | for _, line := range strings.Split(string(content), "\n") { | |
| 28 | - | if !strings.HasPrefix(line, "//go:generate go run ") { | |
| 29 | - | continue | |
| 30 | - | } | |
| 31 | - | fields := strings.Fields(line) | |
| 32 | - | if len(fields) < 5 || !strings.HasSuffix(fields[3], "/cmd/wlturbo-scanner") { | |
| 33 | - | t.Fatalf("%s: expected direct go run of cmd/wlturbo-scanner", path) | |
| 34 | - | } | |
| 35 | - | args := fields[4:] | |
| 36 | - | var pkg, output, input string | |
| 37 | - | imports := make(map[string]string) | |
| 38 | - | for i := 0; i < len(args); i++ { | |
| 39 | - | switch args[i] { | |
| 40 | - | case "-p", "-o", "-import": | |
| 41 | - | if i+1 == len(args) { | |
| 42 | - | t.Fatalf("%s: missing value for %s", path, args[i]) | |
| 43 | - | } | |
| 44 | - | flag, value := args[i], args[i+1] | |
| 45 | - | i++ | |
| 46 | - | switch flag { | |
| 47 | - | case "-p": | |
| 48 | - | pkg = value | |
| 49 | - | case "-o": | |
| 50 | - | output = value | |
| 51 | - | case "-import": | |
| 52 | - | iface, target, ok := strings.Cut(value, "=") | |
| 53 | - | if !ok { | |
| 54 | - | t.Fatalf("%s: invalid import %q", path, value) | |
| 55 | - | } | |
| 56 | - | imports[iface] = target | |
| 57 | - | } | |
| 58 | - | default: | |
| 59 | - | if strings.HasPrefix(args[i], "-") || input != "" { | |
| 60 | - | t.Fatalf("%s: unexpected generation argument %q", path, args[i]) | |
| 61 | - | } | |
| 62 | - | input = args[i] | |
| 63 | - | } | |
| 64 | - | } | |
| 65 | - | if pkg == "" || output == "" || input == "" { | |
| 66 | - | t.Fatalf("%s: incomplete generation command", path) | |
| 67 | - | } | |
| 68 | - | dir := filepath.Dir(path) | |
| 69 | - | xmlPath := filepath.Clean(filepath.Join(dir, input)) | |
| 70 | - | if referenced[xmlPath] { | |
| 71 | - | t.Fatalf("%s generated more than once", xmlPath) | |
| 72 | - | } | |
| 73 | - | referenced[xmlPath] = true | |
| 74 | - | t.Run(pkg, func(t *testing.T) { | |
| 75 | - | s := NewScanner() | |
| 76 | - | s.CrossPackage = imports | |
| 77 | - | if err := s.ParseXML(xmlPath); err != nil { | |
| 78 | - | t.Fatal(err) | |
| 79 | - | } | |
| 80 | - | generated, err := s.Generate(pkg) | |
| 81 | - | if err != nil { | |
| 82 | - | t.Fatal(err) | |
| 83 | - | } | |
| 84 | - | checkedIn, err := os.ReadFile(filepath.Join(dir, output)) | |
| 85 | - | if err != nil { | |
| 86 | - | t.Fatal(err) | |
| 87 | - | } | |
| 88 | - | if !bytes.Equal(generated, checkedIn) { | |
| 89 | - | t.Fatal("bindings are stale; run GOWORK=off go generate ./...") | |
| 90 | - | } | |
| 91 | - | }) | |
| 92 | - | } | |
| 93 | - | return nil | |
| 94 | - | }) | |
| 95 | - | if err != nil { | |
| 96 | - | t.Fatal(err) | |
| 97 | - | } | |
| 98 | - | if len(referenced) == 0 { | |
| 99 | - | t.Fatal("no vendored protocols found") | |
| 100 | - | } | |
| 101 | - | err = filepath.WalkDir(root, func(path string, entry os.DirEntry, err error) error { | |
| 102 | - | if err != nil { | |
| 103 | - | return err | |
| 104 | - | } | |
| 105 | - | if !entry.IsDir() && filepath.Ext(path) == ".xml" && !referenced[path] { | |
| 106 | - | t.Errorf("%s has no generation command", path) | |
| 107 | - | } | |
| 108 | - | return nil | |
| 109 | - | }) | |
| 110 | - | if err != nil { | |
| 111 | - | t.Fatal(err) | |
| 112 | - | } | |
| 113 | - | } | |
D internal/scanner/requestargs_test.go +0 -243
| @@ -1,243 +0,0 @@ | |||
| 1 | - | package scanner | |
| 2 | - | ||
| 3 | - | import ( | |
| 4 | - | "os" | |
| 5 | - | "os/exec" | |
| 6 | - | "path/filepath" | |
| 7 | - | "strings" | |
| 8 | - | "testing" | |
| 9 | - | ) | |
| 10 | - | ||
| 11 | - | const requestArgsXML = `<protocol name="argsfix"> | |
| 12 | - | <interface name="args_obj" version="1"> | |
| 13 | - | <request name="mixed"> | |
| 14 | - | <arg name="serial" type="uint"/><arg name="dx" type="int"/><arg name="fx" type="fixed"/> | |
| 15 | - | <arg name="name" type="string"/><arg name="blob" type="array"/> | |
| 16 | - | <arg name="peer" type="object" interface="args_obj" allow-null="true"/> | |
| 17 | - | </request> | |
| 18 | - | <request name="make"><arg name="id" type="new_id" interface="args_obj"/><arg name="n" type="uint"/></request> | |
| 19 | - | <request name="give"><arg name="tag" type="string"/><arg name="fd" type="fd"/><arg name="size" type="uint"/></request> | |
| 20 | - | <request name="destroy" type="destructor"/> | |
| 21 | - | </interface></protocol>` | |
| 22 | - | ||
| 23 | - | func generateArgsFixture(t *testing.T) string { | |
| 24 | - | t.Helper() | |
| 25 | - | path := filepath.Join(t.TempDir(), "argsfix.xml") | |
| 26 | - | if err := os.WriteFile(path, []byte(requestArgsXML), 0600); err != nil { | |
| 27 | - | t.Fatal(err) | |
| 28 | - | } | |
| 29 | - | s := NewScanner() | |
| 30 | - | if err := s.ParseXML(path); err != nil { | |
| 31 | - | t.Fatal(err) | |
| 32 | - | } | |
| 33 | - | b, err := s.Generate("argsfix") | |
| 34 | - | if err != nil { | |
| 35 | - | t.Fatal(err) | |
| 36 | - | } | |
| 37 | - | return string(b) | |
| 38 | - | } | |
| 39 | - | ||
| 40 | - | // Generated requests must use typed arguments only: no interface{} boxing | |
| 41 | - | // path and no uintptr placeholder for descriptors. | |
| 42 | - | func TestGeneratedRequestsUseTypedArgs(t *testing.T) { | |
| 43 | - | text := generateArgsFixture(t) | |
| 44 | - | for _, want := range []string{ | |
| 45 | - | "RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: \"args_obj.mixed\"}, wl.ArgUint(serial), wl.ArgInt(dx), wl.ArgFixed(fx), wl.ArgString(name), wl.ArgArray(blob), wl.ArgObject(arg5))", | |
| 46 | - | "Child: child}, wl.ArgObject(child), wl.ArgUint(n))", | |
| 47 | - | "FDs: []int{fd}}, wl.ArgString(tag), wl.ArgFD(), wl.ArgUint(size))", | |
| 48 | - | "Destructor: true})", | |
| 49 | - | } { | |
| 50 | - | if !strings.Contains(text, want) { | |
| 51 | - | t.Errorf("generated code missing %q\n%s", want, text) | |
| 52 | - | } | |
| 53 | - | } | |
| 54 | - | for _, bad := range []string{".Request(wl.Request", "uintptr("} { | |
| 55 | - | if strings.Contains(text, bad) { | |
| 56 | - | t.Errorf("generated code still contains %q", bad) | |
| 57 | - | } | |
| 58 | - | } | |
| 59 | - | } | |
| 60 | - | ||
| 61 | - | // The generated requests compile against the transport, put the exact wire | |
| 62 | - | // bytes on the socket, and do not allocate for realistic numeric values. | |
| 63 | - | func TestGeneratedRequestsWireAndAllocations(t *testing.T) { | |
| 64 | - | goBin, err := exec.LookPath("go") | |
| 65 | - | if err != nil { | |
| 66 | - | t.Skip("go unavailable") | |
| 67 | - | } | |
| 68 | - | root, err := filepath.Abs("../..") | |
| 69 | - | if err != nil { | |
| 70 | - | t.Fatal(err) | |
| 71 | - | } | |
| 72 | - | dir := t.TempDir() | |
| 73 | - | write := func(name, content string) { | |
| 74 | - | if err := os.WriteFile(filepath.Join(dir, name), []byte(content), 0600); err != nil { | |
| 75 | - | t.Fatal(err) | |
| 76 | - | } | |
| 77 | - | } | |
| 78 | - | write("args.go", generateArgsFixture(t)) | |
| 79 | - | write("go.mod", "module example.com/argsfix\n\ngo 1.27\n\nrequire github.com/bnema/wlturbo v0.0.0\nreplace github.com/bnema/wlturbo => "+root+"\n") | |
| 80 | - | write("args_test.go", `package argsfix | |
| 81 | - | ||
| 82 | - | import ( | |
| 83 | - | "bytes" | |
| 84 | - | "net" | |
| 85 | - | "os" | |
| 86 | - | "testing" | |
| 87 | - | "time" | |
| 88 | - | ||
| 89 | - | "github.com/bnema/wlturbo" | |
| 90 | - | "golang.org/x/sys/unix" | |
| 91 | - | ) | |
| 92 | - | ||
| 93 | - | type sink struct{ last []byte } | |
| 94 | - | ||
| 95 | - | func (c *sink) Read([]byte) (int, error) { return 0, net.ErrClosed } | |
| 96 | - | func (c *sink) Write(p []byte) (int, error) { | |
| 97 | - | c.last = append(c.last[:0], p...) | |
| 98 | - | return len(p), nil | |
| 99 | - | } | |
| 100 | - | func (c *sink) Close() error { return nil } | |
| 101 | - | func (c *sink) LocalAddr() net.Addr { return a{} } | |
| 102 | - | func (c *sink) RemoteAddr() net.Addr { return a{} } | |
| 103 | - | func (c *sink) SetDeadline(time.Time) error { return nil } | |
| 104 | - | func (c *sink) SetReadDeadline(time.Time) error { return nil } | |
| 105 | - | func (c *sink) SetWriteDeadline(time.Time) error { return nil } | |
| 106 | - | ||
| 107 | - | type a struct{} | |
| 108 | - | ||
| 109 | - | func (a) Network() string { return "t" } | |
| 110 | - | func (a) String() string { return "t" } | |
| 111 | - | ||
| 112 | - | func setup(t testing.TB) (*wlturbo.Display, *sink, *ArgsObj) { | |
| 113 | - | c := &sink{} | |
| 114 | - | d, err := wlturbo.ConnectFromConn(c) | |
| 115 | - | if err != nil { | |
| 116 | - | t.Fatal(err) | |
| 117 | - | } | |
| 118 | - | o := NewArgsObj(d.Context()) | |
| 119 | - | o.SetID(d.AllocateID()) | |
| 120 | - | d.Context().Register(o) | |
| 121 | - | return d, c, o | |
| 122 | - | } | |
| 123 | - | ||
| 124 | - | func TestMixedWire(t *testing.T) { | |
| 125 | - | _, c, o := setup(t) | |
| 126 | - | peer := NewArgsObj(o.Context()) | |
| 127 | - | peer.SetID(0x1234) | |
| 128 | - | if err := o.Mixed(1000, -2, wlturbo.Fixed(512), "ab", []byte{9, 8, 7}, peer); err != nil { | |
| 129 | - | t.Fatal(err) | |
| 130 | - | } | |
| 131 | - | want := []byte{ | |
| 132 | - | byte(o.ID()), 0, 0, 0, 0, 0, 40, 0, | |
| 133 | - | 0xe8, 3, 0, 0, | |
| 134 | - | 0xfe, 0xff, 0xff, 0xff, | |
| 135 | - | 0, 2, 0, 0, | |
| 136 | - | 3, 0, 0, 0, 'a', 'b', 0, 0, | |
| 137 | - | 3, 0, 0, 0, 9, 8, 7, 0, | |
| 138 | - | 0x34, 0x12, 0, 0, | |
| 139 | - | } | |
| 140 | - | if !bytes.Equal(c.last, want) { | |
| 141 | - | t.Fatalf("got %x want %x", c.last, want) | |
| 142 | - | } | |
| 143 | - | if err := o.Mixed(1, 2, 3, "", nil, nil); err != nil { | |
| 144 | - | t.Fatal(err) | |
| 145 | - | } | |
| 146 | - | if got := c.last[len(c.last)-4:]; !bytes.Equal(got, []byte{0, 0, 0, 0}) { | |
| 147 | - | t.Fatalf("nil object = %x", got) | |
| 148 | - | } | |
| 149 | - | } | |
| 150 | - | ||
| 151 | - | func TestMixedAllocFree(t *testing.T) { | |
| 152 | - | _, _, o := setup(t) | |
| 153 | - | blob := []byte("blob") | |
| 154 | - | n := testing.AllocsPerRun(200, func() { | |
| 155 | - | if err := o.Mixed(123456, -70000, wlturbo.Fixed(1<<20), "hello", blob, nil); err != nil { | |
| 156 | - | t.Fatal(err) | |
| 157 | - | } | |
| 158 | - | }) | |
| 159 | - | if n != 0 { | |
| 160 | - | t.Fatalf("Mixed: %v allocs/op, want 0", n) | |
| 161 | - | } | |
| 162 | - | } | |
| 163 | - | ||
| 164 | - | func TestChildAndDestructor(t *testing.T) { | |
| 165 | - | d, c, o := setup(t) | |
| 166 | - | kid, err := o.Make(77777) | |
| 167 | - | if err != nil { | |
| 168 | - | t.Fatal(err) | |
| 169 | - | } | |
| 170 | - | if kid.ID() == 0 || c.last[8] != byte(kid.ID()) { | |
| 171 | - | t.Fatalf("child id %d not on the wire: %x", kid.ID(), c.last) | |
| 172 | - | } | |
| 173 | - | if err := o.Destroy(); err != nil { | |
| 174 | - | t.Fatal(err) | |
| 175 | - | } | |
| 176 | - | n := len(c.last) | |
| 177 | - | c.last = c.last[:0] | |
| 178 | - | if err := o.Destroy(); err == nil { | |
| 179 | - | t.Fatal("second destructor succeeded") | |
| 180 | - | } | |
| 181 | - | if len(c.last) != 0 || n == 0 { | |
| 182 | - | t.Fatal("wrote after destructor") | |
| 183 | - | } | |
| 184 | - | _ = d | |
| 185 | - | } | |
| 186 | - | ||
| 187 | - | func TestFDRequest(t *testing.T) { | |
| 188 | - | sp, err := unix.Socketpair(unix.AF_UNIX, unix.SOCK_STREAM|unix.SOCK_CLOEXEC, 0) | |
| 189 | - | if err != nil { | |
| 190 | - | t.Fatal(err) | |
| 191 | - | } | |
| 192 | - | fa, fb := os.NewFile(uintptr(sp[0]), "a"), os.NewFile(uintptr(sp[1]), "b") | |
| 193 | - | ca, err := net.FileConn(fa) | |
| 194 | - | fa.Close() | |
| 195 | - | if err != nil { | |
| 196 | - | fb.Close() | |
| 197 | - | t.Fatal(err) | |
| 198 | - | } | |
| 199 | - | defer ca.Close() | |
| 200 | - | cb, err := net.FileConn(fb) | |
| 201 | - | fb.Close() | |
| 202 | - | if err != nil { | |
| 203 | - | t.Fatal(err) | |
| 204 | - | } | |
| 205 | - | defer cb.Close() | |
| 206 | - | d, err := wlturbo.ConnectFromConn(ca) | |
| 207 | - | if err != nil { | |
| 208 | - | t.Fatal(err) | |
| 209 | - | } | |
| 210 | - | defer d.Close() | |
| 211 | - | o := NewArgsObj(d.Context()) | |
| 212 | - | o.SetID(d.AllocateID()) | |
| 213 | - | d.Context().Register(o) | |
| 214 | - | fd, err := unix.Open(os.DevNull, unix.O_RDONLY|unix.O_CLOEXEC, 0) | |
| 215 | - | if err != nil { | |
| 216 | - | t.Fatal(err) | |
| 217 | - | } | |
| 218 | - | if err := o.Give("t", fd, 5); err != nil { | |
| 219 | - | t.Fatal(err) | |
| 220 | - | } | |
| 221 | - | if _, err := unix.FcntlInt(uintptr(fd), unix.F_GETFD, 0); err == nil { | |
| 222 | - | t.Fatal("fd not closed after send") | |
| 223 | - | } | |
| 224 | - | // The connection first sends wl_display.get_registry (12 bytes). | |
| 225 | - | buf := make([]byte, 12+8+8+4) | |
| 226 | - | oob := make([]byte, unix.CmsgSpace(4)) | |
| 227 | - | n, oobn, _, _, err := cb.(*net.UnixConn).ReadMsgUnix(buf, oob) | |
| 228 | - | if err != nil || n != len(buf) || oobn == 0 { | |
| 229 | - | t.Fatalf("n=%d oobn=%d err=%v", n, oobn, err) | |
| 230 | - | } | |
| 231 | - | // The descriptor has no body word: string(8) + uint(4) only. | |
| 232 | - | if buf[12+4] != 2 || buf[12+8+8] != 5 || buf[12+6] != 20 { | |
| 233 | - | t.Fatalf("message = %x", buf[12:]) | |
| 234 | - | } | |
| 235 | - | } | |
| 236 | - | `) | |
| 237 | - | cmd := exec.Command(goBin, "test", "./...") | |
| 238 | - | cmd.Dir = dir | |
| 239 | - | cmd.Env = append(os.Environ(), "GOWORK=off", "GOFLAGS=-mod=mod") | |
| 240 | - | if out, err := cmd.CombinedOutput(); err != nil { | |
| 241 | - | t.Fatalf("generated request test: %v\n%s", err, out) | |
| 242 | - | } | |
| 243 | - | } | |
D internal/scanner/scanner.go +0 -748
| @@ -1,748 +0,0 @@ | |||
| 1 | - | // Package scanner generates WLTurbo-backed Go bindings from Wayland protocol | |
| 2 | - | // XML files. | |
| 3 | - | // | |
| 4 | - | // The generated code owns protocol semantics only: it embeds wl.BaseProxy, | |
| 5 | - | // allocates and registers child objects through the wl.Context, sends requests | |
| 6 | - | // through that context, and dispatches typed events to registered handlers. | |
| 7 | - | // Message framing, descriptor passing and connection lifetime stay in the | |
| 8 | - | // transport, so a generated binding never opens a socket or writes a header. | |
| 9 | - | package scanner | |
| 10 | - | ||
| 11 | - | import ( | |
| 12 | - | "bytes" | |
| 13 | - | "encoding/xml" | |
| 14 | - | "fmt" | |
| 15 | - | "go/format" | |
| 16 | - | "io" | |
| 17 | - | "os" | |
| 18 | - | "path/filepath" | |
| 19 | - | "sort" | |
| 20 | - | "strings" | |
| 21 | - | "text/template" | |
| 22 | - | ) | |
| 23 | - | ||
| 24 | - | // TransportImport is the import path generated bindings use for the Wayland | |
| 25 | - | // transport. | |
| 26 | - | const TransportImport = "github.com/bnema/wlturbo/wl" | |
| 27 | - | ||
| 28 | - | // Protocol represents a Wayland protocol specification | |
| 29 | - | type Protocol struct { | |
| 30 | - | XMLName xml.Name `xml:"protocol"` | |
| 31 | - | Name string `xml:"name,attr"` | |
| 32 | - | Copyright string `xml:"copyright"` | |
| 33 | - | Description *Description `xml:"description"` | |
| 34 | - | Interfaces []Interface `xml:"interface"` | |
| 35 | - | } | |
| 36 | - | ||
| 37 | - | // Interface represents a Wayland interface in the protocol | |
| 38 | - | type Interface struct { | |
| 39 | - | Name string `xml:"name,attr"` | |
| 40 | - | Version int `xml:"version,attr"` | |
| 41 | - | Description *Description `xml:"description"` | |
| 42 | - | Requests []Request `xml:"request"` | |
| 43 | - | Events []Event `xml:"event"` | |
| 44 | - | Enums []Enum `xml:"enum"` | |
| 45 | - | } | |
| 46 | - | ||
| 47 | - | // Request represents a client-to-server message | |
| 48 | - | type Request struct { | |
| 49 | - | Name string `xml:"name,attr"` | |
| 50 | - | Type string `xml:"type,attr"` // "destructor" or empty | |
| 51 | - | Since int `xml:"since,attr"` | |
| 52 | - | Description *Description `xml:"description"` | |
| 53 | - | Args []Arg `xml:"arg"` | |
| 54 | - | } | |
| 55 | - | ||
| 56 | - | // Event represents a server-to-client message | |
| 57 | - | type Event struct { | |
| 58 | - | Type string `xml:"type,attr"` | |
| 59 | - | Name string `xml:"name,attr"` | |
| 60 | - | Since int `xml:"since,attr"` | |
| 61 | - | Description *Description `xml:"description"` | |
| 62 | - | Args []Arg `xml:"arg"` | |
| 63 | - | } | |
| 64 | - | ||
| 65 | - | // Arg represents a message argument | |
| 66 | - | type Arg struct { | |
| 67 | - | Name string `xml:"name,attr"` | |
| 68 | - | Type string `xml:"type,attr"` | |
| 69 | - | Summary string `xml:"summary,attr"` | |
| 70 | - | Interface string `xml:"interface,attr"` | |
| 71 | - | AllowNull bool `xml:"allow-null,attr"` | |
| 72 | - | Enum string `xml:"enum,attr"` | |
| 73 | - | } | |
| 74 | - | ||
| 75 | - | // Enum represents an enumeration type | |
| 76 | - | type Enum struct { | |
| 77 | - | Name string `xml:"name,attr"` | |
| 78 | - | Since int `xml:"since,attr"` | |
| 79 | - | Bitfield bool `xml:"bitfield,attr"` | |
| 80 | - | Description *Description `xml:"description"` | |
| 81 | - | Entries []Entry `xml:"entry"` | |
| 82 | - | } | |
| 83 | - | ||
| 84 | - | // Entry represents an enum value | |
| 85 | - | type Entry struct { | |
| 86 | - | Name string `xml:"name,attr"` | |
| 87 | - | Value string `xml:"value,attr"` | |
| 88 | - | Summary string `xml:"summary,attr"` | |
| 89 | - | Since int `xml:"since,attr"` | |
| 90 | - | } | |
| 91 | - | ||
| 92 | - | // Description represents documentation | |
| 93 | - | type Description struct { | |
| 94 | - | Summary string `xml:"summary,attr"` | |
| 95 | - | Text string `xml:",chardata"` | |
| 96 | - | } | |
| 97 | - | ||
| 98 | - | // Scanner generates Go bindings from Wayland protocol XML | |
| 99 | - | type Scanner struct { | |
| 100 | - | protocol *Protocol | |
| 101 | - | source string | |
| 102 | - | // CrossPackage maps interface names to Go package import paths. Local wins. | |
| 103 | - | CrossPackage map[string]string | |
| 104 | - | } | |
| 105 | - | ||
| 106 | - | // NewScanner creates a new protocol scanner | |
| 107 | - | func NewScanner() *Scanner { | |
| 108 | - | return &Scanner{} | |
| 109 | - | } | |
| 110 | - | ||
| 111 | - | // ParseXML parses a Wayland protocol XML file | |
| 112 | - | func (s *Scanner) ParseXML(path string) error { | |
| 113 | - | file, err := os.Open(path) | |
| 114 | - | if err != nil { | |
| 115 | - | return fmt.Errorf("failed to open XML file: %w", err) | |
| 116 | - | } | |
| 117 | - | defer func() { _ = file.Close() }() | |
| 118 | - | ||
| 119 | - | data, err := io.ReadAll(file) | |
| 120 | - | if err != nil { | |
| 121 | - | return fmt.Errorf("failed to read XML file: %w", err) | |
| 122 | - | } | |
| 123 | - | ||
| 124 | - | var protocol Protocol | |
| 125 | - | if err := xml.Unmarshal(data, &protocol); err != nil { | |
| 126 | - | return fmt.Errorf("failed to parse XML: %w", err) | |
| 127 | - | } | |
| 128 | - | ||
| 129 | - | s.protocol = &protocol | |
| 130 | - | // Only the base name is recorded: generated output must not depend on the | |
| 131 | - | // path the XML happened to be read from. | |
| 132 | - | s.source = filepath.Base(path) | |
| 133 | - | return nil | |
| 134 | - | } | |
| 135 | - | ||
| 136 | - | // Generate creates Go source code for the parsed protocol | |
| 137 | - | func (s *Scanner) Generate(packageName string) ([]byte, error) { | |
| 138 | - | if s.protocol == nil { | |
| 139 | - | return nil, fmt.Errorf("no protocol parsed") | |
| 140 | - | } | |
| 141 | - | ||
| 142 | - | data, err := s.prepareTemplateData(packageName) | |
| 143 | - | if err != nil { | |
| 144 | - | return nil, err | |
| 145 | - | } | |
| 146 | - | ||
| 147 | - | var buf bytes.Buffer | |
| 148 | - | tmpl := template.Must(template.New("protocol").Parse(protocolTemplate)) | |
| 149 | - | if err := tmpl.Execute(&buf, data); err != nil { | |
| 150 | - | return nil, fmt.Errorf("failed to execute template: %w", err) | |
| 151 | - | } | |
| 152 | - | ||
| 153 | - | formatted, err := format.Source(buf.Bytes()) | |
| 154 | - | if err != nil { | |
| 155 | - | return buf.Bytes(), fmt.Errorf("failed to format generated code: %w", err) | |
| 156 | - | } | |
| 157 | - | return formatted, nil | |
| 158 | - | } | |
| 159 | - | ||
| 160 | - | // templateData holds data for template generation | |
| 161 | - | type templateData struct { | |
| 162 | - | Package string | |
| 163 | - | Protocol string | |
| 164 | - | Source string | |
| 165 | - | Copyright string | |
| 166 | - | ImportBlock string | |
| 167 | - | Constants []constantData | |
| 168 | - | Interfaces []interfaceData | |
| 169 | - | } | |
| 170 | - | ||
| 171 | - | type interfaceData struct { | |
| 172 | - | Name string | |
| 173 | - | GoName string | |
| 174 | - | Version int | |
| 175 | - | HasEvents bool | |
| 176 | - | SignatureCases []signatureCase | |
| 177 | - | Requests []requestData | |
| 178 | - | Events []eventData | |
| 179 | - | } | |
| 180 | - | ||
| 181 | - | type signatureCase struct { | |
| 182 | - | Opcode int | |
| 183 | - | Signature string | |
| 184 | - | } | |
| 185 | - | type requestData struct { | |
| 186 | - | Name string | |
| 187 | - | GoName string | |
| 188 | - | Doc string | |
| 189 | - | Opcode int | |
| 190 | - | Destructor bool | |
| 191 | - | Since int | |
| 192 | - | Params string | |
| 193 | - | Results string | |
| 194 | - | ArgPreparations []string | |
| 195 | - | CreatesChild bool | |
| 196 | - | ChildVar string | |
| 197 | - | ChildType string | |
| 198 | - | ChildFactory string | |
| 199 | - | ErrorReturn string | |
| 200 | - | HasFDs bool | |
| 201 | - | FDList string | |
| 202 | - | ArgList string | |
| 203 | - | } | |
| 204 | - | ||
| 205 | - | // argSlot is one positional argument of a request, in declaration order. A | |
| 206 | - | // new_id slot is filled in once the child object has been created. | |
| 207 | - | type argSlot struct { | |
| 208 | - | newID bool | |
| 209 | - | expr string | |
| 210 | - | } | |
| 211 | - | ||
| 212 | - | type eventData struct { | |
| 213 | - | HasFD bool | |
| 214 | - | ServerDestroy bool | |
| 215 | - | FDNames []string | |
| 216 | - | Name string | |
| 217 | - | GoName string | |
| 218 | - | Opcode int | |
| 219 | - | HandlerField string | |
| 220 | - | HandlerAccessor string | |
| 221 | - | HandlerParams string | |
| 222 | - | HandlerArgs string | |
| 223 | - | DecodeLines []string | |
| 224 | - | } | |
| 225 | - | ||
| 226 | - | type constantData struct { | |
| 227 | - | Name string | |
| 228 | - | Value string | |
| 229 | - | Type string | |
| 230 | - | Enum string | |
| 231 | - | Entry string | |
| 232 | - | } | |
| 233 | - | ||
| 234 | - | // Only display and registry have handwritten bootstrap bindings. | |
| 235 | - | var bootstrapTypes = map[string]bool{ | |
| 236 | - | "Display": true, | |
| 237 | - | "Registry": true, | |
| 238 | - | } | |
| 239 | - | ||
| 240 | - | // goKeywords are avoided as parameter names because generated identifiers | |
| 241 | - | // must not collide with the language. | |
| 242 | - | var goKeywords = map[string]bool{ | |
| 243 | - | "break": true, "case": true, "chan": true, "const": true, "continue": true, | |
| 244 | - | "default": true, "defer": true, "else": true, "fallthrough": true, "for": true, | |
| 245 | - | "func": true, "go": true, "goto": true, "if": true, "import": true, | |
| 246 | - | "interface": true, "map": true, "package": true, "range": true, "return": true, | |
| 247 | - | "select": true, "struct": true, "switch": true, "type": true, "var": true, | |
| 248 | - | } | |
| 249 | - | ||
| 250 | - | func (s *Scanner) prepareTemplateData(packageName string) (templateData, error) { | |
| 251 | - | data := templateData{ | |
| 252 | - | Package: packageName, | |
| 253 | - | Protocol: s.protocol.Name, | |
| 254 | - | Source: s.source, | |
| 255 | - | } | |
| 256 | - | if notice := strings.TrimSpace(s.protocol.Copyright); notice != "" { | |
| 257 | - | var comment strings.Builder | |
| 258 | - | for _, line := range strings.Split(notice, "\n") { | |
| 259 | - | comment.WriteString("// ") | |
| 260 | - | comment.WriteString(strings.TrimSpace(line)) | |
| 261 | - | comment.WriteByte('\n') | |
| 262 | - | } | |
| 263 | - | data.Copyright = comment.String() | |
| 264 | - | } | |
| 265 | - | ||
| 266 | - | imports := []string{TransportImport} | |
| 267 | - | usedCross := make(map[string]bool) | |
| 268 | - | for _, candidate := range s.protocol.Interfaces { | |
| 269 | - | for _, req := range candidate.Requests { | |
| 270 | - | for _, arg := range req.Args { | |
| 271 | - | if arg.Type == "object" || arg.Type == "new_id" { | |
| 272 | - | usedCross[arg.Interface] = true | |
| 273 | - | } | |
| 274 | - | } | |
| 275 | - | } | |
| 276 | - | for _, ev := range candidate.Events { | |
| 277 | - | for _, arg := range ev.Args { | |
| 278 | - | // Event object references are decoded as IDs, not imported proxies. | |
| 279 | - | if arg.Type == "new_id" { | |
| 280 | - | usedCross[arg.Interface] = true | |
| 281 | - | } | |
| 282 | - | } | |
| 283 | - | } | |
| 284 | - | } | |
| 285 | - | for iface, path := range s.CrossPackage { | |
| 286 | - | local := false | |
| 287 | - | for _, candidate := range s.protocol.Interfaces { | |
| 288 | - | if candidate.Name == iface { | |
| 289 | - | local = true | |
| 290 | - | break | |
| 291 | - | } | |
| 292 | - | } | |
| 293 | - | if local || !usedCross[iface] || bootstrapTypes[s.toGoName(iface)] { | |
| 294 | - | continue | |
| 295 | - | } | |
| 296 | - | alias := "cross_" + strings.ReplaceAll(iface, "-", "_") | |
| 297 | - | imports = append(imports, alias+" "+path) | |
| 298 | - | } | |
| 299 | - | sort.Strings(imports) | |
| 300 | - | stdImports := []string{} | |
| 301 | - | needsSync := false | |
| 302 | - | ||
| 303 | - | // Enum constants are package-level declarations, so two interfaces that | |
| 304 | - | // declare the same enum entry (for example xdg_surface.error.invalid_size | |
| 305 | - | // and xdg_toplevel.error.invalid_size) would collide. Entries whose name | |
| 306 | - | // occurs in more than one interface are qualified with their interface | |
| 307 | - | // name below; unique names keep their historical, unprefixed form. | |
| 308 | - | enumEntryCounts := map[string]int{} | |
| 309 | - | for _, iface := range s.protocol.Interfaces { | |
| 310 | - | for _, enum := range iface.Enums { | |
| 311 | - | for _, entry := range enum.Entries { | |
| 312 | - | enumEntryCounts[constantName(enum.Name, entry.Name)]++ | |
| 313 | - | } | |
| 314 | - | } | |
| 315 | - | } | |
| 316 | - | ||
| 317 | - | for _, iface := range s.protocol.Interfaces { | |
| 318 | - | if packageName == "core" && (iface.Name == "wl_display" || iface.Name == "wl_registry") { | |
| 319 | - | continue | |
| 320 | - | } | |
| 321 | - | ifaceData, err := s.processInterface(iface) | |
| 322 | - | if err != nil { | |
| 323 | - | return data, err | |
| 324 | - | } | |
| 325 | - | data.Interfaces = append(data.Interfaces, ifaceData) | |
| 326 | - | if len(iface.Events) > 0 { | |
| 327 | - | needsSync = true | |
| 328 | - | } | |
| 329 | - | ||
| 330 | - | for _, enum := range iface.Enums { | |
| 331 | - | for _, entry := range enum.Entries { | |
| 332 | - | name := constantName(enum.Name, entry.Name) | |
| 333 | - | if enumEntryCounts[name] > 1 { | |
| 334 | - | name = qualifiedConstantName(iface.Name, enum.Name, entry.Name) | |
| 335 | - | } | |
| 336 | - | // Enum values are emitted untyped: the same enum travels as a uint | |
| 337 | - | // in one protocol and as an int in another, and an untyped constant | |
| 338 | - | // assigns to either without casts at the call site. | |
| 339 | - | data.Constants = append(data.Constants, constantData{ | |
| 340 | - | Name: name, | |
| 341 | - | Value: entry.Value, | |
| 342 | - | Enum: enum.Name, | |
| 343 | - | Entry: entry.Name, | |
| 344 | - | }) | |
| 345 | - | } | |
| 346 | - | } | |
| 347 | - | } | |
| 348 | - | ||
| 349 | - | // Handlers are registered and dispatched from different goroutines, so an | |
| 350 | - | // interface with events needs a mutex. | |
| 351 | - | if needsSync { | |
| 352 | - | stdImports = append(stdImports, "sync") | |
| 353 | - | } | |
| 354 | - | ||
| 355 | - | var block strings.Builder | |
| 356 | - | block.WriteString("import (\n") | |
| 357 | - | for _, imp := range stdImports { | |
| 358 | - | fmt.Fprintf(&block, "\t%q\n", imp) | |
| 359 | - | } | |
| 360 | - | if len(stdImports) > 0 && len(imports) > 0 { | |
| 361 | - | block.WriteString("\n") | |
| 362 | - | } | |
| 363 | - | for _, imp := range imports { | |
| 364 | - | if strings.Contains(imp, " ") { | |
| 365 | - | parts := strings.SplitN(imp, " ", 2) | |
| 366 | - | fmt.Fprintf(&block, "\t%s %q\n", parts[0], parts[1]) | |
| 367 | - | } else { | |
| 368 | - | fmt.Fprintf(&block, "\t%q\n", imp) | |
| 369 | - | } | |
| 370 | - | } | |
| 371 | - | block.WriteString(")") | |
| 372 | - | data.ImportBlock = block.String() | |
| 373 | - | ||
| 374 | - | return data, nil | |
| 375 | - | } | |
| 376 | - | ||
| 377 | - | func (s *Scanner) processInterface(iface Interface) (interfaceData, error) { | |
| 378 | - | data := interfaceData{ | |
| 379 | - | Name: iface.Name, | |
| 380 | - | GoName: s.toGoName(iface.Name), | |
| 381 | - | Version: iface.Version, | |
| 382 | - | HasEvents: len(iface.Events) > 0, | |
| 383 | - | } | |
| 384 | - | ||
| 385 | - | for i, req := range iface.Requests { | |
| 386 | - | request, err := s.processRequest(iface, req, i) | |
| 387 | - | if err != nil { | |
| 388 | - | return data, err | |
| 389 | - | } | |
| 390 | - | data.Requests = append(data.Requests, request) | |
| 391 | - | } | |
| 392 | - | ||
| 393 | - | for i, event := range iface.Events { | |
| 394 | - | var sig strings.Builder | |
| 395 | - | for _, arg := range event.Args { | |
| 396 | - | sig.WriteString(arg.Type) | |
| 397 | - | sig.WriteByte(',') | |
| 398 | - | } | |
| 399 | - | data.SignatureCases = append(data.SignatureCases, signatureCase{i, sig.String()}) | |
| 400 | - | eventData, err := s.processEvent(event, i) | |
| 401 | - | if iface.Name == "wl_callback" && event.Name == "done" { | |
| 402 | - | eventData.ServerDestroy = true | |
| 403 | - | } | |
| 404 | - | if err != nil { | |
| 405 | - | return data, err | |
| 406 | - | } | |
| 407 | - | data.Events = append(data.Events, eventData) | |
| 408 | - | } | |
| 409 | - | ||
| 410 | - | return data, nil | |
| 411 | - | } | |
| 412 | - | ||
| 413 | - | func (s *Scanner) processRequest(iface Interface, req Request, opcode int) (requestData, error) { | |
| 414 | - | data := requestData{ | |
| 415 | - | Name: req.Name, | |
| 416 | - | GoName: s.toGoName(req.Name), | |
| 417 | - | Doc: s.formatDescription(req.Description), | |
| 418 | - | Opcode: opcode, | |
| 419 | - | Destructor: req.Type == "destructor", | |
| 420 | - | Since: req.Since, | |
| 421 | - | ChildVar: "child", | |
| 422 | - | } | |
| 423 | - | ||
| 424 | - | var ( | |
| 425 | - | params []string | |
| 426 | - | argSlots []argSlot | |
| 427 | - | argExprs []string | |
| 428 | - | fdExprs []string | |
| 429 | - | newIDArg *Arg | |
| 430 | - | ) | |
| 431 | - | ||
| 432 | - | for i, arg := range req.Args { | |
| 433 | - | if arg.Type == "new_id" { | |
| 434 | - | if newIDArg != nil { | |
| 435 | - | return data, fmt.Errorf("%s.%s: more than one new_id argument is not supported", iface.Name, req.Name) | |
| 436 | - | } | |
| 437 | - | newIDArg = &arg | |
| 438 | - | // The child object is created later, but it keeps its declared | |
| 439 | - | // position: the wire order is the argument order. | |
| 440 | - | argSlots = append(argSlots, argSlot{newID: true}) | |
| 441 | - | continue | |
| 442 | - | } | |
| 443 | - | ||
| 444 | - | name := s.paramName(arg.Name, i) | |
| 445 | - | goType, err := s.goTypeForArg(arg) | |
| 446 | - | if err != nil { | |
| 447 | - | return data, fmt.Errorf("%s.%s: %w", iface.Name, req.Name, err) | |
| 448 | - | } | |
| 449 | - | ||
| 450 | - | expr := name | |
| 451 | - | switch arg.Type { | |
| 452 | - | case "object": | |
| 453 | - | // Objects are pointer types, and travel as wl.Object so a nil | |
| 454 | - | // pointer is never sent as a non-nil interface holding a typed nil. | |
| 455 | - | params = append(params, name+" *"+goType) | |
| 456 | - | holder := fmt.Sprintf("arg%d", i) | |
| 457 | - | data.ArgPreparations = append(data.ArgPreparations, | |
| 458 | - | fmt.Sprintf("var %s wl.Object", holder), | |
| 459 | - | fmt.Sprintf("if %s != nil {", name), | |
| 460 | - | fmt.Sprintf("\t%s = %s", holder, name), | |
| 461 | - | "}") | |
| 462 | - | expr = "wl.ArgObject(" + holder + ")" | |
| 463 | - | ||
| 464 | - | case "fd": | |
| 465 | - | // Descriptors travel out of band: the body carries no value for | |
| 466 | - | // them, and the descriptor list is attached to the request. | |
| 467 | - | params = append(params, name+" int") | |
| 468 | - | fdExprs = append(fdExprs, name) | |
| 469 | - | expr = "wl.ArgFD()" | |
| 470 | - | ||
| 471 | - | default: | |
| 472 | - | params = append(params, name+" "+goType) | |
| 473 | - | switch arg.Type { | |
| 474 | - | case "int": | |
| 475 | - | expr = "wl.ArgInt(" + name + ")" | |
| 476 | - | case "uint": | |
| 477 | - | expr = "wl.ArgUint(" + name + ")" | |
| 478 | - | case "fixed": | |
| 479 | - | expr = "wl.ArgFixed(" + name + ")" | |
| 480 | - | case "string": | |
| 481 | - | expr = "wl.ArgString(" + name + ")" | |
| 482 | - | case "array": | |
| 483 | - | expr = "wl.ArgArray(" + name + ")" | |
| 484 | - | } | |
| 485 | - | } | |
| 486 | - | ||
| 487 | - | argSlots = append(argSlots, argSlot{expr: expr}) | |
| 488 | - | } | |
| 489 | - | ||
| 490 | - | if newIDArg != nil { | |
| 491 | - | childType, err := s.goTypeForArg(*newIDArg) | |
| 492 | - | if err != nil { | |
| 493 | - | return data, fmt.Errorf("%s.%s: %w", iface.Name, req.Name, err) | |
| 494 | - | } | |
| 495 | - | data.CreatesChild = true | |
| 496 | - | data.ChildType = childType | |
| 497 | - | if strings.Contains(childType, ".") { | |
| 498 | - | data.ChildFactory = childType[:strings.LastIndex(childType, ".")+1] + "New" + s.toGoName(newIDArg.Interface) | |
| 499 | - | } | |
| 500 | - | } | |
| 501 | - | ||
| 502 | - | for _, slot := range argSlots { | |
| 503 | - | if slot.newID { | |
| 504 | - | argExprs = append(argExprs, "wl.ArgObject("+data.ChildVar+")") | |
| 505 | - | continue | |
| 506 | - | } | |
| 507 | - | argExprs = append(argExprs, slot.expr) | |
| 508 | - | } | |
| 509 | - | ||
| 510 | - | data.Params = strings.Join(params, ", ") | |
| 511 | - | args := "" | |
| 512 | - | if len(argExprs) > 0 { | |
| 513 | - | args = ", " + strings.Join(argExprs, ", ") | |
| 514 | - | } | |
| 515 | - | // Context.RequestArgs owns the lifecycle: destructors claim the proxy | |
| 516 | - | // atomically, children are registered before the send and descriptors are | |
| 517 | - | // closed only after a successful send. | |
| 518 | - | data.ArgList = args | |
| 519 | - | data.FDList = strings.Join(fdExprs, ", ") | |
| 520 | - | data.HasFDs = len(fdExprs) > 0 | |
| 521 | - | if data.CreatesChild { | |
| 522 | - | data.Results = "(*" + data.ChildType + ", error)" | |
| 523 | - | data.ErrorReturn = "nil, err" | |
| 524 | - | } else { | |
| 525 | - | data.Results = "error" | |
| 526 | - | data.ErrorReturn = "err" | |
| 527 | - | } | |
| 528 | - | ||
| 529 | - | return data, nil | |
| 530 | - | } | |
| 531 | - | ||
| 532 | - | func (s *Scanner) processEvent(event Event, opcode int) (eventData, error) { | |
| 533 | - | goName := s.toGoName(event.Name) | |
| 534 | - | data := eventData{ | |
| 535 | - | ServerDestroy: event.Type == "destructor", | |
| 536 | - | Name: event.Name, | |
| 537 | - | GoName: goName, | |
| 538 | - | Opcode: opcode, | |
| 539 | - | HandlerField: "on" + goName, | |
| 540 | - | HandlerAccessor: "handlersFor" + goName, | |
| 541 | - | } | |
| 542 | - | ||
| 543 | - | var params, args []string | |
| 544 | - | ||
| 545 | - | for i, arg := range event.Args { | |
| 546 | - | name := s.paramName(arg.Name, i) | |
| 547 | - | ||
| 548 | - | switch arg.Type { | |
| 549 | - | case "new_id": | |
| 550 | - | childType, err := s.goTypeForArg(arg) | |
| 551 | - | if err != nil { | |
| 552 | - | return data, fmt.Errorf("%s.%s: %w", event.Name, arg.Name, err) | |
| 553 | - | } | |
| 554 | - | child := name + "Object" | |
| 555 | - | data.DecodeLines = append(data.DecodeLines, fmt.Sprintf("%sID := event.Uint32()", name)) | |
| 556 | - | if strings.Contains(childType, ".") { | |
| 557 | - | factory := childType[:strings.LastIndex(childType, ".")+1] + "New" + s.toGoName(arg.Interface) | |
| 558 | - | data.DecodeLines = append(data.DecodeLines, fmt.Sprintf("%s := %s(o.Context())", child, factory)) | |
| 559 | - | } else { | |
| 560 | - | data.DecodeLines = append(data.DecodeLines, | |
| 561 | - | fmt.Sprintf("%s := &%s{}", child, childType), | |
| 562 | - | fmt.Sprintf("%s.SetContext(o.Context())", child), | |
| 563 | - | ) | |
| 564 | - | } | |
| 565 | - | data.DecodeLines = append(data.DecodeLines, | |
| 566 | - | fmt.Sprintf("%s.SetID(%sID)", child, name), | |
| 567 | - | fmt.Sprintf("%s.SetVersion(o.Version())", child), | |
| 568 | - | fmt.Sprintf("o.Context().Register(%s)", child), | |
| 569 | - | ) | |
| 570 | - | params = append(params, child+" *"+childType) | |
| 571 | - | args = append(args, child) | |
| 572 | - | ||
| 573 | - | case "object": | |
| 574 | - | // Object references are reported as raw object IDs: the generated | |
| 575 | - | // layer does not own a registry of foreign proxies. | |
| 576 | - | data.DecodeLines = append(data.DecodeLines, fmt.Sprintf("%sID := event.Uint32()", name)) | |
| 577 | - | params = append(params, name+"ID uint32") | |
| 578 | - | args = append(args, name+"ID") | |
| 579 | - | ||
| 580 | - | default: | |
| 581 | - | if arg.Type == "fd" { | |
| 582 | - | data.HasFD = true | |
| 583 | - | data.FDNames = append(data.FDNames, name) | |
| 584 | - | } | |
| 585 | - | goType, decoder, err := s.scalarDecoder(arg) | |
| 586 | - | if err != nil { | |
| 587 | - | return data, fmt.Errorf("%s.%s: %w", event.Name, arg.Name, err) | |
| 588 | - | } | |
| 589 | - | data.DecodeLines = append(data.DecodeLines, fmt.Sprintf("%s := event.%s()", name, decoder)) | |
| 590 | - | params = append(params, name+" "+goType) | |
| 591 | - | args = append(args, name) | |
| 592 | - | } | |
| 593 | - | } | |
| 594 | - | ||
| 595 | - | data.HandlerParams = strings.Join(params, ", ") | |
| 596 | - | data.HandlerArgs = strings.Join(args, ", ") | |
| 597 | - | return data, nil | |
| 598 | - | } | |
| 599 | - | ||
| 600 | - | // scalarDecoder maps a simple argument to its Go type and event decoder. | |
| 601 | - | func (s *Scanner) scalarDecoder(arg Arg) (goType, decoder string, err error) { | |
| 602 | - | switch arg.Type { | |
| 603 | - | case "int": | |
| 604 | - | return "int32", "Int32", nil | |
| 605 | - | case "uint": | |
| 606 | - | return "uint32", "Uint32", nil | |
| 607 | - | case "fixed": | |
| 608 | - | return "wl.Fixed", "Fixed", nil | |
| 609 | - | case "string": | |
| 610 | - | return "string", "String", nil | |
| 611 | - | case "array": | |
| 612 | - | return "[]byte", "Array", nil | |
| 613 | - | case "fd": | |
| 614 | - | return "*wl.OwnedFD", "FD", nil | |
| 615 | - | } | |
| 616 | - | return "", "", fmt.Errorf("unsupported event argument type %q", arg.Type) | |
| 617 | - | } | |
| 618 | - | ||
| 619 | - | // goTypeForArg returns the Go type of an object-like argument. Protocol-local | |
| 620 | - | // interfaces map to generated types, explicit external references to their | |
| 621 | - | // mapped package, and bootstrap display/registry to transport wrappers. | |
| 622 | - | func (s *Scanner) goTypeForArg(arg Arg) (string, error) { | |
| 623 | - | switch arg.Type { | |
| 624 | - | case "int": | |
| 625 | - | return "int32", nil | |
| 626 | - | case "uint": | |
| 627 | - | return "uint32", nil | |
| 628 | - | case "fixed": | |
| 629 | - | return "wl.Fixed", nil | |
| 630 | - | case "string": | |
| 631 | - | return "string", nil | |
| 632 | - | case "array": | |
| 633 | - | return "[]byte", nil | |
| 634 | - | case "fd": | |
| 635 | - | return "int", nil | |
| 636 | - | case "object", "new_id": | |
| 637 | - | return s.goTypeForInterface(arg.Interface) | |
| 638 | - | } | |
| 639 | - | return "", fmt.Errorf("unsupported argument type %q", arg.Type) | |
| 640 | - | } | |
| 641 | - | ||
| 642 | - | func (s *Scanner) goTypeForInterface(iface string) (string, error) { | |
| 643 | - | if iface == "" { | |
| 644 | - | return "wl.BaseProxy", nil | |
| 645 | - | } | |
| 646 | - | // The XML package owns its own definitions even when the name starts wl_. | |
| 647 | - | for _, local := range s.protocol.Interfaces { | |
| 648 | - | if local.Name == iface && iface != "wl_display" && iface != "wl_registry" { | |
| 649 | - | return s.toGoName(iface), nil | |
| 650 | - | } | |
| 651 | - | } | |
| 652 | - | if bootstrapTypes[s.toGoName(iface)] { | |
| 653 | - | return "wl." + s.toGoName(iface), nil | |
| 654 | - | } | |
| 655 | - | if _, ok := s.CrossPackage[iface]; ok { | |
| 656 | - | return "cross_" + strings.ReplaceAll(iface, "-", "_") + "." + s.toGoName(iface), nil | |
| 657 | - | } | |
| 658 | - | return "", fmt.Errorf("unresolved interface %q: add CrossPackage mapping", iface) | |
| 659 | - | } | |
| 660 | - | ||
| 661 | - | // paramName turns a protocol argument name into a Go parameter name. | |
| 662 | - | func (s *Scanner) paramName(name string, index int) string { | |
| 663 | - | if name == "" { | |
| 664 | - | return fmt.Sprintf("arg%d", index) | |
| 665 | - | } | |
| 666 | - | ||
| 667 | - | parts := strings.Split(name, "_") | |
| 668 | - | for i, part := range parts { | |
| 669 | - | if part == "" { | |
| 670 | - | continue | |
| 671 | - | } | |
| 672 | - | if i == 0 { | |
| 673 | - | parts[i] = strings.ToLower(part[:1]) + part[1:] | |
| 674 | - | continue | |
| 675 | - | } | |
| 676 | - | parts[i] = strings.ToUpper(part[:1]) + part[1:] | |
| 677 | - | } | |
| 678 | - | result := strings.Join(parts, "") | |
| 679 | - | if result == "" { | |
| 680 | - | return fmt.Sprintf("arg%d", index) | |
| 681 | - | } | |
| 682 | - | if goKeywords[result] { | |
| 683 | - | return result + "Arg" | |
| 684 | - | } | |
| 685 | - | return result | |
| 686 | - | } | |
| 687 | - | ||
| 688 | - | func (s *Scanner) toGoName(name string) string { | |
| 689 | - | name = strings.TrimPrefix(name, "zwlr_") | |
| 690 | - | name = strings.TrimPrefix(name, "zwp_") | |
| 691 | - | name = strings.TrimPrefix(name, "wl_") | |
| 692 | - | name = strings.TrimSuffix(name, "_v1") | |
| 693 | - | name = strings.TrimSuffix(name, "_v2") | |
| 694 | - | ||
| 695 | - | parts := strings.Split(name, "_") | |
| 696 | - | for i, part := range parts { | |
| 697 | - | if part != "" { | |
| 698 | - | parts[i] = strings.ToUpper(part[:1]) + part[1:] | |
| 699 | - | } | |
| 700 | - | } | |
| 701 | - | return strings.Join(parts, "") | |
| 702 | - | } | |
| 703 | - | ||
| 704 | - | // constantName renders an enum entry as the unprefixed constant name. | |
| 705 | - | func constantName(enum, entry string) string { | |
| 706 | - | return strings.Join(append(joinName(enum), joinName(entry)...), "_") | |
| 707 | - | } | |
| 708 | - | ||
| 709 | - | // qualifiedConstantName prefixes an enum entry constant with its interface | |
| 710 | - | // name. It is used for entries that several interfaces declare, which would | |
| 711 | - | // otherwise collide in the generated package. | |
| 712 | - | func qualifiedConstantName(iface, enum, entry string) string { | |
| 713 | - | return strings.Join(append(joinName(iface), constantName(enum, entry)), "_") | |
| 714 | - | } | |
| 715 | - | ||
| 716 | - | // joinName upper-cases the underscore-separated parts of a protocol name. | |
| 717 | - | func joinName(value string) []string { | |
| 718 | - | parts := strings.Split(value, "_") | |
| 719 | - | out := make([]string, 0, len(parts)) | |
| 720 | - | for _, part := range parts { | |
| 721 | - | if part != "" { | |
| 722 | - | out = append(out, strings.ToUpper(part)) | |
| 723 | - | } | |
| 724 | - | } | |
| 725 | - | return out | |
| 726 | - | } | |
| 727 | - | ||
| 728 | - | // formatDescription renders an argument or request description as a single | |
| 729 | - | // documentation line. | |
| 730 | - | func (s *Scanner) formatDescription(desc *Description) string { | |
| 731 | - | if desc == nil { | |
| 732 | - | return "" | |
| 733 | - | } | |
| 734 | - | ||
| 735 | - | text := strings.TrimSpace(desc.Text) | |
| 736 | - | if text == "" { | |
| 737 | - | return desc.Summary | |
| 738 | - | } | |
| 739 | - | ||
| 740 | - | lines := strings.Split(text, "\n") | |
| 741 | - | formatted := make([]string, 0, len(lines)) | |
| 742 | - | for _, line := range lines { | |
| 743 | - | if line = strings.TrimSpace(line); line != "" { | |
| 744 | - | formatted = append(formatted, line) | |
| 745 | - | } | |
| 746 | - | } | |
| 747 | - | return strings.Join(formatted, " ") | |
| 748 | - | } | |
D internal/scanner/scanner_test.go +0 -163
| @@ -1,163 +0,0 @@ | |||
| 1 | - | package scanner | |
| 2 | - | ||
| 3 | - | import ( | |
| 4 | - | "os" | |
| 5 | - | "os/exec" | |
| 6 | - | "path/filepath" | |
| 7 | - | "strings" | |
| 8 | - | "testing" | |
| 9 | - | ) | |
| 10 | - | ||
| 11 | - | func TestResolution(t *testing.T) { | |
| 12 | - | p := filepath.Join(t.TempDir(), "fixture.xml") | |
| 13 | - | xml := `<protocol name="sample"><interface name="wl_surface" version="1"><event name="done"><arg name="value" type="uint"/></event></interface><interface name="custom_thing" version="1"><request name="make"><arg name="id" type="new_id" interface="wl_surface"/><arg name="output" type="object" interface="wl_output"/></request></interface></protocol>` | |
| 14 | - | if err := os.WriteFile(p, []byte(xml), 0600); err != nil { | |
| 15 | - | t.Fatal(err) | |
| 16 | - | } | |
| 17 | - | s := NewScanner() | |
| 18 | - | if err := s.ParseXML(p); err != nil { | |
| 19 | - | t.Fatal(err) | |
| 20 | - | } | |
| 21 | - | s.CrossPackage = map[string]string{"wl_surface": "github.com/bnema/wlturbo/protocol/core", "wl_output": "github.com/bnema/wlturbo/protocol/core"} | |
| 22 | - | b, err := s.Generate("fixture") | |
| 23 | - | if err != nil { | |
| 24 | - | t.Fatal(err) | |
| 25 | - | } | |
| 26 | - | text := string(b) | |
| 27 | - | if !strings.Contains(text, "(*Surface, error)") || !strings.Contains(text, "output *cross_wl_output.Output") || strings.Contains(text, "cross_wl_surface") { | |
| 28 | - | t.Fatalf("wrong resolution: %s", text) | |
| 29 | - | } | |
| 30 | - | } | |
| 31 | - | func TestCoreGeneration(t *testing.T) { | |
| 32 | - | s := NewScanner() | |
| 33 | - | if err := s.ParseXML("../../protocol/wayland.xml"); err != nil { | |
| 34 | - | t.Fatal(err) | |
| 35 | - | } | |
| 36 | - | b, err := s.Generate("core") | |
| 37 | - | if err != nil { | |
| 38 | - | t.Fatal(err) | |
| 39 | - | } | |
| 40 | - | for _, want := range []string{"type Keyboard struct", "type Subsurface struct", "type Buffer struct", "type Callback struct", "return \"uint,fd,uint,\", true", "child := &Keyboard{}"} { | |
| 41 | - | if !strings.Contains(string(b), want) { | |
| 42 | - | t.Errorf("missing %s", want) | |
| 43 | - | } | |
| 44 | - | } | |
| 45 | - | if strings.Contains(string(b), "type Display struct") || strings.Contains(string(b), "type Registry struct") { | |
| 46 | - | t.Fatal("bootstrap generated twice") | |
| 47 | - | } | |
| 48 | - | } | |
| 49 | - | ||
| 50 | - | // Extension protocols use wl_buffer as both an event-created child and a request-created child. | |
| 51 | - | // Verify the generated code uses the public constructor instead of embedding | |
| 52 | - | // an inaccessible BaseProxy context field across package boundaries. | |
| 53 | - | func TestExternalChildFactory(t *testing.T) { | |
| 54 | - | path := filepath.Join(t.TempDir(), "external.xml") | |
| 55 | - | xml := `<protocol name="fixture"><interface name="ext_params" version="1"><request name="create"><arg name="id" type="new_id" interface="wl_buffer"/></request><event name="created"><arg name="id" type="new_id" interface="wl_buffer"/></event></interface></protocol>` | |
| 56 | - | if err := os.WriteFile(path, []byte(xml), 0600); err != nil { | |
| 57 | - | t.Fatal(err) | |
| 58 | - | } | |
| 59 | - | s := NewScanner() | |
| 60 | - | if err := s.ParseXML(path); err != nil { | |
| 61 | - | t.Fatal(err) | |
| 62 | - | } | |
| 63 | - | s.CrossPackage = map[string]string{"wl_buffer": "github.com/bnema/wlturbo/protocol/core"} | |
| 64 | - | generated, err := s.Generate("ext") | |
| 65 | - | if err != nil { | |
| 66 | - | t.Fatal(err) | |
| 67 | - | } | |
| 68 | - | for _, part := range []string{"cross_wl_buffer.NewBuffer(o.Context())", "(*cross_wl_buffer.Buffer, error)", "idObject.SetID(idID)"} { | |
| 69 | - | if !strings.Contains(string(generated), part) { | |
| 70 | - | t.Errorf("generated code missing %q", part) | |
| 71 | - | } | |
| 72 | - | } | |
| 73 | - | if strings.Contains(string(generated), "&cross_wl_buffer.Buffer{}") { | |
| 74 | - | t.Fatal("foreign child was constructed without its package factory") | |
| 75 | - | } | |
| 76 | - | } | |
| 77 | - | ||
| 78 | - | func TestUnresolvedExternalInterface(t *testing.T) { | |
| 79 | - | path := filepath.Join(t.TempDir(), "extension.xml") | |
| 80 | - | xml := `<protocol name="ext"><interface name="ext_parent" version="1"><request name="make"><arg name="id" type="new_id" interface="wl_surface"/></request></interface></protocol>` | |
| 81 | - | if err := os.WriteFile(path, []byte(xml), 0600); err != nil { | |
| 82 | - | t.Fatal(err) | |
| 83 | - | } | |
| 84 | - | s := NewScanner() | |
| 85 | - | if err := s.ParseXML(path); err != nil { | |
| 86 | - | t.Fatal(err) | |
| 87 | - | } | |
| 88 | - | if _, err := s.Generate("ext"); err == nil || !strings.Contains(err.Error(), "wl_surface") { | |
| 89 | - | t.Fatalf("unmapped external reference: %v", err) | |
| 90 | - | } | |
| 91 | - | } | |
| 92 | - | ||
| 93 | - | func TestMappedExtensionCompilesAndDispatchesChild(t *testing.T) { | |
| 94 | - | goBin, err := exec.LookPath("go") | |
| 95 | - | if err != nil { | |
| 96 | - | t.Skip("go unavailable: generated extension compilation requires go") | |
| 97 | - | } | |
| 98 | - | root, err := filepath.Abs("../..") | |
| 99 | - | if err != nil { | |
| 100 | - | t.Fatal(err) | |
| 101 | - | } | |
| 102 | - | dir := t.TempDir() | |
| 103 | - | xml := `<protocol name="ext"><interface name="ext_parent" version="1"><event name="child"><arg name="id" type="new_id" interface="wl_buffer"/></event></interface></protocol>` | |
| 104 | - | path := filepath.Join(dir, "ext.xml") | |
| 105 | - | if err := os.WriteFile(path, []byte(xml), 0600); err != nil { | |
| 106 | - | t.Fatal(err) | |
| 107 | - | } | |
| 108 | - | s := NewScanner() | |
| 109 | - | if err := s.ParseXML(path); err != nil { | |
| 110 | - | t.Fatal(err) | |
| 111 | - | } | |
| 112 | - | s.CrossPackage = map[string]string{"wl_buffer": "github.com/bnema/wlturbo/protocol/core"} | |
| 113 | - | generated, err := s.Generate("ext") | |
| 114 | - | if err != nil { | |
| 115 | - | t.Fatal(err) | |
| 116 | - | } | |
| 117 | - | if err := os.WriteFile(filepath.Join(dir, "ext.go"), generated, 0600); err != nil { | |
| 118 | - | t.Fatal(err) | |
| 119 | - | } | |
| 120 | - | mod := "module example.com/ext\n\ngo 1.27\n\nrequire github.com/bnema/wlturbo v0.0.0\nreplace github.com/bnema/wlturbo => " + root + "\n" | |
| 121 | - | if err := os.WriteFile(filepath.Join(dir, "go.mod"), []byte(mod), 0600); err != nil { | |
| 122 | - | t.Fatal(err) | |
| 123 | - | } | |
| 124 | - | test := `package ext | |
| 125 | - | import ( | |
| 126 | - | "encoding/binary" | |
| 127 | - | "net" | |
| 128 | - | "os" | |
| 129 | - | "testing" | |
| 130 | - | "github.com/bnema/wlturbo" | |
| 131 | - | "github.com/bnema/wlturbo/protocol/core" | |
| 132 | - | "golang.org/x/sys/unix" | |
| 133 | - | ) | |
| 134 | - | func TestTypedChild(t *testing.T) { | |
| 135 | - | f, err := unix.Socketpair(unix.AF_UNIX, unix.SOCK_STREAM, 0); if err != nil { t.Fatal(err) } | |
| 136 | - | a, b := os.NewFile(uintptr(f[0]), "a"), os.NewFile(uintptr(f[1]), "b") | |
| 137 | - | c, err := net.FileConn(a); a.Close(); if err != nil { t.Fatal(err) }; defer c.Close() | |
| 138 | - | p, err := net.FileConn(b); b.Close(); if err != nil { t.Fatal(err) }; defer p.Close() | |
| 139 | - | d, err := wlturbo.ConnectFromConn(c); if err != nil { t.Fatal(err) }; defer d.Close() | |
| 140 | - | parent := NewExtParent(d.Context()); parent.SetID(d.AllocateID()); d.Context().Register(parent) | |
| 141 | - | var child *core.Buffer | |
| 142 | - | parent.OnChild(func(b *core.Buffer) { child = b }) | |
| 143 | - | frame := make([]byte, 12); binary.LittleEndian.PutUint32(frame, parent.ID()); binary.LittleEndian.PutUint32(frame[4:], 12<<16); binary.LittleEndian.PutUint32(frame[8:], 0xff000001) | |
| 144 | - | if _, err := p.Write(frame); err != nil { t.Fatal(err) } | |
| 145 | - | if err := d.Dispatch(); err != nil { t.Fatal(err) } | |
| 146 | - | if child == nil || child.ID() != 0xff000001 { t.Fatalf("child: %v", child) } | |
| 147 | - | called := false; child.OnRelease(func(){ called = true }) | |
| 148 | - | frame = frame[:8]; binary.LittleEndian.PutUint32(frame, child.ID()); binary.LittleEndian.PutUint32(frame[4:], 8<<16) | |
| 149 | - | if _, err := p.Write(frame); err != nil { t.Fatal(err) } | |
| 150 | - | if err := d.Dispatch(); err != nil { t.Fatal(err) } | |
| 151 | - | if !called { t.Fatal("typed child did not dispatch release") } | |
| 152 | - | } | |
| 153 | - | ` | |
| 154 | - | if err := os.WriteFile(filepath.Join(dir, "ext_test.go"), []byte(test), 0600); err != nil { | |
| 155 | - | t.Fatal(err) | |
| 156 | - | } | |
| 157 | - | cmd := exec.Command(goBin, "test", "./...") | |
| 158 | - | cmd.Dir = dir | |
| 159 | - | cmd.Env = append(os.Environ(), "GOWORK=off", "GOFLAGS=-mod=mod") | |
| 160 | - | if out, err := cmd.CombinedOutput(); err != nil { | |
| 161 | - | t.Fatalf("generated extension test: %v\n%s", err, out) | |
| 162 | - | } | |
| 163 | - | } | |
D internal/scanner/sources_test.go +0 -71
| @@ -1,71 +0,0 @@ | |||
| 1 | - | package scanner | |
| 2 | - | ||
| 3 | - | import ( | |
| 4 | - | "crypto/sha256" | |
| 5 | - | "fmt" | |
| 6 | - | "os" | |
| 7 | - | "path/filepath" | |
| 8 | - | "regexp" | |
| 9 | - | "strings" | |
| 10 | - | "testing" | |
| 11 | - | ) | |
| 12 | - | ||
| 13 | - | func TestProtocolSourceChecksums(t *testing.T) { | |
| 14 | - | root := filepath.Join("..", "..", "protocol") | |
| 15 | - | content, err := os.ReadFile(filepath.Join(root, "SOURCE.md")) | |
| 16 | - | if err != nil { | |
| 17 | - | t.Fatal(err) | |
| 18 | - | } | |
| 19 | - | coreChecksum := regexp.MustCompile("(?m)^SHA-256: `([a-f0-9]{64})`\\.").FindSubmatch(content) | |
| 20 | - | if coreChecksum == nil { | |
| 21 | - | t.Fatal("core protocol source checksum is missing") | |
| 22 | - | } | |
| 23 | - | // Extension tables record upstream path, vendored path and SHA-256. | |
| 24 | - | rows := regexp.MustCompile("(?m)^\\| `[^`]+` \\| `([^`]+)` \\| `([a-f0-9]{64})` \\|$").FindAllSubmatch(content, -1) | |
| 25 | - | if len(rows) == 0 { | |
| 26 | - | t.Fatal("no protocol source checksums found") | |
| 27 | - | } | |
| 28 | - | rows = append(rows, [][]byte{nil, []byte("wayland.xml"), coreChecksum[1]}) | |
| 29 | - | recorded := make(map[string]bool) | |
| 30 | - | for _, row := range rows { | |
| 31 | - | path, want := string(row[1]), string(row[2]) | |
| 32 | - | if !filepath.IsLocal(path) { | |
| 33 | - | t.Fatalf("source path must be repository-relative: %q", path) | |
| 34 | - | } | |
| 35 | - | if recorded[path] { | |
| 36 | - | t.Fatalf("duplicate source record: %s", path) | |
| 37 | - | } | |
| 38 | - | recorded[path] = true | |
| 39 | - | t.Run(path, func(t *testing.T) { | |
| 40 | - | data, err := os.ReadFile(filepath.Join(root, path)) | |
| 41 | - | if err != nil { | |
| 42 | - | t.Fatal(err) | |
| 43 | - | } | |
| 44 | - | if got := fmt.Sprintf("%x", sha256.Sum256(data)); got != want { | |
| 45 | - | t.Fatalf("SHA-256 %s, recorded %s", got, want) | |
| 46 | - | } | |
| 47 | - | if !strings.Contains(string(data), "<copyright>") { | |
| 48 | - | t.Fatal("vendored XML is missing upstream copyright/license") | |
| 49 | - | } | |
| 50 | - | }) | |
| 51 | - | } | |
| 52 | - | err = filepath.WalkDir(root, func(path string, entry os.DirEntry, err error) error { | |
| 53 | - | if err != nil { | |
| 54 | - | return err | |
| 55 | - | } | |
| 56 | - | if entry.IsDir() || filepath.Ext(path) != ".xml" { | |
| 57 | - | return nil | |
| 58 | - | } | |
| 59 | - | rel, err := filepath.Rel(root, path) | |
| 60 | - | if err != nil { | |
| 61 | - | return err | |
| 62 | - | } | |
| 63 | - | if !recorded[filepath.ToSlash(rel)] { | |
| 64 | - | t.Errorf("%s has no source/checksum record", rel) | |
| 65 | - | } | |
| 66 | - | return nil | |
| 67 | - | }) | |
| 68 | - | if err != nil { | |
| 69 | - | t.Fatal(err) | |
| 70 | - | } | |
| 71 | - | } | |
D internal/scanner/template.go +0 -140
| @@ -1,140 +0,0 @@ | |||
| 1 | - | package scanner | |
| 2 | - | ||
| 3 | - | // protocolTemplate is the template for generating WLTurbo-backed Go bindings. | |
| 4 | - | // | |
| 5 | - | // Generated objects embed wl.BaseProxy, send every request through | |
| 6 | - | // wl.Context.RequestArgs (typed arguments, no interface boxing; it owns | |
| 7 | - | // version checks, child registration and FD cleanup), and dispatch typed | |
| 8 | - | // events to registered handlers. Nothing in the generated code opens a | |
| 9 | - | // socket or frames messages itself: that is the transport's job. | |
| 10 | - | const protocolTemplate = `// Code generated by wlturbo-scanner. DO NOT EDIT. | |
| 11 | - | // Protocol: {{.Protocol}} | |
| 12 | - | // Source: {{.Source}} | |
| 13 | - | {{if .Copyright}} | |
| 14 | - | // Upstream protocol copyright and license: | |
| 15 | - | {{.Copyright}}{{end}} | |
| 16 | - | package {{.Package}} | |
| 17 | - | ||
| 18 | - | {{.ImportBlock}} | |
| 19 | - | ||
| 20 | - | {{range .Constants}} | |
| 21 | - | // {{.Name}} is the {{.Enum}} {{.Entry}} value. | |
| 22 | - | const {{.Name}}{{if .Type}} {{.Type}}{{end}} = {{.Value}} | |
| 23 | - | {{- end}} | |
| 24 | - | {{range .Interfaces}} | |
| 25 | - | {{- $iface := .}} | |
| 26 | - | ||
| 27 | - | // {{$iface.GoName}}Interface is the protocol interface name. | |
| 28 | - | const {{$iface.GoName}}Interface = "{{$iface.Name}}" | |
| 29 | - | ||
| 30 | - | // {{$iface.GoName}} is the generated binding for {{$iface.Name}} version {{$iface.Version}}. | |
| 31 | - | type {{$iface.GoName}} struct { | |
| 32 | - | wl.BaseProxy | |
| 33 | - | {{- if $iface.HasEvents}} | |
| 34 | - | // handlersMu guards the handler slices: a client may register or replace | |
| 35 | - | // handlers while another goroutine dispatches events. | |
| 36 | - | handlersMu sync.Mutex | |
| 37 | - | {{- end}} | |
| 38 | - | {{- range $iface.Events}} | |
| 39 | - | {{.HandlerField}} []func({{.HandlerParams}}) | |
| 40 | - | {{- end}} | |
| 41 | - | } | |
| 42 | - | ||
| 43 | - | // New{{$iface.GoName}} returns an unbound {{$iface.GoName}}. | |
| 44 | - | func New{{$iface.GoName}}(ctx *wl.Context) *{{$iface.GoName}} { | |
| 45 | - | obj := &{{$iface.GoName}}{} | |
| 46 | - | obj.SetContext(ctx) | |
| 47 | - | ctx.Register(obj) | |
| 48 | - | return obj | |
| 49 | - | } | |
| 50 | - | {{- range $iface.Requests}} | |
| 51 | - | ||
| 52 | - | {{- if .Doc}} | |
| 53 | - | // {{.Doc}} | |
| 54 | - | {{- end}} | |
| 55 | - | func (o *{{$iface.GoName}}) {{.GoName}}({{.Params}}) {{.Results}} { | |
| 56 | - | {{- range .ArgPreparations}} | |
| 57 | - | {{.}} | |
| 58 | - | {{- end}} | |
| 59 | - | {{- if .CreatesChild}} | |
| 60 | - | {{- if .ChildFactory}} | |
| 61 | - | {{.ChildVar}} := {{.ChildFactory}}(o.Context()) | |
| 62 | - | {{- else}} | |
| 63 | - | {{.ChildVar}} := &{{.ChildType}}{} | |
| 64 | - | {{.ChildVar}}.SetContext(o.Context()) | |
| 65 | - | {{- end}} | |
| 66 | - | {{- end}} | |
| 67 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: {{.Opcode}}, Name: "{{$iface.Name}}.{{.Name}}" | |
| 68 | - | {{- if gt .Since 1}}, Since: {{.Since}}{{end}} | |
| 69 | - | {{- if .Destructor}}, Destructor: true{{end}} | |
| 70 | - | {{- if .CreatesChild}}, Child: {{.ChildVar}}{{end}} | |
| 71 | - | {{- if .HasFDs}}, FDs: []int{ {{- .FDList -}} }{{end}}}{{.ArgList}}); err != nil { | |
| 72 | - | return {{.ErrorReturn}} | |
| 73 | - | } | |
| 74 | - | {{- if .CreatesChild}} | |
| 75 | - | return {{.ChildVar}}, nil | |
| 76 | - | {{- else}} | |
| 77 | - | return nil | |
| 78 | - | {{- end}} | |
| 79 | - | } | |
| 80 | - | {{- end}} | |
| 81 | - | {{- range $iface.Events}} | |
| 82 | - | ||
| 83 | - | // On{{.GoName}} registers a handler for the {{.Name}} event. | |
| 84 | - | // | |
| 85 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 86 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 87 | - | func (o *{{$iface.GoName}}) On{{.GoName}}(handler func({{.HandlerParams}})) { | |
| 88 | - | if handler == nil { return } | |
| 89 | - | o.handlersMu.Lock() | |
| 90 | - | defer o.handlersMu.Unlock() | |
| 91 | - | o.{{.HandlerField}} = append(o.{{.HandlerField}}, handler) | |
| 92 | - | } | |
| 93 | - | ||
| 94 | - | // {{.HandlerAccessor}} returns the handlers registered for {{.Name}}, taken | |
| 95 | - | // under the lock so a handler may register another handler while events are | |
| 96 | - | // being dispatched. | |
| 97 | - | func (o *{{$iface.GoName}}) {{.HandlerAccessor}}() []func({{.HandlerParams}}) { | |
| 98 | - | o.handlersMu.Lock() | |
| 99 | - | defer o.handlersMu.Unlock() | |
| 100 | - | return o.{{.HandlerField}} | |
| 101 | - | } | |
| 102 | - | {{- end}} | |
| 103 | - | ||
| 104 | - | // EventSignature returns the declared event argument types in wire order. | |
| 105 | - | func (o *{{$iface.GoName}}) EventSignature(opcode uint16) (string, bool) { | |
| 106 | - | switch opcode { | |
| 107 | - | {{- range $iface.SignatureCases}} | |
| 108 | - | case {{.Opcode}}: return "{{.Signature}}", true | |
| 109 | - | {{- end}} | |
| 110 | - | default: return "", false | |
| 111 | - | } | |
| 112 | - | } | |
| 113 | - | ||
| 114 | - | // Dispatch decodes one event on {{$iface.Name}} and calls the registered handlers. | |
| 115 | - | func (o *{{$iface.GoName}}) Dispatch(event *wl.Event) { | |
| 116 | - | switch event.Opcode { | |
| 117 | - | {{- range $iface.Events}} | |
| 118 | - | case {{.Opcode}}: // {{.Name}} | |
| 119 | - | {{- range .DecodeLines}} | |
| 120 | - | {{.}} | |
| 121 | - | {{- end}} | |
| 122 | - | {{if .HasFD}}{{range .FDNames}}owned{{.}} := {{.}}; defer owned{{.}}.Close() | |
| 123 | - | {{end}}{{end}} | |
| 124 | - | for i, handler := range o.{{.HandlerAccessor}}() { | |
| 125 | - | {{- if .HasFD}} | |
| 126 | - | if i > 0 { {{range .FDNames}}{{.}} = nil; {{end}} } | |
| 127 | - | {{- else}} | |
| 128 | - | _ = i | |
| 129 | - | {{- end}} | |
| 130 | - | handler({{.HandlerArgs}}) | |
| 131 | - | } | |
| 132 | - | {{- if .ServerDestroy}} | |
| 133 | - | o.Context().Unregister(o) | |
| 134 | - | {{- end}} | |
| 135 | - | {{- end}} | |
| 136 | - | default: | |
| 137 | - | } | |
| 138 | - | } | |
| 139 | - | {{end}} | |
| 140 | - | ` | |
D internal/scanner/testdata/protocol_fixture.xml +0 -112
| @@ -1,112 +0,0 @@ | |||
| 1 | - | <?xml version="1.0" encoding="UTF-8"?> | |
| 2 | - | <protocol name="wlvision_fixture"> | |
| 3 | - | <copyright> | |
| 4 | - | Synthetic protocol used to test the wlvision protocol generator. It exists | |
| 5 | - | only in this repository's tests. | |
| 6 | - | </copyright> | |
| 7 | - | ||
| 8 | - | <interface name="zwlr_fixture_manager_v1" version="2"> | |
| 9 | - | <description summary="fixture manager"> | |
| 10 | - | Exercises new_id requests, object references, fixed point numbers, | |
| 11 | - | strings, arrays, file descriptors and destructors. | |
| 12 | - | </description> | |
| 13 | - | ||
| 14 | - | <request name="create_thing"> | |
| 15 | - | <description summary="create a fixture object"/> | |
| 16 | - | <arg name="seat" type="object" interface="wl_seat"/> | |
| 17 | - | <arg name="id" type="new_id" interface="zwlr_fixture_thing_v1"/> | |
| 18 | - | </request> | |
| 19 | - | ||
| 20 | - | <request name="set_ratio"> | |
| 21 | - | <arg name="ratio" type="fixed"/> | |
| 22 | - | </request> | |
| 23 | - | ||
| 24 | - | <request name="set_label"> | |
| 25 | - | <arg name="label" type="string"/> | |
| 26 | - | </request> | |
| 27 | - | ||
| 28 | - | <request name="set_region"> | |
| 29 | - | <arg name="region" type="object" interface="wl_region"/> | |
| 30 | - | </request> | |
| 31 | - | ||
| 32 | - | <request name="set_buffer"> | |
| 33 | - | <description summary="reference an interface without a typed wrapper"/> | |
| 34 | - | <arg name="buffer" type="object" interface="wl_buffer"/> | |
| 35 | - | </request> | |
| 36 | - | ||
| 37 | - | <request name="set_optional_output"> | |
| 38 | - | <arg name="output" type="object" interface="wl_output" allow-null="true"/> | |
| 39 | - | </request> | |
| 40 | - | ||
| 41 | - | <request name="attach_raw"> | |
| 42 | - | <arg name="data" type="array"/> | |
| 43 | - | </request> | |
| 44 | - | ||
| 45 | - | <request name="pass_fd"> | |
| 46 | - | <arg name="fd" type="fd"/> | |
| 47 | - | </request> | |
| 48 | - | ||
| 49 | - | <request name="destroy" type="destructor"> | |
| 50 | - | <description summary="destroy the manager"/> | |
| 51 | - | </request> | |
| 52 | - | ||
| 53 | - | <request name="create_labeled_thing"> | |
| 54 | - | <description summary="new_id argument that is not the last one"/> | |
| 55 | - | <arg name="id" type="new_id" interface="zwlr_fixture_thing_v1"/> | |
| 56 | - | <arg name="label" type="string"/> | |
| 57 | - | <arg name="ratio" type="fixed"/> | |
| 58 | - | </request> | |
| 59 | - | </interface> | |
| 60 | - | ||
| 61 | - | <interface name="zwlr_fixture_thing_v1" version="1"> | |
| 62 | - | <description summary="fixture object"/> | |
| 63 | - | ||
| 64 | - | <enum name="fixture_state"> | |
| 65 | - | <entry name="idle" value="0"/> | |
| 66 | - | <entry name="busy" value="1"/> | |
| 67 | - | </enum> | |
| 68 | - | ||
| 69 | - | <request name="set_scale"> | |
| 70 | - | <arg name="scale" type="fixed"/> | |
| 71 | - | </request> | |
| 72 | - | ||
| 73 | - | <request name="destroy" type="destructor"/> | |
| 74 | - | ||
| 75 | - | <event name="ready"> | |
| 76 | - | <arg name="serial" type="uint"/> | |
| 77 | - | </event> | |
| 78 | - | ||
| 79 | - | <event name="label_changed"> | |
| 80 | - | <arg name="label" type="string"/> | |
| 81 | - | </event> | |
| 82 | - | ||
| 83 | - | <event name="geometry"> | |
| 84 | - | <arg name="x" type="int"/> | |
| 85 | - | <arg name="y" type="int"/> | |
| 86 | - | <arg name="width" type="uint"/> | |
| 87 | - | <arg name="height" type="uint"/> | |
| 88 | - | </event> | |
| 89 | - | ||
| 90 | - | <event name="mode"> | |
| 91 | - | <arg name="mode" type="new_id" interface="zwlr_fixture_mode_v1"/> | |
| 92 | - | </event> | |
| 93 | - | ||
| 94 | - | <event name="peer"> | |
| 95 | - | <arg name="surface" type="object" interface="wl_surface"/> | |
| 96 | - | </event> | |
| 97 | - | ||
| 98 | - | <event name="scaled"> | |
| 99 | - | <arg name="scale" type="fixed"/> | |
| 100 | - | </event> | |
| 101 | - | ||
| 102 | - | <event name="blob"> | |
| 103 | - | <arg name="data" type="array"/> | |
| 104 | - | </event> | |
| 105 | - | </interface> | |
| 106 | - | ||
| 107 | - | <interface name="zwlr_fixture_mode_v1" version="1"> | |
| 108 | - | <description summary="fixture mode object"/> | |
| 109 | - | ||
| 110 | - | <request name="destroy" type="destructor"/> | |
| 111 | - | </interface> | |
| 112 | - | </protocol> | |
D protocol/SOURCE.md +0 -94
| @@ -1,94 +0,0 @@ | |||
| 1 | - | # Core protocol source | |
| 2 | - | ||
| 3 | - | `wayland.xml` is from Wayland 1.26.0, upstream GitLab | |
| 4 | - | `https://gitlab.freedesktop.org/wayland/wayland`, tag `1.26.0`, peeled commit | |
| 5 | - | `87cc8a8728a923fc57938faa81ba0e74f34ecdc7`. | |
| 6 | - | SHA-256: `cc860987e54f8d85c940e97fa1270c69b6e4ad31fbcf5a7f00107ce1157f5e07`. | |
| 7 | - | License: MIT (full copyright and grant in `wayland.xml` `<copyright>`). | |
| 8 | - | ||
| 9 | - | ## wayland-protocols extensions | |
| 10 | - | ||
| 11 | - | The following XML files come from `https://gitlab.freedesktop.org/wayland/wayland-protocols`, | |
| 12 | - | tag `1.49` (peeled commit `ee78491a237eaff9389a0ccf8680521d074407d3`). | |
| 13 | - | Each XML retains its upstream `<copyright>` and license grant; consult the file for its exact terms. | |
| 14 | - | SHA-256 (of the vendored XML bytes): | |
| 15 | - | ||
| 16 | - | | Upstream path (under tag 1.49) | Vendored path | SHA-256 | | |
| 17 | - | |---|---|---| | |
| 18 | - | | `stable/xdg-shell/xdg-shell.xml` | `xdgshell/xdg-shell.xml` | `7ba7f9c8473deee674cb1f154a18abd0bb0cc072604fc055b0c15e459fc4c7df` | | |
| 19 | - | | `stable/linux-dmabuf/linux-dmabuf-v1.xml` | `linuxdmabuf/linux-dmabuf-v1.xml` | `2735bb4589cbb364dfcb6a821dd3abbf0c0257956b716b9691718ddfd453df4c` | | |
| 20 | - | | `staging/linux-drm-syncobj/linux-drm-syncobj-v1.xml` | `drmsyncobj/linux-drm-syncobj-v1.xml` | `5ede41a56eced6aa635caa7ab2996066bff9fd211620dbf9f73aafab740bec71` | | |
| 21 | - | | `stable/viewporter/viewporter.xml` | `viewporter/viewporter.xml` | `dcb12279a03746301fe490aaed4b38a403485a925abfce2ccfceb644e104fe71` | | |
| 22 | - | | `staging/fractional-scale/fractional-scale-v1.xml` | `fractionalscale/fractional-scale-v1.xml` | `5941de5d28f427ecdadddc8623a6f6af0a30b0ab4726847236ba7a7652b81316` | | |
| 23 | - | | `unstable/text-input/text-input-unstable-v3.xml` | `textinput/text-input-unstable-v3.xml` | `160815cda13c285a30df1971d8f0a5b3aac07071537df59916d2f748b18e4f59` | | |
| 24 | - | | `staging/cursor-shape/cursor-shape-v1.xml` | `cursorshape/cursor-shape-v1.xml` | `bb57d91e53a79dadab7c612dab87c233393cee73673feefa7442cfbfdd9aed2f` | | |
| 25 | - | | `stable/tablet/tablet-v2.xml` | `tablet/tablet-v2.xml` | `ac1128b26c779cf90b9ed71182ba5e34a7262826789adae206d825a4d45908b4` | | |
| 26 | - | | `staging/alpha-modifier/alpha-modifier-v1.xml` | `alphamodifier/alpha-modifier-v1.xml` | `f0b4a43b9e48783fafdb46319fa72b34a41afd932f8613d7cadaf7203f2ffa35` | | |
| 27 | - | | `staging/color-management/color-management-v1.xml` | `colormanagement/color-management-v1.xml` | `18a2678e3352c3be3fbeed20005d48852b7235d0d78f08b9c987a0b8e91449f9` | | |
| 28 | - | | `staging/color-representation/color-representation-v1.xml` | `colorrepresentation/color-representation-v1.xml` | `b824688e0e5c1d01e12afe1d3f82503092ec7599affcd6471fda6d296d4f7e3b` | | |
| 29 | - | | `staging/commit-timing/commit-timing-v1.xml` | `committiming/commit-timing-v1.xml` | `ff3fcf31d13d44bad756a50fda663a43008bacbbd2bf8cba3a1bf5ffe7f54172` | | |
| 30 | - | | `staging/content-type/content-type-v1.xml` | `contenttype/content-type-v1.xml` | `203d17a26baa2ab4a8c2c9cb737c953fa3263c73a0a8aa6e552a41b3eac2196d` | | |
| 31 | - | | `staging/ext-data-control/ext-data-control-v1.xml` | `datacontrol/ext-data-control-v1.xml` | `293deba5dfdb974fbcf8dcf891a30a51a36a8bba0047dc6bdf6a03194089b7fb` | | |
| 32 | - | | `staging/drm-lease/drm-lease-v1.xml` | `drmlease/drm-lease-v1.xml` | `18f325e92285473eca0567ea1038abb16849b8638b36e458ff551f3ca68ef80c` | | |
| 33 | - | | `staging/ext-foreign-toplevel-list/ext-foreign-toplevel-list-v1.xml` | `extforeigntoplevel/ext-foreign-toplevel-list-v1.xml` | `6b2ffb3a07d679d1c4170263adfefb9a7c37dd34ed3db5180bf58cb8ff8fbd0b` | | |
| 34 | - | | `staging/fifo/fifo-v1.xml` | `fifo/fifo-v1.xml` | `0b6c31dfe6bca19b712745c9de7a4a398558cfa1087b1938e96fd3b10ffc1069` | | |
| 35 | - | | `unstable/idle-inhibit/idle-inhibit-unstable-v1.xml` | `idleinhibit/idle-inhibit-unstable-v1.xml` | `c2ac9f002c6669ca6c02eb9b587b8e9108e3ce6deab4a2de58b576f4f864ca38` | | |
| 36 | - | | `staging/ext-idle-notify/ext-idle-notify-v1.xml` | `idlenotify/ext-idle-notify-v1.xml` | `e56a9c22684e6b46655f7221b798328e304c1efc8f63f01241a1cf8c070f4c30` | | |
| 37 | - | | `staging/ext-image-capture-source/ext-image-capture-source-v1.xml` | `imagecapturesource/ext-image-capture-source-v1.xml` | `4ef41d15e4cdb9f550158391358ceec724a6708b43b7efedec03121a6bb8458d` | | |
| 38 | - | | `staging/ext-image-copy-capture/ext-image-copy-capture-v1.xml` | `imagecopycapture/ext-image-copy-capture-v1.xml` | `41a446653f788fabb404cab3168c0bd667c1ff4b54f1f0bb1e18810a1f47d73f` | | |
| 39 | - | | `staging/ext-session-lock/ext-session-lock-v1.xml` | `extsessionlock/ext-session-lock-v1.xml` | `a05df7d95c5e523e457037b3a149484e8064828cda66971f3c7caeb87d597a81` | | |
| 40 | - | | `unstable/pointer-constraints/pointer-constraints-unstable-v1.xml` | `pointerconstraints/pointer-constraints-unstable-v1.xml` | `f980fac900ba1dcfbbe97f588fc17b893926bd2b57624563653a1bfe4d035948` | | |
| 41 | - | | `staging/pointer-warp/pointer-warp-v1.xml` | `pointerwarp/pointer-warp-v1.xml` | `1389e89c68c6f6d231fd2dcda57fa9c75c5230d0ac1deffa8d80a7648e197e66` | | |
| 42 | - | | `stable/presentation-time/presentation-time.xml` | `presentation/presentation-time.xml` | `dffac93bcb2bb1d8c385e72b8a8c2c0d4d79a336866322f3ba886dce2b27b1e2` | | |
| 43 | - | | `unstable/primary-selection/primary-selection-unstable-v1.xml` | `primaryselection/primary-selection-unstable-v1.xml` | `d568482ba84df6e531698b1f531810860995ca24d69495427fe43aee6017f52c` | | |
| 44 | - | | `unstable/relative-pointer/relative-pointer-unstable-v1.xml` | `relativepointer/relative-pointer-unstable-v1.xml` | `ab4930dd3084f732b6fdd12ee6dbd0a112a758ed8a57b170366391dbeb1a22ff` | | |
| 45 | - | | `unstable/keyboard-shortcuts-inhibit/keyboard-shortcuts-inhibit-unstable-v1.xml` | `shortcutsinhibit/keyboard-shortcuts-inhibit-unstable-v1.xml` | `9117d9e8ec02e9a3c3c55803b41e1227e76986f555f7c12eeb29f796fa63e69b` | | |
| 46 | - | | `staging/tearing-control/tearing-control-v1.xml` | `tearingcontrol/tearing-control-v1.xml` | `846895b4a90ba1ddd75673cefc596480beef318f1694ec7dbca0fec54bb27043` | | |
| 47 | - | | `staging/ext-workspace/ext-workspace-v1.xml` | `workspace/ext-workspace-v1.xml` | `9b449d9d5d40f6032eba9813d18093b84f249a2cf38d6755dec7bca7eb96b0f3` | | |
| 48 | - | | `staging/xdg-activation/xdg-activation-v1.xml` | `xdgactivation/xdg-activation-v1.xml` | `d8418be2d5738d50aff788bef1c7574f33f26659aa045447ff2ef9b78c58fe01` | | |
| 49 | - | | `unstable/xdg-decoration/xdg-decoration-unstable-v1.xml` | `xdgdecoration/xdg-decoration-unstable-v1.xml` | `68753c4a85a28659e3aa1fe0f138329a8bf3dff0b4789f4663a2c7fedbfecf2f` | | |
| 50 | - | | `unstable/xdg-output/xdg-output-unstable-v1.xml` | `xdgoutput/xdg-output-unstable-v1.xml` | `363d547c3eefe8959160cac903ff90b311d4b183005557d73640d9df2cfd7f79` | | |
| 51 | - | ||
| 52 | - | ## wlr-protocols | |
| 53 | - | ||
| 54 | - | Source: `https://gitlab.freedesktop.org/wlroots/wlr-protocols`, commit | |
| 55 | - | `bf4fc79abc359eea5a0edec0ac6d4a2b2955f82a`. The XML files retain their upstream | |
| 56 | - | license grants, including the no-fee/no-advertising terms where applicable. | |
| 57 | - | ||
| 58 | - | | Upstream path | Vendored path | SHA-256 | | |
| 59 | - | |---|---|---| | |
| 60 | - | | `unstable/wlr-layer-shell-unstable-v1.xml` | `layershell/wlr-layer-shell-unstable-v1.xml` | `87e0b9c837aecd6977f76f3c47d73088b7159871f5d979dc1840f6cadb5e2ed8` | | |
| 61 | - | | `unstable/wlr-screencopy-unstable-v1.xml` | `screencopy/wlr-screencopy-unstable-v1.xml` | `131b8f9b4aad0c8a9cf705e90d2a1511a5ca0c477637fd3400cf1cc4fa963fb8` | | |
| 62 | - | | `unstable/wlr-foreign-toplevel-management-unstable-v1.xml` | `foreigntoplevel/wlr-foreign-toplevel-management-unstable-v1.xml` | `4ecc4588858e29fe680a33521e1f22bcf22071d66d1553fe96b4ddec03d591d2` | | |
| 63 | - | | `unstable/wlr-output-management-unstable-v1.xml` | `outputmanagement/wlr-output-management-unstable-v1.xml` | `65b0f82a6cf129bf1a1c31a2428795abd33886c15ddd5f3ad97e5922d7bdc3a7` | | |
| 64 | - | | `unstable/wlr-output-power-management-unstable-v1.xml` | `outputpower/wlr-output-power-management-unstable-v1.xml` | `7ebd98f3449d246a57829e4b4dd9fbc3ef98e3dd42fa94ea102f14f490eb20de` | | |
| 65 | - | ||
| 66 | - | ## wlroots input protocols | |
| 67 | - | ||
| 68 | - | Source: `https://gitlab.freedesktop.org/wlroots/wlroots`, tag `0.19.0`, peeled | |
| 69 | - | commit `13a62a23a258d96f902c740310d5c7c59784a4d1`. Both XML files retain their | |
| 70 | - | MIT-style license grants. | |
| 71 | - | ||
| 72 | - | | Upstream path | Vendored path | SHA-256 | | |
| 73 | - | |---|---|---| | |
| 74 | - | | `protocol/virtual-keyboard-unstable-v1.xml` | `virtualkeyboard/virtual-keyboard-unstable-v1.xml` | `7ad7870003ecd592cae47dc19d277a609b7f18fd7b7be012623cf3225a7294f5` | | |
| 75 | - | | `protocol/input-method-unstable-v2.xml` | `inputmethod/input-method-unstable-v2.xml` | `99414dbad9458e71aa1fa01bc45f94ca6685787bfcb4d98948f72c1b45b60703` | | |
| 76 | - | ||
| 77 | - | ## KDE server decoration | |
| 78 | - | ||
| 79 | - | Source: `https://invent.kde.org/libraries/plasma-wayland-protocols`, tag | |
| 80 | - | `v1.23.0`, peeled commit `c5ac4db818f4a575a6ccfe0065b73ecfaba6e93e`. | |
| 81 | - | The XML and its generated `kdeserverdecoration` bindings retain | |
| 82 | - | **LGPL-2.1-or-later**, including the copied protocol documentation. They are not | |
| 83 | - | relicensed under WLTurbo's MIT license. The [license text](../LICENSES/LGPL-2.1-or-later.txt) | |
| 84 | - | is included; generated files retain the upstream notice. | |
| 85 | - | ||
| 86 | - | | Upstream path | Vendored path | SHA-256 | | |
| 87 | - | |---|---|---| | |
| 88 | - | | `src/protocols/server-decoration.xml` | `kdeserverdecoration/server-decoration.xml` | `c5f857734bb190dc9adfb65fb05550a6245f12af1a2be5eefd05be199805a68c` | | |
| 89 | - | ||
| 90 | - | ## Cross-package types | |
| 91 | - | ||
| 92 | - | Cross-package references use canonical generated types. Cursor-shape depends on | |
| 93 | - | `tablet`; xdg-decoration and layer-shell depend on `xdgshell`; image-copy-capture | |
| 94 | - | depends on `imagecapturesource`, which depends on `extforeigntoplevel`. | |
D protocol/alphamodifier/alpha-modifier-v1.xml +0 -103
| @@ -1,103 +0,0 @@ | |||
| 1 | - | <?xml version="1.0" encoding="UTF-8"?> | |
| 2 | - | <protocol name="alpha_modifier_v1"> | |
| 3 | - | <copyright> | |
| 4 | - | Copyright © 2024 Xaver Hugl | |
| 5 | - | ||
| 6 | - | Permission is hereby granted, free of charge, to any person obtaining a | |
| 7 | - | copy of this software and associated documentation files (the "Software"), | |
| 8 | - | to deal in the Software without restriction, including without limitation | |
| 9 | - | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 10 | - | and/or sell copies of the Software, and to permit persons to whom the | |
| 11 | - | Software is furnished to do so, subject to the following conditions: | |
| 12 | - | ||
| 13 | - | The above copyright notice and this permission notice (including the next | |
| 14 | - | paragraph) shall be included in all copies or substantial portions of the | |
| 15 | - | Software. | |
| 16 | - | ||
| 17 | - | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 18 | - | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 19 | - | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 20 | - | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 21 | - | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 22 | - | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
| 23 | - | DEALINGS IN THE SOFTWARE. | |
| 24 | - | </copyright> | |
| 25 | - | ||
| 26 | - | <interface name="wp_alpha_modifier_v1" version="1"> | |
| 27 | - | <description summary="surface alpha modifier manager"> | |
| 28 | - | This interface allows a client to set a factor for the alpha values on a | |
| 29 | - | surface, which can be used to offload such operations to the compositor, | |
| 30 | - | which can in turn for example offload them to KMS. | |
| 31 | - | ||
| 32 | - | Warning! The protocol described in this file is currently in the testing | |
| 33 | - | phase. Backward compatible changes may be added together with the | |
| 34 | - | corresponding interface version bump. Backward incompatible changes can | |
| 35 | - | only be done by creating a new major version of the extension. | |
| 36 | - | </description> | |
| 37 | - | ||
| 38 | - | <request name="destroy" type="destructor"> | |
| 39 | - | <description summary="destroy the alpha modifier manager object"> | |
| 40 | - | Destroy the alpha modifier manager. This doesn't destroy objects | |
| 41 | - | created with the manager. | |
| 42 | - | </description> | |
| 43 | - | </request> | |
| 44 | - | ||
| 45 | - | <enum name="error"> | |
| 46 | - | <entry name="already_constructed" value="0" | |
| 47 | - | summary="wl_surface already has a alpha modifier object"/> | |
| 48 | - | </enum> | |
| 49 | - | ||
| 50 | - | <request name="get_surface"> | |
| 51 | - | <description summary="create a new alpha modifier surface object"> | |
| 52 | - | Create a new alpha modifier surface object associated with the | |
| 53 | - | given wl_surface. If there is already such an object associated with | |
| 54 | - | the wl_surface, the already_constructed error will be raised. | |
| 55 | - | </description> | |
| 56 | - | <arg name="id" type="new_id" interface="wp_alpha_modifier_surface_v1"/> | |
| 57 | - | <arg name="surface" type="object" interface="wl_surface"/> | |
| 58 | - | </request> | |
| 59 | - | </interface> | |
| 60 | - | ||
| 61 | - | <interface name="wp_alpha_modifier_surface_v1" version="1"> | |
| 62 | - | <description summary="alpha modifier object for a surface"> | |
| 63 | - | This interface allows the client to set a factor for the alpha values on | |
| 64 | - | a surface, which can be used to offload such operations to the compositor. | |
| 65 | - | The default factor is UINT32_MAX. | |
| 66 | - | ||
| 67 | - | This object has to be destroyed before the associated wl_surface. Once the | |
| 68 | - | wl_surface is destroyed, all request on this object will raise the | |
| 69 | - | no_surface error. | |
| 70 | - | </description> | |
| 71 | - | ||
| 72 | - | <enum name="error"> | |
| 73 | - | <entry name="no_surface" value="0" summary="wl_surface was destroyed"/> | |
| 74 | - | </enum> | |
| 75 | - | ||
| 76 | - | <request name="destroy" type="destructor"> | |
| 77 | - | <description summary="destroy the alpha modifier object"> | |
| 78 | - | This destroys the object, and is equivalent to set_multiplier with | |
| 79 | - | a value of UINT32_MAX, with the same double-buffered semantics as | |
| 80 | - | set_multiplier. | |
| 81 | - | </description> | |
| 82 | - | </request> | |
| 83 | - | ||
| 84 | - | <request name="set_multiplier"> | |
| 85 | - | <description summary="specify the alpha multiplier"> | |
| 86 | - | Sets the alpha multiplier for the surface. The alpha multiplier is | |
| 87 | - | double-buffered state, see wl_surface.commit for details. | |
| 88 | - | ||
| 89 | - | This factor is applied in the compositor's blending space, as an | |
| 90 | - | additional step after the processing of per-pixel alpha values for the | |
| 91 | - | wl_surface. The exact meaning of the factor is thus undefined, unless | |
| 92 | - | the blending space is specified in a different extension. | |
| 93 | - | ||
| 94 | - | This multiplier is applied even if the buffer attached to the | |
| 95 | - | wl_surface doesn't have an alpha channel; in that case an alpha value | |
| 96 | - | of one is used instead. | |
| 97 | - | ||
| 98 | - | Zero means completely transparent, UINT32_MAX means completely opaque. | |
| 99 | - | </description> | |
| 100 | - | <arg name="factor" type="uint"/> | |
| 101 | - | </request> | |
| 102 | - | </interface> | |
| 103 | - | </protocol> | |
D protocol/alphamodifier/alpha-modifier-v1_generated.go +0 -138
| @@ -1,138 +0,0 @@ | |||
| 1 | - | // Code generated by wlturbo-scanner. DO NOT EDIT. | |
| 2 | - | // Protocol: alpha_modifier_v1 | |
| 3 | - | // Source: alpha-modifier-v1.xml | |
| 4 | - | ||
| 5 | - | // Upstream protocol copyright and license: | |
| 6 | - | // Copyright © 2024 Xaver Hugl | |
| 7 | - | // | |
| 8 | - | // Permission is hereby granted, free of charge, to any person obtaining a | |
| 9 | - | // copy of this software and associated documentation files (the "Software"), | |
| 10 | - | // to deal in the Software without restriction, including without limitation | |
| 11 | - | // the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 12 | - | // and/or sell copies of the Software, and to permit persons to whom the | |
| 13 | - | // Software is furnished to do so, subject to the following conditions: | |
| 14 | - | // | |
| 15 | - | // The above copyright notice and this permission notice (including the next | |
| 16 | - | // paragraph) shall be included in all copies or substantial portions of the | |
| 17 | - | // Software. | |
| 18 | - | // | |
| 19 | - | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 20 | - | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 21 | - | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 22 | - | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 23 | - | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 24 | - | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
| 25 | - | // DEALINGS IN THE SOFTWARE. | |
| 26 | - | ||
| 27 | - | package alphamodifier | |
| 28 | - | ||
| 29 | - | import ( | |
| 30 | - | cross_wl_surface "github.com/bnema/wlturbo/protocol/core" | |
| 31 | - | "github.com/bnema/wlturbo/wl" | |
| 32 | - | ) | |
| 33 | - | ||
| 34 | - | // ERROR_ALREADY_CONSTRUCTED is the error already_constructed value. | |
| 35 | - | const ERROR_ALREADY_CONSTRUCTED = 0 | |
| 36 | - | ||
| 37 | - | // ERROR_NO_SURFACE is the error no_surface value. | |
| 38 | - | const ERROR_NO_SURFACE = 0 | |
| 39 | - | ||
| 40 | - | // WpAlphaModifierInterface is the protocol interface name. | |
| 41 | - | const WpAlphaModifierInterface = "wp_alpha_modifier_v1" | |
| 42 | - | ||
| 43 | - | // WpAlphaModifier is the generated binding for wp_alpha_modifier_v1 version 1. | |
| 44 | - | type WpAlphaModifier struct { | |
| 45 | - | wl.BaseProxy | |
| 46 | - | } | |
| 47 | - | ||
| 48 | - | // NewWpAlphaModifier returns an unbound WpAlphaModifier. | |
| 49 | - | func NewWpAlphaModifier(ctx *wl.Context) *WpAlphaModifier { | |
| 50 | - | obj := &WpAlphaModifier{} | |
| 51 | - | obj.SetContext(ctx) | |
| 52 | - | ctx.Register(obj) | |
| 53 | - | return obj | |
| 54 | - | } | |
| 55 | - | ||
| 56 | - | // Destroy the alpha modifier manager. This doesn't destroy objects created with the manager. | |
| 57 | - | func (o *WpAlphaModifier) Destroy() error { | |
| 58 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "wp_alpha_modifier_v1.destroy", Destructor: true}); err != nil { | |
| 59 | - | return err | |
| 60 | - | } | |
| 61 | - | return nil | |
| 62 | - | } | |
| 63 | - | ||
| 64 | - | // Create a new alpha modifier surface object associated with the given wl_surface. If there is already such an object associated with the wl_surface, the already_constructed error will be raised. | |
| 65 | - | func (o *WpAlphaModifier) GetSurface(surface *cross_wl_surface.Surface) (*WpAlphaModifierSurface, error) { | |
| 66 | - | var arg1 wl.Object | |
| 67 | - | if surface != nil { | |
| 68 | - | arg1 = surface | |
| 69 | - | } | |
| 70 | - | child := &WpAlphaModifierSurface{} | |
| 71 | - | child.SetContext(o.Context()) | |
| 72 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "wp_alpha_modifier_v1.get_surface", Child: child}, wl.ArgObject(child), wl.ArgObject(arg1)); err != nil { | |
| 73 | - | return nil, err | |
| 74 | - | } | |
| 75 | - | return child, nil | |
| 76 | - | } | |
| 77 | - | ||
| 78 | - | // EventSignature returns the declared event argument types in wire order. | |
| 79 | - | func (o *WpAlphaModifier) EventSignature(opcode uint16) (string, bool) { | |
| 80 | - | switch opcode { | |
| 81 | - | default: | |
| 82 | - | return "", false | |
| 83 | - | } | |
| 84 | - | } | |
| 85 | - | ||
| 86 | - | // Dispatch decodes one event on wp_alpha_modifier_v1 and calls the registered handlers. | |
| 87 | - | func (o *WpAlphaModifier) Dispatch(event *wl.Event) { | |
| 88 | - | switch event.Opcode { | |
| 89 | - | default: | |
| 90 | - | } | |
| 91 | - | } | |
| 92 | - | ||
| 93 | - | // WpAlphaModifierSurfaceInterface is the protocol interface name. | |
| 94 | - | const WpAlphaModifierSurfaceInterface = "wp_alpha_modifier_surface_v1" | |
| 95 | - | ||
| 96 | - | // WpAlphaModifierSurface is the generated binding for wp_alpha_modifier_surface_v1 version 1. | |
| 97 | - | type WpAlphaModifierSurface struct { | |
| 98 | - | wl.BaseProxy | |
| 99 | - | } | |
| 100 | - | ||
| 101 | - | // NewWpAlphaModifierSurface returns an unbound WpAlphaModifierSurface. | |
| 102 | - | func NewWpAlphaModifierSurface(ctx *wl.Context) *WpAlphaModifierSurface { | |
| 103 | - | obj := &WpAlphaModifierSurface{} | |
| 104 | - | obj.SetContext(ctx) | |
| 105 | - | ctx.Register(obj) | |
| 106 | - | return obj | |
| 107 | - | } | |
| 108 | - | ||
| 109 | - | // This destroys the object, and is equivalent to set_multiplier with a value of UINT32_MAX, with the same double-buffered semantics as set_multiplier. | |
| 110 | - | func (o *WpAlphaModifierSurface) Destroy() error { | |
| 111 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "wp_alpha_modifier_surface_v1.destroy", Destructor: true}); err != nil { | |
| 112 | - | return err | |
| 113 | - | } | |
| 114 | - | return nil | |
| 115 | - | } | |
| 116 | - | ||
| 117 | - | // Sets the alpha multiplier for the surface. The alpha multiplier is double-buffered state, see wl_surface.commit for details. This factor is applied in the compositor's blending space, as an additional step after the processing of per-pixel alpha values for the wl_surface. The exact meaning of the factor is thus undefined, unless the blending space is specified in a different extension. This multiplier is applied even if the buffer attached to the wl_surface doesn't have an alpha channel; in that case an alpha value of one is used instead. Zero means completely transparent, UINT32_MAX means completely opaque. | |
| 118 | - | func (o *WpAlphaModifierSurface) SetMultiplier(factor uint32) error { | |
| 119 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "wp_alpha_modifier_surface_v1.set_multiplier"}, wl.ArgUint(factor)); err != nil { | |
| 120 | - | return err | |
| 121 | - | } | |
| 122 | - | return nil | |
| 123 | - | } | |
| 124 | - | ||
| 125 | - | // EventSignature returns the declared event argument types in wire order. | |
| 126 | - | func (o *WpAlphaModifierSurface) EventSignature(opcode uint16) (string, bool) { | |
| 127 | - | switch opcode { | |
| 128 | - | default: | |
| 129 | - | return "", false | |
| 130 | - | } | |
| 131 | - | } | |
| 132 | - | ||
| 133 | - | // Dispatch decodes one event on wp_alpha_modifier_surface_v1 and calls the registered handlers. | |
| 134 | - | func (o *WpAlphaModifierSurface) Dispatch(event *wl.Event) { | |
| 135 | - | switch event.Opcode { | |
| 136 | - | default: | |
| 137 | - | } | |
| 138 | - | } | |
D protocol/alphamodifier/generate.go +0 -3
| @@ -1,3 +0,0 @@ | |||
| 1 | - | package alphamodifier | |
| 2 | - | ||
| 3 | - | //go:generate go run ../../cmd/wlturbo-scanner -p alphamodifier -o alpha-modifier-v1_generated.go -import wl_surface=github.com/bnema/wlturbo/protocol/core alpha-modifier-v1.xml | |
D protocol/colormanagement/color-management-v1.xml +0 -1756
| @@ -1,1756 +0,0 @@ | |||
| 1 | - | <?xml version="1.0" encoding="UTF-8"?> | |
| 2 | - | <protocol name="color_management_v1"> | |
| 3 | - | <copyright> | |
| 4 | - | Copyright 2019 Sebastian Wick | |
| 5 | - | Copyright 2019 Erwin Burema | |
| 6 | - | Copyright 2020 AMD | |
| 7 | - | Copyright 2020-2024 Collabora, Ltd. | |
| 8 | - | Copyright 2024 Xaver Hugl | |
| 9 | - | Copyright 2022-2025 Red Hat, Inc. | |
| 10 | - | ||
| 11 | - | Permission is hereby granted, free of charge, to any person obtaining a | |
| 12 | - | copy of this software and associated documentation files (the "Software"), | |
| 13 | - | to deal in the Software without restriction, including without limitation | |
| 14 | - | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 15 | - | and/or sell copies of the Software, and to permit persons to whom the | |
| 16 | - | Software is furnished to do so, subject to the following conditions: | |
| 17 | - | ||
| 18 | - | The above copyright notice and this permission notice (including the next | |
| 19 | - | paragraph) shall be included in all copies or substantial portions of the | |
| 20 | - | Software. | |
| 21 | - | ||
| 22 | - | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 23 | - | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 24 | - | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 25 | - | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 26 | - | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 27 | - | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
| 28 | - | DEALINGS IN THE SOFTWARE. | |
| 29 | - | </copyright> | |
| 30 | - | ||
| 31 | - | <description summary="color management protocol"> | |
| 32 | - | The aim of the color management extension is to allow clients to know | |
| 33 | - | the color properties of outputs, and to tell the compositor about the color | |
| 34 | - | properties of their content on surfaces. All surface contents must be | |
| 35 | - | readily intended for some display, but not necessarily for the display at | |
| 36 | - | hand. Doing this enables a compositor to perform automatic color management | |
| 37 | - | of content for different outputs according to how content is intended to | |
| 38 | - | look like. | |
| 39 | - | ||
| 40 | - | For an introduction, see the section "Color management" in the Wayland | |
| 41 | - | documentation at https://wayland.freedesktop.org/docs/html/ . | |
| 42 | - | ||
| 43 | - | The color properties are represented as an image description object which | |
| 44 | - | is immutable after it has been created. A wl_output always has an | |
| 45 | - | associated image description that clients can observe. A wl_surface | |
| 46 | - | always has an associated preferred image description as a hint chosen by | |
| 47 | - | the compositor that clients can also observe. Clients can set an image | |
| 48 | - | description on a wl_surface to denote the color characteristics of the | |
| 49 | - | surface contents. | |
| 50 | - | ||
| 51 | - | An image description essentially defines a display and (indirectly) its | |
| 52 | - | viewing environment. An image description includes SDR and HDR colorimetry | |
| 53 | - | and encoding, HDR metadata, and some parameters related to the viewing | |
| 54 | - | environment. An image description does not include the properties set | |
| 55 | - | through color-representation extension. It is expected that the | |
| 56 | - | color-representation extension is used in conjunction with the | |
| 57 | - | color-management extension when necessary, particularly with the YUV family | |
| 58 | - | of pixel formats. | |
| 59 | - | ||
| 60 | - | The normative appendix for this protocol is in the appendix.md file beside | |
| 61 | - | this XML file. | |
| 62 | - | ||
| 63 | - | The color-and-hdr repository | |
| 64 | - | (https://gitlab.freedesktop.org/pq/color-and-hdr) contains | |
| 65 | - | background information on the protocol design and legacy color management. | |
| 66 | - | It also contains a glossary, learning resources for digital color, tools, | |
| 67 | - | samples and more. | |
| 68 | - | ||
| 69 | - | The terminology used in this protocol is based on common color science and | |
| 70 | - | color encoding terminology where possible. The glossary in the color-and-hdr | |
| 71 | - | repository shall be the authority on the definition of terms in this | |
| 72 | - | protocol. | |
| 73 | - | ||
| 74 | - | Warning! The protocol described in this file is currently in the testing | |
| 75 | - | phase. Backward compatible changes may be added together with the | |
| 76 | - | corresponding interface version bump. Backward incompatible changes can | |
| 77 | - | only be done by creating a new major version of the extension. | |
| 78 | - | </description> | |
| 79 | - | ||
| 80 | - | <interface name="wp_color_manager_v1" version="3"> | |
| 81 | - | <description summary="color manager singleton"> | |
| 82 | - | A singleton global interface used for getting color management extensions | |
| 83 | - | for wl_surface and wl_output objects, and for creating client defined | |
| 84 | - | image description objects. The extension interfaces allow | |
| 85 | - | getting the image description of outputs and setting the image | |
| 86 | - | description of surfaces. | |
| 87 | - | ||
| 88 | - | Compositors should never remove this global. | |
| 89 | - | </description> | |
| 90 | - | ||
| 91 | - | <request name="destroy" type="destructor"> | |
| 92 | - | <description summary="destroy the color manager"> | |
| 93 | - | Destroy the wp_color_manager_v1 object. This does not affect any other | |
| 94 | - | objects in any way. | |
| 95 | - | </description> | |
| 96 | - | </request> | |
| 97 | - | ||
| 98 | - | <enum name="error"> | |
| 99 | - | <entry name="unsupported_feature" value="0" | |
| 100 | - | summary="request not supported"/> | |
| 101 | - | <entry name="surface_exists" value="1" | |
| 102 | - | summary="color management surface exists already"/> | |
| 103 | - | </enum> | |
| 104 | - | ||
| 105 | - | <enum name="render_intent"> | |
| 106 | - | <description summary="rendering intents"> | |
| 107 | - | See the ICC.1:2022 specification from the International Color Consortium | |
| 108 | - | for more details about rendering intents. | |
| 109 | - | ||
| 110 | - | The principles of ICC defined rendering intents apply with all types of | |
| 111 | - | image descriptions, not only those with ICC file profiles. | |
| 112 | - | ||
| 113 | - | Compositors must support the perceptual rendering intent. Other | |
| 114 | - | rendering intents are optional. | |
| 115 | - | </description> | |
| 116 | - | ||
| 117 | - | <entry name="perceptual" value="0" | |
| 118 | - | summary="perceptual"/> | |
| 119 | - | <entry name="relative" value="1" | |
| 120 | - | summary="media-relative colorimetric"/> | |
| 121 | - | <entry name="saturation" value="2" | |
| 122 | - | summary="saturation"/> | |
| 123 | - | <entry name="absolute" value="3" | |
| 124 | - | summary="ICC-absolute colorimetric"/> | |
| 125 | - | <entry name="relative_bpc" value="4" | |
| 126 | - | summary="media-relative colorimetric + black point compensation"/> | |
| 127 | - | <entry name="absolute_no_adaptation" value="5" since="2"> | |
| 128 | - | <description summary="ICC-absolute colorimetric without adaptation"> | |
| 129 | - | This rendering intent is a modified absolute rendering intent that | |
| 130 | - | assumes the viewer is not adapted to the display white point, so no | |
| 131 | - | chromatic adaptation between surface and display is done. | |
| 132 | - | This can be useful for color proofing applications. | |
| 133 | - | </description> | |
| 134 | - | </entry> | |
| 135 | - | </enum> | |
| 136 | - | ||
| 137 | - | <enum name="feature"> | |
| 138 | - | <description summary="compositor supported features"/> | |
| 139 | - | ||
| 140 | - | <entry name="icc_v2_v4" value="0" | |
| 141 | - | summary="create_icc_creator request"/> | |
| 142 | - | <entry name="parametric" value="1" | |
| 143 | - | summary="create_parametric_creator request"/> | |
| 144 | - | <entry name="set_primaries" value="2" | |
| 145 | - | summary="parametric set_primaries request"/> | |
| 146 | - | <entry name="set_tf_power" value="3" | |
| 147 | - | summary="parametric set_tf_power request"/> | |
| 148 | - | <entry name="set_luminances" value="4" | |
| 149 | - | summary="parametric set_luminances request"/> | |
| 150 | - | <entry name="set_mastering_display_primaries" value="5"> | |
| 151 | - | <description summary="parametric set_mastering_display_primaries request"> | |
| 152 | - | The compositor supports set_mastering_display_primaries request with a | |
| 153 | - | target color volume fully contained inside the primary color volume. | |
| 154 | - | </description> | |
| 155 | - | </entry> | |
| 156 | - | <entry name="extended_target_volume" value="6"> | |
| 157 | - | <description summary="parametric target exceeds primary color volume"> | |
| 158 | - | The compositor additionally supports target color volumes that | |
| 159 | - | extend outside of the primary color volume. | |
| 160 | - | ||
| 161 | - | This can only be advertised if feature set_mastering_display_primaries | |
| 162 | - | is supported as well. | |
| 163 | - | </description> | |
| 164 | - | </entry> | |
| 165 | - | <entry name="windows_scrgb" value="7" | |
| 166 | - | summary="create_windows_scrgb request"/> | |
| 167 | - | <entry name="windows_bt2100" value="8" | |
| 168 | - | summary="create_windows_bt2100 request"/> | |
| 169 | - | </enum> | |
| 170 | - | ||
| 171 | - | <enum name="primaries"> | |
| 172 | - | <description summary="named color primaries"> | |
| 173 | - | Named color primaries used to encode well-known sets of primaries. | |
| 174 | - | ||
| 175 | - | A value of 0 is invalid and will never be present in the list of enums. | |
| 176 | - | </description> | |
| 177 | - | ||
| 178 | - | <entry name="srgb" value="1"> | |
| 179 | - | <description summary="Color primaries for the sRGB color space as defined by the BT.709 standard"> | |
| 180 | - | Color primaries as defined by | |
| 181 | - | - Rec. ITU-R BT.709-6 | |
| 182 | - | - Rec. ITU-R BT.1361-0 conventional colour gamut system and extended | |
| 183 | - | colour gamut system (historical) | |
| 184 | - | - IEC 61966-2-1 sRGB or sYCC | |
| 185 | - | - IEC 61966-2-4 | |
| 186 | - | - Society of Motion Picture and Television Engineers (SMPTE) RP 177 | |
| 187 | - | (1993) Annex B | |
| 188 | - | </description> | |
| 189 | - | </entry> | |
| 190 | - | <entry name="pal_m" value="2"> | |
| 191 | - | <description summary="Color primaries for PAL-M as defined by the BT.470 standard"> | |
| 192 | - | Color primaries as defined by | |
| 193 | - | - Rec. ITU-R BT.470-6 System M (historical) | |
| 194 | - | - United States National Television System Committee 1953 | |
| 195 | - | Recommendation for transmission standards for color television | |
| 196 | - | - United States Federal Communications Commission (2003) Title 47 Code | |
| 197 | - | of Federal Regulations 73.682 (a)(20) | |
| 198 | - | </description> | |
| 199 | - | </entry> | |
| 200 | - | <entry name="pal" value="3"> | |
| 201 | - | <description summary="Color primaries for PAL as defined by the BT.601 standard"> | |
| 202 | - | Color primaries as defined by | |
| 203 | - | - Rec. ITU-R BT.470-6 System B, G (historical) | |
| 204 | - | - Rec. ITU-R BT.601-7 625 | |
| 205 | - | - Rec. ITU-R BT.1358-0 625 (historical) | |
| 206 | - | - Rec. ITU-R BT.1700-0 625 PAL and 625 SECAM | |
| 207 | - | </description> | |
| 208 | - | </entry> | |
| 209 | - | <entry name="ntsc" value="4"> | |
| 210 | - | <description summary="Color primaries for NTSC as defined by the BT.601 standard"> | |
| 211 | - | Color primaries as defined by | |
| 212 | - | - Rec. ITU-R BT.601-7 525 | |
| 213 | - | - Rec. ITU-R BT.1358-1 525 or 625 (historical) | |
| 214 | - | - Rec. ITU-R BT.1700-0 NTSC | |
| 215 | - | - SMPTE 170M (2004) | |
| 216 | - | - SMPTE 240M (1999) (historical) | |
| 217 | - | </description> | |
| 218 | - | </entry> | |
| 219 | - | <entry name="generic_film" value="5"> | |
| 220 | - | <description summary="Generic film with colour filters using Illuminant C"> | |
| 221 | - | Color primaries as defined by Recommendation ITU-T H.273 | |
| 222 | - | "Coding-independent code points for video signal type identification" | |
| 223 | - | for "generic film". | |
| 224 | - | </description> | |
| 225 | - | </entry> | |
| 226 | - | <entry name="bt2020" value="6"> | |
| 227 | - | <description summary="Color primaries as defined by the BT.2020 and BT.2100 standard"> | |
| 228 | - | Color primaries as defined by | |
| 229 | - | - Rec. ITU-R BT.2020-2 | |
| 230 | - | - Rec. ITU-R BT.2100-0 | |
| 231 | - | </description> | |
| 232 | - | </entry> | |
| 233 | - | <entry name="cie1931_xyz" value="7"> | |
| 234 | - | <description summary="Color primaries of the full CIE 1931 XYZ color space"> | |
| 235 | - | Color primaries as defined as the maximum of the CIE 1931 XYZ color | |
| 236 | - | space by | |
| 237 | - | - SMPTE ST 428-1 | |
| 238 | - | - (CIE 1931 XYZ as in ISO 11664-1) | |
| 239 | - | </description> | |
| 240 | - | </entry> | |
| 241 | - | <entry name="dci_p3" value="8"> | |
| 242 | - | <description summary="Color primaries of the DCI P3 color space as defined by the SMPTE RP 431 standard"> | |
| 243 | - | Color primaries as defined by Digital Cinema System and published in | |
| 244 | - | SMPTE RP 431-2 (2011). | |
| 245 | - | </description> | |
| 246 | - | </entry> | |
| 247 | - | <entry name="display_p3" value="9"> | |
| 248 | - | <description summary="Color primaries of Display P3 variant of the DCI-P3 color space as defined by the SMPTE EG 432 standard"> | |
| 249 | - | Color primaries as defined by Digital Cinema System and published in | |
| 250 | - | SMPTE EG 432-1 (2010). | |
| 251 | - | </description> | |
| 252 | - | </entry> | |
| 253 | - | <entry name="adobe_rgb" value="10"> | |
| 254 | - | <description summary="Color primaries of the Adobe RGB color space as defined by the ISO 12640 standard"> | |
| 255 | - | Color primaries as defined by Adobe as "Adobe RGB" and later published | |
| 256 | - | by ISO 12640-4 (2011). | |
| 257 | - | </description> | |
| 258 | - | </entry> | |
| 259 | - | </enum> | |
| 260 | - | ||
| 261 | - | <enum name="transfer_function"> | |
| 262 | - | <description summary="named transfer functions"> | |
| 263 | - | Named transfer functions used to represent well-known transfer | |
| 264 | - | characteristics of displays. | |
| 265 | - | ||
| 266 | - | A value of 0 is invalid and will never be present in the list of enums. | |
| 267 | - | ||
| 268 | - | See appendix.md for the formulae. | |
| 269 | - | </description> | |
| 270 | - | ||
| 271 | - | <entry name="bt1886" value="1"> | |
| 272 | - | <description summary="BT.1886 display transfer characteristic"> | |
| 273 | - | Rec. ITU-R BT.1886 is the display transfer characteristic assumed by | |
| 274 | - | - Rec. ITU-R BT.601-7 525 and 625 | |
| 275 | - | - Rec. ITU-R BT.709-6 | |
| 276 | - | - Rec. ITU-R BT.2020-2 | |
| 277 | - | ||
| 278 | - | This TF implies these default luminances from Rec. ITU-R BT.2035: | |
| 279 | - | - primary color volume minimum: 0.01 cd/m² | |
| 280 | - | - primary color volume maximum: 100 cd/m² | |
| 281 | - | - reference white: 100 cd/m² | |
| 282 | - | </description> | |
| 283 | - | </entry> | |
| 284 | - | <entry name="gamma22" value="2"> | |
| 285 | - | <description summary="Assumed display gamma 2.2 transfer function"> | |
| 286 | - | Transfer characteristics as defined by | |
| 287 | - | - Rec. ITU-R BT.470-6 System M (historical) | |
| 288 | - | - United States National Television System Committee 1953 | |
| 289 | - | Recommendation for transmission standards for color television | |
| 290 | - | - United States Federal Communications Commission (2003) Title 47 Code | |
| 291 | - | of Federal Regulations 73.682 (a) (20) | |
| 292 | - | - Rec. ITU-R BT.1700-0 625 PAL and 625 SECAM | |
| 293 | - | - IEC 61966-2-1 (reference display) | |
| 294 | - | </description> | |
| 295 | - | </entry> | |
| 296 | - | <entry name="gamma28" value="3"> | |
| 297 | - | <description summary="Assumed display gamma 2.8 transfer function"> | |
| 298 | - | Transfer characteristics as defined by | |
| 299 | - | - Rec. ITU-R BT.470-6 System B, G (historical) | |
| 300 | - | </description> | |
| 301 | - | </entry> | |
| 302 | - | <entry name="st240" value="4"> | |
| 303 | - | <description summary="SMPTE ST 240 transfer function"> | |
| 304 | - | Transfer characteristics as defined by | |
| 305 | - | - SMPTE ST 240 (1999) | |
| 306 | - | </description> | |
| 307 | - | </entry> | |
| 308 | - | <entry name="ext_linear" value="5"> | |
| 309 | - | <description summary="extended linear transfer function"> | |
| 310 | - | Linear transfer function defined over all real numbers. | |
| 311 | - | Normalised electrical values are equal the normalised optical values. | |
| 312 | - | </description> | |
| 313 | - | </entry> | |
| 314 | - | <entry name="log_100" value="6"> | |
| 315 | - | <description summary="logarithmic 100:1 transfer function"> | |
| 316 | - | Logarithmic transfer characteristic (100:1 range). | |
| 317 | - | </description> | |
| 318 | - | </entry> | |
| 319 | - | <entry name="log_316" value="7"> | |
| 320 | - | <description summary="logarithmic (100*Sqrt(10) : 1) transfer function"> | |
| 321 | - | Logarithmic transfer characteristic (100 * Sqrt(10) : 1 range). | |
| 322 | - | </description> | |
| 323 | - | </entry> | |
| 324 | - | <entry name="xvycc" value="8"> | |
| 325 | - | <description summary="IEC 61966-2-4 transfer function"> | |
| 326 | - | Transfer characteristics as defined by | |
| 327 | - | - IEC 61966-2-4 | |
| 328 | - | </description> | |
| 329 | - | </entry> | |
| 330 | - | <entry name="srgb" value="9" deprecated-since="2"> | |
| 331 | - | <description summary="Deprecated (ambiguous sRGB transfer function)"> | |
| 332 | - | Transfer characteristics as defined by | |
| 333 | - | - IEC 61966-2-1 sRGB | |
| 334 | - | ||
| 335 | - | As a rule of thumb, use gamma22 for video, motion picture and | |
| 336 | - | computer graphics, or compound_power_2_4 for ICC calibrated print | |
| 337 | - | workflows. | |
| 338 | - | </description> | |
| 339 | - | </entry> | |
| 340 | - | <entry name="ext_srgb" value="10" deprecated-since="2"> | |
| 341 | - | <description summary="Deprecated (Extended sRGB piece-wise transfer function)"> | |
| 342 | - | Transfer characteristics as defined by | |
| 343 | - | - IEC 61966-2-1 sYCC | |
| 344 | - | </description> | |
| 345 | - | </entry> | |
| 346 | - | <entry name="st2084_pq" value="11"> | |
| 347 | - | <description summary="perceptual quantizer transfer function"> | |
| 348 | - | Transfer characteristics as defined by | |
| 349 | - | - SMPTE ST 2084 (2014) for 10-, 12-, 14- and 16-bit systems | |
| 350 | - | - Rec. ITU-R BT.2100-2 perceptual quantization (PQ) system | |
| 351 | - | ||
| 352 | - | This TF implies these default luminances | |
| 353 | - | - primary color volume minimum: 0.005 cd/m² | |
| 354 | - | - primary color volume maximum: 10000 cd/m² | |
| 355 | - | - reference white: 203 cd/m² | |
| 356 | - | ||
| 357 | - | The difference between the primary color volume minimum and maximum | |
| 358 | - | must be approximately 10000 cd/m² as that is the swing of the EOTF | |
| 359 | - | defined by ST 2084 and BT.2100. The default value for the | |
| 360 | - | reference white is a protocol addition: it is suggested by | |
| 361 | - | Report ITU-R BT.2408-7 and is not part of ST 2084 or BT.2100. | |
| 362 | - | </description> | |
| 363 | - | </entry> | |
| 364 | - | <entry name="st428" value="12"> | |
| 365 | - | <description summary="SMPTE ST 428 transfer function"> | |
| 366 | - | Transfer characteristics as defined by | |
| 367 | - | - SMPTE ST 428-1 (2019) | |
| 368 | - | </description> | |
| 369 | - | </entry> | |
| 370 | - | <entry name="hlg" value="13"> | |
| 371 | - | <description summary="hybrid log-gamma transfer function"> | |
| 372 | - | Transfer characteristics as defined by | |
| 373 | - | - ARIB STD-B67 (2015) | |
| 374 | - | - Rec. ITU-R BT.2100-2 hybrid log-gamma (HLG) system | |
| 375 | - | ||
| 376 | - | This TF implies these default luminances | |
| 377 | - | - primary color volume minimum: 0.005 cd/m² | |
| 378 | - | - primary color volume maximum: 1000 cd/m² | |
| 379 | - | - reference white: 203 cd/m² | |
| 380 | - | ||
| 381 | - | HLG is a relative display-referred signal with a specified | |
| 382 | - | non-linear mapping to the display peak luminance (the HLG OOTF). | |
| 383 | - | All absolute luminance values used here for HLG assume a 1000 cd/m² | |
| 384 | - | peak display. | |
| 385 | - | ||
| 386 | - | The default value for the reference white is a protocol addition: | |
| 387 | - | it is suggested by Report ITU-R BT.2408-7 and is not part of | |
| 388 | - | ARIB STD-B67 or BT.2100. | |
| 389 | - | </description> | |
| 390 | - | </entry> | |
| 391 | - | <entry name="compound_power_2_4" value="14" since="2"> | |
| 392 | - | <description summary="IEC 61966-2-1 encoding function"> | |
| 393 | - | Encoding characteristics as defined by IEC 61966-2-1, for displays | |
| 394 | - | that invert the encoding function. | |
| 395 | - | </description> | |
| 396 | - | </entry> | |
| 397 | - | </enum> | |
| 398 | - | ||
| 399 | - | <request name="get_output"> | |
| 400 | - | <description summary="create a color management interface for a wl_output"> | |
| 401 | - | This creates a new wp_color_management_output_v1 object for the | |
| 402 | - | given wl_output. | |
| 403 | - | ||
| 404 | - | See the wp_color_management_output_v1 interface for more details. | |
| 405 | - | </description> | |
| 406 | - | ||
| 407 | - | <arg name="id" type="new_id" interface="wp_color_management_output_v1"/> | |
| 408 | - | <arg name="output" type="object" interface="wl_output"/> | |
| 409 | - | </request> | |
| 410 | - | ||
| 411 | - | <request name="get_surface"> | |
| 412 | - | <description summary="create a color management interface for a wl_surface"> | |
| 413 | - | If a wp_color_management_surface_v1 object already exists for the given | |
| 414 | - | wl_surface, the protocol error surface_exists is raised. | |
| 415 | - | ||
| 416 | - | This creates a new color wp_color_management_surface_v1 object for the | |
| 417 | - | given wl_surface. | |
| 418 | - | ||
| 419 | - | See the wp_color_management_surface_v1 interface for more details. | |
| 420 | - | </description> | |
| 421 | - | ||
| 422 | - | <arg name="id" type="new_id" interface="wp_color_management_surface_v1"/> | |
| 423 | - | <arg name="surface" type="object" interface="wl_surface"/> | |
| 424 | - | </request> | |
| 425 | - | ||
| 426 | - | <request name="get_surface_feedback"> | |
| 427 | - | <description summary="create a color management feedback interface"> | |
| 428 | - | This creates a new color wp_color_management_surface_feedback_v1 object | |
| 429 | - | for the given wl_surface. | |
| 430 | - | ||
| 431 | - | See the wp_color_management_surface_feedback_v1 interface for more | |
| 432 | - | details. | |
| 433 | - | </description> | |
| 434 | - | ||
| 435 | - | <arg name="id" type="new_id" | |
| 436 | - | interface="wp_color_management_surface_feedback_v1"/> | |
| 437 | - | <arg name="surface" type="object" interface="wl_surface"/> | |
| 438 | - | </request> | |
| 439 | - | ||
| 440 | - | <request name="create_icc_creator"> | |
| 441 | - | <description summary="make a new ICC-based image description creator object"> | |
| 442 | - | Makes a new ICC-based image description creator object with all | |
| 443 | - | properties initially unset. The client can then use the object's | |
| 444 | - | interface to define all the required properties for an image description | |
| 445 | - | and finally create a wp_image_description_v1 object. | |
| 446 | - | ||
| 447 | - | This request can be used when the compositor advertises | |
| 448 | - | wp_color_manager_v1.feature.icc_v2_v4. | |
| 449 | - | Otherwise this request raises the protocol error unsupported_feature. | |
| 450 | - | </description> | |
| 451 | - | ||
| 452 | - | <arg name="obj" | |
| 453 | - | type="new_id" interface="wp_image_description_creator_icc_v1" | |
| 454 | - | summary="the new creator object"/> | |
| 455 | - | </request> | |
| 456 | - | ||
| 457 | - | <request name="create_parametric_creator"> | |
| 458 | - | <description summary="make a new parametric image description creator object"> | |
| 459 | - | Makes a new parametric image description creator object with all | |
| 460 | - | properties initially unset. The client can then use the object's | |
| 461 | - | interface to define all the required properties for an image description | |
| 462 | - | and finally create a wp_image_description_v1 object. | |
| 463 | - | ||
| 464 | - | This request can be used when the compositor advertises | |
| 465 | - | wp_color_manager_v1.feature.parametric. | |
| 466 | - | Otherwise this request raises the protocol error unsupported_feature. | |
| 467 | - | </description> | |
| 468 | - | ||
| 469 | - | <arg name="obj" | |
| 470 | - | type="new_id" interface="wp_image_description_creator_params_v1" | |
| 471 | - | summary="the new creator object"/> | |
| 472 | - | </request> | |
| 473 | - | ||
| 474 | - | <request name="create_windows_scrgb"> | |
| 475 | - | <description summary="create Windows-scRGB image description object"> | |
| 476 | - | This creates a pre-defined image description for the so-called | |
| 477 | - | Windows-scRGB stimulus encoding. This comes from the Windows 10 handling | |
| 478 | - | of its own definition of an scRGB color space for an HDR screen | |
| 479 | - | driven in BT.2100/PQ signalling mode. | |
| 480 | - | ||
| 481 | - | Windows-scRGB uses sRGB (BT.709) color primaries and white point. | |
| 482 | - | The transfer characteristic is extended linear. | |
| 483 | - | ||
| 484 | - | The nominal color channel value range is extended, meaning it includes | |
| 485 | - | negative and greater than 1.0 values. Negative values are used to | |
| 486 | - | escape the sRGB color gamut boundaries. To make use of the extended | |
| 487 | - | range, the client needs to use a pixel format that can represent those | |
| 488 | - | values, e.g. floating-point 16 bits per channel. | |
| 489 | - | ||
| 490 | - | Nominal color value R=G=B=0.0 corresponds to BT.2100/PQ system | |
| 491 | - | 0 cd/m², and R=G=B=1.0 corresponds to BT.2100/PQ system 80 cd/m². | |
| 492 | - | The maximum is R=G=B=125.0 corresponding to 10k cd/m². | |
| 493 | - | ||
| 494 | - | Windows-scRGB is displayed by Windows 10 by converting it to | |
| 495 | - | BT.2100/PQ, maintaining the CIE 1931 chromaticity and mapping the | |
| 496 | - | luminance as above. No adjustment is made to the signal to account | |
| 497 | - | for the viewing conditions. | |
| 498 | - | ||
| 499 | - | The reference white level of Windows-scRGB is unknown. If a | |
| 500 | - | reference white level must be assumed for compositor processing, it | |
| 501 | - | should be R=G=B=2.5375 corresponding to 203 cd/m² of Report ITU-R | |
| 502 | - | BT.2408-7. | |
| 503 | - | ||
| 504 | - | The target color volume of Windows-scRGB is unknown. The color gamut | |
| 505 | - | may be anything between sRGB and BT.2100. | |
| 506 | - | ||
| 507 | - | Note: EGL_EXT_gl_colorspace_scrgb_linear definition differs from | |
| 508 | - | Windows-scRGB by using R=G=B=1.0 as the reference white level, while | |
| 509 | - | Windows-scRGB reference white level is unknown or varies. However, | |
| 510 | - | it seems probable that Windows implements both | |
| 511 | - | EGL_EXT_gl_colorspace_scrgb_linear and Vulkan | |
| 512 | - | VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT as Windows-scRGB. | |
| 513 | - | ||
| 514 | - | This request can be used when the compositor advertises | |
| 515 | - | wp_color_manager_v1.feature.windows_scrgb. | |
| 516 | - | Otherwise this request raises the protocol error unsupported_feature. | |
| 517 | - | ||
| 518 | - | The resulting image description object does not allow get_information | |
| 519 | - | request. The wp_image_description_v1.ready event shall be sent. | |
| 520 | - | </description> | |
| 521 | - | ||
| 522 | - | <arg name="image_description" | |
| 523 | - | type="new_id" interface="wp_image_description_v1"/> | |
| 524 | - | </request> | |
| 525 | - | ||
| 526 | - | <event name="supported_intent"> | |
| 527 | - | <description summary="supported rendering intent"> | |
| 528 | - | When this object is created, it shall immediately send this event once | |
| 529 | - | for each rendering intent the compositor supports. | |
| 530 | - | ||
| 531 | - | A compositor must not advertise intents that are deprecated in the | |
| 532 | - | bound version of the interface. | |
| 533 | - | </description> | |
| 534 | - | ||
| 535 | - | <arg name="render_intent" type="uint" enum="render_intent" | |
| 536 | - | summary="rendering intent"/> | |
| 537 | - | </event> | |
| 538 | - | ||
| 539 | - | <event name="supported_feature"> | |
| 540 | - | <description summary="supported features"> | |
| 541 | - | When this object is created, it shall immediately send this event once | |
| 542 | - | for each compositor supported feature listed in the enumeration. | |
| 543 | - | ||
| 544 | - | A compositor must not advertise features that are deprecated in the | |
| 545 | - | bound version of the interface. | |
| 546 | - | </description> | |
| 547 | - | ||
| 548 | - | <arg name="feature" type="uint" enum="feature" | |
| 549 | - | summary="supported feature"/> | |
| 550 | - | </event> | |
| 551 | - | ||
| 552 | - | <event name="supported_tf_named"> | |
| 553 | - | <description summary="supported named transfer characteristic"> | |
| 554 | - | When this object is created, it shall immediately send this event once | |
| 555 | - | for each named transfer function the compositor supports with the | |
| 556 | - | parametric image description creator. | |
| 557 | - | ||
| 558 | - | A compositor must not advertise transfer functions that are deprecated | |
| 559 | - | in the bound version of the interface. | |
| 560 | - | </description> | |
| 561 | - | ||
| 562 | - | <arg name="tf" type="uint" enum="transfer_function" | |
| 563 | - | summary="Named transfer function"/> | |
| 564 | - | </event> | |
| 565 | - | ||
| 566 | - | <event name="supported_primaries_named"> | |
| 567 | - | <description summary="supported named primaries"> | |
| 568 | - | When this object is created, it shall immediately send this event once | |
| 569 | - | for each named set of primaries the compositor supports with the | |
| 570 | - | parametric image description creator. | |
| 571 | - | ||
| 572 | - | A compositor must not advertise names that are deprecated in the | |
| 573 | - | bound version of the interface. | |
| 574 | - | </description> | |
| 575 | - | ||
| 576 | - | <arg name="primaries" type="uint" enum="primaries" | |
| 577 | - | summary="Named color primaries"/> | |
| 578 | - | </event> | |
| 579 | - | ||
| 580 | - | <event name="done"> | |
| 581 | - | <description summary="all features have been sent"> | |
| 582 | - | This event is sent when all supported rendering intents, features, | |
| 583 | - | transfer functions and named primaries have been sent. | |
| 584 | - | </description> | |
| 585 | - | </event> | |
| 586 | - | ||
| 587 | - | <request name="get_image_description" since="2"> | |
| 588 | - | <description summary="create an image description from a reference"> | |
| 589 | - | This request retrieves the image description backing a reference. | |
| 590 | - | ||
| 591 | - | The get_information request can be used if and only if the request that | |
| 592 | - | creates the reference allows it. | |
| 593 | - | </description> | |
| 594 | - | ||
| 595 | - | <arg name="image_description" | |
| 596 | - | type="new_id" interface="wp_image_description_v1"/> | |
| 597 | - | <arg name="reference" | |
| 598 | - | type="object" interface="wp_image_description_reference_v1"/> | |
| 599 | - | </request> | |
| 600 | - | ||
| 601 | - | <request name="create_windows_bt2100" since="3"> | |
| 602 | - | <description summary="create Windows-BT.2100 image description object"> | |
| 603 | - | This creates a pre-defined image description for the so-called | |
| 604 | - | Windows-BT.2100 stimulus encoding. This comes from the Windows 10 | |
| 605 | - | handling of its own definition of a BT.2100 color space for an HDR | |
| 606 | - | screen driven in BT.2100/PQ signalling mode. | |
| 607 | - | ||
| 608 | - | Windows-BT.2100 uses BT.2020 color primaries and white point. | |
| 609 | - | The transfer characteristic is st2084_pq. | |
| 610 | - | ||
| 611 | - | Windows-BT.2100 is generally displayed by Windows 10 without any | |
| 612 | - | adjustments to the signal to account for viewing conditions. | |
| 613 | - | ||
| 614 | - | The reference white level of Windows-BT.2100 is unknown. If a | |
| 615 | - | reference white level must be assumed for compositor processing, it | |
| 616 | - | should be 203 cd/m² of Report ITU-R BT.2408-7. | |
| 617 | - | ||
| 618 | - | The target color volume of Windows-BT.2100 is unknown. The color gamut | |
| 619 | - | may be anything up to BT.2100. | |
| 620 | - | ||
| 621 | - | This request can be used when the compositor advertises | |
| 622 | - | wp_color_manager_v1.feature.windows_bt2100. | |
| 623 | - | Otherwise this request raises the protocol error unsupported_feature. | |
| 624 | - | ||
| 625 | - | The resulting image description object does not allow get_information | |
| 626 | - | request. The wp_image_description_v1.ready event shall be sent. | |
| 627 | - | </description> | |
| 628 | - | ||
| 629 | - | <arg name="image_description" | |
| 630 | - | type="new_id" interface="wp_image_description_v1"/> | |
| 631 | - | </request> | |
| 632 | - | </interface> | |
| 633 | - | ||
| 634 | - | <interface name="wp_color_management_output_v1" version="3"> | |
| 635 | - | <description summary="output color properties"> | |
| 636 | - | A wp_color_management_output_v1 describes the color properties of an | |
| 637 | - | output. | |
| 638 | - | ||
| 639 | - | The wp_color_management_output_v1 is associated with the wl_output global | |
| 640 | - | underlying the wl_output object. Therefore the client destroying the | |
| 641 | - | wl_output object has no impact, but the compositor removing the output | |
| 642 | - | global makes the wp_color_management_output_v1 object inert. | |
| 643 | - | </description> | |
| 644 | - | ||
| 645 | - | <request name="destroy" type="destructor"> | |
| 646 | - | <description summary="destroy the color management output"> | |
| 647 | - | Destroy the color wp_color_management_output_v1 object. This does not | |
| 648 | - | affect any remaining protocol objects. | |
| 649 | - | </description> | |
| 650 | - | </request> | |
| 651 | - | ||
| 652 | - | <event name="image_description_changed"> | |
| 653 | - | <description summary="image description changed"> | |
| 654 | - | This event is sent whenever the image description of the output changed, | |
| 655 | - | followed by one wl_output.done event common to output events across all | |
| 656 | - | extensions. | |
| 657 | - | ||
| 658 | - | If the client wants to use the updated image description, it needs to do | |
| 659 | - | get_image_description again, because image description objects are | |
| 660 | - | immutable. | |
| 661 | - | </description> | |
| 662 | - | </event> | |
| 663 | - | ||
| 664 | - | <request name="get_image_description"> | |
| 665 | - | <description summary="get the image description of the output"> | |
| 666 | - | This creates a new wp_image_description_v1 object for the current image | |
| 667 | - | description of the output. There always is exactly one image description | |
| 668 | - | active for an output so the client should destroy the image description | |
| 669 | - | created by earlier invocations of this request. This request is usually | |
| 670 | - | sent as a reaction to the image_description_changed event or when | |
| 671 | - | creating a wp_color_management_output_v1 object. | |
| 672 | - | ||
| 673 | - | The image description of an output represents the color encoding the | |
| 674 | - | output expects. There might be performance and power advantages, as well | |
| 675 | - | as improved color reproduction, if a content update matches the image | |
| 676 | - | description of the output it is being shown on. If a content update is | |
| 677 | - | shown on any other output than the one it matches the image description | |
| 678 | - | of, then the color reproduction on those outputs might be considerably | |
| 679 | - | worse. | |
| 680 | - | ||
| 681 | - | The created wp_image_description_v1 object preserves the image | |
| 682 | - | description of the output from the time the object was created. | |
| 683 | - | ||
| 684 | - | The resulting image description object allows get_information request. | |
| 685 | - | ||
| 686 | - | If this protocol object is inert, the resulting image description object | |
| 687 | - | shall immediately deliver the wp_image_description_v1.failed event with | |
| 688 | - | the no_output cause. | |
| 689 | - | ||
| 690 | - | If the interface version is inadequate for the output's image | |
| 691 | - | description, meaning that the client does not support all the events | |
| 692 | - | needed to deliver the crucial information, the resulting image | |
| 693 | - | description object shall immediately deliver the | |
| 694 | - | wp_image_description_v1.failed event with the low_version cause. | |
| 695 | - | ||
| 696 | - | Otherwise the object shall immediately deliver the ready event. | |
| 697 | - | </description> | |
| 698 | - | ||
| 699 | - | <arg name="image_description" | |
| 700 | - | type="new_id" interface="wp_image_description_v1"/> | |
| 701 | - | </request> | |
| 702 | - | </interface> | |
| 703 | - | ||
| 704 | - | <interface name="wp_color_management_surface_v1" version="3"> | |
| 705 | - | <description summary="color management extension to a surface"> | |
| 706 | - | A wp_color_management_surface_v1 allows the client to set the color | |
| 707 | - | space and HDR properties of a surface. | |
| 708 | - | ||
| 709 | - | If the wl_surface associated with the wp_color_management_surface_v1 is | |
| 710 | - | destroyed, the wp_color_management_surface_v1 object becomes inert. | |
| 711 | - | </description> | |
| 712 | - | ||
| 713 | - | <request name="destroy" type="destructor"> | |
| 714 | - | <description summary="destroy the color management interface for a surface"> | |
| 715 | - | Destroy the wp_color_management_surface_v1 object and do the same as | |
| 716 | - | unset_image_description. | |
| 717 | - | </description> | |
| 718 | - | </request> | |
| 719 | - | ||
| 720 | - | <enum name="error"> | |
| 721 | - | <description summary="protocol errors"/> | |
| 722 | - | <entry name="render_intent" value="0" | |
| 723 | - | summary="unsupported rendering intent"/> | |
| 724 | - | <entry name="image_description" value="1" | |
| 725 | - | summary="invalid image description"/> | |
| 726 | - | <entry name="inert" value="2" | |
| 727 | - | summary="forbidden request on inert object"/> | |
| 728 | - | </enum> | |
| 729 | - | ||
| 730 | - | <request name="set_image_description"> | |
| 731 | - | <description summary="set the surface image description"> | |
| 732 | - | If this protocol object is inert, the protocol error inert is raised. | |
| 733 | - | ||
| 734 | - | Set the image description of the underlying surface. The image | |
| 735 | - | description and rendering intent are double-buffered state, see | |
| 736 | - | wl_surface.commit. | |
| 737 | - | ||
| 738 | - | It is the client's responsibility to understand the image description | |
| 739 | - | it sets on a surface, and to provide content that matches that image | |
| 740 | - | description. Compositors might convert images to match their own or any | |
| 741 | - | other image descriptions. | |
| 742 | - | ||
| 743 | - | Image descriptions which are not ready (see wp_image_description_v1) | |
| 744 | - | are forbidden in this request, and in such case the protocol error | |
| 745 | - | image_description is raised. | |
| 746 | - | ||
| 747 | - | All image descriptions which are ready (see wp_image_description_v1) | |
| 748 | - | are allowed and must always be accepted by the compositor. | |
| 749 | - | ||
| 750 | - | When an image description is set on a surface, it establishes an | |
| 751 | - | explicit link between surface pixel values and surface colorimetry. | |
| 752 | - | This link may be undefined for some pixel values, see the image | |
| 753 | - | description creator interfaces for the conditions. Non-finite | |
| 754 | - | floating-point values (NaN, Inf) always have an undefined colorimetry. | |
| 755 | - | ||
| 756 | - | A rendering intent provides the client's preference on how surface | |
| 757 | - | colorimetry should be mapped to each output. The render_intent value | |
| 758 | - | must be one advertised by the compositor with | |
| 759 | - | wp_color_manager_v1.render_intent event, otherwise the protocol error | |
| 760 | - | render_intent is raised. | |
| 761 | - | ||
| 762 | - | By default, a surface does not have an associated image description | |
| 763 | - | nor a rendering intent. The handling of color on such surfaces is | |
| 764 | - | compositor implementation defined. Compositors should handle such | |
| 765 | - | surfaces as sRGB, but may handle them differently if they have specific | |
| 766 | - | requirements. | |
| 767 | - | ||
| 768 | - | Setting the image description has copy semantics; after this request, | |
| 769 | - | the image description can be immediately destroyed without affecting | |
| 770 | - | the pending state of the surface. | |
| 771 | - | </description> | |
| 772 | - | ||
| 773 | - | <arg name="image_description" | |
| 774 | - | type="object" interface="wp_image_description_v1"/> | |
| 775 | - | <arg name="render_intent" | |
| 776 | - | type="uint" enum="wp_color_manager_v1.render_intent" | |
| 777 | - | summary="rendering intent"/> | |
| 778 | - | </request> | |
| 779 | - | ||
| 780 | - | <request name="unset_image_description"> | |
| 781 | - | <description summary="remove the surface image description"> | |
| 782 | - | If this protocol object is inert, the protocol error inert is raised. | |
| 783 | - | ||
| 784 | - | This request removes any image description from the surface. See | |
| 785 | - | set_image_description for how a compositor handles a surface without | |
| 786 | - | an image description. This is double-buffered state, see | |
| 787 | - | wl_surface.commit. | |
| 788 | - | </description> | |
| 789 | - | </request> | |
| 790 | - | </interface> | |
| 791 | - | ||
| 792 | - | <interface name="wp_color_management_surface_feedback_v1" version="3"> | |
| 793 | - | <description summary="color management extension to a surface"> | |
| 794 | - | A wp_color_management_surface_feedback_v1 allows the client to get the | |
| 795 | - | preferred image description of a surface. | |
| 796 | - | ||
| 797 | - | If the wl_surface associated with this object is destroyed, the | |
| 798 | - | wp_color_management_surface_feedback_v1 object becomes inert. | |
| 799 | - | </description> | |
| 800 | - | ||
| 801 | - | <request name="destroy" type="destructor"> | |
| 802 | - | <description summary="destroy the color management interface for a surface"> | |
| 803 | - | Destroy the wp_color_management_surface_feedback_v1 object. | |
| 804 | - | </description> | |
| 805 | - | </request> | |
| 806 | - | ||
| 807 | - | <enum name="error"> | |
| 808 | - | <description summary="protocol errors"/> | |
| 809 | - | <entry name="inert" value="0" | |
| 810 | - | summary="forbidden request on inert object"/> | |
| 811 | - | <entry name="unsupported_feature" value="1" | |
| 812 | - | summary="attempted to use an unsupported feature"/> | |
| 813 | - | </enum> | |
| 814 | - | ||
| 815 | - | <event name="preferred_changed" deprecated-since="2"> | |
| 816 | - | <description summary="the preferred image description changed (32-bit)"> | |
| 817 | - | Starting from interface version 2, 'preferred_changed2' is sent instead | |
| 818 | - | of this event. See the 'preferred_changed2' event for the definition. | |
| 819 | - | </description> | |
| 820 | - | ||
| 821 | - | <arg name="identity" type="uint" | |
| 822 | - | summary="the 32-bit image description id number"/> | |
| 823 | - | </event> | |
| 824 | - | ||
| 825 | - | <request name="get_preferred"> | |
| 826 | - | <description summary="get the preferred image description"> | |
| 827 | - | If this protocol object is inert, the protocol error inert is raised. | |
| 828 | - | ||
| 829 | - | The preferred image description represents the compositor's preferred | |
| 830 | - | color encoding for this wl_surface at the current time. There might be | |
| 831 | - | performance and power advantages, as well as improved color | |
| 832 | - | reproduction, if the image description of a content update matches the | |
| 833 | - | preferred image description. | |
| 834 | - | ||
| 835 | - | This creates a new wp_image_description_v1 object for the currently | |
| 836 | - | preferred image description for the wl_surface. The client should | |
| 837 | - | stop using and destroy the image descriptions created by earlier | |
| 838 | - | invocations of this request for the associated wl_surface. | |
| 839 | - | This request is usually sent as a reaction to the preferred_changed | |
| 840 | - | event or when creating a wp_color_management_surface_feedback_v1 object | |
| 841 | - | if the client is capable of adapting to image descriptions. | |
| 842 | - | ||
| 843 | - | The created wp_image_description_v1 object preserves the preferred image | |
| 844 | - | description of the wl_surface from the time the object was created. | |
| 845 | - | ||
| 846 | - | The resulting image description object allows get_information request. | |
| 847 | - | ||
| 848 | - | If the image description is parametric, the client should set it on its | |
| 849 | - | wl_surface only if the image description is an exact match with the | |
| 850 | - | client content. Particularly if everything else matches, but the target | |
| 851 | - | color volume is greater than what the client needs, the client should | |
| 852 | - | create its own parameric image description with its exact parameters. | |
| 853 | - | ||
| 854 | - | If the interface version is inadequate for the preferred image | |
| 855 | - | description, meaning that the client does not support all the | |
| 856 | - | events needed to deliver the crucial information, the resulting image | |
| 857 | - | description object shall immediately deliver the | |
| 858 | - | wp_image_description_v1.failed event with the low_version cause, | |
| 859 | - | otherwise the object shall immediately deliver the ready event. | |
| 860 | - | </description> | |
| 861 | - | ||
| 862 | - | <arg name="image_description" | |
| 863 | - | type="new_id" interface="wp_image_description_v1"/> | |
| 864 | - | </request> | |
| 865 | - | ||
| 866 | - | <request name="get_preferred_parametric"> | |
| 867 | - | <description summary="get the preferred image description"> | |
| 868 | - | The same description as for get_preferred applies, except the returned | |
| 869 | - | image description is guaranteed to be parametric. This is meant for | |
| 870 | - | clients that can only deal with parametric image descriptions. | |
| 871 | - | ||
| 872 | - | If the compositor doesn't support parametric image descriptions, the | |
| 873 | - | unsupported_feature error is emitted. | |
| 874 | - | </description> | |
| 875 | - | ||
| 876 | - | <arg name="image_description" | |
| 877 | - | type="new_id" interface="wp_image_description_v1"/> | |
| 878 | - | </request> | |
| 879 | - | ||
| 880 | - | <!-- Version 2 additions --> | |
| 881 | - | ||
| 882 | - | <event name="preferred_changed2" since="2"> | |
| 883 | - | <description summary="the preferred image description changed"> | |
| 884 | - | The preferred image description is the one which likely has the most | |
| 885 | - | performance and/or quality benefits for the compositor if used by the | |
| 886 | - | client for its wl_surface contents. This event is sent whenever the | |
| 887 | - | compositor changes the wl_surface's preferred image description. | |
| 888 | - | ||
| 889 | - | This event sends the identity of the new preferred state as the argument, | |
| 890 | - | so clients who are aware of the image description already can reuse it. | |
| 891 | - | Otherwise, if the client client wants to know what the preferred image | |
| 892 | - | description is, it shall use the get_preferred request. | |
| 893 | - | ||
| 894 | - | The preferred image description is not automatically used for anything. | |
| 895 | - | It is only a hint, and clients may set any valid image description with | |
| 896 | - | set_image_description, but there might be performance and color accuracy | |
| 897 | - | improvements by providing the wl_surface contents in the preferred | |
| 898 | - | image description. Therefore clients that can, should render according | |
| 899 | - | to the preferred image description | |
| 900 | - | </description> | |
| 901 | - | ||
| 902 | - | <arg name="identity_hi" type="uint" | |
| 903 | - | summary="high 32 bits of the 64-bit image description id number"/> | |
| 904 | - | <arg name="identity_lo" type="uint" | |
| 905 | - | summary="low 32 bits of the 64-bit image description id number"/> | |
| 906 | - | </event> | |
| 907 | - | ||
| 908 | - | </interface> | |
| 909 | - | ||
| 910 | - | <interface name="wp_image_description_creator_icc_v1" version="3"> | |
| 911 | - | <description summary="holder of image description ICC information"> | |
| 912 | - | This type of object is used for collecting all the information required | |
| 913 | - | to create a wp_image_description_v1 object from an ICC file. A complete | |
| 914 | - | set of required parameters consists of these properties: | |
| 915 | - | - ICC file | |
| 916 | - | ||
| 917 | - | Each required property must be set exactly once if the client is to create | |
| 918 | - | an image description. The set requests verify that a property was not | |
| 919 | - | already set. The create request verifies that all required properties are | |
| 920 | - | set. There may be several alternative requests for setting each property, | |
| 921 | - | and in that case the client must choose one of them. | |
| 922 | - | ||
| 923 | - | Once all properties have been set, the create request must be used to | |
| 924 | - | create the image description object, destroying the creator in the | |
| 925 | - | process. | |
| 926 | - | ||
| 927 | - | The link between a pixel value (a device value in ICC) and its respective | |
| 928 | - | colorimetry is defined by the details of the particular ICC profile. | |
| 929 | - | Those details also determine when colorimetry becomes undefined. | |
| 930 | - | </description> | |
| 931 | - | ||
| 932 | - | <enum name="error"> | |
| 933 | - | <description summary="protocol errors"/> | |
| 934 | - | ||
| 935 | - | <entry name="incomplete_set" value="0" | |
| 936 | - | summary="incomplete parameter set"/> | |
| 937 | - | <entry name="already_set" value="1" | |
| 938 | - | summary="property already set"/> | |
| 939 | - | <entry name="bad_fd" value="2" | |
| 940 | - | summary="fd not seekable and readable"/> | |
| 941 | - | <entry name="bad_size" value="3" | |
| 942 | - | summary="no or too much data"/> | |
| 943 | - | <entry name="out_of_file" value="4" | |
| 944 | - | summary="offset + length exceeds file size"/> | |
| 945 | - | </enum> | |
| 946 | - | ||
| 947 | - | <request name="create" type="destructor"> | |
| 948 | - | <description summary="Create the image description object from ICC data"> | |
| 949 | - | Create an image description object based on the ICC information | |
| 950 | - | previously set on this object. A compositor must parse the ICC data in | |
| 951 | - | some undefined but finite amount of time. | |
| 952 | - | ||
| 953 | - | The completeness of the parameter set is verified. If the set is not | |
| 954 | - | complete, the protocol error incomplete_set is raised. For the | |
| 955 | - | definition of a complete set, see the description of this interface. | |
| 956 | - | ||
| 957 | - | If the particular combination of the information is not supported | |
| 958 | - | by the compositor, the resulting image description object shall | |
| 959 | - | immediately deliver the wp_image_description_v1.failed event with the | |
| 960 | - | 'unsupported' cause. If a valid image description was created from the | |
| 961 | - | information, the wp_image_description_v1.ready event will eventually | |
| 962 | - | be sent instead. | |
| 963 | - | ||
| 964 | - | This request destroys the wp_image_description_creator_icc_v1 object. | |
| 965 | - | ||
| 966 | - | The resulting image description object does not allow get_information | |
| 967 | - | request. | |
| 968 | - | </description> | |
| 969 | - | ||
| 970 | - | <arg name="image_description" | |
| 971 | - | type="new_id" interface="wp_image_description_v1"/> | |
| 972 | - | </request> | |
| 973 | - | ||
| 974 | - | <request name="set_icc_file"> | |
| 975 | - | <description summary="set the ICC profile file"> | |
| 976 | - | Sets the ICC profile file to be used as the basis of the image | |
| 977 | - | description. | |
| 978 | - | ||
| 979 | - | The data shall be found through the given fd at the given offset, having | |
| 980 | - | the given length. The fd must be seekable and readable. Violating these | |
| 981 | - | requirements raises the bad_fd protocol error. | |
| 982 | - | ||
| 983 | - | If reading the data fails due to an error independent of the client, the | |
| 984 | - | compositor shall send the wp_image_description_v1.failed event on the | |
| 985 | - | created wp_image_description_v1 with the 'operating_system' cause. | |
| 986 | - | ||
| 987 | - | The maximum size of the ICC profile is 32 MB. If length is greater than | |
| 988 | - | that or zero, the protocol error bad_size is raised. If offset + length | |
| 989 | - | exceeds the file size, the protocol error out_of_file is raised. | |
| 990 | - | ||
| 991 | - | A compositor may read the file at any time starting from this request | |
| 992 | - | and only until whichever happens first: | |
| 993 | - | - If create request was issued, the wp_image_description_v1 object | |
| 994 | - | delivers either failed or ready event; or | |
| 995 | - | - if create request was not issued, this | |
| 996 | - | wp_image_description_creator_icc_v1 object is destroyed. | |
| 997 | - | ||
| 998 | - | A compositor shall not modify the contents of the file, and the fd may | |
| 999 | - | be sealed for writes and size changes. The client must ensure to its | |
| 1000 | - | best ability that the data does not change while the compositor is | |
| 1001 | - | reading it. | |
| 1002 | - | ||
| 1003 | - | The data must represent a valid ICC profile. The ICC profile version | |
| 1004 | - | must be 2 or 4, it must be a 3 channel profile and the class must be | |
| 1005 | - | Display or ColorSpace. Violating these requirements will not result in a | |
| 1006 | - | protocol error, but will eventually send the | |
| 1007 | - | wp_image_description_v1.failed event on the created | |
| 1008 | - | wp_image_description_v1 with the 'unsupported' cause. | |
| 1009 | - | ||
| 1010 | - | See the International Color Consortium specification ICC.1:2022 for more | |
| 1011 | - | details about ICC profiles. | |
| 1012 | - | ||
| 1013 | - | If ICC file has already been set on this object, the protocol error | |
| 1014 | - | already_set is raised. | |
| 1015 | - | </description> | |
| 1016 | - | ||
| 1017 | - | <arg name="icc_profile" type="fd" | |
| 1018 | - | summary="ICC profile"/> | |
| 1019 | - | <arg name="offset" type="uint" | |
| 1020 | - | summary="byte offset in fd to start of ICC data"/> | |
| 1021 | - | <arg name="length" type="uint" | |
| 1022 | - | summary="length of ICC data in bytes"/> | |
| 1023 | - | </request> | |
| 1024 | - | </interface> | |
| 1025 | - | ||
| 1026 | - | <interface name="wp_image_description_creator_params_v1" version="3"> | |
| 1027 | - | <description summary="holder of image description parameters"> | |
| 1028 | - | This type of object is used for collecting all the parameters required | |
| 1029 | - | to create a wp_image_description_v1 object. A complete set of required | |
| 1030 | - | parameters consists of these properties: | |
| 1031 | - | - transfer characteristic function (tf) | |
| 1032 | - | - chromaticities of primaries and white point (primary color volume) | |
| 1033 | - | ||
| 1034 | - | The following properties are optional and have a well-defined default | |
| 1035 | - | if not explicitly set: | |
| 1036 | - | - primary color volume luminance range | |
| 1037 | - | - reference white luminance level | |
| 1038 | - | - mastering display primaries and white point (target color volume) | |
| 1039 | - | - mastering luminance range | |
| 1040 | - | ||
| 1041 | - | The following properties are optional and will be ignored | |
| 1042 | - | if not explicitly set: | |
| 1043 | - | - maximum content light level | |
| 1044 | - | - maximum frame-average light level | |
| 1045 | - | ||
| 1046 | - | Each required property must be set exactly once if the client is to create | |
| 1047 | - | an image description. The set requests verify that a property was not | |
| 1048 | - | already set. The create request verifies that all required properties are | |
| 1049 | - | set. There may be several alternative requests for setting each property, | |
| 1050 | - | and in that case the client must choose one of them. | |
| 1051 | - | ||
| 1052 | - | Once all properties have been set, the create request must be used to | |
| 1053 | - | create the image description object, destroying the creator in the | |
| 1054 | - | process. | |
| 1055 | - | ||
| 1056 | - | A viewer, who is viewing the display defined by the resulting image | |
| 1057 | - | description (the viewing environment included), is assumed to be fully | |
| 1058 | - | adapted to the primary color volume's white point. | |
| 1059 | - | ||
| 1060 | - | Any of the following conditions will cause the colorimetry of a pixel | |
| 1061 | - | to become undefined: | |
| 1062 | - | - Values outside of the defined range of the transfer characteristic. | |
| 1063 | - | - Tristimulus that exceeds the target color volume. | |
| 1064 | - | - If extended_target_volume is not supported: tristimulus that exceeds | |
| 1065 | - | the primary color volume. | |
| 1066 | - | ||
| 1067 | - | The closest correspondence to an image description created through this | |
| 1068 | - | interface is the Display class of profiles in ICC. | |
| 1069 | - | </description> | |
| 1070 | - | ||
| 1071 | - | <enum name="error"> | |
| 1072 | - | <description summary="protocol errors"/> | |
| 1073 | - | ||
| 1074 | - | <entry name="incomplete_set" value="0" | |
| 1075 | - | summary="incomplete parameter set"/> | |
| 1076 | - | <entry name="already_set" value="1" | |
| 1077 | - | summary="property already set"/> | |
| 1078 | - | <entry name="unsupported_feature" value="2" | |
| 1079 | - | summary="request not supported"/> | |
| 1080 | - | <entry name="invalid_tf" value="3" | |
| 1081 | - | summary="invalid transfer characteristic"/> | |
| 1082 | - | <entry name="invalid_primaries_named" value="4" | |
| 1083 | - | summary="invalid primaries named"/> | |
| 1084 | - | <entry name="invalid_luminance" value="5" | |
| 1085 | - | summary="invalid luminance value or range"/> | |
| 1086 | - | </enum> | |
| 1087 | - | ||
| 1088 | - | <request name="create" type="destructor"> | |
| 1089 | - | <description summary="Create the image description object using params"> | |
| 1090 | - | Create an image description object based on the parameters previously | |
| 1091 | - | set on this object. | |
| 1092 | - | ||
| 1093 | - | The completeness of the parameter set is verified. If the set is not | |
| 1094 | - | complete, the protocol error incomplete_set is raised. For the | |
| 1095 | - | definition of a complete set, see the description of this interface. | |
| 1096 | - | ||
| 1097 | - | When both max_cll and max_fall are set, max_fall must be less or equal | |
| 1098 | - | to max_cll otherwise the invalid_luminance protocol error is raised. | |
| 1099 | - | ||
| 1100 | - | In version 1, these following conditions also result in the | |
| 1101 | - | invalid_luminance protocol error. Version 2 and later do not have this | |
| 1102 | - | requirement. | |
| 1103 | - | - When max_cll is set, it must be greater than min L and less or equal | |
| 1104 | - | to max L of the mastering luminance range. | |
| 1105 | - | - When max_fall is set, it must be greater than min L and less or equal | |
| 1106 | - | to max L of the mastering luminance range. | |
| 1107 | - | ||
| 1108 | - | If the particular combination of the parameter set is not supported | |
| 1109 | - | by the compositor, the resulting image description object shall | |
| 1110 | - | immediately deliver the wp_image_description_v1.failed event with the | |
| 1111 | - | 'unsupported' cause. If a valid image description was created from the | |
| 1112 | - | parameter set, the wp_image_description_v1.ready event will eventually | |
| 1113 | - | be sent instead. | |
| 1114 | - | ||
| 1115 | - | This request destroys the wp_image_description_creator_params_v1 | |
| 1116 | - | object. | |
| 1117 | - | ||
| 1118 | - | The resulting image description object does not allow get_information | |
| 1119 | - | request. | |
| 1120 | - | </description> | |
| 1121 | - | ||
| 1122 | - | <arg name="image_description" | |
| 1123 | - | type="new_id" interface="wp_image_description_v1"/> | |
| 1124 | - | </request> | |
| 1125 | - | ||
| 1126 | - | <request name="set_tf_named"> | |
| 1127 | - | <description summary="named transfer characteristic"> | |
| 1128 | - | Sets the transfer characteristic using explicitly enumerated named | |
| 1129 | - | functions. | |
| 1130 | - | ||
| 1131 | - | When the resulting image description is attached to an image, the | |
| 1132 | - | content should be decoded according to the industry standard | |
| 1133 | - | practices for the transfer characteristic. | |
| 1134 | - | ||
| 1135 | - | Only names advertised with wp_color_manager_v1 event supported_tf_named | |
| 1136 | - | are allowed. Other values shall raise the protocol error invalid_tf. | |
| 1137 | - | ||
| 1138 | - | If transfer characteristic has already been set on this object, the | |
| 1139 | - | protocol error already_set is raised. | |
| 1140 | - | </description> | |
| 1141 | - | ||
| 1142 | - | <arg name="tf" type="uint" enum="wp_color_manager_v1.transfer_function" | |
| 1143 | - | summary="named transfer function"/> | |
| 1144 | - | </request> | |
| 1145 | - | ||
| 1146 | - | <request name="set_tf_power"> | |
| 1147 | - | <description summary="transfer characteristic as a power curve"> | |
| 1148 | - | Sets the color component transfer characteristic to a power curve with | |
| 1149 | - | the given exponent. Negative values are handled by mirroring the | |
| 1150 | - | positive half of the curve through the origin. The valid domain and | |
| 1151 | - | range of the curve are all finite real numbers. This curve represents | |
| 1152 | - | the conversion from electrical to optical color channel values. | |
| 1153 | - | ||
| 1154 | - | The curve exponent shall be multiplied by 10000 to get the argument eexp | |
| 1155 | - | value to carry the precision of 4 decimals. | |
| 1156 | - | ||
| 1157 | - | The curve exponent must be at least 1.0 and at most 10.0. Otherwise the | |
| 1158 | - | protocol error invalid_tf is raised. | |
| 1159 | - | ||
| 1160 | - | If transfer characteristic has already been set on this object, the | |
| 1161 | - | protocol error already_set is raised. | |
| 1162 | - | ||
| 1163 | - | This request can be used when the compositor advertises | |
| 1164 | - | wp_color_manager_v1.feature.set_tf_power. Otherwise this request raises | |
| 1165 | - | the protocol error unsupported_feature. | |
| 1166 | - | </description> | |
| 1167 | - | ||
| 1168 | - | <arg name="eexp" type="uint" summary="the exponent * 10000"/> | |
| 1169 | - | </request> | |
| 1170 | - | ||
| 1171 | - | <request name="set_primaries_named"> | |
| 1172 | - | <description summary="named primaries"> | |
| 1173 | - | Sets the color primaries and white point using explicitly named sets. | |
| 1174 | - | This describes the primary color volume which is the basis for color | |
| 1175 | - | value encoding. | |
| 1176 | - | ||
| 1177 | - | Only names advertised with wp_color_manager_v1 event | |
| 1178 | - | supported_primaries_named are allowed. Other values shall raise the | |
| 1179 | - | protocol error invalid_primaries_named. | |
| 1180 | - | ||
| 1181 | - | If primaries have already been set on this object, the protocol error | |
| 1182 | - | already_set is raised. | |
| 1183 | - | </description> | |
| 1184 | - | ||
| 1185 | - | <arg name="primaries" type="uint" enum="wp_color_manager_v1.primaries" | |
| 1186 | - | summary="named primaries"/> | |
| 1187 | - | </request> | |
| 1188 | - | ||
| 1189 | - | <request name="set_primaries"> | |
| 1190 | - | <description summary="primaries as chromaticity coordinates"> | |
| 1191 | - | Sets the color primaries and white point using CIE 1931 xy chromaticity | |
| 1192 | - | coordinates. This describes the primary color volume which is the basis | |
| 1193 | - | for color value encoding. | |
| 1194 | - | ||
| 1195 | - | Each coordinate value is multiplied by 1 million to get the argument | |
| 1196 | - | value to carry precision of 6 decimals. | |
| 1197 | - | ||
| 1198 | - | If primaries have already been set on this object, the protocol error | |
| 1199 | - | already_set is raised. | |
| 1200 | - | ||
| 1201 | - | This request can be used if the compositor advertises | |
| 1202 | - | wp_color_manager_v1.feature.set_primaries. Otherwise this request raises | |
| 1203 | - | the protocol error unsupported_feature. | |
| 1204 | - | </description> | |
| 1205 | - | ||
| 1206 | - | <arg name="r_x" type="int" summary="Red x * 1M"/> | |
| 1207 | - | <arg name="r_y" type="int" summary="Red y * 1M"/> | |
| 1208 | - | <arg name="g_x" type="int" summary="Green x * 1M"/> | |
| 1209 | - | <arg name="g_y" type="int" summary="Green y * 1M"/> | |
| 1210 | - | <arg name="b_x" type="int" summary="Blue x * 1M"/> | |
| 1211 | - | <arg name="b_y" type="int" summary="Blue y * 1M"/> | |
| 1212 | - | <arg name="w_x" type="int" summary="White x * 1M"/> | |
| 1213 | - | <arg name="w_y" type="int" summary="White y * 1M"/> | |
| 1214 | - | </request> | |
| 1215 | - | ||
| 1216 | - | <request name="set_luminances"> | |
| 1217 | - | <description summary="primary color volume luminance range and reference white"> | |
| 1218 | - | Sets the primary color volume luminance range and the reference white | |
| 1219 | - | luminance level. These values include the minimum display emission, but | |
| 1220 | - | not external flare. The minimum display emission is assumed to have | |
| 1221 | - | the chromaticity of the primary color volume white point. | |
| 1222 | - | ||
| 1223 | - | The default luminances from | |
| 1224 | - | https://www.color.org/chardata/rgb/srgb.xalter are | |
| 1225 | - | - primary color volume minimum: 0.2 cd/m² | |
| 1226 | - | - primary color volume maximum: 80 cd/m² | |
| 1227 | - | - reference white: 80 cd/m² | |
| 1228 | - | ||
| 1229 | - | Setting a named transfer characteristic can imply other default | |
| 1230 | - | luminances. | |
| 1231 | - | ||
| 1232 | - | The default luminances get overwritten when this request is used. | |
| 1233 | - | With transfer_function.st2084_pq the given 'max_lum' value is ignored, | |
| 1234 | - | and 'max_lum' is taken as 'min_lum' + 10000 cd/m². | |
| 1235 | - | ||
| 1236 | - | 'min_lum' and 'max_lum' specify the minimum and maximum luminances of | |
| 1237 | - | the primary color volume as reproduced by the targeted display. | |
| 1238 | - | ||
| 1239 | - | 'reference_lum' specifies the luminance of the reference white as | |
| 1240 | - | reproduced by the targeted display, and reflects the targeted viewing | |
| 1241 | - | environment. | |
| 1242 | - | ||
| 1243 | - | Compositors should make sure that all content is anchored, meaning that | |
| 1244 | - | an input signal level of 'reference_lum' on one image description and | |
| 1245 | - | another input signal level of 'reference_lum' on another image | |
| 1246 | - | description should produce the same output level, even though the | |
| 1247 | - | 'reference_lum' on both image representations can be different. | |
| 1248 | - | ||
| 1249 | - | 'reference_lum' may be higher than 'max_lum'. In that case reaching | |
| 1250 | - | the reference white output level in image content requires the | |
| 1251 | - | 'extended_target_volume' feature support. | |
| 1252 | - | ||
| 1253 | - | If 'max_lum' or 'reference_lum' are less than or equal to 'min_lum', | |
| 1254 | - | the protocol error invalid_luminance is raised. | |
| 1255 | - | ||
| 1256 | - | The minimum luminance is multiplied by 10000 to get the argument | |
| 1257 | - | 'min_lum' value and carries precision of 4 decimals. The maximum | |
| 1258 | - | luminance and reference white luminance values are unscaled. | |
| 1259 | - | ||
| 1260 | - | If the primary color volume luminance range and the reference white | |
| 1261 | - | luminance level have already been set on this object, the protocol error | |
| 1262 | - | already_set is raised. | |
| 1263 | - | ||
| 1264 | - | This request can be used if the compositor advertises | |
| 1265 | - | wp_color_manager_v1.feature.set_luminances. Otherwise this request | |
| 1266 | - | raises the protocol error unsupported_feature. | |
| 1267 | - | </description> | |
| 1268 | - | ||
| 1269 | - | <arg name="min_lum" type="uint" | |
| 1270 | - | summary="minimum luminance (cd/m²) * 10000"/> | |
| 1271 | - | <arg name="max_lum" type="uint" | |
| 1272 | - | summary="maximum luminance (cd/m²)"/> | |
| 1273 | - | <arg name="reference_lum" type="uint" | |
| 1274 | - | summary="reference white luminance (cd/m²)"/> | |
| 1275 | - | </request> | |
| 1276 | - | ||
| 1277 | - | <request name="set_mastering_display_primaries"> | |
| 1278 | - | <description summary="mastering display primaries as chromaticity coordinates"> | |
| 1279 | - | Provides the color primaries and white point of the mastering display | |
| 1280 | - | using CIE 1931 xy chromaticity coordinates. This is compatible with the | |
| 1281 | - | SMPTE ST 2086 definition of HDR static metadata. | |
| 1282 | - | ||
| 1283 | - | The mastering display primaries and mastering display luminances define | |
| 1284 | - | the target color volume. | |
| 1285 | - | ||
| 1286 | - | If mastering display primaries are not explicitly set, the target color | |
| 1287 | - | volume is assumed to have the same primaries as the primary color volume. | |
| 1288 | - | ||
| 1289 | - | The target color volume is defined by all tristimulus values between 0.0 | |
| 1290 | - | and 1.0 (inclusive) of the color space defined by the given mastering | |
| 1291 | - | display primaries and white point. The colorimetry is identical between | |
| 1292 | - | the container color space and the mastering display color space, | |
| 1293 | - | including that no chromatic adaptation is applied even if the white | |
| 1294 | - | points differ. | |
| 1295 | - | ||
| 1296 | - | The target color volume can exceed the primary color volume to allow for | |
| 1297 | - | a greater color volume with an existing color space definition (for | |
| 1298 | - | example scRGB). It can be smaller than the primary color volume to | |
| 1299 | - | minimize gamut and tone mapping distances for big color spaces (HDR | |
| 1300 | - | metadata). | |
| 1301 | - | ||
| 1302 | - | To make use of the entire target color volume a suitable pixel format | |
| 1303 | - | has to be chosen (e.g. floating point to exceed the primary color | |
| 1304 | - | volume, or abusing limited quantization range as with xvYCC). | |
| 1305 | - | ||
| 1306 | - | Each coordinate value is multiplied by 1 million to get the argument | |
| 1307 | - | value to carry precision of 6 decimals. | |
| 1308 | - | ||
| 1309 | - | If mastering display primaries have already been set on this object, the | |
| 1310 | - | protocol error already_set is raised. | |
| 1311 | - | ||
| 1312 | - | This request can be used if the compositor advertises | |
| 1313 | - | wp_color_manager_v1.feature.set_mastering_display_primaries. Otherwise | |
| 1314 | - | this request raises the protocol error unsupported_feature. The | |
| 1315 | - | advertisement implies support only for target color volumes fully | |
| 1316 | - | contained within the primary color volume. | |
| 1317 | - | ||
| 1318 | - | If a compositor additionally supports target color volume exceeding the | |
| 1319 | - | primary color volume, it must advertise | |
| 1320 | - | wp_color_manager_v1.feature.extended_target_volume. If a client uses | |
| 1321 | - | target color volume exceeding the primary color volume and the | |
| 1322 | - | compositor does not support it, the result is implementation defined. | |
| 1323 | - | Compositors are recommended to detect this case and fail the image | |
| 1324 | - | description gracefully, but it may as well result in color artifacts. | |
| 1325 | - | </description> | |
| 1326 | - | ||
| 1327 | - | <arg name="r_x" type="int" summary="Red x * 1M"/> | |
| 1328 | - | <arg name="r_y" type="int" summary="Red y * 1M"/> | |
| 1329 | - | <arg name="g_x" type="int" summary="Green x * 1M"/> | |
| 1330 | - | <arg name="g_y" type="int" summary="Green y * 1M"/> | |
| 1331 | - | <arg name="b_x" type="int" summary="Blue x * 1M"/> | |
| 1332 | - | <arg name="b_y" type="int" summary="Blue y * 1M"/> | |
| 1333 | - | <arg name="w_x" type="int" summary="White x * 1M"/> | |
| 1334 | - | <arg name="w_y" type="int" summary="White y * 1M"/> | |
| 1335 | - | </request> | |
| 1336 | - | ||
| 1337 | - | <request name="set_mastering_luminance"> | |
| 1338 | - | <description summary="display mastering luminance range"> | |
| 1339 | - | Sets the luminance range that was used during the content mastering | |
| 1340 | - | process as the minimum and maximum absolute luminance L. These values | |
| 1341 | - | include the minimum display emission and ambient flare luminances, | |
| 1342 | - | assumed to be optically additive and have the chromaticity of the | |
| 1343 | - | primary color volume white point. This should be | |
| 1344 | - | compatible with the SMPTE ST 2086 definition of HDR static metadata. | |
| 1345 | - | ||
| 1346 | - | The mastering display primaries and mastering display luminances define | |
| 1347 | - | the target color volume. | |
| 1348 | - | ||
| 1349 | - | If mastering luminances are not explicitly set, the target color volume | |
| 1350 | - | is assumed to have the same min and max luminances as the primary color | |
| 1351 | - | volume. | |
| 1352 | - | ||
| 1353 | - | If max L is less than or equal to min L, the protocol error | |
| 1354 | - | invalid_luminance is raised. | |
| 1355 | - | ||
| 1356 | - | Min L value is multiplied by 10000 to get the argument min_lum value | |
| 1357 | - | and carry precision of 4 decimals. Max L value is unscaled for max_lum. | |
| 1358 | - | ||
| 1359 | - | This request can be used if the compositor advertises | |
| 1360 | - | wp_color_manager_v1.feature.set_mastering_display_primaries. Otherwise | |
| 1361 | - | this request raises the protocol error unsupported_feature. The | |
| 1362 | - | advertisement implies support only for target color volumes fully | |
| 1363 | - | contained within the primary color volume. | |
| 1364 | - | ||
| 1365 | - | If a compositor additionally supports target color volume exceeding the | |
| 1366 | - | primary color volume, it must advertise | |
| 1367 | - | wp_color_manager_v1.feature.extended_target_volume. If a client uses | |
| 1368 | - | target color volume exceeding the primary color volume and the | |
| 1369 | - | compositor does not support it, the result is implementation defined. | |
| 1370 | - | Compositors are recommended to detect this case and fail the image | |
| 1371 | - | description gracefully, but it may as well result in color artifacts. | |
| 1372 | - | </description> | |
| 1373 | - | ||
| 1374 | - | <arg name="min_lum" type="uint" summary="min L (cd/m²) * 10000"/> | |
| 1375 | - | <arg name="max_lum" type="uint" summary="max L (cd/m²)"/> | |
| 1376 | - | </request> | |
| 1377 | - | ||
| 1378 | - | <request name="set_max_cll"> | |
| 1379 | - | <description summary="maximum content light level"> | |
| 1380 | - | Sets the maximum content light level (max_cll) as defined by CTA-861-H. | |
| 1381 | - | ||
| 1382 | - | max_cll is undefined by default. | |
| 1383 | - | </description> | |
| 1384 | - | ||
| 1385 | - | <arg name="max_cll" type="uint" summary="Maximum content light level (cd/m²)"/> | |
| 1386 | - | </request> | |
| 1387 | - | ||
| 1388 | - | <request name="set_max_fall"> | |
| 1389 | - | <description summary="maximum frame-average light level"> | |
| 1390 | - | Sets the maximum frame-average light level (max_fall) as defined by | |
| 1391 | - | CTA-861-H. | |
| 1392 | - | ||
| 1393 | - | max_fall is undefined by default. | |
| 1394 | - | </description> | |
| 1395 | - | ||
| 1396 | - | <arg name="max_fall" type="uint" summary="Maximum frame-average light level (cd/m²)"/> | |
| 1397 | - | </request> | |
| 1398 | - | </interface> | |
| 1399 | - | ||
| 1400 | - | <interface name="wp_image_description_v1" version="3"> | |
| 1401 | - | <description summary="Colorimetric image description"> | |
| 1402 | - | An image description carries information about the pixel color encoding | |
| 1403 | - | and its intended display and viewing environment. The image description is | |
| 1404 | - | attached to a wl_surface via | |
| 1405 | - | wp_color_management_surface_v1.set_image_description. A compositor can use | |
| 1406 | - | this information to decode pixel values into colorimetrically meaningful | |
| 1407 | - | quantities, which allows the compositor to transform the surface contents | |
| 1408 | - | to become suitable for various displays and viewing environments. | |
| 1409 | - | ||
| 1410 | - | Note, that the wp_image_description_v1 object is not ready to be used | |
| 1411 | - | immediately after creation. The object eventually delivers either the | |
| 1412 | - | 'ready' or the 'failed' event, specified in all requests creating it. The | |
| 1413 | - | object is deemed "ready" after receiving the 'ready' event. | |
| 1414 | - | ||
| 1415 | - | An object which is not ready is illegal to use, it can only be destroyed. | |
| 1416 | - | Any other request in this interface shall result in the 'not_ready' | |
| 1417 | - | protocol error. Attempts to use an object which is not ready through other | |
| 1418 | - | interfaces shall raise protocol errors defined there. | |
| 1419 | - | ||
| 1420 | - | Once created and regardless of how it was created, a | |
| 1421 | - | wp_image_description_v1 object always refers to one fixed image | |
| 1422 | - | description. It cannot change after creation. | |
| 1423 | - | </description> | |
| 1424 | - | ||
| 1425 | - | <request name="destroy" type="destructor"> | |
| 1426 | - | <description summary="destroy the image description"> | |
| 1427 | - | Destroy this object. It is safe to destroy an object which is not ready. | |
| 1428 | - | ||
| 1429 | - | Destroying a wp_image_description_v1 object has no side-effects, not | |
| 1430 | - | even if a wp_color_management_surface_v1.set_image_description has not | |
| 1431 | - | yet been followed by a wl_surface.commit. | |
| 1432 | - | </description> | |
| 1433 | - | </request> | |
| 1434 | - | ||
| 1435 | - | <enum name="error"> | |
| 1436 | - | <description summary="protocol errors"/> | |
| 1437 | - | ||
| 1438 | - | <entry name="not_ready" value="0" | |
| 1439 | - | summary="attempted to use an object which is not ready"/> | |
| 1440 | - | <entry name="no_information" value="1" | |
| 1441 | - | summary="get_information not allowed"/> | |
| 1442 | - | </enum> | |
| 1443 | - | ||
| 1444 | - | <enum name="cause"> | |
| 1445 | - | <description summary="generic reason for failure"/> | |
| 1446 | - | ||
| 1447 | - | <entry name="low_version" value="0" | |
| 1448 | - | summary="interface version too low"/> | |
| 1449 | - | <entry name="unsupported" value="1" | |
| 1450 | - | summary="unsupported image description data"/> | |
| 1451 | - | <entry name="operating_system" value="2" | |
| 1452 | - | summary="error independent of the client"/> | |
| 1453 | - | <entry name="no_output" value="3" | |
| 1454 | - | summary="the relevant output no longer exists"/> | |
| 1455 | - | </enum> | |
| 1456 | - | ||
| 1457 | - | <event name="failed"> | |
| 1458 | - | <description summary="graceful error on creating the image description"> | |
| 1459 | - | If creating a wp_image_description_v1 object fails for a reason that is | |
| 1460 | - | not defined as a protocol error, this event is sent. | |
| 1461 | - | ||
| 1462 | - | The requests that create image description objects define whether and | |
| 1463 | - | when this can occur. Only such creation requests can trigger this event. | |
| 1464 | - | This event cannot be triggered after the image description was | |
| 1465 | - | successfully formed. | |
| 1466 | - | ||
| 1467 | - | Once this event has been sent, the wp_image_description_v1 object will | |
| 1468 | - | never become ready and it can only be destroyed. | |
| 1469 | - | </description> | |
| 1470 | - | ||
| 1471 | - | <arg name="cause" type="uint" enum="cause" | |
| 1472 | - | summary="generic reason"/> | |
| 1473 | - | <arg name="msg" type="string" | |
| 1474 | - | summary="ad hoc human-readable explanation"/> | |
| 1475 | - | </event> | |
| 1476 | - | ||
| 1477 | - | <event name="ready" deprecated-since="2"> | |
| 1478 | - | <description summary="the object is ready to be used (32-bit)"> | |
| 1479 | - | Starting from interface version 2, the 'ready2' event is sent instead | |
| 1480 | - | of this event. | |
| 1481 | - | ||
| 1482 | - | For the definition of this event, see the 'ready2' event. The | |
| 1483 | - | difference to this event is as follows. | |
| 1484 | - | ||
| 1485 | - | The id number is valid only as long as the protocol object is alive. If | |
| 1486 | - | all protocol objects referring to the same image description record are | |
| 1487 | - | destroyed, the id number may be recycled for a different image | |
| 1488 | - | description record. | |
| 1489 | - | </description> | |
| 1490 | - | ||
| 1491 | - | <arg name="identity" type="uint" | |
| 1492 | - | summary="the 32-bit image description id number"/> | |
| 1493 | - | </event> | |
| 1494 | - | ||
| 1495 | - | <request name="get_information"> | |
| 1496 | - | <description summary="get information about the image description"> | |
| 1497 | - | Creates a wp_image_description_info_v1 object which delivers the | |
| 1498 | - | information that makes up the image description. | |
| 1499 | - | ||
| 1500 | - | Not all image description protocol objects allow get_information | |
| 1501 | - | request. Whether it is allowed or not is defined by the request that | |
| 1502 | - | created the object. If get_information is not allowed, the protocol | |
| 1503 | - | error no_information is raised. | |
| 1504 | - | </description> | |
| 1505 | - | ||
| 1506 | - | <arg name="information" | |
| 1507 | - | type="new_id" interface="wp_image_description_info_v1"/> | |
| 1508 | - | </request> | |
| 1509 | - | ||
| 1510 | - | <!-- Version 2 additions --> | |
| 1511 | - | ||
| 1512 | - | <event name="ready2" since="2"> | |
| 1513 | - | <description summary="the object is ready to be used"> | |
| 1514 | - | Once this event has been sent, the wp_image_description_v1 object is | |
| 1515 | - | deemed "ready". Ready objects can be used to send requests and can be | |
| 1516 | - | used through other interfaces. | |
| 1517 | - | ||
| 1518 | - | Every ready wp_image_description_v1 protocol object refers to an | |
| 1519 | - | underlying image description record in the compositor. Multiple protocol | |
| 1520 | - | objects may end up referring to the same record. Clients may identify | |
| 1521 | - | these "copies" by comparing their id numbers: if the numbers from two | |
| 1522 | - | protocol objects are identical, the protocol objects refer to the same | |
| 1523 | - | image description record. Two different image description records | |
| 1524 | - | cannot have the same id number simultaneously. The id number does not | |
| 1525 | - | change during the lifetime of the image description record. | |
| 1526 | - | ||
| 1527 | - | Image description id number is not a protocol object id. Zero is | |
| 1528 | - | reserved as an invalid id number. It shall not be possible for a client | |
| 1529 | - | to refer to an image description by its id number in protocol. The id | |
| 1530 | - | numbers might not be portable between Wayland connections. A compositor | |
| 1531 | - | shall not send an invalid id number. | |
| 1532 | - | ||
| 1533 | - | Compositors must not recycle image description id numbers. | |
| 1534 | - | ||
| 1535 | - | This identity allows clients to de-duplicate image description records | |
| 1536 | - | and avoid get_information request if they already have the image | |
| 1537 | - | description information. | |
| 1538 | - | </description> | |
| 1539 | - | ||
| 1540 | - | <arg name="identity_hi" type="uint" | |
| 1541 | - | summary="high 32 bits of the 64-bit image description id number"/> | |
| 1542 | - | <arg name="identity_lo" type="uint" | |
| 1543 | - | summary="low 32 bits of the 64-bit image description id number"/> | |
| 1544 | - | </event> | |
| 1545 | - | </interface> | |
| 1546 | - | ||
| 1547 | - | <interface name="wp_image_description_info_v1" version="3"> | |
| 1548 | - | <description summary="Colorimetric image description information"> | |
| 1549 | - | Sends all matching events describing an image description object exactly | |
| 1550 | - | once and finally sends the 'done' event. | |
| 1551 | - | ||
| 1552 | - | This means | |
| 1553 | - | - if the image description is parametric, it must send | |
| 1554 | - | - primaries | |
| 1555 | - | - named_primaries, if applicable | |
| 1556 | - | - at least one of tf_power and tf_named, as applicable | |
| 1557 | - | - luminances | |
| 1558 | - | - target_primaries | |
| 1559 | - | - target_luminance | |
| 1560 | - | - if the image description is parametric, it may send, if applicable, | |
| 1561 | - | - target_max_cll | |
| 1562 | - | - target_max_fall | |
| 1563 | - | - if the image description contains an ICC profile, it must send the | |
| 1564 | - | icc_file event | |
| 1565 | - | ||
| 1566 | - | Once a wp_image_description_info_v1 object has delivered a 'done' event it | |
| 1567 | - | is automatically destroyed. | |
| 1568 | - | ||
| 1569 | - | Every wp_image_description_info_v1 created from the same | |
| 1570 | - | wp_image_description_v1 shall always return the exact same data. | |
| 1571 | - | </description> | |
| 1572 | - | ||
| 1573 | - | <event name="done" type="destructor"> | |
| 1574 | - | <description summary="end of information"> | |
| 1575 | - | Signals the end of information events and destroys the object. | |
| 1576 | - | </description> | |
| 1577 | - | </event> | |
| 1578 | - | ||
| 1579 | - | <event name="icc_file"> | |
| 1580 | - | <description summary="ICC profile matching the image description"> | |
| 1581 | - | The icc argument provides a file descriptor to the client which may be | |
| 1582 | - | memory-mapped to provide the ICC profile matching the image description. | |
| 1583 | - | The fd is read-only, and if mapped then it must be mapped with | |
| 1584 | - | MAP_PRIVATE by the client. | |
| 1585 | - | ||
| 1586 | - | The ICC profile version and other details are determined by the | |
| 1587 | - | compositor. There is no provision for a client to ask for a specific | |
| 1588 | - | kind of a profile. | |
| 1589 | - | </description> | |
| 1590 | - | ||
| 1591 | - | <arg name="icc" type="fd" summary="ICC profile file descriptor"/> | |
| 1592 | - | <arg name="icc_size" type="uint" summary="ICC profile size, in bytes"/> | |
| 1593 | - | <!-- Offset always 0, compositor must not expose unnecessary data. --> | |
| 1594 | - | </event> | |
| 1595 | - | ||
| 1596 | - | <event name="primaries"> | |
| 1597 | - | <description summary="primaries as chromaticity coordinates"> | |
| 1598 | - | Delivers the primary color volume primaries and white point using CIE | |
| 1599 | - | 1931 xy chromaticity coordinates. | |
| 1600 | - | ||
| 1601 | - | Each coordinate value is multiplied by 1 million to get the argument | |
| 1602 | - | value to carry precision of 6 decimals. | |
| 1603 | - | </description> | |
| 1604 | - | ||
| 1605 | - | <arg name="r_x" type="int" summary="Red x * 1M"/> | |
| 1606 | - | <arg name="r_y" type="int" summary="Red y * 1M"/> | |
| 1607 | - | <arg name="g_x" type="int" summary="Green x * 1M"/> | |
| 1608 | - | <arg name="g_y" type="int" summary="Green y * 1M"/> | |
| 1609 | - | <arg name="b_x" type="int" summary="Blue x * 1M"/> | |
| 1610 | - | <arg name="b_y" type="int" summary="Blue y * 1M"/> | |
| 1611 | - | <arg name="w_x" type="int" summary="White x * 1M"/> | |
| 1612 | - | <arg name="w_y" type="int" summary="White y * 1M"/> | |
| 1613 | - | </event> | |
| 1614 | - | ||
| 1615 | - | <event name="primaries_named"> | |
| 1616 | - | <description summary="named primaries"> | |
| 1617 | - | Delivers the primary color volume primaries and white point using an | |
| 1618 | - | explicitly enumerated named set. | |
| 1619 | - | </description> | |
| 1620 | - | ||
| 1621 | - | <arg name="primaries" type="uint" enum="wp_color_manager_v1.primaries" | |
| 1622 | - | summary="named primaries"/> | |
| 1623 | - | </event> | |
| 1624 | - | ||
| 1625 | - | <event name="tf_power"> | |
| 1626 | - | <description summary="transfer characteristic as a power curve"> | |
| 1627 | - | The color component transfer characteristic of this image description is | |
| 1628 | - | a pure power curve. This event provides the exponent of the power | |
| 1629 | - | function. This curve represents the conversion from electrical to | |
| 1630 | - | optical pixel or color values. | |
| 1631 | - | ||
| 1632 | - | The curve exponent has been multiplied by 10000 to get the argument eexp | |
| 1633 | - | value to carry the precision of 4 decimals. | |
| 1634 | - | </description> | |
| 1635 | - | ||
| 1636 | - | <arg name="eexp" type="uint" summary="the exponent * 10000"/> | |
| 1637 | - | </event> | |
| 1638 | - | ||
| 1639 | - | <event name="tf_named"> | |
| 1640 | - | <description summary="named transfer characteristic"> | |
| 1641 | - | Delivers the transfer characteristic using an explicitly enumerated | |
| 1642 | - | named function. | |
| 1643 | - | </description> | |
| 1644 | - | ||
| 1645 | - | <arg name="tf" type="uint" enum="wp_color_manager_v1.transfer_function" | |
| 1646 | - | summary="named transfer function"/> | |
| 1647 | - | </event> | |
| 1648 | - | ||
| 1649 | - | <event name="luminances"> | |
| 1650 | - | <description summary="primary color volume luminance range and reference white"> | |
| 1651 | - | Delivers the primary color volume luminance range and the reference | |
| 1652 | - | white luminance level. These values include the minimum display emission | |
| 1653 | - | and ambient flare luminances, assumed to be optically additive and have | |
| 1654 | - | the chromaticity of the primary color volume white point. | |
| 1655 | - | ||
| 1656 | - | The minimum luminance is multiplied by 10000 to get the argument | |
| 1657 | - | 'min_lum' value and carries precision of 4 decimals. The maximum | |
| 1658 | - | luminance and reference white luminance values are unscaled. | |
| 1659 | - | </description> | |
| 1660 | - | ||
| 1661 | - | <arg name="min_lum" type="uint" | |
| 1662 | - | summary="minimum luminance (cd/m²) * 10000"/> | |
| 1663 | - | <arg name="max_lum" type="uint" | |
| 1664 | - | summary="maximum luminance (cd/m²)"/> | |
| 1665 | - | <arg name="reference_lum" type="uint" | |
| 1666 | - | summary="reference white luminance (cd/m²)"/> | |
| 1667 | - | </event> | |
| 1668 | - | ||
| 1669 | - | <event name="target_primaries"> | |
| 1670 | - | <description summary="target primaries as chromaticity coordinates"> | |
| 1671 | - | Provides the color primaries and white point of the target color volume | |
| 1672 | - | using CIE 1931 xy chromaticity coordinates. This is compatible with the | |
| 1673 | - | SMPTE ST 2086 definition of HDR static metadata for mastering displays. | |
| 1674 | - | ||
| 1675 | - | While primary color volume is about how color is encoded, the target | |
| 1676 | - | color volume is the actually displayable color volume. | |
| 1677 | - | ||
| 1678 | - | Each coordinate value is multiplied by 1 million to get the argument | |
| 1679 | - | value to carry precision of 6 decimals. | |
| 1680 | - | </description> | |
| 1681 | - | ||
| 1682 | - | <arg name="r_x" type="int" summary="Red x * 1M"/> | |
| 1683 | - | <arg name="r_y" type="int" summary="Red y * 1M"/> | |
| 1684 | - | <arg name="g_x" type="int" summary="Green x * 1M"/> | |
| 1685 | - | <arg name="g_y" type="int" summary="Green y * 1M"/> | |
| 1686 | - | <arg name="b_x" type="int" summary="Blue x * 1M"/> | |
| 1687 | - | <arg name="b_y" type="int" summary="Blue y * 1M"/> | |
| 1688 | - | <arg name="w_x" type="int" summary="White x * 1M"/> | |
| 1689 | - | <arg name="w_y" type="int" summary="White y * 1M"/> | |
| 1690 | - | </event> | |
| 1691 | - | ||
| 1692 | - | <event name="target_luminance"> | |
| 1693 | - | <description summary="target luminance range"> | |
| 1694 | - | Provides the luminance range that the image description is targeting as | |
| 1695 | - | the minimum and maximum absolute luminance L. These values include the | |
| 1696 | - | minimum display emission and ambient flare luminances, assumed to be | |
| 1697 | - | optically additive and have the chromaticity of the primary color | |
| 1698 | - | volume white point. This should be compatible with the SMPTE ST 2086 | |
| 1699 | - | definition of HDR static metadata. | |
| 1700 | - | ||
| 1701 | - | This luminance range is only theoretical and may not correspond to the | |
| 1702 | - | luminance of light emitted on an actual display. | |
| 1703 | - | ||
| 1704 | - | Min L value is multiplied by 10000 to get the argument min_lum value and | |
| 1705 | - | carry precision of 4 decimals. Max L value is unscaled for max_lum. | |
| 1706 | - | </description> | |
| 1707 | - | ||
| 1708 | - | <arg name="min_lum" type="uint" summary="min L (cd/m²) * 10000"/> | |
| 1709 | - | <arg name="max_lum" type="uint" summary="max L (cd/m²)"/> | |
| 1710 | - | </event> | |
| 1711 | - | ||
| 1712 | - | <event name="target_max_cll"> | |
| 1713 | - | <description summary="target maximum content light level"> | |
| 1714 | - | Provides the targeted max_cll of the image description. max_cll is | |
| 1715 | - | defined by CTA-861-H. | |
| 1716 | - | ||
| 1717 | - | This luminance is only theoretical and may not correspond to the | |
| 1718 | - | luminance of light emitted on an actual display. | |
| 1719 | - | </description> | |
| 1720 | - | ||
| 1721 | - | <arg name="max_cll" type="uint" | |
| 1722 | - | summary="Maximum content light-level (cd/m²)"/> | |
| 1723 | - | </event> | |
| 1724 | - | ||
| 1725 | - | <event name="target_max_fall"> | |
| 1726 | - | <description summary="target maximum frame-average light level"> | |
| 1727 | - | Provides the targeted max_fall of the image description. max_fall is | |
| 1728 | - | defined by CTA-861-H. | |
| 1729 | - | ||
| 1730 | - | This luminance is only theoretical and may not correspond to the | |
| 1731 | - | luminance of light emitted on an actual display. | |
| 1732 | - | </description> | |
| 1733 | - | ||
| 1734 | - | <arg name="max_fall" type="uint" | |
| 1735 | - | summary="Maximum frame-average light level (cd/m²)"/> | |
| 1736 | - | </event> | |
| 1737 | - | </interface> | |
| 1738 | - | ||
| 1739 | - | <interface name="wp_image_description_reference_v1" version="1" frozen="true"> | |
| 1740 | - | <description summary="Reference to an image description"> | |
| 1741 | - | This object is a reference to an image description. This interface is | |
| 1742 | - | frozen at version 1 to allow other protocols to create | |
| 1743 | - | wp_image_description_v1 objects. | |
| 1744 | - | ||
| 1745 | - | The wp_color_manager_v1.get_image_description request can be used to | |
| 1746 | - | retrieve the underlying image description. | |
| 1747 | - | </description> | |
| 1748 | - | ||
| 1749 | - | <request name="destroy" type="destructor"> | |
| 1750 | - | <description summary="destroy the reference"> | |
| 1751 | - | Destroy this object. This has no effect on the referenced image | |
| 1752 | - | description. | |
| 1753 | - | </description> | |
| 1754 | - | </request> | |
| 1755 | - | </interface> | |
| 1756 | - | </protocol> | |
D protocol/colormanagement/color-management-v1_generated.go +0 -1554
| @@ -1,1554 +0,0 @@ | |||
| 1 | - | // Code generated by wlturbo-scanner. DO NOT EDIT. | |
| 2 | - | // Protocol: color_management_v1 | |
| 3 | - | // Source: color-management-v1.xml | |
| 4 | - | ||
| 5 | - | // Upstream protocol copyright and license: | |
| 6 | - | // Copyright 2019 Sebastian Wick | |
| 7 | - | // Copyright 2019 Erwin Burema | |
| 8 | - | // Copyright 2020 AMD | |
| 9 | - | // Copyright 2020-2024 Collabora, Ltd. | |
| 10 | - | // Copyright 2024 Xaver Hugl | |
| 11 | - | // Copyright 2022-2025 Red Hat, Inc. | |
| 12 | - | // | |
| 13 | - | // Permission is hereby granted, free of charge, to any person obtaining a | |
| 14 | - | // copy of this software and associated documentation files (the "Software"), | |
| 15 | - | // to deal in the Software without restriction, including without limitation | |
| 16 | - | // the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 17 | - | // and/or sell copies of the Software, and to permit persons to whom the | |
| 18 | - | // Software is furnished to do so, subject to the following conditions: | |
| 19 | - | // | |
| 20 | - | // The above copyright notice and this permission notice (including the next | |
| 21 | - | // paragraph) shall be included in all copies or substantial portions of the | |
| 22 | - | // Software. | |
| 23 | - | // | |
| 24 | - | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 25 | - | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 26 | - | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 27 | - | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 28 | - | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 29 | - | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
| 30 | - | // DEALINGS IN THE SOFTWARE. | |
| 31 | - | ||
| 32 | - | package colormanagement | |
| 33 | - | ||
| 34 | - | import ( | |
| 35 | - | "sync" | |
| 36 | - | ||
| 37 | - | cross_wl_output "github.com/bnema/wlturbo/protocol/core" | |
| 38 | - | cross_wl_surface "github.com/bnema/wlturbo/protocol/core" | |
| 39 | - | "github.com/bnema/wlturbo/wl" | |
| 40 | - | ) | |
| 41 | - | ||
| 42 | - | // WP_COLOR_MANAGER_V1_ERROR_UNSUPPORTED_FEATURE is the error unsupported_feature value. | |
| 43 | - | const WP_COLOR_MANAGER_V1_ERROR_UNSUPPORTED_FEATURE = 0 | |
| 44 | - | ||
| 45 | - | // ERROR_SURFACE_EXISTS is the error surface_exists value. | |
| 46 | - | const ERROR_SURFACE_EXISTS = 1 | |
| 47 | - | ||
| 48 | - | // RENDER_INTENT_PERCEPTUAL is the render_intent perceptual value. | |
| 49 | - | const RENDER_INTENT_PERCEPTUAL = 0 | |
| 50 | - | ||
| 51 | - | // RENDER_INTENT_RELATIVE is the render_intent relative value. | |
| 52 | - | const RENDER_INTENT_RELATIVE = 1 | |
| 53 | - | ||
| 54 | - | // RENDER_INTENT_SATURATION is the render_intent saturation value. | |
| 55 | - | const RENDER_INTENT_SATURATION = 2 | |
| 56 | - | ||
| 57 | - | // RENDER_INTENT_ABSOLUTE is the render_intent absolute value. | |
| 58 | - | const RENDER_INTENT_ABSOLUTE = 3 | |
| 59 | - | ||
| 60 | - | // RENDER_INTENT_RELATIVE_BPC is the render_intent relative_bpc value. | |
| 61 | - | const RENDER_INTENT_RELATIVE_BPC = 4 | |
| 62 | - | ||
| 63 | - | // RENDER_INTENT_ABSOLUTE_NO_ADAPTATION is the render_intent absolute_no_adaptation value. | |
| 64 | - | const RENDER_INTENT_ABSOLUTE_NO_ADAPTATION = 5 | |
| 65 | - | ||
| 66 | - | // FEATURE_ICC_V2_V4 is the feature icc_v2_v4 value. | |
| 67 | - | const FEATURE_ICC_V2_V4 = 0 | |
| 68 | - | ||
| 69 | - | // FEATURE_PARAMETRIC is the feature parametric value. | |
| 70 | - | const FEATURE_PARAMETRIC = 1 | |
| 71 | - | ||
| 72 | - | // FEATURE_SET_PRIMARIES is the feature set_primaries value. | |
| 73 | - | const FEATURE_SET_PRIMARIES = 2 | |
| 74 | - | ||
| 75 | - | // FEATURE_SET_TF_POWER is the feature set_tf_power value. | |
| 76 | - | const FEATURE_SET_TF_POWER = 3 | |
| 77 | - | ||
| 78 | - | // FEATURE_SET_LUMINANCES is the feature set_luminances value. | |
| 79 | - | const FEATURE_SET_LUMINANCES = 4 | |
| 80 | - | ||
| 81 | - | // FEATURE_SET_MASTERING_DISPLAY_PRIMARIES is the feature set_mastering_display_primaries value. | |
| 82 | - | const FEATURE_SET_MASTERING_DISPLAY_PRIMARIES = 5 | |
| 83 | - | ||
| 84 | - | // FEATURE_EXTENDED_TARGET_VOLUME is the feature extended_target_volume value. | |
| 85 | - | const FEATURE_EXTENDED_TARGET_VOLUME = 6 | |
| 86 | - | ||
| 87 | - | // FEATURE_WINDOWS_SCRGB is the feature windows_scrgb value. | |
| 88 | - | const FEATURE_WINDOWS_SCRGB = 7 | |
| 89 | - | ||
| 90 | - | // FEATURE_WINDOWS_BT2100 is the feature windows_bt2100 value. | |
| 91 | - | const FEATURE_WINDOWS_BT2100 = 8 | |
| 92 | - | ||
| 93 | - | // PRIMARIES_SRGB is the primaries srgb value. | |
| 94 | - | const PRIMARIES_SRGB = 1 | |
| 95 | - | ||
| 96 | - | // PRIMARIES_PAL_M is the primaries pal_m value. | |
| 97 | - | const PRIMARIES_PAL_M = 2 | |
| 98 | - | ||
| 99 | - | // PRIMARIES_PAL is the primaries pal value. | |
| 100 | - | const PRIMARIES_PAL = 3 | |
| 101 | - | ||
| 102 | - | // PRIMARIES_NTSC is the primaries ntsc value. | |
| 103 | - | const PRIMARIES_NTSC = 4 | |
| 104 | - | ||
| 105 | - | // PRIMARIES_GENERIC_FILM is the primaries generic_film value. | |
| 106 | - | const PRIMARIES_GENERIC_FILM = 5 | |
| 107 | - | ||
| 108 | - | // PRIMARIES_BT2020 is the primaries bt2020 value. | |
| 109 | - | const PRIMARIES_BT2020 = 6 | |
| 110 | - | ||
| 111 | - | // PRIMARIES_CIE1931_XYZ is the primaries cie1931_xyz value. | |
| 112 | - | const PRIMARIES_CIE1931_XYZ = 7 | |
| 113 | - | ||
| 114 | - | // PRIMARIES_DCI_P3 is the primaries dci_p3 value. | |
| 115 | - | const PRIMARIES_DCI_P3 = 8 | |
| 116 | - | ||
| 117 | - | // PRIMARIES_DISPLAY_P3 is the primaries display_p3 value. | |
| 118 | - | const PRIMARIES_DISPLAY_P3 = 9 | |
| 119 | - | ||
| 120 | - | // PRIMARIES_ADOBE_RGB is the primaries adobe_rgb value. | |
| 121 | - | const PRIMARIES_ADOBE_RGB = 10 | |
| 122 | - | ||
| 123 | - | // TRANSFER_FUNCTION_BT1886 is the transfer_function bt1886 value. | |
| 124 | - | const TRANSFER_FUNCTION_BT1886 = 1 | |
| 125 | - | ||
| 126 | - | // TRANSFER_FUNCTION_GAMMA22 is the transfer_function gamma22 value. | |
| 127 | - | const TRANSFER_FUNCTION_GAMMA22 = 2 | |
| 128 | - | ||
| 129 | - | // TRANSFER_FUNCTION_GAMMA28 is the transfer_function gamma28 value. | |
| 130 | - | const TRANSFER_FUNCTION_GAMMA28 = 3 | |
| 131 | - | ||
| 132 | - | // TRANSFER_FUNCTION_ST240 is the transfer_function st240 value. | |
| 133 | - | const TRANSFER_FUNCTION_ST240 = 4 | |
| 134 | - | ||
| 135 | - | // TRANSFER_FUNCTION_EXT_LINEAR is the transfer_function ext_linear value. | |
| 136 | - | const TRANSFER_FUNCTION_EXT_LINEAR = 5 | |
| 137 | - | ||
| 138 | - | // TRANSFER_FUNCTION_LOG_100 is the transfer_function log_100 value. | |
| 139 | - | const TRANSFER_FUNCTION_LOG_100 = 6 | |
| 140 | - | ||
| 141 | - | // TRANSFER_FUNCTION_LOG_316 is the transfer_function log_316 value. | |
| 142 | - | const TRANSFER_FUNCTION_LOG_316 = 7 | |
| 143 | - | ||
| 144 | - | // TRANSFER_FUNCTION_XVYCC is the transfer_function xvycc value. | |
| 145 | - | const TRANSFER_FUNCTION_XVYCC = 8 | |
| 146 | - | ||
| 147 | - | // TRANSFER_FUNCTION_SRGB is the transfer_function srgb value. | |
| 148 | - | const TRANSFER_FUNCTION_SRGB = 9 | |
| 149 | - | ||
| 150 | - | // TRANSFER_FUNCTION_EXT_SRGB is the transfer_function ext_srgb value. | |
| 151 | - | const TRANSFER_FUNCTION_EXT_SRGB = 10 | |
| 152 | - | ||
| 153 | - | // TRANSFER_FUNCTION_ST2084_PQ is the transfer_function st2084_pq value. | |
| 154 | - | const TRANSFER_FUNCTION_ST2084_PQ = 11 | |
| 155 | - | ||
| 156 | - | // TRANSFER_FUNCTION_ST428 is the transfer_function st428 value. | |
| 157 | - | const TRANSFER_FUNCTION_ST428 = 12 | |
| 158 | - | ||
| 159 | - | // TRANSFER_FUNCTION_HLG is the transfer_function hlg value. | |
| 160 | - | const TRANSFER_FUNCTION_HLG = 13 | |
| 161 | - | ||
| 162 | - | // TRANSFER_FUNCTION_COMPOUND_POWER_2_4 is the transfer_function compound_power_2_4 value. | |
| 163 | - | const TRANSFER_FUNCTION_COMPOUND_POWER_2_4 = 14 | |
| 164 | - | ||
| 165 | - | // ERROR_RENDER_INTENT is the error render_intent value. | |
| 166 | - | const ERROR_RENDER_INTENT = 0 | |
| 167 | - | ||
| 168 | - | // ERROR_IMAGE_DESCRIPTION is the error image_description value. | |
| 169 | - | const ERROR_IMAGE_DESCRIPTION = 1 | |
| 170 | - | ||
| 171 | - | // WP_COLOR_MANAGEMENT_SURFACE_V1_ERROR_INERT is the error inert value. | |
| 172 | - | const WP_COLOR_MANAGEMENT_SURFACE_V1_ERROR_INERT = 2 | |
| 173 | - | ||
| 174 | - | // WP_COLOR_MANAGEMENT_SURFACE_FEEDBACK_V1_ERROR_INERT is the error inert value. | |
| 175 | - | const WP_COLOR_MANAGEMENT_SURFACE_FEEDBACK_V1_ERROR_INERT = 0 | |
| 176 | - | ||
| 177 | - | // WP_COLOR_MANAGEMENT_SURFACE_FEEDBACK_V1_ERROR_UNSUPPORTED_FEATURE is the error unsupported_feature value. | |
| 178 | - | const WP_COLOR_MANAGEMENT_SURFACE_FEEDBACK_V1_ERROR_UNSUPPORTED_FEATURE = 1 | |
| 179 | - | ||
| 180 | - | // WP_IMAGE_DESCRIPTION_CREATOR_ICC_V1_ERROR_INCOMPLETE_SET is the error incomplete_set value. | |
| 181 | - | const WP_IMAGE_DESCRIPTION_CREATOR_ICC_V1_ERROR_INCOMPLETE_SET = 0 | |
| 182 | - | ||
| 183 | - | // WP_IMAGE_DESCRIPTION_CREATOR_ICC_V1_ERROR_ALREADY_SET is the error already_set value. | |
| 184 | - | const WP_IMAGE_DESCRIPTION_CREATOR_ICC_V1_ERROR_ALREADY_SET = 1 | |
| 185 | - | ||
| 186 | - | // ERROR_BAD_FD is the error bad_fd value. | |
| 187 | - | const ERROR_BAD_FD = 2 | |
| 188 | - | ||
| 189 | - | // ERROR_BAD_SIZE is the error bad_size value. | |
| 190 | - | const ERROR_BAD_SIZE = 3 | |
| 191 | - | ||
| 192 | - | // ERROR_OUT_OF_FILE is the error out_of_file value. | |
| 193 | - | const ERROR_OUT_OF_FILE = 4 | |
| 194 | - | ||
| 195 | - | // WP_IMAGE_DESCRIPTION_CREATOR_PARAMS_V1_ERROR_INCOMPLETE_SET is the error incomplete_set value. | |
| 196 | - | const WP_IMAGE_DESCRIPTION_CREATOR_PARAMS_V1_ERROR_INCOMPLETE_SET = 0 | |
| 197 | - | ||
| 198 | - | // WP_IMAGE_DESCRIPTION_CREATOR_PARAMS_V1_ERROR_ALREADY_SET is the error already_set value. | |
| 199 | - | const WP_IMAGE_DESCRIPTION_CREATOR_PARAMS_V1_ERROR_ALREADY_SET = 1 | |
| 200 | - | ||
| 201 | - | // WP_IMAGE_DESCRIPTION_CREATOR_PARAMS_V1_ERROR_UNSUPPORTED_FEATURE is the error unsupported_feature value. | |
| 202 | - | const WP_IMAGE_DESCRIPTION_CREATOR_PARAMS_V1_ERROR_UNSUPPORTED_FEATURE = 2 | |
| 203 | - | ||
| 204 | - | // ERROR_INVALID_TF is the error invalid_tf value. | |
| 205 | - | const ERROR_INVALID_TF = 3 | |
| 206 | - | ||
| 207 | - | // ERROR_INVALID_PRIMARIES_NAMED is the error invalid_primaries_named value. | |
| 208 | - | const ERROR_INVALID_PRIMARIES_NAMED = 4 | |
| 209 | - | ||
| 210 | - | // ERROR_INVALID_LUMINANCE is the error invalid_luminance value. | |
| 211 | - | const ERROR_INVALID_LUMINANCE = 5 | |
| 212 | - | ||
| 213 | - | // ERROR_NOT_READY is the error not_ready value. | |
| 214 | - | const ERROR_NOT_READY = 0 | |
| 215 | - | ||
| 216 | - | // ERROR_NO_INFORMATION is the error no_information value. | |
| 217 | - | const ERROR_NO_INFORMATION = 1 | |
| 218 | - | ||
| 219 | - | // CAUSE_LOW_VERSION is the cause low_version value. | |
| 220 | - | const CAUSE_LOW_VERSION = 0 | |
| 221 | - | ||
| 222 | - | // CAUSE_UNSUPPORTED is the cause unsupported value. | |
| 223 | - | const CAUSE_UNSUPPORTED = 1 | |
| 224 | - | ||
| 225 | - | // CAUSE_OPERATING_SYSTEM is the cause operating_system value. | |
| 226 | - | const CAUSE_OPERATING_SYSTEM = 2 | |
| 227 | - | ||
| 228 | - | // CAUSE_NO_OUTPUT is the cause no_output value. | |
| 229 | - | const CAUSE_NO_OUTPUT = 3 | |
| 230 | - | ||
| 231 | - | // WpColorManagerInterface is the protocol interface name. | |
| 232 | - | const WpColorManagerInterface = "wp_color_manager_v1" | |
| 233 | - | ||
| 234 | - | // WpColorManager is the generated binding for wp_color_manager_v1 version 3. | |
| 235 | - | type WpColorManager struct { | |
| 236 | - | wl.BaseProxy | |
| 237 | - | // handlersMu guards the handler slices: a client may register or replace | |
| 238 | - | // handlers while another goroutine dispatches events. | |
| 239 | - | handlersMu sync.Mutex | |
| 240 | - | onSupportedIntent []func(renderIntent uint32) | |
| 241 | - | onSupportedFeature []func(feature uint32) | |
| 242 | - | onSupportedTfNamed []func(tf uint32) | |
| 243 | - | onSupportedPrimariesNamed []func(primaries uint32) | |
| 244 | - | onDone []func() | |
| 245 | - | } | |
| 246 | - | ||
| 247 | - | // NewWpColorManager returns an unbound WpColorManager. | |
| 248 | - | func NewWpColorManager(ctx *wl.Context) *WpColorManager { | |
| 249 | - | obj := &WpColorManager{} | |
| 250 | - | obj.SetContext(ctx) | |
| 251 | - | ctx.Register(obj) | |
| 252 | - | return obj | |
| 253 | - | } | |
| 254 | - | ||
| 255 | - | // Destroy the wp_color_manager_v1 object. This does not affect any other objects in any way. | |
| 256 | - | func (o *WpColorManager) Destroy() error { | |
| 257 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "wp_color_manager_v1.destroy", Destructor: true}); err != nil { | |
| 258 | - | return err | |
| 259 | - | } | |
| 260 | - | return nil | |
| 261 | - | } | |
| 262 | - | ||
| 263 | - | // This creates a new wp_color_management_output_v1 object for the given wl_output. See the wp_color_management_output_v1 interface for more details. | |
| 264 | - | func (o *WpColorManager) GetOutput(output *cross_wl_output.Output) (*WpColorManagementOutput, error) { | |
| 265 | - | var arg1 wl.Object | |
| 266 | - | if output != nil { | |
| 267 | - | arg1 = output | |
| 268 | - | } | |
| 269 | - | child := &WpColorManagementOutput{} | |
| 270 | - | child.SetContext(o.Context()) | |
| 271 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "wp_color_manager_v1.get_output", Child: child}, wl.ArgObject(child), wl.ArgObject(arg1)); err != nil { | |
| 272 | - | return nil, err | |
| 273 | - | } | |
| 274 | - | return child, nil | |
| 275 | - | } | |
| 276 | - | ||
| 277 | - | // If a wp_color_management_surface_v1 object already exists for the given wl_surface, the protocol error surface_exists is raised. This creates a new color wp_color_management_surface_v1 object for the given wl_surface. See the wp_color_management_surface_v1 interface for more details. | |
| 278 | - | func (o *WpColorManager) GetSurface(surface *cross_wl_surface.Surface) (*WpColorManagementSurface, error) { | |
| 279 | - | var arg1 wl.Object | |
| 280 | - | if surface != nil { | |
| 281 | - | arg1 = surface | |
| 282 | - | } | |
| 283 | - | child := &WpColorManagementSurface{} | |
| 284 | - | child.SetContext(o.Context()) | |
| 285 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 2, Name: "wp_color_manager_v1.get_surface", Child: child}, wl.ArgObject(child), wl.ArgObject(arg1)); err != nil { | |
| 286 | - | return nil, err | |
| 287 | - | } | |
| 288 | - | return child, nil | |
| 289 | - | } | |
| 290 | - | ||
| 291 | - | // This creates a new color wp_color_management_surface_feedback_v1 object for the given wl_surface. See the wp_color_management_surface_feedback_v1 interface for more details. | |
| 292 | - | func (o *WpColorManager) GetSurfaceFeedback(surface *cross_wl_surface.Surface) (*WpColorManagementSurfaceFeedback, error) { | |
| 293 | - | var arg1 wl.Object | |
| 294 | - | if surface != nil { | |
| 295 | - | arg1 = surface | |
| 296 | - | } | |
| 297 | - | child := &WpColorManagementSurfaceFeedback{} | |
| 298 | - | child.SetContext(o.Context()) | |
| 299 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 3, Name: "wp_color_manager_v1.get_surface_feedback", Child: child}, wl.ArgObject(child), wl.ArgObject(arg1)); err != nil { | |
| 300 | - | return nil, err | |
| 301 | - | } | |
| 302 | - | return child, nil | |
| 303 | - | } | |
| 304 | - | ||
| 305 | - | // Makes a new ICC-based image description creator object with all properties initially unset. The client can then use the object's interface to define all the required properties for an image description and finally create a wp_image_description_v1 object. This request can be used when the compositor advertises wp_color_manager_v1.feature.icc_v2_v4. Otherwise this request raises the protocol error unsupported_feature. | |
| 306 | - | func (o *WpColorManager) CreateIccCreator() (*WpImageDescriptionCreatorIcc, error) { | |
| 307 | - | child := &WpImageDescriptionCreatorIcc{} | |
| 308 | - | child.SetContext(o.Context()) | |
| 309 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 4, Name: "wp_color_manager_v1.create_icc_creator", Child: child}, wl.ArgObject(child)); err != nil { | |
| 310 | - | return nil, err | |
| 311 | - | } | |
| 312 | - | return child, nil | |
| 313 | - | } | |
| 314 | - | ||
| 315 | - | // Makes a new parametric image description creator object with all properties initially unset. The client can then use the object's interface to define all the required properties for an image description and finally create a wp_image_description_v1 object. This request can be used when the compositor advertises wp_color_manager_v1.feature.parametric. Otherwise this request raises the protocol error unsupported_feature. | |
| 316 | - | func (o *WpColorManager) CreateParametricCreator() (*WpImageDescriptionCreatorParams, error) { | |
| 317 | - | child := &WpImageDescriptionCreatorParams{} | |
| 318 | - | child.SetContext(o.Context()) | |
| 319 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 5, Name: "wp_color_manager_v1.create_parametric_creator", Child: child}, wl.ArgObject(child)); err != nil { | |
| 320 | - | return nil, err | |
| 321 | - | } | |
| 322 | - | return child, nil | |
| 323 | - | } | |
| 324 | - | ||
| 325 | - | // This creates a pre-defined image description for the so-called Windows-scRGB stimulus encoding. This comes from the Windows 10 handling of its own definition of an scRGB color space for an HDR screen driven in BT.2100/PQ signalling mode. Windows-scRGB uses sRGB (BT.709) color primaries and white point. The transfer characteristic is extended linear. The nominal color channel value range is extended, meaning it includes negative and greater than 1.0 values. Negative values are used to escape the sRGB color gamut boundaries. To make use of the extended range, the client needs to use a pixel format that can represent those values, e.g. floating-point 16 bits per channel. Nominal color value R=G=B=0.0 corresponds to BT.2100/PQ system 0 cd/m², and R=G=B=1.0 corresponds to BT.2100/PQ system 80 cd/m². The maximum is R=G=B=125.0 corresponding to 10k cd/m². Windows-scRGB is displayed by Windows 10 by converting it to BT.2100/PQ, maintaining the CIE 1931 chromaticity and mapping the luminance as above. No adjustment is made to the signal to account for the viewing conditions. The reference white level of Windows-scRGB is unknown. If a reference white level must be assumed for compositor processing, it should be R=G=B=2.5375 corresponding to 203 cd/m² of Report ITU-R BT.2408-7. The target color volume of Windows-scRGB is unknown. The color gamut may be anything between sRGB and BT.2100. Note: EGL_EXT_gl_colorspace_scrgb_linear definition differs from Windows-scRGB by using R=G=B=1.0 as the reference white level, while Windows-scRGB reference white level is unknown or varies. However, it seems probable that Windows implements both EGL_EXT_gl_colorspace_scrgb_linear and Vulkan VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT as Windows-scRGB. This request can be used when the compositor advertises wp_color_manager_v1.feature.windows_scrgb. Otherwise this request raises the protocol error unsupported_feature. The resulting image description object does not allow get_information request. The wp_image_description_v1.ready event shall be sent. | |
| 326 | - | func (o *WpColorManager) CreateWindowsScrgb() (*WpImageDescription, error) { | |
| 327 | - | child := &WpImageDescription{} | |
| 328 | - | child.SetContext(o.Context()) | |
| 329 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 6, Name: "wp_color_manager_v1.create_windows_scrgb", Child: child}, wl.ArgObject(child)); err != nil { | |
| 330 | - | return nil, err | |
| 331 | - | } | |
| 332 | - | return child, nil | |
| 333 | - | } | |
| 334 | - | ||
| 335 | - | // This request retrieves the image description backing a reference. The get_information request can be used if and only if the request that creates the reference allows it. | |
| 336 | - | func (o *WpColorManager) GetImageDescription(reference *WpImageDescriptionReference) (*WpImageDescription, error) { | |
| 337 | - | var arg1 wl.Object | |
| 338 | - | if reference != nil { | |
| 339 | - | arg1 = reference | |
| 340 | - | } | |
| 341 | - | child := &WpImageDescription{} | |
| 342 | - | child.SetContext(o.Context()) | |
| 343 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 7, Name: "wp_color_manager_v1.get_image_description", Since: 2, Child: child}, wl.ArgObject(child), wl.ArgObject(arg1)); err != nil { | |
| 344 | - | return nil, err | |
| 345 | - | } | |
| 346 | - | return child, nil | |
| 347 | - | } | |
| 348 | - | ||
| 349 | - | // This creates a pre-defined image description for the so-called Windows-BT.2100 stimulus encoding. This comes from the Windows 10 handling of its own definition of a BT.2100 color space for an HDR screen driven in BT.2100/PQ signalling mode. Windows-BT.2100 uses BT.2020 color primaries and white point. The transfer characteristic is st2084_pq. Windows-BT.2100 is generally displayed by Windows 10 without any adjustments to the signal to account for viewing conditions. The reference white level of Windows-BT.2100 is unknown. If a reference white level must be assumed for compositor processing, it should be 203 cd/m² of Report ITU-R BT.2408-7. The target color volume of Windows-BT.2100 is unknown. The color gamut may be anything up to BT.2100. This request can be used when the compositor advertises wp_color_manager_v1.feature.windows_bt2100. Otherwise this request raises the protocol error unsupported_feature. The resulting image description object does not allow get_information request. The wp_image_description_v1.ready event shall be sent. | |
| 350 | - | func (o *WpColorManager) CreateWindowsBt2100() (*WpImageDescription, error) { | |
| 351 | - | child := &WpImageDescription{} | |
| 352 | - | child.SetContext(o.Context()) | |
| 353 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 8, Name: "wp_color_manager_v1.create_windows_bt2100", Since: 3, Child: child}, wl.ArgObject(child)); err != nil { | |
| 354 | - | return nil, err | |
| 355 | - | } | |
| 356 | - | return child, nil | |
| 357 | - | } | |
| 358 | - | ||
| 359 | - | // OnSupportedIntent registers a handler for the supported_intent event. | |
| 360 | - | // | |
| 361 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 362 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 363 | - | func (o *WpColorManager) OnSupportedIntent(handler func(renderIntent uint32)) { | |
| 364 | - | if handler == nil { | |
| 365 | - | return | |
| 366 | - | } | |
| 367 | - | o.handlersMu.Lock() | |
| 368 | - | defer o.handlersMu.Unlock() | |
| 369 | - | o.onSupportedIntent = append(o.onSupportedIntent, handler) | |
| 370 | - | } | |
| 371 | - | ||
| 372 | - | // handlersForSupportedIntent returns the handlers registered for supported_intent, taken | |
| 373 | - | // under the lock so a handler may register another handler while events are | |
| 374 | - | // being dispatched. | |
| 375 | - | func (o *WpColorManager) handlersForSupportedIntent() []func(renderIntent uint32) { | |
| 376 | - | o.handlersMu.Lock() | |
| 377 | - | defer o.handlersMu.Unlock() | |
| 378 | - | return o.onSupportedIntent | |
| 379 | - | } | |
| 380 | - | ||
| 381 | - | // OnSupportedFeature registers a handler for the supported_feature event. | |
| 382 | - | // | |
| 383 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 384 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 385 | - | func (o *WpColorManager) OnSupportedFeature(handler func(feature uint32)) { | |
| 386 | - | if handler == nil { | |
| 387 | - | return | |
| 388 | - | } | |
| 389 | - | o.handlersMu.Lock() | |
| 390 | - | defer o.handlersMu.Unlock() | |
| 391 | - | o.onSupportedFeature = append(o.onSupportedFeature, handler) | |
| 392 | - | } | |
| 393 | - | ||
| 394 | - | // handlersForSupportedFeature returns the handlers registered for supported_feature, taken | |
| 395 | - | // under the lock so a handler may register another handler while events are | |
| 396 | - | // being dispatched. | |
| 397 | - | func (o *WpColorManager) handlersForSupportedFeature() []func(feature uint32) { | |
| 398 | - | o.handlersMu.Lock() | |
| 399 | - | defer o.handlersMu.Unlock() | |
| 400 | - | return o.onSupportedFeature | |
| 401 | - | } | |
| 402 | - | ||
| 403 | - | // OnSupportedTfNamed registers a handler for the supported_tf_named event. | |
| 404 | - | // | |
| 405 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 406 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 407 | - | func (o *WpColorManager) OnSupportedTfNamed(handler func(tf uint32)) { | |
| 408 | - | if handler == nil { | |
| 409 | - | return | |
| 410 | - | } | |
| 411 | - | o.handlersMu.Lock() | |
| 412 | - | defer o.handlersMu.Unlock() | |
| 413 | - | o.onSupportedTfNamed = append(o.onSupportedTfNamed, handler) | |
| 414 | - | } | |
| 415 | - | ||
| 416 | - | // handlersForSupportedTfNamed returns the handlers registered for supported_tf_named, taken | |
| 417 | - | // under the lock so a handler may register another handler while events are | |
| 418 | - | // being dispatched. | |
| 419 | - | func (o *WpColorManager) handlersForSupportedTfNamed() []func(tf uint32) { | |
| 420 | - | o.handlersMu.Lock() | |
| 421 | - | defer o.handlersMu.Unlock() | |
| 422 | - | return o.onSupportedTfNamed | |
| 423 | - | } | |
| 424 | - | ||
| 425 | - | // OnSupportedPrimariesNamed registers a handler for the supported_primaries_named event. | |
| 426 | - | // | |
| 427 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 428 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 429 | - | func (o *WpColorManager) OnSupportedPrimariesNamed(handler func(primaries uint32)) { | |
| 430 | - | if handler == nil { | |
| 431 | - | return | |
| 432 | - | } | |
| 433 | - | o.handlersMu.Lock() | |
| 434 | - | defer o.handlersMu.Unlock() | |
| 435 | - | o.onSupportedPrimariesNamed = append(o.onSupportedPrimariesNamed, handler) | |
| 436 | - | } | |
| 437 | - | ||
| 438 | - | // handlersForSupportedPrimariesNamed returns the handlers registered for supported_primaries_named, taken | |
| 439 | - | // under the lock so a handler may register another handler while events are | |
| 440 | - | // being dispatched. | |
| 441 | - | func (o *WpColorManager) handlersForSupportedPrimariesNamed() []func(primaries uint32) { | |
| 442 | - | o.handlersMu.Lock() | |
| 443 | - | defer o.handlersMu.Unlock() | |
| 444 | - | return o.onSupportedPrimariesNamed | |
| 445 | - | } | |
| 446 | - | ||
| 447 | - | // OnDone registers a handler for the done event. | |
| 448 | - | // | |
| 449 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 450 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 451 | - | func (o *WpColorManager) OnDone(handler func()) { | |
| 452 | - | if handler == nil { | |
| 453 | - | return | |
| 454 | - | } | |
| 455 | - | o.handlersMu.Lock() | |
| 456 | - | defer o.handlersMu.Unlock() | |
| 457 | - | o.onDone = append(o.onDone, handler) | |
| 458 | - | } | |
| 459 | - | ||
| 460 | - | // handlersForDone returns the handlers registered for done, taken | |
| 461 | - | // under the lock so a handler may register another handler while events are | |
| 462 | - | // being dispatched. | |
| 463 | - | func (o *WpColorManager) handlersForDone() []func() { | |
| 464 | - | o.handlersMu.Lock() | |
| 465 | - | defer o.handlersMu.Unlock() | |
| 466 | - | return o.onDone | |
| 467 | - | } | |
| 468 | - | ||
| 469 | - | // EventSignature returns the declared event argument types in wire order. | |
| 470 | - | func (o *WpColorManager) EventSignature(opcode uint16) (string, bool) { | |
| 471 | - | switch opcode { | |
| 472 | - | case 0: | |
| 473 | - | return "uint,", true | |
| 474 | - | case 1: | |
| 475 | - | return "uint,", true | |
| 476 | - | case 2: | |
| 477 | - | return "uint,", true | |
| 478 | - | case 3: | |
| 479 | - | return "uint,", true | |
| 480 | - | case 4: | |
| 481 | - | return "", true | |
| 482 | - | default: | |
| 483 | - | return "", false | |
| 484 | - | } | |
| 485 | - | } | |
| 486 | - | ||
| 487 | - | // Dispatch decodes one event on wp_color_manager_v1 and calls the registered handlers. | |
| 488 | - | func (o *WpColorManager) Dispatch(event *wl.Event) { | |
| 489 | - | switch event.Opcode { | |
| 490 | - | case 0: // supported_intent | |
| 491 | - | renderIntent := event.Uint32() | |
| 492 | - | ||
| 493 | - | for i, handler := range o.handlersForSupportedIntent() { | |
| 494 | - | _ = i | |
| 495 | - | handler(renderIntent) | |
| 496 | - | } | |
| 497 | - | case 1: // supported_feature | |
| 498 | - | feature := event.Uint32() | |
| 499 | - | ||
| 500 | - | for i, handler := range o.handlersForSupportedFeature() { | |
| 501 | - | _ = i | |
| 502 | - | handler(feature) | |
| 503 | - | } | |
| 504 | - | case 2: // supported_tf_named | |
| 505 | - | tf := event.Uint32() | |
| 506 | - | ||
| 507 | - | for i, handler := range o.handlersForSupportedTfNamed() { | |
| 508 | - | _ = i | |
| 509 | - | handler(tf) | |
| 510 | - | } | |
| 511 | - | case 3: // supported_primaries_named | |
| 512 | - | primaries := event.Uint32() | |
| 513 | - | ||
| 514 | - | for i, handler := range o.handlersForSupportedPrimariesNamed() { | |
| 515 | - | _ = i | |
| 516 | - | handler(primaries) | |
| 517 | - | } | |
| 518 | - | case 4: // done | |
| 519 | - | ||
| 520 | - | for i, handler := range o.handlersForDone() { | |
| 521 | - | _ = i | |
| 522 | - | handler() | |
| 523 | - | } | |
| 524 | - | default: | |
| 525 | - | } | |
| 526 | - | } | |
| 527 | - | ||
| 528 | - | // WpColorManagementOutputInterface is the protocol interface name. | |
| 529 | - | const WpColorManagementOutputInterface = "wp_color_management_output_v1" | |
| 530 | - | ||
| 531 | - | // WpColorManagementOutput is the generated binding for wp_color_management_output_v1 version 3. | |
| 532 | - | type WpColorManagementOutput struct { | |
| 533 | - | wl.BaseProxy | |
| 534 | - | // handlersMu guards the handler slices: a client may register or replace | |
| 535 | - | // handlers while another goroutine dispatches events. | |
| 536 | - | handlersMu sync.Mutex | |
| 537 | - | onImageDescriptionChanged []func() | |
| 538 | - | } | |
| 539 | - | ||
| 540 | - | // NewWpColorManagementOutput returns an unbound WpColorManagementOutput. | |
| 541 | - | func NewWpColorManagementOutput(ctx *wl.Context) *WpColorManagementOutput { | |
| 542 | - | obj := &WpColorManagementOutput{} | |
| 543 | - | obj.SetContext(ctx) | |
| 544 | - | ctx.Register(obj) | |
| 545 | - | return obj | |
| 546 | - | } | |
| 547 | - | ||
| 548 | - | // Destroy the color wp_color_management_output_v1 object. This does not affect any remaining protocol objects. | |
| 549 | - | func (o *WpColorManagementOutput) Destroy() error { | |
| 550 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "wp_color_management_output_v1.destroy", Destructor: true}); err != nil { | |
| 551 | - | return err | |
| 552 | - | } | |
| 553 | - | return nil | |
| 554 | - | } | |
| 555 | - | ||
| 556 | - | // This creates a new wp_image_description_v1 object for the current image description of the output. There always is exactly one image description active for an output so the client should destroy the image description created by earlier invocations of this request. This request is usually sent as a reaction to the image_description_changed event or when creating a wp_color_management_output_v1 object. The image description of an output represents the color encoding the output expects. There might be performance and power advantages, as well as improved color reproduction, if a content update matches the image description of the output it is being shown on. If a content update is shown on any other output than the one it matches the image description of, then the color reproduction on those outputs might be considerably worse. The created wp_image_description_v1 object preserves the image description of the output from the time the object was created. The resulting image description object allows get_information request. If this protocol object is inert, the resulting image description object shall immediately deliver the wp_image_description_v1.failed event with the no_output cause. If the interface version is inadequate for the output's image description, meaning that the client does not support all the events needed to deliver the crucial information, the resulting image description object shall immediately deliver the wp_image_description_v1.failed event with the low_version cause. Otherwise the object shall immediately deliver the ready event. | |
| 557 | - | func (o *WpColorManagementOutput) GetImageDescription() (*WpImageDescription, error) { | |
| 558 | - | child := &WpImageDescription{} | |
| 559 | - | child.SetContext(o.Context()) | |
| 560 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "wp_color_management_output_v1.get_image_description", Child: child}, wl.ArgObject(child)); err != nil { | |
| 561 | - | return nil, err | |
| 562 | - | } | |
| 563 | - | return child, nil | |
| 564 | - | } | |
| 565 | - | ||
| 566 | - | // OnImageDescriptionChanged registers a handler for the image_description_changed event. | |
| 567 | - | // | |
| 568 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 569 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 570 | - | func (o *WpColorManagementOutput) OnImageDescriptionChanged(handler func()) { | |
| 571 | - | if handler == nil { | |
| 572 | - | return | |
| 573 | - | } | |
| 574 | - | o.handlersMu.Lock() | |
| 575 | - | defer o.handlersMu.Unlock() | |
| 576 | - | o.onImageDescriptionChanged = append(o.onImageDescriptionChanged, handler) | |
| 577 | - | } | |
| 578 | - | ||
| 579 | - | // handlersForImageDescriptionChanged returns the handlers registered for image_description_changed, taken | |
| 580 | - | // under the lock so a handler may register another handler while events are | |
| 581 | - | // being dispatched. | |
| 582 | - | func (o *WpColorManagementOutput) handlersForImageDescriptionChanged() []func() { | |
| 583 | - | o.handlersMu.Lock() | |
| 584 | - | defer o.handlersMu.Unlock() | |
| 585 | - | return o.onImageDescriptionChanged | |
| 586 | - | } | |
| 587 | - | ||
| 588 | - | // EventSignature returns the declared event argument types in wire order. | |
| 589 | - | func (o *WpColorManagementOutput) EventSignature(opcode uint16) (string, bool) { | |
| 590 | - | switch opcode { | |
| 591 | - | case 0: | |
| 592 | - | return "", true | |
| 593 | - | default: | |
| 594 | - | return "", false | |
| 595 | - | } | |
| 596 | - | } | |
| 597 | - | ||
| 598 | - | // Dispatch decodes one event on wp_color_management_output_v1 and calls the registered handlers. | |
| 599 | - | func (o *WpColorManagementOutput) Dispatch(event *wl.Event) { | |
| 600 | - | switch event.Opcode { | |
| 601 | - | case 0: // image_description_changed | |
| 602 | - | ||
| 603 | - | for i, handler := range o.handlersForImageDescriptionChanged() { | |
| 604 | - | _ = i | |
| 605 | - | handler() | |
| 606 | - | } | |
| 607 | - | default: | |
| 608 | - | } | |
| 609 | - | } | |
| 610 | - | ||
| 611 | - | // WpColorManagementSurfaceInterface is the protocol interface name. | |
| 612 | - | const WpColorManagementSurfaceInterface = "wp_color_management_surface_v1" | |
| 613 | - | ||
| 614 | - | // WpColorManagementSurface is the generated binding for wp_color_management_surface_v1 version 3. | |
| 615 | - | type WpColorManagementSurface struct { | |
| 616 | - | wl.BaseProxy | |
| 617 | - | } | |
| 618 | - | ||
| 619 | - | // NewWpColorManagementSurface returns an unbound WpColorManagementSurface. | |
| 620 | - | func NewWpColorManagementSurface(ctx *wl.Context) *WpColorManagementSurface { | |
| 621 | - | obj := &WpColorManagementSurface{} | |
| 622 | - | obj.SetContext(ctx) | |
| 623 | - | ctx.Register(obj) | |
| 624 | - | return obj | |
| 625 | - | } | |
| 626 | - | ||
| 627 | - | // Destroy the wp_color_management_surface_v1 object and do the same as unset_image_description. | |
| 628 | - | func (o *WpColorManagementSurface) Destroy() error { | |
| 629 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "wp_color_management_surface_v1.destroy", Destructor: true}); err != nil { | |
| 630 | - | return err | |
| 631 | - | } | |
| 632 | - | return nil | |
| 633 | - | } | |
| 634 | - | ||
| 635 | - | // If this protocol object is inert, the protocol error inert is raised. Set the image description of the underlying surface. The image description and rendering intent are double-buffered state, see wl_surface.commit. It is the client's responsibility to understand the image description it sets on a surface, and to provide content that matches that image description. Compositors might convert images to match their own or any other image descriptions. Image descriptions which are not ready (see wp_image_description_v1) are forbidden in this request, and in such case the protocol error image_description is raised. All image descriptions which are ready (see wp_image_description_v1) are allowed and must always be accepted by the compositor. When an image description is set on a surface, it establishes an explicit link between surface pixel values and surface colorimetry. This link may be undefined for some pixel values, see the image description creator interfaces for the conditions. Non-finite floating-point values (NaN, Inf) always have an undefined colorimetry. A rendering intent provides the client's preference on how surface colorimetry should be mapped to each output. The render_intent value must be one advertised by the compositor with wp_color_manager_v1.render_intent event, otherwise the protocol error render_intent is raised. By default, a surface does not have an associated image description nor a rendering intent. The handling of color on such surfaces is compositor implementation defined. Compositors should handle such surfaces as sRGB, but may handle them differently if they have specific requirements. Setting the image description has copy semantics; after this request, the image description can be immediately destroyed without affecting the pending state of the surface. | |
| 636 | - | func (o *WpColorManagementSurface) SetImageDescription(imageDescription *WpImageDescription, renderIntent uint32) error { | |
| 637 | - | var arg0 wl.Object | |
| 638 | - | if imageDescription != nil { | |
| 639 | - | arg0 = imageDescription | |
| 640 | - | } | |
| 641 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "wp_color_management_surface_v1.set_image_description"}, wl.ArgObject(arg0), wl.ArgUint(renderIntent)); err != nil { | |
| 642 | - | return err | |
| 643 | - | } | |
| 644 | - | return nil | |
| 645 | - | } | |
| 646 | - | ||
| 647 | - | // If this protocol object is inert, the protocol error inert is raised. This request removes any image description from the surface. See set_image_description for how a compositor handles a surface without an image description. This is double-buffered state, see wl_surface.commit. | |
| 648 | - | func (o *WpColorManagementSurface) UnsetImageDescription() error { | |
| 649 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 2, Name: "wp_color_management_surface_v1.unset_image_description"}); err != nil { | |
| 650 | - | return err | |
| 651 | - | } | |
| 652 | - | return nil | |
| 653 | - | } | |
| 654 | - | ||
| 655 | - | // EventSignature returns the declared event argument types in wire order. | |
| 656 | - | func (o *WpColorManagementSurface) EventSignature(opcode uint16) (string, bool) { | |
| 657 | - | switch opcode { | |
| 658 | - | default: | |
| 659 | - | return "", false | |
| 660 | - | } | |
| 661 | - | } | |
| 662 | - | ||
| 663 | - | // Dispatch decodes one event on wp_color_management_surface_v1 and calls the registered handlers. | |
| 664 | - | func (o *WpColorManagementSurface) Dispatch(event *wl.Event) { | |
| 665 | - | switch event.Opcode { | |
| 666 | - | default: | |
| 667 | - | } | |
| 668 | - | } | |
| 669 | - | ||
| 670 | - | // WpColorManagementSurfaceFeedbackInterface is the protocol interface name. | |
| 671 | - | const WpColorManagementSurfaceFeedbackInterface = "wp_color_management_surface_feedback_v1" | |
| 672 | - | ||
| 673 | - | // WpColorManagementSurfaceFeedback is the generated binding for wp_color_management_surface_feedback_v1 version 3. | |
| 674 | - | type WpColorManagementSurfaceFeedback struct { | |
| 675 | - | wl.BaseProxy | |
| 676 | - | // handlersMu guards the handler slices: a client may register or replace | |
| 677 | - | // handlers while another goroutine dispatches events. | |
| 678 | - | handlersMu sync.Mutex | |
| 679 | - | onPreferredChanged []func(identity uint32) | |
| 680 | - | onPreferredChanged2 []func(identityHi uint32, identityLo uint32) | |
| 681 | - | } | |
| 682 | - | ||
| 683 | - | // NewWpColorManagementSurfaceFeedback returns an unbound WpColorManagementSurfaceFeedback. | |
| 684 | - | func NewWpColorManagementSurfaceFeedback(ctx *wl.Context) *WpColorManagementSurfaceFeedback { | |
| 685 | - | obj := &WpColorManagementSurfaceFeedback{} | |
| 686 | - | obj.SetContext(ctx) | |
| 687 | - | ctx.Register(obj) | |
| 688 | - | return obj | |
| 689 | - | } | |
| 690 | - | ||
| 691 | - | // Destroy the wp_color_management_surface_feedback_v1 object. | |
| 692 | - | func (o *WpColorManagementSurfaceFeedback) Destroy() error { | |
| 693 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "wp_color_management_surface_feedback_v1.destroy", Destructor: true}); err != nil { | |
| 694 | - | return err | |
| 695 | - | } | |
| 696 | - | return nil | |
| 697 | - | } | |
| 698 | - | ||
| 699 | - | // If this protocol object is inert, the protocol error inert is raised. The preferred image description represents the compositor's preferred color encoding for this wl_surface at the current time. There might be performance and power advantages, as well as improved color reproduction, if the image description of a content update matches the preferred image description. This creates a new wp_image_description_v1 object for the currently preferred image description for the wl_surface. The client should stop using and destroy the image descriptions created by earlier invocations of this request for the associated wl_surface. This request is usually sent as a reaction to the preferred_changed event or when creating a wp_color_management_surface_feedback_v1 object if the client is capable of adapting to image descriptions. The created wp_image_description_v1 object preserves the preferred image description of the wl_surface from the time the object was created. The resulting image description object allows get_information request. If the image description is parametric, the client should set it on its wl_surface only if the image description is an exact match with the client content. Particularly if everything else matches, but the target color volume is greater than what the client needs, the client should create its own parameric image description with its exact parameters. If the interface version is inadequate for the preferred image description, meaning that the client does not support all the events needed to deliver the crucial information, the resulting image description object shall immediately deliver the wp_image_description_v1.failed event with the low_version cause, otherwise the object shall immediately deliver the ready event. | |
| 700 | - | func (o *WpColorManagementSurfaceFeedback) GetPreferred() (*WpImageDescription, error) { | |
| 701 | - | child := &WpImageDescription{} | |
| 702 | - | child.SetContext(o.Context()) | |
| 703 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "wp_color_management_surface_feedback_v1.get_preferred", Child: child}, wl.ArgObject(child)); err != nil { | |
| 704 | - | return nil, err | |
| 705 | - | } | |
| 706 | - | return child, nil | |
| 707 | - | } | |
| 708 | - | ||
| 709 | - | // The same description as for get_preferred applies, except the returned image description is guaranteed to be parametric. This is meant for clients that can only deal with parametric image descriptions. If the compositor doesn't support parametric image descriptions, the unsupported_feature error is emitted. | |
| 710 | - | func (o *WpColorManagementSurfaceFeedback) GetPreferredParametric() (*WpImageDescription, error) { | |
| 711 | - | child := &WpImageDescription{} | |
| 712 | - | child.SetContext(o.Context()) | |
| 713 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 2, Name: "wp_color_management_surface_feedback_v1.get_preferred_parametric", Child: child}, wl.ArgObject(child)); err != nil { | |
| 714 | - | return nil, err | |
| 715 | - | } | |
| 716 | - | return child, nil | |
| 717 | - | } | |
| 718 | - | ||
| 719 | - | // OnPreferredChanged registers a handler for the preferred_changed event. | |
| 720 | - | // | |
| 721 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 722 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 723 | - | func (o *WpColorManagementSurfaceFeedback) OnPreferredChanged(handler func(identity uint32)) { | |
| 724 | - | if handler == nil { | |
| 725 | - | return | |
| 726 | - | } | |
| 727 | - | o.handlersMu.Lock() | |
| 728 | - | defer o.handlersMu.Unlock() | |
| 729 | - | o.onPreferredChanged = append(o.onPreferredChanged, handler) | |
| 730 | - | } | |
| 731 | - | ||
| 732 | - | // handlersForPreferredChanged returns the handlers registered for preferred_changed, taken | |
| 733 | - | // under the lock so a handler may register another handler while events are | |
| 734 | - | // being dispatched. | |
| 735 | - | func (o *WpColorManagementSurfaceFeedback) handlersForPreferredChanged() []func(identity uint32) { | |
| 736 | - | o.handlersMu.Lock() | |
| 737 | - | defer o.handlersMu.Unlock() | |
| 738 | - | return o.onPreferredChanged | |
| 739 | - | } | |
| 740 | - | ||
| 741 | - | // OnPreferredChanged2 registers a handler for the preferred_changed2 event. | |
| 742 | - | // | |
| 743 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 744 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 745 | - | func (o *WpColorManagementSurfaceFeedback) OnPreferredChanged2(handler func(identityHi uint32, identityLo uint32)) { | |
| 746 | - | if handler == nil { | |
| 747 | - | return | |
| 748 | - | } | |
| 749 | - | o.handlersMu.Lock() | |
| 750 | - | defer o.handlersMu.Unlock() | |
| 751 | - | o.onPreferredChanged2 = append(o.onPreferredChanged2, handler) | |
| 752 | - | } | |
| 753 | - | ||
| 754 | - | // handlersForPreferredChanged2 returns the handlers registered for preferred_changed2, taken | |
| 755 | - | // under the lock so a handler may register another handler while events are | |
| 756 | - | // being dispatched. | |
| 757 | - | func (o *WpColorManagementSurfaceFeedback) handlersForPreferredChanged2() []func(identityHi uint32, identityLo uint32) { | |
| 758 | - | o.handlersMu.Lock() | |
| 759 | - | defer o.handlersMu.Unlock() | |
| 760 | - | return o.onPreferredChanged2 | |
| 761 | - | } | |
| 762 | - | ||
| 763 | - | // EventSignature returns the declared event argument types in wire order. | |
| 764 | - | func (o *WpColorManagementSurfaceFeedback) EventSignature(opcode uint16) (string, bool) { | |
| 765 | - | switch opcode { | |
| 766 | - | case 0: | |
| 767 | - | return "uint,", true | |
| 768 | - | case 1: | |
| 769 | - | return "uint,uint,", true | |
| 770 | - | default: | |
| 771 | - | return "", false | |
| 772 | - | } | |
| 773 | - | } | |
| 774 | - | ||
| 775 | - | // Dispatch decodes one event on wp_color_management_surface_feedback_v1 and calls the registered handlers. | |
| 776 | - | func (o *WpColorManagementSurfaceFeedback) Dispatch(event *wl.Event) { | |
| 777 | - | switch event.Opcode { | |
| 778 | - | case 0: // preferred_changed | |
| 779 | - | identity := event.Uint32() | |
| 780 | - | ||
| 781 | - | for i, handler := range o.handlersForPreferredChanged() { | |
| 782 | - | _ = i | |
| 783 | - | handler(identity) | |
| 784 | - | } | |
| 785 | - | case 1: // preferred_changed2 | |
| 786 | - | identityHi := event.Uint32() | |
| 787 | - | identityLo := event.Uint32() | |
| 788 | - | ||
| 789 | - | for i, handler := range o.handlersForPreferredChanged2() { | |
| 790 | - | _ = i | |
| 791 | - | handler(identityHi, identityLo) | |
| 792 | - | } | |
| 793 | - | default: | |
| 794 | - | } | |
| 795 | - | } | |
| 796 | - | ||
| 797 | - | // WpImageDescriptionCreatorIccInterface is the protocol interface name. | |
| 798 | - | const WpImageDescriptionCreatorIccInterface = "wp_image_description_creator_icc_v1" | |
| 799 | - | ||
| 800 | - | // WpImageDescriptionCreatorIcc is the generated binding for wp_image_description_creator_icc_v1 version 3. | |
| 801 | - | type WpImageDescriptionCreatorIcc struct { | |
| 802 | - | wl.BaseProxy | |
| 803 | - | } | |
| 804 | - | ||
| 805 | - | // NewWpImageDescriptionCreatorIcc returns an unbound WpImageDescriptionCreatorIcc. | |
| 806 | - | func NewWpImageDescriptionCreatorIcc(ctx *wl.Context) *WpImageDescriptionCreatorIcc { | |
| 807 | - | obj := &WpImageDescriptionCreatorIcc{} | |
| 808 | - | obj.SetContext(ctx) | |
| 809 | - | ctx.Register(obj) | |
| 810 | - | return obj | |
| 811 | - | } | |
| 812 | - | ||
| 813 | - | // Create an image description object based on the ICC information previously set on this object. A compositor must parse the ICC data in some undefined but finite amount of time. The completeness of the parameter set is verified. If the set is not complete, the protocol error incomplete_set is raised. For the definition of a complete set, see the description of this interface. If the particular combination of the information is not supported by the compositor, the resulting image description object shall immediately deliver the wp_image_description_v1.failed event with the 'unsupported' cause. If a valid image description was created from the information, the wp_image_description_v1.ready event will eventually be sent instead. This request destroys the wp_image_description_creator_icc_v1 object. The resulting image description object does not allow get_information request. | |
| 814 | - | func (o *WpImageDescriptionCreatorIcc) Create() (*WpImageDescription, error) { | |
| 815 | - | child := &WpImageDescription{} | |
| 816 | - | child.SetContext(o.Context()) | |
| 817 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "wp_image_description_creator_icc_v1.create", Destructor: true, Child: child}, wl.ArgObject(child)); err != nil { | |
| 818 | - | return nil, err | |
| 819 | - | } | |
| 820 | - | return child, nil | |
| 821 | - | } | |
| 822 | - | ||
| 823 | - | // Sets the ICC profile file to be used as the basis of the image description. The data shall be found through the given fd at the given offset, having the given length. The fd must be seekable and readable. Violating these requirements raises the bad_fd protocol error. If reading the data fails due to an error independent of the client, the compositor shall send the wp_image_description_v1.failed event on the created wp_image_description_v1 with the 'operating_system' cause. The maximum size of the ICC profile is 32 MB. If length is greater than that or zero, the protocol error bad_size is raised. If offset + length exceeds the file size, the protocol error out_of_file is raised. A compositor may read the file at any time starting from this request and only until whichever happens first: - If create request was issued, the wp_image_description_v1 object delivers either failed or ready event; or - if create request was not issued, this wp_image_description_creator_icc_v1 object is destroyed. A compositor shall not modify the contents of the file, and the fd may be sealed for writes and size changes. The client must ensure to its best ability that the data does not change while the compositor is reading it. The data must represent a valid ICC profile. The ICC profile version must be 2 or 4, it must be a 3 channel profile and the class must be Display or ColorSpace. Violating these requirements will not result in a protocol error, but will eventually send the wp_image_description_v1.failed event on the created wp_image_description_v1 with the 'unsupported' cause. See the International Color Consortium specification ICC.1:2022 for more details about ICC profiles. If ICC file has already been set on this object, the protocol error already_set is raised. | |
| 824 | - | func (o *WpImageDescriptionCreatorIcc) SetIccFile(iccProfile int, offset uint32, length uint32) error { | |
| 825 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "wp_image_description_creator_icc_v1.set_icc_file", FDs: []int{iccProfile}}, wl.ArgFD(), wl.ArgUint(offset), wl.ArgUint(length)); err != nil { | |
| 826 | - | return err | |
| 827 | - | } | |
| 828 | - | return nil | |
| 829 | - | } | |
| 830 | - | ||
| 831 | - | // EventSignature returns the declared event argument types in wire order. | |
| 832 | - | func (o *WpImageDescriptionCreatorIcc) EventSignature(opcode uint16) (string, bool) { | |
| 833 | - | switch opcode { | |
| 834 | - | default: | |
| 835 | - | return "", false | |
| 836 | - | } | |
| 837 | - | } | |
| 838 | - | ||
| 839 | - | // Dispatch decodes one event on wp_image_description_creator_icc_v1 and calls the registered handlers. | |
| 840 | - | func (o *WpImageDescriptionCreatorIcc) Dispatch(event *wl.Event) { | |
| 841 | - | switch event.Opcode { | |
| 842 | - | default: | |
| 843 | - | } | |
| 844 | - | } | |
| 845 | - | ||
| 846 | - | // WpImageDescriptionCreatorParamsInterface is the protocol interface name. | |
| 847 | - | const WpImageDescriptionCreatorParamsInterface = "wp_image_description_creator_params_v1" | |
| 848 | - | ||
| 849 | - | // WpImageDescriptionCreatorParams is the generated binding for wp_image_description_creator_params_v1 version 3. | |
| 850 | - | type WpImageDescriptionCreatorParams struct { | |
| 851 | - | wl.BaseProxy | |
| 852 | - | } | |
| 853 | - | ||
| 854 | - | // NewWpImageDescriptionCreatorParams returns an unbound WpImageDescriptionCreatorParams. | |
| 855 | - | func NewWpImageDescriptionCreatorParams(ctx *wl.Context) *WpImageDescriptionCreatorParams { | |
| 856 | - | obj := &WpImageDescriptionCreatorParams{} | |
| 857 | - | obj.SetContext(ctx) | |
| 858 | - | ctx.Register(obj) | |
| 859 | - | return obj | |
| 860 | - | } | |
| 861 | - | ||
| 862 | - | // Create an image description object based on the parameters previously set on this object. The completeness of the parameter set is verified. If the set is not complete, the protocol error incomplete_set is raised. For the definition of a complete set, see the description of this interface. When both max_cll and max_fall are set, max_fall must be less or equal to max_cll otherwise the invalid_luminance protocol error is raised. In version 1, these following conditions also result in the invalid_luminance protocol error. Version 2 and later do not have this requirement. - When max_cll is set, it must be greater than min L and less or equal to max L of the mastering luminance range. - When max_fall is set, it must be greater than min L and less or equal to max L of the mastering luminance range. If the particular combination of the parameter set is not supported by the compositor, the resulting image description object shall immediately deliver the wp_image_description_v1.failed event with the 'unsupported' cause. If a valid image description was created from the parameter set, the wp_image_description_v1.ready event will eventually be sent instead. This request destroys the wp_image_description_creator_params_v1 object. The resulting image description object does not allow get_information request. | |
| 863 | - | func (o *WpImageDescriptionCreatorParams) Create() (*WpImageDescription, error) { | |
| 864 | - | child := &WpImageDescription{} | |
| 865 | - | child.SetContext(o.Context()) | |
| 866 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "wp_image_description_creator_params_v1.create", Destructor: true, Child: child}, wl.ArgObject(child)); err != nil { | |
| 867 | - | return nil, err | |
| 868 | - | } | |
| 869 | - | return child, nil | |
| 870 | - | } | |
| 871 | - | ||
| 872 | - | // Sets the transfer characteristic using explicitly enumerated named functions. When the resulting image description is attached to an image, the content should be decoded according to the industry standard practices for the transfer characteristic. Only names advertised with wp_color_manager_v1 event supported_tf_named are allowed. Other values shall raise the protocol error invalid_tf. If transfer characteristic has already been set on this object, the protocol error already_set is raised. | |
| 873 | - | func (o *WpImageDescriptionCreatorParams) SetTfNamed(tf uint32) error { | |
| 874 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "wp_image_description_creator_params_v1.set_tf_named"}, wl.ArgUint(tf)); err != nil { | |
| 875 | - | return err | |
| 876 | - | } | |
| 877 | - | return nil | |
| 878 | - | } | |
| 879 | - | ||
| 880 | - | // Sets the color component transfer characteristic to a power curve with the given exponent. Negative values are handled by mirroring the positive half of the curve through the origin. The valid domain and range of the curve are all finite real numbers. This curve represents the conversion from electrical to optical color channel values. The curve exponent shall be multiplied by 10000 to get the argument eexp value to carry the precision of 4 decimals. The curve exponent must be at least 1.0 and at most 10.0. Otherwise the protocol error invalid_tf is raised. If transfer characteristic has already been set on this object, the protocol error already_set is raised. This request can be used when the compositor advertises wp_color_manager_v1.feature.set_tf_power. Otherwise this request raises the protocol error unsupported_feature. | |
| 881 | - | func (o *WpImageDescriptionCreatorParams) SetTfPower(eexp uint32) error { | |
| 882 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 2, Name: "wp_image_description_creator_params_v1.set_tf_power"}, wl.ArgUint(eexp)); err != nil { | |
| 883 | - | return err | |
| 884 | - | } | |
| 885 | - | return nil | |
| 886 | - | } | |
| 887 | - | ||
| 888 | - | // Sets the color primaries and white point using explicitly named sets. This describes the primary color volume which is the basis for color value encoding. Only names advertised with wp_color_manager_v1 event supported_primaries_named are allowed. Other values shall raise the protocol error invalid_primaries_named. If primaries have already been set on this object, the protocol error already_set is raised. | |
| 889 | - | func (o *WpImageDescriptionCreatorParams) SetPrimariesNamed(primaries uint32) error { | |
| 890 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 3, Name: "wp_image_description_creator_params_v1.set_primaries_named"}, wl.ArgUint(primaries)); err != nil { | |
| 891 | - | return err | |
| 892 | - | } | |
| 893 | - | return nil | |
| 894 | - | } | |
| 895 | - | ||
| 896 | - | // Sets the color primaries and white point using CIE 1931 xy chromaticity coordinates. This describes the primary color volume which is the basis for color value encoding. Each coordinate value is multiplied by 1 million to get the argument value to carry precision of 6 decimals. If primaries have already been set on this object, the protocol error already_set is raised. This request can be used if the compositor advertises wp_color_manager_v1.feature.set_primaries. Otherwise this request raises the protocol error unsupported_feature. | |
| 897 | - | func (o *WpImageDescriptionCreatorParams) SetPrimaries(rX int32, rY int32, gX int32, gY int32, bX int32, bY int32, wX int32, wY int32) error { | |
| 898 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 4, Name: "wp_image_description_creator_params_v1.set_primaries"}, wl.ArgInt(rX), wl.ArgInt(rY), wl.ArgInt(gX), wl.ArgInt(gY), wl.ArgInt(bX), wl.ArgInt(bY), wl.ArgInt(wX), wl.ArgInt(wY)); err != nil { | |
| 899 | - | return err | |
| 900 | - | } | |
| 901 | - | return nil | |
| 902 | - | } | |
| 903 | - | ||
| 904 | - | // Sets the primary color volume luminance range and the reference white luminance level. These values include the minimum display emission, but not external flare. The minimum display emission is assumed to have the chromaticity of the primary color volume white point. The default luminances from https://www.color.org/chardata/rgb/srgb.xalter are - primary color volume minimum: 0.2 cd/m² - primary color volume maximum: 80 cd/m² - reference white: 80 cd/m² Setting a named transfer characteristic can imply other default luminances. The default luminances get overwritten when this request is used. With transfer_function.st2084_pq the given 'max_lum' value is ignored, and 'max_lum' is taken as 'min_lum' + 10000 cd/m². 'min_lum' and 'max_lum' specify the minimum and maximum luminances of the primary color volume as reproduced by the targeted display. 'reference_lum' specifies the luminance of the reference white as reproduced by the targeted display, and reflects the targeted viewing environment. Compositors should make sure that all content is anchored, meaning that an input signal level of 'reference_lum' on one image description and another input signal level of 'reference_lum' on another image description should produce the same output level, even though the 'reference_lum' on both image representations can be different. 'reference_lum' may be higher than 'max_lum'. In that case reaching the reference white output level in image content requires the 'extended_target_volume' feature support. If 'max_lum' or 'reference_lum' are less than or equal to 'min_lum', the protocol error invalid_luminance is raised. The minimum luminance is multiplied by 10000 to get the argument 'min_lum' value and carries precision of 4 decimals. The maximum luminance and reference white luminance values are unscaled. If the primary color volume luminance range and the reference white luminance level have already been set on this object, the protocol error already_set is raised. This request can be used if the compositor advertises wp_color_manager_v1.feature.set_luminances. Otherwise this request raises the protocol error unsupported_feature. | |
| 905 | - | func (o *WpImageDescriptionCreatorParams) SetLuminances(minLum uint32, maxLum uint32, referenceLum uint32) error { | |
| 906 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 5, Name: "wp_image_description_creator_params_v1.set_luminances"}, wl.ArgUint(minLum), wl.ArgUint(maxLum), wl.ArgUint(referenceLum)); err != nil { | |
| 907 | - | return err | |
| 908 | - | } | |
| 909 | - | return nil | |
| 910 | - | } | |
| 911 | - | ||
| 912 | - | // Provides the color primaries and white point of the mastering display using CIE 1931 xy chromaticity coordinates. This is compatible with the SMPTE ST 2086 definition of HDR static metadata. The mastering display primaries and mastering display luminances define the target color volume. If mastering display primaries are not explicitly set, the target color volume is assumed to have the same primaries as the primary color volume. The target color volume is defined by all tristimulus values between 0.0 and 1.0 (inclusive) of the color space defined by the given mastering display primaries and white point. The colorimetry is identical between the container color space and the mastering display color space, including that no chromatic adaptation is applied even if the white points differ. The target color volume can exceed the primary color volume to allow for a greater color volume with an existing color space definition (for example scRGB). It can be smaller than the primary color volume to minimize gamut and tone mapping distances for big color spaces (HDR metadata). To make use of the entire target color volume a suitable pixel format has to be chosen (e.g. floating point to exceed the primary color volume, or abusing limited quantization range as with xvYCC). Each coordinate value is multiplied by 1 million to get the argument value to carry precision of 6 decimals. If mastering display primaries have already been set on this object, the protocol error already_set is raised. This request can be used if the compositor advertises wp_color_manager_v1.feature.set_mastering_display_primaries. Otherwise this request raises the protocol error unsupported_feature. The advertisement implies support only for target color volumes fully contained within the primary color volume. If a compositor additionally supports target color volume exceeding the primary color volume, it must advertise wp_color_manager_v1.feature.extended_target_volume. If a client uses target color volume exceeding the primary color volume and the compositor does not support it, the result is implementation defined. Compositors are recommended to detect this case and fail the image description gracefully, but it may as well result in color artifacts. | |
| 913 | - | func (o *WpImageDescriptionCreatorParams) SetMasteringDisplayPrimaries(rX int32, rY int32, gX int32, gY int32, bX int32, bY int32, wX int32, wY int32) error { | |
| 914 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 6, Name: "wp_image_description_creator_params_v1.set_mastering_display_primaries"}, wl.ArgInt(rX), wl.ArgInt(rY), wl.ArgInt(gX), wl.ArgInt(gY), wl.ArgInt(bX), wl.ArgInt(bY), wl.ArgInt(wX), wl.ArgInt(wY)); err != nil { | |
| 915 | - | return err | |
| 916 | - | } | |
| 917 | - | return nil | |
| 918 | - | } | |
| 919 | - | ||
| 920 | - | // Sets the luminance range that was used during the content mastering process as the minimum and maximum absolute luminance L. These values include the minimum display emission and ambient flare luminances, assumed to be optically additive and have the chromaticity of the primary color volume white point. This should be compatible with the SMPTE ST 2086 definition of HDR static metadata. The mastering display primaries and mastering display luminances define the target color volume. If mastering luminances are not explicitly set, the target color volume is assumed to have the same min and max luminances as the primary color volume. If max L is less than or equal to min L, the protocol error invalid_luminance is raised. Min L value is multiplied by 10000 to get the argument min_lum value and carry precision of 4 decimals. Max L value is unscaled for max_lum. This request can be used if the compositor advertises wp_color_manager_v1.feature.set_mastering_display_primaries. Otherwise this request raises the protocol error unsupported_feature. The advertisement implies support only for target color volumes fully contained within the primary color volume. If a compositor additionally supports target color volume exceeding the primary color volume, it must advertise wp_color_manager_v1.feature.extended_target_volume. If a client uses target color volume exceeding the primary color volume and the compositor does not support it, the result is implementation defined. Compositors are recommended to detect this case and fail the image description gracefully, but it may as well result in color artifacts. | |
| 921 | - | func (o *WpImageDescriptionCreatorParams) SetMasteringLuminance(minLum uint32, maxLum uint32) error { | |
| 922 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 7, Name: "wp_image_description_creator_params_v1.set_mastering_luminance"}, wl.ArgUint(minLum), wl.ArgUint(maxLum)); err != nil { | |
| 923 | - | return err | |
| 924 | - | } | |
| 925 | - | return nil | |
| 926 | - | } | |
| 927 | - | ||
| 928 | - | // Sets the maximum content light level (max_cll) as defined by CTA-861-H. max_cll is undefined by default. | |
| 929 | - | func (o *WpImageDescriptionCreatorParams) SetMaxCll(maxCll uint32) error { | |
| 930 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 8, Name: "wp_image_description_creator_params_v1.set_max_cll"}, wl.ArgUint(maxCll)); err != nil { | |
| 931 | - | return err | |
| 932 | - | } | |
| 933 | - | return nil | |
| 934 | - | } | |
| 935 | - | ||
| 936 | - | // Sets the maximum frame-average light level (max_fall) as defined by CTA-861-H. max_fall is undefined by default. | |
| 937 | - | func (o *WpImageDescriptionCreatorParams) SetMaxFall(maxFall uint32) error { | |
| 938 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 9, Name: "wp_image_description_creator_params_v1.set_max_fall"}, wl.ArgUint(maxFall)); err != nil { | |
| 939 | - | return err | |
| 940 | - | } | |
| 941 | - | return nil | |
| 942 | - | } | |
| 943 | - | ||
| 944 | - | // EventSignature returns the declared event argument types in wire order. | |
| 945 | - | func (o *WpImageDescriptionCreatorParams) EventSignature(opcode uint16) (string, bool) { | |
| 946 | - | switch opcode { | |
| 947 | - | default: | |
| 948 | - | return "", false | |
| 949 | - | } | |
| 950 | - | } | |
| 951 | - | ||
| 952 | - | // Dispatch decodes one event on wp_image_description_creator_params_v1 and calls the registered handlers. | |
| 953 | - | func (o *WpImageDescriptionCreatorParams) Dispatch(event *wl.Event) { | |
| 954 | - | switch event.Opcode { | |
| 955 | - | default: | |
| 956 | - | } | |
| 957 | - | } | |
| 958 | - | ||
| 959 | - | // WpImageDescriptionInterface is the protocol interface name. | |
| 960 | - | const WpImageDescriptionInterface = "wp_image_description_v1" | |
| 961 | - | ||
| 962 | - | // WpImageDescription is the generated binding for wp_image_description_v1 version 3. | |
| 963 | - | type WpImageDescription struct { | |
| 964 | - | wl.BaseProxy | |
| 965 | - | // handlersMu guards the handler slices: a client may register or replace | |
| 966 | - | // handlers while another goroutine dispatches events. | |
| 967 | - | handlersMu sync.Mutex | |
| 968 | - | onFailed []func(cause uint32, msg string) | |
| 969 | - | onReady []func(identity uint32) | |
| 970 | - | onReady2 []func(identityHi uint32, identityLo uint32) | |
| 971 | - | } | |
| 972 | - | ||
| 973 | - | // NewWpImageDescription returns an unbound WpImageDescription. | |
| 974 | - | func NewWpImageDescription(ctx *wl.Context) *WpImageDescription { | |
| 975 | - | obj := &WpImageDescription{} | |
| 976 | - | obj.SetContext(ctx) | |
| 977 | - | ctx.Register(obj) | |
| 978 | - | return obj | |
| 979 | - | } | |
| 980 | - | ||
| 981 | - | // Destroy this object. It is safe to destroy an object which is not ready. Destroying a wp_image_description_v1 object has no side-effects, not even if a wp_color_management_surface_v1.set_image_description has not yet been followed by a wl_surface.commit. | |
| 982 | - | func (o *WpImageDescription) Destroy() error { | |
| 983 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "wp_image_description_v1.destroy", Destructor: true}); err != nil { | |
| 984 | - | return err | |
| 985 | - | } | |
| 986 | - | return nil | |
| 987 | - | } | |
| 988 | - | ||
| 989 | - | // Creates a wp_image_description_info_v1 object which delivers the information that makes up the image description. Not all image description protocol objects allow get_information request. Whether it is allowed or not is defined by the request that created the object. If get_information is not allowed, the protocol error no_information is raised. | |
| 990 | - | func (o *WpImageDescription) GetInformation() (*WpImageDescriptionInfo, error) { | |
| 991 | - | child := &WpImageDescriptionInfo{} | |
| 992 | - | child.SetContext(o.Context()) | |
| 993 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "wp_image_description_v1.get_information", Child: child}, wl.ArgObject(child)); err != nil { | |
| 994 | - | return nil, err | |
| 995 | - | } | |
| 996 | - | return child, nil | |
| 997 | - | } | |
| 998 | - | ||
| 999 | - | // OnFailed registers a handler for the failed event. | |
| 1000 | - | // | |
| 1001 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 1002 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 1003 | - | func (o *WpImageDescription) OnFailed(handler func(cause uint32, msg string)) { | |
| 1004 | - | if handler == nil { | |
| 1005 | - | return | |
| 1006 | - | } | |
| 1007 | - | o.handlersMu.Lock() | |
| 1008 | - | defer o.handlersMu.Unlock() | |
| 1009 | - | o.onFailed = append(o.onFailed, handler) | |
| 1010 | - | } | |
| 1011 | - | ||
| 1012 | - | // handlersForFailed returns the handlers registered for failed, taken | |
| 1013 | - | // under the lock so a handler may register another handler while events are | |
| 1014 | - | // being dispatched. | |
| 1015 | - | func (o *WpImageDescription) handlersForFailed() []func(cause uint32, msg string) { | |
| 1016 | - | o.handlersMu.Lock() | |
| 1017 | - | defer o.handlersMu.Unlock() | |
| 1018 | - | return o.onFailed | |
| 1019 | - | } | |
| 1020 | - | ||
| 1021 | - | // OnReady registers a handler for the ready event. | |
| 1022 | - | // | |
| 1023 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 1024 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 1025 | - | func (o *WpImageDescription) OnReady(handler func(identity uint32)) { | |
| 1026 | - | if handler == nil { | |
| 1027 | - | return | |
| 1028 | - | } | |
| 1029 | - | o.handlersMu.Lock() | |
| 1030 | - | defer o.handlersMu.Unlock() | |
| 1031 | - | o.onReady = append(o.onReady, handler) | |
| 1032 | - | } | |
| 1033 | - | ||
| 1034 | - | // handlersForReady returns the handlers registered for ready, taken | |
| 1035 | - | // under the lock so a handler may register another handler while events are | |
| 1036 | - | // being dispatched. | |
| 1037 | - | func (o *WpImageDescription) handlersForReady() []func(identity uint32) { | |
| 1038 | - | o.handlersMu.Lock() | |
| 1039 | - | defer o.handlersMu.Unlock() | |
| 1040 | - | return o.onReady | |
| 1041 | - | } | |
| 1042 | - | ||
| 1043 | - | // OnReady2 registers a handler for the ready2 event. | |
| 1044 | - | // | |
| 1045 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 1046 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 1047 | - | func (o *WpImageDescription) OnReady2(handler func(identityHi uint32, identityLo uint32)) { | |
| 1048 | - | if handler == nil { | |
| 1049 | - | return | |
| 1050 | - | } | |
| 1051 | - | o.handlersMu.Lock() | |
| 1052 | - | defer o.handlersMu.Unlock() | |
| 1053 | - | o.onReady2 = append(o.onReady2, handler) | |
| 1054 | - | } | |
| 1055 | - | ||
| 1056 | - | // handlersForReady2 returns the handlers registered for ready2, taken | |
| 1057 | - | // under the lock so a handler may register another handler while events are | |
| 1058 | - | // being dispatched. | |
| 1059 | - | func (o *WpImageDescription) handlersForReady2() []func(identityHi uint32, identityLo uint32) { | |
| 1060 | - | o.handlersMu.Lock() | |
| 1061 | - | defer o.handlersMu.Unlock() | |
| 1062 | - | return o.onReady2 | |
| 1063 | - | } | |
| 1064 | - | ||
| 1065 | - | // EventSignature returns the declared event argument types in wire order. | |
| 1066 | - | func (o *WpImageDescription) EventSignature(opcode uint16) (string, bool) { | |
| 1067 | - | switch opcode { | |
| 1068 | - | case 0: | |
| 1069 | - | return "uint,string,", true | |
| 1070 | - | case 1: | |
| 1071 | - | return "uint,", true | |
| 1072 | - | case 2: | |
| 1073 | - | return "uint,uint,", true | |
| 1074 | - | default: | |
| 1075 | - | return "", false | |
| 1076 | - | } | |
| 1077 | - | } | |
| 1078 | - | ||
| 1079 | - | // Dispatch decodes one event on wp_image_description_v1 and calls the registered handlers. | |
| 1080 | - | func (o *WpImageDescription) Dispatch(event *wl.Event) { | |
| 1081 | - | switch event.Opcode { | |
| 1082 | - | case 0: // failed | |
| 1083 | - | cause := event.Uint32() | |
| 1084 | - | msg := event.String() | |
| 1085 | - | ||
| 1086 | - | for i, handler := range o.handlersForFailed() { | |
| 1087 | - | _ = i | |
| 1088 | - | handler(cause, msg) | |
| 1089 | - | } | |
| 1090 | - | case 1: // ready | |
| 1091 | - | identity := event.Uint32() | |
| 1092 | - | ||
| 1093 | - | for i, handler := range o.handlersForReady() { | |
| 1094 | - | _ = i | |
| 1095 | - | handler(identity) | |
| 1096 | - | } | |
| 1097 | - | case 2: // ready2 | |
| 1098 | - | identityHi := event.Uint32() | |
| 1099 | - | identityLo := event.Uint32() | |
| 1100 | - | ||
| 1101 | - | for i, handler := range o.handlersForReady2() { | |
| 1102 | - | _ = i | |
| 1103 | - | handler(identityHi, identityLo) | |
| 1104 | - | } | |
| 1105 | - | default: | |
| 1106 | - | } | |
| 1107 | - | } | |
| 1108 | - | ||
| 1109 | - | // WpImageDescriptionInfoInterface is the protocol interface name. | |
| 1110 | - | const WpImageDescriptionInfoInterface = "wp_image_description_info_v1" | |
| 1111 | - | ||
| 1112 | - | // WpImageDescriptionInfo is the generated binding for wp_image_description_info_v1 version 3. | |
| 1113 | - | type WpImageDescriptionInfo struct { | |
| 1114 | - | wl.BaseProxy | |
| 1115 | - | // handlersMu guards the handler slices: a client may register or replace | |
| 1116 | - | // handlers while another goroutine dispatches events. | |
| 1117 | - | handlersMu sync.Mutex | |
| 1118 | - | onDone []func() | |
| 1119 | - | onIccFile []func(icc *wl.OwnedFD, iccSize uint32) | |
| 1120 | - | onPrimaries []func(rX int32, rY int32, gX int32, gY int32, bX int32, bY int32, wX int32, wY int32) | |
| 1121 | - | onPrimariesNamed []func(primaries uint32) | |
| 1122 | - | onTfPower []func(eexp uint32) | |
| 1123 | - | onTfNamed []func(tf uint32) | |
| 1124 | - | onLuminances []func(minLum uint32, maxLum uint32, referenceLum uint32) | |
| 1125 | - | onTargetPrimaries []func(rX int32, rY int32, gX int32, gY int32, bX int32, bY int32, wX int32, wY int32) | |
| 1126 | - | onTargetLuminance []func(minLum uint32, maxLum uint32) | |
| 1127 | - | onTargetMaxCll []func(maxCll uint32) | |
| 1128 | - | onTargetMaxFall []func(maxFall uint32) | |
| 1129 | - | } | |
| 1130 | - | ||
| 1131 | - | // NewWpImageDescriptionInfo returns an unbound WpImageDescriptionInfo. | |
| 1132 | - | func NewWpImageDescriptionInfo(ctx *wl.Context) *WpImageDescriptionInfo { | |
| 1133 | - | obj := &WpImageDescriptionInfo{} | |
| 1134 | - | obj.SetContext(ctx) | |
| 1135 | - | ctx.Register(obj) | |
| 1136 | - | return obj | |
| 1137 | - | } | |
| 1138 | - | ||
| 1139 | - | // OnDone registers a handler for the done event. | |
| 1140 | - | // | |
| 1141 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 1142 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 1143 | - | func (o *WpImageDescriptionInfo) OnDone(handler func()) { | |
| 1144 | - | if handler == nil { | |
| 1145 | - | return | |
| 1146 | - | } | |
| 1147 | - | o.handlersMu.Lock() | |
| 1148 | - | defer o.handlersMu.Unlock() | |
| 1149 | - | o.onDone = append(o.onDone, handler) | |
| 1150 | - | } | |
| 1151 | - | ||
| 1152 | - | // handlersForDone returns the handlers registered for done, taken | |
| 1153 | - | // under the lock so a handler may register another handler while events are | |
| 1154 | - | // being dispatched. | |
| 1155 | - | func (o *WpImageDescriptionInfo) handlersForDone() []func() { | |
| 1156 | - | o.handlersMu.Lock() | |
| 1157 | - | defer o.handlersMu.Unlock() | |
| 1158 | - | return o.onDone | |
| 1159 | - | } | |
| 1160 | - | ||
| 1161 | - | // OnIccFile registers a handler for the icc_file event. | |
| 1162 | - | // | |
| 1163 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 1164 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 1165 | - | func (o *WpImageDescriptionInfo) OnIccFile(handler func(icc *wl.OwnedFD, iccSize uint32)) { | |
| 1166 | - | if handler == nil { | |
| 1167 | - | return | |
| 1168 | - | } | |
| 1169 | - | o.handlersMu.Lock() | |
| 1170 | - | defer o.handlersMu.Unlock() | |
| 1171 | - | o.onIccFile = append(o.onIccFile, handler) | |
| 1172 | - | } | |
| 1173 | - | ||
| 1174 | - | // handlersForIccFile returns the handlers registered for icc_file, taken | |
| 1175 | - | // under the lock so a handler may register another handler while events are | |
| 1176 | - | // being dispatched. | |
| 1177 | - | func (o *WpImageDescriptionInfo) handlersForIccFile() []func(icc *wl.OwnedFD, iccSize uint32) { | |
| 1178 | - | o.handlersMu.Lock() | |
| 1179 | - | defer o.handlersMu.Unlock() | |
| 1180 | - | return o.onIccFile | |
| 1181 | - | } | |
| 1182 | - | ||
| 1183 | - | // OnPrimaries registers a handler for the primaries event. | |
| 1184 | - | // | |
| 1185 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 1186 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 1187 | - | func (o *WpImageDescriptionInfo) OnPrimaries(handler func(rX int32, rY int32, gX int32, gY int32, bX int32, bY int32, wX int32, wY int32)) { | |
| 1188 | - | if handler == nil { | |
| 1189 | - | return | |
| 1190 | - | } | |
| 1191 | - | o.handlersMu.Lock() | |
| 1192 | - | defer o.handlersMu.Unlock() | |
| 1193 | - | o.onPrimaries = append(o.onPrimaries, handler) | |
| 1194 | - | } | |
| 1195 | - | ||
| 1196 | - | // handlersForPrimaries returns the handlers registered for primaries, taken | |
| 1197 | - | // under the lock so a handler may register another handler while events are | |
| 1198 | - | // being dispatched. | |
| 1199 | - | func (o *WpImageDescriptionInfo) handlersForPrimaries() []func(rX int32, rY int32, gX int32, gY int32, bX int32, bY int32, wX int32, wY int32) { | |
| 1200 | - | o.handlersMu.Lock() | |
| 1201 | - | defer o.handlersMu.Unlock() | |
| 1202 | - | return o.onPrimaries | |
| 1203 | - | } | |
| 1204 | - | ||
| 1205 | - | // OnPrimariesNamed registers a handler for the primaries_named event. | |
| 1206 | - | // | |
| 1207 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 1208 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 1209 | - | func (o *WpImageDescriptionInfo) OnPrimariesNamed(handler func(primaries uint32)) { | |
| 1210 | - | if handler == nil { | |
| 1211 | - | return | |
| 1212 | - | } | |
| 1213 | - | o.handlersMu.Lock() | |
| 1214 | - | defer o.handlersMu.Unlock() | |
| 1215 | - | o.onPrimariesNamed = append(o.onPrimariesNamed, handler) | |
| 1216 | - | } | |
| 1217 | - | ||
| 1218 | - | // handlersForPrimariesNamed returns the handlers registered for primaries_named, taken | |
| 1219 | - | // under the lock so a handler may register another handler while events are | |
| 1220 | - | // being dispatched. | |
| 1221 | - | func (o *WpImageDescriptionInfo) handlersForPrimariesNamed() []func(primaries uint32) { | |
| 1222 | - | o.handlersMu.Lock() | |
| 1223 | - | defer o.handlersMu.Unlock() | |
| 1224 | - | return o.onPrimariesNamed | |
| 1225 | - | } | |
| 1226 | - | ||
| 1227 | - | // OnTfPower registers a handler for the tf_power event. | |
| 1228 | - | // | |
| 1229 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 1230 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 1231 | - | func (o *WpImageDescriptionInfo) OnTfPower(handler func(eexp uint32)) { | |
| 1232 | - | if handler == nil { | |
| 1233 | - | return | |
| 1234 | - | } | |
| 1235 | - | o.handlersMu.Lock() | |
| 1236 | - | defer o.handlersMu.Unlock() | |
| 1237 | - | o.onTfPower = append(o.onTfPower, handler) | |
| 1238 | - | } | |
| 1239 | - | ||
| 1240 | - | // handlersForTfPower returns the handlers registered for tf_power, taken | |
| 1241 | - | // under the lock so a handler may register another handler while events are | |
| 1242 | - | // being dispatched. | |
| 1243 | - | func (o *WpImageDescriptionInfo) handlersForTfPower() []func(eexp uint32) { | |
| 1244 | - | o.handlersMu.Lock() | |
| 1245 | - | defer o.handlersMu.Unlock() | |
| 1246 | - | return o.onTfPower | |
| 1247 | - | } | |
| 1248 | - | ||
| 1249 | - | // OnTfNamed registers a handler for the tf_named event. | |
| 1250 | - | // | |
| 1251 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 1252 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 1253 | - | func (o *WpImageDescriptionInfo) OnTfNamed(handler func(tf uint32)) { | |
| 1254 | - | if handler == nil { | |
| 1255 | - | return | |
| 1256 | - | } | |
| 1257 | - | o.handlersMu.Lock() | |
| 1258 | - | defer o.handlersMu.Unlock() | |
| 1259 | - | o.onTfNamed = append(o.onTfNamed, handler) | |
| 1260 | - | } | |
| 1261 | - | ||
| 1262 | - | // handlersForTfNamed returns the handlers registered for tf_named, taken | |
| 1263 | - | // under the lock so a handler may register another handler while events are | |
| 1264 | - | // being dispatched. | |
| 1265 | - | func (o *WpImageDescriptionInfo) handlersForTfNamed() []func(tf uint32) { | |
| 1266 | - | o.handlersMu.Lock() | |
| 1267 | - | defer o.handlersMu.Unlock() | |
| 1268 | - | return o.onTfNamed | |
| 1269 | - | } | |
| 1270 | - | ||
| 1271 | - | // OnLuminances registers a handler for the luminances event. | |
| 1272 | - | // | |
| 1273 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 1274 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 1275 | - | func (o *WpImageDescriptionInfo) OnLuminances(handler func(minLum uint32, maxLum uint32, referenceLum uint32)) { | |
| 1276 | - | if handler == nil { | |
| 1277 | - | return | |
| 1278 | - | } | |
| 1279 | - | o.handlersMu.Lock() | |
| 1280 | - | defer o.handlersMu.Unlock() | |
| 1281 | - | o.onLuminances = append(o.onLuminances, handler) | |
| 1282 | - | } | |
| 1283 | - | ||
| 1284 | - | // handlersForLuminances returns the handlers registered for luminances, taken | |
| 1285 | - | // under the lock so a handler may register another handler while events are | |
| 1286 | - | // being dispatched. | |
| 1287 | - | func (o *WpImageDescriptionInfo) handlersForLuminances() []func(minLum uint32, maxLum uint32, referenceLum uint32) { | |
| 1288 | - | o.handlersMu.Lock() | |
| 1289 | - | defer o.handlersMu.Unlock() | |
| 1290 | - | return o.onLuminances | |
| 1291 | - | } | |
| 1292 | - | ||
| 1293 | - | // OnTargetPrimaries registers a handler for the target_primaries event. | |
| 1294 | - | // | |
| 1295 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 1296 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 1297 | - | func (o *WpImageDescriptionInfo) OnTargetPrimaries(handler func(rX int32, rY int32, gX int32, gY int32, bX int32, bY int32, wX int32, wY int32)) { | |
| 1298 | - | if handler == nil { | |
| 1299 | - | return | |
| 1300 | - | } | |
| 1301 | - | o.handlersMu.Lock() | |
| 1302 | - | defer o.handlersMu.Unlock() | |
| 1303 | - | o.onTargetPrimaries = append(o.onTargetPrimaries, handler) | |
| 1304 | - | } | |
| 1305 | - | ||
| 1306 | - | // handlersForTargetPrimaries returns the handlers registered for target_primaries, taken | |
| 1307 | - | // under the lock so a handler may register another handler while events are | |
| 1308 | - | // being dispatched. | |
| 1309 | - | func (o *WpImageDescriptionInfo) handlersForTargetPrimaries() []func(rX int32, rY int32, gX int32, gY int32, bX int32, bY int32, wX int32, wY int32) { | |
| 1310 | - | o.handlersMu.Lock() | |
| 1311 | - | defer o.handlersMu.Unlock() | |
| 1312 | - | return o.onTargetPrimaries | |
| 1313 | - | } | |
| 1314 | - | ||
| 1315 | - | // OnTargetLuminance registers a handler for the target_luminance event. | |
| 1316 | - | // | |
| 1317 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 1318 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 1319 | - | func (o *WpImageDescriptionInfo) OnTargetLuminance(handler func(minLum uint32, maxLum uint32)) { | |
| 1320 | - | if handler == nil { | |
| 1321 | - | return | |
| 1322 | - | } | |
| 1323 | - | o.handlersMu.Lock() | |
| 1324 | - | defer o.handlersMu.Unlock() | |
| 1325 | - | o.onTargetLuminance = append(o.onTargetLuminance, handler) | |
| 1326 | - | } | |
| 1327 | - | ||
| 1328 | - | // handlersForTargetLuminance returns the handlers registered for target_luminance, taken | |
| 1329 | - | // under the lock so a handler may register another handler while events are | |
| 1330 | - | // being dispatched. | |
| 1331 | - | func (o *WpImageDescriptionInfo) handlersForTargetLuminance() []func(minLum uint32, maxLum uint32) { | |
| 1332 | - | o.handlersMu.Lock() | |
| 1333 | - | defer o.handlersMu.Unlock() | |
| 1334 | - | return o.onTargetLuminance | |
| 1335 | - | } | |
| 1336 | - | ||
| 1337 | - | // OnTargetMaxCll registers a handler for the target_max_cll event. | |
| 1338 | - | // | |
| 1339 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 1340 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 1341 | - | func (o *WpImageDescriptionInfo) OnTargetMaxCll(handler func(maxCll uint32)) { | |
| 1342 | - | if handler == nil { | |
| 1343 | - | return | |
| 1344 | - | } | |
| 1345 | - | o.handlersMu.Lock() | |
| 1346 | - | defer o.handlersMu.Unlock() | |
| 1347 | - | o.onTargetMaxCll = append(o.onTargetMaxCll, handler) | |
| 1348 | - | } | |
| 1349 | - | ||
| 1350 | - | // handlersForTargetMaxCll returns the handlers registered for target_max_cll, taken | |
| 1351 | - | // under the lock so a handler may register another handler while events are | |
| 1352 | - | // being dispatched. | |
| 1353 | - | func (o *WpImageDescriptionInfo) handlersForTargetMaxCll() []func(maxCll uint32) { | |
| 1354 | - | o.handlersMu.Lock() | |
| 1355 | - | defer o.handlersMu.Unlock() | |
| 1356 | - | return o.onTargetMaxCll | |
| 1357 | - | } | |
| 1358 | - | ||
| 1359 | - | // OnTargetMaxFall registers a handler for the target_max_fall event. | |
| 1360 | - | // | |
| 1361 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 1362 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 1363 | - | func (o *WpImageDescriptionInfo) OnTargetMaxFall(handler func(maxFall uint32)) { | |
| 1364 | - | if handler == nil { | |
| 1365 | - | return | |
| 1366 | - | } | |
| 1367 | - | o.handlersMu.Lock() | |
| 1368 | - | defer o.handlersMu.Unlock() | |
| 1369 | - | o.onTargetMaxFall = append(o.onTargetMaxFall, handler) | |
| 1370 | - | } | |
| 1371 | - | ||
| 1372 | - | // handlersForTargetMaxFall returns the handlers registered for target_max_fall, taken | |
| 1373 | - | // under the lock so a handler may register another handler while events are | |
| 1374 | - | // being dispatched. | |
| 1375 | - | func (o *WpImageDescriptionInfo) handlersForTargetMaxFall() []func(maxFall uint32) { | |
| 1376 | - | o.handlersMu.Lock() | |
| 1377 | - | defer o.handlersMu.Unlock() | |
| 1378 | - | return o.onTargetMaxFall | |
| 1379 | - | } | |
| 1380 | - | ||
| 1381 | - | // EventSignature returns the declared event argument types in wire order. | |
| 1382 | - | func (o *WpImageDescriptionInfo) EventSignature(opcode uint16) (string, bool) { | |
| 1383 | - | switch opcode { | |
| 1384 | - | case 0: | |
| 1385 | - | return "", true | |
| 1386 | - | case 1: | |
| 1387 | - | return "fd,uint,", true | |
| 1388 | - | case 2: | |
| 1389 | - | return "int,int,int,int,int,int,int,int,", true | |
| 1390 | - | case 3: | |
| 1391 | - | return "uint,", true | |
| 1392 | - | case 4: | |
| 1393 | - | return "uint,", true | |
| 1394 | - | case 5: | |
| 1395 | - | return "uint,", true | |
| 1396 | - | case 6: | |
| 1397 | - | return "uint,uint,uint,", true | |
| 1398 | - | case 7: | |
| 1399 | - | return "int,int,int,int,int,int,int,int,", true | |
| 1400 | - | case 8: | |
| 1401 | - | return "uint,uint,", true | |
| 1402 | - | case 9: | |
| 1403 | - | return "uint,", true | |
| 1404 | - | case 10: | |
| 1405 | - | return "uint,", true | |
| 1406 | - | default: | |
| 1407 | - | return "", false | |
| 1408 | - | } | |
| 1409 | - | } | |
| 1410 | - | ||
| 1411 | - | // Dispatch decodes one event on wp_image_description_info_v1 and calls the registered handlers. | |
| 1412 | - | func (o *WpImageDescriptionInfo) Dispatch(event *wl.Event) { | |
| 1413 | - | switch event.Opcode { | |
| 1414 | - | case 0: // done | |
| 1415 | - | ||
| 1416 | - | for i, handler := range o.handlersForDone() { | |
| 1417 | - | _ = i | |
| 1418 | - | handler() | |
| 1419 | - | } | |
| 1420 | - | o.Context().Unregister(o) | |
| 1421 | - | case 1: // icc_file | |
| 1422 | - | icc := event.FD() | |
| 1423 | - | iccSize := event.Uint32() | |
| 1424 | - | ownedicc := icc | |
| 1425 | - | defer ownedicc.Close() | |
| 1426 | - | ||
| 1427 | - | for i, handler := range o.handlersForIccFile() { | |
| 1428 | - | if i > 0 { | |
| 1429 | - | icc = nil | |
| 1430 | - | } | |
| 1431 | - | handler(icc, iccSize) | |
| 1432 | - | } | |
| 1433 | - | case 2: // primaries | |
| 1434 | - | rX := event.Int32() | |
| 1435 | - | rY := event.Int32() | |
| 1436 | - | gX := event.Int32() | |
| 1437 | - | gY := event.Int32() | |
| 1438 | - | bX := event.Int32() | |
| 1439 | - | bY := event.Int32() | |
| 1440 | - | wX := event.Int32() | |
| 1441 | - | wY := event.Int32() | |
| 1442 | - | ||
| 1443 | - | for i, handler := range o.handlersForPrimaries() { | |
| 1444 | - | _ = i | |
| 1445 | - | handler(rX, rY, gX, gY, bX, bY, wX, wY) | |
| 1446 | - | } | |
| 1447 | - | case 3: // primaries_named | |
| 1448 | - | primaries := event.Uint32() | |
| 1449 | - | ||
| 1450 | - | for i, handler := range o.handlersForPrimariesNamed() { | |
| 1451 | - | _ = i | |
| 1452 | - | handler(primaries) | |
| 1453 | - | } | |
| 1454 | - | case 4: // tf_power | |
| 1455 | - | eexp := event.Uint32() | |
| 1456 | - | ||
| 1457 | - | for i, handler := range o.handlersForTfPower() { | |
| 1458 | - | _ = i | |
| 1459 | - | handler(eexp) | |
| 1460 | - | } | |
| 1461 | - | case 5: // tf_named | |
| 1462 | - | tf := event.Uint32() | |
| 1463 | - | ||
| 1464 | - | for i, handler := range o.handlersForTfNamed() { | |
| 1465 | - | _ = i | |
| 1466 | - | handler(tf) | |
| 1467 | - | } | |
| 1468 | - | case 6: // luminances | |
| 1469 | - | minLum := event.Uint32() | |
| 1470 | - | maxLum := event.Uint32() | |
| 1471 | - | referenceLum := event.Uint32() | |
| 1472 | - | ||
| 1473 | - | for i, handler := range o.handlersForLuminances() { | |
| 1474 | - | _ = i | |
| 1475 | - | handler(minLum, maxLum, referenceLum) | |
| 1476 | - | } | |
| 1477 | - | case 7: // target_primaries | |
| 1478 | - | rX := event.Int32() | |
| 1479 | - | rY := event.Int32() | |
| 1480 | - | gX := event.Int32() | |
| 1481 | - | gY := event.Int32() | |
| 1482 | - | bX := event.Int32() | |
| 1483 | - | bY := event.Int32() | |
| 1484 | - | wX := event.Int32() | |
| 1485 | - | wY := event.Int32() | |
| 1486 | - | ||
| 1487 | - | for i, handler := range o.handlersForTargetPrimaries() { | |
| 1488 | - | _ = i | |
| 1489 | - | handler(rX, rY, gX, gY, bX, bY, wX, wY) | |
| 1490 | - | } | |
| 1491 | - | case 8: // target_luminance | |
| 1492 | - | minLum := event.Uint32() | |
| 1493 | - | maxLum := event.Uint32() | |
| 1494 | - | ||
| 1495 | - | for i, handler := range o.handlersForTargetLuminance() { | |
| 1496 | - | _ = i | |
| 1497 | - | handler(minLum, maxLum) | |
| 1498 | - | } | |
| 1499 | - | case 9: // target_max_cll | |
| 1500 | - | maxCll := event.Uint32() | |
| 1501 | - | ||
| 1502 | - | for i, handler := range o.handlersForTargetMaxCll() { | |
| 1503 | - | _ = i | |
| 1504 | - | handler(maxCll) | |
| 1505 | - | } | |
| 1506 | - | case 10: // target_max_fall | |
| 1507 | - | maxFall := event.Uint32() | |
| 1508 | - | ||
| 1509 | - | for i, handler := range o.handlersForTargetMaxFall() { | |
| 1510 | - | _ = i | |
| 1511 | - | handler(maxFall) | |
| 1512 | - | } | |
| 1513 | - | default: | |
| 1514 | - | } | |
| 1515 | - | } | |
| 1516 | - | ||
| 1517 | - | // WpImageDescriptionReferenceInterface is the protocol interface name. | |
| 1518 | - | const WpImageDescriptionReferenceInterface = "wp_image_description_reference_v1" | |
| 1519 | - | ||
| 1520 | - | // WpImageDescriptionReference is the generated binding for wp_image_description_reference_v1 version 1. | |
| 1521 | - | type WpImageDescriptionReference struct { | |
| 1522 | - | wl.BaseProxy | |
| 1523 | - | } | |
| 1524 | - | ||
| 1525 | - | // NewWpImageDescriptionReference returns an unbound WpImageDescriptionReference. | |
| 1526 | - | func NewWpImageDescriptionReference(ctx *wl.Context) *WpImageDescriptionReference { | |
| 1527 | - | obj := &WpImageDescriptionReference{} | |
| 1528 | - | obj.SetContext(ctx) | |
| 1529 | - | ctx.Register(obj) | |
| 1530 | - | return obj | |
| 1531 | - | } | |
| 1532 | - | ||
| 1533 | - | // Destroy this object. This has no effect on the referenced image description. | |
| 1534 | - | func (o *WpImageDescriptionReference) Destroy() error { | |
| 1535 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "wp_image_description_reference_v1.destroy", Destructor: true}); err != nil { | |
| 1536 | - | return err | |
| 1537 | - | } | |
| 1538 | - | return nil | |
| 1539 | - | } | |
| 1540 | - | ||
| 1541 | - | // EventSignature returns the declared event argument types in wire order. | |
| 1542 | - | func (o *WpImageDescriptionReference) EventSignature(opcode uint16) (string, bool) { | |
| 1543 | - | switch opcode { | |
| 1544 | - | default: | |
| 1545 | - | return "", false | |
| 1546 | - | } | |
| 1547 | - | } | |
| 1548 | - | ||
| 1549 | - | // Dispatch decodes one event on wp_image_description_reference_v1 and calls the registered handlers. | |
| 1550 | - | func (o *WpImageDescriptionReference) Dispatch(event *wl.Event) { | |
| 1551 | - | switch event.Opcode { | |
| 1552 | - | default: | |
| 1553 | - | } | |
| 1554 | - | } | |
D protocol/colormanagement/generate.go +0 -3
| @@ -1,3 +0,0 @@ | |||
| 1 | - | package colormanagement | |
| 2 | - | ||
| 3 | - | //go:generate go run ../../cmd/wlturbo-scanner -p colormanagement -o color-management-v1_generated.go -import wl_surface=github.com/bnema/wlturbo/protocol/core -import wl_output=github.com/bnema/wlturbo/protocol/core color-management-v1.xml | |
D protocol/colorrepresentation/color-representation-v1.xml +0 -433
| @@ -1,433 +0,0 @@ | |||
| 1 | - | <?xml version="1.0" encoding="UTF-8"?> | |
| 2 | - | <protocol name="color_representation_v1"> | |
| 3 | - | <copyright> | |
| 4 | - | Copyright 2022 Simon Ser | |
| 5 | - | Copyright 2022 Red Hat, Inc. | |
| 6 | - | Copyright 2022 Collabora, Ltd. | |
| 7 | - | Copyright 2022-2025 Red Hat, Inc. | |
| 8 | - | ||
| 9 | - | Permission is hereby granted, free of charge, to any person obtaining a | |
| 10 | - | copy of this software and associated documentation files (the "Software"), | |
| 11 | - | to deal in the Software without restriction, including without limitation | |
| 12 | - | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 13 | - | and/or sell copies of the Software, and to permit persons to whom the | |
| 14 | - | Software is furnished to do so, subject to the following conditions: | |
| 15 | - | ||
| 16 | - | The above copyright notice and this permission notice (including the next | |
| 17 | - | paragraph) shall be included in all copies or substantial portions of the | |
| 18 | - | Software. | |
| 19 | - | ||
| 20 | - | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 21 | - | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 22 | - | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 23 | - | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 24 | - | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 25 | - | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
| 26 | - | DEALINGS IN THE SOFTWARE. | |
| 27 | - | </copyright> | |
| 28 | - | ||
| 29 | - | <description summary="color representation protocol extension"> | |
| 30 | - | This protocol extension delivers the metadata required to define alpha mode, | |
| 31 | - | the color model, sub-sampling and quantization range used when interpreting | |
| 32 | - | buffer contents. The main use case is defining how the YCbCr family of pixel | |
| 33 | - | formats convert to RGB. | |
| 34 | - | ||
| 35 | - | Note that this protocol does not define the colorimetry of the resulting RGB | |
| 36 | - | channels / tristimulus values. Without the help of other extensions the | |
| 37 | - | resulting colorimetry is therefore implementation defined. | |
| 38 | - | ||
| 39 | - | If this extension is not used, the color representation used is compositor | |
| 40 | - | implementation defined. | |
| 41 | - | ||
| 42 | - | Recommendation ITU-T H.273 | |
| 43 | - | "Coding-independent code points for video signal type identification" | |
| 44 | - | shall be referred to as simply H.273 here. | |
| 45 | - | </description> | |
| 46 | - | ||
| 47 | - | <interface name="wp_color_representation_manager_v1" version="1"> | |
| 48 | - | <description summary="color representation manager singleton"> | |
| 49 | - | A singleton global interface used for getting color representation | |
| 50 | - | extensions for wl_surface. The extension interfaces allow setting the | |
| 51 | - | color representation of surfaces. | |
| 52 | - | ||
| 53 | - | Compositors should never remove this global. | |
| 54 | - | </description> | |
| 55 | - | ||
| 56 | - | <enum name="error"> | |
| 57 | - | <description summary="protocol errors"/> | |
| 58 | - | <entry name="surface_exists" value="1" | |
| 59 | - | summary="color representation surface exists already"/> | |
| 60 | - | </enum> | |
| 61 | - | ||
| 62 | - | <request name="destroy" type="destructor"> | |
| 63 | - | <description summary="destroy the manager"> | |
| 64 | - | Destroy the wp_color_representation_manager_v1 object. This does not | |
| 65 | - | affect any other objects in any way. | |
| 66 | - | </description> | |
| 67 | - | ||
| 68 | - | </request> | |
| 69 | - | ||
| 70 | - | <request name="get_surface"> | |
| 71 | - | <description summary="create a color representation interface for a wl_surface"> | |
| 72 | - | If a wp_color_representation_surface_v1 object already exists for the | |
| 73 | - | given wl_surface, the protocol error surface_exists is raised. | |
| 74 | - | ||
| 75 | - | This creates a new color wp_color_representation_surface_v1 object for | |
| 76 | - | the given wl_surface. | |
| 77 | - | ||
| 78 | - | See the wp_color_representation_surface_v1 interface for more details. | |
| 79 | - | </description> | |
| 80 | - | <arg name="id" | |
| 81 | - | type="new_id" interface="wp_color_representation_surface_v1"/> | |
| 82 | - | <arg name="surface" | |
| 83 | - | type="object" interface="wl_surface"/> | |
| 84 | - | </request> | |
| 85 | - | ||
| 86 | - | <event name="supported_alpha_mode"> | |
| 87 | - | <description summary="supported alpha modes"> | |
| 88 | - | When this object is created, it shall immediately send this event once | |
| 89 | - | for each alpha mode the compositor supports. | |
| 90 | - | ||
| 91 | - | For the definition of the supported values, see the | |
| 92 | - | wp_color_representation_surface_v1::alpha_mode enum. | |
| 93 | - | </description> | |
| 94 | - | <arg name="alpha_mode" | |
| 95 | - | type="uint" enum="wp_color_representation_surface_v1.alpha_mode" | |
| 96 | - | summary="supported alpha mode"/> | |
| 97 | - | </event> | |
| 98 | - | ||
| 99 | - | <event name="supported_coefficients_and_ranges"> | |
| 100 | - | <description summary="supported matrix coefficients and ranges"> | |
| 101 | - | When this object is created, it shall immediately send this event once | |
| 102 | - | for each matrix coefficient and color range combination the compositor | |
| 103 | - | supports. | |
| 104 | - | ||
| 105 | - | For the definition of the supported values, see the | |
| 106 | - | wp_color_representation_surface_v1::coefficients and | |
| 107 | - | wp_color_representation_surface_v1::range enums. | |
| 108 | - | </description> | |
| 109 | - | <arg name="coefficients" | |
| 110 | - | type="uint" enum="wp_color_representation_surface_v1.coefficients" | |
| 111 | - | summary="supported matrix coefficients"/> | |
| 112 | - | <arg name="range" | |
| 113 | - | type="uint" enum="wp_color_representation_surface_v1.range" | |
| 114 | - | summary="full range flag"/> | |
| 115 | - | </event> | |
| 116 | - | ||
| 117 | - | <event name="done"> | |
| 118 | - | <description summary="all features have been sent"> | |
| 119 | - | This event is sent when all supported features have been sent. | |
| 120 | - | </description> | |
| 121 | - | </event> | |
| 122 | - | </interface> | |
| 123 | - | ||
| 124 | - | <interface name="wp_color_representation_surface_v1" version="1"> | |
| 125 | - | <description summary="color representation extension to a surface"> | |
| 126 | - | A wp_color_representation_surface_v1 allows the client to set the color | |
| 127 | - | representation metadata of a surface. | |
| 128 | - | ||
| 129 | - | By default, a surface does not have any color representation metadata set. | |
| 130 | - | The reconstruction of R, G, B signals on such surfaces is compositor | |
| 131 | - | implementation defined. The alpha mode is assumed to be | |
| 132 | - | premultiplied_electrical when the alpha mode is unset. | |
| 133 | - | ||
| 134 | - | If the wl_surface associated with the wp_color_representation_surface_v1 | |
| 135 | - | is destroyed, the wp_color_representation_surface_v1 object becomes inert. | |
| 136 | - | </description> | |
| 137 | - | ||
| 138 | - | <enum name="error"> | |
| 139 | - | <description summary="protocol errors"/> | |
| 140 | - | <entry name="alpha_mode" value="1" | |
| 141 | - | summary="unsupported alpha mode"/> | |
| 142 | - | <entry name="coefficients" value="2" | |
| 143 | - | summary="unsupported coefficients"/> | |
| 144 | - | <entry name="pixel_format" value="3" | |
| 145 | - | summary="the pixel format and a set value are incompatible"/> | |
| 146 | - | <entry name="inert" value="4" | |
| 147 | - | summary="forbidden request on inert object"/> | |
| 148 | - | <entry name="chroma_location" value="5" | |
| 149 | - | summary="invalid chroma location"/> | |
| 150 | - | </enum> | |
| 151 | - | ||
| 152 | - | <request name="destroy" type="destructor"> | |
| 153 | - | <description summary="destroy the color representation"> | |
| 154 | - | Destroy the wp_color_representation_surface_v1 object. | |
| 155 | - | ||
| 156 | - | Destroying this object unsets all the color representation metadata from | |
| 157 | - | the surface. See the wp_color_representation_surface_v1 interface | |
| 158 | - | description for how a compositor handles a surface without color | |
| 159 | - | representation metadata. Unsetting is double-buffered state, see | |
| 160 | - | wl_surface.commit. | |
| 161 | - | </description> | |
| 162 | - | </request> | |
| 163 | - | ||
| 164 | - | <enum name="alpha_mode"> | |
| 165 | - | <description summary="alpha mode"> | |
| 166 | - | Specifies how the alpha channel affects the color channels. | |
| 167 | - | </description> | |
| 168 | - | <entry name="premultiplied_electrical" value="0"> | |
| 169 | - | <description summary="premultiplied alpha in electrical values"> | |
| 170 | - | Electrical color channel values (after transfer function encoding) | |
| 171 | - | are already multiplied with the alpha channel value. | |
| 172 | - | </description> | |
| 173 | - | </entry> | |
| 174 | - | <entry name="premultiplied_optical" value="1"> | |
| 175 | - | <description summary="premultiplied alpha in optical values"> | |
| 176 | - | Optical color channel values (before transfer function encoding) | |
| 177 | - | are already multiplied with the alpha channel value. | |
| 178 | - | </description> | |
| 179 | - | </entry> | |
| 180 | - | <entry name="straight" value="2"> | |
| 181 | - | <description summary="straight alpha"> | |
| 182 | - | Alpha channel has not been pre-multiplied into color channels. | |
| 183 | - | </description> | |
| 184 | - | </entry> | |
| 185 | - | </enum> | |
| 186 | - | ||
| 187 | - | <enum name="coefficients"> | |
| 188 | - | <description summary="named coefficients"> | |
| 189 | - | Named matrix coefficients used to encode well-known sets of | |
| 190 | - | coefficients. H.273 is the authority, when it comes to the exact values | |
| 191 | - | of coefficients and authoritative specifications, where an equivalent | |
| 192 | - | code point exists. | |
| 193 | - | ||
| 194 | - | A value of 0 is invalid and will never be present in the list of enums. | |
| 195 | - | ||
| 196 | - | Descriptions do list the specifications for convenience. | |
| 197 | - | </description> | |
| 198 | - | <entry name="identity" value="1"> | |
| 199 | - | <description summary="The identity matrix"> | |
| 200 | - | Coefficients as defined by | |
| 201 | - | - IEC 61966-2-1 sRGB | |
| 202 | - | - SMPTE ST 428-1 (2019) | |
| 203 | - | ||
| 204 | - | Equivalent to H.273 MatrixCoefficients code point 0. | |
| 205 | - | Compatible with pixel formats of the RGB family. | |
| 206 | - | </description> | |
| 207 | - | </entry> | |
| 208 | - | <entry name="bt709" value="2"> | |
| 209 | - | <description summary="BT.709 matrix coefficients"> | |
| 210 | - | Coefficients as defined by | |
| 211 | - | - Rec. ITU-R BT.709-6 | |
| 212 | - | - Rec. ITU-R BT.1361-0 conventional colour gamut system (historical) | |
| 213 | - | - Rec. ITU-R BT.1361-0 conventional colour gamut system and extended | |
| 214 | - | colour gamut system (historical) | |
| 215 | - | - IEC 61966-2-4 xvYCC709 | |
| 216 | - | - SMPTE RP 177 (1993) Annex B | |
| 217 | - | ||
| 218 | - | Equivalent to H.273 MatrixCoefficients code point 1. | |
| 219 | - | Compatible with pixel formats of the YCbCr family. | |
| 220 | - | </description> | |
| 221 | - | </entry> | |
| 222 | - | <entry name="fcc" value="3"> | |
| 223 | - | <description summary="FCC matrix coefficients"> | |
| 224 | - | Coefficients as defined by | |
| 225 | - | - United States Federal Communications Commission (2003) Title 47 | |
| 226 | - | Code of Federal Regulations 73.682 (a) (20) | |
| 227 | - | ||
| 228 | - | Equivalent to H.273 MatrixCoefficients code point 4. | |
| 229 | - | Compatible with pixel formats of the YCbCr family. | |
| 230 | - | </description> | |
| 231 | - | </entry> | |
| 232 | - | <entry name="bt601" value="4"> | |
| 233 | - | <description summary="BT.601-7 matrix coefficients"> | |
| 234 | - | Coefficients as defined by | |
| 235 | - | - Rec. ITU-R BT.470-6 System B, G (historical) | |
| 236 | - | - Rec. ITU-R BT.601-7 625 | |
| 237 | - | - Rec. ITU-R BT.601-7 525 | |
| 238 | - | - Rec. ITU-R BT.1358-0 625 (historical) | |
| 239 | - | - Rec. ITU-R BT.1358-1 525 or 625 (historical) | |
| 240 | - | - Rec. ITU-R BT.1700-0 625 PAL and 625 SECAM | |
| 241 | - | - Rec. ITU-R BT.1700-0 NTSC | |
| 242 | - | - IEC 61966-2-1 sYCC | |
| 243 | - | - IEC 61966-2-4 xvYCC601 | |
| 244 | - | - SMPTE ST 170 (2004) | |
| 245 | - | ||
| 246 | - | Equivalent to H.273 MatrixCoefficients code point 5, 6. | |
| 247 | - | Compatible with pixel formats of the YCbCr family. | |
| 248 | - | </description> | |
| 249 | - | </entry> | |
| 250 | - | <entry name="smpte240" value="5"> | |
| 251 | - | <description summary="SMPTE ST 240 matrix coefficients"> | |
| 252 | - | Coefficients as defined by | |
| 253 | - | - SMPTE ST 240 (1999) | |
| 254 | - | ||
| 255 | - | Equivalent to H.273 MatrixCoefficients code point 7. | |
| 256 | - | Compatible with pixel formats of the YCbCr family. | |
| 257 | - | </description> | |
| 258 | - | </entry> | |
| 259 | - | <entry name="bt2020" value="6"> | |
| 260 | - | <description summary="BT.2020 and BT.2100 YCbCr matrix coefficients"> | |
| 261 | - | Coefficients as defined by | |
| 262 | - | - Rec. ITU-R BT.2020-2 (non-constant luminance) | |
| 263 | - | - Rec. ITU-R BT.2100-2 Y′CbCr | |
| 264 | - | ||
| 265 | - | Equivalent to H.273 MatrixCoefficients code point 9. | |
| 266 | - | Compatible with pixel formats of the YCbCr family. | |
| 267 | - | </description> | |
| 268 | - | </entry> | |
| 269 | - | <entry name="bt2020_cl" value="7"> | |
| 270 | - | <description summary="BT.2020 matrix coefficients for constant luminance"> | |
| 271 | - | Coefficients as defined by | |
| 272 | - | - Rec. ITU-R BT.2020-2 (constant luminance) | |
| 273 | - | ||
| 274 | - | Equivalent to H.273 MatrixCoefficients code point 10. | |
| 275 | - | Compatible with pixel formats of the YCbCr family. | |
| 276 | - | </description> | |
| 277 | - | </entry> | |
| 278 | - | <entry name="ictcp" value="8"> | |
| 279 | - | <description summary="BT.2100 ICtCp matrix coefficients"> | |
| 280 | - | Coefficients as defined by | |
| 281 | - | - Rec. ITU-R BT.2100-2 ICTCP | |
| 282 | - | ||
| 283 | - | Equivalent to H.273 MatrixCoefficients code point 14. | |
| 284 | - | Compatible with pixel formats of the YCbCr family. | |
| 285 | - | </description> | |
| 286 | - | </entry> | |
| 287 | - | </enum> | |
| 288 | - | ||
| 289 | - | <enum name="range"> | |
| 290 | - | <description summary="Color range values"> | |
| 291 | - | Possible color range values. | |
| 292 | - | ||
| 293 | - | A value of 0 is invalid and will never be present in the list of enums. | |
| 294 | - | </description> | |
| 295 | - | <entry name="full" value="1" summary="Full color range"/> | |
| 296 | - | <entry name="limited" value="2" summary="Limited color range"/> | |
| 297 | - | </enum> | |
| 298 | - | ||
| 299 | - | <enum name="chroma_location"> | |
| 300 | - | <description summary="Chroma sample location for 4:2:0 YCbCr"> | |
| 301 | - | Chroma sample location as defined by H.273 Chroma420SampleLocType. | |
| 302 | - | ||
| 303 | - | A value of 0 is invalid and will never be present in the list of enums. | |
| 304 | - | ||
| 305 | - | The descriptions list the matching Vulkan VkChromaLocation combinations | |
| 306 | - | for convenience. | |
| 307 | - | </description> | |
| 308 | - | <entry name="type_0" value="1"> | |
| 309 | - | <description summary="Horizontal offset of 0, vertical offset of 0.5"> | |
| 310 | - | Corresponding to VkChromaLocations: | |
| 311 | - | - xChromaOffset: VK_CHROMA_LOCATION_COSITED_EVEN | |
| 312 | - | - yChromaOffset: VK_CHROMA_LOCATION_MIDPOINT | |
| 313 | - | ||
| 314 | - | Equivalent to H.273 Chroma420SampleLocType 0. | |
| 315 | - | </description> | |
| 316 | - | </entry> | |
| 317 | - | <entry name="type_1" value="2"> | |
| 318 | - | <description summary="Horizontal offset of 0.5, vertical offset of 0.5"> | |
| 319 | - | Corresponding to VkChromaLocations: | |
| 320 | - | - xChromaOffset: VK_CHROMA_LOCATION_MIDPOINT | |
| 321 | - | - yChromaOffset: VK_CHROMA_LOCATION_MIDPOINT | |
| 322 | - | ||
| 323 | - | Equivalent to H.273 Chroma420SampleLocType 1. | |
| 324 | - | </description> | |
| 325 | - | </entry> | |
| 326 | - | <entry name="type_2" value="3"> | |
| 327 | - | <description summary="Horizontal offset of 0, vertical offset of 0"> | |
| 328 | - | Corresponding to VkChromaLocations: | |
| 329 | - | - xChromaOffset: VK_CHROMA_LOCATION_COSITED_EVEN | |
| 330 | - | - yChromaOffset: VK_CHROMA_LOCATION_COSITED_EVEN | |
| 331 | - | ||
| 332 | - | Equivalent to H.273 Chroma420SampleLocType 2. | |
| 333 | - | </description> | |
| 334 | - | </entry> | |
| 335 | - | <entry name="type_3" value="4"> | |
| 336 | - | <description summary="Horizontal offset of 0.5, vertical offset of 0"> | |
| 337 | - | Corresponding to VkChromaLocations: | |
| 338 | - | - xChromaOffset: VK_CHROMA_LOCATION_MIDPOINT | |
| 339 | - | - yChromaOffset: VK_CHROMA_LOCATION_COSITED_EVEN | |
| 340 | - | ||
| 341 | - | Equivalent to H.273 Chroma420SampleLocType 3. | |
| 342 | - | </description> | |
| 343 | - | </entry> | |
| 344 | - | <entry name="type_4" value="5"> | |
| 345 | - | <description summary="Horizontal offset of 0, vertical offset of 1"> | |
| 346 | - | Equivalent to H.273 Chroma420SampleLocType 4. | |
| 347 | - | </description> | |
| 348 | - | </entry> | |
| 349 | - | <entry name="type_5" value="6"> | |
| 350 | - | <description summary="Horizontal offset of 0.5, vertical offset of 1"> | |
| 351 | - | Equivalent to H.273 Chroma420SampleLocType 5. | |
| 352 | - | </description> | |
| 353 | - | </entry> | |
| 354 | - | </enum> | |
| 355 | - | ||
| 356 | - | <request name="set_alpha_mode"> | |
| 357 | - | <description summary="set the surface alpha mode"> | |
| 358 | - | If this protocol object is inert, the protocol error inert is raised. | |
| 359 | - | ||
| 360 | - | Assuming an alpha channel exists, it is always linear. The alpha mode | |
| 361 | - | determines whether and how the color channels include pre-multiplied | |
| 362 | - | alpha. Using straight alpha might have performance benefits. | |
| 363 | - | ||
| 364 | - | Only alpha modes advertised by the compositor are allowed to be used as | |
| 365 | - | argument for this request. The "alpha_mode" protocol error is raised | |
| 366 | - | otherwise. | |
| 367 | - | ||
| 368 | - | Alpha mode is double buffered, see wl_surface.commit. | |
| 369 | - | </description> | |
| 370 | - | <arg name="alpha_mode" type="uint" enum="alpha_mode" | |
| 371 | - | summary="alpha mode"/> | |
| 372 | - | </request> | |
| 373 | - | ||
| 374 | - | <request name="set_coefficients_and_range"> | |
| 375 | - | <description summary="set the matrix coefficients and range"> | |
| 376 | - | If this protocol object is inert, the protocol error inert is raised. | |
| 377 | - | ||
| 378 | - | Set the matrix coefficients and video range which defines the formula | |
| 379 | - | and the related constants used to derive red, green and blue signals. | |
| 380 | - | Usually coefficients correspond to MatrixCoefficients code points in | |
| 381 | - | H.273. | |
| 382 | - | ||
| 383 | - | Only combinations advertised by the compositor are allowed to be used as | |
| 384 | - | argument for this request. The "coefficients" protocol error is raised | |
| 385 | - | otherwise. | |
| 386 | - | ||
| 387 | - | A call to wl_surface.commit verifies that the pixel format and the | |
| 388 | - | coefficients-range combination in the committed surface contents are | |
| 389 | - | compatible, if contents exist. The "pixel_format" protocol error is | |
| 390 | - | raised otherwise. | |
| 391 | - | ||
| 392 | - | A pixel format is compatible with the coefficients-range combination if | |
| 393 | - | the related equations and conventions as defined in H.273 can produce | |
| 394 | - | the color channels (RGB or YCbCr) of the pixel format. | |
| 395 | - | ||
| 396 | - | For the definition of the supported combination, see the | |
| 397 | - | wp_color_representation_surface_v1::coefficients and | |
| 398 | - | wp_color_representation_surface_v1::range enums. | |
| 399 | - | ||
| 400 | - | The coefficients-range combination is double-buffered, see | |
| 401 | - | wl_surface.commit. | |
| 402 | - | </description> | |
| 403 | - | <arg name="coefficients" type="uint" enum="coefficients" | |
| 404 | - | summary="matrix coefficients"/> | |
| 405 | - | <arg name="range" type="uint" enum="range" | |
| 406 | - | summary="range"/> | |
| 407 | - | </request> | |
| 408 | - | ||
| 409 | - | <request name="set_chroma_location"> | |
| 410 | - | <description summary="set the chroma location"> | |
| 411 | - | If this protocol object is inert, the protocol error inert is raised. | |
| 412 | - | ||
| 413 | - | Set the chroma location type which defines the position of downsampled | |
| 414 | - | chroma samples, corresponding to Chroma420SampleLocType code points in | |
| 415 | - | H.273. | |
| 416 | - | ||
| 417 | - | An invalid chroma location enum value raises the "chroma_location" | |
| 418 | - | protocol error. | |
| 419 | - | ||
| 420 | - | A call to wl_surface.commit verifies that the pixel format and chroma | |
| 421 | - | location type in the committed surface contents are compatible, if | |
| 422 | - | contents exist. The "pixel_format" protocol error is raised otherwise. | |
| 423 | - | ||
| 424 | - | For the definition of the supported chroma location types, see the | |
| 425 | - | wp_color_representation_surface_v1::chroma_location enum. | |
| 426 | - | ||
| 427 | - | The chroma location type is double-buffered, see wl_surface.commit. | |
| 428 | - | </description> | |
| 429 | - | <arg name="chroma_location" type="uint" enum="chroma_location" | |
| 430 | - | summary="chroma sample location"/> | |
| 431 | - | </request> | |
| 432 | - | </interface> | |
| 433 | - | </protocol> | |
D protocol/colorrepresentation/color-representation-v1_generated.go +0 -327
| @@ -1,327 +0,0 @@ | |||
| 1 | - | // Code generated by wlturbo-scanner. DO NOT EDIT. | |
| 2 | - | // Protocol: color_representation_v1 | |
| 3 | - | // Source: color-representation-v1.xml | |
| 4 | - | ||
| 5 | - | // Upstream protocol copyright and license: | |
| 6 | - | // Copyright 2022 Simon Ser | |
| 7 | - | // Copyright 2022 Red Hat, Inc. | |
| 8 | - | // Copyright 2022 Collabora, Ltd. | |
| 9 | - | // Copyright 2022-2025 Red Hat, Inc. | |
| 10 | - | // | |
| 11 | - | // Permission is hereby granted, free of charge, to any person obtaining a | |
| 12 | - | // copy of this software and associated documentation files (the "Software"), | |
| 13 | - | // to deal in the Software without restriction, including without limitation | |
| 14 | - | // the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 15 | - | // and/or sell copies of the Software, and to permit persons to whom the | |
| 16 | - | // Software is furnished to do so, subject to the following conditions: | |
| 17 | - | // | |
| 18 | - | // The above copyright notice and this permission notice (including the next | |
| 19 | - | // paragraph) shall be included in all copies or substantial portions of the | |
| 20 | - | // Software. | |
| 21 | - | // | |
| 22 | - | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 23 | - | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 24 | - | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 25 | - | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 26 | - | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 27 | - | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
| 28 | - | // DEALINGS IN THE SOFTWARE. | |
| 29 | - | ||
| 30 | - | package colorrepresentation | |
| 31 | - | ||
| 32 | - | import ( | |
| 33 | - | "sync" | |
| 34 | - | ||
| 35 | - | cross_wl_surface "github.com/bnema/wlturbo/protocol/core" | |
| 36 | - | "github.com/bnema/wlturbo/wl" | |
| 37 | - | ) | |
| 38 | - | ||
| 39 | - | // ERROR_SURFACE_EXISTS is the error surface_exists value. | |
| 40 | - | const ERROR_SURFACE_EXISTS = 1 | |
| 41 | - | ||
| 42 | - | // ERROR_ALPHA_MODE is the error alpha_mode value. | |
| 43 | - | const ERROR_ALPHA_MODE = 1 | |
| 44 | - | ||
| 45 | - | // ERROR_COEFFICIENTS is the error coefficients value. | |
| 46 | - | const ERROR_COEFFICIENTS = 2 | |
| 47 | - | ||
| 48 | - | // ERROR_PIXEL_FORMAT is the error pixel_format value. | |
| 49 | - | const ERROR_PIXEL_FORMAT = 3 | |
| 50 | - | ||
| 51 | - | // ERROR_INERT is the error inert value. | |
| 52 | - | const ERROR_INERT = 4 | |
| 53 | - | ||
| 54 | - | // ERROR_CHROMA_LOCATION is the error chroma_location value. | |
| 55 | - | const ERROR_CHROMA_LOCATION = 5 | |
| 56 | - | ||
| 57 | - | // ALPHA_MODE_PREMULTIPLIED_ELECTRICAL is the alpha_mode premultiplied_electrical value. | |
| 58 | - | const ALPHA_MODE_PREMULTIPLIED_ELECTRICAL = 0 | |
| 59 | - | ||
| 60 | - | // ALPHA_MODE_PREMULTIPLIED_OPTICAL is the alpha_mode premultiplied_optical value. | |
| 61 | - | const ALPHA_MODE_PREMULTIPLIED_OPTICAL = 1 | |
| 62 | - | ||
| 63 | - | // ALPHA_MODE_STRAIGHT is the alpha_mode straight value. | |
| 64 | - | const ALPHA_MODE_STRAIGHT = 2 | |
| 65 | - | ||
| 66 | - | // COEFFICIENTS_IDENTITY is the coefficients identity value. | |
| 67 | - | const COEFFICIENTS_IDENTITY = 1 | |
| 68 | - | ||
| 69 | - | // COEFFICIENTS_BT709 is the coefficients bt709 value. | |
| 70 | - | const COEFFICIENTS_BT709 = 2 | |
| 71 | - | ||
| 72 | - | // COEFFICIENTS_FCC is the coefficients fcc value. | |
| 73 | - | const COEFFICIENTS_FCC = 3 | |
| 74 | - | ||
| 75 | - | // COEFFICIENTS_BT601 is the coefficients bt601 value. | |
| 76 | - | const COEFFICIENTS_BT601 = 4 | |
| 77 | - | ||
| 78 | - | // COEFFICIENTS_SMPTE240 is the coefficients smpte240 value. | |
| 79 | - | const COEFFICIENTS_SMPTE240 = 5 | |
| 80 | - | ||
| 81 | - | // COEFFICIENTS_BT2020 is the coefficients bt2020 value. | |
| 82 | - | const COEFFICIENTS_BT2020 = 6 | |
| 83 | - | ||
| 84 | - | // COEFFICIENTS_BT2020_CL is the coefficients bt2020_cl value. | |
| 85 | - | const COEFFICIENTS_BT2020_CL = 7 | |
| 86 | - | ||
| 87 | - | // COEFFICIENTS_ICTCP is the coefficients ictcp value. | |
| 88 | - | const COEFFICIENTS_ICTCP = 8 | |
| 89 | - | ||
| 90 | - | // RANGE_FULL is the range full value. | |
| 91 | - | const RANGE_FULL = 1 | |
| 92 | - | ||
| 93 | - | // RANGE_LIMITED is the range limited value. | |
| 94 | - | const RANGE_LIMITED = 2 | |
| 95 | - | ||
| 96 | - | // CHROMA_LOCATION_TYPE_0 is the chroma_location type_0 value. | |
| 97 | - | const CHROMA_LOCATION_TYPE_0 = 1 | |
| 98 | - | ||
| 99 | - | // CHROMA_LOCATION_TYPE_1 is the chroma_location type_1 value. | |
| 100 | - | const CHROMA_LOCATION_TYPE_1 = 2 | |
| 101 | - | ||
| 102 | - | // CHROMA_LOCATION_TYPE_2 is the chroma_location type_2 value. | |
| 103 | - | const CHROMA_LOCATION_TYPE_2 = 3 | |
| 104 | - | ||
| 105 | - | // CHROMA_LOCATION_TYPE_3 is the chroma_location type_3 value. | |
| 106 | - | const CHROMA_LOCATION_TYPE_3 = 4 | |
| 107 | - | ||
| 108 | - | // CHROMA_LOCATION_TYPE_4 is the chroma_location type_4 value. | |
| 109 | - | const CHROMA_LOCATION_TYPE_4 = 5 | |
| 110 | - | ||
| 111 | - | // CHROMA_LOCATION_TYPE_5 is the chroma_location type_5 value. | |
| 112 | - | const CHROMA_LOCATION_TYPE_5 = 6 | |
| 113 | - | ||
| 114 | - | // WpColorRepresentationManagerInterface is the protocol interface name. | |
| 115 | - | const WpColorRepresentationManagerInterface = "wp_color_representation_manager_v1" | |
| 116 | - | ||
| 117 | - | // WpColorRepresentationManager is the generated binding for wp_color_representation_manager_v1 version 1. | |
| 118 | - | type WpColorRepresentationManager struct { | |
| 119 | - | wl.BaseProxy | |
| 120 | - | // handlersMu guards the handler slices: a client may register or replace | |
| 121 | - | // handlers while another goroutine dispatches events. | |
| 122 | - | handlersMu sync.Mutex | |
| 123 | - | onSupportedAlphaMode []func(alphaMode uint32) | |
| 124 | - | onSupportedCoefficientsAndRanges []func(coefficients uint32, rangeArg uint32) | |
| 125 | - | onDone []func() | |
| 126 | - | } | |
| 127 | - | ||
| 128 | - | // NewWpColorRepresentationManager returns an unbound WpColorRepresentationManager. | |
| 129 | - | func NewWpColorRepresentationManager(ctx *wl.Context) *WpColorRepresentationManager { | |
| 130 | - | obj := &WpColorRepresentationManager{} | |
| 131 | - | obj.SetContext(ctx) | |
| 132 | - | ctx.Register(obj) | |
| 133 | - | return obj | |
| 134 | - | } | |
| 135 | - | ||
| 136 | - | // Destroy the wp_color_representation_manager_v1 object. This does not affect any other objects in any way. | |
| 137 | - | func (o *WpColorRepresentationManager) Destroy() error { | |
| 138 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "wp_color_representation_manager_v1.destroy", Destructor: true}); err != nil { | |
| 139 | - | return err | |
| 140 | - | } | |
| 141 | - | return nil | |
| 142 | - | } | |
| 143 | - | ||
| 144 | - | // If a wp_color_representation_surface_v1 object already exists for the given wl_surface, the protocol error surface_exists is raised. This creates a new color wp_color_representation_surface_v1 object for the given wl_surface. See the wp_color_representation_surface_v1 interface for more details. | |
| 145 | - | func (o *WpColorRepresentationManager) GetSurface(surface *cross_wl_surface.Surface) (*WpColorRepresentationSurface, error) { | |
| 146 | - | var arg1 wl.Object | |
| 147 | - | if surface != nil { | |
| 148 | - | arg1 = surface | |
| 149 | - | } | |
| 150 | - | child := &WpColorRepresentationSurface{} | |
| 151 | - | child.SetContext(o.Context()) | |
| 152 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "wp_color_representation_manager_v1.get_surface", Child: child}, wl.ArgObject(child), wl.ArgObject(arg1)); err != nil { | |
| 153 | - | return nil, err | |
| 154 | - | } | |
| 155 | - | return child, nil | |
| 156 | - | } | |
| 157 | - | ||
| 158 | - | // OnSupportedAlphaMode registers a handler for the supported_alpha_mode event. | |
| 159 | - | // | |
| 160 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 161 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 162 | - | func (o *WpColorRepresentationManager) OnSupportedAlphaMode(handler func(alphaMode uint32)) { | |
| 163 | - | if handler == nil { | |
| 164 | - | return | |
| 165 | - | } | |
| 166 | - | o.handlersMu.Lock() | |
| 167 | - | defer o.handlersMu.Unlock() | |
| 168 | - | o.onSupportedAlphaMode = append(o.onSupportedAlphaMode, handler) | |
| 169 | - | } | |
| 170 | - | ||
| 171 | - | // handlersForSupportedAlphaMode returns the handlers registered for supported_alpha_mode, taken | |
| 172 | - | // under the lock so a handler may register another handler while events are | |
| 173 | - | // being dispatched. | |
| 174 | - | func (o *WpColorRepresentationManager) handlersForSupportedAlphaMode() []func(alphaMode uint32) { | |
| 175 | - | o.handlersMu.Lock() | |
| 176 | - | defer o.handlersMu.Unlock() | |
| 177 | - | return o.onSupportedAlphaMode | |
| 178 | - | } | |
| 179 | - | ||
| 180 | - | // OnSupportedCoefficientsAndRanges registers a handler for the supported_coefficients_and_ranges event. | |
| 181 | - | // | |
| 182 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 183 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 184 | - | func (o *WpColorRepresentationManager) OnSupportedCoefficientsAndRanges(handler func(coefficients uint32, rangeArg uint32)) { | |
| 185 | - | if handler == nil { | |
| 186 | - | return | |
| 187 | - | } | |
| 188 | - | o.handlersMu.Lock() | |
| 189 | - | defer o.handlersMu.Unlock() | |
| 190 | - | o.onSupportedCoefficientsAndRanges = append(o.onSupportedCoefficientsAndRanges, handler) | |
| 191 | - | } | |
| 192 | - | ||
| 193 | - | // handlersForSupportedCoefficientsAndRanges returns the handlers registered for supported_coefficients_and_ranges, taken | |
| 194 | - | // under the lock so a handler may register another handler while events are | |
| 195 | - | // being dispatched. | |
| 196 | - | func (o *WpColorRepresentationManager) handlersForSupportedCoefficientsAndRanges() []func(coefficients uint32, rangeArg uint32) { | |
| 197 | - | o.handlersMu.Lock() | |
| 198 | - | defer o.handlersMu.Unlock() | |
| 199 | - | return o.onSupportedCoefficientsAndRanges | |
| 200 | - | } | |
| 201 | - | ||
| 202 | - | // OnDone registers a handler for the done event. | |
| 203 | - | // | |
| 204 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 205 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 206 | - | func (o *WpColorRepresentationManager) OnDone(handler func()) { | |
| 207 | - | if handler == nil { | |
| 208 | - | return | |
| 209 | - | } | |
| 210 | - | o.handlersMu.Lock() | |
| 211 | - | defer o.handlersMu.Unlock() | |
| 212 | - | o.onDone = append(o.onDone, handler) | |
| 213 | - | } | |
| 214 | - | ||
| 215 | - | // handlersForDone returns the handlers registered for done, taken | |
| 216 | - | // under the lock so a handler may register another handler while events are | |
| 217 | - | // being dispatched. | |
| 218 | - | func (o *WpColorRepresentationManager) handlersForDone() []func() { | |
| 219 | - | o.handlersMu.Lock() | |
| 220 | - | defer o.handlersMu.Unlock() | |
| 221 | - | return o.onDone | |
| 222 | - | } | |
| 223 | - | ||
| 224 | - | // EventSignature returns the declared event argument types in wire order. | |
| 225 | - | func (o *WpColorRepresentationManager) EventSignature(opcode uint16) (string, bool) { | |
| 226 | - | switch opcode { | |
| 227 | - | case 0: | |
| 228 | - | return "uint,", true | |
| 229 | - | case 1: | |
| 230 | - | return "uint,uint,", true | |
| 231 | - | case 2: | |
| 232 | - | return "", true | |
| 233 | - | default: | |
| 234 | - | return "", false | |
| 235 | - | } | |
| 236 | - | } | |
| 237 | - | ||
| 238 | - | // Dispatch decodes one event on wp_color_representation_manager_v1 and calls the registered handlers. | |
| 239 | - | func (o *WpColorRepresentationManager) Dispatch(event *wl.Event) { | |
| 240 | - | switch event.Opcode { | |
| 241 | - | case 0: // supported_alpha_mode | |
| 242 | - | alphaMode := event.Uint32() | |
| 243 | - | ||
| 244 | - | for i, handler := range o.handlersForSupportedAlphaMode() { | |
| 245 | - | _ = i | |
| 246 | - | handler(alphaMode) | |
| 247 | - | } | |
| 248 | - | case 1: // supported_coefficients_and_ranges | |
| 249 | - | coefficients := event.Uint32() | |
| 250 | - | rangeArg := event.Uint32() | |
| 251 | - | ||
| 252 | - | for i, handler := range o.handlersForSupportedCoefficientsAndRanges() { | |
| 253 | - | _ = i | |
| 254 | - | handler(coefficients, rangeArg) | |
| 255 | - | } | |
| 256 | - | case 2: // done | |
| 257 | - | ||
| 258 | - | for i, handler := range o.handlersForDone() { | |
| 259 | - | _ = i | |
| 260 | - | handler() | |
| 261 | - | } | |
| 262 | - | default: | |
| 263 | - | } | |
| 264 | - | } | |
| 265 | - | ||
| 266 | - | // WpColorRepresentationSurfaceInterface is the protocol interface name. | |
| 267 | - | const WpColorRepresentationSurfaceInterface = "wp_color_representation_surface_v1" | |
| 268 | - | ||
| 269 | - | // WpColorRepresentationSurface is the generated binding for wp_color_representation_surface_v1 version 1. | |
| 270 | - | type WpColorRepresentationSurface struct { | |
| 271 | - | wl.BaseProxy | |
| 272 | - | } | |
| 273 | - | ||
| 274 | - | // NewWpColorRepresentationSurface returns an unbound WpColorRepresentationSurface. | |
| 275 | - | func NewWpColorRepresentationSurface(ctx *wl.Context) *WpColorRepresentationSurface { | |
| 276 | - | obj := &WpColorRepresentationSurface{} | |
| 277 | - | obj.SetContext(ctx) | |
| 278 | - | ctx.Register(obj) | |
| 279 | - | return obj | |
| 280 | - | } | |
| 281 | - | ||
| 282 | - | // Destroy the wp_color_representation_surface_v1 object. Destroying this object unsets all the color representation metadata from the surface. See the wp_color_representation_surface_v1 interface description for how a compositor handles a surface without color representation metadata. Unsetting is double-buffered state, see wl_surface.commit. | |
| 283 | - | func (o *WpColorRepresentationSurface) Destroy() error { | |
| 284 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "wp_color_representation_surface_v1.destroy", Destructor: true}); err != nil { | |
| 285 | - | return err | |
| 286 | - | } | |
| 287 | - | return nil | |
| 288 | - | } | |
| 289 | - | ||
| 290 | - | // If this protocol object is inert, the protocol error inert is raised. Assuming an alpha channel exists, it is always linear. The alpha mode determines whether and how the color channels include pre-multiplied alpha. Using straight alpha might have performance benefits. Only alpha modes advertised by the compositor are allowed to be used as argument for this request. The "alpha_mode" protocol error is raised otherwise. Alpha mode is double buffered, see wl_surface.commit. | |
| 291 | - | func (o *WpColorRepresentationSurface) SetAlphaMode(alphaMode uint32) error { | |
| 292 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "wp_color_representation_surface_v1.set_alpha_mode"}, wl.ArgUint(alphaMode)); err != nil { | |
| 293 | - | return err | |
| 294 | - | } | |
| 295 | - | return nil | |
| 296 | - | } | |
| 297 | - | ||
| 298 | - | // If this protocol object is inert, the protocol error inert is raised. Set the matrix coefficients and video range which defines the formula and the related constants used to derive red, green and blue signals. Usually coefficients correspond to MatrixCoefficients code points in H.273. Only combinations advertised by the compositor are allowed to be used as argument for this request. The "coefficients" protocol error is raised otherwise. A call to wl_surface.commit verifies that the pixel format and the coefficients-range combination in the committed surface contents are compatible, if contents exist. The "pixel_format" protocol error is raised otherwise. A pixel format is compatible with the coefficients-range combination if the related equations and conventions as defined in H.273 can produce the color channels (RGB or YCbCr) of the pixel format. For the definition of the supported combination, see the wp_color_representation_surface_v1::coefficients and wp_color_representation_surface_v1::range enums. The coefficients-range combination is double-buffered, see wl_surface.commit. | |
| 299 | - | func (o *WpColorRepresentationSurface) SetCoefficientsAndRange(coefficients uint32, rangeArg uint32) error { | |
| 300 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 2, Name: "wp_color_representation_surface_v1.set_coefficients_and_range"}, wl.ArgUint(coefficients), wl.ArgUint(rangeArg)); err != nil { | |
| 301 | - | return err | |
| 302 | - | } | |
| 303 | - | return nil | |
| 304 | - | } | |
| 305 | - | ||
| 306 | - | // If this protocol object is inert, the protocol error inert is raised. Set the chroma location type which defines the position of downsampled chroma samples, corresponding to Chroma420SampleLocType code points in H.273. An invalid chroma location enum value raises the "chroma_location" protocol error. A call to wl_surface.commit verifies that the pixel format and chroma location type in the committed surface contents are compatible, if contents exist. The "pixel_format" protocol error is raised otherwise. For the definition of the supported chroma location types, see the wp_color_representation_surface_v1::chroma_location enum. The chroma location type is double-buffered, see wl_surface.commit. | |
| 307 | - | func (o *WpColorRepresentationSurface) SetChromaLocation(chromaLocation uint32) error { | |
| 308 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 3, Name: "wp_color_representation_surface_v1.set_chroma_location"}, wl.ArgUint(chromaLocation)); err != nil { | |
| 309 | - | return err | |
| 310 | - | } | |
| 311 | - | return nil | |
| 312 | - | } | |
| 313 | - | ||
| 314 | - | // EventSignature returns the declared event argument types in wire order. | |
| 315 | - | func (o *WpColorRepresentationSurface) EventSignature(opcode uint16) (string, bool) { | |
| 316 | - | switch opcode { | |
| 317 | - | default: | |
| 318 | - | return "", false | |
| 319 | - | } | |
| 320 | - | } | |
| 321 | - | ||
| 322 | - | // Dispatch decodes one event on wp_color_representation_surface_v1 and calls the registered handlers. | |
| 323 | - | func (o *WpColorRepresentationSurface) Dispatch(event *wl.Event) { | |
| 324 | - | switch event.Opcode { | |
| 325 | - | default: | |
| 326 | - | } | |
| 327 | - | } | |
D protocol/colorrepresentation/generate.go +0 -3
| @@ -1,3 +0,0 @@ | |||
| 1 | - | package colorrepresentation | |
| 2 | - | ||
| 3 | - | //go:generate go run ../../cmd/wlturbo-scanner -p colorrepresentation -o color-representation-v1_generated.go -import wl_surface=github.com/bnema/wlturbo/protocol/core color-representation-v1.xml | |
D protocol/committiming/commit-timing-v1.xml +0 -124
| @@ -1,124 +0,0 @@ | |||
| 1 | - | <?xml version="1.0" encoding="UTF-8"?> | |
| 2 | - | <protocol name="commit_timing_v1"> | |
| 3 | - | ||
| 4 | - | <copyright> | |
| 5 | - | Copyright © 2023 Valve Corporation | |
| 6 | - | ||
| 7 | - | Permission is hereby granted, free of charge, to any person obtaining a | |
| 8 | - | copy of this software and associated documentation files (the "Software"), | |
| 9 | - | to deal in the Software without restriction, including without limitation | |
| 10 | - | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 11 | - | and/or sell copies of the Software, and to permit persons to whom the | |
| 12 | - | Software is furnished to do so, subject to the following conditions: | |
| 13 | - | ||
| 14 | - | The above copyright notice and this permission notice (including the next | |
| 15 | - | paragraph) shall be included in all copies or substantial portions of the | |
| 16 | - | Software. | |
| 17 | - | ||
| 18 | - | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 19 | - | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 20 | - | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 21 | - | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 22 | - | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 23 | - | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
| 24 | - | DEALINGS IN THE SOFTWARE. | |
| 25 | - | </copyright> | |
| 26 | - | ||
| 27 | - | <interface name="wp_commit_timing_manager_v1" version="1"> | |
| 28 | - | <description summary="commit timing"> | |
| 29 | - | When a compositor latches on to new content updates it will check for | |
| 30 | - | any number of requirements of the available content updates (such as | |
| 31 | - | fences of all buffers being signalled) to consider the update ready. | |
| 32 | - | ||
| 33 | - | This protocol provides a method for adding a time constraint to surface | |
| 34 | - | content. This constraint indicates to the compositor that a content | |
| 35 | - | update should be presented as closely as possible to, but not before, | |
| 36 | - | a specified time. | |
| 37 | - | ||
| 38 | - | This protocol does not change the Wayland property that content | |
| 39 | - | updates are applied in the order they are received, even when some | |
| 40 | - | content updates contain timestamps and others do not. | |
| 41 | - | ||
| 42 | - | To provide timestamps, this global factory interface must be used to | |
| 43 | - | acquire a wp_commit_timing_v1 object for a surface, which may then be | |
| 44 | - | used to provide timestamp information for commits. | |
| 45 | - | ||
| 46 | - | Warning! The protocol described in this file is currently in the testing | |
| 47 | - | phase. Backward compatible changes may be added together with the | |
| 48 | - | corresponding interface version bump. Backward incompatible changes can | |
| 49 | - | only be done by creating a new major version of the extension. | |
| 50 | - | </description> | |
| 51 | - | <enum name="error"> | |
| 52 | - | <entry name="commit_timer_exists" value="0" | |
| 53 | - | summary="commit timer already exists for surface"/> | |
| 54 | - | </enum> | |
| 55 | - | ||
| 56 | - | <request name="destroy" type="destructor"> | |
| 57 | - | <description summary="unbind from the commit timing interface"> | |
| 58 | - | Informs the server that the client will no longer be using | |
| 59 | - | this protocol object. Existing objects created by this object | |
| 60 | - | are not affected. | |
| 61 | - | </description> | |
| 62 | - | </request> | |
| 63 | - | ||
| 64 | - | <request name="get_timer"> | |
| 65 | - | <description summary="request commit timer interface for surface"> | |
| 66 | - | Establish a timing controller for a surface. | |
| 67 | - | ||
| 68 | - | Only one commit timer can be created for a surface, or a | |
| 69 | - | commit_timer_exists protocol error will be generated. | |
| 70 | - | </description> | |
| 71 | - | <arg name="id" type="new_id" interface="wp_commit_timer_v1"/> | |
| 72 | - | <arg name="surface" type="object" interface="wl_surface"/> | |
| 73 | - | </request> | |
| 74 | - | </interface> | |
| 75 | - | ||
| 76 | - | <interface name="wp_commit_timer_v1" version="1"> | |
| 77 | - | <description summary="Surface commit timer"> | |
| 78 | - | An object to set a time constraint for a content update on a surface. | |
| 79 | - | </description> | |
| 80 | - | ||
| 81 | - | <enum name="error"> | |
| 82 | - | <entry name="invalid_timestamp" value="0" | |
| 83 | - | summary="timestamp contains an invalid value"/> | |
| 84 | - | <entry name="timestamp_exists" value="1" | |
| 85 | - | summary="timestamp exists"/> | |
| 86 | - | <entry name="surface_destroyed" value="2" | |
| 87 | - | summary="the associated surface no longer exists"/> | |
| 88 | - | </enum> | |
| 89 | - | ||
| 90 | - | <request name="set_timestamp"> | |
| 91 | - | <description summary="Specify time the following commit takes effect"> | |
| 92 | - | Provide a timing constraint for a surface content update. | |
| 93 | - | ||
| 94 | - | A set_timestamp request may be made before a wl_surface.commit to | |
| 95 | - | tell the compositor that the content is intended to be presented | |
| 96 | - | as closely as possible to, but not before, the specified time. | |
| 97 | - | The time is in the domain of the compositor's presentation clock. | |
| 98 | - | ||
| 99 | - | An invalid_timestamp error will be generated for invalid tv_nsec. | |
| 100 | - | ||
| 101 | - | If a timestamp already exists on the surface, a timestamp_exists | |
| 102 | - | error is generated. | |
| 103 | - | ||
| 104 | - | Requesting set_timestamp after the commit_timer object's surface is | |
| 105 | - | destroyed will generate a "surface_destroyed" error. | |
| 106 | - | </description> | |
| 107 | - | <arg name="tv_sec_hi" type="uint" | |
| 108 | - | summary="high 32 bits of the seconds part of target time"/> | |
| 109 | - | <arg name="tv_sec_lo" type="uint" | |
| 110 | - | summary="low 32 bits of the seconds part of target time"/> | |
| 111 | - | <arg name="tv_nsec" type="uint" | |
| 112 | - | summary="nanoseconds part of target time"/> | |
| 113 | - | </request> | |
| 114 | - | ||
| 115 | - | <request name="destroy" type="destructor"> | |
| 116 | - | <description summary="Destroy the timer"> | |
| 117 | - | Informs the server that the client will no longer be using | |
| 118 | - | this protocol object. | |
| 119 | - | ||
| 120 | - | Existing timing constraints are not affected by the destruction. | |
| 121 | - | </description> | |
| 122 | - | </request> | |
| 123 | - | </interface> | |
| 124 | - | </protocol> | |
D protocol/committiming/commit-timing-v1_generated.go +0 -144
| @@ -1,144 +0,0 @@ | |||
| 1 | - | // Code generated by wlturbo-scanner. DO NOT EDIT. | |
| 2 | - | // Protocol: commit_timing_v1 | |
| 3 | - | // Source: commit-timing-v1.xml | |
| 4 | - | ||
| 5 | - | // Upstream protocol copyright and license: | |
| 6 | - | // Copyright © 2023 Valve Corporation | |
| 7 | - | // | |
| 8 | - | // Permission is hereby granted, free of charge, to any person obtaining a | |
| 9 | - | // copy of this software and associated documentation files (the "Software"), | |
| 10 | - | // to deal in the Software without restriction, including without limitation | |
| 11 | - | // the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 12 | - | // and/or sell copies of the Software, and to permit persons to whom the | |
| 13 | - | // Software is furnished to do so, subject to the following conditions: | |
| 14 | - | // | |
| 15 | - | // The above copyright notice and this permission notice (including the next | |
| 16 | - | // paragraph) shall be included in all copies or substantial portions of the | |
| 17 | - | // Software. | |
| 18 | - | // | |
| 19 | - | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 20 | - | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 21 | - | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 22 | - | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 23 | - | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 24 | - | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
| 25 | - | // DEALINGS IN THE SOFTWARE. | |
| 26 | - | ||
| 27 | - | package committiming | |
| 28 | - | ||
| 29 | - | import ( | |
| 30 | - | cross_wl_surface "github.com/bnema/wlturbo/protocol/core" | |
| 31 | - | "github.com/bnema/wlturbo/wl" | |
| 32 | - | ) | |
| 33 | - | ||
| 34 | - | // ERROR_COMMIT_TIMER_EXISTS is the error commit_timer_exists value. | |
| 35 | - | const ERROR_COMMIT_TIMER_EXISTS = 0 | |
| 36 | - | ||
| 37 | - | // ERROR_INVALID_TIMESTAMP is the error invalid_timestamp value. | |
| 38 | - | const ERROR_INVALID_TIMESTAMP = 0 | |
| 39 | - | ||
| 40 | - | // ERROR_TIMESTAMP_EXISTS is the error timestamp_exists value. | |
| 41 | - | const ERROR_TIMESTAMP_EXISTS = 1 | |
| 42 | - | ||
| 43 | - | // ERROR_SURFACE_DESTROYED is the error surface_destroyed value. | |
| 44 | - | const ERROR_SURFACE_DESTROYED = 2 | |
| 45 | - | ||
| 46 | - | // WpCommitTimingManagerInterface is the protocol interface name. | |
| 47 | - | const WpCommitTimingManagerInterface = "wp_commit_timing_manager_v1" | |
| 48 | - | ||
| 49 | - | // WpCommitTimingManager is the generated binding for wp_commit_timing_manager_v1 version 1. | |
| 50 | - | type WpCommitTimingManager struct { | |
| 51 | - | wl.BaseProxy | |
| 52 | - | } | |
| 53 | - | ||
| 54 | - | // NewWpCommitTimingManager returns an unbound WpCommitTimingManager. | |
| 55 | - | func NewWpCommitTimingManager(ctx *wl.Context) *WpCommitTimingManager { | |
| 56 | - | obj := &WpCommitTimingManager{} | |
| 57 | - | obj.SetContext(ctx) | |
| 58 | - | ctx.Register(obj) | |
| 59 | - | return obj | |
| 60 | - | } | |
| 61 | - | ||
| 62 | - | // Informs the server that the client will no longer be using this protocol object. Existing objects created by this object are not affected. | |
| 63 | - | func (o *WpCommitTimingManager) Destroy() error { | |
| 64 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "wp_commit_timing_manager_v1.destroy", Destructor: true}); err != nil { | |
| 65 | - | return err | |
| 66 | - | } | |
| 67 | - | return nil | |
| 68 | - | } | |
| 69 | - | ||
| 70 | - | // Establish a timing controller for a surface. Only one commit timer can be created for a surface, or a commit_timer_exists protocol error will be generated. | |
| 71 | - | func (o *WpCommitTimingManager) GetTimer(surface *cross_wl_surface.Surface) (*WpCommitTimer, error) { | |
| 72 | - | var arg1 wl.Object | |
| 73 | - | if surface != nil { | |
| 74 | - | arg1 = surface | |
| 75 | - | } | |
| 76 | - | child := &WpCommitTimer{} | |
| 77 | - | child.SetContext(o.Context()) | |
| 78 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "wp_commit_timing_manager_v1.get_timer", Child: child}, wl.ArgObject(child), wl.ArgObject(arg1)); err != nil { | |
| 79 | - | return nil, err | |
| 80 | - | } | |
| 81 | - | return child, nil | |
| 82 | - | } | |
| 83 | - | ||
| 84 | - | // EventSignature returns the declared event argument types in wire order. | |
| 85 | - | func (o *WpCommitTimingManager) EventSignature(opcode uint16) (string, bool) { | |
| 86 | - | switch opcode { | |
| 87 | - | default: | |
| 88 | - | return "", false | |
| 89 | - | } | |
| 90 | - | } | |
| 91 | - | ||
| 92 | - | // Dispatch decodes one event on wp_commit_timing_manager_v1 and calls the registered handlers. | |
| 93 | - | func (o *WpCommitTimingManager) Dispatch(event *wl.Event) { | |
| 94 | - | switch event.Opcode { | |
| 95 | - | default: | |
| 96 | - | } | |
| 97 | - | } | |
| 98 | - | ||
| 99 | - | // WpCommitTimerInterface is the protocol interface name. | |
| 100 | - | const WpCommitTimerInterface = "wp_commit_timer_v1" | |
| 101 | - | ||
| 102 | - | // WpCommitTimer is the generated binding for wp_commit_timer_v1 version 1. | |
| 103 | - | type WpCommitTimer struct { | |
| 104 | - | wl.BaseProxy | |
| 105 | - | } | |
| 106 | - | ||
| 107 | - | // NewWpCommitTimer returns an unbound WpCommitTimer. | |
| 108 | - | func NewWpCommitTimer(ctx *wl.Context) *WpCommitTimer { | |
| 109 | - | obj := &WpCommitTimer{} | |
| 110 | - | obj.SetContext(ctx) | |
| 111 | - | ctx.Register(obj) | |
| 112 | - | return obj | |
| 113 | - | } | |
| 114 | - | ||
| 115 | - | // Provide a timing constraint for a surface content update. A set_timestamp request may be made before a wl_surface.commit to tell the compositor that the content is intended to be presented as closely as possible to, but not before, the specified time. The time is in the domain of the compositor's presentation clock. An invalid_timestamp error will be generated for invalid tv_nsec. If a timestamp already exists on the surface, a timestamp_exists error is generated. Requesting set_timestamp after the commit_timer object's surface is destroyed will generate a "surface_destroyed" error. | |
| 116 | - | func (o *WpCommitTimer) SetTimestamp(tvSecHi uint32, tvSecLo uint32, tvNsec uint32) error { | |
| 117 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "wp_commit_timer_v1.set_timestamp"}, wl.ArgUint(tvSecHi), wl.ArgUint(tvSecLo), wl.ArgUint(tvNsec)); err != nil { | |
| 118 | - | return err | |
| 119 | - | } | |
| 120 | - | return nil | |
| 121 | - | } | |
| 122 | - | ||
| 123 | - | // Informs the server that the client will no longer be using this protocol object. Existing timing constraints are not affected by the destruction. | |
| 124 | - | func (o *WpCommitTimer) Destroy() error { | |
| 125 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "wp_commit_timer_v1.destroy", Destructor: true}); err != nil { | |
| 126 | - | return err | |
| 127 | - | } | |
| 128 | - | return nil | |
| 129 | - | } | |
| 130 | - | ||
| 131 | - | // EventSignature returns the declared event argument types in wire order. | |
| 132 | - | func (o *WpCommitTimer) EventSignature(opcode uint16) (string, bool) { | |
| 133 | - | switch opcode { | |
| 134 | - | default: | |
| 135 | - | return "", false | |
| 136 | - | } | |
| 137 | - | } | |
| 138 | - | ||
| 139 | - | // Dispatch decodes one event on wp_commit_timer_v1 and calls the registered handlers. | |
| 140 | - | func (o *WpCommitTimer) Dispatch(event *wl.Event) { | |
| 141 | - | switch event.Opcode { | |
| 142 | - | default: | |
| 143 | - | } | |
| 144 | - | } | |
D protocol/committiming/generate.go +0 -3
| @@ -1,3 +0,0 @@ | |||
| 1 | - | package committiming | |
| 2 | - | ||
| 3 | - | //go:generate go run ../../cmd/wlturbo-scanner -p committiming -o commit-timing-v1_generated.go -import wl_surface=github.com/bnema/wlturbo/protocol/core commit-timing-v1.xml | |
D protocol/contenttype/content-type-v1.xml +0 -128
| @@ -1,128 +0,0 @@ | |||
| 1 | - | <?xml version="1.0" encoding="UTF-8"?> | |
| 2 | - | <protocol name="content_type_v1"> | |
| 3 | - | <copyright> | |
| 4 | - | Copyright © 2021 Emmanuel Gil Peyrot | |
| 5 | - | Copyright © 2022 Xaver Hugl | |
| 6 | - | ||
| 7 | - | Permission is hereby granted, free of charge, to any person obtaining a | |
| 8 | - | copy of this software and associated documentation files (the "Software"), | |
| 9 | - | to deal in the Software without restriction, including without limitation | |
| 10 | - | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 11 | - | and/or sell copies of the Software, and to permit persons to whom the | |
| 12 | - | Software is furnished to do so, subject to the following conditions: | |
| 13 | - | ||
| 14 | - | The above copyright notice and this permission notice (including the next | |
| 15 | - | paragraph) shall be included in all copies or substantial portions of the | |
| 16 | - | Software. | |
| 17 | - | ||
| 18 | - | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 19 | - | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 20 | - | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 21 | - | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 22 | - | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 23 | - | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
| 24 | - | DEALINGS IN THE SOFTWARE. | |
| 25 | - | </copyright> | |
| 26 | - | ||
| 27 | - | <interface name="wp_content_type_manager_v1" version="1"> | |
| 28 | - | <description summary="surface content type manager"> | |
| 29 | - | This interface allows a client to describe the kind of content a surface | |
| 30 | - | will display, to allow the compositor to optimize its behavior for it. | |
| 31 | - | ||
| 32 | - | Warning! The protocol described in this file is currently in the testing | |
| 33 | - | phase. Backward compatible changes may be added together with the | |
| 34 | - | corresponding interface version bump. Backward incompatible changes can | |
| 35 | - | only be done by creating a new major version of the extension. | |
| 36 | - | </description> | |
| 37 | - | ||
| 38 | - | <request name="destroy" type="destructor"> | |
| 39 | - | <description summary="destroy the content type manager object"> | |
| 40 | - | Destroy the content type manager. This doesn't destroy objects created | |
| 41 | - | with the manager. | |
| 42 | - | </description> | |
| 43 | - | </request> | |
| 44 | - | ||
| 45 | - | <enum name="error"> | |
| 46 | - | <entry name="already_constructed" value="0" | |
| 47 | - | summary="wl_surface already has a content type object"/> | |
| 48 | - | </enum> | |
| 49 | - | ||
| 50 | - | <request name="get_surface_content_type"> | |
| 51 | - | <description summary="create a new content type object"> | |
| 52 | - | Create a new content type object associated with the given surface. | |
| 53 | - | ||
| 54 | - | Creating a wp_content_type_v1 from a wl_surface which already has one | |
| 55 | - | attached is a client error: already_constructed. | |
| 56 | - | </description> | |
| 57 | - | <arg name="id" type="new_id" interface="wp_content_type_v1"/> | |
| 58 | - | <arg name="surface" type="object" interface="wl_surface"/> | |
| 59 | - | </request> | |
| 60 | - | </interface> | |
| 61 | - | ||
| 62 | - | <interface name="wp_content_type_v1" version="1"> | |
| 63 | - | <description summary="content type object for a surface"> | |
| 64 | - | The content type object allows the compositor to optimize for the kind | |
| 65 | - | of content shown on the surface. A compositor may for example use it to | |
| 66 | - | set relevant drm properties like "content type". | |
| 67 | - | ||
| 68 | - | The client may request to switch to another content type at any time. | |
| 69 | - | When the associated surface gets destroyed, this object becomes inert and | |
| 70 | - | the client should destroy it. | |
| 71 | - | </description> | |
| 72 | - | ||
| 73 | - | <request name="destroy" type="destructor"> | |
| 74 | - | <description summary="destroy the content type object"> | |
| 75 | - | Switch back to not specifying the content type of this surface. This is | |
| 76 | - | equivalent to setting the content type to none, including double | |
| 77 | - | buffering semantics. See set_content_type for details. | |
| 78 | - | </description> | |
| 79 | - | </request> | |
| 80 | - | ||
| 81 | - | <enum name="type"> | |
| 82 | - | <description summary="possible content types"> | |
| 83 | - | These values describe the available content types for a surface. | |
| 84 | - | </description> | |
| 85 | - | <entry name="none" value="0"> | |
| 86 | - | <description summary="no content type applies"> | |
| 87 | - | The content type none means that either the application has no data | |
| 88 | - | about the content type, or that the content doesn't fit into one of | |
| 89 | - | the other categories. | |
| 90 | - | </description> | |
| 91 | - | </entry> | |
| 92 | - | <entry name="photo" value="1"> | |
| 93 | - | <description summary="photo content type"> | |
| 94 | - | The content type photo describes content derived from digital still | |
| 95 | - | pictures and may be presented with minimal processing. | |
| 96 | - | </description> | |
| 97 | - | </entry> | |
| 98 | - | <entry name="video" value="2"> | |
| 99 | - | <description summary="video content type"> | |
| 100 | - | The content type video describes a video or animation and may be | |
| 101 | - | presented with more accurate timing to avoid stutter. Where scaling | |
| 102 | - | is needed, scaling methods more appropriate for video may be used. | |
| 103 | - | </description> | |
| 104 | - | </entry> | |
| 105 | - | <entry name="game" value="3"> | |
| 106 | - | <description summary="game content type"> | |
| 107 | - | The content type game describes a running game. Its content may be | |
| 108 | - | presented with reduced latency. | |
| 109 | - | </description> | |
| 110 | - | </entry> | |
| 111 | - | </enum> | |
| 112 | - | ||
| 113 | - | <request name="set_content_type"> | |
| 114 | - | <description summary="specify the content type"> | |
| 115 | - | Set the surface content type. This informs the compositor that the | |
| 116 | - | client believes it is displaying buffers matching this content type. | |
| 117 | - | ||
| 118 | - | This is purely a hint for the compositor, which can be used to adjust | |
| 119 | - | its behavior or hardware settings to fit the presented content best. | |
| 120 | - | ||
| 121 | - | The content type is double-buffered state, see wl_surface.commit for | |
| 122 | - | details. | |
| 123 | - | </description> | |
| 124 | - | <arg name="content_type" type="uint" enum="type" | |
| 125 | - | summary="the content type"/> | |
| 126 | - | </request> | |
| 127 | - | </interface> | |
| 128 | - | </protocol> | |
D protocol/contenttype/content-type-v1_generated.go +0 -148
| @@ -1,148 +0,0 @@ | |||
| 1 | - | // Code generated by wlturbo-scanner. DO NOT EDIT. | |
| 2 | - | // Protocol: content_type_v1 | |
| 3 | - | // Source: content-type-v1.xml | |
| 4 | - | ||
| 5 | - | // Upstream protocol copyright and license: | |
| 6 | - | // Copyright © 2021 Emmanuel Gil Peyrot | |
| 7 | - | // Copyright © 2022 Xaver Hugl | |
| 8 | - | // | |
| 9 | - | // Permission is hereby granted, free of charge, to any person obtaining a | |
| 10 | - | // copy of this software and associated documentation files (the "Software"), | |
| 11 | - | // to deal in the Software without restriction, including without limitation | |
| 12 | - | // the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 13 | - | // and/or sell copies of the Software, and to permit persons to whom the | |
| 14 | - | // Software is furnished to do so, subject to the following conditions: | |
| 15 | - | // | |
| 16 | - | // The above copyright notice and this permission notice (including the next | |
| 17 | - | // paragraph) shall be included in all copies or substantial portions of the | |
| 18 | - | // Software. | |
| 19 | - | // | |
| 20 | - | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 21 | - | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 22 | - | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 23 | - | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 24 | - | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 25 | - | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
| 26 | - | // DEALINGS IN THE SOFTWARE. | |
| 27 | - | ||
| 28 | - | package contenttype | |
| 29 | - | ||
| 30 | - | import ( | |
| 31 | - | cross_wl_surface "github.com/bnema/wlturbo/protocol/core" | |
| 32 | - | "github.com/bnema/wlturbo/wl" | |
| 33 | - | ) | |
| 34 | - | ||
| 35 | - | // ERROR_ALREADY_CONSTRUCTED is the error already_constructed value. | |
| 36 | - | const ERROR_ALREADY_CONSTRUCTED = 0 | |
| 37 | - | ||
| 38 | - | // TYPE_NONE is the type none value. | |
| 39 | - | const TYPE_NONE = 0 | |
| 40 | - | ||
| 41 | - | // TYPE_PHOTO is the type photo value. | |
| 42 | - | const TYPE_PHOTO = 1 | |
| 43 | - | ||
| 44 | - | // TYPE_VIDEO is the type video value. | |
| 45 | - | const TYPE_VIDEO = 2 | |
| 46 | - | ||
| 47 | - | // TYPE_GAME is the type game value. | |
| 48 | - | const TYPE_GAME = 3 | |
| 49 | - | ||
| 50 | - | // WpContentTypeManagerInterface is the protocol interface name. | |
| 51 | - | const WpContentTypeManagerInterface = "wp_content_type_manager_v1" | |
| 52 | - | ||
| 53 | - | // WpContentTypeManager is the generated binding for wp_content_type_manager_v1 version 1. | |
| 54 | - | type WpContentTypeManager struct { | |
| 55 | - | wl.BaseProxy | |
| 56 | - | } | |
| 57 | - | ||
| 58 | - | // NewWpContentTypeManager returns an unbound WpContentTypeManager. | |
| 59 | - | func NewWpContentTypeManager(ctx *wl.Context) *WpContentTypeManager { | |
| 60 | - | obj := &WpContentTypeManager{} | |
| 61 | - | obj.SetContext(ctx) | |
| 62 | - | ctx.Register(obj) | |
| 63 | - | return obj | |
| 64 | - | } | |
| 65 | - | ||
| 66 | - | // Destroy the content type manager. This doesn't destroy objects created with the manager. | |
| 67 | - | func (o *WpContentTypeManager) Destroy() error { | |
| 68 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "wp_content_type_manager_v1.destroy", Destructor: true}); err != nil { | |
| 69 | - | return err | |
| 70 | - | } | |
| 71 | - | return nil | |
| 72 | - | } | |
| 73 | - | ||
| 74 | - | // 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. | |
| 75 | - | func (o *WpContentTypeManager) GetSurfaceContentType(surface *cross_wl_surface.Surface) (*WpContentType, error) { | |
| 76 | - | var arg1 wl.Object | |
| 77 | - | if surface != nil { | |
| 78 | - | arg1 = surface | |
| 79 | - | } | |
| 80 | - | child := &WpContentType{} | |
| 81 | - | child.SetContext(o.Context()) | |
| 82 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "wp_content_type_manager_v1.get_surface_content_type", Child: child}, wl.ArgObject(child), wl.ArgObject(arg1)); err != nil { | |
| 83 | - | return nil, err | |
| 84 | - | } | |
| 85 | - | return child, nil | |
| 86 | - | } | |
| 87 | - | ||
| 88 | - | // EventSignature returns the declared event argument types in wire order. | |
| 89 | - | func (o *WpContentTypeManager) EventSignature(opcode uint16) (string, bool) { | |
| 90 | - | switch opcode { | |
| 91 | - | default: | |
| 92 | - | return "", false | |
| 93 | - | } | |
| 94 | - | } | |
| 95 | - | ||
| 96 | - | // Dispatch decodes one event on wp_content_type_manager_v1 and calls the registered handlers. | |
| 97 | - | func (o *WpContentTypeManager) Dispatch(event *wl.Event) { | |
| 98 | - | switch event.Opcode { | |
| 99 | - | default: | |
| 100 | - | } | |
| 101 | - | } | |
| 102 | - | ||
| 103 | - | // WpContentTypeInterface is the protocol interface name. | |
| 104 | - | const WpContentTypeInterface = "wp_content_type_v1" | |
| 105 | - | ||
| 106 | - | // WpContentType is the generated binding for wp_content_type_v1 version 1. | |
| 107 | - | type WpContentType struct { | |
| 108 | - | wl.BaseProxy | |
| 109 | - | } | |
| 110 | - | ||
| 111 | - | // NewWpContentType returns an unbound WpContentType. | |
| 112 | - | func NewWpContentType(ctx *wl.Context) *WpContentType { | |
| 113 | - | obj := &WpContentType{} | |
| 114 | - | obj.SetContext(ctx) | |
| 115 | - | ctx.Register(obj) | |
| 116 | - | return obj | |
| 117 | - | } | |
| 118 | - | ||
| 119 | - | // 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. | |
| 120 | - | func (o *WpContentType) Destroy() error { | |
| 121 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "wp_content_type_v1.destroy", Destructor: true}); err != nil { | |
| 122 | - | return err | |
| 123 | - | } | |
| 124 | - | return nil | |
| 125 | - | } | |
| 126 | - | ||
| 127 | - | // 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. | |
| 128 | - | func (o *WpContentType) SetContentType(contentType uint32) error { | |
| 129 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "wp_content_type_v1.set_content_type"}, wl.ArgUint(contentType)); err != nil { | |
| 130 | - | return err | |
| 131 | - | } | |
| 132 | - | return nil | |
| 133 | - | } | |
| 134 | - | ||
| 135 | - | // EventSignature returns the declared event argument types in wire order. | |
| 136 | - | func (o *WpContentType) EventSignature(opcode uint16) (string, bool) { | |
| 137 | - | switch opcode { | |
| 138 | - | default: | |
| 139 | - | return "", false | |
| 140 | - | } | |
| 141 | - | } | |
| 142 | - | ||
| 143 | - | // Dispatch decodes one event on wp_content_type_v1 and calls the registered handlers. | |
| 144 | - | func (o *WpContentType) Dispatch(event *wl.Event) { | |
| 145 | - | switch event.Opcode { | |
| 146 | - | default: | |
| 147 | - | } | |
| 148 | - | } | |
D protocol/contenttype/generate.go +0 -3
| @@ -1,3 +0,0 @@ | |||
| 1 | - | package contenttype | |
| 2 | - | ||
| 3 | - | //go:generate go run ../../cmd/wlturbo-scanner -p contenttype -o content-type-v1_generated.go -import wl_surface=github.com/bnema/wlturbo/protocol/core content-type-v1.xml | |
D protocol/core/core_test.go +0 -532
| @@ -1,532 +0,0 @@ | |||
| 1 | - | //go:build linux | |
| 2 | - | ||
| 3 | - | package core_test | |
| 4 | - | ||
| 5 | - | import ( | |
| 6 | - | "encoding/binary" | |
| 7 | - | "errors" | |
| 8 | - | "io" | |
| 9 | - | "net" | |
| 10 | - | "os" | |
| 11 | - | "testing" | |
| 12 | - | "time" | |
| 13 | - | ||
| 14 | - | "github.com/bnema/wlturbo" | |
| 15 | - | "github.com/bnema/wlturbo/protocol/core" | |
| 16 | - | "golang.org/x/sys/unix" | |
| 17 | - | ) | |
| 18 | - | ||
| 19 | - | func pair(t *testing.T) (*net.UnixConn, *net.UnixConn) { | |
| 20 | - | t.Helper() | |
| 21 | - | f, err := unix.Socketpair(unix.AF_UNIX, unix.SOCK_STREAM|unix.SOCK_CLOEXEC, 0) | |
| 22 | - | if err != nil { | |
| 23 | - | t.Fatal(err) | |
| 24 | - | } | |
| 25 | - | a := os.NewFile(uintptr(f[0]), "a") | |
| 26 | - | b := os.NewFile(uintptr(f[1]), "b") | |
| 27 | - | ca, e := net.FileConn(a) | |
| 28 | - | a.Close() | |
| 29 | - | if e != nil { | |
| 30 | - | t.Fatal(e) | |
| 31 | - | } | |
| 32 | - | cb, e := net.FileConn(b) | |
| 33 | - | b.Close() | |
| 34 | - | if e != nil { | |
| 35 | - | t.Fatal(e) | |
| 36 | - | } | |
| 37 | - | t.Cleanup(func() { ca.Close(); cb.Close() }) | |
| 38 | - | return ca.(*net.UnixConn), cb.(*net.UnixConn) | |
| 39 | - | } | |
| 40 | - | func frame(id uint32, op uint16, body ...uint32) []byte { | |
| 41 | - | p := make([]byte, 8+4*len(body)) | |
| 42 | - | binary.LittleEndian.PutUint32(p, id) | |
| 43 | - | binary.LittleEndian.PutUint32(p[4:], uint32(len(p))<<16|uint32(op)) | |
| 44 | - | for i, v := range body { | |
| 45 | - | binary.LittleEndian.PutUint32(p[8+i*4:], v) | |
| 46 | - | } | |
| 47 | - | return p | |
| 48 | - | } | |
| 49 | - | func receiveRequest(t *testing.T, p *net.UnixConn) { | |
| 50 | - | t.Helper() | |
| 51 | - | p.SetReadDeadline(testDeadline()) | |
| 52 | - | b := make([]byte, 256) | |
| 53 | - | if _, e := p.Read(b); e != nil { | |
| 54 | - | t.Fatal(e) | |
| 55 | - | } | |
| 56 | - | } | |
| 57 | - | func testDeadline() (d time.Time) { return time.Now().Add(2 * time.Second) } | |
| 58 | - | func send(t *testing.T, p *net.UnixConn, msg []byte, fd ...int) { | |
| 59 | - | t.Helper() | |
| 60 | - | var oob []byte | |
| 61 | - | if len(fd) > 0 { | |
| 62 | - | oob = unix.UnixRights(fd...) | |
| 63 | - | } | |
| 64 | - | if _, _, e := p.WriteMsgUnix(msg, oob, nil); e != nil { | |
| 65 | - | t.Fatal(e) | |
| 66 | - | } | |
| 67 | - | } | |
| 68 | - | func TestGeneratedCoreOverSocketpair(t *testing.T) { | |
| 69 | - | c, p := pair(t) | |
| 70 | - | d, err := wlturbo.ConnectFromConn(c) | |
| 71 | - | if err != nil { | |
| 72 | - | t.Fatal(err) | |
| 73 | - | } | |
| 74 | - | defer d.Close() | |
| 75 | - | receiveRequest(t, p) // get_registry | |
| 76 | - | seat := core.NewSeat(d.Context()) | |
| 77 | - | if err := d.Registry().Bind(1, core.SeatInterface, 1, seat); err != nil { | |
| 78 | - | t.Fatal(err) | |
| 79 | - | } | |
| 80 | - | receiveRequest(t, p) | |
| 81 | - | kb, err := seat.GetKeyboard() | |
| 82 | - | if err != nil { | |
| 83 | - | t.Fatal(err) | |
| 84 | - | } | |
| 85 | - | receiveRequest(t, p) | |
| 86 | - | var key uint32 | |
| 87 | - | kb.OnKey(func(_, _, k, _ uint32) { key = k }) | |
| 88 | - | send(t, p, frame(kb.ID(), 3, 1, 2, 42, 1)) | |
| 89 | - | if err := d.Dispatch(); err != nil { | |
| 90 | - | t.Fatal(err) | |
| 91 | - | } | |
| 92 | - | if key != 42 { | |
| 93 | - | t.Fatalf("key=%d", key) | |
| 94 | - | } | |
| 95 | - | compositor := core.NewCompositor(d.Context()) | |
| 96 | - | if err := d.Registry().Bind(2, core.CompositorInterface, 1, compositor); err != nil { | |
| 97 | - | t.Fatal(err) | |
| 98 | - | } | |
| 99 | - | receiveRequest(t, p) | |
| 100 | - | surface, err := compositor.CreateSurface() | |
| 101 | - | if err != nil { | |
| 102 | - | t.Fatal(err) | |
| 103 | - | } | |
| 104 | - | receiveRequest(t, p) | |
| 105 | - | callback, err := surface.Frame() | |
| 106 | - | if err != nil { | |
| 107 | - | t.Fatal(err) | |
| 108 | - | } | |
| 109 | - | receiveRequest(t, p) | |
| 110 | - | var done uint32 | |
| 111 | - | callback.OnDone(func(ms uint32) { done = ms }) | |
| 112 | - | send(t, p, frame(callback.ID(), 0, 123)) | |
| 113 | - | if err := d.Dispatch(); err != nil { | |
| 114 | - | t.Fatal(err) | |
| 115 | - | } | |
| 116 | - | if done != 123 { | |
| 117 | - | t.Fatalf("done=%d", done) | |
| 118 | - | } | |
| 119 | - | send(t, p, frame(callback.ID(), 0, 124)) | |
| 120 | - | if err := d.Dispatch(); !errors.Is(err, wlturbo.ErrUnknownObject) { | |
| 121 | - | t.Fatalf("destroyed callback: %v", err) | |
| 122 | - | } | |
| 123 | - | } | |
| 124 | - | func TestKeymapFDNoHandlerAndMultipleHandlers(t *testing.T) { | |
| 125 | - | c, p := pair(t) | |
| 126 | - | d, e := wlturbo.ConnectFromConn(c) | |
| 127 | - | if e != nil { | |
| 128 | - | t.Fatal(e) | |
| 129 | - | } | |
| 130 | - | defer d.Close() | |
| 131 | - | receiveRequest(t, p) | |
| 132 | - | kb := core.NewKeyboard(d.Context()) | |
| 133 | - | kb.SetID(d.AllocateID()) | |
| 134 | - | d.Context().Register(kb) | |
| 135 | - | r, w, e := os.Pipe() | |
| 136 | - | if e != nil { | |
| 137 | - | t.Fatal(e) | |
| 138 | - | } | |
| 139 | - | defer r.Close() | |
| 140 | - | send(t, p, frame(kb.ID(), 0, 1, 8), int(w.Fd())) | |
| 141 | - | w.Close() | |
| 142 | - | if e := d.Dispatch(); e != nil { | |
| 143 | - | t.Fatal(e) | |
| 144 | - | } | |
| 145 | - | buf := make([]byte, 1) | |
| 146 | - | if n, e := r.Read(buf); n != 0 || e != io.EOF { | |
| 147 | - | t.Fatalf("unclaimed FD n=%d err=%v", n, e) | |
| 148 | - | } | |
| 149 | - | r2, w2, e := os.Pipe() | |
| 150 | - | if e != nil { | |
| 151 | - | t.Fatal(e) | |
| 152 | - | } | |
| 153 | - | defer r2.Close() | |
| 154 | - | received := 0 | |
| 155 | - | kb.OnKeymap(func(_ uint32, fd *wlturbo.OwnedFD, _ uint32) { | |
| 156 | - | if fd == nil { | |
| 157 | - | t.Fatal("first FD missing") | |
| 158 | - | } | |
| 159 | - | n, e := fd.Take() | |
| 160 | - | if e != nil { | |
| 161 | - | t.Fatal(e) | |
| 162 | - | } | |
| 163 | - | received++ | |
| 164 | - | unix.Close(n) | |
| 165 | - | }) | |
| 166 | - | kb.OnKeymap(func(_ uint32, fd *wlturbo.OwnedFD, _ uint32) { | |
| 167 | - | if fd != nil { | |
| 168 | - | t.Fatal("duplicated owner") | |
| 169 | - | } | |
| 170 | - | received++ | |
| 171 | - | }) | |
| 172 | - | send(t, p, frame(kb.ID(), 0, 1, 8), int(w2.Fd())) | |
| 173 | - | w2.Close() | |
| 174 | - | if e := d.Dispatch(); e != nil { | |
| 175 | - | t.Fatal(e) | |
| 176 | - | } | |
| 177 | - | if received != 2 { | |
| 178 | - | t.Fatalf("handlers=%d", received) | |
| 179 | - | } | |
| 180 | - | } | |
| 181 | - | func TestBufferReleaseAndOfferChild(t *testing.T) { | |
| 182 | - | c, p := pair(t) | |
| 183 | - | d, e := wlturbo.ConnectFromConn(c) | |
| 184 | - | if e != nil { | |
| 185 | - | t.Fatal(e) | |
| 186 | - | } | |
| 187 | - | defer d.Close() | |
| 188 | - | receiveRequest(t, p) | |
| 189 | - | b := core.NewBuffer(d.Context()) | |
| 190 | - | b.SetID(d.AllocateID()) | |
| 191 | - | d.Context().Register(b) | |
| 192 | - | releases := 0 | |
| 193 | - | b.OnRelease(func() { releases++ }) | |
| 194 | - | send(t, p, frame(b.ID(), 0)) | |
| 195 | - | if e := d.Dispatch(); e != nil { | |
| 196 | - | t.Fatal(e) | |
| 197 | - | } | |
| 198 | - | if releases != 1 { | |
| 199 | - | t.Fatal("release not dispatched") | |
| 200 | - | } | |
| 201 | - | device := core.NewDataDevice(d.Context()) | |
| 202 | - | device.SetID(d.AllocateID()) | |
| 203 | - | d.Context().Register(device) | |
| 204 | - | var offer *core.DataOffer | |
| 205 | - | device.OnDataOffer(func(o *core.DataOffer) { offer = o }) | |
| 206 | - | send(t, p, frame(device.ID(), 0, 0xff000001)) | |
| 207 | - | if e := d.Dispatch(); e != nil { | |
| 208 | - | t.Fatal(e) | |
| 209 | - | } | |
| 210 | - | if offer == nil || offer.ID() != 0xff000001 { | |
| 211 | - | t.Fatalf("offer=%v", offer) | |
| 212 | - | } | |
| 213 | - | } | |
| 214 | - | ||
| 215 | - | func TestMissingKeymapDescriptor(t *testing.T) { | |
| 216 | - | c, p := pair(t) | |
| 217 | - | d, e := wlturbo.ConnectFromConn(c) | |
| 218 | - | if e != nil { | |
| 219 | - | t.Fatal(e) | |
| 220 | - | } | |
| 221 | - | defer d.Close() | |
| 222 | - | receiveRequest(t, p) | |
| 223 | - | kb := core.NewKeyboard(d.Context()) | |
| 224 | - | kb.SetID(d.AllocateID()) | |
| 225 | - | d.Context().Register(kb) | |
| 226 | - | send(t, p, frame(kb.ID(), 0, 1, 8)) | |
| 227 | - | if e := d.Dispatch(); !errors.Is(e, wlturbo.ErrMalformedFrame) { | |
| 228 | - | t.Fatalf("missing FD: %v", e) | |
| 229 | - | } | |
| 230 | - | } | |
| 231 | - | ||
| 232 | - | func TestInterleavedFDAndPlainMessages(t *testing.T) { | |
| 233 | - | c, p := pair(t) | |
| 234 | - | d, e := wlturbo.ConnectFromConn(c) | |
| 235 | - | if e != nil { | |
| 236 | - | t.Fatal(e) | |
| 237 | - | } | |
| 238 | - | defer d.Close() | |
| 239 | - | receiveRequest(t, p) | |
| 240 | - | kb := core.NewKeyboard(d.Context()) | |
| 241 | - | kb.SetID(d.AllocateID()) | |
| 242 | - | d.Context().Register(kb) | |
| 243 | - | calls := 0 | |
| 244 | - | kb.OnKeymap(func(_ uint32, fd *wlturbo.OwnedFD, _ uint32) { | |
| 245 | - | if fd == nil { | |
| 246 | - | t.Fatal("FD not assigned") | |
| 247 | - | } | |
| 248 | - | _ = fd.Close() | |
| 249 | - | calls++ | |
| 250 | - | }) | |
| 251 | - | kb.OnKey(func(_, _, key, _ uint32) { | |
| 252 | - | if key != 33 { | |
| 253 | - | t.Errorf("key=%d", key) | |
| 254 | - | } | |
| 255 | - | calls++ | |
| 256 | - | }) | |
| 257 | - | r, w, e := os.Pipe() | |
| 258 | - | if e != nil { | |
| 259 | - | t.Fatal(e) | |
| 260 | - | } | |
| 261 | - | defer r.Close() | |
| 262 | - | send(t, p, frame(kb.ID(), 0, 1, 8), int(w.Fd())) | |
| 263 | - | w.Close() | |
| 264 | - | send(t, p, frame(kb.ID(), 3, 1, 2, 33, 1)) | |
| 265 | - | if e := d.Dispatch(); e != nil { | |
| 266 | - | t.Fatal(e) | |
| 267 | - | } | |
| 268 | - | if e := d.Dispatch(); e != nil { | |
| 269 | - | t.Fatal(e) | |
| 270 | - | } | |
| 271 | - | if calls != 2 { | |
| 272 | - | t.Fatalf("calls=%d", calls) | |
| 273 | - | } | |
| 274 | - | } | |
| 275 | - | func TestMalformedGeneratedPayload(t *testing.T) { | |
| 276 | - | c, p := pair(t) | |
| 277 | - | d, e := wlturbo.ConnectFromConn(c) | |
| 278 | - | if e != nil { | |
| 279 | - | t.Fatal(e) | |
| 280 | - | } | |
| 281 | - | defer d.Close() | |
| 282 | - | receiveRequest(t, p) | |
| 283 | - | kb := core.NewKeyboard(d.Context()) | |
| 284 | - | kb.SetID(d.AllocateID()) | |
| 285 | - | d.Context().Register(kb) | |
| 286 | - | send(t, p, frame(kb.ID(), 3, 1, 2)) | |
| 287 | - | if e := d.Dispatch(); !errors.Is(e, wlturbo.ErrMalformedFrame) { | |
| 288 | - | t.Fatalf("truncated key: %v", e) | |
| 289 | - | } | |
| 290 | - | } | |
| 291 | - | ||
| 292 | - | func TestServerChildEventsAfterOffer(t *testing.T) { | |
| 293 | - | c, p := pair(t) | |
| 294 | - | d, e := wlturbo.ConnectFromConn(c) | |
| 295 | - | if e != nil { | |
| 296 | - | t.Fatal(e) | |
| 297 | - | } | |
| 298 | - | defer d.Close() | |
| 299 | - | receiveRequest(t, p) | |
| 300 | - | device := core.NewDataDevice(d.Context()) | |
| 301 | - | device.SetID(d.AllocateID()) | |
| 302 | - | d.Context().Register(device) | |
| 303 | - | const offerID = 0xff000011 | |
| 304 | - | var offer *core.DataOffer | |
| 305 | - | device.OnDataOffer(func(o *core.DataOffer) { offer = o }) | |
| 306 | - | send(t, p, frame(device.ID(), 0, offerID)) | |
| 307 | - | if e := d.Dispatch(); e != nil { | |
| 308 | - | t.Fatal(e) | |
| 309 | - | } | |
| 310 | - | if offer == nil { | |
| 311 | - | t.Fatal("missing concrete child") | |
| 312 | - | } | |
| 313 | - | got := "" | |
| 314 | - | offer.OnOffer(func(mime string) { got = mime }) | |
| 315 | - | payload := append(frame(offerID, 0), 4, 0, 0, 0, 'a', 'b', 'c', 0) | |
| 316 | - | binary.LittleEndian.PutUint32(payload[4:], uint32(len(payload))<<16) | |
| 317 | - | send(t, p, payload) | |
| 318 | - | if e := d.Dispatch(); e != nil { | |
| 319 | - | t.Fatal(e) | |
| 320 | - | } | |
| 321 | - | if got != "abc" { | |
| 322 | - | t.Fatalf("typed child event: %q", got) | |
| 323 | - | } | |
| 324 | - | } | |
| 325 | - | ||
| 326 | - | func TestRegistryBootstrapAnnouncements(t *testing.T) { | |
| 327 | - | c, p := pair(t) | |
| 328 | - | d, e := wlturbo.ConnectFromConn(c) | |
| 329 | - | if e != nil { | |
| 330 | - | t.Fatal(e) | |
| 331 | - | } | |
| 332 | - | defer d.Close() | |
| 333 | - | receiveRequest(t, p) | |
| 334 | - | var got wlturbo.Global | |
| 335 | - | d.Registry().AddHandler("wl_compositor", func(r *wlturbo.Registry, n, v uint32) { got, _ = r.FindGlobalByName(n) }) | |
| 336 | - | name := "wl_compositor" | |
| 337 | - | body := make([]byte, 4+4+((len(name)+1+3)&^3)+4) | |
| 338 | - | binary.LittleEndian.PutUint32(body, 17) | |
| 339 | - | binary.LittleEndian.PutUint32(body[4:], uint32(len(name)+1)) | |
| 340 | - | copy(body[8:], name) | |
| 341 | - | binary.LittleEndian.PutUint32(body[len(body)-4:], 7) | |
| 342 | - | msg := append(frame(d.Registry().ID(), 0), body...) | |
| 343 | - | binary.LittleEndian.PutUint32(msg[4:], uint32(len(msg))<<16) | |
| 344 | - | send(t, p, msg) | |
| 345 | - | if e := d.Dispatch(); e != nil { | |
| 346 | - | t.Fatal(e) | |
| 347 | - | } | |
| 348 | - | if got.Name != 17 || got.Interface != name || got.Version != 7 { | |
| 349 | - | t.Fatalf("global: %+v", got) | |
| 350 | - | } | |
| 351 | - | send(t, p, frame(d.Registry().ID(), 1, 17)) | |
| 352 | - | if e := d.Dispatch(); e != nil { | |
| 353 | - | t.Fatal(e) | |
| 354 | - | } | |
| 355 | - | if _, ok := d.Registry().FindGlobalByName(17); ok { | |
| 356 | - | t.Fatal("global not removed") | |
| 357 | - | } | |
| 358 | - | send(t, p, frame(d.Registry().ID(), 2)) | |
| 359 | - | if e := d.Dispatch(); !errors.Is(e, wlturbo.ErrUnknownOpcode) { | |
| 360 | - | t.Fatalf("unknown registry opcode: %v", e) | |
| 361 | - | } | |
| 362 | - | } | |
| 363 | - | func TestUnclaimedFirstHandlerFDClosed(t *testing.T) { | |
| 364 | - | c, p := pair(t) | |
| 365 | - | d, e := wlturbo.ConnectFromConn(c) | |
| 366 | - | if e != nil { | |
| 367 | - | t.Fatal(e) | |
| 368 | - | } | |
| 369 | - | defer d.Close() | |
| 370 | - | receiveRequest(t, p) | |
| 371 | - | kb := core.NewKeyboard(d.Context()) | |
| 372 | - | kb.SetID(d.AllocateID()) | |
| 373 | - | d.Context().Register(kb) | |
| 374 | - | kb.OnKeymap(func(_ uint32, fd *wlturbo.OwnedFD, _ uint32) { | |
| 375 | - | if fd == nil { | |
| 376 | - | t.Fatal("missing first owner") | |
| 377 | - | } | |
| 378 | - | }) | |
| 379 | - | kb.OnKeymap(func(_ uint32, fd *wlturbo.OwnedFD, _ uint32) { | |
| 380 | - | if fd != nil { | |
| 381 | - | t.Fatal("duplicate owner") | |
| 382 | - | } | |
| 383 | - | }) | |
| 384 | - | r, w, e := os.Pipe() | |
| 385 | - | if e != nil { | |
| 386 | - | t.Fatal(e) | |
| 387 | - | } | |
| 388 | - | defer r.Close() | |
| 389 | - | send(t, p, frame(kb.ID(), 0, 1, 8), int(w.Fd())) | |
| 390 | - | w.Close() | |
| 391 | - | if e := d.Dispatch(); e != nil { | |
| 392 | - | t.Fatal(e) | |
| 393 | - | } | |
| 394 | - | if e := r.SetReadDeadline(testDeadline()); e != nil { | |
| 395 | - | t.Fatal(e) | |
| 396 | - | } | |
| 397 | - | var b [1]byte | |
| 398 | - | if n, e := r.Read(b[:]); n != 0 || e != io.EOF { | |
| 399 | - | t.Fatalf("unclaimed FD not closed: %d %v", n, e) | |
| 400 | - | } | |
| 401 | - | } | |
| 402 | - | ||
| 403 | - | func TestDestroyedProxyRejectsRequests(t *testing.T) { | |
| 404 | - | c, p := pair(t) | |
| 405 | - | d, err := wlturbo.ConnectFromConn(c) | |
| 406 | - | if err != nil { | |
| 407 | - | t.Fatal(err) | |
| 408 | - | } | |
| 409 | - | defer d.Close() | |
| 410 | - | receiveRequest(t, p) | |
| 411 | - | surface := core.NewSurface(d.Context()) | |
| 412 | - | surface.SetID(d.AllocateID()) | |
| 413 | - | d.Context().Register(surface) | |
| 414 | - | if err := surface.Destroy(); err != nil { | |
| 415 | - | t.Fatal(err) | |
| 416 | - | } | |
| 417 | - | receiveRequest(t, p) | |
| 418 | - | if err := surface.Destroy(); err == nil { | |
| 419 | - | t.Fatal("second destroy succeeded") | |
| 420 | - | } | |
| 421 | - | if err := surface.Commit(); err == nil { | |
| 422 | - | t.Fatal("request on destroyed surface succeeded") | |
| 423 | - | } | |
| 424 | - | if _, err := surface.Frame(); err == nil { | |
| 425 | - | t.Fatal("child request on destroyed surface succeeded") | |
| 426 | - | } | |
| 427 | - | p.SetReadDeadline(time.Now().Add(20 * time.Millisecond)) | |
| 428 | - | _, err = p.Read(make([]byte, 32)) | |
| 429 | - | ne, ok := err.(net.Error) | |
| 430 | - | if !ok || !ne.Timeout() { | |
| 431 | - | t.Fatalf("unexpected bytes on wire: %v", err) | |
| 432 | - | } | |
| 433 | - | } | |
| 434 | - | ||
| 435 | - | func TestConcurrentDestroySendsOnce(t *testing.T) { | |
| 436 | - | c, p := pair(t) | |
| 437 | - | d, err := wlturbo.ConnectFromConn(c) | |
| 438 | - | if err != nil { | |
| 439 | - | t.Fatal(err) | |
| 440 | - | } | |
| 441 | - | defer d.Close() | |
| 442 | - | receiveRequest(t, p) | |
| 443 | - | const rounds, destroyers, committers = 100, 4, 4 | |
| 444 | - | totalCommits := 0 | |
| 445 | - | for round := 0; round < rounds; round++ { | |
| 446 | - | surface := core.NewSurface(d.Context()) | |
| 447 | - | surface.SetID(d.AllocateID()) | |
| 448 | - | d.Context().Register(surface) | |
| 449 | - | start := make(chan struct{}) | |
| 450 | - | destroyed := make(chan error, destroyers) | |
| 451 | - | committed := make(chan error, committers) | |
| 452 | - | for i := 0; i < destroyers; i++ { | |
| 453 | - | go func() { <-start; destroyed <- surface.Destroy() }() | |
| 454 | - | } | |
| 455 | - | for i := 0; i < committers; i++ { | |
| 456 | - | go func() { <-start; committed <- surface.Commit() }() | |
| 457 | - | } | |
| 458 | - | close(start) | |
| 459 | - | okDestroy, okCommit := 0, 0 | |
| 460 | - | for i := 0; i < destroyers; i++ { | |
| 461 | - | if <-destroyed == nil { | |
| 462 | - | okDestroy++ | |
| 463 | - | } | |
| 464 | - | } | |
| 465 | - | for i := 0; i < committers; i++ { | |
| 466 | - | if <-committed == nil { | |
| 467 | - | okCommit++ | |
| 468 | - | } | |
| 469 | - | } | |
| 470 | - | if okDestroy != 1 { | |
| 471 | - | t.Fatalf("round %d: %d destroys succeeded, want 1", round, okDestroy) | |
| 472 | - | } | |
| 473 | - | totalCommits += okCommit | |
| 474 | - | // Decode every frame: exactly okCommit commits (opcode 6), then one | |
| 475 | - | // destroy (opcode 0) for this surface, and nothing after it. | |
| 476 | - | frames := readFrames(t, p, okCommit+1) | |
| 477 | - | for i, f := range frames { | |
| 478 | - | if f.id != surface.ID() { | |
| 479 | - | t.Fatalf("round %d: frame %d targets object %d", round, i, f.id) | |
| 480 | - | } | |
| 481 | - | last := i == len(frames)-1 | |
| 482 | - | if last && f.opcode != 0 || !last && f.opcode != 6 { | |
| 483 | - | t.Fatalf("round %d: frame %d opcode %d (last=%v)", round, i, f.opcode, last) | |
| 484 | - | } | |
| 485 | - | } | |
| 486 | - | p.SetReadDeadline(time.Now().Add(2 * time.Millisecond)) | |
| 487 | - | if n, err := p.Read(make([]byte, 8)); n != 0 { | |
| 488 | - | t.Fatalf("round %d: request after destroy (%d bytes, %v)", round, n, err) | |
| 489 | - | } | |
| 490 | - | p.SetReadDeadline(time.Time{}) | |
| 491 | - | } | |
| 492 | - | // Ordering is only exercised when some commits won the race. | |
| 493 | - | if totalCommits == 0 { | |
| 494 | - | t.Fatal("no commit succeeded in any round; ordering was not exercised") | |
| 495 | - | } | |
| 496 | - | } | |
| 497 | - | ||
| 498 | - | type wireFrame struct { | |
| 499 | - | id uint32 | |
| 500 | - | opcode uint16 | |
| 501 | - | } | |
| 502 | - | ||
| 503 | - | func readFrames(t *testing.T, p *net.UnixConn, n int) []wireFrame { | |
| 504 | - | t.Helper() | |
| 505 | - | p.SetReadDeadline(testDeadline()) | |
| 506 | - | defer p.SetReadDeadline(time.Time{}) | |
| 507 | - | var out []wireFrame | |
| 508 | - | var buf []byte | |
| 509 | - | tmp := make([]byte, 4096) | |
| 510 | - | for len(out) < n { | |
| 511 | - | for len(buf) >= 8 { | |
| 512 | - | size := int(binary.LittleEndian.Uint32(buf[4:8]) >> 16) | |
| 513 | - | if size < 8 || len(buf) < size { | |
| 514 | - | break | |
| 515 | - | } | |
| 516 | - | out = append(out, wireFrame{binary.LittleEndian.Uint32(buf[0:4]), uint16(binary.LittleEndian.Uint32(buf[4:8]))}) | |
| 517 | - | buf = buf[size:] | |
| 518 | - | } | |
| 519 | - | if len(out) >= n { | |
| 520 | - | break | |
| 521 | - | } | |
| 522 | - | m, err := p.Read(tmp) | |
| 523 | - | if err != nil { | |
| 524 | - | t.Fatalf("read frames: got %d of %d: %v", len(out), n, err) | |
| 525 | - | } | |
| 526 | - | buf = append(buf, tmp[:m]...) | |
| 527 | - | } | |
| 528 | - | if len(out) != n || len(buf) != 0 { | |
| 529 | - | t.Fatalf("got %d frames (+%d bytes), want %d", len(out), len(buf), n) | |
| 530 | - | } | |
| 531 | - | return out | |
| 532 | - | } | |
D protocol/core/doc.go +0 -8
| @@ -1,8 +0,0 @@ | |||
| 1 | - | // Package core contains canonical Wayland core protocol bindings generated from | |
| 2 | - | // pinned wayland.xml. Bind globals with display.Registry().Bind and the | |
| 3 | - | // corresponding New* constructor. Client-created and server-created children | |
| 4 | - | // are registered with their concrete generated types; never replace them with | |
| 5 | - | // transport wrappers. On* handlers receive typed values. Received OwnedFDs | |
| 6 | - | // are closed after the event unless a handler calls Take; request FDs are | |
| 7 | - | // transferred (and closed locally) only after a complete successful send. | |
| 8 | - | package core | |
D protocol/core/wayland_generated.go +0 -3995 large diff (3995 lines changed): collapsed
D protocol/cursorshape/cursor-shape-v1.xml +0 -162
| @@ -1,162 +0,0 @@ | |||
| 1 | - | <?xml version="1.0" encoding="UTF-8"?> | |
| 2 | - | <protocol name="cursor_shape_v1"> | |
| 3 | - | <copyright> | |
| 4 | - | Copyright 2018 The Chromium Authors | |
| 5 | - | Copyright 2023 Simon Ser | |
| 6 | - | ||
| 7 | - | Permission is hereby granted, free of charge, to any person obtaining a | |
| 8 | - | copy of this software and associated documentation files (the "Software"), | |
| 9 | - | to deal in the Software without restriction, including without limitation | |
| 10 | - | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 11 | - | and/or sell copies of the Software, and to permit persons to whom the | |
| 12 | - | Software is furnished to do so, subject to the following conditions: | |
| 13 | - | The above copyright notice and this permission notice (including the next | |
| 14 | - | paragraph) shall be included in all copies or substantial portions of the | |
| 15 | - | Software. | |
| 16 | - | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 17 | - | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 18 | - | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 19 | - | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 20 | - | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 21 | - | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
| 22 | - | DEALINGS IN THE SOFTWARE. | |
| 23 | - | </copyright> | |
| 24 | - | ||
| 25 | - | <interface name="wp_cursor_shape_manager_v1" version="2"> | |
| 26 | - | <description summary="cursor shape manager"> | |
| 27 | - | This global offers an alternative, optional way to set cursor images. This | |
| 28 | - | new way uses enumerated cursors instead of a wl_surface like | |
| 29 | - | wl_pointer.set_cursor does. | |
| 30 | - | ||
| 31 | - | Warning! The protocol described in this file is currently in the testing | |
| 32 | - | phase. Backward compatible changes may be added together with the | |
| 33 | - | corresponding interface version bump. Backward incompatible changes can | |
| 34 | - | only be done by creating a new major version of the extension. | |
| 35 | - | </description> | |
| 36 | - | ||
| 37 | - | <request name="destroy" type="destructor"> | |
| 38 | - | <description summary="destroy the manager"> | |
| 39 | - | Destroy the cursor shape manager. | |
| 40 | - | </description> | |
| 41 | - | </request> | |
| 42 | - | ||
| 43 | - | <request name="get_pointer"> | |
| 44 | - | <description summary="manage the cursor shape of a pointer device"> | |
| 45 | - | Obtain a wp_cursor_shape_device_v1 for a wl_pointer object. | |
| 46 | - | ||
| 47 | - | When the pointer capability is removed from the wl_seat, the | |
| 48 | - | wp_cursor_shape_device_v1 object becomes inert. | |
| 49 | - | </description> | |
| 50 | - | <arg name="cursor_shape_device" type="new_id" interface="wp_cursor_shape_device_v1"/> | |
| 51 | - | <arg name="pointer" type="object" interface="wl_pointer"/> | |
| 52 | - | </request> | |
| 53 | - | ||
| 54 | - | <request name="get_tablet_tool_v2"> | |
| 55 | - | <description summary="manage the cursor shape of a tablet tool device"> | |
| 56 | - | Obtain a wp_cursor_shape_device_v1 for a zwp_tablet_tool_v2 object. | |
| 57 | - | ||
| 58 | - | When the zwp_tablet_tool_v2 is removed, the wp_cursor_shape_device_v1 | |
| 59 | - | object becomes inert. | |
| 60 | - | </description> | |
| 61 | - | <arg name="cursor_shape_device" type="new_id" interface="wp_cursor_shape_device_v1"/> | |
| 62 | - | <arg name="tablet_tool" type="object" interface="zwp_tablet_tool_v2"/> | |
| 63 | - | </request> | |
| 64 | - | </interface> | |
| 65 | - | ||
| 66 | - | <interface name="wp_cursor_shape_device_v1" version="2"> | |
| 67 | - | <description summary="cursor shape for a device"> | |
| 68 | - | This interface allows clients to set the cursor shape. | |
| 69 | - | </description> | |
| 70 | - | ||
| 71 | - | <enum name="shape"> | |
| 72 | - | <description summary="cursor shapes"> | |
| 73 | - | This enum describes cursor shapes. | |
| 74 | - | ||
| 75 | - | The names are taken from the CSS W3C specification: | |
| 76 | - | https://w3c.github.io/csswg-drafts/css-ui/#cursor | |
| 77 | - | with a few additions. | |
| 78 | - | ||
| 79 | - | Note that there are some groups of cursor shapes that are related: | |
| 80 | - | The first group is drag-and-drop cursors which are used to indicate | |
| 81 | - | the selected action during dnd operations. The second group is resize | |
| 82 | - | cursors which are used to indicate resizing and moving possibilities | |
| 83 | - | on window borders. It is recommended that the shapes in these groups | |
| 84 | - | should use visually compatible images and metaphors. | |
| 85 | - | </description> | |
| 86 | - | <entry name="default" value="1" summary="default cursor"/> | |
| 87 | - | <entry name="context_menu" value="2" summary="a context menu is available for the object under the cursor"/> | |
| 88 | - | <entry name="help" value="3" summary="help is available for the object under the cursor"/> | |
| 89 | - | <entry name="pointer" value="4" summary="pointer that indicates a link or another interactive element"/> | |
| 90 | - | <entry name="progress" value="5" summary="progress indicator"/> | |
| 91 | - | <entry name="wait" value="6" summary="program is busy, user should wait"/> | |
| 92 | - | <entry name="cell" value="7" summary="a cell or set of cells may be selected"/> | |
| 93 | - | <entry name="crosshair" value="8" summary="simple crosshair"/> | |
| 94 | - | <entry name="text" value="9" summary="text may be selected"/> | |
| 95 | - | <entry name="vertical_text" value="10" summary="vertical text may be selected"/> | |
| 96 | - | <entry name="alias" value="11" summary="drag-and-drop: alias of/shortcut to something is to be created"/> | |
| 97 | - | <entry name="copy" value="12" summary="drag-and-drop: something is to be copied"/> | |
| 98 | - | <entry name="move" value="13" summary="drag-and-drop: something is to be moved"/> | |
| 99 | - | <entry name="no_drop" value="14" summary="drag-and-drop: the dragged item cannot be dropped at the current cursor location"/> | |
| 100 | - | <entry name="not_allowed" value="15" summary="drag-and-drop: the requested action will not be carried out"/> | |
| 101 | - | <entry name="grab" value="16" summary="drag-and-drop: something can be grabbed"/> | |
| 102 | - | <entry name="grabbing" value="17" summary="drag-and-drop: something is being grabbed"/> | |
| 103 | - | <entry name="e_resize" value="18" summary="resizing: the east border is to be moved"/> | |
| 104 | - | <entry name="n_resize" value="19" summary="resizing: the north border is to be moved"/> | |
| 105 | - | <entry name="ne_resize" value="20" summary="resizing: the north-east corner is to be moved"/> | |
| 106 | - | <entry name="nw_resize" value="21" summary="resizing: the north-west corner is to be moved"/> | |
| 107 | - | <entry name="s_resize" value="22" summary="resizing: the south border is to be moved"/> | |
| 108 | - | <entry name="se_resize" value="23" summary="resizing: the south-east corner is to be moved"/> | |
| 109 | - | <entry name="sw_resize" value="24" summary="resizing: the south-west corner is to be moved"/> | |
| 110 | - | <entry name="w_resize" value="25" summary="resizing: the west border is to be moved"/> | |
| 111 | - | <entry name="ew_resize" value="26" summary="resizing: the east and west borders are to be moved"/> | |
| 112 | - | <entry name="ns_resize" value="27" summary="resizing: the north and south borders are to be moved"/> | |
| 113 | - | <entry name="nesw_resize" value="28" summary="resizing: the north-east and south-west corners are to be moved"/> | |
| 114 | - | <entry name="nwse_resize" value="29" summary="resizing: the north-west and south-east corners are to be moved"/> | |
| 115 | - | <entry name="col_resize" value="30" summary="resizing: that the item/column can be resized horizontally"/> | |
| 116 | - | <entry name="row_resize" value="31" summary="resizing: that the item/row can be resized vertically"/> | |
| 117 | - | <entry name="all_scroll" value="32" summary="something can be scrolled in any direction"/> | |
| 118 | - | <entry name="zoom_in" value="33" summary="something can be zoomed in"/> | |
| 119 | - | <entry name="zoom_out" value="34" summary="something can be zoomed out"/> | |
| 120 | - | <entry name="dnd_ask" value="35" summary="drag-and-drop: the user will select which action will be carried out (non-css value)" since="2"/> | |
| 121 | - | <entry name="all_resize" value="36" summary="resizing: something can be moved or resized in any direction (non-css value)" since="2"/> | |
| 122 | - | </enum> | |
| 123 | - | ||
| 124 | - | <enum name="error"> | |
| 125 | - | <entry name="invalid_shape" value="1" | |
| 126 | - | summary="the specified shape value is invalid"/> | |
| 127 | - | </enum> | |
| 128 | - | ||
| 129 | - | <request name="destroy" type="destructor"> | |
| 130 | - | <description summary="destroy the cursor shape device"> | |
| 131 | - | Destroy the cursor shape device. | |
| 132 | - | ||
| 133 | - | The device cursor shape remains unchanged. | |
| 134 | - | </description> | |
| 135 | - | </request> | |
| 136 | - | ||
| 137 | - | <request name="set_shape"> | |
| 138 | - | <description summary="set device cursor to the shape"> | |
| 139 | - | Sets the device cursor to the specified shape. The compositor will | |
| 140 | - | change the cursor image based on the specified shape. | |
| 141 | - | ||
| 142 | - | The cursor actually changes only if the input device focus is one of | |
| 143 | - | the requesting client's surfaces. If any, the previous cursor image | |
| 144 | - | (surface or shape) is replaced. | |
| 145 | - | ||
| 146 | - | The "shape" argument must be a valid enum entry, otherwise the | |
| 147 | - | invalid_shape protocol error is raised. | |
| 148 | - | ||
| 149 | - | This is similar to the wl_pointer.set_cursor and | |
| 150 | - | zwp_tablet_tool_v2.set_cursor requests, but this request accepts a | |
| 151 | - | shape instead of contents in the form of a surface. Clients can mix | |
| 152 | - | set_cursor and set_shape requests. | |
| 153 | - | ||
| 154 | - | The serial parameter must match the latest wl_pointer.enter or | |
| 155 | - | zwp_tablet_tool_v2.proximity_in serial number sent to the client. | |
| 156 | - | Otherwise the request will be ignored. | |
| 157 | - | </description> | |
| 158 | - | <arg name="serial" type="uint" summary="serial number of the enter event"/> | |
| 159 | - | <arg name="shape" type="uint" enum="shape"/> | |
| 160 | - | </request> | |
| 161 | - | </interface> | |
| 162 | - | </protocol> | |
D protocol/cursorshape/cursor-shape-v1_generated.go +0 -257
| @@ -1,257 +0,0 @@ | |||
| 1 | - | // Code generated by wlturbo-scanner. DO NOT EDIT. | |
| 2 | - | // Protocol: cursor_shape_v1 | |
| 3 | - | // Source: cursor-shape-v1.xml | |
| 4 | - | ||
| 5 | - | // Upstream protocol copyright and license: | |
| 6 | - | // Copyright 2018 The Chromium Authors | |
| 7 | - | // Copyright 2023 Simon Ser | |
| 8 | - | // | |
| 9 | - | // Permission is hereby granted, free of charge, to any person obtaining a | |
| 10 | - | // copy of this software and associated documentation files (the "Software"), | |
| 11 | - | // to deal in the Software without restriction, including without limitation | |
| 12 | - | // the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 13 | - | // and/or sell copies of the Software, and to permit persons to whom the | |
| 14 | - | // Software is furnished to do so, subject to the following conditions: | |
| 15 | - | // The above copyright notice and this permission notice (including the next | |
| 16 | - | // paragraph) shall be included in all copies or substantial portions of the | |
| 17 | - | // Software. | |
| 18 | - | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 19 | - | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 20 | - | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 21 | - | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 22 | - | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 23 | - | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
| 24 | - | // DEALINGS IN THE SOFTWARE. | |
| 25 | - | ||
| 26 | - | package cursorshape | |
| 27 | - | ||
| 28 | - | import ( | |
| 29 | - | cross_wl_pointer "github.com/bnema/wlturbo/protocol/core" | |
| 30 | - | cross_zwp_tablet_tool_v2 "github.com/bnema/wlturbo/protocol/tablet" | |
| 31 | - | "github.com/bnema/wlturbo/wl" | |
| 32 | - | ) | |
| 33 | - | ||
| 34 | - | // SHAPE_DEFAULT is the shape default value. | |
| 35 | - | const SHAPE_DEFAULT = 1 | |
| 36 | - | ||
| 37 | - | // SHAPE_CONTEXT_MENU is the shape context_menu value. | |
| 38 | - | const SHAPE_CONTEXT_MENU = 2 | |
| 39 | - | ||
| 40 | - | // SHAPE_HELP is the shape help value. | |
| 41 | - | const SHAPE_HELP = 3 | |
| 42 | - | ||
| 43 | - | // SHAPE_POINTER is the shape pointer value. | |
| 44 | - | const SHAPE_POINTER = 4 | |
| 45 | - | ||
| 46 | - | // SHAPE_PROGRESS is the shape progress value. | |
| 47 | - | const SHAPE_PROGRESS = 5 | |
| 48 | - | ||
| 49 | - | // SHAPE_WAIT is the shape wait value. | |
| 50 | - | const SHAPE_WAIT = 6 | |
| 51 | - | ||
| 52 | - | // SHAPE_CELL is the shape cell value. | |
| 53 | - | const SHAPE_CELL = 7 | |
| 54 | - | ||
| 55 | - | // SHAPE_CROSSHAIR is the shape crosshair value. | |
| 56 | - | const SHAPE_CROSSHAIR = 8 | |
| 57 | - | ||
| 58 | - | // SHAPE_TEXT is the shape text value. | |
| 59 | - | const SHAPE_TEXT = 9 | |
| 60 | - | ||
| 61 | - | // SHAPE_VERTICAL_TEXT is the shape vertical_text value. | |
| 62 | - | const SHAPE_VERTICAL_TEXT = 10 | |
| 63 | - | ||
| 64 | - | // SHAPE_ALIAS is the shape alias value. | |
| 65 | - | const SHAPE_ALIAS = 11 | |
| 66 | - | ||
| 67 | - | // SHAPE_COPY is the shape copy value. | |
| 68 | - | const SHAPE_COPY = 12 | |
| 69 | - | ||
| 70 | - | // SHAPE_MOVE is the shape move value. | |
| 71 | - | const SHAPE_MOVE = 13 | |
| 72 | - | ||
| 73 | - | // SHAPE_NO_DROP is the shape no_drop value. | |
| 74 | - | const SHAPE_NO_DROP = 14 | |
| 75 | - | ||
| 76 | - | // SHAPE_NOT_ALLOWED is the shape not_allowed value. | |
| 77 | - | const SHAPE_NOT_ALLOWED = 15 | |
| 78 | - | ||
| 79 | - | // SHAPE_GRAB is the shape grab value. | |
| 80 | - | const SHAPE_GRAB = 16 | |
| 81 | - | ||
| 82 | - | // SHAPE_GRABBING is the shape grabbing value. | |
| 83 | - | const SHAPE_GRABBING = 17 | |
| 84 | - | ||
| 85 | - | // SHAPE_E_RESIZE is the shape e_resize value. | |
| 86 | - | const SHAPE_E_RESIZE = 18 | |
| 87 | - | ||
| 88 | - | // SHAPE_N_RESIZE is the shape n_resize value. | |
| 89 | - | const SHAPE_N_RESIZE = 19 | |
| 90 | - | ||
| 91 | - | // SHAPE_NE_RESIZE is the shape ne_resize value. | |
| 92 | - | const SHAPE_NE_RESIZE = 20 | |
| 93 | - | ||
| 94 | - | // SHAPE_NW_RESIZE is the shape nw_resize value. | |
| 95 | - | const SHAPE_NW_RESIZE = 21 | |
| 96 | - | ||
| 97 | - | // SHAPE_S_RESIZE is the shape s_resize value. | |
| 98 | - | const SHAPE_S_RESIZE = 22 | |
| 99 | - | ||
| 100 | - | // SHAPE_SE_RESIZE is the shape se_resize value. | |
| 101 | - | const SHAPE_SE_RESIZE = 23 | |
| 102 | - | ||
| 103 | - | // SHAPE_SW_RESIZE is the shape sw_resize value. | |
| 104 | - | const SHAPE_SW_RESIZE = 24 | |
| 105 | - | ||
| 106 | - | // SHAPE_W_RESIZE is the shape w_resize value. | |
| 107 | - | const SHAPE_W_RESIZE = 25 | |
| 108 | - | ||
| 109 | - | // SHAPE_EW_RESIZE is the shape ew_resize value. | |
| 110 | - | const SHAPE_EW_RESIZE = 26 | |
| 111 | - | ||
| 112 | - | // SHAPE_NS_RESIZE is the shape ns_resize value. | |
| 113 | - | const SHAPE_NS_RESIZE = 27 | |
| 114 | - | ||
| 115 | - | // SHAPE_NESW_RESIZE is the shape nesw_resize value. | |
| 116 | - | const SHAPE_NESW_RESIZE = 28 | |
| 117 | - | ||
| 118 | - | // SHAPE_NWSE_RESIZE is the shape nwse_resize value. | |
| 119 | - | const SHAPE_NWSE_RESIZE = 29 | |
| 120 | - | ||
| 121 | - | // SHAPE_COL_RESIZE is the shape col_resize value. | |
| 122 | - | const SHAPE_COL_RESIZE = 30 | |
| 123 | - | ||
| 124 | - | // SHAPE_ROW_RESIZE is the shape row_resize value. | |
| 125 | - | const SHAPE_ROW_RESIZE = 31 | |
| 126 | - | ||
| 127 | - | // SHAPE_ALL_SCROLL is the shape all_scroll value. | |
| 128 | - | const SHAPE_ALL_SCROLL = 32 | |
| 129 | - | ||
| 130 | - | // SHAPE_ZOOM_IN is the shape zoom_in value. | |
| 131 | - | const SHAPE_ZOOM_IN = 33 | |
| 132 | - | ||
| 133 | - | // SHAPE_ZOOM_OUT is the shape zoom_out value. | |
| 134 | - | const SHAPE_ZOOM_OUT = 34 | |
| 135 | - | ||
| 136 | - | // SHAPE_DND_ASK is the shape dnd_ask value. | |
| 137 | - | const SHAPE_DND_ASK = 35 | |
| 138 | - | ||
| 139 | - | // SHAPE_ALL_RESIZE is the shape all_resize value. | |
| 140 | - | const SHAPE_ALL_RESIZE = 36 | |
| 141 | - | ||
| 142 | - | // ERROR_INVALID_SHAPE is the error invalid_shape value. | |
| 143 | - | const ERROR_INVALID_SHAPE = 1 | |
| 144 | - | ||
| 145 | - | // WpCursorShapeManagerInterface is the protocol interface name. | |
| 146 | - | const WpCursorShapeManagerInterface = "wp_cursor_shape_manager_v1" | |
| 147 | - | ||
| 148 | - | // WpCursorShapeManager is the generated binding for wp_cursor_shape_manager_v1 version 2. | |
| 149 | - | type WpCursorShapeManager struct { | |
| 150 | - | wl.BaseProxy | |
| 151 | - | } | |
| 152 | - | ||
| 153 | - | // NewWpCursorShapeManager returns an unbound WpCursorShapeManager. | |
| 154 | - | func NewWpCursorShapeManager(ctx *wl.Context) *WpCursorShapeManager { | |
| 155 | - | obj := &WpCursorShapeManager{} | |
| 156 | - | obj.SetContext(ctx) | |
| 157 | - | ctx.Register(obj) | |
| 158 | - | return obj | |
| 159 | - | } | |
| 160 | - | ||
| 161 | - | // Destroy the cursor shape manager. | |
| 162 | - | func (o *WpCursorShapeManager) Destroy() error { | |
| 163 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "wp_cursor_shape_manager_v1.destroy", Destructor: true}); err != nil { | |
| 164 | - | return err | |
| 165 | - | } | |
| 166 | - | return nil | |
| 167 | - | } | |
| 168 | - | ||
| 169 | - | // Obtain a wp_cursor_shape_device_v1 for a wl_pointer object. When the pointer capability is removed from the wl_seat, the wp_cursor_shape_device_v1 object becomes inert. | |
| 170 | - | func (o *WpCursorShapeManager) GetPointer(pointer *cross_wl_pointer.Pointer) (*WpCursorShapeDevice, error) { | |
| 171 | - | var arg1 wl.Object | |
| 172 | - | if pointer != nil { | |
| 173 | - | arg1 = pointer | |
| 174 | - | } | |
| 175 | - | child := &WpCursorShapeDevice{} | |
| 176 | - | child.SetContext(o.Context()) | |
| 177 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "wp_cursor_shape_manager_v1.get_pointer", Child: child}, wl.ArgObject(child), wl.ArgObject(arg1)); err != nil { | |
| 178 | - | return nil, err | |
| 179 | - | } | |
| 180 | - | return child, nil | |
| 181 | - | } | |
| 182 | - | ||
| 183 | - | // Obtain a wp_cursor_shape_device_v1 for a zwp_tablet_tool_v2 object. When the zwp_tablet_tool_v2 is removed, the wp_cursor_shape_device_v1 object becomes inert. | |
| 184 | - | func (o *WpCursorShapeManager) GetTabletTool(tabletTool *cross_zwp_tablet_tool_v2.TabletTool) (*WpCursorShapeDevice, error) { | |
| 185 | - | var arg1 wl.Object | |
| 186 | - | if tabletTool != nil { | |
| 187 | - | arg1 = tabletTool | |
| 188 | - | } | |
| 189 | - | child := &WpCursorShapeDevice{} | |
| 190 | - | child.SetContext(o.Context()) | |
| 191 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 2, Name: "wp_cursor_shape_manager_v1.get_tablet_tool_v2", Child: child}, wl.ArgObject(child), wl.ArgObject(arg1)); err != nil { | |
| 192 | - | return nil, err | |
| 193 | - | } | |
| 194 | - | return child, nil | |
| 195 | - | } | |
| 196 | - | ||
| 197 | - | // EventSignature returns the declared event argument types in wire order. | |
| 198 | - | func (o *WpCursorShapeManager) EventSignature(opcode uint16) (string, bool) { | |
| 199 | - | switch opcode { | |
| 200 | - | default: | |
| 201 | - | return "", false | |
| 202 | - | } | |
| 203 | - | } | |
| 204 | - | ||
| 205 | - | // Dispatch decodes one event on wp_cursor_shape_manager_v1 and calls the registered handlers. | |
| 206 | - | func (o *WpCursorShapeManager) Dispatch(event *wl.Event) { | |
| 207 | - | switch event.Opcode { | |
| 208 | - | default: | |
| 209 | - | } | |
| 210 | - | } | |
| 211 | - | ||
| 212 | - | // WpCursorShapeDeviceInterface is the protocol interface name. | |
| 213 | - | const WpCursorShapeDeviceInterface = "wp_cursor_shape_device_v1" | |
| 214 | - | ||
| 215 | - | // WpCursorShapeDevice is the generated binding for wp_cursor_shape_device_v1 version 2. | |
| 216 | - | type WpCursorShapeDevice struct { | |
| 217 | - | wl.BaseProxy | |
| 218 | - | } | |
| 219 | - | ||
| 220 | - | // NewWpCursorShapeDevice returns an unbound WpCursorShapeDevice. | |
| 221 | - | func NewWpCursorShapeDevice(ctx *wl.Context) *WpCursorShapeDevice { | |
| 222 | - | obj := &WpCursorShapeDevice{} | |
| 223 | - | obj.SetContext(ctx) | |
| 224 | - | ctx.Register(obj) | |
| 225 | - | return obj | |
| 226 | - | } | |
| 227 | - | ||
| 228 | - | // Destroy the cursor shape device. The device cursor shape remains unchanged. | |
| 229 | - | func (o *WpCursorShapeDevice) Destroy() error { | |
| 230 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "wp_cursor_shape_device_v1.destroy", Destructor: true}); err != nil { | |
| 231 | - | return err | |
| 232 | - | } | |
| 233 | - | return nil | |
| 234 | - | } | |
| 235 | - | ||
| 236 | - | // 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. | |
| 237 | - | func (o *WpCursorShapeDevice) SetShape(serial uint32, shape uint32) error { | |
| 238 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "wp_cursor_shape_device_v1.set_shape"}, wl.ArgUint(serial), wl.ArgUint(shape)); err != nil { | |
| 239 | - | return err | |
| 240 | - | } | |
| 241 | - | return nil | |
| 242 | - | } | |
| 243 | - | ||
| 244 | - | // EventSignature returns the declared event argument types in wire order. | |
| 245 | - | func (o *WpCursorShapeDevice) EventSignature(opcode uint16) (string, bool) { | |
| 246 | - | switch opcode { | |
| 247 | - | default: | |
| 248 | - | return "", false | |
| 249 | - | } | |
| 250 | - | } | |
| 251 | - | ||
| 252 | - | // Dispatch decodes one event on wp_cursor_shape_device_v1 and calls the registered handlers. | |
| 253 | - | func (o *WpCursorShapeDevice) Dispatch(event *wl.Event) { | |
| 254 | - | switch event.Opcode { | |
| 255 | - | default: | |
| 256 | - | } | |
| 257 | - | } | |
D protocol/datacontrol/ext-data-control-v1.xml +0 -276
| @@ -1,276 +0,0 @@ | |||
| 1 | - | <?xml version="1.0" encoding="UTF-8"?> | |
| 2 | - | <protocol name="ext_data_control_v1"> | |
| 3 | - | <copyright> | |
| 4 | - | Copyright © 2018 Simon Ser | |
| 5 | - | Copyright © 2019 Ivan Molodetskikh | |
| 6 | - | Copyright © 2024 Neal Gompa | |
| 7 | - | ||
| 8 | - | Permission to use, copy, modify, distribute, and sell this | |
| 9 | - | software and its documentation for any purpose is hereby granted | |
| 10 | - | without fee, provided that the above copyright notice appear in | |
| 11 | - | all copies and that both that copyright notice and this permission | |
| 12 | - | notice appear in supporting documentation, and that the name of | |
| 13 | - | the copyright holders not be used in advertising or publicity | |
| 14 | - | pertaining to distribution of the software without specific, | |
| 15 | - | written prior permission. The copyright holders make no | |
| 16 | - | representations about the suitability of this software for any | |
| 17 | - | purpose. It is provided "as is" without express or implied | |
| 18 | - | warranty. | |
| 19 | - | ||
| 20 | - | THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS | |
| 21 | - | SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | |
| 22 | - | FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY | |
| 23 | - | SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
| 24 | - | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN | |
| 25 | - | AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | |
| 26 | - | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF | |
| 27 | - | THIS SOFTWARE. | |
| 28 | - | </copyright> | |
| 29 | - | ||
| 30 | - | <description summary="control data devices"> | |
| 31 | - | This protocol allows a privileged client to control data devices. In | |
| 32 | - | particular, the client will be able to manage the current selection and take | |
| 33 | - | the role of a clipboard manager. | |
| 34 | - | ||
| 35 | - | Warning! The protocol described in this file is currently in the testing | |
| 36 | - | phase. Backward compatible changes may be added together with the | |
| 37 | - | corresponding interface version bump. Backward incompatible changes can | |
| 38 | - | only be done by creating a new major version of the extension. | |
| 39 | - | </description> | |
| 40 | - | ||
| 41 | - | <interface name="ext_data_control_manager_v1" version="1"> | |
| 42 | - | <description summary="manager to control data devices"> | |
| 43 | - | This interface is a manager that allows creating per-seat data device | |
| 44 | - | controls. | |
| 45 | - | </description> | |
| 46 | - | ||
| 47 | - | <request name="create_data_source"> | |
| 48 | - | <description summary="create a new data source"> | |
| 49 | - | Create a new data source. | |
| 50 | - | </description> | |
| 51 | - | <arg name="id" type="new_id" interface="ext_data_control_source_v1" | |
| 52 | - | summary="data source to create"/> | |
| 53 | - | </request> | |
| 54 | - | ||
| 55 | - | <request name="get_data_device"> | |
| 56 | - | <description summary="get a data device for a seat"> | |
| 57 | - | Create a data device that can be used to manage a seat's selection. | |
| 58 | - | </description> | |
| 59 | - | <arg name="id" type="new_id" interface="ext_data_control_device_v1"/> | |
| 60 | - | <arg name="seat" type="object" interface="wl_seat"/> | |
| 61 | - | </request> | |
| 62 | - | ||
| 63 | - | <request name="destroy" type="destructor"> | |
| 64 | - | <description summary="destroy the manager"> | |
| 65 | - | All objects created by the manager will still remain valid, until their | |
| 66 | - | appropriate destroy request has been called. | |
| 67 | - | </description> | |
| 68 | - | </request> | |
| 69 | - | </interface> | |
| 70 | - | ||
| 71 | - | <interface name="ext_data_control_device_v1" version="1"> | |
| 72 | - | <description summary="manage a data device for a seat"> | |
| 73 | - | This interface allows a client to manage a seat's selection. | |
| 74 | - | ||
| 75 | - | When the seat is destroyed, this object becomes inert. | |
| 76 | - | </description> | |
| 77 | - | ||
| 78 | - | <request name="set_selection"> | |
| 79 | - | <description summary="copy data to the selection"> | |
| 80 | - | This request asks the compositor to set the selection to the data from | |
| 81 | - | the source on behalf of the client. | |
| 82 | - | ||
| 83 | - | The given source may not be used in any further set_selection or | |
| 84 | - | set_primary_selection requests. Attempting to use a previously used | |
| 85 | - | source triggers the used_source protocol error. | |
| 86 | - | ||
| 87 | - | To unset the selection, set the source to NULL. | |
| 88 | - | </description> | |
| 89 | - | <arg name="source" type="object" interface="ext_data_control_source_v1" | |
| 90 | - | allow-null="true"/> | |
| 91 | - | </request> | |
| 92 | - | ||
| 93 | - | <request name="destroy" type="destructor"> | |
| 94 | - | <description summary="destroy this data device"> | |
| 95 | - | Destroys the data device object. | |
| 96 | - | </description> | |
| 97 | - | </request> | |
| 98 | - | ||
| 99 | - | <event name="data_offer"> | |
| 100 | - | <description summary="introduce a new ext_data_control_offer"> | |
| 101 | - | The data_offer event introduces a new ext_data_control_offer object, | |
| 102 | - | which will subsequently be used in either the | |
| 103 | - | ext_data_control_device.selection event (for the regular clipboard | |
| 104 | - | selections) or the ext_data_control_device.primary_selection event (for | |
| 105 | - | the primary clipboard selections). Immediately following the | |
| 106 | - | ext_data_control_device.data_offer event, the new data_offer object | |
| 107 | - | will send out ext_data_control_offer.offer events to describe the MIME | |
| 108 | - | types it offers. | |
| 109 | - | </description> | |
| 110 | - | <arg name="id" type="new_id" interface="ext_data_control_offer_v1"/> | |
| 111 | - | </event> | |
| 112 | - | ||
| 113 | - | <event name="selection"> | |
| 114 | - | <description summary="advertise new selection"> | |
| 115 | - | The selection event is sent out to notify the client of a new | |
| 116 | - | ext_data_control_offer for the selection for this device. The | |
| 117 | - | ext_data_control_device.data_offer and the ext_data_control_offer.offer | |
| 118 | - | events are sent out immediately before this event to introduce the data | |
| 119 | - | offer object. The selection event is sent to a client when a new | |
| 120 | - | selection is set. The ext_data_control_offer is valid until a new | |
| 121 | - | ext_data_control_offer or NULL is received. The client must destroy the | |
| 122 | - | previous selection ext_data_control_offer, if any, upon receiving this | |
| 123 | - | event. Regardless, the previous selection will be ignored once a new | |
| 124 | - | selection ext_data_control_offer is received. | |
| 125 | - | ||
| 126 | - | The first selection event is sent upon binding the | |
| 127 | - | ext_data_control_device object. | |
| 128 | - | </description> | |
| 129 | - | <arg name="id" type="object" interface="ext_data_control_offer_v1" | |
| 130 | - | allow-null="true"/> | |
| 131 | - | </event> | |
| 132 | - | ||
| 133 | - | <event name="finished"> | |
| 134 | - | <description summary="this data control is no longer valid"> | |
| 135 | - | This data control object is no longer valid and should be destroyed by | |
| 136 | - | the client. | |
| 137 | - | </description> | |
| 138 | - | </event> | |
| 139 | - | ||
| 140 | - | <event name="primary_selection"> | |
| 141 | - | <description summary="advertise new primary selection"> | |
| 142 | - | The primary_selection event is sent out to notify the client of a new | |
| 143 | - | ext_data_control_offer for the primary selection for this device. The | |
| 144 | - | ext_data_control_device.data_offer and the ext_data_control_offer.offer | |
| 145 | - | events are sent out immediately before this event to introduce the data | |
| 146 | - | offer object. The primary_selection event is sent to a client when a | |
| 147 | - | new primary selection is set. The ext_data_control_offer is valid until | |
| 148 | - | a new ext_data_control_offer or NULL is received. The client must | |
| 149 | - | destroy the previous primary selection ext_data_control_offer, if any, | |
| 150 | - | upon receiving this event. Regardless, the previous primary selection | |
| 151 | - | will be ignored once a new primary selection ext_data_control_offer is | |
| 152 | - | received. | |
| 153 | - | ||
| 154 | - | If the compositor supports primary selection, the first | |
| 155 | - | primary_selection event is sent upon binding the | |
| 156 | - | ext_data_control_device object. | |
| 157 | - | </description> | |
| 158 | - | <arg name="id" type="object" interface="ext_data_control_offer_v1" | |
| 159 | - | allow-null="true"/> | |
| 160 | - | </event> | |
| 161 | - | ||
| 162 | - | <request name="set_primary_selection"> | |
| 163 | - | <description summary="copy data to the primary selection"> | |
| 164 | - | This request asks the compositor to set the primary selection to the | |
| 165 | - | data from the source on behalf of the client. | |
| 166 | - | ||
| 167 | - | The given source may not be used in any further set_selection or | |
| 168 | - | set_primary_selection requests. Attempting to use a previously used | |
| 169 | - | source triggers the used_source protocol error. | |
| 170 | - | ||
| 171 | - | To unset the primary selection, set the source to NULL. | |
| 172 | - | ||
| 173 | - | The compositor will ignore this request if it does not support primary | |
| 174 | - | selection. | |
| 175 | - | </description> | |
| 176 | - | <arg name="source" type="object" interface="ext_data_control_source_v1" | |
| 177 | - | allow-null="true"/> | |
| 178 | - | </request> | |
| 179 | - | ||
| 180 | - | <enum name="error"> | |
| 181 | - | <entry name="used_source" value="1" | |
| 182 | - | summary="source given to set_selection or set_primary_selection was already used before"/> | |
| 183 | - | </enum> | |
| 184 | - | </interface> | |
| 185 | - | ||
| 186 | - | <interface name="ext_data_control_source_v1" version="1"> | |
| 187 | - | <description summary="offer to transfer data"> | |
| 188 | - | The ext_data_control_source object is the source side of a | |
| 189 | - | ext_data_control_offer. It is created by the source client in a data | |
| 190 | - | transfer and provides a way to describe the offered data and a way to | |
| 191 | - | respond to requests to transfer the data. | |
| 192 | - | </description> | |
| 193 | - | ||
| 194 | - | <enum name="error"> | |
| 195 | - | <entry name="invalid_offer" value="1" | |
| 196 | - | summary="offer sent after ext_data_control_device.set_selection"/> | |
| 197 | - | </enum> | |
| 198 | - | ||
| 199 | - | <request name="offer"> | |
| 200 | - | <description summary="add an offered MIME type"> | |
| 201 | - | This request adds a MIME type to the set of MIME types advertised to | |
| 202 | - | targets. Can be called several times to offer multiple types. | |
| 203 | - | ||
| 204 | - | Calling this after ext_data_control_device.set_selection is a protocol | |
| 205 | - | error. | |
| 206 | - | </description> | |
| 207 | - | <arg name="mime_type" type="string" | |
| 208 | - | summary="MIME type offered by the data source"/> | |
| 209 | - | </request> | |
| 210 | - | ||
| 211 | - | <request name="destroy" type="destructor"> | |
| 212 | - | <description summary="destroy this source"> | |
| 213 | - | Destroys the data source object. | |
| 214 | - | </description> | |
| 215 | - | </request> | |
| 216 | - | ||
| 217 | - | <event name="send"> | |
| 218 | - | <description summary="send the data"> | |
| 219 | - | Request for data from the client. Send the data as the specified MIME | |
| 220 | - | type over the passed file descriptor, then close it. | |
| 221 | - | </description> | |
| 222 | - | <arg name="mime_type" type="string" summary="MIME type for the data"/> | |
| 223 | - | <arg name="fd" type="fd" summary="file descriptor for the data"/> | |
| 224 | - | </event> | |
| 225 | - | ||
| 226 | - | <event name="cancelled"> | |
| 227 | - | <description summary="selection was cancelled"> | |
| 228 | - | This data source is no longer valid. The data source has been replaced | |
| 229 | - | by another data source. | |
| 230 | - | ||
| 231 | - | The client should clean up and destroy this data source. | |
| 232 | - | </description> | |
| 233 | - | </event> | |
| 234 | - | </interface> | |
| 235 | - | ||
| 236 | - | <interface name="ext_data_control_offer_v1" version="1"> | |
| 237 | - | <description summary="offer to transfer data"> | |
| 238 | - | A ext_data_control_offer represents a piece of data offered for transfer | |
| 239 | - | by another client (the source client). The offer describes the different | |
| 240 | - | MIME types that the data can be converted to and provides the mechanism | |
| 241 | - | for transferring the data directly from the source client. | |
| 242 | - | </description> | |
| 243 | - | ||
| 244 | - | <request name="receive"> | |
| 245 | - | <description summary="request that the data is transferred"> | |
| 246 | - | To transfer the offered data, the client issues this request and | |
| 247 | - | indicates the MIME type it wants to receive. The transfer happens | |
| 248 | - | through the passed file descriptor (typically created with the pipe | |
| 249 | - | system call). The source client writes the data in the MIME type | |
| 250 | - | representation requested and then closes the file descriptor. | |
| 251 | - | ||
| 252 | - | The receiving client reads from the read end of the pipe until EOF and | |
| 253 | - | then closes its end, at which point the transfer is complete. | |
| 254 | - | ||
| 255 | - | This request may happen multiple times for different MIME types. | |
| 256 | - | </description> | |
| 257 | - | <arg name="mime_type" type="string" | |
| 258 | - | summary="MIME type desired by receiver"/> | |
| 259 | - | <arg name="fd" type="fd" summary="file descriptor for data transfer"/> | |
| 260 | - | </request> | |
| 261 | - | ||
| 262 | - | <request name="destroy" type="destructor"> | |
| 263 | - | <description summary="destroy this offer"> | |
| 264 | - | Destroys the data offer object. | |
| 265 | - | </description> | |
| 266 | - | </request> | |
| 267 | - | ||
| 268 | - | <event name="offer"> | |
| 269 | - | <description summary="advertise offered MIME type"> | |
| 270 | - | Sent immediately after creating the ext_data_control_offer object. | |
| 271 | - | One event per offered MIME type. | |
| 272 | - | </description> | |
| 273 | - | <arg name="mime_type" type="string" summary="offered MIME type"/> | |
| 274 | - | </event> | |
| 275 | - | </interface> | |
| 276 | - | </protocol> | |
D protocol/datacontrol/ext-data-control-v1_generated.go +0 -505
| @@ -1,505 +0,0 @@ | |||
| 1 | - | // Code generated by wlturbo-scanner. DO NOT EDIT. | |
| 2 | - | // Protocol: ext_data_control_v1 | |
| 3 | - | // Source: ext-data-control-v1.xml | |
| 4 | - | ||
| 5 | - | // Upstream protocol copyright and license: | |
| 6 | - | // Copyright © 2018 Simon Ser | |
| 7 | - | // Copyright © 2019 Ivan Molodetskikh | |
| 8 | - | // Copyright © 2024 Neal Gompa | |
| 9 | - | // | |
| 10 | - | // Permission to use, copy, modify, distribute, and sell this | |
| 11 | - | // software and its documentation for any purpose is hereby granted | |
| 12 | - | // without fee, provided that the above copyright notice appear in | |
| 13 | - | // all copies and that both that copyright notice and this permission | |
| 14 | - | // notice appear in supporting documentation, and that the name of | |
| 15 | - | // the copyright holders not be used in advertising or publicity | |
| 16 | - | // pertaining to distribution of the software without specific, | |
| 17 | - | // written prior permission. The copyright holders make no | |
| 18 | - | // representations about the suitability of this software for any | |
| 19 | - | // purpose. It is provided "as is" without express or implied | |
| 20 | - | // warranty. | |
| 21 | - | // | |
| 22 | - | // THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS | |
| 23 | - | // SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | |
| 24 | - | // FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY | |
| 25 | - | // SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
| 26 | - | // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN | |
| 27 | - | // AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | |
| 28 | - | // ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF | |
| 29 | - | // THIS SOFTWARE. | |
| 30 | - | ||
| 31 | - | package datacontrol | |
| 32 | - | ||
| 33 | - | import ( | |
| 34 | - | "sync" | |
| 35 | - | ||
| 36 | - | cross_wl_seat "github.com/bnema/wlturbo/protocol/core" | |
| 37 | - | "github.com/bnema/wlturbo/wl" | |
| 38 | - | ) | |
| 39 | - | ||
| 40 | - | // ERROR_USED_SOURCE is the error used_source value. | |
| 41 | - | const ERROR_USED_SOURCE = 1 | |
| 42 | - | ||
| 43 | - | // ERROR_INVALID_OFFER is the error invalid_offer value. | |
| 44 | - | const ERROR_INVALID_OFFER = 1 | |
| 45 | - | ||
| 46 | - | // ExtDataControlManagerInterface is the protocol interface name. | |
| 47 | - | const ExtDataControlManagerInterface = "ext_data_control_manager_v1" | |
| 48 | - | ||
| 49 | - | // ExtDataControlManager is the generated binding for ext_data_control_manager_v1 version 1. | |
| 50 | - | type ExtDataControlManager struct { | |
| 51 | - | wl.BaseProxy | |
| 52 | - | } | |
| 53 | - | ||
| 54 | - | // NewExtDataControlManager returns an unbound ExtDataControlManager. | |
| 55 | - | func NewExtDataControlManager(ctx *wl.Context) *ExtDataControlManager { | |
| 56 | - | obj := &ExtDataControlManager{} | |
| 57 | - | obj.SetContext(ctx) | |
| 58 | - | ctx.Register(obj) | |
| 59 | - | return obj | |
| 60 | - | } | |
| 61 | - | ||
| 62 | - | // Create a new data source. | |
| 63 | - | func (o *ExtDataControlManager) CreateDataSource() (*ExtDataControlSource, error) { | |
| 64 | - | child := &ExtDataControlSource{} | |
| 65 | - | child.SetContext(o.Context()) | |
| 66 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "ext_data_control_manager_v1.create_data_source", Child: child}, wl.ArgObject(child)); err != nil { | |
| 67 | - | return nil, err | |
| 68 | - | } | |
| 69 | - | return child, nil | |
| 70 | - | } | |
| 71 | - | ||
| 72 | - | // Create a data device that can be used to manage a seat's selection. | |
| 73 | - | func (o *ExtDataControlManager) GetDataDevice(seat *cross_wl_seat.Seat) (*ExtDataControlDevice, error) { | |
| 74 | - | var arg1 wl.Object | |
| 75 | - | if seat != nil { | |
| 76 | - | arg1 = seat | |
| 77 | - | } | |
| 78 | - | child := &ExtDataControlDevice{} | |
| 79 | - | child.SetContext(o.Context()) | |
| 80 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "ext_data_control_manager_v1.get_data_device", Child: child}, wl.ArgObject(child), wl.ArgObject(arg1)); err != nil { | |
| 81 | - | return nil, err | |
| 82 | - | } | |
| 83 | - | return child, nil | |
| 84 | - | } | |
| 85 | - | ||
| 86 | - | // All objects created by the manager will still remain valid, until their appropriate destroy request has been called. | |
| 87 | - | func (o *ExtDataControlManager) Destroy() error { | |
| 88 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 2, Name: "ext_data_control_manager_v1.destroy", Destructor: true}); err != nil { | |
| 89 | - | return err | |
| 90 | - | } | |
| 91 | - | return nil | |
| 92 | - | } | |
| 93 | - | ||
| 94 | - | // EventSignature returns the declared event argument types in wire order. | |
| 95 | - | func (o *ExtDataControlManager) EventSignature(opcode uint16) (string, bool) { | |
| 96 | - | switch opcode { | |
| 97 | - | default: | |
| 98 | - | return "", false | |
| 99 | - | } | |
| 100 | - | } | |
| 101 | - | ||
| 102 | - | // Dispatch decodes one event on ext_data_control_manager_v1 and calls the registered handlers. | |
| 103 | - | func (o *ExtDataControlManager) Dispatch(event *wl.Event) { | |
| 104 | - | switch event.Opcode { | |
| 105 | - | default: | |
| 106 | - | } | |
| 107 | - | } | |
| 108 | - | ||
| 109 | - | // ExtDataControlDeviceInterface is the protocol interface name. | |
| 110 | - | const ExtDataControlDeviceInterface = "ext_data_control_device_v1" | |
| 111 | - | ||
| 112 | - | // ExtDataControlDevice is the generated binding for ext_data_control_device_v1 version 1. | |
| 113 | - | type ExtDataControlDevice struct { | |
| 114 | - | wl.BaseProxy | |
| 115 | - | // handlersMu guards the handler slices: a client may register or replace | |
| 116 | - | // handlers while another goroutine dispatches events. | |
| 117 | - | handlersMu sync.Mutex | |
| 118 | - | onDataOffer []func(idObject *ExtDataControlOffer) | |
| 119 | - | onSelection []func(idID uint32) | |
| 120 | - | onFinished []func() | |
| 121 | - | onPrimarySelection []func(idID uint32) | |
| 122 | - | } | |
| 123 | - | ||
| 124 | - | // NewExtDataControlDevice returns an unbound ExtDataControlDevice. | |
| 125 | - | func NewExtDataControlDevice(ctx *wl.Context) *ExtDataControlDevice { | |
| 126 | - | obj := &ExtDataControlDevice{} | |
| 127 | - | obj.SetContext(ctx) | |
| 128 | - | ctx.Register(obj) | |
| 129 | - | return obj | |
| 130 | - | } | |
| 131 | - | ||
| 132 | - | // 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 triggers the used_source protocol error. To unset the selection, set the source to NULL. | |
| 133 | - | func (o *ExtDataControlDevice) SetSelection(source *ExtDataControlSource) error { | |
| 134 | - | var arg0 wl.Object | |
| 135 | - | if source != nil { | |
| 136 | - | arg0 = source | |
| 137 | - | } | |
| 138 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "ext_data_control_device_v1.set_selection"}, wl.ArgObject(arg0)); err != nil { | |
| 139 | - | return err | |
| 140 | - | } | |
| 141 | - | return nil | |
| 142 | - | } | |
| 143 | - | ||
| 144 | - | // Destroys the data device object. | |
| 145 | - | func (o *ExtDataControlDevice) Destroy() error { | |
| 146 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "ext_data_control_device_v1.destroy", Destructor: true}); err != nil { | |
| 147 | - | return err | |
| 148 | - | } | |
| 149 | - | return nil | |
| 150 | - | } | |
| 151 | - | ||
| 152 | - | // 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 triggers the used_source 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. | |
| 153 | - | func (o *ExtDataControlDevice) SetPrimarySelection(source *ExtDataControlSource) error { | |
| 154 | - | var arg0 wl.Object | |
| 155 | - | if source != nil { | |
| 156 | - | arg0 = source | |
| 157 | - | } | |
| 158 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 2, Name: "ext_data_control_device_v1.set_primary_selection"}, wl.ArgObject(arg0)); err != nil { | |
| 159 | - | return err | |
| 160 | - | } | |
| 161 | - | return nil | |
| 162 | - | } | |
| 163 | - | ||
| 164 | - | // OnDataOffer registers a handler for the data_offer event. | |
| 165 | - | // | |
| 166 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 167 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 168 | - | func (o *ExtDataControlDevice) OnDataOffer(handler func(idObject *ExtDataControlOffer)) { | |
| 169 | - | if handler == nil { | |
| 170 | - | return | |
| 171 | - | } | |
| 172 | - | o.handlersMu.Lock() | |
| 173 | - | defer o.handlersMu.Unlock() | |
| 174 | - | o.onDataOffer = append(o.onDataOffer, handler) | |
| 175 | - | } | |
| 176 | - | ||
| 177 | - | // handlersForDataOffer returns the handlers registered for data_offer, taken | |
| 178 | - | // under the lock so a handler may register another handler while events are | |
| 179 | - | // being dispatched. | |
| 180 | - | func (o *ExtDataControlDevice) handlersForDataOffer() []func(idObject *ExtDataControlOffer) { | |
| 181 | - | o.handlersMu.Lock() | |
| 182 | - | defer o.handlersMu.Unlock() | |
| 183 | - | return o.onDataOffer | |
| 184 | - | } | |
| 185 | - | ||
| 186 | - | // OnSelection registers a handler for the selection event. | |
| 187 | - | // | |
| 188 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 189 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 190 | - | func (o *ExtDataControlDevice) OnSelection(handler func(idID uint32)) { | |
| 191 | - | if handler == nil { | |
| 192 | - | return | |
| 193 | - | } | |
| 194 | - | o.handlersMu.Lock() | |
| 195 | - | defer o.handlersMu.Unlock() | |
| 196 | - | o.onSelection = append(o.onSelection, handler) | |
| 197 | - | } | |
| 198 | - | ||
| 199 | - | // handlersForSelection returns the handlers registered for selection, taken | |
| 200 | - | // under the lock so a handler may register another handler while events are | |
| 201 | - | // being dispatched. | |
| 202 | - | func (o *ExtDataControlDevice) handlersForSelection() []func(idID uint32) { | |
| 203 | - | o.handlersMu.Lock() | |
| 204 | - | defer o.handlersMu.Unlock() | |
| 205 | - | return o.onSelection | |
| 206 | - | } | |
| 207 | - | ||
| 208 | - | // OnFinished registers a handler for the finished event. | |
| 209 | - | // | |
| 210 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 211 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 212 | - | func (o *ExtDataControlDevice) OnFinished(handler func()) { | |
| 213 | - | if handler == nil { | |
| 214 | - | return | |
| 215 | - | } | |
| 216 | - | o.handlersMu.Lock() | |
| 217 | - | defer o.handlersMu.Unlock() | |
| 218 | - | o.onFinished = append(o.onFinished, handler) | |
| 219 | - | } | |
| 220 | - | ||
| 221 | - | // handlersForFinished returns the handlers registered for finished, taken | |
| 222 | - | // under the lock so a handler may register another handler while events are | |
| 223 | - | // being dispatched. | |
| 224 | - | func (o *ExtDataControlDevice) handlersForFinished() []func() { | |
| 225 | - | o.handlersMu.Lock() | |
| 226 | - | defer o.handlersMu.Unlock() | |
| 227 | - | return o.onFinished | |
| 228 | - | } | |
| 229 | - | ||
| 230 | - | // OnPrimarySelection registers a handler for the primary_selection event. | |
| 231 | - | // | |
| 232 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 233 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 234 | - | func (o *ExtDataControlDevice) OnPrimarySelection(handler func(idID uint32)) { | |
| 235 | - | if handler == nil { | |
| 236 | - | return | |
| 237 | - | } | |
| 238 | - | o.handlersMu.Lock() | |
| 239 | - | defer o.handlersMu.Unlock() | |
| 240 | - | o.onPrimarySelection = append(o.onPrimarySelection, handler) | |
| 241 | - | } | |
| 242 | - | ||
| 243 | - | // handlersForPrimarySelection returns the handlers registered for primary_selection, taken | |
| 244 | - | // under the lock so a handler may register another handler while events are | |
| 245 | - | // being dispatched. | |
| 246 | - | func (o *ExtDataControlDevice) handlersForPrimarySelection() []func(idID uint32) { | |
| 247 | - | o.handlersMu.Lock() | |
| 248 | - | defer o.handlersMu.Unlock() | |
| 249 | - | return o.onPrimarySelection | |
| 250 | - | } | |
| 251 | - | ||
| 252 | - | // EventSignature returns the declared event argument types in wire order. | |
| 253 | - | func (o *ExtDataControlDevice) EventSignature(opcode uint16) (string, bool) { | |
| 254 | - | switch opcode { | |
| 255 | - | case 0: | |
| 256 | - | return "new_id,", true | |
| 257 | - | case 1: | |
| 258 | - | return "object,", true | |
| 259 | - | case 2: | |
| 260 | - | return "", true | |
| 261 | - | case 3: | |
| 262 | - | return "object,", true | |
| 263 | - | default: | |
| 264 | - | return "", false | |
| 265 | - | } | |
| 266 | - | } | |
| 267 | - | ||
| 268 | - | // Dispatch decodes one event on ext_data_control_device_v1 and calls the registered handlers. | |
| 269 | - | func (o *ExtDataControlDevice) Dispatch(event *wl.Event) { | |
| 270 | - | switch event.Opcode { | |
| 271 | - | case 0: // data_offer | |
| 272 | - | idID := event.Uint32() | |
| 273 | - | idObject := &ExtDataControlOffer{} | |
| 274 | - | idObject.SetContext(o.Context()) | |
| 275 | - | idObject.SetID(idID) | |
| 276 | - | idObject.SetVersion(o.Version()) | |
| 277 | - | o.Context().Register(idObject) | |
| 278 | - | ||
| 279 | - | for i, handler := range o.handlersForDataOffer() { | |
| 280 | - | _ = i | |
| 281 | - | handler(idObject) | |
| 282 | - | } | |
| 283 | - | case 1: // selection | |
| 284 | - | idID := event.Uint32() | |
| 285 | - | ||
| 286 | - | for i, handler := range o.handlersForSelection() { | |
| 287 | - | _ = i | |
| 288 | - | handler(idID) | |
| 289 | - | } | |
| 290 | - | case 2: // finished | |
| 291 | - | ||
| 292 | - | for i, handler := range o.handlersForFinished() { | |
| 293 | - | _ = i | |
| 294 | - | handler() | |
| 295 | - | } | |
| 296 | - | case 3: // primary_selection | |
| 297 | - | idID := event.Uint32() | |
| 298 | - | ||
| 299 | - | for i, handler := range o.handlersForPrimarySelection() { | |
| 300 | - | _ = i | |
| 301 | - | handler(idID) | |
| 302 | - | } | |
| 303 | - | default: | |
| 304 | - | } | |
| 305 | - | } | |
| 306 | - | ||
| 307 | - | // ExtDataControlSourceInterface is the protocol interface name. | |
| 308 | - | const ExtDataControlSourceInterface = "ext_data_control_source_v1" | |
| 309 | - | ||
| 310 | - | // ExtDataControlSource is the generated binding for ext_data_control_source_v1 version 1. | |
| 311 | - | type ExtDataControlSource struct { | |
| 312 | - | wl.BaseProxy | |
| 313 | - | // handlersMu guards the handler slices: a client may register or replace | |
| 314 | - | // handlers while another goroutine dispatches events. | |
| 315 | - | handlersMu sync.Mutex | |
| 316 | - | onSend []func(mimeType string, fd *wl.OwnedFD) | |
| 317 | - | onCancelled []func() | |
| 318 | - | } | |
| 319 | - | ||
| 320 | - | // NewExtDataControlSource returns an unbound ExtDataControlSource. | |
| 321 | - | func NewExtDataControlSource(ctx *wl.Context) *ExtDataControlSource { | |
| 322 | - | obj := &ExtDataControlSource{} | |
| 323 | - | obj.SetContext(ctx) | |
| 324 | - | ctx.Register(obj) | |
| 325 | - | return obj | |
| 326 | - | } | |
| 327 | - | ||
| 328 | - | // 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 ext_data_control_device.set_selection is a protocol error. | |
| 329 | - | func (o *ExtDataControlSource) Offer(mimeType string) error { | |
| 330 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "ext_data_control_source_v1.offer"}, wl.ArgString(mimeType)); err != nil { | |
| 331 | - | return err | |
| 332 | - | } | |
| 333 | - | return nil | |
| 334 | - | } | |
| 335 | - | ||
| 336 | - | // Destroys the data source object. | |
| 337 | - | func (o *ExtDataControlSource) Destroy() error { | |
| 338 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "ext_data_control_source_v1.destroy", Destructor: true}); err != nil { | |
| 339 | - | return err | |
| 340 | - | } | |
| 341 | - | return nil | |
| 342 | - | } | |
| 343 | - | ||
| 344 | - | // OnSend registers a handler for the send event. | |
| 345 | - | // | |
| 346 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 347 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 348 | - | func (o *ExtDataControlSource) OnSend(handler func(mimeType string, fd *wl.OwnedFD)) { | |
| 349 | - | if handler == nil { | |
| 350 | - | return | |
| 351 | - | } | |
| 352 | - | o.handlersMu.Lock() | |
| 353 | - | defer o.handlersMu.Unlock() | |
| 354 | - | o.onSend = append(o.onSend, handler) | |
| 355 | - | } | |
| 356 | - | ||
| 357 | - | // handlersForSend returns the handlers registered for send, taken | |
| 358 | - | // under the lock so a handler may register another handler while events are | |
| 359 | - | // being dispatched. | |
| 360 | - | func (o *ExtDataControlSource) handlersForSend() []func(mimeType string, fd *wl.OwnedFD) { | |
| 361 | - | o.handlersMu.Lock() | |
| 362 | - | defer o.handlersMu.Unlock() | |
| 363 | - | return o.onSend | |
| 364 | - | } | |
| 365 | - | ||
| 366 | - | // OnCancelled registers a handler for the cancelled event. | |
| 367 | - | // | |
| 368 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 369 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 370 | - | func (o *ExtDataControlSource) OnCancelled(handler func()) { | |
| 371 | - | if handler == nil { | |
| 372 | - | return | |
| 373 | - | } | |
| 374 | - | o.handlersMu.Lock() | |
| 375 | - | defer o.handlersMu.Unlock() | |
| 376 | - | o.onCancelled = append(o.onCancelled, handler) | |
| 377 | - | } | |
| 378 | - | ||
| 379 | - | // handlersForCancelled returns the handlers registered for cancelled, taken | |
| 380 | - | // under the lock so a handler may register another handler while events are | |
| 381 | - | // being dispatched. | |
| 382 | - | func (o *ExtDataControlSource) handlersForCancelled() []func() { | |
| 383 | - | o.handlersMu.Lock() | |
| 384 | - | defer o.handlersMu.Unlock() | |
| 385 | - | return o.onCancelled | |
| 386 | - | } | |
| 387 | - | ||
| 388 | - | // EventSignature returns the declared event argument types in wire order. | |
| 389 | - | func (o *ExtDataControlSource) EventSignature(opcode uint16) (string, bool) { | |
| 390 | - | switch opcode { | |
| 391 | - | case 0: | |
| 392 | - | return "string,fd,", true | |
| 393 | - | case 1: | |
| 394 | - | return "", true | |
| 395 | - | default: | |
| 396 | - | return "", false | |
| 397 | - | } | |
| 398 | - | } | |
| 399 | - | ||
| 400 | - | // Dispatch decodes one event on ext_data_control_source_v1 and calls the registered handlers. | |
| 401 | - | func (o *ExtDataControlSource) Dispatch(event *wl.Event) { | |
| 402 | - | switch event.Opcode { | |
| 403 | - | case 0: // send | |
| 404 | - | mimeType := event.String() | |
| 405 | - | fd := event.FD() | |
| 406 | - | ownedfd := fd | |
| 407 | - | defer ownedfd.Close() | |
| 408 | - | ||
| 409 | - | for i, handler := range o.handlersForSend() { | |
| 410 | - | if i > 0 { | |
| 411 | - | fd = nil | |
| 412 | - | } | |
| 413 | - | handler(mimeType, fd) | |
| 414 | - | } | |
| 415 | - | case 1: // cancelled | |
| 416 | - | ||
| 417 | - | for i, handler := range o.handlersForCancelled() { | |
| 418 | - | _ = i | |
| 419 | - | handler() | |
| 420 | - | } | |
| 421 | - | default: | |
| 422 | - | } | |
| 423 | - | } | |
| 424 | - | ||
| 425 | - | // ExtDataControlOfferInterface is the protocol interface name. | |
| 426 | - | const ExtDataControlOfferInterface = "ext_data_control_offer_v1" | |
| 427 | - | ||
| 428 | - | // ExtDataControlOffer is the generated binding for ext_data_control_offer_v1 version 1. | |
| 429 | - | type ExtDataControlOffer struct { | |
| 430 | - | wl.BaseProxy | |
| 431 | - | // handlersMu guards the handler slices: a client may register or replace | |
| 432 | - | // handlers while another goroutine dispatches events. | |
| 433 | - | handlersMu sync.Mutex | |
| 434 | - | onOffer []func(mimeType string) | |
| 435 | - | } | |
| 436 | - | ||
| 437 | - | // NewExtDataControlOffer returns an unbound ExtDataControlOffer. | |
| 438 | - | func NewExtDataControlOffer(ctx *wl.Context) *ExtDataControlOffer { | |
| 439 | - | obj := &ExtDataControlOffer{} | |
| 440 | - | obj.SetContext(ctx) | |
| 441 | - | ctx.Register(obj) | |
| 442 | - | return obj | |
| 443 | - | } | |
| 444 | - | ||
| 445 | - | // 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. | |
| 446 | - | func (o *ExtDataControlOffer) Receive(mimeType string, fd int) error { | |
| 447 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "ext_data_control_offer_v1.receive", FDs: []int{fd}}, wl.ArgString(mimeType), wl.ArgFD()); err != nil { | |
| 448 | - | return err | |
| 449 | - | } | |
| 450 | - | return nil | |
| 451 | - | } | |
| 452 | - | ||
| 453 | - | // Destroys the data offer object. | |
| 454 | - | func (o *ExtDataControlOffer) Destroy() error { | |
| 455 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "ext_data_control_offer_v1.destroy", Destructor: true}); err != nil { | |
| 456 | - | return err | |
| 457 | - | } | |
| 458 | - | return nil | |
| 459 | - | } | |
| 460 | - | ||
| 461 | - | // OnOffer registers a handler for the offer event. | |
| 462 | - | // | |
| 463 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 464 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 465 | - | func (o *ExtDataControlOffer) OnOffer(handler func(mimeType string)) { | |
| 466 | - | if handler == nil { | |
| 467 | - | return | |
| 468 | - | } | |
| 469 | - | o.handlersMu.Lock() | |
| 470 | - | defer o.handlersMu.Unlock() | |
| 471 | - | o.onOffer = append(o.onOffer, handler) | |
| 472 | - | } | |
| 473 | - | ||
| 474 | - | // handlersForOffer returns the handlers registered for offer, taken | |
| 475 | - | // under the lock so a handler may register another handler while events are | |
| 476 | - | // being dispatched. | |
| 477 | - | func (o *ExtDataControlOffer) handlersForOffer() []func(mimeType string) { | |
| 478 | - | o.handlersMu.Lock() | |
| 479 | - | defer o.handlersMu.Unlock() | |
| 480 | - | return o.onOffer | |
| 481 | - | } | |
| 482 | - | ||
| 483 | - | // EventSignature returns the declared event argument types in wire order. | |
| 484 | - | func (o *ExtDataControlOffer) EventSignature(opcode uint16) (string, bool) { | |
| 485 | - | switch opcode { | |
| 486 | - | case 0: | |
| 487 | - | return "string,", true | |
| 488 | - | default: | |
| 489 | - | return "", false | |
| 490 | - | } | |
| 491 | - | } | |
| 492 | - | ||
| 493 | - | // Dispatch decodes one event on ext_data_control_offer_v1 and calls the registered handlers. | |
| 494 | - | func (o *ExtDataControlOffer) Dispatch(event *wl.Event) { | |
| 495 | - | switch event.Opcode { | |
| 496 | - | case 0: // offer | |
| 497 | - | mimeType := event.String() | |
| 498 | - | ||
| 499 | - | for i, handler := range o.handlersForOffer() { | |
| 500 | - | _ = i | |
| 501 | - | handler(mimeType) | |
| 502 | - | } | |
| 503 | - | default: | |
| 504 | - | } | |
| 505 | - | } | |
D protocol/datacontrol/generate.go +0 -3
| @@ -1,3 +0,0 @@ | |||
| 1 | - | package datacontrol | |
| 2 | - | ||
| 3 | - | //go:generate go run ../../cmd/wlturbo-scanner -p datacontrol -o ext-data-control-v1_generated.go -import wl_seat=github.com/bnema/wlturbo/protocol/core ext-data-control-v1.xml | |
D protocol/drmlease/drm-lease-v1.xml +0 -317
| @@ -1,317 +0,0 @@ | |||
| 1 | - | <?xml version="1.0" encoding="UTF-8"?> | |
| 2 | - | <protocol name="drm_lease_v1"> | |
| 3 | - | <copyright> | |
| 4 | - | Copyright © 2018 NXP | |
| 5 | - | Copyright © 2019 Status Research & Development GmbH. | |
| 6 | - | Copyright © 2021 Xaver Hugl | |
| 7 | - | ||
| 8 | - | Permission is hereby granted, free of charge, to any person obtaining a | |
| 9 | - | copy of this software and associated documentation files (the "Software"), | |
| 10 | - | to deal in the Software without restriction, including without limitation | |
| 11 | - | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 12 | - | and/or sell copies of the Software, and to permit persons to whom the | |
| 13 | - | Software is furnished to do so, subject to the following conditions: | |
| 14 | - | ||
| 15 | - | The above copyright notice and this permission notice (including the next | |
| 16 | - | paragraph) shall be included in all copies or substantial portions of the | |
| 17 | - | Software. | |
| 18 | - | ||
| 19 | - | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 20 | - | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 21 | - | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 22 | - | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 23 | - | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 24 | - | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
| 25 | - | DEALINGS IN THE SOFTWARE. | |
| 26 | - | </copyright> | |
| 27 | - | ||
| 28 | - | <interface name="wp_drm_lease_device_v1" version="1"> | |
| 29 | - | <description summary="lease device"> | |
| 30 | - | This protocol is used by Wayland compositors which act as Direct | |
| 31 | - | Rendering Manager (DRM) masters to lease DRM resources to Wayland | |
| 32 | - | clients. | |
| 33 | - | ||
| 34 | - | The compositor will advertise one wp_drm_lease_device_v1 global for each | |
| 35 | - | DRM node. Some time after a client binds to the wp_drm_lease_device_v1 | |
| 36 | - | global, the compositor will send a drm_fd event followed by zero, one or | |
| 37 | - | more connector events. After all currently available connectors have been | |
| 38 | - | sent, the compositor will send a wp_drm_lease_device_v1.done event. | |
| 39 | - | ||
| 40 | - | When the list of connectors available for lease changes the compositor | |
| 41 | - | will send wp_drm_lease_device_v1.connector events for added connectors and | |
| 42 | - | wp_drm_lease_connector_v1.withdrawn events for removed connectors, | |
| 43 | - | followed by a wp_drm_lease_device_v1.done event. | |
| 44 | - | ||
| 45 | - | The compositor will indicate when a device is gone by removing the global | |
| 46 | - | via a wl_registry.global_remove event. Upon receiving this event, the | |
| 47 | - | client should destroy any matching wp_drm_lease_device_v1 object. | |
| 48 | - | ||
| 49 | - | To destroy a wp_drm_lease_device_v1 object, the client must first issue | |
| 50 | - | a release request. Upon receiving this request, the compositor will | |
| 51 | - | immediately send a released event and destroy the object. The client must | |
| 52 | - | continue to process and discard drm_fd and connector events until it | |
| 53 | - | receives the released event. Upon receiving the released event, the | |
| 54 | - | client can safely cleanup any client-side resources. | |
| 55 | - | ||
| 56 | - | Warning! The protocol described in this file is currently in the testing | |
| 57 | - | phase. Backward compatible changes may be added together with the | |
| 58 | - | corresponding interface version bump. Backward incompatible changes can | |
| 59 | - | only be done by creating a new major version of the extension. | |
| 60 | - | </description> | |
| 61 | - | ||
| 62 | - | <request name="create_lease_request"> | |
| 63 | - | <description summary="create a lease request object"> | |
| 64 | - | Creates a lease request object. | |
| 65 | - | ||
| 66 | - | See the documentation for wp_drm_lease_request_v1 for details. | |
| 67 | - | </description> | |
| 68 | - | <arg name="id" type="new_id" interface="wp_drm_lease_request_v1" /> | |
| 69 | - | </request> | |
| 70 | - | ||
| 71 | - | <request name="release"> | |
| 72 | - | <description summary="release this object"> | |
| 73 | - | Indicates the client no longer wishes to use this object. In response | |
| 74 | - | the compositor will immediately send the released event and destroy | |
| 75 | - | this object. It can however not guarantee that the client won't receive | |
| 76 | - | connector events before the released event. The client must not send any | |
| 77 | - | requests after this one, doing so will raise a wl_display error. | |
| 78 | - | Existing connectors, lease request and leases will not be affected. | |
| 79 | - | </description> | |
| 80 | - | </request> | |
| 81 | - | ||
| 82 | - | <event name="drm_fd"> | |
| 83 | - | <description summary="open a non-master fd for this DRM node"> | |
| 84 | - | The compositor will send this event when the wp_drm_lease_device_v1 | |
| 85 | - | global is bound, although there are no guarantees as to how long this | |
| 86 | - | takes - the compositor might need to wait until regaining DRM master. | |
| 87 | - | The included fd is a non-master DRM file descriptor opened for this | |
| 88 | - | device and the compositor must not authenticate it. | |
| 89 | - | The purpose of this event is to give the client the ability to | |
| 90 | - | query DRM and discover information which may help them pick the | |
| 91 | - | appropriate DRM device or select the appropriate connectors therein. | |
| 92 | - | </description> | |
| 93 | - | <arg name="fd" type="fd" summary="DRM file descriptor" /> | |
| 94 | - | </event> | |
| 95 | - | ||
| 96 | - | <event name="connector"> | |
| 97 | - | <description summary="advertise connectors available for leases"> | |
| 98 | - | The compositor will use this event to advertise connectors available for | |
| 99 | - | lease by clients. This object may be passed into a lease request to | |
| 100 | - | indicate the client would like to lease that connector, see | |
| 101 | - | wp_drm_lease_request_v1.request_connector for details. While the | |
| 102 | - | compositor will make a best effort to not send disconnected connectors, | |
| 103 | - | no guarantees can be made. | |
| 104 | - | ||
| 105 | - | The compositor must send the drm_fd event before sending connectors. | |
| 106 | - | After the drm_fd event it will send all available connectors but may | |
| 107 | - | send additional connectors at any time. | |
| 108 | - | </description> | |
| 109 | - | <arg name="id" type="new_id" interface="wp_drm_lease_connector_v1" /> | |
| 110 | - | </event> | |
| 111 | - | ||
| 112 | - | <event name="done"> | |
| 113 | - | <description summary="signals grouping of connectors"> | |
| 114 | - | The compositor will send this event to indicate that it has sent all | |
| 115 | - | currently available connectors after the client binds to the global or | |
| 116 | - | when it updates the connector list, for example on hotplug, drm master | |
| 117 | - | change or when a leased connector becomes available again. It will | |
| 118 | - | similarly send this event to group wp_drm_lease_connector_v1.withdrawn | |
| 119 | - | events of connectors of this device. | |
| 120 | - | </description> | |
| 121 | - | </event> | |
| 122 | - | ||
| 123 | - | <event name="released" type="destructor"> | |
| 124 | - | <description summary="the compositor has finished using the device"> | |
| 125 | - | This event is sent in response to the release request and indicates | |
| 126 | - | that the compositor is done sending connector events. | |
| 127 | - | The compositor will destroy this object immediately after sending the | |
| 128 | - | event and it will become invalid. The client should release any | |
| 129 | - | resources associated with this device after receiving this event. | |
| 130 | - | </description> | |
| 131 | - | </event> | |
| 132 | - | </interface> | |
| 133 | - | ||
| 134 | - | <interface name="wp_drm_lease_connector_v1" version="1"> | |
| 135 | - | <description summary="a leasable DRM connector"> | |
| 136 | - | Represents a DRM connector which is available for lease. These objects are | |
| 137 | - | created via wp_drm_lease_device_v1.connector events, and should be passed | |
| 138 | - | to lease requests via wp_drm_lease_request_v1.request_connector. | |
| 139 | - | Immediately after the wp_drm_lease_connector_v1 object is created the | |
| 140 | - | compositor will send a name, a description, a connector_id and a done | |
| 141 | - | event. When the description is updated the compositor will send a | |
| 142 | - | description event followed by a done event. | |
| 143 | - | </description> | |
| 144 | - | ||
| 145 | - | <event name="name"> | |
| 146 | - | <description summary="name"> | |
| 147 | - | The compositor sends this event once the connector is created to | |
| 148 | - | indicate the name of this connector. This will not change for the | |
| 149 | - | duration of the Wayland session, but is not guaranteed to be consistent | |
| 150 | - | between sessions. | |
| 151 | - | ||
| 152 | - | If the compositor supports wl_output version 4 and this connector | |
| 153 | - | corresponds to a wl_output, the compositor should use the same name as | |
| 154 | - | for the wl_output. | |
| 155 | - | </description> | |
| 156 | - | <arg name="name" type="string" summary="connector name" /> | |
| 157 | - | </event> | |
| 158 | - | ||
| 159 | - | <event name="description"> | |
| 160 | - | <description summary="description"> | |
| 161 | - | The compositor sends this event once the connector is created to provide | |
| 162 | - | a human-readable description for this connector, which may be presented | |
| 163 | - | to the user. The compositor may send this event multiple times over the | |
| 164 | - | lifetime of this object to reflect changes in the description. | |
| 165 | - | </description> | |
| 166 | - | <arg name="description" type="string" summary="connector description" /> | |
| 167 | - | </event> | |
| 168 | - | ||
| 169 | - | <event name="connector_id"> | |
| 170 | - | <description summary="connector_id"> | |
| 171 | - | The compositor sends this event once the connector is created to | |
| 172 | - | indicate the DRM object ID which represents the underlying connector | |
| 173 | - | that is being offered. Note that the final lease may include additional | |
| 174 | - | object IDs, such as CRTCs and planes. | |
| 175 | - | </description> | |
| 176 | - | <arg name="connector_id" type="uint" summary="DRM connector ID" /> | |
| 177 | - | </event> | |
| 178 | - | ||
| 179 | - | <event name="done"> | |
| 180 | - | <description summary="all properties have been sent"> | |
| 181 | - | This event is sent after all properties of a connector have been sent. | |
| 182 | - | This allows changes to the properties to be seen as atomic even if they | |
| 183 | - | happen via multiple events. | |
| 184 | - | </description> | |
| 185 | - | </event> | |
| 186 | - | ||
| 187 | - | <event name="withdrawn"> | |
| 188 | - | <description summary="lease offer withdrawn"> | |
| 189 | - | Sent to indicate that the compositor will no longer honor requests for | |
| 190 | - | DRM leases which include this connector. The client may still issue a | |
| 191 | - | lease request including this connector, but the compositor will send | |
| 192 | - | wp_drm_lease_v1.finished without issuing a lease fd. Compositors are | |
| 193 | - | encouraged to send this event when they lose access to connector, for | |
| 194 | - | example when the connector is hot-unplugged, when the connector gets | |
| 195 | - | leased to a client or when the compositor loses DRM master. | |
| 196 | - | ||
| 197 | - | If a client holds a lease for the connector, the status of the lease | |
| 198 | - | remains the same. The client should destroy the object after receiving | |
| 199 | - | this event. | |
| 200 | - | </description> | |
| 201 | - | </event> | |
| 202 | - | ||
| 203 | - | <request name="destroy" type="destructor"> | |
| 204 | - | <description summary="destroy connector"> | |
| 205 | - | The client may send this request to indicate that it will not use this | |
| 206 | - | connector. Clients are encouraged to send this after receiving the | |
| 207 | - | "withdrawn" event so that the server can release the resources | |
| 208 | - | associated with this connector offer. Neither existing lease requests | |
| 209 | - | nor leases will be affected. | |
| 210 | - | </description> | |
| 211 | - | </request> | |
| 212 | - | </interface> | |
| 213 | - | ||
| 214 | - | <interface name="wp_drm_lease_request_v1" version="1"> | |
| 215 | - | <description summary="DRM lease request"> | |
| 216 | - | A client that wishes to lease DRM resources will attach the list of | |
| 217 | - | connectors advertised with wp_drm_lease_device_v1.connector that they | |
| 218 | - | wish to lease, then use wp_drm_lease_request_v1.submit to submit the | |
| 219 | - | request. | |
| 220 | - | </description> | |
| 221 | - | ||
| 222 | - | <enum name="error"> | |
| 223 | - | <entry name="wrong_device" value="0" | |
| 224 | - | summary="requested a connector from a different lease device"/> | |
| 225 | - | <entry name="duplicate_connector" value="1" | |
| 226 | - | summary="requested a connector twice"/> | |
| 227 | - | <entry name="empty_lease" value="2" | |
| 228 | - | summary="requested a lease without requesting a connector"/> | |
| 229 | - | </enum> | |
| 230 | - | ||
| 231 | - | <request name="request_connector"> | |
| 232 | - | <description summary="request a connector for this lease"> | |
| 233 | - | Indicates that the client would like to lease the given connector. | |
| 234 | - | This is only used as a suggestion, the compositor may choose to | |
| 235 | - | include any resources in the lease it issues, or change the set of | |
| 236 | - | leased resources at any time. Compositors are however encouraged to | |
| 237 | - | include the requested connector and other resources necessary | |
| 238 | - | to drive the connected output in the lease. | |
| 239 | - | ||
| 240 | - | Requesting a connector that was created from a different lease device | |
| 241 | - | than this lease request raises the wrong_device error. Requesting a | |
| 242 | - | connector twice will raise the duplicate_connector error. | |
| 243 | - | </description> | |
| 244 | - | <arg name="connector" type="object" | |
| 245 | - | interface="wp_drm_lease_connector_v1" /> | |
| 246 | - | </request> | |
| 247 | - | ||
| 248 | - | <request name="submit" type="destructor"> | |
| 249 | - | <description summary="submit the lease request"> | |
| 250 | - | Submits the lease request and creates a new wp_drm_lease_v1 object. | |
| 251 | - | After calling submit the compositor will immediately destroy this | |
| 252 | - | object, issuing any more requests will cause a wl_display error. | |
| 253 | - | The compositor doesn't make any guarantees about the events of the | |
| 254 | - | lease object, clients cannot expect an immediate response. | |
| 255 | - | Not requesting any connectors before submitting the lease request | |
| 256 | - | will raise the empty_lease error. | |
| 257 | - | </description> | |
| 258 | - | <arg name="id" type="new_id" interface="wp_drm_lease_v1" /> | |
| 259 | - | </request> | |
| 260 | - | </interface> | |
| 261 | - | ||
| 262 | - | <interface name="wp_drm_lease_v1" version="1"> | |
| 263 | - | <description summary="a DRM lease"> | |
| 264 | - | A DRM lease object is used to transfer the DRM file descriptor to the | |
| 265 | - | client and manage the lifetime of the lease. | |
| 266 | - | ||
| 267 | - | Some time after the wp_drm_lease_v1 object is created, the compositor | |
| 268 | - | will reply with the lease request's result. If the lease request is | |
| 269 | - | granted, the compositor will send a lease_fd event. If the lease request | |
| 270 | - | is denied, the compositor will send a finished event without a lease_fd | |
| 271 | - | event. | |
| 272 | - | </description> | |
| 273 | - | ||
| 274 | - | <event name="lease_fd"> | |
| 275 | - | <description summary="shares the DRM file descriptor"> | |
| 276 | - | This event returns a file descriptor suitable for use with DRM-related | |
| 277 | - | ioctls. The client should use drmModeGetLease to enumerate the DRM | |
| 278 | - | objects which have been leased to them. The compositor guarantees it | |
| 279 | - | will not use the leased DRM objects itself until it sends the finished | |
| 280 | - | event. If the compositor cannot or will not grant a lease for the | |
| 281 | - | requested connectors, it will not send this event, instead sending the | |
| 282 | - | finished event. | |
| 283 | - | ||
| 284 | - | The compositor will send this event at most once during this objects | |
| 285 | - | lifetime. | |
| 286 | - | </description> | |
| 287 | - | <arg name="leased_fd" type="fd" summary="leased DRM file descriptor" /> | |
| 288 | - | </event> | |
| 289 | - | ||
| 290 | - | <event name="finished"> | |
| 291 | - | <description summary="sent when the lease has been revoked"> | |
| 292 | - | The compositor uses this event to either reject a lease request, or if | |
| 293 | - | it previously sent a lease_fd, to notify the client that the lease has | |
| 294 | - | been revoked. If the client requires a new lease, they should destroy | |
| 295 | - | this object and submit a new lease request. The compositor will send | |
| 296 | - | no further events for this object after sending the finish event. | |
| 297 | - | Compositors should revoke the lease when any of the leased resources | |
| 298 | - | become unavailable, namely when a hot-unplug occurs or when the | |
| 299 | - | compositor loses DRM master. Compositors may advertise the connector | |
| 300 | - | for leasing again, if the resource is available, by sending the | |
| 301 | - | connector event through the wp_drm_lease_device_v1 interface. | |
| 302 | - | </description> | |
| 303 | - | </event> | |
| 304 | - | ||
| 305 | - | <request name="destroy" type="destructor"> | |
| 306 | - | <description summary="destroys the lease object"> | |
| 307 | - | The client should send this to indicate that it no longer wishes to use | |
| 308 | - | this lease. The compositor should use drmModeRevokeLease on the | |
| 309 | - | appropriate file descriptor, if necessary. | |
| 310 | - | ||
| 311 | - | Upon destruction, the compositor should advertise the connector for | |
| 312 | - | leasing again by sending the connector event through the | |
| 313 | - | wp_drm_lease_device_v1 interface. | |
| 314 | - | </description> | |
| 315 | - | </request> | |
| 316 | - | </interface> | |
| 317 | - | </protocol> | |
D protocol/drmlease/drm-lease-v1_generated.go +0 -594
| @@ -1,594 +0,0 @@ | |||
| 1 | - | // Code generated by wlturbo-scanner. DO NOT EDIT. | |
| 2 | - | // Protocol: drm_lease_v1 | |
| 3 | - | // Source: drm-lease-v1.xml | |
| 4 | - | ||
| 5 | - | // Upstream protocol copyright and license: | |
| 6 | - | // Copyright © 2018 NXP | |
| 7 | - | // Copyright © 2019 Status Research & Development GmbH. | |
| 8 | - | // Copyright © 2021 Xaver Hugl | |
| 9 | - | // | |
| 10 | - | // Permission is hereby granted, free of charge, to any person obtaining a | |
| 11 | - | // copy of this software and associated documentation files (the "Software"), | |
| 12 | - | // to deal in the Software without restriction, including without limitation | |
| 13 | - | // the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 14 | - | // and/or sell copies of the Software, and to permit persons to whom the | |
| 15 | - | // Software is furnished to do so, subject to the following conditions: | |
| 16 | - | // | |
| 17 | - | // The above copyright notice and this permission notice (including the next | |
| 18 | - | // paragraph) shall be included in all copies or substantial portions of the | |
| 19 | - | // Software. | |
| 20 | - | // | |
| 21 | - | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 22 | - | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 23 | - | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 24 | - | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 25 | - | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 26 | - | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
| 27 | - | // DEALINGS IN THE SOFTWARE. | |
| 28 | - | ||
| 29 | - | package drmlease | |
| 30 | - | ||
| 31 | - | import ( | |
| 32 | - | "sync" | |
| 33 | - | ||
| 34 | - | "github.com/bnema/wlturbo/wl" | |
| 35 | - | ) | |
| 36 | - | ||
| 37 | - | // ERROR_WRONG_DEVICE is the error wrong_device value. | |
| 38 | - | const ERROR_WRONG_DEVICE = 0 | |
| 39 | - | ||
| 40 | - | // ERROR_DUPLICATE_CONNECTOR is the error duplicate_connector value. | |
| 41 | - | const ERROR_DUPLICATE_CONNECTOR = 1 | |
| 42 | - | ||
| 43 | - | // ERROR_EMPTY_LEASE is the error empty_lease value. | |
| 44 | - | const ERROR_EMPTY_LEASE = 2 | |
| 45 | - | ||
| 46 | - | // WpDrmLeaseDeviceInterface is the protocol interface name. | |
| 47 | - | const WpDrmLeaseDeviceInterface = "wp_drm_lease_device_v1" | |
| 48 | - | ||
| 49 | - | // WpDrmLeaseDevice is the generated binding for wp_drm_lease_device_v1 version 1. | |
| 50 | - | type WpDrmLeaseDevice struct { | |
| 51 | - | wl.BaseProxy | |
| 52 | - | // handlersMu guards the handler slices: a client may register or replace | |
| 53 | - | // handlers while another goroutine dispatches events. | |
| 54 | - | handlersMu sync.Mutex | |
| 55 | - | onDrmFd []func(fd *wl.OwnedFD) | |
| 56 | - | onConnector []func(idObject *WpDrmLeaseConnector) | |
| 57 | - | onDone []func() | |
| 58 | - | onReleased []func() | |
| 59 | - | } | |
| 60 | - | ||
| 61 | - | // NewWpDrmLeaseDevice returns an unbound WpDrmLeaseDevice. | |
| 62 | - | func NewWpDrmLeaseDevice(ctx *wl.Context) *WpDrmLeaseDevice { | |
| 63 | - | obj := &WpDrmLeaseDevice{} | |
| 64 | - | obj.SetContext(ctx) | |
| 65 | - | ctx.Register(obj) | |
| 66 | - | return obj | |
| 67 | - | } | |
| 68 | - | ||
| 69 | - | // Creates a lease request object. See the documentation for wp_drm_lease_request_v1 for details. | |
| 70 | - | func (o *WpDrmLeaseDevice) CreateLeaseRequest() (*WpDrmLeaseRequest, error) { | |
| 71 | - | child := &WpDrmLeaseRequest{} | |
| 72 | - | child.SetContext(o.Context()) | |
| 73 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "wp_drm_lease_device_v1.create_lease_request", Child: child}, wl.ArgObject(child)); err != nil { | |
| 74 | - | return nil, err | |
| 75 | - | } | |
| 76 | - | return child, nil | |
| 77 | - | } | |
| 78 | - | ||
| 79 | - | // 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. | |
| 80 | - | func (o *WpDrmLeaseDevice) Release() error { | |
| 81 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "wp_drm_lease_device_v1.release"}); err != nil { | |
| 82 | - | return err | |
| 83 | - | } | |
| 84 | - | return nil | |
| 85 | - | } | |
| 86 | - | ||
| 87 | - | // OnDrmFd registers a handler for the drm_fd event. | |
| 88 | - | // | |
| 89 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 90 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 91 | - | func (o *WpDrmLeaseDevice) OnDrmFd(handler func(fd *wl.OwnedFD)) { | |
| 92 | - | if handler == nil { | |
| 93 | - | return | |
| 94 | - | } | |
| 95 | - | o.handlersMu.Lock() | |
| 96 | - | defer o.handlersMu.Unlock() | |
| 97 | - | o.onDrmFd = append(o.onDrmFd, handler) | |
| 98 | - | } | |
| 99 | - | ||
| 100 | - | // handlersForDrmFd returns the handlers registered for drm_fd, taken | |
| 101 | - | // under the lock so a handler may register another handler while events are | |
| 102 | - | // being dispatched. | |
| 103 | - | func (o *WpDrmLeaseDevice) handlersForDrmFd() []func(fd *wl.OwnedFD) { | |
| 104 | - | o.handlersMu.Lock() | |
| 105 | - | defer o.handlersMu.Unlock() | |
| 106 | - | return o.onDrmFd | |
| 107 | - | } | |
| 108 | - | ||
| 109 | - | // OnConnector registers a handler for the connector event. | |
| 110 | - | // | |
| 111 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 112 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 113 | - | func (o *WpDrmLeaseDevice) OnConnector(handler func(idObject *WpDrmLeaseConnector)) { | |
| 114 | - | if handler == nil { | |
| 115 | - | return | |
| 116 | - | } | |
| 117 | - | o.handlersMu.Lock() | |
| 118 | - | defer o.handlersMu.Unlock() | |
| 119 | - | o.onConnector = append(o.onConnector, handler) | |
| 120 | - | } | |
| 121 | - | ||
| 122 | - | // handlersForConnector returns the handlers registered for connector, taken | |
| 123 | - | // under the lock so a handler may register another handler while events are | |
| 124 | - | // being dispatched. | |
| 125 | - | func (o *WpDrmLeaseDevice) handlersForConnector() []func(idObject *WpDrmLeaseConnector) { | |
| 126 | - | o.handlersMu.Lock() | |
| 127 | - | defer o.handlersMu.Unlock() | |
| 128 | - | return o.onConnector | |
| 129 | - | } | |
| 130 | - | ||
| 131 | - | // OnDone registers a handler for the done event. | |
| 132 | - | // | |
| 133 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 134 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 135 | - | func (o *WpDrmLeaseDevice) OnDone(handler func()) { | |
| 136 | - | if handler == nil { | |
| 137 | - | return | |
| 138 | - | } | |
| 139 | - | o.handlersMu.Lock() | |
| 140 | - | defer o.handlersMu.Unlock() | |
| 141 | - | o.onDone = append(o.onDone, handler) | |
| 142 | - | } | |
| 143 | - | ||
| 144 | - | // handlersForDone returns the handlers registered for done, taken | |
| 145 | - | // under the lock so a handler may register another handler while events are | |
| 146 | - | // being dispatched. | |
| 147 | - | func (o *WpDrmLeaseDevice) handlersForDone() []func() { | |
| 148 | - | o.handlersMu.Lock() | |
| 149 | - | defer o.handlersMu.Unlock() | |
| 150 | - | return o.onDone | |
| 151 | - | } | |
| 152 | - | ||
| 153 | - | // OnReleased registers a handler for the released event. | |
| 154 | - | // | |
| 155 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 156 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 157 | - | func (o *WpDrmLeaseDevice) OnReleased(handler func()) { | |
| 158 | - | if handler == nil { | |
| 159 | - | return | |
| 160 | - | } | |
| 161 | - | o.handlersMu.Lock() | |
| 162 | - | defer o.handlersMu.Unlock() | |
| 163 | - | o.onReleased = append(o.onReleased, handler) | |
| 164 | - | } | |
| 165 | - | ||
| 166 | - | // handlersForReleased returns the handlers registered for released, taken | |
| 167 | - | // under the lock so a handler may register another handler while events are | |
| 168 | - | // being dispatched. | |
| 169 | - | func (o *WpDrmLeaseDevice) handlersForReleased() []func() { | |
| 170 | - | o.handlersMu.Lock() | |
| 171 | - | defer o.handlersMu.Unlock() | |
| 172 | - | return o.onReleased | |
| 173 | - | } | |
| 174 | - | ||
| 175 | - | // EventSignature returns the declared event argument types in wire order. | |
| 176 | - | func (o *WpDrmLeaseDevice) EventSignature(opcode uint16) (string, bool) { | |
| 177 | - | switch opcode { | |
| 178 | - | case 0: | |
| 179 | - | return "fd,", true | |
| 180 | - | case 1: | |
| 181 | - | return "new_id,", true | |
| 182 | - | case 2: | |
| 183 | - | return "", true | |
| 184 | - | case 3: | |
| 185 | - | return "", true | |
| 186 | - | default: | |
| 187 | - | return "", false | |
| 188 | - | } | |
| 189 | - | } | |
| 190 | - | ||
| 191 | - | // Dispatch decodes one event on wp_drm_lease_device_v1 and calls the registered handlers. | |
| 192 | - | func (o *WpDrmLeaseDevice) Dispatch(event *wl.Event) { | |
| 193 | - | switch event.Opcode { | |
| 194 | - | case 0: // drm_fd | |
| 195 | - | fd := event.FD() | |
| 196 | - | ownedfd := fd | |
| 197 | - | defer ownedfd.Close() | |
| 198 | - | ||
| 199 | - | for i, handler := range o.handlersForDrmFd() { | |
| 200 | - | if i > 0 { | |
| 201 | - | fd = nil | |
| 202 | - | } | |
| 203 | - | handler(fd) | |
| 204 | - | } | |
| 205 | - | case 1: // connector | |
| 206 | - | idID := event.Uint32() | |
| 207 | - | idObject := &WpDrmLeaseConnector{} | |
| 208 | - | idObject.SetContext(o.Context()) | |
| 209 | - | idObject.SetID(idID) | |
| 210 | - | idObject.SetVersion(o.Version()) | |
| 211 | - | o.Context().Register(idObject) | |
| 212 | - | ||
| 213 | - | for i, handler := range o.handlersForConnector() { | |
| 214 | - | _ = i | |
| 215 | - | handler(idObject) | |
| 216 | - | } | |
| 217 | - | case 2: // done | |
| 218 | - | ||
| 219 | - | for i, handler := range o.handlersForDone() { | |
| 220 | - | _ = i | |
| 221 | - | handler() | |
| 222 | - | } | |
| 223 | - | case 3: // released | |
| 224 | - | ||
| 225 | - | for i, handler := range o.handlersForReleased() { | |
| 226 | - | _ = i | |
| 227 | - | handler() | |
| 228 | - | } | |
| 229 | - | o.Context().Unregister(o) | |
| 230 | - | default: | |
| 231 | - | } | |
| 232 | - | } | |
| 233 | - | ||
| 234 | - | // WpDrmLeaseConnectorInterface is the protocol interface name. | |
| 235 | - | const WpDrmLeaseConnectorInterface = "wp_drm_lease_connector_v1" | |
| 236 | - | ||
| 237 | - | // WpDrmLeaseConnector is the generated binding for wp_drm_lease_connector_v1 version 1. | |
| 238 | - | type WpDrmLeaseConnector struct { | |
| 239 | - | wl.BaseProxy | |
| 240 | - | // handlersMu guards the handler slices: a client may register or replace | |
| 241 | - | // handlers while another goroutine dispatches events. | |
| 242 | - | handlersMu sync.Mutex | |
| 243 | - | onName []func(name string) | |
| 244 | - | onDescription []func(description string) | |
| 245 | - | onConnectorId []func(connectorId uint32) | |
| 246 | - | onDone []func() | |
| 247 | - | onWithdrawn []func() | |
| 248 | - | } | |
| 249 | - | ||
| 250 | - | // NewWpDrmLeaseConnector returns an unbound WpDrmLeaseConnector. | |
| 251 | - | func NewWpDrmLeaseConnector(ctx *wl.Context) *WpDrmLeaseConnector { | |
| 252 | - | obj := &WpDrmLeaseConnector{} | |
| 253 | - | obj.SetContext(ctx) | |
| 254 | - | ctx.Register(obj) | |
| 255 | - | return obj | |
| 256 | - | } | |
| 257 | - | ||
| 258 | - | // 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. | |
| 259 | - | func (o *WpDrmLeaseConnector) Destroy() error { | |
| 260 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "wp_drm_lease_connector_v1.destroy", Destructor: true}); err != nil { | |
| 261 | - | return err | |
| 262 | - | } | |
| 263 | - | return nil | |
| 264 | - | } | |
| 265 | - | ||
| 266 | - | // OnName registers a handler for the name event. | |
| 267 | - | // | |
| 268 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 269 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 270 | - | func (o *WpDrmLeaseConnector) OnName(handler func(name string)) { | |
| 271 | - | if handler == nil { | |
| 272 | - | return | |
| 273 | - | } | |
| 274 | - | o.handlersMu.Lock() | |
| 275 | - | defer o.handlersMu.Unlock() | |
| 276 | - | o.onName = append(o.onName, handler) | |
| 277 | - | } | |
| 278 | - | ||
| 279 | - | // handlersForName returns the handlers registered for name, taken | |
| 280 | - | // under the lock so a handler may register another handler while events are | |
| 281 | - | // being dispatched. | |
| 282 | - | func (o *WpDrmLeaseConnector) handlersForName() []func(name string) { | |
| 283 | - | o.handlersMu.Lock() | |
| 284 | - | defer o.handlersMu.Unlock() | |
| 285 | - | return o.onName | |
| 286 | - | } | |
| 287 | - | ||
| 288 | - | // OnDescription registers a handler for the description event. | |
| 289 | - | // | |
| 290 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 291 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 292 | - | func (o *WpDrmLeaseConnector) OnDescription(handler func(description string)) { | |
| 293 | - | if handler == nil { | |
| 294 | - | return | |
| 295 | - | } | |
| 296 | - | o.handlersMu.Lock() | |
| 297 | - | defer o.handlersMu.Unlock() | |
| 298 | - | o.onDescription = append(o.onDescription, handler) | |
| 299 | - | } | |
| 300 | - | ||
| 301 | - | // handlersForDescription returns the handlers registered for description, taken | |
| 302 | - | // under the lock so a handler may register another handler while events are | |
| 303 | - | // being dispatched. | |
| 304 | - | func (o *WpDrmLeaseConnector) handlersForDescription() []func(description string) { | |
| 305 | - | o.handlersMu.Lock() | |
| 306 | - | defer o.handlersMu.Unlock() | |
| 307 | - | return o.onDescription | |
| 308 | - | } | |
| 309 | - | ||
| 310 | - | // OnConnectorId registers a handler for the connector_id event. | |
| 311 | - | // | |
| 312 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 313 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 314 | - | func (o *WpDrmLeaseConnector) OnConnectorId(handler func(connectorId uint32)) { | |
| 315 | - | if handler == nil { | |
| 316 | - | return | |
| 317 | - | } | |
| 318 | - | o.handlersMu.Lock() | |
| 319 | - | defer o.handlersMu.Unlock() | |
| 320 | - | o.onConnectorId = append(o.onConnectorId, handler) | |
| 321 | - | } | |
| 322 | - | ||
| 323 | - | // handlersForConnectorId returns the handlers registered for connector_id, taken | |
| 324 | - | // under the lock so a handler may register another handler while events are | |
| 325 | - | // being dispatched. | |
| 326 | - | func (o *WpDrmLeaseConnector) handlersForConnectorId() []func(connectorId uint32) { | |
| 327 | - | o.handlersMu.Lock() | |
| 328 | - | defer o.handlersMu.Unlock() | |
| 329 | - | return o.onConnectorId | |
| 330 | - | } | |
| 331 | - | ||
| 332 | - | // OnDone registers a handler for the done event. | |
| 333 | - | // | |
| 334 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 335 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 336 | - | func (o *WpDrmLeaseConnector) OnDone(handler func()) { | |
| 337 | - | if handler == nil { | |
| 338 | - | return | |
| 339 | - | } | |
| 340 | - | o.handlersMu.Lock() | |
| 341 | - | defer o.handlersMu.Unlock() | |
| 342 | - | o.onDone = append(o.onDone, handler) | |
| 343 | - | } | |
| 344 | - | ||
| 345 | - | // handlersForDone returns the handlers registered for done, taken | |
| 346 | - | // under the lock so a handler may register another handler while events are | |
| 347 | - | // being dispatched. | |
| 348 | - | func (o *WpDrmLeaseConnector) handlersForDone() []func() { | |
| 349 | - | o.handlersMu.Lock() | |
| 350 | - | defer o.handlersMu.Unlock() | |
| 351 | - | return o.onDone | |
| 352 | - | } | |
| 353 | - | ||
| 354 | - | // OnWithdrawn registers a handler for the withdrawn event. | |
| 355 | - | // | |
| 356 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 357 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 358 | - | func (o *WpDrmLeaseConnector) OnWithdrawn(handler func()) { | |
| 359 | - | if handler == nil { | |
| 360 | - | return | |
| 361 | - | } | |
| 362 | - | o.handlersMu.Lock() | |
| 363 | - | defer o.handlersMu.Unlock() | |
| 364 | - | o.onWithdrawn = append(o.onWithdrawn, handler) | |
| 365 | - | } | |
| 366 | - | ||
| 367 | - | // handlersForWithdrawn returns the handlers registered for withdrawn, taken | |
| 368 | - | // under the lock so a handler may register another handler while events are | |
| 369 | - | // being dispatched. | |
| 370 | - | func (o *WpDrmLeaseConnector) handlersForWithdrawn() []func() { | |
| 371 | - | o.handlersMu.Lock() | |
| 372 | - | defer o.handlersMu.Unlock() | |
| 373 | - | return o.onWithdrawn | |
| 374 | - | } | |
| 375 | - | ||
| 376 | - | // EventSignature returns the declared event argument types in wire order. | |
| 377 | - | func (o *WpDrmLeaseConnector) EventSignature(opcode uint16) (string, bool) { | |
| 378 | - | switch opcode { | |
| 379 | - | case 0: | |
| 380 | - | return "string,", true | |
| 381 | - | case 1: | |
| 382 | - | return "string,", true | |
| 383 | - | case 2: | |
| 384 | - | return "uint,", true | |
| 385 | - | case 3: | |
| 386 | - | return "", true | |
| 387 | - | case 4: | |
| 388 | - | return "", true | |
| 389 | - | default: | |
| 390 | - | return "", false | |
| 391 | - | } | |
| 392 | - | } | |
| 393 | - | ||
| 394 | - | // Dispatch decodes one event on wp_drm_lease_connector_v1 and calls the registered handlers. | |
| 395 | - | func (o *WpDrmLeaseConnector) Dispatch(event *wl.Event) { | |
| 396 | - | switch event.Opcode { | |
| 397 | - | case 0: // name | |
| 398 | - | name := event.String() | |
| 399 | - | ||
| 400 | - | for i, handler := range o.handlersForName() { | |
| 401 | - | _ = i | |
| 402 | - | handler(name) | |
| 403 | - | } | |
| 404 | - | case 1: // description | |
| 405 | - | description := event.String() | |
| 406 | - | ||
| 407 | - | for i, handler := range o.handlersForDescription() { | |
| 408 | - | _ = i | |
| 409 | - | handler(description) | |
| 410 | - | } | |
| 411 | - | case 2: // connector_id | |
| 412 | - | connectorId := event.Uint32() | |
| 413 | - | ||
| 414 | - | for i, handler := range o.handlersForConnectorId() { | |
| 415 | - | _ = i | |
| 416 | - | handler(connectorId) | |
| 417 | - | } | |
| 418 | - | case 3: // done | |
| 419 | - | ||
| 420 | - | for i, handler := range o.handlersForDone() { | |
| 421 | - | _ = i | |
| 422 | - | handler() | |
| 423 | - | } | |
| 424 | - | case 4: // withdrawn | |
| 425 | - | ||
| 426 | - | for i, handler := range o.handlersForWithdrawn() { | |
| 427 | - | _ = i | |
| 428 | - | handler() | |
| 429 | - | } | |
| 430 | - | default: | |
| 431 | - | } | |
| 432 | - | } | |
| 433 | - | ||
| 434 | - | // WpDrmLeaseRequestInterface is the protocol interface name. | |
| 435 | - | const WpDrmLeaseRequestInterface = "wp_drm_lease_request_v1" | |
| 436 | - | ||
| 437 | - | // WpDrmLeaseRequest is the generated binding for wp_drm_lease_request_v1 version 1. | |
| 438 | - | type WpDrmLeaseRequest struct { | |
| 439 | - | wl.BaseProxy | |
| 440 | - | } | |
| 441 | - | ||
| 442 | - | // NewWpDrmLeaseRequest returns an unbound WpDrmLeaseRequest. | |
| 443 | - | func NewWpDrmLeaseRequest(ctx *wl.Context) *WpDrmLeaseRequest { | |
| 444 | - | obj := &WpDrmLeaseRequest{} | |
| 445 | - | obj.SetContext(ctx) | |
| 446 | - | ctx.Register(obj) | |
| 447 | - | return obj | |
| 448 | - | } | |
| 449 | - | ||
| 450 | - | // 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. | |
| 451 | - | func (o *WpDrmLeaseRequest) RequestConnector(connector *WpDrmLeaseConnector) error { | |
| 452 | - | var arg0 wl.Object | |
| 453 | - | if connector != nil { | |
| 454 | - | arg0 = connector | |
| 455 | - | } | |
| 456 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "wp_drm_lease_request_v1.request_connector"}, wl.ArgObject(arg0)); err != nil { | |
| 457 | - | return err | |
| 458 | - | } | |
| 459 | - | return nil | |
| 460 | - | } | |
| 461 | - | ||
| 462 | - | // 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_display 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. | |
| 463 | - | func (o *WpDrmLeaseRequest) Submit() (*WpDrmLease, error) { | |
| 464 | - | child := &WpDrmLease{} | |
| 465 | - | child.SetContext(o.Context()) | |
| 466 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "wp_drm_lease_request_v1.submit", Destructor: true, Child: child}, wl.ArgObject(child)); err != nil { | |
| 467 | - | return nil, err | |
| 468 | - | } | |
| 469 | - | return child, nil | |
| 470 | - | } | |
| 471 | - | ||
| 472 | - | // EventSignature returns the declared event argument types in wire order. | |
| 473 | - | func (o *WpDrmLeaseRequest) EventSignature(opcode uint16) (string, bool) { | |
| 474 | - | switch opcode { | |
| 475 | - | default: | |
| 476 | - | return "", false | |
| 477 | - | } | |
| 478 | - | } | |
| 479 | - | ||
| 480 | - | // Dispatch decodes one event on wp_drm_lease_request_v1 and calls the registered handlers. | |
| 481 | - | func (o *WpDrmLeaseRequest) Dispatch(event *wl.Event) { | |
| 482 | - | switch event.Opcode { | |
| 483 | - | default: | |
| 484 | - | } | |
| 485 | - | } | |
| 486 | - | ||
| 487 | - | // WpDrmLeaseInterface is the protocol interface name. | |
| 488 | - | const WpDrmLeaseInterface = "wp_drm_lease_v1" | |
| 489 | - | ||
| 490 | - | // WpDrmLease is the generated binding for wp_drm_lease_v1 version 1. | |
| 491 | - | type WpDrmLease struct { | |
| 492 | - | wl.BaseProxy | |
| 493 | - | // handlersMu guards the handler slices: a client may register or replace | |
| 494 | - | // handlers while another goroutine dispatches events. | |
| 495 | - | handlersMu sync.Mutex | |
| 496 | - | onLeaseFd []func(leasedFd *wl.OwnedFD) | |
| 497 | - | onFinished []func() | |
| 498 | - | } | |
| 499 | - | ||
| 500 | - | // NewWpDrmLease returns an unbound WpDrmLease. | |
| 501 | - | func NewWpDrmLease(ctx *wl.Context) *WpDrmLease { | |
| 502 | - | obj := &WpDrmLease{} | |
| 503 | - | obj.SetContext(ctx) | |
| 504 | - | ctx.Register(obj) | |
| 505 | - | return obj | |
| 506 | - | } | |
| 507 | - | ||
| 508 | - | // 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. Upon destruction, the compositor should advertise the connector for leasing again by sending the connector event through the wp_drm_lease_device_v1 interface. | |
| 509 | - | func (o *WpDrmLease) Destroy() error { | |
| 510 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "wp_drm_lease_v1.destroy", Destructor: true}); err != nil { | |
| 511 | - | return err | |
| 512 | - | } | |
| 513 | - | return nil | |
| 514 | - | } | |
| 515 | - | ||
| 516 | - | // OnLeaseFd registers a handler for the lease_fd event. | |
| 517 | - | // | |
| 518 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 519 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 520 | - | func (o *WpDrmLease) OnLeaseFd(handler func(leasedFd *wl.OwnedFD)) { | |
| 521 | - | if handler == nil { | |
| 522 | - | return | |
| 523 | - | } | |
| 524 | - | o.handlersMu.Lock() | |
| 525 | - | defer o.handlersMu.Unlock() | |
| 526 | - | o.onLeaseFd = append(o.onLeaseFd, handler) | |
| 527 | - | } | |
| 528 | - | ||
| 529 | - | // handlersForLeaseFd returns the handlers registered for lease_fd, taken | |
| 530 | - | // under the lock so a handler may register another handler while events are | |
| 531 | - | // being dispatched. | |
| 532 | - | func (o *WpDrmLease) handlersForLeaseFd() []func(leasedFd *wl.OwnedFD) { | |
| 533 | - | o.handlersMu.Lock() | |
| 534 | - | defer o.handlersMu.Unlock() | |
| 535 | - | return o.onLeaseFd | |
| 536 | - | } | |
| 537 | - | ||
| 538 | - | // OnFinished registers a handler for the finished event. | |
| 539 | - | // | |
| 540 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 541 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 542 | - | func (o *WpDrmLease) OnFinished(handler func()) { | |
| 543 | - | if handler == nil { | |
| 544 | - | return | |
| 545 | - | } | |
| 546 | - | o.handlersMu.Lock() | |
| 547 | - | defer o.handlersMu.Unlock() | |
| 548 | - | o.onFinished = append(o.onFinished, handler) | |
| 549 | - | } | |
| 550 | - | ||
| 551 | - | // handlersForFinished returns the handlers registered for finished, taken | |
| 552 | - | // under the lock so a handler may register another handler while events are | |
| 553 | - | // being dispatched. | |
| 554 | - | func (o *WpDrmLease) handlersForFinished() []func() { | |
| 555 | - | o.handlersMu.Lock() | |
| 556 | - | defer o.handlersMu.Unlock() | |
| 557 | - | return o.onFinished | |
| 558 | - | } | |
| 559 | - | ||
| 560 | - | // EventSignature returns the declared event argument types in wire order. | |
| 561 | - | func (o *WpDrmLease) EventSignature(opcode uint16) (string, bool) { | |
| 562 | - | switch opcode { | |
| 563 | - | case 0: | |
| 564 | - | return "fd,", true | |
| 565 | - | case 1: | |
| 566 | - | return "", true | |
| 567 | - | default: | |
| 568 | - | return "", false | |
| 569 | - | } | |
| 570 | - | } | |
| 571 | - | ||
| 572 | - | // Dispatch decodes one event on wp_drm_lease_v1 and calls the registered handlers. | |
| 573 | - | func (o *WpDrmLease) Dispatch(event *wl.Event) { | |
| 574 | - | switch event.Opcode { | |
| 575 | - | case 0: // lease_fd | |
| 576 | - | leasedFd := event.FD() | |
| 577 | - | ownedleasedFd := leasedFd | |
| 578 | - | defer ownedleasedFd.Close() | |
| 579 | - | ||
| 580 | - | for i, handler := range o.handlersForLeaseFd() { | |
| 581 | - | if i > 0 { | |
| 582 | - | leasedFd = nil | |
| 583 | - | } | |
| 584 | - | handler(leasedFd) | |
| 585 | - | } | |
| 586 | - | case 1: // finished | |
| 587 | - | ||
| 588 | - | for i, handler := range o.handlersForFinished() { | |
| 589 | - | _ = i | |
| 590 | - | handler() | |
| 591 | - | } | |
| 592 | - | default: | |
| 593 | - | } | |
| 594 | - | } | |
D protocol/drmlease/generate.go +0 -3
| @@ -1,3 +0,0 @@ | |||
| 1 | - | package drmlease | |
| 2 | - | ||
| 3 | - | //go:generate go run ../../cmd/wlturbo-scanner -p drmlease -o drm-lease-v1_generated.go drm-lease-v1.xml | |
D protocol/drmsyncobj/linux-drm-syncobj-v1.xml +0 -261
| @@ -1,261 +0,0 @@ | |||
| 1 | - | <?xml version="1.0" encoding="UTF-8"?> | |
| 2 | - | <protocol name="linux_drm_syncobj_v1"> | |
| 3 | - | <copyright> | |
| 4 | - | Copyright 2016 The Chromium Authors. | |
| 5 | - | Copyright 2017 Intel Corporation | |
| 6 | - | Copyright 2018 Collabora, Ltd | |
| 7 | - | Copyright 2021 Simon Ser | |
| 8 | - | ||
| 9 | - | Permission is hereby granted, free of charge, to any person obtaining a | |
| 10 | - | copy of this software and associated documentation files (the "Software"), | |
| 11 | - | to deal in the Software without restriction, including without limitation | |
| 12 | - | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 13 | - | and/or sell copies of the Software, and to permit persons to whom the | |
| 14 | - | Software is furnished to do so, subject to the following conditions: | |
| 15 | - | ||
| 16 | - | The above copyright notice and this permission notice (including the next | |
| 17 | - | paragraph) shall be included in all copies or substantial portions of the | |
| 18 | - | Software. | |
| 19 | - | ||
| 20 | - | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 21 | - | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 22 | - | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 23 | - | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 24 | - | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 25 | - | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
| 26 | - | DEALINGS IN THE SOFTWARE. | |
| 27 | - | </copyright> | |
| 28 | - | ||
| 29 | - | <description summary="protocol for providing explicit synchronization"> | |
| 30 | - | This protocol allows clients to request explicit synchronization for | |
| 31 | - | buffers. It is tied to the Linux DRM synchronization object framework. | |
| 32 | - | ||
| 33 | - | Synchronization refers to co-ordination of pipelined operations performed | |
| 34 | - | on buffers. Most GPU clients will schedule an asynchronous operation to | |
| 35 | - | render to the buffer, then immediately send the buffer to the compositor | |
| 36 | - | to be attached to a surface. | |
| 37 | - | ||
| 38 | - | With implicit synchronization, ensuring that the rendering operation is | |
| 39 | - | complete before the compositor displays the buffer is an implementation | |
| 40 | - | detail handled by either the kernel or userspace graphics driver. | |
| 41 | - | ||
| 42 | - | By contrast, with explicit synchronization, DRM synchronization object | |
| 43 | - | timeline points mark when the asynchronous operations are complete. When | |
| 44 | - | submitting a buffer, the client provides a timeline point which will be | |
| 45 | - | waited on before the compositor accesses the buffer, and another timeline | |
| 46 | - | point that the compositor will signal when it no longer needs to access the | |
| 47 | - | buffer contents for the purposes of the surface commit. | |
| 48 | - | ||
| 49 | - | Linux DRM synchronization objects are documented at: | |
| 50 | - | https://dri.freedesktop.org/docs/drm/gpu/drm-mm.html#drm-sync-objects | |
| 51 | - | ||
| 52 | - | Warning! The protocol described in this file is currently in the testing | |
| 53 | - | phase. Backward compatible changes may be added together with the | |
| 54 | - | corresponding interface version bump. Backward incompatible changes can | |
| 55 | - | only be done by creating a new major version of the extension. | |
| 56 | - | </description> | |
| 57 | - | ||
| 58 | - | <interface name="wp_linux_drm_syncobj_manager_v1" version="1"> | |
| 59 | - | <description summary="global for providing explicit synchronization"> | |
| 60 | - | This global is a factory interface, allowing clients to request | |
| 61 | - | explicit synchronization for buffers on a per-surface basis. | |
| 62 | - | ||
| 63 | - | See wp_linux_drm_syncobj_surface_v1 for more information. | |
| 64 | - | </description> | |
| 65 | - | ||
| 66 | - | <request name="destroy" type="destructor"> | |
| 67 | - | <description summary="destroy explicit synchronization factory object"> | |
| 68 | - | Destroy this explicit synchronization factory object. Other objects | |
| 69 | - | shall not be affected by this request. | |
| 70 | - | </description> | |
| 71 | - | </request> | |
| 72 | - | ||
| 73 | - | <enum name="error"> | |
| 74 | - | <entry name="surface_exists" value="0" | |
| 75 | - | summary="the surface already has a synchronization object associated"/> | |
| 76 | - | <entry name="invalid_timeline" value="1" | |
| 77 | - | summary="the timeline object could not be imported"/> | |
| 78 | - | </enum> | |
| 79 | - | ||
| 80 | - | <request name="get_surface"> | |
| 81 | - | <description summary="extend surface interface for explicit synchronization"> | |
| 82 | - | Instantiate an interface extension for the given wl_surface to provide | |
| 83 | - | explicit synchronization. | |
| 84 | - | ||
| 85 | - | If the given wl_surface already has an explicit synchronization object | |
| 86 | - | associated, the surface_exists protocol error is raised. | |
| 87 | - | ||
| 88 | - | Graphics APIs, like EGL or Vulkan, that manage the buffer queue and | |
| 89 | - | commits of a wl_surface themselves, are likely to be using this | |
| 90 | - | extension internally. If a client is using such an API for a | |
| 91 | - | wl_surface, it should not directly use this extension on that surface, | |
| 92 | - | to avoid raising a surface_exists protocol error. | |
| 93 | - | </description> | |
| 94 | - | <arg name="id" type="new_id" interface="wp_linux_drm_syncobj_surface_v1" | |
| 95 | - | summary="the new synchronization surface object id"/> | |
| 96 | - | <arg name="surface" type="object" interface="wl_surface" | |
| 97 | - | summary="the surface"/> | |
| 98 | - | </request> | |
| 99 | - | ||
| 100 | - | <request name="import_timeline"> | |
| 101 | - | <description summary="import a DRM syncobj timeline"> | |
| 102 | - | Import a DRM synchronization object timeline. | |
| 103 | - | ||
| 104 | - | If the FD cannot be imported, the invalid_timeline error is raised. | |
| 105 | - | </description> | |
| 106 | - | <arg name="id" type="new_id" interface="wp_linux_drm_syncobj_timeline_v1"/> | |
| 107 | - | <arg name="fd" type="fd" summary="drm_syncobj file descriptor"/> | |
| 108 | - | </request> | |
| 109 | - | </interface> | |
| 110 | - | ||
| 111 | - | <interface name="wp_linux_drm_syncobj_timeline_v1" version="1"> | |
| 112 | - | <description summary="synchronization object timeline"> | |
| 113 | - | This object represents an explicit synchronization object timeline | |
| 114 | - | imported by the client to the compositor. | |
| 115 | - | </description> | |
| 116 | - | ||
| 117 | - | <request name="destroy" type="destructor"> | |
| 118 | - | <description summary="destroy the timeline"> | |
| 119 | - | Destroy the synchronization object timeline. Other objects are not | |
| 120 | - | affected by this request, in particular timeline points set by | |
| 121 | - | set_acquire_point and set_release_point are not unset. | |
| 122 | - | </description> | |
| 123 | - | </request> | |
| 124 | - | </interface> | |
| 125 | - | ||
| 126 | - | <interface name="wp_linux_drm_syncobj_surface_v1" version="1"> | |
| 127 | - | <description summary="per-surface explicit synchronization"> | |
| 128 | - | This object is an add-on interface for wl_surface to enable explicit | |
| 129 | - | synchronization. | |
| 130 | - | ||
| 131 | - | Each surface can be associated with only one object of this interface at | |
| 132 | - | any time. | |
| 133 | - | ||
| 134 | - | Explicit synchronization is guaranteed to be supported for buffers | |
| 135 | - | created with any version of the linux-dmabuf protocol. Compositors are | |
| 136 | - | free to support explicit synchronization for additional buffer types. | |
| 137 | - | If at surface commit time the attached buffer does not support explicit | |
| 138 | - | synchronization, an unsupported_buffer error is raised. | |
| 139 | - | ||
| 140 | - | As long as the wp_linux_drm_syncobj_surface_v1 object is alive, the | |
| 141 | - | compositor may ignore implicit synchronization for buffers attached and | |
| 142 | - | committed to the wl_surface. The delivery of wl_buffer.release events | |
| 143 | - | for buffers attached to the surface becomes undefined. | |
| 144 | - | ||
| 145 | - | Clients must set both acquire and release points if and only if a | |
| 146 | - | non-null buffer is attached in the same surface commit. See the | |
| 147 | - | no_buffer, no_acquire_point and no_release_point protocol errors. | |
| 148 | - | ||
| 149 | - | If at surface commit time the acquire and release DRM syncobj timelines | |
| 150 | - | are identical, the acquire point value must be strictly less than the | |
| 151 | - | release point value, or else the conflicting_points protocol error is | |
| 152 | - | raised. | |
| 153 | - | </description> | |
| 154 | - | ||
| 155 | - | <request name="destroy" type="destructor"> | |
| 156 | - | <description summary="destroy the surface synchronization object"> | |
| 157 | - | Destroy this surface synchronization object. | |
| 158 | - | ||
| 159 | - | Any timeline point set by this object with set_acquire_point or | |
| 160 | - | set_release_point since the last commit may be discarded by the | |
| 161 | - | compositor. Any timeline point set by this object before the last | |
| 162 | - | commit will not be affected. | |
| 163 | - | </description> | |
| 164 | - | </request> | |
| 165 | - | ||
| 166 | - | <enum name="error"> | |
| 167 | - | <entry name="no_surface" value="1" | |
| 168 | - | summary="the associated wl_surface was destroyed"/> | |
| 169 | - | <entry name="unsupported_buffer" value="2" | |
| 170 | - | summary="the buffer does not support explicit synchronization"/> | |
| 171 | - | <entry name="no_buffer" value="3" summary="no buffer was attached"/> | |
| 172 | - | <entry name="no_acquire_point" value="4" | |
| 173 | - | summary="no acquire timeline point was set"/> | |
| 174 | - | <entry name="no_release_point" value="5" | |
| 175 | - | summary="no release timeline point was set"/> | |
| 176 | - | <entry name="conflicting_points" value="6" | |
| 177 | - | summary="acquire and release timeline points are in conflict"/> | |
| 178 | - | </enum> | |
| 179 | - | ||
| 180 | - | <request name="set_acquire_point"> | |
| 181 | - | <description summary="set the acquire timeline point"> | |
| 182 | - | Set the timeline point that must be signalled before the compositor may | |
| 183 | - | sample from the buffer attached with wl_surface.attach. | |
| 184 | - | ||
| 185 | - | The 64-bit unsigned value combined from point_hi and point_lo is the | |
| 186 | - | point value. | |
| 187 | - | ||
| 188 | - | The acquire point is double-buffered state, and will be applied on the | |
| 189 | - | next wl_surface.commit request for the associated surface. Thus, it | |
| 190 | - | applies only to the buffer that is attached to the surface at commit | |
| 191 | - | time. | |
| 192 | - | ||
| 193 | - | If an acquire point has already been attached during the same commit | |
| 194 | - | cycle, the new point replaces the old one. | |
| 195 | - | ||
| 196 | - | If the associated wl_surface was destroyed, a no_surface error is | |
| 197 | - | raised. | |
| 198 | - | ||
| 199 | - | If at surface commit time there is a pending acquire timeline point set | |
| 200 | - | but no pending buffer attached, a no_buffer error is raised. If at | |
| 201 | - | surface commit time there is a pending buffer attached but no pending | |
| 202 | - | acquire timeline point set, the no_acquire_point protocol error is | |
| 203 | - | raised. | |
| 204 | - | </description> | |
| 205 | - | <arg name="timeline" type="object" interface="wp_linux_drm_syncobj_timeline_v1"/> | |
| 206 | - | <arg name="point_hi" type="uint" summary="high 32 bits of the point value"/> | |
| 207 | - | <arg name="point_lo" type="uint" summary="low 32 bits of the point value"/> | |
| 208 | - | </request> | |
| 209 | - | ||
| 210 | - | <request name="set_release_point"> | |
| 211 | - | <description summary="set the release timeline point"> | |
| 212 | - | Set the timeline point that must be signalled by the compositor when it | |
| 213 | - | has finished its usage of the buffer attached with wl_surface.attach | |
| 214 | - | for the relevant commit. | |
| 215 | - | ||
| 216 | - | Once the timeline point is signaled, and assuming the associated buffer | |
| 217 | - | is not pending release from other wl_surface.commit requests, no | |
| 218 | - | additional explicit or implicit synchronization with the compositor is | |
| 219 | - | required to safely re-use the buffer. | |
| 220 | - | ||
| 221 | - | Note that clients cannot rely on the release point being always | |
| 222 | - | signaled after the acquire point: compositors may release buffers | |
| 223 | - | without ever reading from them. In addition, the compositor may use | |
| 224 | - | different presentation paths for different commits, which may have | |
| 225 | - | different release behavior. As a result, the compositor may signal the | |
| 226 | - | release points in a different order than the client committed them. | |
| 227 | - | ||
| 228 | - | Because signaling a timeline point also signals every previous point, | |
| 229 | - | it is generally not safe to use the same timeline object for the | |
| 230 | - | release points of multiple buffers. The out-of-order signaling | |
| 231 | - | described above may lead to a release point being signaled before the | |
| 232 | - | compositor has finished reading. To avoid this, it is strongly | |
| 233 | - | recommended that each buffer should use a separate timeline for its | |
| 234 | - | release points. | |
| 235 | - | ||
| 236 | - | The 64-bit unsigned value combined from point_hi and point_lo is the | |
| 237 | - | point value. | |
| 238 | - | ||
| 239 | - | The release point is double-buffered state, and will be applied on the | |
| 240 | - | next wl_surface.commit request for the associated surface. Thus, it | |
| 241 | - | applies only to the buffer that is attached to the surface at commit | |
| 242 | - | time. | |
| 243 | - | ||
| 244 | - | If a release point has already been attached during the same commit | |
| 245 | - | cycle, the new point replaces the old one. | |
| 246 | - | ||
| 247 | - | If the associated wl_surface was destroyed, a no_surface error is | |
| 248 | - | raised. | |
| 249 | - | ||
| 250 | - | If at surface commit time there is a pending release timeline point set | |
| 251 | - | but no pending buffer attached, a no_buffer error is raised. If at | |
| 252 | - | surface commit time there is a pending buffer attached but no pending | |
| 253 | - | release timeline point set, the no_release_point protocol error is | |
| 254 | - | raised. | |
| 255 | - | </description> | |
| 256 | - | <arg name="timeline" type="object" interface="wp_linux_drm_syncobj_timeline_v1"/> | |
| 257 | - | <arg name="point_hi" type="uint" summary="high 32 bits of the point value"/> | |
| 258 | - | <arg name="point_lo" type="uint" summary="low 32 bits of the point value"/> | |
| 259 | - | </request> | |
| 260 | - | </interface> | |
| 261 | - | </protocol> | |
D protocol/drmsyncobj/linux-drm-syncobj-v1_generated.go +0 -224
| @@ -1,224 +0,0 @@ | |||
| 1 | - | // Code generated by wlturbo-scanner. DO NOT EDIT. | |
| 2 | - | // Protocol: linux_drm_syncobj_v1 | |
| 3 | - | // Source: linux-drm-syncobj-v1.xml | |
| 4 | - | ||
| 5 | - | // Upstream protocol copyright and license: | |
| 6 | - | // Copyright 2016 The Chromium Authors. | |
| 7 | - | // Copyright 2017 Intel Corporation | |
| 8 | - | // Copyright 2018 Collabora, Ltd | |
| 9 | - | // Copyright 2021 Simon Ser | |
| 10 | - | // | |
| 11 | - | // Permission is hereby granted, free of charge, to any person obtaining a | |
| 12 | - | // copy of this software and associated documentation files (the "Software"), | |
| 13 | - | // to deal in the Software without restriction, including without limitation | |
| 14 | - | // the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 15 | - | // and/or sell copies of the Software, and to permit persons to whom the | |
| 16 | - | // Software is furnished to do so, subject to the following conditions: | |
| 17 | - | // | |
| 18 | - | // The above copyright notice and this permission notice (including the next | |
| 19 | - | // paragraph) shall be included in all copies or substantial portions of the | |
| 20 | - | // Software. | |
| 21 | - | // | |
| 22 | - | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 23 | - | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 24 | - | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 25 | - | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 26 | - | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 27 | - | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
| 28 | - | // DEALINGS IN THE SOFTWARE. | |
| 29 | - | ||
| 30 | - | package drmsyncobj | |
| 31 | - | ||
| 32 | - | import ( | |
| 33 | - | cross_wl_surface "github.com/bnema/wlturbo/protocol/core" | |
| 34 | - | "github.com/bnema/wlturbo/wl" | |
| 35 | - | ) | |
| 36 | - | ||
| 37 | - | // ERROR_SURFACE_EXISTS is the error surface_exists value. | |
| 38 | - | const ERROR_SURFACE_EXISTS = 0 | |
| 39 | - | ||
| 40 | - | // ERROR_INVALID_TIMELINE is the error invalid_timeline value. | |
| 41 | - | const ERROR_INVALID_TIMELINE = 1 | |
| 42 | - | ||
| 43 | - | // ERROR_NO_SURFACE is the error no_surface value. | |
| 44 | - | const ERROR_NO_SURFACE = 1 | |
| 45 | - | ||
| 46 | - | // ERROR_UNSUPPORTED_BUFFER is the error unsupported_buffer value. | |
| 47 | - | const ERROR_UNSUPPORTED_BUFFER = 2 | |
| 48 | - | ||
| 49 | - | // ERROR_NO_BUFFER is the error no_buffer value. | |
| 50 | - | const ERROR_NO_BUFFER = 3 | |
| 51 | - | ||
| 52 | - | // ERROR_NO_ACQUIRE_POINT is the error no_acquire_point value. | |
| 53 | - | const ERROR_NO_ACQUIRE_POINT = 4 | |
| 54 | - | ||
| 55 | - | // ERROR_NO_RELEASE_POINT is the error no_release_point value. | |
| 56 | - | const ERROR_NO_RELEASE_POINT = 5 | |
| 57 | - | ||
| 58 | - | // ERROR_CONFLICTING_POINTS is the error conflicting_points value. | |
| 59 | - | const ERROR_CONFLICTING_POINTS = 6 | |
| 60 | - | ||
| 61 | - | // WpLinuxDrmSyncobjManagerInterface is the protocol interface name. | |
| 62 | - | const WpLinuxDrmSyncobjManagerInterface = "wp_linux_drm_syncobj_manager_v1" | |
| 63 | - | ||
| 64 | - | // WpLinuxDrmSyncobjManager is the generated binding for wp_linux_drm_syncobj_manager_v1 version 1. | |
| 65 | - | type WpLinuxDrmSyncobjManager struct { | |
| 66 | - | wl.BaseProxy | |
| 67 | - | } | |
| 68 | - | ||
| 69 | - | // NewWpLinuxDrmSyncobjManager returns an unbound WpLinuxDrmSyncobjManager. | |
| 70 | - | func NewWpLinuxDrmSyncobjManager(ctx *wl.Context) *WpLinuxDrmSyncobjManager { | |
| 71 | - | obj := &WpLinuxDrmSyncobjManager{} | |
| 72 | - | obj.SetContext(ctx) | |
| 73 | - | ctx.Register(obj) | |
| 74 | - | return obj | |
| 75 | - | } | |
| 76 | - | ||
| 77 | - | // Destroy this explicit synchronization factory object. Other objects shall not be affected by this request. | |
| 78 | - | func (o *WpLinuxDrmSyncobjManager) Destroy() error { | |
| 79 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "wp_linux_drm_syncobj_manager_v1.destroy", Destructor: true}); err != nil { | |
| 80 | - | return err | |
| 81 | - | } | |
| 82 | - | return nil | |
| 83 | - | } | |
| 84 | - | ||
| 85 | - | // 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 surface_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 surface_exists protocol error. | |
| 86 | - | func (o *WpLinuxDrmSyncobjManager) GetSurface(surface *cross_wl_surface.Surface) (*WpLinuxDrmSyncobjSurface, error) { | |
| 87 | - | var arg1 wl.Object | |
| 88 | - | if surface != nil { | |
| 89 | - | arg1 = surface | |
| 90 | - | } | |
| 91 | - | child := &WpLinuxDrmSyncobjSurface{} | |
| 92 | - | child.SetContext(o.Context()) | |
| 93 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "wp_linux_drm_syncobj_manager_v1.get_surface", Child: child}, wl.ArgObject(child), wl.ArgObject(arg1)); err != nil { | |
| 94 | - | return nil, err | |
| 95 | - | } | |
| 96 | - | return child, nil | |
| 97 | - | } | |
| 98 | - | ||
| 99 | - | // Import a DRM synchronization object timeline. If the FD cannot be imported, the invalid_timeline error is raised. | |
| 100 | - | func (o *WpLinuxDrmSyncobjManager) ImportTimeline(fd int) (*WpLinuxDrmSyncobjTimeline, error) { | |
| 101 | - | child := &WpLinuxDrmSyncobjTimeline{} | |
| 102 | - | child.SetContext(o.Context()) | |
| 103 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 2, Name: "wp_linux_drm_syncobj_manager_v1.import_timeline", Child: child, FDs: []int{fd}}, wl.ArgObject(child), wl.ArgFD()); err != nil { | |
| 104 | - | return nil, err | |
| 105 | - | } | |
| 106 | - | return child, nil | |
| 107 | - | } | |
| 108 | - | ||
| 109 | - | // EventSignature returns the declared event argument types in wire order. | |
| 110 | - | func (o *WpLinuxDrmSyncobjManager) EventSignature(opcode uint16) (string, bool) { | |
| 111 | - | switch opcode { | |
| 112 | - | default: | |
| 113 | - | return "", false | |
| 114 | - | } | |
| 115 | - | } | |
| 116 | - | ||
| 117 | - | // Dispatch decodes one event on wp_linux_drm_syncobj_manager_v1 and calls the registered handlers. | |
| 118 | - | func (o *WpLinuxDrmSyncobjManager) Dispatch(event *wl.Event) { | |
| 119 | - | switch event.Opcode { | |
| 120 | - | default: | |
| 121 | - | } | |
| 122 | - | } | |
| 123 | - | ||
| 124 | - | // WpLinuxDrmSyncobjTimelineInterface is the protocol interface name. | |
| 125 | - | const WpLinuxDrmSyncobjTimelineInterface = "wp_linux_drm_syncobj_timeline_v1" | |
| 126 | - | ||
| 127 | - | // WpLinuxDrmSyncobjTimeline is the generated binding for wp_linux_drm_syncobj_timeline_v1 version 1. | |
| 128 | - | type WpLinuxDrmSyncobjTimeline struct { | |
| 129 | - | wl.BaseProxy | |
| 130 | - | } | |
| 131 | - | ||
| 132 | - | // NewWpLinuxDrmSyncobjTimeline returns an unbound WpLinuxDrmSyncobjTimeline. | |
| 133 | - | func NewWpLinuxDrmSyncobjTimeline(ctx *wl.Context) *WpLinuxDrmSyncobjTimeline { | |
| 134 | - | obj := &WpLinuxDrmSyncobjTimeline{} | |
| 135 | - | obj.SetContext(ctx) | |
| 136 | - | ctx.Register(obj) | |
| 137 | - | return obj | |
| 138 | - | } | |
| 139 | - | ||
| 140 | - | // Destroy the synchronization object timeline. Other objects are not affected by this request, in particular timeline points set by set_acquire_point and set_release_point are not unset. | |
| 141 | - | func (o *WpLinuxDrmSyncobjTimeline) Destroy() error { | |
| 142 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "wp_linux_drm_syncobj_timeline_v1.destroy", Destructor: true}); err != nil { | |
| 143 | - | return err | |
| 144 | - | } | |
| 145 | - | return nil | |
| 146 | - | } | |
| 147 | - | ||
| 148 | - | // EventSignature returns the declared event argument types in wire order. | |
| 149 | - | func (o *WpLinuxDrmSyncobjTimeline) EventSignature(opcode uint16) (string, bool) { | |
| 150 | - | switch opcode { | |
| 151 | - | default: | |
| 152 | - | return "", false | |
| 153 | - | } | |
| 154 | - | } | |
| 155 | - | ||
| 156 | - | // Dispatch decodes one event on wp_linux_drm_syncobj_timeline_v1 and calls the registered handlers. | |
| 157 | - | func (o *WpLinuxDrmSyncobjTimeline) Dispatch(event *wl.Event) { | |
| 158 | - | switch event.Opcode { | |
| 159 | - | default: | |
| 160 | - | } | |
| 161 | - | } | |
| 162 | - | ||
| 163 | - | // WpLinuxDrmSyncobjSurfaceInterface is the protocol interface name. | |
| 164 | - | const WpLinuxDrmSyncobjSurfaceInterface = "wp_linux_drm_syncobj_surface_v1" | |
| 165 | - | ||
| 166 | - | // WpLinuxDrmSyncobjSurface is the generated binding for wp_linux_drm_syncobj_surface_v1 version 1. | |
| 167 | - | type WpLinuxDrmSyncobjSurface struct { | |
| 168 | - | wl.BaseProxy | |
| 169 | - | } | |
| 170 | - | ||
| 171 | - | // NewWpLinuxDrmSyncobjSurface returns an unbound WpLinuxDrmSyncobjSurface. | |
| 172 | - | func NewWpLinuxDrmSyncobjSurface(ctx *wl.Context) *WpLinuxDrmSyncobjSurface { | |
| 173 | - | obj := &WpLinuxDrmSyncobjSurface{} | |
| 174 | - | obj.SetContext(ctx) | |
| 175 | - | ctx.Register(obj) | |
| 176 | - | return obj | |
| 177 | - | } | |
| 178 | - | ||
| 179 | - | // Destroy this surface synchronization object. Any timeline point set by this object with set_acquire_point or set_release_point since the last commit may be discarded by the compositor. Any timeline point set by this object before the last commit will not be affected. | |
| 180 | - | func (o *WpLinuxDrmSyncobjSurface) Destroy() error { | |
| 181 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "wp_linux_drm_syncobj_surface_v1.destroy", Destructor: true}); err != nil { | |
| 182 | - | return err | |
| 183 | - | } | |
| 184 | - | return nil | |
| 185 | - | } | |
| 186 | - | ||
| 187 | - | // Set the timeline point that must be signalled before the compositor may sample from the buffer attached with wl_surface.attach. The 64-bit unsigned value combined from point_hi and point_lo is the point value. The acquire point 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 an acquire point has already been attached during the same commit cycle, the new point replaces the old one. If the associated wl_surface was destroyed, a no_surface error is raised. If at surface commit time there is a pending acquire timeline point set but no pending buffer attached, a no_buffer error is raised. If at surface commit time there is a pending buffer attached but no pending acquire timeline point set, the no_acquire_point protocol error is raised. | |
| 188 | - | func (o *WpLinuxDrmSyncobjSurface) SetAcquirePoint(timeline *WpLinuxDrmSyncobjTimeline, pointHi uint32, pointLo uint32) error { | |
| 189 | - | var arg0 wl.Object | |
| 190 | - | if timeline != nil { | |
| 191 | - | arg0 = timeline | |
| 192 | - | } | |
| 193 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "wp_linux_drm_syncobj_surface_v1.set_acquire_point"}, wl.ArgObject(arg0), wl.ArgUint(pointHi), wl.ArgUint(pointLo)); err != nil { | |
| 194 | - | return err | |
| 195 | - | } | |
| 196 | - | return nil | |
| 197 | - | } | |
| 198 | - | ||
| 199 | - | // Set the timeline point that must be signalled by the compositor when it has finished its usage of the buffer attached with wl_surface.attach for the relevant commit. Once the timeline point is signaled, and assuming the associated buffer is not pending release from other wl_surface.commit requests, no additional explicit or implicit synchronization with the compositor is required to safely re-use the buffer. Note that clients cannot rely on the release point being always signaled after the acquire point: compositors may release buffers without ever reading from them. In addition, the compositor may use different presentation paths for different commits, which may have different release behavior. As a result, the compositor may signal the release points in a different order than the client committed them. Because signaling a timeline point also signals every previous point, it is generally not safe to use the same timeline object for the release points of multiple buffers. The out-of-order signaling described above may lead to a release point being signaled before the compositor has finished reading. To avoid this, it is strongly recommended that each buffer should use a separate timeline for its release points. The 64-bit unsigned value combined from point_hi and point_lo is the point value. The release point 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 a release point has already been attached during the same commit cycle, the new point replaces the old one. If the associated wl_surface was destroyed, a no_surface error is raised. If at surface commit time there is a pending release timeline point set but no pending buffer attached, a no_buffer error is raised. If at surface commit time there is a pending buffer attached but no pending release timeline point set, the no_release_point protocol error is raised. | |
| 200 | - | func (o *WpLinuxDrmSyncobjSurface) SetReleasePoint(timeline *WpLinuxDrmSyncobjTimeline, pointHi uint32, pointLo uint32) error { | |
| 201 | - | var arg0 wl.Object | |
| 202 | - | if timeline != nil { | |
| 203 | - | arg0 = timeline | |
| 204 | - | } | |
| 205 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 2, Name: "wp_linux_drm_syncobj_surface_v1.set_release_point"}, wl.ArgObject(arg0), wl.ArgUint(pointHi), wl.ArgUint(pointLo)); err != nil { | |
| 206 | - | return err | |
| 207 | - | } | |
| 208 | - | return nil | |
| 209 | - | } | |
| 210 | - | ||
| 211 | - | // EventSignature returns the declared event argument types in wire order. | |
| 212 | - | func (o *WpLinuxDrmSyncobjSurface) EventSignature(opcode uint16) (string, bool) { | |
| 213 | - | switch opcode { | |
| 214 | - | default: | |
| 215 | - | return "", false | |
| 216 | - | } | |
| 217 | - | } | |
| 218 | - | ||
| 219 | - | // Dispatch decodes one event on wp_linux_drm_syncobj_surface_v1 and calls the registered handlers. | |
| 220 | - | func (o *WpLinuxDrmSyncobjSurface) Dispatch(event *wl.Event) { | |
| 221 | - | switch event.Opcode { | |
| 222 | - | default: | |
| 223 | - | } | |
| 224 | - | } | |
D protocol/extensions_test.go +0 -722
| @@ -1,722 +0,0 @@ | |||
| 1 | - | //go:build linux | |
| 2 | - | ||
| 3 | - | package protocol_test | |
| 4 | - | ||
| 5 | - | import ( | |
| 6 | - | "encoding/binary" | |
| 7 | - | "errors" | |
| 8 | - | "net" | |
| 9 | - | "os" | |
| 10 | - | "slices" | |
| 11 | - | "strings" | |
| 12 | - | "testing" | |
| 13 | - | "time" | |
| 14 | - | ||
| 15 | - | "github.com/bnema/wlturbo" | |
| 16 | - | "github.com/bnema/wlturbo/protocol/core" | |
| 17 | - | "github.com/bnema/wlturbo/protocol/cursorshape" | |
| 18 | - | "github.com/bnema/wlturbo/protocol/drmsyncobj" | |
| 19 | - | "github.com/bnema/wlturbo/protocol/fractionalscale" | |
| 20 | - | "github.com/bnema/wlturbo/protocol/linuxdmabuf" | |
| 21 | - | "github.com/bnema/wlturbo/protocol/textinput" | |
| 22 | - | "github.com/bnema/wlturbo/protocol/viewporter" | |
| 23 | - | "github.com/bnema/wlturbo/protocol/xdgshell" | |
| 24 | - | "golang.org/x/sys/unix" | |
| 25 | - | ) | |
| 26 | - | ||
| 27 | - | func pair(t *testing.T) (*net.UnixConn, *net.UnixConn) { | |
| 28 | - | t.Helper() | |
| 29 | - | fds, e := unix.Socketpair(unix.AF_UNIX, unix.SOCK_STREAM|unix.SOCK_CLOEXEC, 0) | |
| 30 | - | if e != nil { | |
| 31 | - | t.Fatal(e) | |
| 32 | - | } | |
| 33 | - | a := os.NewFile(uintptr(fds[0]), "a") | |
| 34 | - | b := os.NewFile(uintptr(fds[1]), "b") | |
| 35 | - | ca, e := net.FileConn(a) | |
| 36 | - | a.Close() | |
| 37 | - | if e != nil { | |
| 38 | - | t.Fatal(e) | |
| 39 | - | } | |
| 40 | - | cb, e := net.FileConn(b) | |
| 41 | - | b.Close() | |
| 42 | - | if e != nil { | |
| 43 | - | t.Fatal(e) | |
| 44 | - | } | |
| 45 | - | t.Cleanup(func() { ca.Close(); cb.Close() }) | |
| 46 | - | return ca.(*net.UnixConn), cb.(*net.UnixConn) | |
| 47 | - | } | |
| 48 | - | func msg(id uint32, op uint16, body ...uint32) []byte { | |
| 49 | - | b := make([]byte, 8+4*len(body)) | |
| 50 | - | binary.NativeEndian.PutUint32(b, id) | |
| 51 | - | binary.NativeEndian.PutUint32(b[4:], uint32(len(b))<<16|uint32(op)) | |
| 52 | - | for i, v := range body { | |
| 53 | - | binary.NativeEndian.PutUint32(b[8+i*4:], v) | |
| 54 | - | } | |
| 55 | - | return b | |
| 56 | - | } | |
| 57 | - | func payload(id uint32, op uint16, b ...byte) []byte { | |
| 58 | - | p := make([]byte, 8+len(b)) | |
| 59 | - | copy(p, msg(id, op)) | |
| 60 | - | copy(p[8:], b) | |
| 61 | - | binary.NativeEndian.PutUint32(p[4:], uint32(len(p))<<16|uint32(op)) | |
| 62 | - | return p | |
| 63 | - | } | |
| 64 | - | func arr(b []byte) []byte { | |
| 65 | - | out := make([]byte, 4+(len(b)+3)&^3) | |
| 66 | - | binary.NativeEndian.PutUint32(out, uint32(len(b))) | |
| 67 | - | copy(out[4:], b) | |
| 68 | - | return out | |
| 69 | - | } | |
| 70 | - | func str(s string) []byte { return arr(append([]byte(s), 0)) } | |
| 71 | - | func send(t *testing.T, p *net.UnixConn, b []byte, fd ...int) { | |
| 72 | - | t.Helper() | |
| 73 | - | var rights []byte | |
| 74 | - | if len(fd) > 0 { | |
| 75 | - | rights = unix.UnixRights(fd...) | |
| 76 | - | } | |
| 77 | - | if _, _, e := p.WriteMsgUnix(b, rights, nil); e != nil { | |
| 78 | - | t.Fatal(e) | |
| 79 | - | } | |
| 80 | - | } | |
| 81 | - | func request(t *testing.T, p *net.UnixConn) (uint32, uint16, []byte) { | |
| 82 | - | t.Helper() | |
| 83 | - | p.SetReadDeadline(time.Now().Add(2 * time.Second)) | |
| 84 | - | b := make([]byte, 4096) | |
| 85 | - | n, e := p.Read(b) | |
| 86 | - | if e != nil { | |
| 87 | - | t.Fatal(e) | |
| 88 | - | } | |
| 89 | - | if n < 8 { | |
| 90 | - | t.Fatal("short request") | |
| 91 | - | } | |
| 92 | - | return binary.NativeEndian.Uint32(b), uint16(binary.NativeEndian.Uint32(b[4:])), b[8:n] | |
| 93 | - | } | |
| 94 | - | func noerr(t *testing.T, e error) { | |
| 95 | - | t.Helper() | |
| 96 | - | if e != nil { | |
| 97 | - | t.Fatal(e) | |
| 98 | - | } | |
| 99 | - | } | |
| 100 | - | func bind(t *testing.T, d *wlturbo.Display, p *net.UnixConn, name uint32, iface string, announced uint32, supported uint32, proxy wlturbo.Proxy) { | |
| 101 | - | t.Helper() | |
| 102 | - | // A fake server must advertise a global before clients can negotiate it. | |
| 103 | - | announcement := append(msg(0, 0, name)[8:], str(iface)...) | |
| 104 | - | announcement = append(announcement, msg(0, 0, announced)[8:]...) | |
| 105 | - | send(t, p, payload(d.Registry().ID(), 0, announcement...)) | |
| 106 | - | noerr(t, d.Dispatch()) | |
| 107 | - | v, err := d.Registry().BindNegotiated(iface, supported, proxy) | |
| 108 | - | noerr(t, err) | |
| 109 | - | want := min(announced, supported) | |
| 110 | - | _, op, b := request(t, p) | |
| 111 | - | if op != 0 || v != want || binary.NativeEndian.Uint32(b) != name || binary.NativeEndian.Uint32(b[len(b)-8:]) != want || binary.NativeEndian.Uint32(b[len(b)-4:]) != proxy.ID() { | |
| 112 | - | t.Fatalf("bad bind %s announced=%d supported=%d negotiated=%d wire=%x", iface, announced, supported, v, b) | |
| 113 | - | } | |
| 114 | - | } | |
| 115 | - | ||
| 116 | - | // serverID is the first server-allocated object ID on the wire. | |
| 117 | - | const serverID = 0xff000000 | |
| 118 | - | ||
| 119 | - | // wordBytes encodes 32-bit words as a message body in native byte order. | |
| 120 | - | func wordBytes(v ...uint32) []byte { return msg(0, 0, v...)[8:] } | |
| 121 | - | ||
| 122 | - | // cat concatenates message body fragments. | |
| 123 | - | func cat(parts ...[]byte) []byte { | |
| 124 | - | var out []byte | |
| 125 | - | for _, p := range parts { | |
| 126 | - | out = append(out, p...) | |
| 127 | - | } | |
| 128 | - | return out | |
| 129 | - | } | |
| 130 | - | ||
| 131 | - | // decodeWords splits a message body into 32-bit words. | |
| 132 | - | func decodeWords(b []byte) []uint32 { | |
| 133 | - | w := make([]uint32, len(b)/4) | |
| 134 | - | for i := range w { | |
| 135 | - | w[i] = binary.NativeEndian.Uint32(b[i*4:]) | |
| 136 | - | } | |
| 137 | - | return w | |
| 138 | - | } | |
| 139 | - | ||
| 140 | - | // wantWords requires a request body to be exactly the given 32-bit words. | |
| 141 | - | func wantWords(t *testing.T, what string, b []byte, want ...uint32) { | |
| 142 | - | t.Helper() | |
| 143 | - | if got := decodeWords(b); !slices.Equal(got, want) { // nil and empty are equal | |
| 144 | - | t.Fatalf("%s wire = %v, want %v", what, got, want) | |
| 145 | - | } | |
| 146 | - | } | |
| 147 | - | ||
| 148 | - | // wantRequestWords reads one request and requires its exact object, opcode and | |
| 149 | - | // 32-bit word arguments. | |
| 150 | - | func wantRequestWords(t *testing.T, p *net.UnixConn, id uint32, op uint16, want ...uint32) { | |
| 151 | - | t.Helper() | |
| 152 | - | gid, gop, body := request(t, p) | |
| 153 | - | if gid != id || gop != op || len(body) != 4*len(want) { | |
| 154 | - | t.Fatalf("request object=%d op=%d body=%x, want object=%d op=%d words=%v", gid, gop, body, id, op, want) | |
| 155 | - | } | |
| 156 | - | wantWords(t, "request", body, want...) | |
| 157 | - | } | |
| 158 | - | ||
| 159 | - | // requireFDClosed fails if fd is still open in this process: the binding must | |
| 160 | - | // close its copy of a descriptor once the kernel took it with a request. Call | |
| 161 | - | // it before reading the request, because the received duplicate may reuse the | |
| 162 | - | // same descriptor number. | |
| 163 | - | func requireFDClosed(t *testing.T, fd int) { | |
| 164 | - | t.Helper() | |
| 165 | - | if _, e := unix.FcntlInt(uintptr(fd), unix.F_GETFD, 0); e == nil { | |
| 166 | - | t.Fatalf("descriptor %d sent by the client was not closed", fd) | |
| 167 | - | } | |
| 168 | - | } | |
| 169 | - | ||
| 170 | - | // requireNoWrite fails unless the client wrote nothing within a short deadline. | |
| 171 | - | func requireNoWrite(t *testing.T, p *net.UnixConn) { | |
| 172 | - | t.Helper() | |
| 173 | - | p.SetReadDeadline(time.Now().Add(100 * time.Millisecond)) | |
| 174 | - | var b [64]byte | |
| 175 | - | n, e := p.Read(b[:]) | |
| 176 | - | if e == nil { | |
| 177 | - | t.Fatalf("unexpected bytes on the wire: %x", b[:n]) | |
| 178 | - | } | |
| 179 | - | if !errors.Is(e, os.ErrDeadlineExceeded) { | |
| 180 | - | t.Fatal(e) | |
| 181 | - | } | |
| 182 | - | } | |
| 183 | - | ||
| 184 | - | // recvRequestFDs reads one client message and the descriptors that came with | |
| 185 | - | // it. Every received descriptor is closed before a fatal failure, so a failed | |
| 186 | - | // check cannot leak them; on success the caller owns fds. | |
| 187 | - | func recvRequestFDs(t *testing.T, p *net.UnixConn) (id uint32, op uint16, body []byte, fds []int) { | |
| 188 | - | t.Helper() | |
| 189 | - | fail := func(format string, args ...any) { | |
| 190 | - | t.Helper() | |
| 191 | - | for _, fd := range fds { | |
| 192 | - | unix.Close(fd) | |
| 193 | - | } | |
| 194 | - | t.Fatalf(format, args...) | |
| 195 | - | } | |
| 196 | - | p.SetReadDeadline(time.Now().Add(2 * time.Second)) | |
| 197 | - | b := make([]byte, 4096) | |
| 198 | - | oob := make([]byte, 256) | |
| 199 | - | n, oobn, _, _, e := p.ReadMsgUnix(b, oob) | |
| 200 | - | if oobn > 0 { | |
| 201 | - | msgs, pe := unix.ParseSocketControlMessage(oob[:oobn]) | |
| 202 | - | for i := range msgs { | |
| 203 | - | r, re := unix.ParseUnixRights(&msgs[i]) | |
| 204 | - | fds = append(fds, r...) | |
| 205 | - | if re != nil && pe == nil { | |
| 206 | - | pe = re | |
| 207 | - | } | |
| 208 | - | } | |
| 209 | - | if pe != nil { | |
| 210 | - | fail("control message: %v", pe) | |
| 211 | - | } | |
| 212 | - | } | |
| 213 | - | if e != nil { | |
| 214 | - | fail("read request: %v", e) | |
| 215 | - | } | |
| 216 | - | if n < 8 { | |
| 217 | - | fail("short request (%d bytes)", n) | |
| 218 | - | } | |
| 219 | - | if size := int(binary.NativeEndian.Uint32(b[4:]) >> 16); size != n { | |
| 220 | - | fail("header size %d != %d bytes read", size, n) | |
| 221 | - | } | |
| 222 | - | return binary.NativeEndian.Uint32(b), uint16(binary.NativeEndian.Uint32(b[4:])), b[8:n], fds | |
| 223 | - | } | |
| 224 | - | ||
| 225 | - | // requestWithFD reads the next request, requires its object and opcode, and | |
| 226 | - | // requires exactly one descriptor, which the caller then owns. | |
| 227 | - | func requestWithFD(t *testing.T, p *net.UnixConn, id uint32, op uint16) ([]byte, int) { | |
| 228 | - | t.Helper() | |
| 229 | - | gid, gop, body, fds := recvRequestFDs(t, p) | |
| 230 | - | if gid != id || gop != op || len(fds) != 1 { | |
| 231 | - | for _, fd := range fds { | |
| 232 | - | unix.Close(fd) | |
| 233 | - | } | |
| 234 | - | t.Fatalf("request object=%d op=%d fds=%d, want object=%d op=%d with 1 descriptor (body %x)", gid, gop, len(fds), id, op, body) | |
| 235 | - | } | |
| 236 | - | return body, fds[0] | |
| 237 | - | } | |
| 238 | - | ||
| 239 | - | // register gives a proxy a client-allocated ID and registers it with d. | |
| 240 | - | func register(d *wlturbo.Display, o wlturbo.Proxy) { | |
| 241 | - | o.SetID(d.AllocateID()) | |
| 242 | - | d.Context().Register(o) | |
| 243 | - | } | |
| 244 | - | ||
| 245 | - | // wireEnv is one client connection against a fake compositor on a socketpair. | |
| 246 | - | type wireEnv struct { | |
| 247 | - | t *testing.T | |
| 248 | - | d *wlturbo.Display | |
| 249 | - | p *net.UnixConn | |
| 250 | - | } | |
| 251 | - | ||
| 252 | - | func newWireEnv(t *testing.T) *wireEnv { | |
| 253 | - | t.Helper() | |
| 254 | - | c, p := pair(t) | |
| 255 | - | d, e := wlturbo.ConnectFromConn(c) | |
| 256 | - | noerr(t, e) | |
| 257 | - | t.Cleanup(func() { d.Close() }) | |
| 258 | - | request(t, p) // wl_display.get_registry | |
| 259 | - | return &wireEnv{t: t, d: d, p: p} | |
| 260 | - | } | |
| 261 | - | ||
| 262 | - | func (s *wireEnv) dispatch() { s.t.Helper(); noerr(s.t, s.d.Dispatch()) } | |
| 263 | - | ||
| 264 | - | // bind advertises and binds a global; see the package-level bind. | |
| 265 | - | func (s *wireEnv) bind(name uint32, iface string, announced, supported uint32, proxy wlturbo.Proxy) { | |
| 266 | - | s.t.Helper() | |
| 267 | - | bind(s.t, s.d, s.p, name, iface, announced, supported, proxy) | |
| 268 | - | } | |
| 269 | - | ||
| 270 | - | // event sends one server event and dispatches it on the client. | |
| 271 | - | func (s *wireEnv) event(id uint32, op uint16, body ...byte) { | |
| 272 | - | s.t.Helper() | |
| 273 | - | s.eventFD(id, op, body) | |
| 274 | - | } | |
| 275 | - | ||
| 276 | - | // eventFD is event for an event that carries descriptors (SCM_RIGHTS). | |
| 277 | - | func (s *wireEnv) eventFD(id uint32, op uint16, body []byte, fd ...int) { | |
| 278 | - | s.t.Helper() | |
| 279 | - | send(s.t, s.p, payload(id, op, body...), fd...) | |
| 280 | - | s.dispatch() | |
| 281 | - | } | |
| 282 | - | ||
| 283 | - | // req reads the next client request and checks its object and opcode. | |
| 284 | - | func (s *wireEnv) req(id uint32, op uint16) []byte { | |
| 285 | - | s.t.Helper() | |
| 286 | - | gid, gop, b := request(s.t, s.p) | |
| 287 | - | if gid != id || gop != op { | |
| 288 | - | s.t.Fatalf("request object=%d op=%d, want object=%d op=%d (body %x)", gid, gop, id, op, b) | |
| 289 | - | } | |
| 290 | - | return b | |
| 291 | - | } | |
| 292 | - | ||
| 293 | - | // reqFD is req for a request that carries exactly one descriptor. | |
| 294 | - | func (s *wireEnv) reqFD(id uint32, op uint16) ([]byte, int) { | |
| 295 | - | s.t.Helper() | |
| 296 | - | return requestWithFD(s.t, s.p, id, op) | |
| 297 | - | } | |
| 298 | - | ||
| 299 | - | // noRequest fails if the client wrote anything. | |
| 300 | - | func (s *wireEnv) noRequest() { s.t.Helper(); requireNoWrite(s.t, s.p) } | |
| 301 | - | ||
| 302 | - | func (s *wireEnv) surface() *core.Surface { | |
| 303 | - | o := core.NewSurface(s.d.Context()) | |
| 304 | - | register(s.d, o) | |
| 305 | - | return o | |
| 306 | - | } | |
| 307 | - | func (s *wireEnv) seat() *core.Seat { | |
| 308 | - | o := core.NewSeat(s.d.Context()) | |
| 309 | - | register(s.d, o) | |
| 310 | - | return o | |
| 311 | - | } | |
| 312 | - | func (s *wireEnv) output() *core.Output { | |
| 313 | - | o := core.NewOutput(s.d.Context()) | |
| 314 | - | register(s.d, o) | |
| 315 | - | return o | |
| 316 | - | } | |
| 317 | - | func (s *wireEnv) pointer() *core.Pointer { | |
| 318 | - | o := core.NewPointer(s.d.Context()) | |
| 319 | - | register(s.d, o) | |
| 320 | - | return o | |
| 321 | - | } | |
| 322 | - | func (s *wireEnv) region() *core.Region { | |
| 323 | - | o := core.NewRegion(s.d.Context()) | |
| 324 | - | register(s.d, o) | |
| 325 | - | return o | |
| 326 | - | } | |
| 327 | - | func (s *wireEnv) buffer() *core.Buffer { | |
| 328 | - | o := core.NewBuffer(s.d.Context()) | |
| 329 | - | register(s.d, o) | |
| 330 | - | return o | |
| 331 | - | } | |
| 332 | - | ||
| 333 | - | func TestExtensionsOverSocketpair(t *testing.T) { | |
| 334 | - | c, p := pair(t) | |
| 335 | - | d, e := wlturbo.ConnectFromConn(c) | |
| 336 | - | noerr(t, e) | |
| 337 | - | defer d.Close() | |
| 338 | - | request(t, p) | |
| 339 | - | // A registry announcement is the only input to optional-global discovery. | |
| 340 | - | send(t, p, payload(d.Registry().ID(), 0, append(msg(0, 0, 11)[8:12], append(str(fractionalscale.WpFractionalScaleManagerInterface), msg(0, 0, 1)[8:12]...)...)...)) | |
| 341 | - | noerr(t, d.Dispatch()) | |
| 342 | - | if g, ok := d.Registry().FindGlobal(fractionalscale.WpFractionalScaleManagerInterface); !ok || g.Version != 1 { | |
| 343 | - | t.Fatal("announced fractional scale missing", g, ok) | |
| 344 | - | } | |
| 345 | - | if _, ok := d.Registry().FindGlobal(textinput.TextInputManagerV3Interface); ok { | |
| 346 | - | t.Fatal("absent text input") | |
| 347 | - | } | |
| 348 | - | // Remove the discovery-only announcement before the bind matrix assigns | |
| 349 | - | // its own global name to this interface. | |
| 350 | - | send(t, p, msg(d.Registry().ID(), 1, 11)) | |
| 351 | - | noerr(t, d.Dispatch()) | |
| 352 | - | surface := core.NewSurface(d.Context()) | |
| 353 | - | surface.SetID(d.AllocateID()) | |
| 354 | - | d.Context().Register(surface) | |
| 355 | - | seat := core.NewSeat(d.Context()) | |
| 356 | - | seat.SetID(d.AllocateID()) | |
| 357 | - | d.Context().Register(seat) | |
| 358 | - | wm := xdgshell.NewXdgWmBase(d.Context()) | |
| 359 | - | bind(t, d, p, 1, xdgshell.XdgWmBaseInterface, 6, 7, wm) | |
| 360 | - | xs, e := wm.GetXdgSurface(surface) | |
| 361 | - | noerr(t, e) | |
| 362 | - | request(t, p) | |
| 363 | - | top, e := xs.GetToplevel() | |
| 364 | - | noerr(t, e) | |
| 365 | - | request(t, p) | |
| 366 | - | var sequence []string | |
| 367 | - | top.OnConfigure(func(w, h int32, states []byte) { | |
| 368 | - | if w != 800 || h != 600 { | |
| 369 | - | t.Fatalf("size %d,%d", w, h) | |
| 370 | - | } | |
| 371 | - | sequence = append(sequence, "top") | |
| 372 | - | }) | |
| 373 | - | xs.OnConfigure(func(serial uint32) { sequence = append(sequence, "surface"); noerr(t, xs.AckConfigure(serial)) }) | |
| 374 | - | send(t, p, payload(top.ID(), 0, append(msg(0, 0, 800, 600)[8:], arr(nil)...)...)) | |
| 375 | - | noerr(t, d.Dispatch()) | |
| 376 | - | send(t, p, msg(xs.ID(), 0, 9)) | |
| 377 | - | noerr(t, d.Dispatch()) | |
| 378 | - | _, op, b := request(t, p) | |
| 379 | - | if op != 4 || binary.NativeEndian.Uint32(b) != 9 || strings.Join(sequence, ",") != "top,surface" { | |
| 380 | - | t.Fatalf("xdg %d %x %v", op, b, sequence) | |
| 381 | - | } | |
| 382 | - | noerr(t, top.Destroy()) | |
| 383 | - | request(t, p) | |
| 384 | - | noerr(t, xs.Destroy()) | |
| 385 | - | request(t, p) | |
| 386 | - | noerr(t, wm.Destroy()) | |
| 387 | - | request(t, p) | |
| 388 | - | dm := linuxdmabuf.NewLinuxDmabuf(d.Context()) | |
| 389 | - | bind(t, d, p, 2, linuxdmabuf.LinuxDmabufInterface, 6, 4, dm) | |
| 390 | - | fb, e := dm.GetDefaultFeedback() | |
| 391 | - | noerr(t, e) | |
| 392 | - | request(t, p) | |
| 393 | - | table, e := os.CreateTemp(t.TempDir(), "table") | |
| 394 | - | noerr(t, e) | |
| 395 | - | var bytes [32]byte | |
| 396 | - | binary.NativeEndian.PutUint32(bytes[:], 0x34325258) | |
| 397 | - | binary.NativeEndian.PutUint64(bytes[8:], 19) | |
| 398 | - | binary.NativeEndian.PutUint32(bytes[16:], 0x34325241) | |
| 399 | - | binary.NativeEndian.PutUint64(bytes[24:], 42) | |
| 400 | - | _, e = table.Write(bytes[:]) | |
| 401 | - | noerr(t, e) | |
| 402 | - | defer table.Close() | |
| 403 | - | var entries []linuxdmabuf.FormatEntry | |
| 404 | - | var indices []uint16 | |
| 405 | - | var feedback []string | |
| 406 | - | fb.OnMainDevice(func(dev []byte) { | |
| 407 | - | if len(dev) != 8 { | |
| 408 | - | t.Fatalf("device %x", dev) | |
| 409 | - | } | |
| 410 | - | feedback = append(feedback, "main") | |
| 411 | - | }) | |
| 412 | - | fb.OnFormatTable(func(fd *wlturbo.OwnedFD, size uint32) { | |
| 413 | - | entries, e = linuxdmabuf.ReadFormatTable(fd, size) | |
| 414 | - | noerr(t, e) | |
| 415 | - | feedback = append(feedback, "table") | |
| 416 | - | }) | |
| 417 | - | fb.OnTrancheTargetDevice(func(dev []byte) { feedback = append(feedback, "target") }) | |
| 418 | - | fb.OnTrancheFormats(func(data []byte) { | |
| 419 | - | indices, e = linuxdmabuf.TrancheIndices(data, len(entries)) | |
| 420 | - | noerr(t, e) | |
| 421 | - | feedback = append(feedback, "formats") | |
| 422 | - | }) | |
| 423 | - | fb.OnTrancheFlags(func(flags uint32) { | |
| 424 | - | if flags != 1 { | |
| 425 | - | t.Fatal(flags) | |
| 426 | - | } | |
| 427 | - | feedback = append(feedback, "flags") | |
| 428 | - | }) | |
| 429 | - | fb.OnTrancheDone(func() { feedback = append(feedback, "tranche") }) | |
| 430 | - | fb.OnDone(func() { feedback = append(feedback, "done") }) | |
| 431 | - | send(t, p, payload(fb.ID(), 2, arr(make([]byte, 8))...)) | |
| 432 | - | noerr(t, d.Dispatch()) | |
| 433 | - | send(t, p, msg(fb.ID(), 1, 32), int(table.Fd())) | |
| 434 | - | noerr(t, d.Dispatch()) | |
| 435 | - | send(t, p, payload(fb.ID(), 4, arr(make([]byte, 8))...)) | |
| 436 | - | noerr(t, d.Dispatch()) | |
| 437 | - | send(t, p, payload(fb.ID(), 5, arr([]byte{0, 0, 1, 0})...)) | |
| 438 | - | noerr(t, d.Dispatch()) | |
| 439 | - | send(t, p, msg(fb.ID(), 6, 1)) | |
| 440 | - | noerr(t, d.Dispatch()) | |
| 441 | - | send(t, p, msg(fb.ID(), 3)) | |
| 442 | - | noerr(t, d.Dispatch()) | |
| 443 | - | send(t, p, msg(fb.ID(), 0)) | |
| 444 | - | noerr(t, d.Dispatch()) | |
| 445 | - | if len(entries) != 2 || entries[1].Modifier != 42 || len(indices) != 2 || indices[1] != 1 || strings.Join(feedback, ",") != "main,table,target,formats,flags,tranche,done" { | |
| 446 | - | t.Fatalf("feedback %v %v %v", entries, indices, feedback) | |
| 447 | - | } | |
| 448 | - | noerr(t, fb.Destroy()) | |
| 449 | - | request(t, p) | |
| 450 | - | params, e := dm.CreateParams() | |
| 451 | - | noerr(t, e) | |
| 452 | - | request(t, p) | |
| 453 | - | f, e := os.Open("/dev/null") | |
| 454 | - | noerr(t, e) | |
| 455 | - | noerr(t, params.Add(int(f.Fd()), 0, 0, 4, 0, 0)) | |
| 456 | - | request(t, p) | |
| 457 | - | if _, e := unix.FcntlInt(f.Fd(), unix.F_GETFD, 0); e == nil { | |
| 458 | - | t.Fatal("sent fd not closed") | |
| 459 | - | } | |
| 460 | - | f.Close() | |
| 461 | - | var buffer *core.Buffer | |
| 462 | - | params.OnCreated(func(b *core.Buffer) { buffer = b }) | |
| 463 | - | params.OnFailed(func() { sequence = append(sequence, "failed") }) | |
| 464 | - | noerr(t, params.Create(1, 1, 0x34325258, 0)) | |
| 465 | - | request(t, p) | |
| 466 | - | send(t, p, msg(params.ID(), 0, 999)) | |
| 467 | - | noerr(t, d.Dispatch()) | |
| 468 | - | if buffer == nil || buffer.ID() != 999 { | |
| 469 | - | t.Fatal("typed buffer missing") | |
| 470 | - | } | |
| 471 | - | noerr(t, buffer.Destroy()) | |
| 472 | - | request(t, p) | |
| 473 | - | noerr(t, params.Destroy()) | |
| 474 | - | request(t, p) | |
| 475 | - | failedParams, e := dm.CreateParams() | |
| 476 | - | noerr(t, e) | |
| 477 | - | request(t, p) | |
| 478 | - | failedParams.OnFailed(func() { sequence = append(sequence, "failed") }) | |
| 479 | - | noerr(t, failedParams.Create(1, 1, 0x34325258, 0)) | |
| 480 | - | request(t, p) | |
| 481 | - | send(t, p, msg(failedParams.ID(), 1)) | |
| 482 | - | noerr(t, d.Dispatch()) | |
| 483 | - | if sequence[len(sequence)-1] != "failed" { | |
| 484 | - | t.Fatal(sequence) | |
| 485 | - | } | |
| 486 | - | noerr(t, failedParams.Destroy()) | |
| 487 | - | request(t, p) | |
| 488 | - | immedParams, e := dm.CreateParams() | |
| 489 | - | noerr(t, e) | |
| 490 | - | request(t, p) | |
| 491 | - | immediate, e := immedParams.CreateImmed(1, 1, 0x34325258, 0) | |
| 492 | - | noerr(t, e) | |
| 493 | - | request(t, p) | |
| 494 | - | noerr(t, immediate.Destroy()) | |
| 495 | - | request(t, p) | |
| 496 | - | noerr(t, immedParams.Destroy()) | |
| 497 | - | request(t, p) | |
| 498 | - | noerr(t, dm.Destroy()) | |
| 499 | - | request(t, p) | |
| 500 | - | sync := drmsyncobj.NewWpLinuxDrmSyncobjManager(d.Context()) | |
| 501 | - | bind(t, d, p, 3, drmsyncobj.WpLinuxDrmSyncobjManagerInterface, 1, 1, sync) | |
| 502 | - | ss, e := sync.GetSurface(surface) | |
| 503 | - | noerr(t, e) | |
| 504 | - | request(t, p) | |
| 505 | - | f, e = os.Open("/dev/null") | |
| 506 | - | noerr(t, e) | |
| 507 | - | tl, e := sync.ImportTimeline(int(f.Fd())) | |
| 508 | - | noerr(t, e) | |
| 509 | - | request(t, p) | |
| 510 | - | if _, e := unix.FcntlInt(f.Fd(), unix.F_GETFD, 0); e == nil { | |
| 511 | - | t.Fatal("timeline fd not closed") | |
| 512 | - | } | |
| 513 | - | f.Close() | |
| 514 | - | noerr(t, ss.SetAcquirePoint(tl, 0x123, 0x456)) | |
| 515 | - | _, op, b = request(t, p) | |
| 516 | - | if op != 1 || binary.NativeEndian.Uint32(b[4:]) != 0x123 || binary.NativeEndian.Uint32(b[8:]) != 0x456 { | |
| 517 | - | t.Fatalf("acquire %d %x", op, b) | |
| 518 | - | } | |
| 519 | - | noerr(t, ss.SetReleasePoint(tl, 0x789, 0xabc)) | |
| 520 | - | _, op, b = request(t, p) | |
| 521 | - | if op != 2 || binary.NativeEndian.Uint32(b[4:]) != 0x789 { | |
| 522 | - | t.Fatalf("release %d %x", op, b) | |
| 523 | - | } | |
| 524 | - | noerr(t, ss.Destroy()) | |
| 525 | - | request(t, p) | |
| 526 | - | noerr(t, tl.Destroy()) | |
| 527 | - | request(t, p) | |
| 528 | - | noerr(t, sync.Destroy()) | |
| 529 | - | request(t, p) | |
| 530 | - | vp := viewporter.NewWpViewporter(d.Context()) | |
| 531 | - | bind(t, d, p, 4, viewporter.WpViewporterInterface, 1, 1, vp) | |
| 532 | - | view, e := vp.GetViewport(surface) | |
| 533 | - | noerr(t, e) | |
| 534 | - | request(t, p) | |
| 535 | - | noerr(t, view.Destroy()) | |
| 536 | - | request(t, p) | |
| 537 | - | noerr(t, vp.Destroy()) | |
| 538 | - | request(t, p) | |
| 539 | - | fs := fractionalscale.NewWpFractionalScaleManager(d.Context()) | |
| 540 | - | bind(t, d, p, 5, fractionalscale.WpFractionalScaleManagerInterface, 1, 1, fs) | |
| 541 | - | scale, e := fs.GetFractionalScale(surface) | |
| 542 | - | noerr(t, e) | |
| 543 | - | request(t, p) | |
| 544 | - | var preferred uint32 | |
| 545 | - | scale.OnPreferredScale(func(v uint32) { preferred = v }) | |
| 546 | - | send(t, p, msg(scale.ID(), 0, 150)) | |
| 547 | - | noerr(t, d.Dispatch()) | |
| 548 | - | if preferred != 150 { | |
| 549 | - | t.Fatal(preferred) | |
| 550 | - | } | |
| 551 | - | noerr(t, scale.Destroy()) | |
| 552 | - | request(t, p) | |
| 553 | - | noerr(t, fs.Destroy()) | |
| 554 | - | request(t, p) | |
| 555 | - | ti := textinput.NewTextInputManagerV3(d.Context()) | |
| 556 | - | bind(t, d, p, 6, textinput.TextInputManagerV3Interface, 2, 1, ti) | |
| 557 | - | input, e := ti.GetTextInput(seat) | |
| 558 | - | noerr(t, e) | |
| 559 | - | request(t, p) | |
| 560 | - | noerr(t, input.Enable()) | |
| 561 | - | request(t, p) | |
| 562 | - | noerr(t, input.SetSurroundingText("hello", 5, 5)) | |
| 563 | - | request(t, p) | |
| 564 | - | noerr(t, input.Commit()) | |
| 565 | - | request(t, p) | |
| 566 | - | var events []string | |
| 567 | - | input.OnPreeditString(func(s string, _, _ int32) { events = append(events, "preedit:"+s) }) | |
| 568 | - | input.OnCommitString(func(s string) { events = append(events, "commit:"+s) }) | |
| 569 | - | input.OnDeleteSurroundingText(func(_, _ uint32) { events = append(events, "delete") }) | |
| 570 | - | input.OnDone(func(uint32) { events = append(events, "done") }) | |
| 571 | - | send(t, p, payload(input.ID(), 2, append(str("é"), msg(0, 0, 0, 0)[8:]...)...)) | |
| 572 | - | noerr(t, d.Dispatch()) | |
| 573 | - | send(t, p, payload(input.ID(), 3, str("hi")...)) | |
| 574 | - | noerr(t, d.Dispatch()) | |
| 575 | - | send(t, p, msg(input.ID(), 4, 1, 2)) | |
| 576 | - | noerr(t, d.Dispatch()) | |
| 577 | - | send(t, p, msg(input.ID(), 5, 1)) | |
| 578 | - | noerr(t, d.Dispatch()) | |
| 579 | - | if strings.Join(events, ",") != "preedit:é,commit:hi,delete,done" { | |
| 580 | - | t.Fatal(events) | |
| 581 | - | } | |
| 582 | - | noerr(t, input.Disable()) | |
| 583 | - | request(t, p) | |
| 584 | - | noerr(t, input.Commit()) | |
| 585 | - | request(t, p) | |
| 586 | - | noerr(t, input.Destroy()) | |
| 587 | - | request(t, p) | |
| 588 | - | noerr(t, ti.Destroy()) | |
| 589 | - | request(t, p) | |
| 590 | - | // Core data-device remains in protocol/core; verify its typed child and | |
| 591 | - | // both directions of clipboard descriptor ownership. | |
| 592 | - | mgr := core.NewDataDeviceManager(d.Context()) | |
| 593 | - | bind(t, d, p, 7, core.DataDeviceManagerInterface, 3, 4, mgr) | |
| 594 | - | device, e := mgr.GetDataDevice(seat) | |
| 595 | - | noerr(t, e) | |
| 596 | - | request(t, p) | |
| 597 | - | source, e := mgr.CreateDataSource() | |
| 598 | - | noerr(t, e) | |
| 599 | - | request(t, p) | |
| 600 | - | var offer *core.DataOffer | |
| 601 | - | device.OnDataOffer(func(o *core.DataOffer) { offer = o }) | |
| 602 | - | send(t, p, msg(device.ID(), 0, 998)) | |
| 603 | - | noerr(t, d.Dispatch()) | |
| 604 | - | if offer == nil || offer.ID() != 998 { | |
| 605 | - | t.Fatal("offer not typed") | |
| 606 | - | } | |
| 607 | - | read, write, e := os.Pipe() | |
| 608 | - | noerr(t, e) | |
| 609 | - | defer read.Close() | |
| 610 | - | noerr(t, offer.Receive("text/plain", int(write.Fd()))) | |
| 611 | - | request(t, p) | |
| 612 | - | if _, e := unix.FcntlInt(write.Fd(), unix.F_GETFD, 0); e == nil { | |
| 613 | - | t.Fatal("clipboard sent fd retained") | |
| 614 | - | } | |
| 615 | - | write.Close() | |
| 616 | - | source.OnSend(func(mime string, fd *wlturbo.OwnedFD) { | |
| 617 | - | if mime != "text/plain" { | |
| 618 | - | t.Fatal(mime) | |
| 619 | - | } | |
| 620 | - | n, e := fd.Take() | |
| 621 | - | noerr(t, e) | |
| 622 | - | unix.Close(n) | |
| 623 | - | }) | |
| 624 | - | received, e := os.Open("/dev/null") | |
| 625 | - | noerr(t, e) | |
| 626 | - | send(t, p, payload(source.ID(), 1, str("text/plain")...), int(received.Fd())) | |
| 627 | - | noerr(t, d.Dispatch()) | |
| 628 | - | received.Close() | |
| 629 | - | noerr(t, offer.Destroy()) | |
| 630 | - | request(t, p) | |
| 631 | - | noerr(t, source.Destroy()) | |
| 632 | - | request(t, p) | |
| 633 | - | noerr(t, device.Release()) | |
| 634 | - | request(t, p) | |
| 635 | - | // release is a version 4 request; the manager was negotiated at 3, so it | |
| 636 | - | // must be refused locally instead of reaching the compositor. | |
| 637 | - | if err := mgr.Release(); !errors.Is(err, wlturbo.ErrVersionTooLow) { | |
| 638 | - | t.Fatalf("release at v3 = %v, want ErrVersionTooLow", err) | |
| 639 | - | } | |
| 640 | - | // Cursor shape: get a device for a wl_pointer and set a shape at an | |
| 641 | - | // enter serial; check the exact wire arguments. | |
| 642 | - | pointer := core.NewPointer(d.Context()) | |
| 643 | - | pointer.SetID(d.AllocateID()) | |
| 644 | - | d.Context().Register(pointer) | |
| 645 | - | shapes := cursorshape.NewWpCursorShapeManager(d.Context()) | |
| 646 | - | bind(t, d, p, 8, cursorshape.WpCursorShapeManagerInterface, 2, 1, shapes) | |
| 647 | - | shape, e := shapes.GetPointer(pointer) | |
| 648 | - | noerr(t, e) | |
| 649 | - | if id, op, b := request(t, p); id != shapes.ID() || op != 1 || binary.NativeEndian.Uint32(b) != shape.ID() || binary.NativeEndian.Uint32(b[4:]) != pointer.ID() { | |
| 650 | - | t.Fatalf("get_pointer wire id=%d op=%d %x", id, op, b) | |
| 651 | - | } | |
| 652 | - | noerr(t, shape.SetShape(42, cursorshape.SHAPE_POINTER)) | |
| 653 | - | if id, op, b := request(t, p); id != shape.ID() || op != 1 || binary.NativeEndian.Uint32(b) != 42 || binary.NativeEndian.Uint32(b[4:]) != 4 { | |
| 654 | - | t.Fatalf("set_shape wire id=%d op=%d %x", id, op, b) | |
| 655 | - | } | |
| 656 | - | noerr(t, shape.Destroy()) | |
| 657 | - | request(t, p) | |
| 658 | - | noerr(t, shapes.Destroy()) | |
| 659 | - | request(t, p) | |
| 660 | - | ||
| 661 | - | } | |
| 662 | - | ||
| 663 | - | func TestLiveFeedback(t *testing.T) { | |
| 664 | - | if os.Getenv("WLTURBO_LIVE") != "1" { | |
| 665 | - | t.Skip("set WLTURBO_LIVE=1") | |
| 666 | - | } | |
| 667 | - | d, e := wlturbo.Connect("") | |
| 668 | - | noerr(t, e) | |
| 669 | - | defer d.Close() | |
| 670 | - | noerr(t, d.Roundtrip()) | |
| 671 | - | for _, iface := range []string{xdgshell.XdgWmBaseInterface, linuxdmabuf.LinuxDmabufInterface, drmsyncobj.WpLinuxDrmSyncobjManagerInterface, viewporter.WpViewporterInterface, fractionalscale.WpFractionalScaleManagerInterface, textinput.TextInputManagerV3Interface, cursorshape.WpCursorShapeManagerInterface} { | |
| 672 | - | g, ok := d.Registry().FindGlobal(iface) | |
| 673 | - | if !ok { | |
| 674 | - | t.Logf("%s absent", iface) | |
| 675 | - | continue | |
| 676 | - | } | |
| 677 | - | v := g.Version | |
| 678 | - | cap := uint32(1) | |
| 679 | - | if iface == xdgshell.XdgWmBaseInterface { | |
| 680 | - | cap = 7 | |
| 681 | - | } | |
| 682 | - | if iface == linuxdmabuf.LinuxDmabufInterface { | |
| 683 | - | cap = 4 | |
| 684 | - | } | |
| 685 | - | if v > cap { | |
| 686 | - | v = cap | |
| 687 | - | } | |
| 688 | - | t.Logf("%s negotiated=%d (server=%d)", iface, v, g.Version) | |
| 689 | - | if iface != linuxdmabuf.LinuxDmabufInterface { | |
| 690 | - | continue | |
| 691 | - | } | |
| 692 | - | if v < 4 { | |
| 693 | - | t.Fatal("dmabuf feedback requires v4") | |
| 694 | - | } | |
| 695 | - | dm := linuxdmabuf.NewLinuxDmabuf(d.Context()) | |
| 696 | - | negotiated, err := d.Registry().BindNegotiated(iface, 4, dm) | |
| 697 | - | noerr(t, err) | |
| 698 | - | if negotiated != v { | |
| 699 | - | t.Fatalf("dmabuf negotiated=%d want=%d", negotiated, v) | |
| 700 | - | } | |
| 701 | - | fb, e := dm.GetDefaultFeedback() | |
| 702 | - | noerr(t, e) | |
| 703 | - | done := false | |
| 704 | - | fb.OnMainDevice(func(b []byte) { t.Logf("main_device=%x", b) }) | |
| 705 | - | fb.OnFormatTable(func(fd *wlturbo.OwnedFD, size uint32) { | |
| 706 | - | entries, err := linuxdmabuf.ReadFormatTable(fd, size) | |
| 707 | - | if err != nil { | |
| 708 | - | t.Errorf("table: %v", err) | |
| 709 | - | } | |
| 710 | - | t.Logf("format-table entries=%d", len(entries)) | |
| 711 | - | }) | |
| 712 | - | fb.OnDone(func() { done = true }) | |
| 713 | - | for i := 0; i < 100 && !done; i++ { | |
| 714 | - | noerr(t, d.Dispatch()) | |
| 715 | - | } | |
| 716 | - | if !done { | |
| 717 | - | t.Fatal("no feedback done") | |
| 718 | - | } | |
| 719 | - | noerr(t, fb.Destroy()) | |
| 720 | - | noerr(t, dm.Destroy()) | |
| 721 | - | } | |
| 722 | - | } | |
D protocol/extforeigntoplevel/ext-foreign-toplevel-list-v1.xml +0 -219
| @@ -1,219 +0,0 @@ | |||
| 1 | - | <?xml version="1.0" encoding="UTF-8"?> | |
| 2 | - | <protocol name="ext_foreign_toplevel_list_v1"> | |
| 3 | - | <copyright> | |
| 4 | - | Copyright © 2018 Ilia Bozhinov | |
| 5 | - | Copyright © 2020 Isaac Freund | |
| 6 | - | Copyright © 2022 wb9688 | |
| 7 | - | Copyright © 2023 i509VCB | |
| 8 | - | ||
| 9 | - | Permission to use, copy, modify, distribute, and sell this | |
| 10 | - | software and its documentation for any purpose is hereby granted | |
| 11 | - | without fee, provided that the above copyright notice appear in | |
| 12 | - | all copies and that both that copyright notice and this permission | |
| 13 | - | notice appear in supporting documentation, and that the name of | |
| 14 | - | the copyright holders not be used in advertising or publicity | |
| 15 | - | pertaining to distribution of the software without specific, | |
| 16 | - | written prior permission. The copyright holders make no | |
| 17 | - | representations about the suitability of this software for any | |
| 18 | - | purpose. It is provided "as is" without express or implied | |
| 19 | - | warranty. | |
| 20 | - | ||
| 21 | - | THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS | |
| 22 | - | SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | |
| 23 | - | FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY | |
| 24 | - | SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
| 25 | - | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN | |
| 26 | - | AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | |
| 27 | - | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF | |
| 28 | - | THIS SOFTWARE. | |
| 29 | - | </copyright> | |
| 30 | - | ||
| 31 | - | <description summary="list toplevels"> | |
| 32 | - | The purpose of this protocol is to provide protocol object handles for | |
| 33 | - | toplevels, possibly originating from another client. | |
| 34 | - | ||
| 35 | - | This protocol is intentionally minimalistic and expects additional | |
| 36 | - | functionality (e.g. creating a screencopy source from a toplevel handle, | |
| 37 | - | getting information about the state of the toplevel) to be implemented | |
| 38 | - | in extension protocols. | |
| 39 | - | ||
| 40 | - | The compositor may choose to restrict this protocol to a special client | |
| 41 | - | launched by the compositor itself or expose it to all clients, | |
| 42 | - | this is compositor policy. | |
| 43 | - | ||
| 44 | - | The key words "must", "must not", "required", "shall", "shall not", | |
| 45 | - | "should", "should not", "recommended", "may", and "optional" in this | |
| 46 | - | document are to be interpreted as described in IETF RFC 2119. | |
| 47 | - | ||
| 48 | - | Warning! The protocol described in this file is currently in the testing | |
| 49 | - | phase. Backward compatible changes may be added together with the | |
| 50 | - | corresponding interface version bump. Backward incompatible changes can | |
| 51 | - | only be done by creating a new major version of the extension. | |
| 52 | - | </description> | |
| 53 | - | ||
| 54 | - | <interface name="ext_foreign_toplevel_list_v1" version="1"> | |
| 55 | - | <description summary="list toplevels"> | |
| 56 | - | A toplevel is defined as a surface with a role similar to xdg_toplevel. | |
| 57 | - | XWayland surfaces may be treated like toplevels in this protocol. | |
| 58 | - | ||
| 59 | - | After a client binds the ext_foreign_toplevel_list_v1, each mapped | |
| 60 | - | toplevel window will be sent using the ext_foreign_toplevel_list_v1.toplevel | |
| 61 | - | event. | |
| 62 | - | ||
| 63 | - | Clients which only care about the current state can perform a roundtrip after | |
| 64 | - | binding this global. | |
| 65 | - | ||
| 66 | - | For each instance of ext_foreign_toplevel_list_v1, the compositor must | |
| 67 | - | create a new ext_foreign_toplevel_handle_v1 object for each mapped toplevel. | |
| 68 | - | ||
| 69 | - | If a compositor implementation sends the ext_foreign_toplevel_list_v1.finished | |
| 70 | - | event after the global is bound, the compositor must not send any | |
| 71 | - | ext_foreign_toplevel_list_v1.toplevel events. | |
| 72 | - | </description> | |
| 73 | - | ||
| 74 | - | <event name="toplevel"> | |
| 75 | - | <description summary="a toplevel has been created"> | |
| 76 | - | This event is emitted whenever a new toplevel window is created. It is | |
| 77 | - | emitted for all toplevels, regardless of the app that has created them. | |
| 78 | - | ||
| 79 | - | All initial properties of the toplevel (identifier, title, app_id) will be sent | |
| 80 | - | immediately after this event using the corresponding events for | |
| 81 | - | ext_foreign_toplevel_handle_v1. The compositor will use the | |
| 82 | - | ext_foreign_toplevel_handle_v1.done event to indicate when all data has | |
| 83 | - | been sent. | |
| 84 | - | </description> | |
| 85 | - | <arg name="toplevel" type="new_id" interface="ext_foreign_toplevel_handle_v1"/> | |
| 86 | - | </event> | |
| 87 | - | ||
| 88 | - | <event name="finished"> | |
| 89 | - | <description summary="the compositor has finished with the toplevel manager"> | |
| 90 | - | This event indicates that the compositor is done sending events | |
| 91 | - | to this object. The client should destroy the object. | |
| 92 | - | See ext_foreign_toplevel_list_v1.destroy for more information. | |
| 93 | - | ||
| 94 | - | The compositor must not send any more toplevel events after this event. | |
| 95 | - | </description> | |
| 96 | - | </event> | |
| 97 | - | ||
| 98 | - | <request name="stop"> | |
| 99 | - | <description summary="stop sending events"> | |
| 100 | - | This request indicates that the client no longer wishes to receive | |
| 101 | - | events for new toplevels. | |
| 102 | - | ||
| 103 | - | The Wayland protocol is asynchronous, meaning the compositor may send | |
| 104 | - | further toplevel events until the stop request is processed. | |
| 105 | - | The client should wait for a ext_foreign_toplevel_list_v1.finished | |
| 106 | - | event before destroying this object. | |
| 107 | - | </description> | |
| 108 | - | </request> | |
| 109 | - | ||
| 110 | - | <request name="destroy" type="destructor"> | |
| 111 | - | <description summary="destroy the ext_foreign_toplevel_list_v1 object"> | |
| 112 | - | This request should be called either when the client will no longer | |
| 113 | - | use the ext_foreign_toplevel_list_v1 or after the finished event | |
| 114 | - | has been received to allow destruction of the object. | |
| 115 | - | ||
| 116 | - | If a client wishes to destroy this object it should send a | |
| 117 | - | ext_foreign_toplevel_list_v1.stop request and wait for a ext_foreign_toplevel_list_v1.finished | |
| 118 | - | event, then destroy the handles and then this object. | |
| 119 | - | </description> | |
| 120 | - | </request> | |
| 121 | - | </interface> | |
| 122 | - | ||
| 123 | - | <interface name="ext_foreign_toplevel_handle_v1" version="1"> | |
| 124 | - | <description summary="a mapped toplevel"> | |
| 125 | - | A ext_foreign_toplevel_handle_v1 object represents a mapped toplevel | |
| 126 | - | window. A single app may have multiple mapped toplevels. | |
| 127 | - | </description> | |
| 128 | - | ||
| 129 | - | <request name="destroy" type="destructor"> | |
| 130 | - | <description summary="destroy the ext_foreign_toplevel_handle_v1 object"> | |
| 131 | - | This request should be used when the client will no longer use the handle | |
| 132 | - | or after the closed event has been received to allow destruction of the | |
| 133 | - | object. | |
| 134 | - | ||
| 135 | - | When a handle is destroyed, a new handle may not be created by the server | |
| 136 | - | until the toplevel is unmapped and then remapped. Destroying a toplevel handle | |
| 137 | - | is not recommended unless the client is cleaning up child objects | |
| 138 | - | before destroying the ext_foreign_toplevel_list_v1 object, the toplevel | |
| 139 | - | was closed or the toplevel handle will not be used in the future. | |
| 140 | - | ||
| 141 | - | Other protocols which extend the ext_foreign_toplevel_handle_v1 | |
| 142 | - | interface should require destructors for extension interfaces be | |
| 143 | - | called before allowing the toplevel handle to be destroyed. | |
| 144 | - | </description> | |
| 145 | - | </request> | |
| 146 | - | ||
| 147 | - | <event name="closed"> | |
| 148 | - | <description summary="the toplevel has been closed"> | |
| 149 | - | The server will emit no further events on the ext_foreign_toplevel_handle_v1 | |
| 150 | - | after this event. Any requests received aside from the destroy request must | |
| 151 | - | be ignored. Upon receiving this event, the client should destroy the handle. | |
| 152 | - | ||
| 153 | - | Other protocols which extend the ext_foreign_toplevel_handle_v1 | |
| 154 | - | interface must also ignore requests other than destructors. | |
| 155 | - | </description> | |
| 156 | - | </event> | |
| 157 | - | ||
| 158 | - | <event name="done"> | |
| 159 | - | <description summary="all information about the toplevel has been sent"> | |
| 160 | - | This event is sent after all changes in the toplevel state have | |
| 161 | - | been sent. | |
| 162 | - | ||
| 163 | - | This allows changes to the ext_foreign_toplevel_handle_v1 properties | |
| 164 | - | to be atomically applied. Other protocols which extend the | |
| 165 | - | ext_foreign_toplevel_handle_v1 interface may use this event to also | |
| 166 | - | atomically apply any pending state. | |
| 167 | - | ||
| 168 | - | This event must not be sent after the ext_foreign_toplevel_handle_v1.closed | |
| 169 | - | event. | |
| 170 | - | </description> | |
| 171 | - | </event> | |
| 172 | - | ||
| 173 | - | <event name="title"> | |
| 174 | - | <description summary="title change"> | |
| 175 | - | The title of the toplevel has changed. | |
| 176 | - | ||
| 177 | - | The configured state must not be applied immediately. See | |
| 178 | - | ext_foreign_toplevel_handle_v1.done for details. | |
| 179 | - | </description> | |
| 180 | - | <arg name="title" type="string"/> | |
| 181 | - | </event> | |
| 182 | - | ||
| 183 | - | <event name="app_id"> | |
| 184 | - | <description summary="app_id change"> | |
| 185 | - | The app id of the toplevel has changed. | |
| 186 | - | ||
| 187 | - | The configured state must not be applied immediately. See | |
| 188 | - | ext_foreign_toplevel_handle_v1.done for details. | |
| 189 | - | </description> | |
| 190 | - | <arg name="app_id" type="string"/> | |
| 191 | - | </event> | |
| 192 | - | ||
| 193 | - | <event name="identifier"> | |
| 194 | - | <description summary="a stable identifier for a toplevel"> | |
| 195 | - | This identifier is used to check if two or more toplevel handles belong | |
| 196 | - | to the same toplevel. | |
| 197 | - | ||
| 198 | - | The identifier is useful for command line tools or privileged clients | |
| 199 | - | which may need to reference an exact toplevel across processes or | |
| 200 | - | instances of the ext_foreign_toplevel_list_v1 global. | |
| 201 | - | ||
| 202 | - | The compositor must only send this event when the handle is created. | |
| 203 | - | ||
| 204 | - | The identifier must be unique per toplevel and its handles. Two different | |
| 205 | - | toplevels must not have the same identifier. The identifier is only valid | |
| 206 | - | as long as the toplevel is mapped. If the toplevel is unmapped the identifier | |
| 207 | - | must not be reused. An identifier must not be reused by the compositor to | |
| 208 | - | ensure there are no races when sharing identifiers between processes. | |
| 209 | - | ||
| 210 | - | An identifier is a string that contains up to 32 printable ASCII bytes. | |
| 211 | - | An identifier must not be an empty string. It is recommended that a | |
| 212 | - | compositor includes an opaque generation value in identifiers. How the | |
| 213 | - | generation value is used when generating the identifier is implementation | |
| 214 | - | dependent. | |
| 215 | - | </description> | |
| 216 | - | <arg name="identifier" type="string"/> | |
| 217 | - | </event> | |
| 218 | - | </interface> | |
| 219 | - | </protocol> | |
D protocol/extforeigntoplevel/ext-foreign-toplevel-list-v1_generated.go +0 -356
| @@ -1,356 +0,0 @@ | |||
| 1 | - | // Code generated by wlturbo-scanner. DO NOT EDIT. | |
| 2 | - | // Protocol: ext_foreign_toplevel_list_v1 | |
| 3 | - | // Source: ext-foreign-toplevel-list-v1.xml | |
| 4 | - | ||
| 5 | - | // Upstream protocol copyright and license: | |
| 6 | - | // Copyright © 2018 Ilia Bozhinov | |
| 7 | - | // Copyright © 2020 Isaac Freund | |
| 8 | - | // Copyright © 2022 wb9688 | |
| 9 | - | // Copyright © 2023 i509VCB | |
| 10 | - | // | |
| 11 | - | // Permission to use, copy, modify, distribute, and sell this | |
| 12 | - | // software and its documentation for any purpose is hereby granted | |
| 13 | - | // without fee, provided that the above copyright notice appear in | |
| 14 | - | // all copies and that both that copyright notice and this permission | |
| 15 | - | // notice appear in supporting documentation, and that the name of | |
| 16 | - | // the copyright holders not be used in advertising or publicity | |
| 17 | - | // pertaining to distribution of the software without specific, | |
| 18 | - | // written prior permission. The copyright holders make no | |
| 19 | - | // representations about the suitability of this software for any | |
| 20 | - | // purpose. It is provided "as is" without express or implied | |
| 21 | - | // warranty. | |
| 22 | - | // | |
| 23 | - | // THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS | |
| 24 | - | // SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | |
| 25 | - | // FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY | |
| 26 | - | // SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
| 27 | - | // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN | |
| 28 | - | // AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | |
| 29 | - | // ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF | |
| 30 | - | // THIS SOFTWARE. | |
| 31 | - | ||
| 32 | - | package extforeigntoplevel | |
| 33 | - | ||
| 34 | - | import ( | |
| 35 | - | "sync" | |
| 36 | - | ||
| 37 | - | "github.com/bnema/wlturbo/wl" | |
| 38 | - | ) | |
| 39 | - | ||
| 40 | - | // ExtForeignToplevelListInterface is the protocol interface name. | |
| 41 | - | const ExtForeignToplevelListInterface = "ext_foreign_toplevel_list_v1" | |
| 42 | - | ||
| 43 | - | // ExtForeignToplevelList is the generated binding for ext_foreign_toplevel_list_v1 version 1. | |
| 44 | - | type ExtForeignToplevelList struct { | |
| 45 | - | wl.BaseProxy | |
| 46 | - | // handlersMu guards the handler slices: a client may register or replace | |
| 47 | - | // handlers while another goroutine dispatches events. | |
| 48 | - | handlersMu sync.Mutex | |
| 49 | - | onToplevel []func(toplevelObject *ExtForeignToplevelHandle) | |
| 50 | - | onFinished []func() | |
| 51 | - | } | |
| 52 | - | ||
| 53 | - | // NewExtForeignToplevelList returns an unbound ExtForeignToplevelList. | |
| 54 | - | func NewExtForeignToplevelList(ctx *wl.Context) *ExtForeignToplevelList { | |
| 55 | - | obj := &ExtForeignToplevelList{} | |
| 56 | - | obj.SetContext(ctx) | |
| 57 | - | ctx.Register(obj) | |
| 58 | - | return obj | |
| 59 | - | } | |
| 60 | - | ||
| 61 | - | // 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. | |
| 62 | - | func (o *ExtForeignToplevelList) Stop() error { | |
| 63 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "ext_foreign_toplevel_list_v1.stop"}); err != nil { | |
| 64 | - | return err | |
| 65 | - | } | |
| 66 | - | return nil | |
| 67 | - | } | |
| 68 | - | ||
| 69 | - | // 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. | |
| 70 | - | func (o *ExtForeignToplevelList) Destroy() error { | |
| 71 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "ext_foreign_toplevel_list_v1.destroy", Destructor: true}); err != nil { | |
| 72 | - | return err | |
| 73 | - | } | |
| 74 | - | return nil | |
| 75 | - | } | |
| 76 | - | ||
| 77 | - | // OnToplevel registers a handler for the toplevel event. | |
| 78 | - | // | |
| 79 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 80 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 81 | - | func (o *ExtForeignToplevelList) OnToplevel(handler func(toplevelObject *ExtForeignToplevelHandle)) { | |
| 82 | - | if handler == nil { | |
| 83 | - | return | |
| 84 | - | } | |
| 85 | - | o.handlersMu.Lock() | |
| 86 | - | defer o.handlersMu.Unlock() | |
| 87 | - | o.onToplevel = append(o.onToplevel, handler) | |
| 88 | - | } | |
| 89 | - | ||
| 90 | - | // handlersForToplevel returns the handlers registered for toplevel, taken | |
| 91 | - | // under the lock so a handler may register another handler while events are | |
| 92 | - | // being dispatched. | |
| 93 | - | func (o *ExtForeignToplevelList) handlersForToplevel() []func(toplevelObject *ExtForeignToplevelHandle) { | |
| 94 | - | o.handlersMu.Lock() | |
| 95 | - | defer o.handlersMu.Unlock() | |
| 96 | - | return o.onToplevel | |
| 97 | - | } | |
| 98 | - | ||
| 99 | - | // OnFinished registers a handler for the finished event. | |
| 100 | - | // | |
| 101 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 102 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 103 | - | func (o *ExtForeignToplevelList) OnFinished(handler func()) { | |
| 104 | - | if handler == nil { | |
| 105 | - | return | |
| 106 | - | } | |
| 107 | - | o.handlersMu.Lock() | |
| 108 | - | defer o.handlersMu.Unlock() | |
| 109 | - | o.onFinished = append(o.onFinished, handler) | |
| 110 | - | } | |
| 111 | - | ||
| 112 | - | // handlersForFinished returns the handlers registered for finished, taken | |
| 113 | - | // under the lock so a handler may register another handler while events are | |
| 114 | - | // being dispatched. | |
| 115 | - | func (o *ExtForeignToplevelList) handlersForFinished() []func() { | |
| 116 | - | o.handlersMu.Lock() | |
| 117 | - | defer o.handlersMu.Unlock() | |
| 118 | - | return o.onFinished | |
| 119 | - | } | |
| 120 | - | ||
| 121 | - | // EventSignature returns the declared event argument types in wire order. | |
| 122 | - | func (o *ExtForeignToplevelList) EventSignature(opcode uint16) (string, bool) { | |
| 123 | - | switch opcode { | |
| 124 | - | case 0: | |
| 125 | - | return "new_id,", true | |
| 126 | - | case 1: | |
| 127 | - | return "", true | |
| 128 | - | default: | |
| 129 | - | return "", false | |
| 130 | - | } | |
| 131 | - | } | |
| 132 | - | ||
| 133 | - | // Dispatch decodes one event on ext_foreign_toplevel_list_v1 and calls the registered handlers. | |
| 134 | - | func (o *ExtForeignToplevelList) Dispatch(event *wl.Event) { | |
| 135 | - | switch event.Opcode { | |
| 136 | - | case 0: // toplevel | |
| 137 | - | toplevelID := event.Uint32() | |
| 138 | - | toplevelObject := &ExtForeignToplevelHandle{} | |
| 139 | - | toplevelObject.SetContext(o.Context()) | |
| 140 | - | toplevelObject.SetID(toplevelID) | |
| 141 | - | toplevelObject.SetVersion(o.Version()) | |
| 142 | - | o.Context().Register(toplevelObject) | |
| 143 | - | ||
| 144 | - | for i, handler := range o.handlersForToplevel() { | |
| 145 | - | _ = i | |
| 146 | - | handler(toplevelObject) | |
| 147 | - | } | |
| 148 | - | case 1: // finished | |
| 149 | - | ||
| 150 | - | for i, handler := range o.handlersForFinished() { | |
| 151 | - | _ = i | |
| 152 | - | handler() | |
| 153 | - | } | |
| 154 | - | default: | |
| 155 | - | } | |
| 156 | - | } | |
| 157 | - | ||
| 158 | - | // ExtForeignToplevelHandleInterface is the protocol interface name. | |
| 159 | - | const ExtForeignToplevelHandleInterface = "ext_foreign_toplevel_handle_v1" | |
| 160 | - | ||
| 161 | - | // ExtForeignToplevelHandle is the generated binding for ext_foreign_toplevel_handle_v1 version 1. | |
| 162 | - | type ExtForeignToplevelHandle struct { | |
| 163 | - | wl.BaseProxy | |
| 164 | - | // handlersMu guards the handler slices: a client may register or replace | |
| 165 | - | // handlers while another goroutine dispatches events. | |
| 166 | - | handlersMu sync.Mutex | |
| 167 | - | onClosed []func() | |
| 168 | - | onDone []func() | |
| 169 | - | onTitle []func(title string) | |
| 170 | - | onAppId []func(appId string) | |
| 171 | - | onIdentifier []func(identifier string) | |
| 172 | - | } | |
| 173 | - | ||
| 174 | - | // NewExtForeignToplevelHandle returns an unbound ExtForeignToplevelHandle. | |
| 175 | - | func NewExtForeignToplevelHandle(ctx *wl.Context) *ExtForeignToplevelHandle { | |
| 176 | - | obj := &ExtForeignToplevelHandle{} | |
| 177 | - | obj.SetContext(ctx) | |
| 178 | - | ctx.Register(obj) | |
| 179 | - | return obj | |
| 180 | - | } | |
| 181 | - | ||
| 182 | - | // 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. | |
| 183 | - | func (o *ExtForeignToplevelHandle) Destroy() error { | |
| 184 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "ext_foreign_toplevel_handle_v1.destroy", Destructor: true}); err != nil { | |
| 185 | - | return err | |
| 186 | - | } | |
| 187 | - | return nil | |
| 188 | - | } | |
| 189 | - | ||
| 190 | - | // OnClosed registers a handler for the closed event. | |
| 191 | - | // | |
| 192 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 193 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 194 | - | func (o *ExtForeignToplevelHandle) OnClosed(handler func()) { | |
| 195 | - | if handler == nil { | |
| 196 | - | return | |
| 197 | - | } | |
| 198 | - | o.handlersMu.Lock() | |
| 199 | - | defer o.handlersMu.Unlock() | |
| 200 | - | o.onClosed = append(o.onClosed, handler) | |
| 201 | - | } | |
| 202 | - | ||
| 203 | - | // handlersForClosed returns the handlers registered for closed, taken | |
| 204 | - | // under the lock so a handler may register another handler while events are | |
| 205 | - | // being dispatched. | |
| 206 | - | func (o *ExtForeignToplevelHandle) handlersForClosed() []func() { | |
| 207 | - | o.handlersMu.Lock() | |
| 208 | - | defer o.handlersMu.Unlock() | |
| 209 | - | return o.onClosed | |
| 210 | - | } | |
| 211 | - | ||
| 212 | - | // OnDone registers a handler for the done event. | |
| 213 | - | // | |
| 214 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 215 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 216 | - | func (o *ExtForeignToplevelHandle) OnDone(handler func()) { | |
| 217 | - | if handler == nil { | |
| 218 | - | return | |
| 219 | - | } | |
| 220 | - | o.handlersMu.Lock() | |
| 221 | - | defer o.handlersMu.Unlock() | |
| 222 | - | o.onDone = append(o.onDone, handler) | |
| 223 | - | } | |
| 224 | - | ||
| 225 | - | // handlersForDone returns the handlers registered for done, taken | |
| 226 | - | // under the lock so a handler may register another handler while events are | |
| 227 | - | // being dispatched. | |
| 228 | - | func (o *ExtForeignToplevelHandle) handlersForDone() []func() { | |
| 229 | - | o.handlersMu.Lock() | |
| 230 | - | defer o.handlersMu.Unlock() | |
| 231 | - | return o.onDone | |
| 232 | - | } | |
| 233 | - | ||
| 234 | - | // OnTitle registers a handler for the title event. | |
| 235 | - | // | |
| 236 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 237 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 238 | - | func (o *ExtForeignToplevelHandle) OnTitle(handler func(title string)) { | |
| 239 | - | if handler == nil { | |
| 240 | - | return | |
| 241 | - | } | |
| 242 | - | o.handlersMu.Lock() | |
| 243 | - | defer o.handlersMu.Unlock() | |
| 244 | - | o.onTitle = append(o.onTitle, handler) | |
| 245 | - | } | |
| 246 | - | ||
| 247 | - | // handlersForTitle returns the handlers registered for title, taken | |
| 248 | - | // under the lock so a handler may register another handler while events are | |
| 249 | - | // being dispatched. | |
| 250 | - | func (o *ExtForeignToplevelHandle) handlersForTitle() []func(title string) { | |
| 251 | - | o.handlersMu.Lock() | |
| 252 | - | defer o.handlersMu.Unlock() | |
| 253 | - | return o.onTitle | |
| 254 | - | } | |
| 255 | - | ||
| 256 | - | // OnAppId registers a handler for the app_id event. | |
| 257 | - | // | |
| 258 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 259 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 260 | - | func (o *ExtForeignToplevelHandle) OnAppId(handler func(appId string)) { | |
| 261 | - | if handler == nil { | |
| 262 | - | return | |
| 263 | - | } | |
| 264 | - | o.handlersMu.Lock() | |
| 265 | - | defer o.handlersMu.Unlock() | |
| 266 | - | o.onAppId = append(o.onAppId, handler) | |
| 267 | - | } | |
| 268 | - | ||
| 269 | - | // handlersForAppId returns the handlers registered for app_id, taken | |
| 270 | - | // under the lock so a handler may register another handler while events are | |
| 271 | - | // being dispatched. | |
| 272 | - | func (o *ExtForeignToplevelHandle) handlersForAppId() []func(appId string) { | |
| 273 | - | o.handlersMu.Lock() | |
| 274 | - | defer o.handlersMu.Unlock() | |
| 275 | - | return o.onAppId | |
| 276 | - | } | |
| 277 | - | ||
| 278 | - | // OnIdentifier registers a handler for the identifier event. | |
| 279 | - | // | |
| 280 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 281 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 282 | - | func (o *ExtForeignToplevelHandle) OnIdentifier(handler func(identifier string)) { | |
| 283 | - | if handler == nil { | |
| 284 | - | return | |
| 285 | - | } | |
| 286 | - | o.handlersMu.Lock() | |
| 287 | - | defer o.handlersMu.Unlock() | |
| 288 | - | o.onIdentifier = append(o.onIdentifier, handler) | |
| 289 | - | } | |
| 290 | - | ||
| 291 | - | // handlersForIdentifier returns the handlers registered for identifier, taken | |
| 292 | - | // under the lock so a handler may register another handler while events are | |
| 293 | - | // being dispatched. | |
| 294 | - | func (o *ExtForeignToplevelHandle) handlersForIdentifier() []func(identifier string) { | |
| 295 | - | o.handlersMu.Lock() | |
| 296 | - | defer o.handlersMu.Unlock() | |
| 297 | - | return o.onIdentifier | |
| 298 | - | } | |
| 299 | - | ||
| 300 | - | // EventSignature returns the declared event argument types in wire order. | |
| 301 | - | func (o *ExtForeignToplevelHandle) EventSignature(opcode uint16) (string, bool) { | |
| 302 | - | switch opcode { | |
| 303 | - | case 0: | |
| 304 | - | return "", true | |
| 305 | - | case 1: | |
| 306 | - | return "", true | |
| 307 | - | case 2: | |
| 308 | - | return "string,", true | |
| 309 | - | case 3: | |
| 310 | - | return "string,", true | |
| 311 | - | case 4: | |
| 312 | - | return "string,", true | |
| 313 | - | default: | |
| 314 | - | return "", false | |
| 315 | - | } | |
| 316 | - | } | |
| 317 | - | ||
| 318 | - | // Dispatch decodes one event on ext_foreign_toplevel_handle_v1 and calls the registered handlers. | |
| 319 | - | func (o *ExtForeignToplevelHandle) Dispatch(event *wl.Event) { | |
| 320 | - | switch event.Opcode { | |
| 321 | - | case 0: // closed | |
| 322 | - | ||
| 323 | - | for i, handler := range o.handlersForClosed() { | |
| 324 | - | _ = i | |
| 325 | - | handler() | |
| 326 | - | } | |
| 327 | - | case 1: // done | |
| 328 | - | ||
| 329 | - | for i, handler := range o.handlersForDone() { | |
| 330 | - | _ = i | |
| 331 | - | handler() | |
| 332 | - | } | |
| 333 | - | case 2: // title | |
| 334 | - | title := event.String() | |
| 335 | - | ||
| 336 | - | for i, handler := range o.handlersForTitle() { | |
| 337 | - | _ = i | |
| 338 | - | handler(title) | |
| 339 | - | } | |
| 340 | - | case 3: // app_id | |
| 341 | - | appId := event.String() | |
| 342 | - | ||
| 343 | - | for i, handler := range o.handlersForAppId() { | |
| 344 | - | _ = i | |
| 345 | - | handler(appId) | |
| 346 | - | } | |
| 347 | - | case 4: // identifier | |
| 348 | - | identifier := event.String() | |
| 349 | - | ||
| 350 | - | for i, handler := range o.handlersForIdentifier() { | |
| 351 | - | _ = i | |
| 352 | - | handler(identifier) | |
| 353 | - | } | |
| 354 | - | default: | |
| 355 | - | } | |
| 356 | - | } | |
D protocol/extforeigntoplevel/generate.go +0 -3
| @@ -1,3 +0,0 @@ | |||
| 1 | - | package extforeigntoplevel | |
| 2 | - | ||
| 3 | - | //go:generate go run ../../cmd/wlturbo-scanner -p extforeigntoplevel -o ext-foreign-toplevel-list-v1_generated.go ext-foreign-toplevel-list-v1.xml | |
D protocol/extsessionlock/ext-session-lock-v1.xml +0 -328
| @@ -1,328 +0,0 @@ | |||
| 1 | - | <?xml version="1.0" encoding="UTF-8"?> | |
| 2 | - | <protocol name="ext_session_lock_v1"> | |
| 3 | - | <copyright> | |
| 4 | - | Copyright 2021 Isaac Freund | |
| 5 | - | ||
| 6 | - | Permission is hereby granted, free of charge, to any person obtaining a | |
| 7 | - | copy of this software and associated documentation files (the "Software"), | |
| 8 | - | to deal in the Software without restriction, including without limitation | |
| 9 | - | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 10 | - | and/or sell copies of the Software, and to permit persons to whom the | |
| 11 | - | Software is furnished to do so, subject to the following conditions: | |
| 12 | - | ||
| 13 | - | The above copyright notice and this permission notice shall be included in | |
| 14 | - | all copies or substantial portions of the Software. | |
| 15 | - | ||
| 16 | - | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 17 | - | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 18 | - | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 19 | - | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 20 | - | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
| 21 | - | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
| 22 | - | THE SOFTWARE. | |
| 23 | - | </copyright> | |
| 24 | - | ||
| 25 | - | <description summary="secure session locking with arbitrary graphics"> | |
| 26 | - | This protocol allows for a privileged Wayland client to lock the session | |
| 27 | - | and display arbitrary graphics while the session is locked. | |
| 28 | - | ||
| 29 | - | The compositor may choose to restrict this protocol to a special client | |
| 30 | - | launched by the compositor itself or expose it to all privileged clients, | |
| 31 | - | this is compositor policy. | |
| 32 | - | ||
| 33 | - | The client is responsible for performing authentication and informing the | |
| 34 | - | compositor when the session should be unlocked. If the client dies while | |
| 35 | - | the session is locked the session remains locked, possibly permanently | |
| 36 | - | depending on compositor policy. | |
| 37 | - | ||
| 38 | - | The key words "must", "must not", "required", "shall", "shall not", | |
| 39 | - | "should", "should not", "recommended", "may", and "optional" in this | |
| 40 | - | document are to be interpreted as described in IETF RFC 2119. | |
| 41 | - | ||
| 42 | - | Warning! The protocol described in this file is currently in the | |
| 43 | - | testing phase. Backward compatible changes may be added together with | |
| 44 | - | the corresponding interface version bump. Backward incompatible changes | |
| 45 | - | can only be done by creating a new major version of the extension. | |
| 46 | - | </description> | |
| 47 | - | ||
| 48 | - | <interface name="ext_session_lock_manager_v1" version="1"> | |
| 49 | - | <description summary="used to lock the session"> | |
| 50 | - | This interface is used to request that the session be locked. | |
| 51 | - | </description> | |
| 52 | - | ||
| 53 | - | <request name="destroy" type="destructor"> | |
| 54 | - | <description summary="destroy the session lock manager object"> | |
| 55 | - | This informs the compositor that the session lock manager object will | |
| 56 | - | no longer be used. Existing objects created through this interface | |
| 57 | - | remain valid. | |
| 58 | - | </description> | |
| 59 | - | </request> | |
| 60 | - | ||
| 61 | - | <request name="lock"> | |
| 62 | - | <description summary="attempt to lock the session"> | |
| 63 | - | This request creates a session lock and asks the compositor to lock the | |
| 64 | - | session. The compositor will send either the ext_session_lock_v1.locked | |
| 65 | - | or ext_session_lock_v1.finished event on the created object in | |
| 66 | - | response to this request. | |
| 67 | - | </description> | |
| 68 | - | <arg name="id" type="new_id" interface="ext_session_lock_v1"/> | |
| 69 | - | </request> | |
| 70 | - | </interface> | |
| 71 | - | ||
| 72 | - | <interface name="ext_session_lock_v1" version="1"> | |
| 73 | - | <description summary="manage lock state and create lock surfaces"> | |
| 74 | - | In response to the creation of this object the compositor must send | |
| 75 | - | either the locked or finished event. | |
| 76 | - | ||
| 77 | - | The locked event indicates that the session is locked. This means | |
| 78 | - | that the compositor must stop rendering and providing input to normal | |
| 79 | - | clients. Instead the compositor must blank all outputs with an opaque | |
| 80 | - | color such that their normal content is fully hidden. | |
| 81 | - | ||
| 82 | - | The only surfaces that should be rendered while the session is locked | |
| 83 | - | are the lock surfaces created through this interface and optionally, | |
| 84 | - | at the compositor's discretion, special privileged surfaces such as | |
| 85 | - | input methods or portions of desktop shell UIs. | |
| 86 | - | ||
| 87 | - | The locked event must not be sent until a new "locked" frame (either | |
| 88 | - | from a session lock surface or the compositor blanking the output) has | |
| 89 | - | been presented on all outputs and no security sensitive normal/unlocked | |
| 90 | - | content is possibly visible. | |
| 91 | - | ||
| 92 | - | The finished event should be sent immediately on creation of this | |
| 93 | - | object if the compositor decides that the locked event will not be sent. | |
| 94 | - | ||
| 95 | - | The compositor may wait for the client to create and render session lock | |
| 96 | - | surfaces before sending the locked event to avoid displaying intermediate | |
| 97 | - | blank frames. However, it must impose a reasonable time limit if | |
| 98 | - | waiting and send the locked event as soon as the hard requirements | |
| 99 | - | described above can be met if the time limit expires. Clients should | |
| 100 | - | immediately create lock surfaces for all outputs on creation of this | |
| 101 | - | object to make this possible. | |
| 102 | - | ||
| 103 | - | This behavior of the locked event is required in order to prevent | |
| 104 | - | possible race conditions with clients that wish to suspend the system | |
| 105 | - | or similar after locking the session. Without these semantics, clients | |
| 106 | - | triggering a suspend after receiving the locked event would race with | |
| 107 | - | the first "locked" frame being presented and normal/unlocked frames | |
| 108 | - | might be briefly visible as the system is resumed if the suspend | |
| 109 | - | operation wins the race. | |
| 110 | - | ||
| 111 | - | If the client dies while the session is locked, the compositor must not | |
| 112 | - | unlock the session in response. It is acceptable for the session to be | |
| 113 | - | permanently locked if this happens. The compositor may choose to continue | |
| 114 | - | to display the lock surfaces the client had mapped before it died or | |
| 115 | - | alternatively fall back to a solid color, this is compositor policy. | |
| 116 | - | ||
| 117 | - | Compositors may also allow a secure way to recover the session, the | |
| 118 | - | details of this are compositor policy. Compositors may allow a new | |
| 119 | - | client to create a ext_session_lock_v1 object and take responsibility | |
| 120 | - | for unlocking the session, they may even start a new lock client | |
| 121 | - | instance automatically. | |
| 122 | - | </description> | |
| 123 | - | ||
| 124 | - | <enum name="error"> | |
| 125 | - | <entry name="invalid_destroy" value="0" | |
| 126 | - | summary="attempted to destroy session lock while locked"/> | |
| 127 | - | <entry name="invalid_unlock" value="1" | |
| 128 | - | summary="unlock requested but locked event was never sent"/> | |
| 129 | - | <entry name="role" value="2" | |
| 130 | - | summary="given wl_surface already has a role"/> | |
| 131 | - | <entry name="duplicate_output" value="3" | |
| 132 | - | summary="given output already has a lock surface"/> | |
| 133 | - | <entry name="already_constructed" value="4" | |
| 134 | - | summary="given wl_surface has a buffer attached or committed"/> | |
| 135 | - | </enum> | |
| 136 | - | ||
| 137 | - | <request name="destroy" type="destructor"> | |
| 138 | - | <description summary="destroy the session lock"> | |
| 139 | - | This informs the compositor that the lock object will no longer be | |
| 140 | - | used. Existing objects created through this interface remain valid. | |
| 141 | - | ||
| 142 | - | After this request is made, lock surfaces created through this object | |
| 143 | - | should be destroyed by the client as they will no longer be used by | |
| 144 | - | the compositor. | |
| 145 | - | ||
| 146 | - | It is a protocol error to make this request if the locked event was | |
| 147 | - | sent, the unlock_and_destroy request must be used instead. | |
| 148 | - | </description> | |
| 149 | - | </request> | |
| 150 | - | ||
| 151 | - | <event name="locked"> | |
| 152 | - | <description summary="session successfully locked"> | |
| 153 | - | This client is now responsible for displaying graphics while the | |
| 154 | - | session is locked and deciding when to unlock the session. | |
| 155 | - | ||
| 156 | - | The locked event must not be sent until a new "locked" frame has been | |
| 157 | - | presented on all outputs and no security sensitive normal/unlocked | |
| 158 | - | content is possibly visible. | |
| 159 | - | ||
| 160 | - | If this event is sent, making the destroy request is a protocol error, | |
| 161 | - | the lock object must be destroyed using the unlock_and_destroy request. | |
| 162 | - | </description> | |
| 163 | - | </event> | |
| 164 | - | ||
| 165 | - | <event name="finished"> | |
| 166 | - | <description summary="the session lock object should be destroyed"> | |
| 167 | - | The compositor has decided that the session lock should be destroyed | |
| 168 | - | as it will no longer be used by the compositor. Exactly when this | |
| 169 | - | event is sent is compositor policy, but it must never be sent more | |
| 170 | - | than once for a given session lock object. | |
| 171 | - | ||
| 172 | - | This might be sent because there is already another ext_session_lock_v1 | |
| 173 | - | object held by a client, or the compositor has decided to deny the | |
| 174 | - | request to lock the session for some other reason. This might also | |
| 175 | - | be sent because the compositor implements some alternative, secure | |
| 176 | - | way to authenticate and unlock the session. | |
| 177 | - | ||
| 178 | - | The finished event should be sent immediately on creation of this | |
| 179 | - | object if the compositor decides that the locked event will not | |
| 180 | - | be sent. | |
| 181 | - | ||
| 182 | - | If the locked event is sent on creation of this object the finished | |
| 183 | - | event may still be sent at some later time in this object's | |
| 184 | - | lifetime. This is compositor policy. | |
| 185 | - | ||
| 186 | - | Upon receiving this event, the client should make either the destroy | |
| 187 | - | request or the unlock_and_destroy request, depending on whether or | |
| 188 | - | not the locked event was received on this object. | |
| 189 | - | </description> | |
| 190 | - | </event> | |
| 191 | - | ||
| 192 | - | <request name="get_lock_surface"> | |
| 193 | - | <description summary="create a lock surface for a given output"> | |
| 194 | - | The client is expected to create lock surfaces for all outputs | |
| 195 | - | currently present and any new outputs as they are advertised. These | |
| 196 | - | won't be displayed by the compositor unless the lock is successful | |
| 197 | - | and the locked event is sent. | |
| 198 | - | ||
| 199 | - | Providing a wl_surface which already has a role or already has a buffer | |
| 200 | - | attached or committed is a protocol error, as is attaching/committing | |
| 201 | - | a buffer before the first ext_session_lock_surface_v1.configure event. | |
| 202 | - | ||
| 203 | - | Attempting to create more than one lock surface for a given output | |
| 204 | - | is a duplicate_output protocol error. | |
| 205 | - | </description> | |
| 206 | - | <arg name="id" type="new_id" interface="ext_session_lock_surface_v1"/> | |
| 207 | - | <arg name="surface" type="object" interface="wl_surface"/> | |
| 208 | - | <arg name="output" type="object" interface="wl_output"/> | |
| 209 | - | </request> | |
| 210 | - | ||
| 211 | - | <request name="unlock_and_destroy" type="destructor"> | |
| 212 | - | <description summary="unlock the session, destroying the object"> | |
| 213 | - | This request indicates that the session should be unlocked, for | |
| 214 | - | example because the user has entered their password and it has been | |
| 215 | - | verified by the client. | |
| 216 | - | ||
| 217 | - | This request also informs the compositor that the lock object will | |
| 218 | - | no longer be used and should be destroyed. Existing objects created | |
| 219 | - | through this interface remain valid. | |
| 220 | - | ||
| 221 | - | After this request is made, lock surfaces created through this object | |
| 222 | - | should be destroyed by the client as they will no longer be used by | |
| 223 | - | the compositor. | |
| 224 | - | ||
| 225 | - | It is a protocol error to make this request if the locked event has | |
| 226 | - | not been sent. In that case, the lock object must be destroyed using | |
| 227 | - | the destroy request. | |
| 228 | - | ||
| 229 | - | Note that a correct client that wishes to exit directly after unlocking | |
| 230 | - | the session must use the wl_display.sync request to ensure the server | |
| 231 | - | receives and processes the unlock_and_destroy request. Otherwise | |
| 232 | - | there is no guarantee that the server has unlocked the session due | |
| 233 | - | to the asynchronous nature of the Wayland protocol. For example, | |
| 234 | - | the server might terminate the client with a protocol error before | |
| 235 | - | it processes the unlock_and_destroy request. | |
| 236 | - | </description> | |
| 237 | - | </request> | |
| 238 | - | </interface> | |
| 239 | - | ||
| 240 | - | <interface name="ext_session_lock_surface_v1" version="1"> | |
| 241 | - | <description summary="a surface displayed while the session is locked"> | |
| 242 | - | The client may use lock surfaces to display a screensaver, render a | |
| 243 | - | dialog to enter a password and unlock the session, or however else it | |
| 244 | - | sees fit. | |
| 245 | - | ||
| 246 | - | On binding this interface the compositor will immediately send the | |
| 247 | - | first configure event. After making the ack_configure request in | |
| 248 | - | response to this event the client should attach and commit the first | |
| 249 | - | buffer. Committing the surface before acking the first configure is a | |
| 250 | - | protocol error. Committing the surface with a null buffer at any time | |
| 251 | - | is a protocol error. | |
| 252 | - | ||
| 253 | - | The compositor is free to handle keyboard/pointer focus for lock | |
| 254 | - | surfaces however it chooses. A reasonable way to do this would be to | |
| 255 | - | give the first lock surface created keyboard focus and change keyboard | |
| 256 | - | focus if the user clicks on other surfaces. | |
| 257 | - | </description> | |
| 258 | - | ||
| 259 | - | <enum name="error"> | |
| 260 | - | <entry name="commit_before_first_ack" value="0" | |
| 261 | - | summary="surface committed before first ack_configure request"/> | |
| 262 | - | <entry name="null_buffer" value="1" | |
| 263 | - | summary="surface committed with a null buffer"/> | |
| 264 | - | <entry name="dimensions_mismatch" value="2" | |
| 265 | - | summary="failed to match ack'd width/height"/> | |
| 266 | - | <entry name="invalid_serial" value="3" | |
| 267 | - | summary="serial provided in ack_configure is invalid"/> | |
| 268 | - | </enum> | |
| 269 | - | ||
| 270 | - | <request name="destroy" type="destructor"> | |
| 271 | - | <description summary="destroy the lock surface object"> | |
| 272 | - | This informs the compositor that the lock surface object will no | |
| 273 | - | longer be used. | |
| 274 | - | ||
| 275 | - | It is recommended for a lock client to destroy lock surfaces if | |
| 276 | - | their corresponding wl_output global is removed. | |
| 277 | - | ||
| 278 | - | If a lock surface on an active output is destroyed before the | |
| 279 | - | ext_session_lock_v1.unlock_and_destroy event is sent, the compositor | |
| 280 | - | must fall back to rendering a solid color. | |
| 281 | - | </description> | |
| 282 | - | </request> | |
| 283 | - | ||
| 284 | - | <request name="ack_configure"> | |
| 285 | - | <description summary="ack a configure event"> | |
| 286 | - | When a configure event is received, if a client commits the surface | |
| 287 | - | in response to the configure event, then the client must make an | |
| 288 | - | ack_configure request sometime before the commit request, passing | |
| 289 | - | along the serial of the configure event. | |
| 290 | - | ||
| 291 | - | If the client receives multiple configure events before it can | |
| 292 | - | respond to one, it only has to ack the last configure event. | |
| 293 | - | ||
| 294 | - | A client is not required to commit immediately after sending an | |
| 295 | - | ack_configure request - it may even ack_configure several times | |
| 296 | - | before its next surface commit. | |
| 297 | - | ||
| 298 | - | A client may send multiple ack_configure requests before committing, | |
| 299 | - | but only the last request sent before a commit indicates which | |
| 300 | - | configure event the client really is responding to. | |
| 301 | - | ||
| 302 | - | Sending an ack_configure request consumes the configure event | |
| 303 | - | referenced by the given serial, as well as all older configure events | |
| 304 | - | sent on this object. | |
| 305 | - | ||
| 306 | - | It is a protocol error to issue multiple ack_configure requests | |
| 307 | - | referencing the same configure event or to issue an ack_configure | |
| 308 | - | request referencing a configure event older than the last configure | |
| 309 | - | event acked for a given lock surface. | |
| 310 | - | </description> | |
| 311 | - | <arg name="serial" type="uint" summary="serial from the configure event"/> | |
| 312 | - | </request> | |
| 313 | - | ||
| 314 | - | <event name="configure"> | |
| 315 | - | <description summary="the client should resize its surface"> | |
| 316 | - | This event is sent once on binding the interface and may be sent again | |
| 317 | - | at the compositor's discretion, for example if output geometry changes. | |
| 318 | - | ||
| 319 | - | The width and height are in surface-local coordinates and are exact | |
| 320 | - | requirements. Failing to match these surface dimensions in the next | |
| 321 | - | commit after acking a configure is a protocol error. | |
| 322 | - | </description> | |
| 323 | - | <arg name="serial" type="uint" summary="serial for use in ack_configure"/> | |
| 324 | - | <arg name="width" type="uint"/> | |
| 325 | - | <arg name="height" type="uint"/> | |
| 326 | - | </event> | |
| 327 | - | </interface> | |
| 328 | - | </protocol> | |
D protocol/extsessionlock/ext-session-lock-v1_generated.go +0 -324
| @@ -1,324 +0,0 @@ | |||
| 1 | - | // Code generated by wlturbo-scanner. DO NOT EDIT. | |
| 2 | - | // Protocol: ext_session_lock_v1 | |
| 3 | - | // Source: ext-session-lock-v1.xml | |
| 4 | - | ||
| 5 | - | // Upstream protocol copyright and license: | |
| 6 | - | // Copyright 2021 Isaac Freund | |
| 7 | - | // | |
| 8 | - | // Permission is hereby granted, free of charge, to any person obtaining a | |
| 9 | - | // copy of this software and associated documentation files (the "Software"), | |
| 10 | - | // to deal in the Software without restriction, including without limitation | |
| 11 | - | // the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 12 | - | // and/or sell copies of the Software, and to permit persons to whom the | |
| 13 | - | // Software is furnished to do so, subject to the following conditions: | |
| 14 | - | // | |
| 15 | - | // The above copyright notice and this permission notice shall be included in | |
| 16 | - | // all copies or substantial portions of the Software. | |
| 17 | - | // | |
| 18 | - | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 19 | - | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 20 | - | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 21 | - | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 22 | - | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
| 23 | - | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
| 24 | - | // THE SOFTWARE. | |
| 25 | - | ||
| 26 | - | package extsessionlock | |
| 27 | - | ||
| 28 | - | import ( | |
| 29 | - | "sync" | |
| 30 | - | ||
| 31 | - | cross_wl_output "github.com/bnema/wlturbo/protocol/core" | |
| 32 | - | cross_wl_surface "github.com/bnema/wlturbo/protocol/core" | |
| 33 | - | "github.com/bnema/wlturbo/wl" | |
| 34 | - | ) | |
| 35 | - | ||
| 36 | - | // ERROR_INVALID_DESTROY is the error invalid_destroy value. | |
| 37 | - | const ERROR_INVALID_DESTROY = 0 | |
| 38 | - | ||
| 39 | - | // ERROR_INVALID_UNLOCK is the error invalid_unlock value. | |
| 40 | - | const ERROR_INVALID_UNLOCK = 1 | |
| 41 | - | ||
| 42 | - | // ERROR_ROLE is the error role value. | |
| 43 | - | const ERROR_ROLE = 2 | |
| 44 | - | ||
| 45 | - | // ERROR_DUPLICATE_OUTPUT is the error duplicate_output value. | |
| 46 | - | const ERROR_DUPLICATE_OUTPUT = 3 | |
| 47 | - | ||
| 48 | - | // ERROR_ALREADY_CONSTRUCTED is the error already_constructed value. | |
| 49 | - | const ERROR_ALREADY_CONSTRUCTED = 4 | |
| 50 | - | ||
| 51 | - | // ERROR_COMMIT_BEFORE_FIRST_ACK is the error commit_before_first_ack value. | |
| 52 | - | const ERROR_COMMIT_BEFORE_FIRST_ACK = 0 | |
| 53 | - | ||
| 54 | - | // ERROR_NULL_BUFFER is the error null_buffer value. | |
| 55 | - | const ERROR_NULL_BUFFER = 1 | |
| 56 | - | ||
| 57 | - | // ERROR_DIMENSIONS_MISMATCH is the error dimensions_mismatch value. | |
| 58 | - | const ERROR_DIMENSIONS_MISMATCH = 2 | |
| 59 | - | ||
| 60 | - | // ERROR_INVALID_SERIAL is the error invalid_serial value. | |
| 61 | - | const ERROR_INVALID_SERIAL = 3 | |
| 62 | - | ||
| 63 | - | // ExtSessionLockManagerInterface is the protocol interface name. | |
| 64 | - | const ExtSessionLockManagerInterface = "ext_session_lock_manager_v1" | |
| 65 | - | ||
| 66 | - | // ExtSessionLockManager is the generated binding for ext_session_lock_manager_v1 version 1. | |
| 67 | - | type ExtSessionLockManager struct { | |
| 68 | - | wl.BaseProxy | |
| 69 | - | } | |
| 70 | - | ||
| 71 | - | // NewExtSessionLockManager returns an unbound ExtSessionLockManager. | |
| 72 | - | func NewExtSessionLockManager(ctx *wl.Context) *ExtSessionLockManager { | |
| 73 | - | obj := &ExtSessionLockManager{} | |
| 74 | - | obj.SetContext(ctx) | |
| 75 | - | ctx.Register(obj) | |
| 76 | - | return obj | |
| 77 | - | } | |
| 78 | - | ||
| 79 | - | // This informs the compositor that the session lock manager object will no longer be used. Existing objects created through this interface remain valid. | |
| 80 | - | func (o *ExtSessionLockManager) Destroy() error { | |
| 81 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "ext_session_lock_manager_v1.destroy", Destructor: true}); err != nil { | |
| 82 | - | return err | |
| 83 | - | } | |
| 84 | - | return nil | |
| 85 | - | } | |
| 86 | - | ||
| 87 | - | // 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. | |
| 88 | - | func (o *ExtSessionLockManager) Lock() (*ExtSessionLock, error) { | |
| 89 | - | child := &ExtSessionLock{} | |
| 90 | - | child.SetContext(o.Context()) | |
| 91 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "ext_session_lock_manager_v1.lock", Child: child}, wl.ArgObject(child)); err != nil { | |
| 92 | - | return nil, err | |
| 93 | - | } | |
| 94 | - | return child, nil | |
| 95 | - | } | |
| 96 | - | ||
| 97 | - | // EventSignature returns the declared event argument types in wire order. | |
| 98 | - | func (o *ExtSessionLockManager) EventSignature(opcode uint16) (string, bool) { | |
| 99 | - | switch opcode { | |
| 100 | - | default: | |
| 101 | - | return "", false | |
| 102 | - | } | |
| 103 | - | } | |
| 104 | - | ||
| 105 | - | // Dispatch decodes one event on ext_session_lock_manager_v1 and calls the registered handlers. | |
| 106 | - | func (o *ExtSessionLockManager) Dispatch(event *wl.Event) { | |
| 107 | - | switch event.Opcode { | |
| 108 | - | default: | |
| 109 | - | } | |
| 110 | - | } | |
| 111 | - | ||
| 112 | - | // ExtSessionLockInterface is the protocol interface name. | |
| 113 | - | const ExtSessionLockInterface = "ext_session_lock_v1" | |
| 114 | - | ||
| 115 | - | // ExtSessionLock is the generated binding for ext_session_lock_v1 version 1. | |
| 116 | - | type ExtSessionLock struct { | |
| 117 | - | wl.BaseProxy | |
| 118 | - | // handlersMu guards the handler slices: a client may register or replace | |
| 119 | - | // handlers while another goroutine dispatches events. | |
| 120 | - | handlersMu sync.Mutex | |
| 121 | - | onLocked []func() | |
| 122 | - | onFinished []func() | |
| 123 | - | } | |
| 124 | - | ||
| 125 | - | // NewExtSessionLock returns an unbound ExtSessionLock. | |
| 126 | - | func NewExtSessionLock(ctx *wl.Context) *ExtSessionLock { | |
| 127 | - | obj := &ExtSessionLock{} | |
| 128 | - | obj.SetContext(ctx) | |
| 129 | - | ctx.Register(obj) | |
| 130 | - | return obj | |
| 131 | - | } | |
| 132 | - | ||
| 133 | - | // 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. | |
| 134 | - | func (o *ExtSessionLock) Destroy() error { | |
| 135 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "ext_session_lock_v1.destroy", Destructor: true}); err != nil { | |
| 136 | - | return err | |
| 137 | - | } | |
| 138 | - | return nil | |
| 139 | - | } | |
| 140 | - | ||
| 141 | - | // 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. | |
| 142 | - | func (o *ExtSessionLock) GetLockSurface(surface *cross_wl_surface.Surface, output *cross_wl_output.Output) (*ExtSessionLockSurface, error) { | |
| 143 | - | var arg1 wl.Object | |
| 144 | - | if surface != nil { | |
| 145 | - | arg1 = surface | |
| 146 | - | } | |
| 147 | - | var arg2 wl.Object | |
| 148 | - | if output != nil { | |
| 149 | - | arg2 = output | |
| 150 | - | } | |
| 151 | - | child := &ExtSessionLockSurface{} | |
| 152 | - | child.SetContext(o.Context()) | |
| 153 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "ext_session_lock_v1.get_lock_surface", Child: child}, wl.ArgObject(child), wl.ArgObject(arg1), wl.ArgObject(arg2)); err != nil { | |
| 154 | - | return nil, err | |
| 155 | - | } | |
| 156 | - | return child, nil | |
| 157 | - | } | |
| 158 | - | ||
| 159 | - | // 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. | |
| 160 | - | func (o *ExtSessionLock) UnlockAndDestroy() error { | |
| 161 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 2, Name: "ext_session_lock_v1.unlock_and_destroy", Destructor: true}); err != nil { | |
| 162 | - | return err | |
| 163 | - | } | |
| 164 | - | return nil | |
| 165 | - | } | |
| 166 | - | ||
| 167 | - | // OnLocked registers a handler for the locked event. | |
| 168 | - | // | |
| 169 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 170 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 171 | - | func (o *ExtSessionLock) OnLocked(handler func()) { | |
| 172 | - | if handler == nil { | |
| 173 | - | return | |
| 174 | - | } | |
| 175 | - | o.handlersMu.Lock() | |
| 176 | - | defer o.handlersMu.Unlock() | |
| 177 | - | o.onLocked = append(o.onLocked, handler) | |
| 178 | - | } | |
| 179 | - | ||
| 180 | - | // handlersForLocked returns the handlers registered for locked, taken | |
| 181 | - | // under the lock so a handler may register another handler while events are | |
| 182 | - | // being dispatched. | |
| 183 | - | func (o *ExtSessionLock) handlersForLocked() []func() { | |
| 184 | - | o.handlersMu.Lock() | |
| 185 | - | defer o.handlersMu.Unlock() | |
| 186 | - | return o.onLocked | |
| 187 | - | } | |
| 188 | - | ||
| 189 | - | // OnFinished registers a handler for the finished event. | |
| 190 | - | // | |
| 191 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 192 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 193 | - | func (o *ExtSessionLock) OnFinished(handler func()) { | |
| 194 | - | if handler == nil { | |
| 195 | - | return | |
| 196 | - | } | |
| 197 | - | o.handlersMu.Lock() | |
| 198 | - | defer o.handlersMu.Unlock() | |
| 199 | - | o.onFinished = append(o.onFinished, handler) | |
| 200 | - | } | |
| 201 | - | ||
| 202 | - | // handlersForFinished returns the handlers registered for finished, taken | |
| 203 | - | // under the lock so a handler may register another handler while events are | |
| 204 | - | // being dispatched. | |
| 205 | - | func (o *ExtSessionLock) handlersForFinished() []func() { | |
| 206 | - | o.handlersMu.Lock() | |
| 207 | - | defer o.handlersMu.Unlock() | |
| 208 | - | return o.onFinished | |
| 209 | - | } | |
| 210 | - | ||
| 211 | - | // EventSignature returns the declared event argument types in wire order. | |
| 212 | - | func (o *ExtSessionLock) EventSignature(opcode uint16) (string, bool) { | |
| 213 | - | switch opcode { | |
| 214 | - | case 0: | |
| 215 | - | return "", true | |
| 216 | - | case 1: | |
| 217 | - | return "", true | |
| 218 | - | default: | |
| 219 | - | return "", false | |
| 220 | - | } | |
| 221 | - | } | |
| 222 | - | ||
| 223 | - | // Dispatch decodes one event on ext_session_lock_v1 and calls the registered handlers. | |
| 224 | - | func (o *ExtSessionLock) Dispatch(event *wl.Event) { | |
| 225 | - | switch event.Opcode { | |
| 226 | - | case 0: // locked | |
| 227 | - | ||
| 228 | - | for i, handler := range o.handlersForLocked() { | |
| 229 | - | _ = i | |
| 230 | - | handler() | |
| 231 | - | } | |
| 232 | - | case 1: // finished | |
| 233 | - | ||
| 234 | - | for i, handler := range o.handlersForFinished() { | |
| 235 | - | _ = i | |
| 236 | - | handler() | |
| 237 | - | } | |
| 238 | - | default: | |
| 239 | - | } | |
| 240 | - | } | |
| 241 | - | ||
| 242 | - | // ExtSessionLockSurfaceInterface is the protocol interface name. | |
| 243 | - | const ExtSessionLockSurfaceInterface = "ext_session_lock_surface_v1" | |
| 244 | - | ||
| 245 | - | // ExtSessionLockSurface is the generated binding for ext_session_lock_surface_v1 version 1. | |
| 246 | - | type ExtSessionLockSurface struct { | |
| 247 | - | wl.BaseProxy | |
| 248 | - | // handlersMu guards the handler slices: a client may register or replace | |
| 249 | - | // handlers while another goroutine dispatches events. | |
| 250 | - | handlersMu sync.Mutex | |
| 251 | - | onConfigure []func(serial uint32, width uint32, height uint32) | |
| 252 | - | } | |
| 253 | - | ||
| 254 | - | // NewExtSessionLockSurface returns an unbound ExtSessionLockSurface. | |
| 255 | - | func NewExtSessionLockSurface(ctx *wl.Context) *ExtSessionLockSurface { | |
| 256 | - | obj := &ExtSessionLockSurface{} | |
| 257 | - | obj.SetContext(ctx) | |
| 258 | - | ctx.Register(obj) | |
| 259 | - | return obj | |
| 260 | - | } | |
| 261 | - | ||
| 262 | - | // 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. | |
| 263 | - | func (o *ExtSessionLockSurface) Destroy() error { | |
| 264 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "ext_session_lock_surface_v1.destroy", Destructor: true}); err != nil { | |
| 265 | - | return err | |
| 266 | - | } | |
| 267 | - | return nil | |
| 268 | - | } | |
| 269 | - | ||
| 270 | - | // 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. | |
| 271 | - | func (o *ExtSessionLockSurface) AckConfigure(serial uint32) error { | |
| 272 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "ext_session_lock_surface_v1.ack_configure"}, wl.ArgUint(serial)); err != nil { | |
| 273 | - | return err | |
| 274 | - | } | |
| 275 | - | return nil | |
| 276 | - | } | |
| 277 | - | ||
| 278 | - | // OnConfigure registers a handler for the configure event. | |
| 279 | - | // | |
| 280 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 281 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 282 | - | func (o *ExtSessionLockSurface) OnConfigure(handler func(serial uint32, width uint32, height uint32)) { | |
| 283 | - | if handler == nil { | |
| 284 | - | return | |
| 285 | - | } | |
| 286 | - | o.handlersMu.Lock() | |
| 287 | - | defer o.handlersMu.Unlock() | |
| 288 | - | o.onConfigure = append(o.onConfigure, handler) | |
| 289 | - | } | |
| 290 | - | ||
| 291 | - | // handlersForConfigure returns the handlers registered for configure, taken | |
| 292 | - | // under the lock so a handler may register another handler while events are | |
| 293 | - | // being dispatched. | |
| 294 | - | func (o *ExtSessionLockSurface) handlersForConfigure() []func(serial uint32, width uint32, height uint32) { | |
| 295 | - | o.handlersMu.Lock() | |
| 296 | - | defer o.handlersMu.Unlock() | |
| 297 | - | return o.onConfigure | |
| 298 | - | } | |
| 299 | - | ||
| 300 | - | // EventSignature returns the declared event argument types in wire order. | |
| 301 | - | func (o *ExtSessionLockSurface) EventSignature(opcode uint16) (string, bool) { | |
| 302 | - | switch opcode { | |
| 303 | - | case 0: | |
| 304 | - | return "uint,uint,uint,", true | |
| 305 | - | default: | |
| 306 | - | return "", false | |
| 307 | - | } | |
| 308 | - | } | |
| 309 | - | ||
| 310 | - | // Dispatch decodes one event on ext_session_lock_surface_v1 and calls the registered handlers. | |
| 311 | - | func (o *ExtSessionLockSurface) Dispatch(event *wl.Event) { | |
| 312 | - | switch event.Opcode { | |
| 313 | - | case 0: // configure | |
| 314 | - | serial := event.Uint32() | |
| 315 | - | width := event.Uint32() | |
| 316 | - | height := event.Uint32() | |
| 317 | - | ||
| 318 | - | for i, handler := range o.handlersForConfigure() { | |
| 319 | - | _ = i | |
| 320 | - | handler(serial, width, height) | |
| 321 | - | } | |
| 322 | - | default: | |
| 323 | - | } | |
| 324 | - | } | |
D protocol/extsessionlock/generate.go +0 -3
| @@ -1,3 +0,0 @@ | |||
| 1 | - | package extsessionlock | |
| 2 | - | ||
| 3 | - | //go:generate go run ../../cmd/wlturbo-scanner -p extsessionlock -o ext-session-lock-v1_generated.go -import wl_surface=github.com/bnema/wlturbo/protocol/core -import wl_output=github.com/bnema/wlturbo/protocol/core ext-session-lock-v1.xml | |
D protocol/fifo/fifo-v1.xml +0 -143
| @@ -1,143 +0,0 @@ | |||
| 1 | - | <?xml version="1.0" encoding="UTF-8"?> | |
| 2 | - | <protocol name="fifo_v1"> | |
| 3 | - | <copyright> | |
| 4 | - | Copyright © 2023 Valve Corporation | |
| 5 | - | ||
| 6 | - | Permission is hereby granted, free of charge, to any person obtaining a | |
| 7 | - | copy of this software and associated documentation files (the "Software"), | |
| 8 | - | to deal in the Software without restriction, including without limitation | |
| 9 | - | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 10 | - | and/or sell copies of the Software, and to permit persons to whom the | |
| 11 | - | Software is furnished to do so, subject to the following conditions: | |
| 12 | - | ||
| 13 | - | The above copyright notice and this permission notice (including the next | |
| 14 | - | paragraph) shall be included in all copies or substantial portions of the | |
| 15 | - | Software. | |
| 16 | - | ||
| 17 | - | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 18 | - | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 19 | - | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 20 | - | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 21 | - | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 22 | - | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
| 23 | - | DEALINGS IN THE SOFTWARE. | |
| 24 | - | </copyright> | |
| 25 | - | ||
| 26 | - | <interface name="wp_fifo_manager_v1" version="1"> | |
| 27 | - | <description summary="protocol for fifo constraints"> | |
| 28 | - | When a Wayland compositor considers applying a content update, | |
| 29 | - | it must ensure all the update's readiness constraints (fences, etc) | |
| 30 | - | are met. | |
| 31 | - | ||
| 32 | - | This protocol provides a way to use the completion of a display refresh | |
| 33 | - | cycle as an additional readiness constraint. | |
| 34 | - | ||
| 35 | - | Warning! The protocol described in this file is currently in the testing | |
| 36 | - | phase. Backward compatible changes may be added together with the | |
| 37 | - | corresponding interface version bump. Backward incompatible changes can | |
| 38 | - | only be done by creating a new major version of the extension. | |
| 39 | - | </description> | |
| 40 | - | ||
| 41 | - | <enum name="error"> | |
| 42 | - | <description summary="fatal presentation error"> | |
| 43 | - | These fatal protocol errors may be emitted in response to | |
| 44 | - | illegal requests. | |
| 45 | - | </description> | |
| 46 | - | <entry name="already_exists" value="0" | |
| 47 | - | summary="fifo manager already exists for surface"/> | |
| 48 | - | </enum> | |
| 49 | - | ||
| 50 | - | <request name="destroy" type="destructor"> | |
| 51 | - | <description summary="unbind from the manager interface"> | |
| 52 | - | Informs the server that the client will no longer be using | |
| 53 | - | this protocol object. Existing objects created by this object | |
| 54 | - | are not affected. | |
| 55 | - | </description> | |
| 56 | - | </request> | |
| 57 | - | ||
| 58 | - | <request name="get_fifo"> | |
| 59 | - | <description summary="request fifo interface for surface"> | |
| 60 | - | Establish a fifo object for a surface that may be used to add | |
| 61 | - | display refresh constraints to content updates. | |
| 62 | - | ||
| 63 | - | Only one such object may exist for a surface and attempting | |
| 64 | - | to create more than one will result in an already_exists | |
| 65 | - | protocol error. If a surface is acted on by multiple software | |
| 66 | - | components, general best practice is that only the component | |
| 67 | - | performing wl_surface.attach operations should use this protocol. | |
| 68 | - | </description> | |
| 69 | - | <arg name="id" type="new_id" interface="wp_fifo_v1"/> | |
| 70 | - | <arg name="surface" type="object" interface="wl_surface"/> | |
| 71 | - | </request> | |
| 72 | - | </interface> | |
| 73 | - | ||
| 74 | - | <interface name="wp_fifo_v1" version="1"> | |
| 75 | - | <description summary="fifo interface"> | |
| 76 | - | A fifo object for a surface that may be used to add | |
| 77 | - | display refresh constraints to content updates. | |
| 78 | - | </description> | |
| 79 | - | ||
| 80 | - | <enum name="error"> | |
| 81 | - | <description summary="fatal error"> | |
| 82 | - | These fatal protocol errors may be emitted in response to | |
| 83 | - | illegal requests. | |
| 84 | - | </description> | |
| 85 | - | <entry name="surface_destroyed" value="0" | |
| 86 | - | summary="the associated surface no longer exists"/> | |
| 87 | - | </enum> | |
| 88 | - | ||
| 89 | - | <request name="set_barrier"> | |
| 90 | - | <description summary="sets the start point for a fifo constraint"> | |
| 91 | - | When the content update containing the "set_barrier" is applied, | |
| 92 | - | it sets a "fifo_barrier" condition on the surface associated with | |
| 93 | - | the fifo object. The condition is cleared immediately after the | |
| 94 | - | following latching deadline for non-tearing presentation. | |
| 95 | - | ||
| 96 | - | The compositor may clear the condition early if it must do so to | |
| 97 | - | ensure client forward progress assumptions. | |
| 98 | - | ||
| 99 | - | To wait for this condition to clear, use the "wait_barrier" request. | |
| 100 | - | ||
| 101 | - | "set_barrier" is double-buffered state, see wl_surface.commit. | |
| 102 | - | ||
| 103 | - | Requesting set_barrier after the fifo object's surface is | |
| 104 | - | destroyed will generate a "surface_destroyed" error. | |
| 105 | - | </description> | |
| 106 | - | </request> | |
| 107 | - | ||
| 108 | - | <request name="wait_barrier"> | |
| 109 | - | <description summary="adds a fifo constraint to a content update"> | |
| 110 | - | Indicate that this content update is not ready while a | |
| 111 | - | "fifo_barrier" condition is present on the surface. | |
| 112 | - | ||
| 113 | - | This means that when the content update containing "set_barrier" | |
| 114 | - | was made active at a latching deadline, it will be active for | |
| 115 | - | at least one refresh cycle. A content update which is allowed to | |
| 116 | - | tear might become active after a latching deadline if no content | |
| 117 | - | update became active at the deadline. | |
| 118 | - | ||
| 119 | - | The constraint must be ignored if the surface is a subsurface in | |
| 120 | - | synchronized mode. If the surface is not being updated by the | |
| 121 | - | compositor (off-screen, occluded) the compositor may ignore the | |
| 122 | - | constraint. Clients must use an additional mechanism such as | |
| 123 | - | frame callbacks or timestamps to ensure throttling occurs under | |
| 124 | - | all conditions. | |
| 125 | - | ||
| 126 | - | "wait_barrier" is double-buffered state, see wl_surface.commit. | |
| 127 | - | ||
| 128 | - | Requesting "wait_barrier" after the fifo object's surface is | |
| 129 | - | destroyed will generate a "surface_destroyed" error. | |
| 130 | - | </description> | |
| 131 | - | </request> | |
| 132 | - | ||
| 133 | - | <request name="destroy" type="destructor"> | |
| 134 | - | <description summary="destroy the fifo interface"> | |
| 135 | - | Informs the server that the client will no longer be using | |
| 136 | - | this protocol object. | |
| 137 | - | ||
| 138 | - | Surface state changes previously made by this protocol are | |
| 139 | - | unaffected by this object's destruction. | |
| 140 | - | </description> | |
| 141 | - | </request> | |
| 142 | - | </interface> | |
| 143 | - | </protocol> | |
D protocol/fifo/fifo-v1_generated.go +0 -146
| @@ -1,146 +0,0 @@ | |||
| 1 | - | // Code generated by wlturbo-scanner. DO NOT EDIT. | |
| 2 | - | // Protocol: fifo_v1 | |
| 3 | - | // Source: fifo-v1.xml | |
| 4 | - | ||
| 5 | - | // Upstream protocol copyright and license: | |
| 6 | - | // Copyright © 2023 Valve Corporation | |
| 7 | - | // | |
| 8 | - | // Permission is hereby granted, free of charge, to any person obtaining a | |
| 9 | - | // copy of this software and associated documentation files (the "Software"), | |
| 10 | - | // to deal in the Software without restriction, including without limitation | |
| 11 | - | // the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 12 | - | // and/or sell copies of the Software, and to permit persons to whom the | |
| 13 | - | // Software is furnished to do so, subject to the following conditions: | |
| 14 | - | // | |
| 15 | - | // The above copyright notice and this permission notice (including the next | |
| 16 | - | // paragraph) shall be included in all copies or substantial portions of the | |
| 17 | - | // Software. | |
| 18 | - | // | |
| 19 | - | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 20 | - | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 21 | - | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 22 | - | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 23 | - | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 24 | - | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
| 25 | - | // DEALINGS IN THE SOFTWARE. | |
| 26 | - | ||
| 27 | - | package fifo | |
| 28 | - | ||
| 29 | - | import ( | |
| 30 | - | cross_wl_surface "github.com/bnema/wlturbo/protocol/core" | |
| 31 | - | "github.com/bnema/wlturbo/wl" | |
| 32 | - | ) | |
| 33 | - | ||
| 34 | - | // ERROR_ALREADY_EXISTS is the error already_exists value. | |
| 35 | - | const ERROR_ALREADY_EXISTS = 0 | |
| 36 | - | ||
| 37 | - | // ERROR_SURFACE_DESTROYED is the error surface_destroyed value. | |
| 38 | - | const ERROR_SURFACE_DESTROYED = 0 | |
| 39 | - | ||
| 40 | - | // WpFifoManagerInterface is the protocol interface name. | |
| 41 | - | const WpFifoManagerInterface = "wp_fifo_manager_v1" | |
| 42 | - | ||
| 43 | - | // WpFifoManager is the generated binding for wp_fifo_manager_v1 version 1. | |
| 44 | - | type WpFifoManager struct { | |
| 45 | - | wl.BaseProxy | |
| 46 | - | } | |
| 47 | - | ||
| 48 | - | // NewWpFifoManager returns an unbound WpFifoManager. | |
| 49 | - | func NewWpFifoManager(ctx *wl.Context) *WpFifoManager { | |
| 50 | - | obj := &WpFifoManager{} | |
| 51 | - | obj.SetContext(ctx) | |
| 52 | - | ctx.Register(obj) | |
| 53 | - | return obj | |
| 54 | - | } | |
| 55 | - | ||
| 56 | - | // Informs the server that the client will no longer be using this protocol object. Existing objects created by this object are not affected. | |
| 57 | - | func (o *WpFifoManager) Destroy() error { | |
| 58 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "wp_fifo_manager_v1.destroy", Destructor: true}); err != nil { | |
| 59 | - | return err | |
| 60 | - | } | |
| 61 | - | return nil | |
| 62 | - | } | |
| 63 | - | ||
| 64 | - | // Establish a fifo object for a surface that may be used to add display refresh constraints to content updates. Only one such object may exist for a surface and attempting to create more than one will result in an already_exists protocol error. If a surface is acted on by multiple software components, general best practice is that only the component performing wl_surface.attach operations should use this protocol. | |
| 65 | - | func (o *WpFifoManager) GetFifo(surface *cross_wl_surface.Surface) (*WpFifo, error) { | |
| 66 | - | var arg1 wl.Object | |
| 67 | - | if surface != nil { | |
| 68 | - | arg1 = surface | |
| 69 | - | } | |
| 70 | - | child := &WpFifo{} | |
| 71 | - | child.SetContext(o.Context()) | |
| 72 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "wp_fifo_manager_v1.get_fifo", Child: child}, wl.ArgObject(child), wl.ArgObject(arg1)); err != nil { | |
| 73 | - | return nil, err | |
| 74 | - | } | |
| 75 | - | return child, nil | |
| 76 | - | } | |
| 77 | - | ||
| 78 | - | // EventSignature returns the declared event argument types in wire order. | |
| 79 | - | func (o *WpFifoManager) EventSignature(opcode uint16) (string, bool) { | |
| 80 | - | switch opcode { | |
| 81 | - | default: | |
| 82 | - | return "", false | |
| 83 | - | } | |
| 84 | - | } | |
| 85 | - | ||
| 86 | - | // Dispatch decodes one event on wp_fifo_manager_v1 and calls the registered handlers. | |
| 87 | - | func (o *WpFifoManager) Dispatch(event *wl.Event) { | |
| 88 | - | switch event.Opcode { | |
| 89 | - | default: | |
| 90 | - | } | |
| 91 | - | } | |
| 92 | - | ||
| 93 | - | // WpFifoInterface is the protocol interface name. | |
| 94 | - | const WpFifoInterface = "wp_fifo_v1" | |
| 95 | - | ||
| 96 | - | // WpFifo is the generated binding for wp_fifo_v1 version 1. | |
| 97 | - | type WpFifo struct { | |
| 98 | - | wl.BaseProxy | |
| 99 | - | } | |
| 100 | - | ||
| 101 | - | // NewWpFifo returns an unbound WpFifo. | |
| 102 | - | func NewWpFifo(ctx *wl.Context) *WpFifo { | |
| 103 | - | obj := &WpFifo{} | |
| 104 | - | obj.SetContext(ctx) | |
| 105 | - | ctx.Register(obj) | |
| 106 | - | return obj | |
| 107 | - | } | |
| 108 | - | ||
| 109 | - | // When the content update containing the "set_barrier" is applied, it sets a "fifo_barrier" condition on the surface associated with the fifo object. The condition is cleared immediately after the following latching deadline for non-tearing presentation. The compositor may clear the condition early if it must do so to ensure client forward progress assumptions. To wait for this condition to clear, use the "wait_barrier" request. "set_barrier" is double-buffered state, see wl_surface.commit. Requesting set_barrier after the fifo object's surface is destroyed will generate a "surface_destroyed" error. | |
| 110 | - | func (o *WpFifo) SetBarrier() error { | |
| 111 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "wp_fifo_v1.set_barrier"}); err != nil { | |
| 112 | - | return err | |
| 113 | - | } | |
| 114 | - | return nil | |
| 115 | - | } | |
| 116 | - | ||
| 117 | - | // Indicate that this content update is not ready while a "fifo_barrier" condition is present on the surface. This means that when the content update containing "set_barrier" was made active at a latching deadline, it will be active for at least one refresh cycle. A content update which is allowed to tear might become active after a latching deadline if no content update became active at the deadline. The constraint must be ignored if the surface is a subsurface in synchronized mode. If the surface is not being updated by the compositor (off-screen, occluded) the compositor may ignore the constraint. Clients must use an additional mechanism such as frame callbacks or timestamps to ensure throttling occurs under all conditions. "wait_barrier" is double-buffered state, see wl_surface.commit. Requesting "wait_barrier" after the fifo object's surface is destroyed will generate a "surface_destroyed" error. | |
| 118 | - | func (o *WpFifo) WaitBarrier() error { | |
| 119 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "wp_fifo_v1.wait_barrier"}); err != nil { | |
| 120 | - | return err | |
| 121 | - | } | |
| 122 | - | return nil | |
| 123 | - | } | |
| 124 | - | ||
| 125 | - | // Informs the server that the client will no longer be using this protocol object. Surface state changes previously made by this protocol are unaffected by this object's destruction. | |
| 126 | - | func (o *WpFifo) Destroy() error { | |
| 127 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 2, Name: "wp_fifo_v1.destroy", Destructor: true}); err != nil { | |
| 128 | - | return err | |
| 129 | - | } | |
| 130 | - | return nil | |
| 131 | - | } | |
| 132 | - | ||
| 133 | - | // EventSignature returns the declared event argument types in wire order. | |
| 134 | - | func (o *WpFifo) EventSignature(opcode uint16) (string, bool) { | |
| 135 | - | switch opcode { | |
| 136 | - | default: | |
| 137 | - | return "", false | |
| 138 | - | } | |
| 139 | - | } | |
| 140 | - | ||
| 141 | - | // Dispatch decodes one event on wp_fifo_v1 and calls the registered handlers. | |
| 142 | - | func (o *WpFifo) Dispatch(event *wl.Event) { | |
| 143 | - | switch event.Opcode { | |
| 144 | - | default: | |
| 145 | - | } | |
| 146 | - | } | |
D protocol/fifo/generate.go +0 -3
| @@ -1,3 +0,0 @@ | |||
| 1 | - | package fifo | |
| 2 | - | ||
| 3 | - | //go:generate go run ../../cmd/wlturbo-scanner -p fifo -o fifo-v1_generated.go -import wl_surface=github.com/bnema/wlturbo/protocol/core fifo-v1.xml | |
D protocol/foreigntoplevel/generate.go +0 -3
| @@ -1,3 +0,0 @@ | |||
| 1 | - | package foreigntoplevel | |
| 2 | - | ||
| 3 | - | //go:generate go run ../../cmd/wlturbo-scanner -p foreigntoplevel -o wlr-foreign-toplevel-management-unstable-v1_generated.go -import wl_output=github.com/bnema/wlturbo/protocol/core -import wl_seat=github.com/bnema/wlturbo/protocol/core -import wl_surface=github.com/bnema/wlturbo/protocol/core wlr-foreign-toplevel-management-unstable-v1.xml | |
D protocol/foreigntoplevel/wlr-foreign-toplevel-management-unstable-v1.xml +0 -270
| @@ -1,270 +0,0 @@ | |||
| 1 | - | <?xml version="1.0" encoding="UTF-8"?> | |
| 2 | - | <protocol name="wlr_foreign_toplevel_management_unstable_v1"> | |
| 3 | - | <copyright> | |
| 4 | - | Copyright © 2018 Ilia Bozhinov | |
| 5 | - | ||
| 6 | - | Permission to use, copy, modify, distribute, and sell this | |
| 7 | - | software and its documentation for any purpose is hereby granted | |
| 8 | - | without fee, provided that the above copyright notice appear in | |
| 9 | - | all copies and that both that copyright notice and this permission | |
| 10 | - | notice appear in supporting documentation, and that the name of | |
| 11 | - | the copyright holders not be used in advertising or publicity | |
| 12 | - | pertaining to distribution of the software without specific, | |
| 13 | - | written prior permission. The copyright holders make no | |
| 14 | - | representations about the suitability of this software for any | |
| 15 | - | purpose. It is provided "as is" without express or implied | |
| 16 | - | warranty. | |
| 17 | - | ||
| 18 | - | THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS | |
| 19 | - | SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | |
| 20 | - | FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY | |
| 21 | - | SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
| 22 | - | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN | |
| 23 | - | AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | |
| 24 | - | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF | |
| 25 | - | THIS SOFTWARE. | |
| 26 | - | </copyright> | |
| 27 | - | ||
| 28 | - | <interface name="zwlr_foreign_toplevel_manager_v1" version="3"> | |
| 29 | - | <description summary="list and control opened apps"> | |
| 30 | - | The purpose of this protocol is to enable the creation of taskbars | |
| 31 | - | and docks by providing them with a list of opened applications and | |
| 32 | - | letting them request certain actions on them, like maximizing, etc. | |
| 33 | - | ||
| 34 | - | After a client binds the zwlr_foreign_toplevel_manager_v1, each opened | |
| 35 | - | toplevel window will be sent via the toplevel event | |
| 36 | - | </description> | |
| 37 | - | ||
| 38 | - | <event name="toplevel"> | |
| 39 | - | <description summary="a toplevel has been created"> | |
| 40 | - | This event is emitted whenever a new toplevel window is created. It | |
| 41 | - | is emitted for all toplevels, regardless of the app that has created | |
| 42 | - | them. | |
| 43 | - | ||
| 44 | - | All initial details of the toplevel(title, app_id, states, etc.) will | |
| 45 | - | be sent immediately after this event via the corresponding events in | |
| 46 | - | zwlr_foreign_toplevel_handle_v1. | |
| 47 | - | </description> | |
| 48 | - | <arg name="toplevel" type="new_id" interface="zwlr_foreign_toplevel_handle_v1"/> | |
| 49 | - | </event> | |
| 50 | - | ||
| 51 | - | <request name="stop"> | |
| 52 | - | <description summary="stop sending events"> | |
| 53 | - | Indicates the client no longer wishes to receive events for new toplevels. | |
| 54 | - | However the compositor may emit further toplevel_created events, until | |
| 55 | - | the finished event is emitted. | |
| 56 | - | ||
| 57 | - | The client must not send any more requests after this one. | |
| 58 | - | </description> | |
| 59 | - | </request> | |
| 60 | - | ||
| 61 | - | <event name="finished" type="destructor"> | |
| 62 | - | <description summary="the compositor has finished with the toplevel manager"> | |
| 63 | - | This event indicates that the compositor is done sending events to the | |
| 64 | - | zwlr_foreign_toplevel_manager_v1. The server will destroy the object | |
| 65 | - | immediately after sending this request, so it will become invalid and | |
| 66 | - | the client should free any resources associated with it. | |
| 67 | - | </description> | |
| 68 | - | </event> | |
| 69 | - | </interface> | |
| 70 | - | ||
| 71 | - | <interface name="zwlr_foreign_toplevel_handle_v1" version="3"> | |
| 72 | - | <description summary="an opened toplevel"> | |
| 73 | - | A zwlr_foreign_toplevel_handle_v1 object represents an opened toplevel | |
| 74 | - | window. Each app may have multiple opened toplevels. | |
| 75 | - | ||
| 76 | - | Each toplevel has a list of outputs it is visible on, conveyed to the | |
| 77 | - | client with the output_enter and output_leave events. | |
| 78 | - | </description> | |
| 79 | - | ||
| 80 | - | <event name="title"> | |
| 81 | - | <description summary="title change"> | |
| 82 | - | This event is emitted whenever the title of the toplevel changes. | |
| 83 | - | </description> | |
| 84 | - | <arg name="title" type="string"/> | |
| 85 | - | </event> | |
| 86 | - | ||
| 87 | - | <event name="app_id"> | |
| 88 | - | <description summary="app-id change"> | |
| 89 | - | This event is emitted whenever the app-id of the toplevel changes. | |
| 90 | - | </description> | |
| 91 | - | <arg name="app_id" type="string"/> | |
| 92 | - | </event> | |
| 93 | - | ||
| 94 | - | <event name="output_enter"> | |
| 95 | - | <description summary="toplevel entered an output"> | |
| 96 | - | This event is emitted whenever the toplevel becomes visible on | |
| 97 | - | the given output. A toplevel may be visible on multiple outputs. | |
| 98 | - | </description> | |
| 99 | - | <arg name="output" type="object" interface="wl_output"/> | |
| 100 | - | </event> | |
| 101 | - | ||
| 102 | - | <event name="output_leave"> | |
| 103 | - | <description summary="toplevel left an output"> | |
| 104 | - | This event is emitted whenever the toplevel stops being visible on | |
| 105 | - | the given output. It is guaranteed that an entered-output event | |
| 106 | - | with the same output has been emitted before this event. | |
| 107 | - | </description> | |
| 108 | - | <arg name="output" type="object" interface="wl_output"/> | |
| 109 | - | </event> | |
| 110 | - | ||
| 111 | - | <request name="set_maximized"> | |
| 112 | - | <description summary="requests that the toplevel be maximized"> | |
| 113 | - | Requests that the toplevel be maximized. If the maximized state actually | |
| 114 | - | changes, this will be indicated by the state event. | |
| 115 | - | </description> | |
| 116 | - | </request> | |
| 117 | - | ||
| 118 | - | <request name="unset_maximized"> | |
| 119 | - | <description summary="requests that the toplevel be unmaximized"> | |
| 120 | - | Requests that the toplevel be unmaximized. If the maximized state actually | |
| 121 | - | changes, this will be indicated by the state event. | |
| 122 | - | </description> | |
| 123 | - | </request> | |
| 124 | - | ||
| 125 | - | <request name="set_minimized"> | |
| 126 | - | <description summary="requests that the toplevel be minimized"> | |
| 127 | - | Requests that the toplevel be minimized. If the minimized state actually | |
| 128 | - | changes, this will be indicated by the state event. | |
| 129 | - | </description> | |
| 130 | - | </request> | |
| 131 | - | ||
| 132 | - | <request name="unset_minimized"> | |
| 133 | - | <description summary="requests that the toplevel be unminimized"> | |
| 134 | - | Requests that the toplevel be unminimized. If the minimized state actually | |
| 135 | - | changes, this will be indicated by the state event. | |
| 136 | - | </description> | |
| 137 | - | </request> | |
| 138 | - | ||
| 139 | - | <request name="activate"> | |
| 140 | - | <description summary="activate the toplevel"> | |
| 141 | - | Request that this toplevel be activated on the given seat. | |
| 142 | - | There is no guarantee the toplevel will be actually activated. | |
| 143 | - | </description> | |
| 144 | - | <arg name="seat" type="object" interface="wl_seat"/> | |
| 145 | - | </request> | |
| 146 | - | ||
| 147 | - | <enum name="state"> | |
| 148 | - | <description summary="types of states on the toplevel"> | |
| 149 | - | The different states that a toplevel can have. These have the same meaning | |
| 150 | - | as the states with the same names defined in xdg-toplevel | |
| 151 | - | </description> | |
| 152 | - | ||
| 153 | - | <entry name="maximized" value="0" summary="the toplevel is maximized"/> | |
| 154 | - | <entry name="minimized" value="1" summary="the toplevel is minimized"/> | |
| 155 | - | <entry name="activated" value="2" summary="the toplevel is active"/> | |
| 156 | - | <entry name="fullscreen" value="3" summary="the toplevel is fullscreen" since="2"/> | |
| 157 | - | </enum> | |
| 158 | - | ||
| 159 | - | <event name="state"> | |
| 160 | - | <description summary="the toplevel state changed"> | |
| 161 | - | This event is emitted immediately after the zlw_foreign_toplevel_handle_v1 | |
| 162 | - | is created and each time the toplevel state changes, either because of a | |
| 163 | - | compositor action or because of a request in this protocol. | |
| 164 | - | </description> | |
| 165 | - | ||
| 166 | - | <arg name="state" type="array"/> | |
| 167 | - | </event> | |
| 168 | - | ||
| 169 | - | <event name="done"> | |
| 170 | - | <description summary="all information about the toplevel has been sent"> | |
| 171 | - | This event is sent after all changes in the toplevel state have been | |
| 172 | - | sent. | |
| 173 | - | ||
| 174 | - | This allows changes to the zwlr_foreign_toplevel_handle_v1 properties | |
| 175 | - | to be seen as atomic, even if they happen via multiple events. | |
| 176 | - | </description> | |
| 177 | - | </event> | |
| 178 | - | ||
| 179 | - | <request name="close"> | |
| 180 | - | <description summary="request that the toplevel be closed"> | |
| 181 | - | Send a request to the toplevel to close itself. The compositor would | |
| 182 | - | typically use a shell-specific method to carry out this request, for | |
| 183 | - | example by sending the xdg_toplevel.close event. However, this gives | |
| 184 | - | no guarantees the toplevel will actually be destroyed. If and when | |
| 185 | - | this happens, the zwlr_foreign_toplevel_handle_v1.closed event will | |
| 186 | - | be emitted. | |
| 187 | - | </description> | |
| 188 | - | </request> | |
| 189 | - | ||
| 190 | - | <request name="set_rectangle"> | |
| 191 | - | <description summary="the rectangle which represents the toplevel"> | |
| 192 | - | The rectangle of the surface specified in this request corresponds to | |
| 193 | - | the place where the app using this protocol represents the given toplevel. | |
| 194 | - | It can be used by the compositor as a hint for some operations, e.g | |
| 195 | - | minimizing. The client is however not required to set this, in which | |
| 196 | - | case the compositor is free to decide some default value. | |
| 197 | - | ||
| 198 | - | If the client specifies more than one rectangle, only the last one is | |
| 199 | - | considered. | |
| 200 | - | ||
| 201 | - | The dimensions are given in surface-local coordinates. | |
| 202 | - | Setting width=height=0 removes the already-set rectangle. | |
| 203 | - | </description> | |
| 204 | - | ||
| 205 | - | <arg name="surface" type="object" interface="wl_surface"/> | |
| 206 | - | <arg name="x" type="int"/> | |
| 207 | - | <arg name="y" type="int"/> | |
| 208 | - | <arg name="width" type="int"/> | |
| 209 | - | <arg name="height" type="int"/> | |
| 210 | - | </request> | |
| 211 | - | ||
| 212 | - | <enum name="error"> | |
| 213 | - | <entry name="invalid_rectangle" value="0" | |
| 214 | - | summary="the provided rectangle is invalid"/> | |
| 215 | - | </enum> | |
| 216 | - | ||
| 217 | - | <event name="closed"> | |
| 218 | - | <description summary="this toplevel has been destroyed"> | |
| 219 | - | This event means the toplevel has been destroyed. It is guaranteed there | |
| 220 | - | won't be any more events for this zwlr_foreign_toplevel_handle_v1. The | |
| 221 | - | toplevel itself becomes inert so any requests will be ignored except the | |
| 222 | - | destroy request. | |
| 223 | - | </description> | |
| 224 | - | </event> | |
| 225 | - | ||
| 226 | - | <request name="destroy" type="destructor"> | |
| 227 | - | <description summary="destroy the zwlr_foreign_toplevel_handle_v1 object"> | |
| 228 | - | Destroys the zwlr_foreign_toplevel_handle_v1 object. | |
| 229 | - | ||
| 230 | - | This request should be called either when the client does not want to | |
| 231 | - | use the toplevel anymore or after the closed event to finalize the | |
| 232 | - | destruction of the object. | |
| 233 | - | </description> | |
| 234 | - | </request> | |
| 235 | - | ||
| 236 | - | <!-- Version 2 additions --> | |
| 237 | - | ||
| 238 | - | <request name="set_fullscreen" since="2"> | |
| 239 | - | <description summary="request that the toplevel be fullscreened"> | |
| 240 | - | Requests that the toplevel be fullscreened on the given output. If the | |
| 241 | - | fullscreen state and/or the outputs the toplevel is visible on actually | |
| 242 | - | change, this will be indicated by the state and output_enter/leave | |
| 243 | - | events. | |
| 244 | - | ||
| 245 | - | The output parameter is only a hint to the compositor. Also, if output | |
| 246 | - | is NULL, the compositor should decide which output the toplevel will be | |
| 247 | - | fullscreened on, if at all. | |
| 248 | - | </description> | |
| 249 | - | <arg name="output" type="object" interface="wl_output" allow-null="true"/> | |
| 250 | - | </request> | |
| 251 | - | ||
| 252 | - | <request name="unset_fullscreen" since="2"> | |
| 253 | - | <description summary="request that the toplevel be unfullscreened"> | |
| 254 | - | Requests that the toplevel be unfullscreened. If the fullscreen state | |
| 255 | - | actually changes, this will be indicated by the state event. | |
| 256 | - | </description> | |
| 257 | - | </request> | |
| 258 | - | ||
| 259 | - | <!-- Version 3 additions --> | |
| 260 | - | ||
| 261 | - | <event name="parent" since="3"> | |
| 262 | - | <description summary="parent change"> | |
| 263 | - | This event is emitted whenever the parent of the toplevel changes. | |
| 264 | - | ||
| 265 | - | No event is emitted when the parent handle is destroyed by the client. | |
| 266 | - | </description> | |
| 267 | - | <arg name="parent" type="object" interface="zwlr_foreign_toplevel_handle_v1" allow-null="true"/> | |
| 268 | - | </event> | |
| 269 | - | </interface> | |
| 270 | - | </protocol> | |
D protocol/foreigntoplevel/wlr-foreign-toplevel-management-unstable-v1_generated.go +0 -544
| @@ -1,544 +0,0 @@ | |||
| 1 | - | // Code generated by wlturbo-scanner. DO NOT EDIT. | |
| 2 | - | // Protocol: wlr_foreign_toplevel_management_unstable_v1 | |
| 3 | - | // Source: wlr-foreign-toplevel-management-unstable-v1.xml | |
| 4 | - | ||
| 5 | - | // Upstream protocol copyright and license: | |
| 6 | - | // Copyright © 2018 Ilia Bozhinov | |
| 7 | - | // | |
| 8 | - | // Permission to use, copy, modify, distribute, and sell this | |
| 9 | - | // software and its documentation for any purpose is hereby granted | |
| 10 | - | // without fee, provided that the above copyright notice appear in | |
| 11 | - | // all copies and that both that copyright notice and this permission | |
| 12 | - | // notice appear in supporting documentation, and that the name of | |
| 13 | - | // the copyright holders not be used in advertising or publicity | |
| 14 | - | // pertaining to distribution of the software without specific, | |
| 15 | - | // written prior permission. The copyright holders make no | |
| 16 | - | // representations about the suitability of this software for any | |
| 17 | - | // purpose. It is provided "as is" without express or implied | |
| 18 | - | // warranty. | |
| 19 | - | // | |
| 20 | - | // THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS | |
| 21 | - | // SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | |
| 22 | - | // FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY | |
| 23 | - | // SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
| 24 | - | // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN | |
| 25 | - | // AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | |
| 26 | - | // ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF | |
| 27 | - | // THIS SOFTWARE. | |
| 28 | - | ||
| 29 | - | package foreigntoplevel | |
| 30 | - | ||
| 31 | - | import ( | |
| 32 | - | "sync" | |
| 33 | - | ||
| 34 | - | cross_wl_output "github.com/bnema/wlturbo/protocol/core" | |
| 35 | - | cross_wl_seat "github.com/bnema/wlturbo/protocol/core" | |
| 36 | - | cross_wl_surface "github.com/bnema/wlturbo/protocol/core" | |
| 37 | - | "github.com/bnema/wlturbo/wl" | |
| 38 | - | ) | |
| 39 | - | ||
| 40 | - | // STATE_MAXIMIZED is the state maximized value. | |
| 41 | - | const STATE_MAXIMIZED = 0 | |
| 42 | - | ||
| 43 | - | // STATE_MINIMIZED is the state minimized value. | |
| 44 | - | const STATE_MINIMIZED = 1 | |
| 45 | - | ||
| 46 | - | // STATE_ACTIVATED is the state activated value. | |
| 47 | - | const STATE_ACTIVATED = 2 | |
| 48 | - | ||
| 49 | - | // STATE_FULLSCREEN is the state fullscreen value. | |
| 50 | - | const STATE_FULLSCREEN = 3 | |
| 51 | - | ||
| 52 | - | // ERROR_INVALID_RECTANGLE is the error invalid_rectangle value. | |
| 53 | - | const ERROR_INVALID_RECTANGLE = 0 | |
| 54 | - | ||
| 55 | - | // ForeignToplevelManagerInterface is the protocol interface name. | |
| 56 | - | const ForeignToplevelManagerInterface = "zwlr_foreign_toplevel_manager_v1" | |
| 57 | - | ||
| 58 | - | // ForeignToplevelManager is the generated binding for zwlr_foreign_toplevel_manager_v1 version 3. | |
| 59 | - | type ForeignToplevelManager struct { | |
| 60 | - | wl.BaseProxy | |
| 61 | - | // handlersMu guards the handler slices: a client may register or replace | |
| 62 | - | // handlers while another goroutine dispatches events. | |
| 63 | - | handlersMu sync.Mutex | |
| 64 | - | onToplevel []func(toplevelObject *ForeignToplevelHandle) | |
| 65 | - | onFinished []func() | |
| 66 | - | } | |
| 67 | - | ||
| 68 | - | // NewForeignToplevelManager returns an unbound ForeignToplevelManager. | |
| 69 | - | func NewForeignToplevelManager(ctx *wl.Context) *ForeignToplevelManager { | |
| 70 | - | obj := &ForeignToplevelManager{} | |
| 71 | - | obj.SetContext(ctx) | |
| 72 | - | ctx.Register(obj) | |
| 73 | - | return obj | |
| 74 | - | } | |
| 75 | - | ||
| 76 | - | // 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. | |
| 77 | - | func (o *ForeignToplevelManager) Stop() error { | |
| 78 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "zwlr_foreign_toplevel_manager_v1.stop"}); err != nil { | |
| 79 | - | return err | |
| 80 | - | } | |
| 81 | - | return nil | |
| 82 | - | } | |
| 83 | - | ||
| 84 | - | // OnToplevel registers a handler for the toplevel event. | |
| 85 | - | // | |
| 86 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 87 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 88 | - | func (o *ForeignToplevelManager) OnToplevel(handler func(toplevelObject *ForeignToplevelHandle)) { | |
| 89 | - | if handler == nil { | |
| 90 | - | return | |
| 91 | - | } | |
| 92 | - | o.handlersMu.Lock() | |
| 93 | - | defer o.handlersMu.Unlock() | |
| 94 | - | o.onToplevel = append(o.onToplevel, handler) | |
| 95 | - | } | |
| 96 | - | ||
| 97 | - | // handlersForToplevel returns the handlers registered for toplevel, taken | |
| 98 | - | // under the lock so a handler may register another handler while events are | |
| 99 | - | // being dispatched. | |
| 100 | - | func (o *ForeignToplevelManager) handlersForToplevel() []func(toplevelObject *ForeignToplevelHandle) { | |
| 101 | - | o.handlersMu.Lock() | |
| 102 | - | defer o.handlersMu.Unlock() | |
| 103 | - | return o.onToplevel | |
| 104 | - | } | |
| 105 | - | ||
| 106 | - | // OnFinished registers a handler for the finished event. | |
| 107 | - | // | |
| 108 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 109 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 110 | - | func (o *ForeignToplevelManager) OnFinished(handler func()) { | |
| 111 | - | if handler == nil { | |
| 112 | - | return | |
| 113 | - | } | |
| 114 | - | o.handlersMu.Lock() | |
| 115 | - | defer o.handlersMu.Unlock() | |
| 116 | - | o.onFinished = append(o.onFinished, handler) | |
| 117 | - | } | |
| 118 | - | ||
| 119 | - | // handlersForFinished returns the handlers registered for finished, taken | |
| 120 | - | // under the lock so a handler may register another handler while events are | |
| 121 | - | // being dispatched. | |
| 122 | - | func (o *ForeignToplevelManager) handlersForFinished() []func() { | |
| 123 | - | o.handlersMu.Lock() | |
| 124 | - | defer o.handlersMu.Unlock() | |
| 125 | - | return o.onFinished | |
| 126 | - | } | |
| 127 | - | ||
| 128 | - | // EventSignature returns the declared event argument types in wire order. | |
| 129 | - | func (o *ForeignToplevelManager) EventSignature(opcode uint16) (string, bool) { | |
| 130 | - | switch opcode { | |
| 131 | - | case 0: | |
| 132 | - | return "new_id,", true | |
| 133 | - | case 1: | |
| 134 | - | return "", true | |
| 135 | - | default: | |
| 136 | - | return "", false | |
| 137 | - | } | |
| 138 | - | } | |
| 139 | - | ||
| 140 | - | // Dispatch decodes one event on zwlr_foreign_toplevel_manager_v1 and calls the registered handlers. | |
| 141 | - | func (o *ForeignToplevelManager) Dispatch(event *wl.Event) { | |
| 142 | - | switch event.Opcode { | |
| 143 | - | case 0: // toplevel | |
| 144 | - | toplevelID := event.Uint32() | |
| 145 | - | toplevelObject := &ForeignToplevelHandle{} | |
| 146 | - | toplevelObject.SetContext(o.Context()) | |
| 147 | - | toplevelObject.SetID(toplevelID) | |
| 148 | - | toplevelObject.SetVersion(o.Version()) | |
| 149 | - | o.Context().Register(toplevelObject) | |
| 150 | - | ||
| 151 | - | for i, handler := range o.handlersForToplevel() { | |
| 152 | - | _ = i | |
| 153 | - | handler(toplevelObject) | |
| 154 | - | } | |
| 155 | - | case 1: // finished | |
| 156 | - | ||
| 157 | - | for i, handler := range o.handlersForFinished() { | |
| 158 | - | _ = i | |
| 159 | - | handler() | |
| 160 | - | } | |
| 161 | - | o.Context().Unregister(o) | |
| 162 | - | default: | |
| 163 | - | } | |
| 164 | - | } | |
| 165 | - | ||
| 166 | - | // ForeignToplevelHandleInterface is the protocol interface name. | |
| 167 | - | const ForeignToplevelHandleInterface = "zwlr_foreign_toplevel_handle_v1" | |
| 168 | - | ||
| 169 | - | // ForeignToplevelHandle is the generated binding for zwlr_foreign_toplevel_handle_v1 version 3. | |
| 170 | - | type ForeignToplevelHandle struct { | |
| 171 | - | wl.BaseProxy | |
| 172 | - | // handlersMu guards the handler slices: a client may register or replace | |
| 173 | - | // handlers while another goroutine dispatches events. | |
| 174 | - | handlersMu sync.Mutex | |
| 175 | - | onTitle []func(title string) | |
| 176 | - | onAppId []func(appId string) | |
| 177 | - | onOutputEnter []func(outputID uint32) | |
| 178 | - | onOutputLeave []func(outputID uint32) | |
| 179 | - | onState []func(state []byte) | |
| 180 | - | onDone []func() | |
| 181 | - | onClosed []func() | |
| 182 | - | onParent []func(parentID uint32) | |
| 183 | - | } | |
| 184 | - | ||
| 185 | - | // NewForeignToplevelHandle returns an unbound ForeignToplevelHandle. | |
| 186 | - | func NewForeignToplevelHandle(ctx *wl.Context) *ForeignToplevelHandle { | |
| 187 | - | obj := &ForeignToplevelHandle{} | |
| 188 | - | obj.SetContext(ctx) | |
| 189 | - | ctx.Register(obj) | |
| 190 | - | return obj | |
| 191 | - | } | |
| 192 | - | ||
| 193 | - | // Requests that the toplevel be maximized. If the maximized state actually changes, this will be indicated by the state event. | |
| 194 | - | func (o *ForeignToplevelHandle) SetMaximized() error { | |
| 195 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "zwlr_foreign_toplevel_handle_v1.set_maximized"}); err != nil { | |
| 196 | - | return err | |
| 197 | - | } | |
| 198 | - | return nil | |
| 199 | - | } | |
| 200 | - | ||
| 201 | - | // Requests that the toplevel be unmaximized. If the maximized state actually changes, this will be indicated by the state event. | |
| 202 | - | func (o *ForeignToplevelHandle) UnsetMaximized() error { | |
| 203 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "zwlr_foreign_toplevel_handle_v1.unset_maximized"}); err != nil { | |
| 204 | - | return err | |
| 205 | - | } | |
| 206 | - | return nil | |
| 207 | - | } | |
| 208 | - | ||
| 209 | - | // Requests that the toplevel be minimized. If the minimized state actually changes, this will be indicated by the state event. | |
| 210 | - | func (o *ForeignToplevelHandle) SetMinimized() error { | |
| 211 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 2, Name: "zwlr_foreign_toplevel_handle_v1.set_minimized"}); err != nil { | |
| 212 | - | return err | |
| 213 | - | } | |
| 214 | - | return nil | |
| 215 | - | } | |
| 216 | - | ||
| 217 | - | // Requests that the toplevel be unminimized. If the minimized state actually changes, this will be indicated by the state event. | |
| 218 | - | func (o *ForeignToplevelHandle) UnsetMinimized() error { | |
| 219 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 3, Name: "zwlr_foreign_toplevel_handle_v1.unset_minimized"}); err != nil { | |
| 220 | - | return err | |
| 221 | - | } | |
| 222 | - | return nil | |
| 223 | - | } | |
| 224 | - | ||
| 225 | - | // Request that this toplevel be activated on the given seat. There is no guarantee the toplevel will be actually activated. | |
| 226 | - | func (o *ForeignToplevelHandle) Activate(seat *cross_wl_seat.Seat) error { | |
| 227 | - | var arg0 wl.Object | |
| 228 | - | if seat != nil { | |
| 229 | - | arg0 = seat | |
| 230 | - | } | |
| 231 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 4, Name: "zwlr_foreign_toplevel_handle_v1.activate"}, wl.ArgObject(arg0)); err != nil { | |
| 232 | - | return err | |
| 233 | - | } | |
| 234 | - | return nil | |
| 235 | - | } | |
| 236 | - | ||
| 237 | - | // 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. | |
| 238 | - | func (o *ForeignToplevelHandle) Close() error { | |
| 239 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 5, Name: "zwlr_foreign_toplevel_handle_v1.close"}); err != nil { | |
| 240 | - | return err | |
| 241 | - | } | |
| 242 | - | return nil | |
| 243 | - | } | |
| 244 | - | ||
| 245 | - | // 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. | |
| 246 | - | func (o *ForeignToplevelHandle) SetRectangle(surface *cross_wl_surface.Surface, x int32, y int32, width int32, height int32) error { | |
| 247 | - | var arg0 wl.Object | |
| 248 | - | if surface != nil { | |
| 249 | - | arg0 = surface | |
| 250 | - | } | |
| 251 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 6, Name: "zwlr_foreign_toplevel_handle_v1.set_rectangle"}, wl.ArgObject(arg0), wl.ArgInt(x), wl.ArgInt(y), wl.ArgInt(width), wl.ArgInt(height)); err != nil { | |
| 252 | - | return err | |
| 253 | - | } | |
| 254 | - | return nil | |
| 255 | - | } | |
| 256 | - | ||
| 257 | - | // 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. | |
| 258 | - | func (o *ForeignToplevelHandle) Destroy() error { | |
| 259 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 7, Name: "zwlr_foreign_toplevel_handle_v1.destroy", Destructor: true}); err != nil { | |
| 260 | - | return err | |
| 261 | - | } | |
| 262 | - | return nil | |
| 263 | - | } | |
| 264 | - | ||
| 265 | - | // 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. | |
| 266 | - | func (o *ForeignToplevelHandle) SetFullscreen(output *cross_wl_output.Output) error { | |
| 267 | - | var arg0 wl.Object | |
| 268 | - | if output != nil { | |
| 269 | - | arg0 = output | |
| 270 | - | } | |
| 271 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 8, Name: "zwlr_foreign_toplevel_handle_v1.set_fullscreen", Since: 2}, wl.ArgObject(arg0)); err != nil { | |
| 272 | - | return err | |
| 273 | - | } | |
| 274 | - | return nil | |
| 275 | - | } | |
| 276 | - | ||
| 277 | - | // Requests that the toplevel be unfullscreened. If the fullscreen state actually changes, this will be indicated by the state event. | |
| 278 | - | func (o *ForeignToplevelHandle) UnsetFullscreen() error { | |
| 279 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 9, Name: "zwlr_foreign_toplevel_handle_v1.unset_fullscreen", Since: 2}); err != nil { | |
| 280 | - | return err | |
| 281 | - | } | |
| 282 | - | return nil | |
| 283 | - | } | |
| 284 | - | ||
| 285 | - | // OnTitle registers a handler for the title event. | |
| 286 | - | // | |
| 287 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 288 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 289 | - | func (o *ForeignToplevelHandle) OnTitle(handler func(title string)) { | |
| 290 | - | if handler == nil { | |
| 291 | - | return | |
| 292 | - | } | |
| 293 | - | o.handlersMu.Lock() | |
| 294 | - | defer o.handlersMu.Unlock() | |
| 295 | - | o.onTitle = append(o.onTitle, handler) | |
| 296 | - | } | |
| 297 | - | ||
| 298 | - | // handlersForTitle returns the handlers registered for title, taken | |
| 299 | - | // under the lock so a handler may register another handler while events are | |
| 300 | - | // being dispatched. | |
| 301 | - | func (o *ForeignToplevelHandle) handlersForTitle() []func(title string) { | |
| 302 | - | o.handlersMu.Lock() | |
| 303 | - | defer o.handlersMu.Unlock() | |
| 304 | - | return o.onTitle | |
| 305 | - | } | |
| 306 | - | ||
| 307 | - | // OnAppId registers a handler for the app_id event. | |
| 308 | - | // | |
| 309 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 310 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 311 | - | func (o *ForeignToplevelHandle) OnAppId(handler func(appId string)) { | |
| 312 | - | if handler == nil { | |
| 313 | - | return | |
| 314 | - | } | |
| 315 | - | o.handlersMu.Lock() | |
| 316 | - | defer o.handlersMu.Unlock() | |
| 317 | - | o.onAppId = append(o.onAppId, handler) | |
| 318 | - | } | |
| 319 | - | ||
| 320 | - | // handlersForAppId returns the handlers registered for app_id, taken | |
| 321 | - | // under the lock so a handler may register another handler while events are | |
| 322 | - | // being dispatched. | |
| 323 | - | func (o *ForeignToplevelHandle) handlersForAppId() []func(appId string) { | |
| 324 | - | o.handlersMu.Lock() | |
| 325 | - | defer o.handlersMu.Unlock() | |
| 326 | - | return o.onAppId | |
| 327 | - | } | |
| 328 | - | ||
| 329 | - | // OnOutputEnter registers a handler for the output_enter event. | |
| 330 | - | // | |
| 331 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 332 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 333 | - | func (o *ForeignToplevelHandle) OnOutputEnter(handler func(outputID uint32)) { | |
| 334 | - | if handler == nil { | |
| 335 | - | return | |
| 336 | - | } | |
| 337 | - | o.handlersMu.Lock() | |
| 338 | - | defer o.handlersMu.Unlock() | |
| 339 | - | o.onOutputEnter = append(o.onOutputEnter, handler) | |
| 340 | - | } | |
| 341 | - | ||
| 342 | - | // handlersForOutputEnter returns the handlers registered for output_enter, taken | |
| 343 | - | // under the lock so a handler may register another handler while events are | |
| 344 | - | // being dispatched. | |
| 345 | - | func (o *ForeignToplevelHandle) handlersForOutputEnter() []func(outputID uint32) { | |
| 346 | - | o.handlersMu.Lock() | |
| 347 | - | defer o.handlersMu.Unlock() | |
| 348 | - | return o.onOutputEnter | |
| 349 | - | } | |
| 350 | - | ||
| 351 | - | // OnOutputLeave registers a handler for the output_leave event. | |
| 352 | - | // | |
| 353 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 354 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 355 | - | func (o *ForeignToplevelHandle) OnOutputLeave(handler func(outputID uint32)) { | |
| 356 | - | if handler == nil { | |
| 357 | - | return | |
| 358 | - | } | |
| 359 | - | o.handlersMu.Lock() | |
| 360 | - | defer o.handlersMu.Unlock() | |
| 361 | - | o.onOutputLeave = append(o.onOutputLeave, handler) | |
| 362 | - | } | |
| 363 | - | ||
| 364 | - | // handlersForOutputLeave returns the handlers registered for output_leave, taken | |
| 365 | - | // under the lock so a handler may register another handler while events are | |
| 366 | - | // being dispatched. | |
| 367 | - | func (o *ForeignToplevelHandle) handlersForOutputLeave() []func(outputID uint32) { | |
| 368 | - | o.handlersMu.Lock() | |
| 369 | - | defer o.handlersMu.Unlock() | |
| 370 | - | return o.onOutputLeave | |
| 371 | - | } | |
| 372 | - | ||
| 373 | - | // OnState registers a handler for the state event. | |
| 374 | - | // | |
| 375 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 376 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 377 | - | func (o *ForeignToplevelHandle) OnState(handler func(state []byte)) { | |
| 378 | - | if handler == nil { | |
| 379 | - | return | |
| 380 | - | } | |
| 381 | - | o.handlersMu.Lock() | |
| 382 | - | defer o.handlersMu.Unlock() | |
| 383 | - | o.onState = append(o.onState, handler) | |
| 384 | - | } | |
| 385 | - | ||
| 386 | - | // handlersForState returns the handlers registered for state, taken | |
| 387 | - | // under the lock so a handler may register another handler while events are | |
| 388 | - | // being dispatched. | |
| 389 | - | func (o *ForeignToplevelHandle) handlersForState() []func(state []byte) { | |
| 390 | - | o.handlersMu.Lock() | |
| 391 | - | defer o.handlersMu.Unlock() | |
| 392 | - | return o.onState | |
| 393 | - | } | |
| 394 | - | ||
| 395 | - | // OnDone registers a handler for the done event. | |
| 396 | - | // | |
| 397 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 398 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 399 | - | func (o *ForeignToplevelHandle) OnDone(handler func()) { | |
| 400 | - | if handler == nil { | |
| 401 | - | return | |
| 402 | - | } | |
| 403 | - | o.handlersMu.Lock() | |
| 404 | - | defer o.handlersMu.Unlock() | |
| 405 | - | o.onDone = append(o.onDone, handler) | |
| 406 | - | } | |
| 407 | - | ||
| 408 | - | // handlersForDone returns the handlers registered for done, taken | |
| 409 | - | // under the lock so a handler may register another handler while events are | |
| 410 | - | // being dispatched. | |
| 411 | - | func (o *ForeignToplevelHandle) handlersForDone() []func() { | |
| 412 | - | o.handlersMu.Lock() | |
| 413 | - | defer o.handlersMu.Unlock() | |
| 414 | - | return o.onDone | |
| 415 | - | } | |
| 416 | - | ||
| 417 | - | // OnClosed registers a handler for the closed event. | |
| 418 | - | // | |
| 419 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 420 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 421 | - | func (o *ForeignToplevelHandle) OnClosed(handler func()) { | |
| 422 | - | if handler == nil { | |
| 423 | - | return | |
| 424 | - | } | |
| 425 | - | o.handlersMu.Lock() | |
| 426 | - | defer o.handlersMu.Unlock() | |
| 427 | - | o.onClosed = append(o.onClosed, handler) | |
| 428 | - | } | |
| 429 | - | ||
| 430 | - | // handlersForClosed returns the handlers registered for closed, taken | |
| 431 | - | // under the lock so a handler may register another handler while events are | |
| 432 | - | // being dispatched. | |
| 433 | - | func (o *ForeignToplevelHandle) handlersForClosed() []func() { | |
| 434 | - | o.handlersMu.Lock() | |
| 435 | - | defer o.handlersMu.Unlock() | |
| 436 | - | return o.onClosed | |
| 437 | - | } | |
| 438 | - | ||
| 439 | - | // OnParent registers a handler for the parent event. | |
| 440 | - | // | |
| 441 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 442 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 443 | - | func (o *ForeignToplevelHandle) OnParent(handler func(parentID uint32)) { | |
| 444 | - | if handler == nil { | |
| 445 | - | return | |
| 446 | - | } | |
| 447 | - | o.handlersMu.Lock() | |
| 448 | - | defer o.handlersMu.Unlock() | |
| 449 | - | o.onParent = append(o.onParent, handler) | |
| 450 | - | } | |
| 451 | - | ||
| 452 | - | // handlersForParent returns the handlers registered for parent, taken | |
| 453 | - | // under the lock so a handler may register another handler while events are | |
| 454 | - | // being dispatched. | |
| 455 | - | func (o *ForeignToplevelHandle) handlersForParent() []func(parentID uint32) { | |
| 456 | - | o.handlersMu.Lock() | |
| 457 | - | defer o.handlersMu.Unlock() | |
| 458 | - | return o.onParent | |
| 459 | - | } | |
| 460 | - | ||
| 461 | - | // EventSignature returns the declared event argument types in wire order. | |
| 462 | - | func (o *ForeignToplevelHandle) EventSignature(opcode uint16) (string, bool) { | |
| 463 | - | switch opcode { | |
| 464 | - | case 0: | |
| 465 | - | return "string,", true | |
| 466 | - | case 1: | |
| 467 | - | return "string,", true | |
| 468 | - | case 2: | |
| 469 | - | return "object,", true | |
| 470 | - | case 3: | |
| 471 | - | return "object,", true | |
| 472 | - | case 4: | |
| 473 | - | return "array,", true | |
| 474 | - | case 5: | |
| 475 | - | return "", true | |
| 476 | - | case 6: | |
| 477 | - | return "", true | |
| 478 | - | case 7: | |
| 479 | - | return "object,", true | |
| 480 | - | default: | |
| 481 | - | return "", false | |
| 482 | - | } | |
| 483 | - | } | |
| 484 | - | ||
| 485 | - | // Dispatch decodes one event on zwlr_foreign_toplevel_handle_v1 and calls the registered handlers. | |
| 486 | - | func (o *ForeignToplevelHandle) Dispatch(event *wl.Event) { | |
| 487 | - | switch event.Opcode { | |
| 488 | - | case 0: // title | |
| 489 | - | title := event.String() | |
| 490 | - | ||
| 491 | - | for i, handler := range o.handlersForTitle() { | |
| 492 | - | _ = i | |
| 493 | - | handler(title) | |
| 494 | - | } | |
| 495 | - | case 1: // app_id | |
| 496 | - | appId := event.String() | |
| 497 | - | ||
| 498 | - | for i, handler := range o.handlersForAppId() { | |
| 499 | - | _ = i | |
| 500 | - | handler(appId) | |
| 501 | - | } | |
| 502 | - | case 2: // output_enter | |
| 503 | - | outputID := event.Uint32() | |
| 504 | - | ||
| 505 | - | for i, handler := range o.handlersForOutputEnter() { | |
| 506 | - | _ = i | |
| 507 | - | handler(outputID) | |
| 508 | - | } | |
| 509 | - | case 3: // output_leave | |
| 510 | - | outputID := event.Uint32() | |
| 511 | - | ||
| 512 | - | for i, handler := range o.handlersForOutputLeave() { | |
| 513 | - | _ = i | |
| 514 | - | handler(outputID) | |
| 515 | - | } | |
| 516 | - | case 4: // state | |
| 517 | - | state := event.Array() | |
| 518 | - | ||
| 519 | - | for i, handler := range o.handlersForState() { | |
| 520 | - | _ = i | |
| 521 | - | handler(state) | |
| 522 | - | } | |
| 523 | - | case 5: // done | |
| 524 | - | ||
| 525 | - | for i, handler := range o.handlersForDone() { | |
| 526 | - | _ = i | |
| 527 | - | handler() | |
| 528 | - | } | |
| 529 | - | case 6: // closed | |
| 530 | - | ||
| 531 | - | for i, handler := range o.handlersForClosed() { | |
| 532 | - | _ = i | |
| 533 | - | handler() | |
| 534 | - | } | |
| 535 | - | case 7: // parent | |
| 536 | - | parentID := event.Uint32() | |
| 537 | - | ||
| 538 | - | for i, handler := range o.handlersForParent() { | |
| 539 | - | _ = i | |
| 540 | - | handler(parentID) | |
| 541 | - | } | |
| 542 | - | default: | |
| 543 | - | } | |
| 544 | - | } | |
D protocol/format_table_test.go +0 -71
| @@ -1,71 +0,0 @@ | |||
| 1 | - | //go:build linux | |
| 2 | - | ||
| 3 | - | package protocol_test | |
| 4 | - | ||
| 5 | - | import ( | |
| 6 | - | "errors" | |
| 7 | - | "github.com/bnema/wlturbo" | |
| 8 | - | "github.com/bnema/wlturbo/protocol/linuxdmabuf" | |
| 9 | - | "golang.org/x/sys/unix" | |
| 10 | - | "io" | |
| 11 | - | "os" | |
| 12 | - | "testing" | |
| 13 | - | ) | |
| 14 | - | ||
| 15 | - | // Exercise format_table through generated event dispatch so the received FD | |
| 16 | - | // has real transport ownership; verify closing by inspecting the taken FD. | |
| 17 | - | func TestMalformedFormatTables(t *testing.T) { | |
| 18 | - | for _, tc := range []struct { | |
| 19 | - | name string | |
| 20 | - | contents []byte | |
| 21 | - | size uint32 | |
| 22 | - | wantErr bool | |
| 23 | - | }{ | |
| 24 | - | {"unaligned", make([]byte, 16), 17, true}, | |
| 25 | - | {"truncated", make([]byte, 16), 32, true}, | |
| 26 | - | {"zero", nil, 0, false}, | |
| 27 | - | {"oversize", nil, (16 << 20) + 16, true}, | |
| 28 | - | } { | |
| 29 | - | t.Run(tc.name, func(t *testing.T) { | |
| 30 | - | c, p := pair(t) | |
| 31 | - | d, e := wlturbo.ConnectFromConn(c) | |
| 32 | - | noerr(t, e) | |
| 33 | - | defer d.Close() | |
| 34 | - | request(t, p) | |
| 35 | - | fb := linuxdmabuf.NewLinuxDmabufFeedback(d.Context()) | |
| 36 | - | fb.SetID(d.AllocateID()) | |
| 37 | - | d.Context().Register(fb) | |
| 38 | - | file, e := os.CreateTemp(t.TempDir(), "table") | |
| 39 | - | noerr(t, e) | |
| 40 | - | defer file.Close() | |
| 41 | - | _, e = file.Write(tc.contents) | |
| 42 | - | noerr(t, e) | |
| 43 | - | called := false | |
| 44 | - | fb.OnFormatTable(func(fd *wlturbo.OwnedFD, size uint32) { | |
| 45 | - | called = true | |
| 46 | - | entries, err := linuxdmabuf.ReadFormatTable(fd, size) | |
| 47 | - | if (err != nil) != tc.wantErr { | |
| 48 | - | t.Fatalf("size=%d entries=%v err=%v", size, entries, err) | |
| 49 | - | } | |
| 50 | - | if tc.name == "truncated" && !errors.Is(err, io.ErrUnexpectedEOF) { | |
| 51 | - | t.Fatalf("short read: %v", err) | |
| 52 | - | } | |
| 53 | - | // Take/Close must be idempotent, including after a failed size check. | |
| 54 | - | if _, err = fd.Take(); err == nil { | |
| 55 | - | t.Fatal("already consumed fd still takeable") | |
| 56 | - | } | |
| 57 | - | noerr(t, fd.Close()) | |
| 58 | - | noerr(t, fd.Close()) | |
| 59 | - | }) | |
| 60 | - | send(t, p, msg(fb.ID(), 1, tc.size), int(file.Fd())) | |
| 61 | - | noerr(t, d.Dispatch()) | |
| 62 | - | if !called { | |
| 63 | - | t.Fatal("no callback") | |
| 64 | - | } | |
| 65 | - | // The transport FD was a duplicate: caller's descriptor is still open. | |
| 66 | - | if _, e = unix.FcntlInt(file.Fd(), unix.F_GETFD, 0); e != nil { | |
| 67 | - | t.Fatalf("sender fd closed: %v", e) | |
| 68 | - | } | |
| 69 | - | }) | |
| 70 | - | } | |
| 71 | - | } | |
D protocol/fractionalscale/fractional-scale-v1.xml +0 -102
| @@ -1,102 +0,0 @@ | |||
| 1 | - | <?xml version="1.0" encoding="UTF-8"?> | |
| 2 | - | <protocol name="fractional_scale_v1"> | |
| 3 | - | <copyright> | |
| 4 | - | Copyright © 2022 Kenny Levinsen | |
| 5 | - | ||
| 6 | - | Permission is hereby granted, free of charge, to any person obtaining a | |
| 7 | - | copy of this software and associated documentation files (the "Software"), | |
| 8 | - | to deal in the Software without restriction, including without limitation | |
| 9 | - | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 10 | - | and/or sell copies of the Software, and to permit persons to whom the | |
| 11 | - | Software is furnished to do so, subject to the following conditions: | |
| 12 | - | ||
| 13 | - | The above copyright notice and this permission notice (including the next | |
| 14 | - | paragraph) shall be included in all copies or substantial portions of the | |
| 15 | - | Software. | |
| 16 | - | ||
| 17 | - | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 18 | - | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 19 | - | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 20 | - | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 21 | - | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 22 | - | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
| 23 | - | DEALINGS IN THE SOFTWARE. | |
| 24 | - | </copyright> | |
| 25 | - | ||
| 26 | - | <description summary="Protocol for requesting fractional surface scales"> | |
| 27 | - | This protocol allows a compositor to suggest for surfaces to render at | |
| 28 | - | fractional scales. | |
| 29 | - | ||
| 30 | - | A client can submit scaled content by utilizing wp_viewport. This is done by | |
| 31 | - | creating a wp_viewport object for the surface and setting the destination | |
| 32 | - | rectangle to the surface size before the scale factor is applied. | |
| 33 | - | ||
| 34 | - | The buffer size is calculated by multiplying the surface size by the | |
| 35 | - | intended scale. | |
| 36 | - | ||
| 37 | - | The wl_surface buffer scale should remain set to 1. | |
| 38 | - | ||
| 39 | - | If a surface has a surface-local size of 100 px by 50 px and wishes to | |
| 40 | - | submit buffers with a scale of 1.5, then a buffer of 150px by 75 px should | |
| 41 | - | be used and the wp_viewport destination rectangle should be 100 px by 50 px. | |
| 42 | - | ||
| 43 | - | For toplevel surfaces, the size is rounded halfway away from zero. The | |
| 44 | - | rounding algorithm for subsurface position and size is not defined. | |
| 45 | - | </description> | |
| 46 | - | ||
| 47 | - | <interface name="wp_fractional_scale_manager_v1" version="1"> | |
| 48 | - | <description summary="fractional surface scale information"> | |
| 49 | - | A global interface for requesting surfaces to use fractional scales. | |
| 50 | - | </description> | |
| 51 | - | ||
| 52 | - | <request name="destroy" type="destructor"> | |
| 53 | - | <description summary="unbind the fractional surface scale interface"> | |
| 54 | - | Informs the server that the client will not be using this protocol | |
| 55 | - | object anymore. This does not affect any other objects, | |
| 56 | - | wp_fractional_scale_v1 objects included. | |
| 57 | - | </description> | |
| 58 | - | </request> | |
| 59 | - | ||
| 60 | - | <enum name="error"> | |
| 61 | - | <entry name="fractional_scale_exists" value="0" | |
| 62 | - | summary="the surface already has a fractional_scale object associated"/> | |
| 63 | - | </enum> | |
| 64 | - | ||
| 65 | - | <request name="get_fractional_scale"> | |
| 66 | - | <description summary="extend surface interface for scale information"> | |
| 67 | - | Create an add-on object for the the wl_surface to let the compositor | |
| 68 | - | request fractional scales. If the given wl_surface already has a | |
| 69 | - | wp_fractional_scale_v1 object associated, the fractional_scale_exists | |
| 70 | - | protocol error is raised. | |
| 71 | - | </description> | |
| 72 | - | <arg name="id" type="new_id" interface="wp_fractional_scale_v1" | |
| 73 | - | summary="the new surface scale info interface id"/> | |
| 74 | - | <arg name="surface" type="object" interface="wl_surface" | |
| 75 | - | summary="the surface"/> | |
| 76 | - | </request> | |
| 77 | - | </interface> | |
| 78 | - | ||
| 79 | - | <interface name="wp_fractional_scale_v1" version="1"> | |
| 80 | - | <description summary="fractional scale interface to a wl_surface"> | |
| 81 | - | An additional interface to a wl_surface object which allows the compositor | |
| 82 | - | to inform the client of the preferred scale. | |
| 83 | - | </description> | |
| 84 | - | ||
| 85 | - | <request name="destroy" type="destructor"> | |
| 86 | - | <description summary="remove surface scale information for surface"> | |
| 87 | - | Destroy the fractional scale object. When this object is destroyed, | |
| 88 | - | preferred_scale events will no longer be sent. | |
| 89 | - | </description> | |
| 90 | - | </request> | |
| 91 | - | ||
| 92 | - | <event name="preferred_scale"> | |
| 93 | - | <description summary="notify of new preferred scale"> | |
| 94 | - | Notification of a new preferred scale for this surface that the | |
| 95 | - | compositor suggests that the client should use. | |
| 96 | - | ||
| 97 | - | The sent scale is the numerator of a fraction with a denominator of 120. | |
| 98 | - | </description> | |
| 99 | - | <arg name="scale" type="uint" summary="the new preferred scale"/> | |
| 100 | - | </event> | |
| 101 | - | </interface> | |
| 102 | - | </protocol> | |
D protocol/fractionalscale/fractional-scale-v1_generated.go +0 -164
| @@ -1,164 +0,0 @@ | |||
| 1 | - | // Code generated by wlturbo-scanner. DO NOT EDIT. | |
| 2 | - | // Protocol: fractional_scale_v1 | |
| 3 | - | // Source: fractional-scale-v1.xml | |
| 4 | - | ||
| 5 | - | // Upstream protocol copyright and license: | |
| 6 | - | // Copyright © 2022 Kenny Levinsen | |
| 7 | - | // | |
| 8 | - | // Permission is hereby granted, free of charge, to any person obtaining a | |
| 9 | - | // copy of this software and associated documentation files (the "Software"), | |
| 10 | - | // to deal in the Software without restriction, including without limitation | |
| 11 | - | // the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 12 | - | // and/or sell copies of the Software, and to permit persons to whom the | |
| 13 | - | // Software is furnished to do so, subject to the following conditions: | |
| 14 | - | // | |
| 15 | - | // The above copyright notice and this permission notice (including the next | |
| 16 | - | // paragraph) shall be included in all copies or substantial portions of the | |
| 17 | - | // Software. | |
| 18 | - | // | |
| 19 | - | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 20 | - | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 21 | - | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 22 | - | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 23 | - | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 24 | - | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
| 25 | - | // DEALINGS IN THE SOFTWARE. | |
| 26 | - | ||
| 27 | - | package fractionalscale | |
| 28 | - | ||
| 29 | - | import ( | |
| 30 | - | "sync" | |
| 31 | - | ||
| 32 | - | cross_wl_surface "github.com/bnema/wlturbo/protocol/core" | |
| 33 | - | "github.com/bnema/wlturbo/wl" | |
| 34 | - | ) | |
| 35 | - | ||
| 36 | - | // ERROR_FRACTIONAL_SCALE_EXISTS is the error fractional_scale_exists value. | |
| 37 | - | const ERROR_FRACTIONAL_SCALE_EXISTS = 0 | |
| 38 | - | ||
| 39 | - | // WpFractionalScaleManagerInterface is the protocol interface name. | |
| 40 | - | const WpFractionalScaleManagerInterface = "wp_fractional_scale_manager_v1" | |
| 41 | - | ||
| 42 | - | // WpFractionalScaleManager is the generated binding for wp_fractional_scale_manager_v1 version 1. | |
| 43 | - | type WpFractionalScaleManager struct { | |
| 44 | - | wl.BaseProxy | |
| 45 | - | } | |
| 46 | - | ||
| 47 | - | // NewWpFractionalScaleManager returns an unbound WpFractionalScaleManager. | |
| 48 | - | func NewWpFractionalScaleManager(ctx *wl.Context) *WpFractionalScaleManager { | |
| 49 | - | obj := &WpFractionalScaleManager{} | |
| 50 | - | obj.SetContext(ctx) | |
| 51 | - | ctx.Register(obj) | |
| 52 | - | return obj | |
| 53 | - | } | |
| 54 | - | ||
| 55 | - | // 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. | |
| 56 | - | func (o *WpFractionalScaleManager) Destroy() error { | |
| 57 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "wp_fractional_scale_manager_v1.destroy", Destructor: true}); err != nil { | |
| 58 | - | return err | |
| 59 | - | } | |
| 60 | - | return nil | |
| 61 | - | } | |
| 62 | - | ||
| 63 | - | // 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. | |
| 64 | - | func (o *WpFractionalScaleManager) GetFractionalScale(surface *cross_wl_surface.Surface) (*WpFractionalScale, error) { | |
| 65 | - | var arg1 wl.Object | |
| 66 | - | if surface != nil { | |
| 67 | - | arg1 = surface | |
| 68 | - | } | |
| 69 | - | child := &WpFractionalScale{} | |
| 70 | - | child.SetContext(o.Context()) | |
| 71 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "wp_fractional_scale_manager_v1.get_fractional_scale", Child: child}, wl.ArgObject(child), wl.ArgObject(arg1)); err != nil { | |
| 72 | - | return nil, err | |
| 73 | - | } | |
| 74 | - | return child, nil | |
| 75 | - | } | |
| 76 | - | ||
| 77 | - | // EventSignature returns the declared event argument types in wire order. | |
| 78 | - | func (o *WpFractionalScaleManager) EventSignature(opcode uint16) (string, bool) { | |
| 79 | - | switch opcode { | |
| 80 | - | default: | |
| 81 | - | return "", false | |
| 82 | - | } | |
| 83 | - | } | |
| 84 | - | ||
| 85 | - | // Dispatch decodes one event on wp_fractional_scale_manager_v1 and calls the registered handlers. | |
| 86 | - | func (o *WpFractionalScaleManager) Dispatch(event *wl.Event) { | |
| 87 | - | switch event.Opcode { | |
| 88 | - | default: | |
| 89 | - | } | |
| 90 | - | } | |
| 91 | - | ||
| 92 | - | // WpFractionalScaleInterface is the protocol interface name. | |
| 93 | - | const WpFractionalScaleInterface = "wp_fractional_scale_v1" | |
| 94 | - | ||
| 95 | - | // WpFractionalScale is the generated binding for wp_fractional_scale_v1 version 1. | |
| 96 | - | type WpFractionalScale struct { | |
| 97 | - | wl.BaseProxy | |
| 98 | - | // handlersMu guards the handler slices: a client may register or replace | |
| 99 | - | // handlers while another goroutine dispatches events. | |
| 100 | - | handlersMu sync.Mutex | |
| 101 | - | onPreferredScale []func(scale uint32) | |
| 102 | - | } | |
| 103 | - | ||
| 104 | - | // NewWpFractionalScale returns an unbound WpFractionalScale. | |
| 105 | - | func NewWpFractionalScale(ctx *wl.Context) *WpFractionalScale { | |
| 106 | - | obj := &WpFractionalScale{} | |
| 107 | - | obj.SetContext(ctx) | |
| 108 | - | ctx.Register(obj) | |
| 109 | - | return obj | |
| 110 | - | } | |
| 111 | - | ||
| 112 | - | // Destroy the fractional scale object. When this object is destroyed, preferred_scale events will no longer be sent. | |
| 113 | - | func (o *WpFractionalScale) Destroy() error { | |
| 114 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "wp_fractional_scale_v1.destroy", Destructor: true}); err != nil { | |
| 115 | - | return err | |
| 116 | - | } | |
| 117 | - | return nil | |
| 118 | - | } | |
| 119 | - | ||
| 120 | - | // OnPreferredScale registers a handler for the preferred_scale event. | |
| 121 | - | // | |
| 122 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 123 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 124 | - | func (o *WpFractionalScale) OnPreferredScale(handler func(scale uint32)) { | |
| 125 | - | if handler == nil { | |
| 126 | - | return | |
| 127 | - | } | |
| 128 | - | o.handlersMu.Lock() | |
| 129 | - | defer o.handlersMu.Unlock() | |
| 130 | - | o.onPreferredScale = append(o.onPreferredScale, handler) | |
| 131 | - | } | |
| 132 | - | ||
| 133 | - | // handlersForPreferredScale returns the handlers registered for preferred_scale, taken | |
| 134 | - | // under the lock so a handler may register another handler while events are | |
| 135 | - | // being dispatched. | |
| 136 | - | func (o *WpFractionalScale) handlersForPreferredScale() []func(scale uint32) { | |
| 137 | - | o.handlersMu.Lock() | |
| 138 | - | defer o.handlersMu.Unlock() | |
| 139 | - | return o.onPreferredScale | |
| 140 | - | } | |
| 141 | - | ||
| 142 | - | // EventSignature returns the declared event argument types in wire order. | |
| 143 | - | func (o *WpFractionalScale) EventSignature(opcode uint16) (string, bool) { | |
| 144 | - | switch opcode { | |
| 145 | - | case 0: | |
| 146 | - | return "uint,", true | |
| 147 | - | default: | |
| 148 | - | return "", false | |
| 149 | - | } | |
| 150 | - | } | |
| 151 | - | ||
| 152 | - | // Dispatch decodes one event on wp_fractional_scale_v1 and calls the registered handlers. | |
| 153 | - | func (o *WpFractionalScale) Dispatch(event *wl.Event) { | |
| 154 | - | switch event.Opcode { | |
| 155 | - | case 0: // preferred_scale | |
| 156 | - | scale := event.Uint32() | |
| 157 | - | ||
| 158 | - | for i, handler := range o.handlersForPreferredScale() { | |
| 159 | - | _ = i | |
| 160 | - | handler(scale) | |
| 161 | - | } | |
| 162 | - | default: | |
| 163 | - | } | |
| 164 | - | } | |
D protocol/generate.go +0 -11
| @@ -1,11 +0,0 @@ | |||
| 1 | - | package protocol | |
| 2 | - | ||
| 3 | - | //go:generate go run ../cmd/wlturbo-scanner -p core -o core/wayland_generated.go wayland.xml | |
| 4 | - | //go:generate go run ../cmd/wlturbo-scanner -p xdgshell -o xdgshell/xdg-shell_generated.go -import wl_surface=github.com/bnema/wlturbo/protocol/core -import wl_seat=github.com/bnema/wlturbo/protocol/core -import wl_output=github.com/bnema/wlturbo/protocol/core xdgshell/xdg-shell.xml | |
| 5 | - | //go:generate go run ../cmd/wlturbo-scanner -p linuxdmabuf -o linuxdmabuf/linux-dmabuf-v1_generated.go -import wl_surface=github.com/bnema/wlturbo/protocol/core -import wl_buffer=github.com/bnema/wlturbo/protocol/core linuxdmabuf/linux-dmabuf-v1.xml | |
| 6 | - | //go:generate go run ../cmd/wlturbo-scanner -p drmsyncobj -o drmsyncobj/linux-drm-syncobj-v1_generated.go -import wl_surface=github.com/bnema/wlturbo/protocol/core drmsyncobj/linux-drm-syncobj-v1.xml | |
| 7 | - | //go:generate go run ../cmd/wlturbo-scanner -p viewporter -o viewporter/viewporter_generated.go -import wl_surface=github.com/bnema/wlturbo/protocol/core viewporter/viewporter.xml | |
| 8 | - | //go:generate go run ../cmd/wlturbo-scanner -p fractionalscale -o fractionalscale/fractional-scale-v1_generated.go -import wl_surface=github.com/bnema/wlturbo/protocol/core fractionalscale/fractional-scale-v1.xml | |
| 9 | - | //go:generate go run ../cmd/wlturbo-scanner -p tablet -o tablet/tablet-v2_generated.go -import wl_surface=github.com/bnema/wlturbo/protocol/core -import wl_seat=github.com/bnema/wlturbo/protocol/core tablet/tablet-v2.xml | |
| 10 | - | //go:generate go run ../cmd/wlturbo-scanner -p cursorshape -o cursorshape/cursor-shape-v1_generated.go -import wl_pointer=github.com/bnema/wlturbo/protocol/core -import zwp_tablet_tool_v2=github.com/bnema/wlturbo/protocol/tablet cursorshape/cursor-shape-v1.xml | |
| 11 | - | //go:generate go run ../cmd/wlturbo-scanner -p textinput -o textinput/text-input-unstable-v3_generated.go -import wl_surface=github.com/bnema/wlturbo/protocol/core -import wl_seat=github.com/bnema/wlturbo/protocol/core textinput/text-input-unstable-v3.xml | |
D protocol/headless_extensions_test.go +0 -430
| @@ -1,430 +0,0 @@ | |||
| 1 | - | //go:build linux | |
| 2 | - | ||
| 3 | - | package protocol_test | |
| 4 | - | ||
| 5 | - | import ( | |
| 6 | - | "fmt" | |
| 7 | - | "sort" | |
| 8 | - | "testing" | |
| 9 | - | ||
| 10 | - | "github.com/bnema/wlturbo" | |
| 11 | - | "github.com/bnema/wlturbo/protocol/alphamodifier" | |
| 12 | - | "github.com/bnema/wlturbo/protocol/colormanagement" | |
| 13 | - | "github.com/bnema/wlturbo/protocol/colorrepresentation" | |
| 14 | - | "github.com/bnema/wlturbo/protocol/committiming" | |
| 15 | - | "github.com/bnema/wlturbo/protocol/contenttype" | |
| 16 | - | "github.com/bnema/wlturbo/protocol/core" | |
| 17 | - | "github.com/bnema/wlturbo/protocol/cursorshape" | |
| 18 | - | "github.com/bnema/wlturbo/protocol/datacontrol" | |
| 19 | - | "github.com/bnema/wlturbo/protocol/drmlease" | |
| 20 | - | "github.com/bnema/wlturbo/protocol/drmsyncobj" | |
| 21 | - | "github.com/bnema/wlturbo/protocol/extforeigntoplevel" | |
| 22 | - | "github.com/bnema/wlturbo/protocol/fifo" | |
| 23 | - | "github.com/bnema/wlturbo/protocol/foreigntoplevel" | |
| 24 | - | "github.com/bnema/wlturbo/protocol/fractionalscale" | |
| 25 | - | "github.com/bnema/wlturbo/protocol/idleinhibit" | |
| 26 | - | "github.com/bnema/wlturbo/protocol/idlenotify" | |
| 27 | - | "github.com/bnema/wlturbo/protocol/imagecapturesource" | |
| 28 | - | "github.com/bnema/wlturbo/protocol/imagecopycapture" | |
| 29 | - | "github.com/bnema/wlturbo/protocol/inputmethod" | |
| 30 | - | "github.com/bnema/wlturbo/protocol/kdeserverdecoration" | |
| 31 | - | "github.com/bnema/wlturbo/protocol/layershell" | |
| 32 | - | "github.com/bnema/wlturbo/protocol/linuxdmabuf" | |
| 33 | - | "github.com/bnema/wlturbo/protocol/outputmanagement" | |
| 34 | - | "github.com/bnema/wlturbo/protocol/outputpower" | |
| 35 | - | "github.com/bnema/wlturbo/protocol/pointerconstraints" | |
| 36 | - | "github.com/bnema/wlturbo/protocol/pointerwarp" | |
| 37 | - | "github.com/bnema/wlturbo/protocol/presentation" | |
| 38 | - | "github.com/bnema/wlturbo/protocol/primaryselection" | |
| 39 | - | "github.com/bnema/wlturbo/protocol/relativepointer" | |
| 40 | - | "github.com/bnema/wlturbo/protocol/screencopy" | |
| 41 | - | "github.com/bnema/wlturbo/protocol/shortcutsinhibit" | |
| 42 | - | "github.com/bnema/wlturbo/protocol/tablet" | |
| 43 | - | "github.com/bnema/wlturbo/protocol/tearingcontrol" | |
| 44 | - | "github.com/bnema/wlturbo/protocol/textinput" | |
| 45 | - | "github.com/bnema/wlturbo/protocol/viewporter" | |
| 46 | - | "github.com/bnema/wlturbo/protocol/virtualkeyboard" | |
| 47 | - | "github.com/bnema/wlturbo/protocol/workspace" | |
| 48 | - | "github.com/bnema/wlturbo/protocol/xdgactivation" | |
| 49 | - | "github.com/bnema/wlturbo/protocol/xdgdecoration" | |
| 50 | - | "github.com/bnema/wlturbo/protocol/xdgoutput" | |
| 51 | - | "github.com/bnema/wlturbo/protocol/xdgshell" | |
| 52 | - | "golang.org/x/sys/unix" | |
| 53 | - | ) | |
| 54 | - | ||
| 55 | - | // headlessBinding is one generated root object and the highest version its | |
| 56 | - | // package supports (the XML interface version). | |
| 57 | - | type headlessBinding struct { | |
| 58 | - | iface string | |
| 59 | - | supported uint32 | |
| 60 | - | make func(*wlturbo.Context) wlturbo.Proxy | |
| 61 | - | // optional marks globals that depend on GPU, DRM or input devices, or that | |
| 62 | - | // this NeferWL build does not advertise headless: absence is logged, not | |
| 63 | - | // a failure. Everything else must be announced. | |
| 64 | - | optional bool | |
| 65 | - | } | |
| 66 | - | ||
| 67 | - | func headlessBindings() []headlessBinding { | |
| 68 | - | return []headlessBinding{ | |
| 69 | - | {core.CompositorInterface, 7, func(c *wlturbo.Context) wlturbo.Proxy { return core.NewCompositor(c) }, false}, | |
| 70 | - | {core.SubcompositorInterface, 1, func(c *wlturbo.Context) wlturbo.Proxy { return core.NewSubcompositor(c) }, false}, | |
| 71 | - | {core.ShmInterface, 3, func(c *wlturbo.Context) wlturbo.Proxy { return core.NewShm(c) }, false}, | |
| 72 | - | {core.SeatInterface, 11, func(c *wlturbo.Context) wlturbo.Proxy { return core.NewSeat(c) }, false}, | |
| 73 | - | {core.OutputInterface, 4, func(c *wlturbo.Context) wlturbo.Proxy { return core.NewOutput(c) }, false}, | |
| 74 | - | {core.DataDeviceManagerInterface, 4, func(c *wlturbo.Context) wlturbo.Proxy { return core.NewDataDeviceManager(c) }, false}, | |
| 75 | - | {xdgshell.XdgWmBaseInterface, 7, func(c *wlturbo.Context) wlturbo.Proxy { return xdgshell.NewXdgWmBase(c) }, false}, | |
| 76 | - | {linuxdmabuf.LinuxDmabufInterface, 6, func(c *wlturbo.Context) wlturbo.Proxy { return linuxdmabuf.NewLinuxDmabuf(c) }, true}, | |
| 77 | - | {drmsyncobj.WpLinuxDrmSyncobjManagerInterface, 1, func(c *wlturbo.Context) wlturbo.Proxy { return drmsyncobj.NewWpLinuxDrmSyncobjManager(c) }, true}, | |
| 78 | - | {viewporter.WpViewporterInterface, 1, func(c *wlturbo.Context) wlturbo.Proxy { return viewporter.NewWpViewporter(c) }, false}, | |
| 79 | - | {fractionalscale.WpFractionalScaleManagerInterface, 1, func(c *wlturbo.Context) wlturbo.Proxy { return fractionalscale.NewWpFractionalScaleManager(c) }, false}, | |
| 80 | - | {cursorshape.WpCursorShapeManagerInterface, 2, func(c *wlturbo.Context) wlturbo.Proxy { return cursorshape.NewWpCursorShapeManager(c) }, false}, | |
| 81 | - | {tablet.TabletManagerInterface, 2, func(c *wlturbo.Context) wlturbo.Proxy { return tablet.NewTabletManager(c) }, true}, | |
| 82 | - | {textinput.TextInputManagerV3Interface, 2, func(c *wlturbo.Context) wlturbo.Proxy { return textinput.NewTextInputManagerV3(c) }, false}, | |
| 83 | - | {alphamodifier.WpAlphaModifierInterface, 1, func(c *wlturbo.Context) wlturbo.Proxy { return alphamodifier.NewWpAlphaModifier(c) }, false}, | |
| 84 | - | {colormanagement.WpColorManagerInterface, 3, func(c *wlturbo.Context) wlturbo.Proxy { return colormanagement.NewWpColorManager(c) }, false}, | |
| 85 | - | {colorrepresentation.WpColorRepresentationManagerInterface, 1, func(c *wlturbo.Context) wlturbo.Proxy { return colorrepresentation.NewWpColorRepresentationManager(c) }, false}, | |
| 86 | - | {committiming.WpCommitTimingManagerInterface, 1, func(c *wlturbo.Context) wlturbo.Proxy { return committiming.NewWpCommitTimingManager(c) }, false}, | |
| 87 | - | {contenttype.WpContentTypeManagerInterface, 1, func(c *wlturbo.Context) wlturbo.Proxy { return contenttype.NewWpContentTypeManager(c) }, false}, | |
| 88 | - | {datacontrol.ExtDataControlManagerInterface, 1, func(c *wlturbo.Context) wlturbo.Proxy { return datacontrol.NewExtDataControlManager(c) }, false}, | |
| 89 | - | {drmlease.WpDrmLeaseDeviceInterface, 1, func(c *wlturbo.Context) wlturbo.Proxy { return drmlease.NewWpDrmLeaseDevice(c) }, true}, | |
| 90 | - | {extforeigntoplevel.ExtForeignToplevelListInterface, 1, func(c *wlturbo.Context) wlturbo.Proxy { return extforeigntoplevel.NewExtForeignToplevelList(c) }, true}, | |
| 91 | - | {fifo.WpFifoManagerInterface, 1, func(c *wlturbo.Context) wlturbo.Proxy { return fifo.NewWpFifoManager(c) }, false}, | |
| 92 | - | {foreigntoplevel.ForeignToplevelManagerInterface, 3, func(c *wlturbo.Context) wlturbo.Proxy { return foreigntoplevel.NewForeignToplevelManager(c) }, false}, | |
| 93 | - | {idleinhibit.IdleInhibitManagerInterface, 1, func(c *wlturbo.Context) wlturbo.Proxy { return idleinhibit.NewIdleInhibitManager(c) }, false}, | |
| 94 | - | {idlenotify.ExtIdleNotifierInterface, 2, func(c *wlturbo.Context) wlturbo.Proxy { return idlenotify.NewExtIdleNotifier(c) }, false}, | |
| 95 | - | {imagecapturesource.ExtOutputImageCaptureSourceManagerInterface, 1, func(c *wlturbo.Context) wlturbo.Proxy { | |
| 96 | - | return imagecapturesource.NewExtOutputImageCaptureSourceManager(c) | |
| 97 | - | }, false}, | |
| 98 | - | {imagecapturesource.ExtForeignToplevelImageCaptureSourceManagerInterface, 1, func(c *wlturbo.Context) wlturbo.Proxy { | |
| 99 | - | return imagecapturesource.NewExtForeignToplevelImageCaptureSourceManager(c) | |
| 100 | - | }, true}, | |
| 101 | - | {imagecopycapture.ExtImageCopyCaptureManagerInterface, 1, func(c *wlturbo.Context) wlturbo.Proxy { return imagecopycapture.NewExtImageCopyCaptureManager(c) }, false}, | |
| 102 | - | {inputmethod.InputMethodManagerInterface, 1, func(c *wlturbo.Context) wlturbo.Proxy { return inputmethod.NewInputMethodManager(c) }, false}, | |
| 103 | - | {kdeserverdecoration.OrgKdeKwinServerDecorationManagerInterface, 1, func(c *wlturbo.Context) wlturbo.Proxy { | |
| 104 | - | return kdeserverdecoration.NewOrgKdeKwinServerDecorationManager(c) | |
| 105 | - | }, false}, | |
| 106 | - | {layershell.LayerShellInterface, 5, func(c *wlturbo.Context) wlturbo.Proxy { return layershell.NewLayerShell(c) }, false}, | |
| 107 | - | {outputmanagement.OutputManagerInterface, 4, func(c *wlturbo.Context) wlturbo.Proxy { return outputmanagement.NewOutputManager(c) }, false}, | |
| 108 | - | {outputpower.OutputPowerManagerInterface, 1, func(c *wlturbo.Context) wlturbo.Proxy { return outputpower.NewOutputPowerManager(c) }, false}, | |
| 109 | - | {pointerconstraints.PointerConstraintsInterface, 1, func(c *wlturbo.Context) wlturbo.Proxy { return pointerconstraints.NewPointerConstraints(c) }, false}, | |
| 110 | - | {pointerwarp.WpPointerWarpInterface, 1, func(c *wlturbo.Context) wlturbo.Proxy { return pointerwarp.NewWpPointerWarp(c) }, false}, | |
| 111 | - | {presentation.WpPresentationInterface, 2, func(c *wlturbo.Context) wlturbo.Proxy { return presentation.NewWpPresentation(c) }, false}, | |
| 112 | - | {primaryselection.PrimarySelectionDeviceManagerInterface, 1, func(c *wlturbo.Context) wlturbo.Proxy { return primaryselection.NewPrimarySelectionDeviceManager(c) }, false}, | |
| 113 | - | {relativepointer.RelativePointerManagerInterface, 1, func(c *wlturbo.Context) wlturbo.Proxy { return relativepointer.NewRelativePointerManager(c) }, false}, | |
| 114 | - | {screencopy.ScreencopyManagerInterface, 3, func(c *wlturbo.Context) wlturbo.Proxy { return screencopy.NewScreencopyManager(c) }, false}, | |
| 115 | - | {shortcutsinhibit.KeyboardShortcutsInhibitManagerInterface, 1, func(c *wlturbo.Context) wlturbo.Proxy { return shortcutsinhibit.NewKeyboardShortcutsInhibitManager(c) }, false}, | |
| 116 | - | {tearingcontrol.WpTearingControlManagerInterface, 1, func(c *wlturbo.Context) wlturbo.Proxy { return tearingcontrol.NewWpTearingControlManager(c) }, false}, | |
| 117 | - | {virtualkeyboard.VirtualKeyboardManagerInterface, 1, func(c *wlturbo.Context) wlturbo.Proxy { return virtualkeyboard.NewVirtualKeyboardManager(c) }, false}, | |
| 118 | - | {workspace.ExtWorkspaceManagerInterface, 1, func(c *wlturbo.Context) wlturbo.Proxy { return workspace.NewExtWorkspaceManager(c) }, false}, | |
| 119 | - | {xdgactivation.XdgActivationInterface, 1, func(c *wlturbo.Context) wlturbo.Proxy { return xdgactivation.NewXdgActivation(c) }, false}, | |
| 120 | - | {xdgdecoration.ZxdgDecorationManagerInterface, 2, func(c *wlturbo.Context) wlturbo.Proxy { return xdgdecoration.NewZxdgDecorationManager(c) }, false}, | |
| 121 | - | {xdgoutput.ZxdgOutputManagerInterface, 3, func(c *wlturbo.Context) wlturbo.Proxy { return xdgoutput.NewZxdgOutputManager(c) }, false}, | |
| 122 | - | } | |
| 123 | - | } | |
| 124 | - | ||
| 125 | - | // waitGlobal blocks in Dispatch until iface is announced. wl_output is added | |
| 126 | - | // by the compositor after startup, so it can follow the first roundtrip. The | |
| 127 | - | // instance context ends a wait that never completes. | |
| 128 | - | func (h *headlessInstance) waitGlobal(t *testing.T, d *wlturbo.Display, iface string) { | |
| 129 | - | t.Helper() | |
| 130 | - | for { | |
| 131 | - | if _, ok := d.Registry().FindGlobal(iface); ok { | |
| 132 | - | return | |
| 133 | - | } | |
| 134 | - | if e := d.Dispatch(); e != nil { | |
| 135 | - | t.Fatalf("waiting for %s: %v (ctx %v)\n%s", iface, e, h.ctx.Err(), h.Log()) | |
| 136 | - | } | |
| 137 | - | } | |
| 138 | - | } | |
| 139 | - | ||
| 140 | - | // bindOne binds a global at its negotiated version and fails on any error. | |
| 141 | - | func (h *headlessInstance) bindOne(t *testing.T, d *wlturbo.Display, iface string, supported uint32, p wlturbo.Proxy) uint32 { | |
| 142 | - | t.Helper() | |
| 143 | - | v, e := d.Registry().BindNegotiated(iface, supported, p) | |
| 144 | - | if e != nil { | |
| 145 | - | t.Fatalf("bind %s: %v\n%s", iface, e, h.Log()) | |
| 146 | - | } | |
| 147 | - | return v | |
| 148 | - | } | |
| 149 | - | ||
| 150 | - | func TestHeadlessExtensions(t *testing.T) { | |
| 151 | - | h := startHeadless(t) | |
| 152 | - | ||
| 153 | - | t.Run("bind announced globals", func(t *testing.T) { | |
| 154 | - | d := h.connect(t) | |
| 155 | - | h.waitGlobal(t, d, core.OutputInterface) | |
| 156 | - | for _, b := range headlessBindings() { | |
| 157 | - | g, ok := d.Registry().FindGlobal(b.iface) | |
| 158 | - | if !ok { | |
| 159 | - | if b.optional { | |
| 160 | - | t.Logf("%s absent (optional: hardware, device or build dependent)", b.iface) | |
| 161 | - | } else { | |
| 162 | - | t.Errorf("%s not announced", b.iface) | |
| 163 | - | } | |
| 164 | - | continue | |
| 165 | - | } | |
| 166 | - | p := b.make(d.Context()) | |
| 167 | - | v, e := d.Registry().BindNegotiated(b.iface, b.supported, p) | |
| 168 | - | if e != nil { | |
| 169 | - | t.Errorf("bind %s: %v", b.iface, e) | |
| 170 | - | continue | |
| 171 | - | } | |
| 172 | - | want := min(g.Version, b.supported) | |
| 173 | - | if v != want || v == 0 { | |
| 174 | - | t.Errorf("%s negotiated %d, announced %d supported %d", b.iface, v, g.Version, b.supported) | |
| 175 | - | } | |
| 176 | - | if pv, ok := p.(interface{ Version() uint32 }); ok && pv.Version() != v { | |
| 177 | - | t.Errorf("%s proxy version %d, negotiated %d", b.iface, pv.Version(), v) | |
| 178 | - | } | |
| 179 | - | t.Logf("%s announced=%d supported=%d negotiated=%d", b.iface, g.Version, b.supported, v) | |
| 180 | - | } | |
| 181 | - | // Every bind request is validated by the compositor before this returns. | |
| 182 | - | h.sync(t, d, "bind all") | |
| 183 | - | // Report announced globals that no generated package covers. | |
| 184 | - | known := map[string]bool{"wl_fixes": true} | |
| 185 | - | for _, b := range headlessBindings() { | |
| 186 | - | known[b.iface] = true | |
| 187 | - | } | |
| 188 | - | var extra []string | |
| 189 | - | for _, g := range d.Registry().GetGlobals() { | |
| 190 | - | if !known[g.Interface] { | |
| 191 | - | extra = append(extra, g.Interface) | |
| 192 | - | } | |
| 193 | - | } | |
| 194 | - | sort.Strings(extra) | |
| 195 | - | t.Logf("announced without a client binding: %v", extra) | |
| 196 | - | }) | |
| 197 | - | ||
| 198 | - | t.Run("output description", func(t *testing.T) { | |
| 199 | - | d := h.connect(t) | |
| 200 | - | h.waitGlobal(t, d, core.OutputInterface) | |
| 201 | - | out := core.NewOutput(d.Context()) | |
| 202 | - | h.bindOne(t, d, core.OutputInterface, 4, out) | |
| 203 | - | xm := xdgoutput.NewZxdgOutputManager(d.Context()) | |
| 204 | - | h.bindOne(t, d, xdgoutput.ZxdgOutputManagerInterface, 3, xm) | |
| 205 | - | xo, e := xm.GetXdgOutput(out) | |
| 206 | - | noerr(t, e) | |
| 207 | - | var lw, lh int32 | |
| 208 | - | var name string | |
| 209 | - | var wlDone, xdgDone bool | |
| 210 | - | var modes int | |
| 211 | - | out.OnMode(func(flags uint32, w, h, refresh int32) { modes++ }) | |
| 212 | - | out.OnDone(func() { wlDone = true }) | |
| 213 | - | xo.OnLogicalSize(func(w, h int32) { lw, lh = w, h }) | |
| 214 | - | xo.OnName(func(n string) { name = n }) | |
| 215 | - | xo.OnDone(func() { xdgDone = true }) | |
| 216 | - | // Registered after the bind request but before any event is read. | |
| 217 | - | h.sync(t, d, "xdg_output") | |
| 218 | - | if lw != 640 || lh != 480 || name == "" || modes == 0 || !(wlDone || xdgDone) { | |
| 219 | - | t.Fatalf("logical=%dx%d name=%q modes=%d wl_done=%t xdg_done=%t\n%s", lw, lh, name, modes, wlDone, xdgDone, h.Log()) | |
| 220 | - | } | |
| 221 | - | t.Logf("output %q logical %dx%d", name, lw, lh) | |
| 222 | - | ||
| 223 | - | // wlr-output-management lists the same output as a head with modes. | |
| 224 | - | om := outputmanagement.NewOutputManager(d.Context()) | |
| 225 | - | h.bindOne(t, d, outputmanagement.OutputManagerInterface, 4, om) | |
| 226 | - | // Head events arrive in any order, so each head keeps its own record. | |
| 227 | - | type head struct { | |
| 228 | - | name string | |
| 229 | - | modes int | |
| 230 | - | } | |
| 231 | - | var heads []*head | |
| 232 | - | done := false | |
| 233 | - | om.OnHead(func(hd *outputmanagement.OutputHead) { | |
| 234 | - | rec := &head{} | |
| 235 | - | heads = append(heads, rec) | |
| 236 | - | hd.OnName(func(s string) { rec.name = s }) | |
| 237 | - | hd.OnMode(func(*outputmanagement.OutputMode) { rec.modes++ }) | |
| 238 | - | }) | |
| 239 | - | om.OnDone(func(serial uint32) { done = true }) | |
| 240 | - | h.sync(t, d, "output manager") | |
| 241 | - | found := false | |
| 242 | - | for _, rec := range heads { | |
| 243 | - | found = found || (rec.name == name && rec.modes > 0) | |
| 244 | - | } | |
| 245 | - | if !done || !found { | |
| 246 | - | t.Fatalf("done=%t want head %q with modes; heads:%s\n%s", done, name, func() (s string) { | |
| 247 | - | for _, rec := range heads { | |
| 248 | - | s += fmt.Sprintf(" %q/%d", rec.name, rec.modes) | |
| 249 | - | } | |
| 250 | - | return | |
| 251 | - | }(), h.Log()) | |
| 252 | - | } | |
| 253 | - | noerr(t, xo.Destroy()) | |
| 254 | - | noerr(t, om.Stop()) | |
| 255 | - | h.sync(t, d, "output teardown") | |
| 256 | - | }) | |
| 257 | - | ||
| 258 | - | t.Run("decoration negotiation", func(t *testing.T) { | |
| 259 | - | d := h.connect(t) | |
| 260 | - | compositor := core.NewCompositor(d.Context()) | |
| 261 | - | h.bindOne(t, d, core.CompositorInterface, 6, compositor) | |
| 262 | - | wm := xdgshell.NewXdgWmBase(d.Context()) | |
| 263 | - | h.bindOne(t, d, xdgshell.XdgWmBaseInterface, 6, wm) | |
| 264 | - | dm := xdgdecoration.NewZxdgDecorationManager(d.Context()) | |
| 265 | - | h.bindOne(t, d, xdgdecoration.ZxdgDecorationManagerInterface, 2, dm) | |
| 266 | - | kde := kdeserverdecoration.NewOrgKdeKwinServerDecorationManager(d.Context()) | |
| 267 | - | var kdeDefault uint32 = 99 | |
| 268 | - | kde.OnDefaultMode(func(m uint32) { kdeDefault = m }) | |
| 269 | - | h.bindOne(t, d, kdeserverdecoration.OrgKdeKwinServerDecorationManagerInterface, 1, kde) | |
| 270 | - | ||
| 271 | - | surface, e := compositor.CreateSurface() | |
| 272 | - | noerr(t, e) | |
| 273 | - | xs, e := wm.GetXdgSurface(surface) | |
| 274 | - | noerr(t, e) | |
| 275 | - | top, e := xs.GetToplevel() | |
| 276 | - | noerr(t, e) | |
| 277 | - | deco, e := dm.GetToplevelDecoration(top) | |
| 278 | - | noerr(t, e) | |
| 279 | - | var modes []uint32 | |
| 280 | - | deco.OnConfigure(func(m uint32) { modes = append(modes, m) }) | |
| 281 | - | // A client asking for client-side is answered with the compositor's server-side mode. | |
| 282 | - | noerr(t, deco.SetMode(xdgdecoration.MODE_CLIENT_SIDE)) | |
| 283 | - | xs.OnConfigure(func(serial uint32) { noerr(t, xs.AckConfigure(serial)) }) | |
| 284 | - | // The initial empty commit lets the compositor send xdg_surface.configure. | |
| 285 | - | noerr(t, surface.Commit()) | |
| 286 | - | h.sync(t, d, "decoration") | |
| 287 | - | if len(modes) == 0 || modes[len(modes)-1] != xdgdecoration.MODE_SERVER_SIDE { | |
| 288 | - | t.Fatalf("xdg decoration modes %v\n%s", modes, h.Log()) | |
| 289 | - | } | |
| 290 | - | kdeDeco, e := kde.Create(surface) | |
| 291 | - | noerr(t, e) | |
| 292 | - | var kdeMode uint32 = 99 | |
| 293 | - | kdeDeco.OnMode(func(m uint32) { kdeMode = m }) | |
| 294 | - | h.sync(t, d, "kde decoration") | |
| 295 | - | if kdeDefault != kdeserverdecoration.ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_SERVER || kdeMode != kdeserverdecoration.ORG_KDE_KWIN_SERVER_DECORATION_MODE_SERVER { | |
| 296 | - | t.Fatalf("kde default=%d mode=%d", kdeDefault, kdeMode) | |
| 297 | - | } | |
| 298 | - | noerr(t, kdeDeco.Release()) | |
| 299 | - | noerr(t, deco.Destroy()) | |
| 300 | - | noerr(t, top.Destroy()) | |
| 301 | - | noerr(t, xs.Destroy()) | |
| 302 | - | noerr(t, surface.Destroy()) | |
| 303 | - | h.sync(t, d, "decoration teardown") | |
| 304 | - | }) | |
| 305 | - | ||
| 306 | - | t.Run("workspaces", func(t *testing.T) { | |
| 307 | - | d := h.connect(t) | |
| 308 | - | wsm := workspace.NewExtWorkspaceManager(d.Context()) | |
| 309 | - | groups, workspaces, done, finished := 0, 0, false, false | |
| 310 | - | names := map[string]bool{} | |
| 311 | - | wsm.OnWorkspaceGroup(func(*workspace.ExtWorkspaceGroupHandle) { groups++ }) | |
| 312 | - | wsm.OnWorkspace(func(w *workspace.ExtWorkspaceHandle) { | |
| 313 | - | workspaces++ | |
| 314 | - | w.OnName(func(n string) { names[n] = true }) | |
| 315 | - | }) | |
| 316 | - | wsm.OnDone(func() { done = true }) | |
| 317 | - | wsm.OnFinished(func() { finished = true }) | |
| 318 | - | h.bindOne(t, d, workspace.ExtWorkspaceManagerInterface, 1, wsm) | |
| 319 | - | h.sync(t, d, "workspace snapshot") | |
| 320 | - | if !done || groups == 0 || workspaces == 0 || len(names) == 0 { | |
| 321 | - | t.Fatalf("done=%t groups=%d workspaces=%d names=%v\n%s", done, groups, workspaces, names, h.Log()) | |
| 322 | - | } | |
| 323 | - | t.Logf("workspaces: groups=%d workspaces=%d names=%v", groups, workspaces, names) | |
| 324 | - | // stop is answered by finished; wait for it with the blocking dispatch. | |
| 325 | - | noerr(t, wsm.Stop()) | |
| 326 | - | for !finished { | |
| 327 | - | if e := d.Dispatch(); e != nil { | |
| 328 | - | t.Fatalf("waiting for finished: %v\n%s", e, h.Log()) | |
| 329 | - | } | |
| 330 | - | } | |
| 331 | - | }) | |
| 332 | - | ||
| 333 | - | t.Run("color capabilities", func(t *testing.T) { | |
| 334 | - | d := h.connect(t) | |
| 335 | - | cm := colormanagement.NewWpColorManager(d.Context()) | |
| 336 | - | intents, features, tfs, prims := map[uint32]bool{}, map[uint32]bool{}, map[uint32]bool{}, map[uint32]bool{} | |
| 337 | - | cmDone := false | |
| 338 | - | cm.OnSupportedIntent(func(v uint32) { intents[v] = true }) | |
| 339 | - | cm.OnSupportedFeature(func(v uint32) { features[v] = true }) | |
| 340 | - | cm.OnSupportedTfNamed(func(v uint32) { tfs[v] = true }) | |
| 341 | - | cm.OnSupportedPrimariesNamed(func(v uint32) { prims[v] = true }) | |
| 342 | - | cm.OnDone(func() { cmDone = true }) | |
| 343 | - | version := h.bindOne(t, d, colormanagement.WpColorManagerInterface, 3, cm) | |
| 344 | - | ||
| 345 | - | cr := colorrepresentation.NewWpColorRepresentationManager(d.Context()) | |
| 346 | - | alpha, crDone := map[uint32]bool{}, false | |
| 347 | - | cr.OnSupportedAlphaMode(func(v uint32) { alpha[v] = true }) | |
| 348 | - | cr.OnDone(func() { crDone = true }) | |
| 349 | - | h.bindOne(t, d, colorrepresentation.WpColorRepresentationManagerInterface, 1, cr) | |
| 350 | - | h.sync(t, d, "color capabilities") | |
| 351 | - | ||
| 352 | - | if !cmDone || !intents[colormanagement.RENDER_INTENT_PERCEPTUAL] || !features[colormanagement.FEATURE_PARAMETRIC] || | |
| 353 | - | !tfs[colormanagement.TRANSFER_FUNCTION_SRGB] || !prims[colormanagement.PRIMARIES_SRGB] { | |
| 354 | - | t.Fatalf("color manager v%d done=%t intents=%v features=%v tf=%v primaries=%v\n%s", version, cmDone, intents, features, tfs, prims, h.Log()) | |
| 355 | - | } | |
| 356 | - | if !crDone || len(alpha) == 0 { | |
| 357 | - | t.Fatalf("color representation done=%t alpha=%v", crDone, alpha) | |
| 358 | - | } | |
| 359 | - | t.Logf("color v%d intents=%v features=%v tf=%v primaries=%v alpha=%v", version, intents, features, tfs, prims, alpha) | |
| 360 | - | }) | |
| 361 | - | ||
| 362 | - | t.Run("presentation clock", func(t *testing.T) { | |
| 363 | - | d := h.connect(t) | |
| 364 | - | p := presentation.NewWpPresentation(d.Context()) | |
| 365 | - | clock, got := uint32(0), false | |
| 366 | - | p.OnClockId(func(id uint32) { clock, got = id, true }) | |
| 367 | - | h.bindOne(t, d, presentation.WpPresentationInterface, 2, p) | |
| 368 | - | h.sync(t, d, "presentation clock") | |
| 369 | - | // An empty commit produces no frame, so only the clock is asserted. | |
| 370 | - | if !got || clock != unix.CLOCK_MONOTONIC { | |
| 371 | - | t.Fatalf("clock_id got=%t %d, want CLOCK_MONOTONIC", got, clock) | |
| 372 | - | } | |
| 373 | - | noerr(t, p.Destroy()) | |
| 374 | - | h.sync(t, d, "presentation teardown") | |
| 375 | - | }) | |
| 376 | - | ||
| 377 | - | t.Run("layer surface configure", func(t *testing.T) { | |
| 378 | - | d := h.connect(t) | |
| 379 | - | h.waitGlobal(t, d, core.OutputInterface) | |
| 380 | - | compositor := core.NewCompositor(d.Context()) | |
| 381 | - | h.bindOne(t, d, core.CompositorInterface, 6, compositor) | |
| 382 | - | shell := layershell.NewLayerShell(d.Context()) | |
| 383 | - | h.bindOne(t, d, layershell.LayerShellInterface, 5, shell) | |
| 384 | - | surface, e := compositor.CreateSurface() | |
| 385 | - | noerr(t, e) | |
| 386 | - | ls, e := shell.GetLayerSurface(surface, nil, layershell.LAYER_TOP, "wlturbo-test") | |
| 387 | - | noerr(t, e) | |
| 388 | - | noerr(t, ls.SetAnchor(layershell.ANCHOR_TOP|layershell.ANCHOR_LEFT|layershell.ANCHOR_RIGHT)) | |
| 389 | - | noerr(t, ls.SetSize(0, 30)) | |
| 390 | - | var serial, w, hgt uint32 | |
| 391 | - | configured := false | |
| 392 | - | ls.OnConfigure(func(s, cw, ch uint32) { serial, w, hgt, configured = s, cw, ch, true }) | |
| 393 | - | // The initial empty commit asks the compositor for the first configure. | |
| 394 | - | noerr(t, surface.Commit()) | |
| 395 | - | h.sync(t, d, "layer configure") | |
| 396 | - | if !configured || w != 640 || hgt != 30 { | |
| 397 | - | t.Fatalf("configured=%t %dx%d\n%s", configured, w, hgt, h.Log()) | |
| 398 | - | } | |
| 399 | - | noerr(t, ls.AckConfigure(serial)) | |
| 400 | - | noerr(t, ls.Destroy()) | |
| 401 | - | noerr(t, surface.Destroy()) | |
| 402 | - | h.sync(t, d, "layer teardown") | |
| 403 | - | }) | |
| 404 | - | ||
| 405 | - | t.Run("relative pointer object", func(t *testing.T) { | |
| 406 | - | d := h.connect(t) | |
| 407 | - | seat := core.NewSeat(d.Context()) | |
| 408 | - | var caps uint32 | |
| 409 | - | seat.OnCapabilities(func(c uint32) { caps = c }) | |
| 410 | - | h.bindOne(t, d, core.SeatInterface, 8, seat) | |
| 411 | - | rm := relativepointer.NewRelativePointerManager(d.Context()) | |
| 412 | - | h.bindOne(t, d, relativepointer.RelativePointerManagerInterface, 1, rm) | |
| 413 | - | h.sync(t, d, "seat capabilities") | |
| 414 | - | if caps&core.CAPABILITY_POINTER == 0 { | |
| 415 | - | t.Skipf("seat has no pointer (caps %d); headless input capability dependent", caps) | |
| 416 | - | } | |
| 417 | - | ptr, e := seat.GetPointer() | |
| 418 | - | noerr(t, e) | |
| 419 | - | rp, e := rm.GetRelativePointer(ptr) | |
| 420 | - | noerr(t, e) | |
| 421 | - | // Motion needs pointer focus on a mapped surface, which an empty | |
| 422 | - | // commit cannot provide; creation and teardown must still be valid. | |
| 423 | - | rp.OnRelativeMotion(func(uint32, uint32, wlturbo.Fixed, wlturbo.Fixed, wlturbo.Fixed, wlturbo.Fixed) {}) | |
| 424 | - | h.sync(t, d, "relative pointer") | |
| 425 | - | noerr(t, rp.Destroy()) | |
| 426 | - | noerr(t, ptr.Release()) | |
| 427 | - | noerr(t, rm.Destroy()) | |
| 428 | - | h.sync(t, d, "relative pointer teardown") | |
| 429 | - | }) | |
| 430 | - | } | |
D protocol/headless_test.go +0 -319
| @@ -1,319 +0,0 @@ | |||
| 1 | - | //go:build linux | |
| 2 | - | ||
| 3 | - | package protocol_test | |
| 4 | - | ||
| 5 | - | import ( | |
| 6 | - | "context" | |
| 7 | - | "errors" | |
| 8 | - | "fmt" | |
| 9 | - | "net" | |
| 10 | - | "os" | |
| 11 | - | "os/exec" | |
| 12 | - | "path/filepath" | |
| 13 | - | "strings" | |
| 14 | - | "syscall" | |
| 15 | - | "testing" | |
| 16 | - | "time" | |
| 17 | - | ||
| 18 | - | "github.com/bnema/wlturbo" | |
| 19 | - | "github.com/bnema/wlturbo/protocol/core" | |
| 20 | - | "github.com/bnema/wlturbo/protocol/drmsyncobj" | |
| 21 | - | "github.com/bnema/wlturbo/protocol/fractionalscale" | |
| 22 | - | "github.com/bnema/wlturbo/protocol/linuxdmabuf" | |
| 23 | - | "github.com/bnema/wlturbo/protocol/viewporter" | |
| 24 | - | "github.com/bnema/wlturbo/protocol/xdgshell" | |
| 25 | - | "golang.org/x/sys/unix" | |
| 26 | - | ) | |
| 27 | - | ||
| 28 | - | func TestHeadlessNeferWL(t *testing.T) { | |
| 29 | - | h := startHeadless(t) | |
| 30 | - | d := h.connect(t) | |
| 31 | - | bind := h.binder(t, d) | |
| 32 | - | ctx := h.ctx | |
| 33 | - | compositor := core.NewCompositor(d.Context()) | |
| 34 | - | bind(core.CompositorInterface, 6, compositor) | |
| 35 | - | wm := xdgshell.NewXdgWmBase(d.Context()) | |
| 36 | - | bind(xdgshell.XdgWmBaseInterface, 7, wm) | |
| 37 | - | dm := linuxdmabuf.NewLinuxDmabuf(d.Context()) | |
| 38 | - | if bind(linuxdmabuf.LinuxDmabufInterface, 4, dm) < 4 { | |
| 39 | - | t.Fatal("dmabuf feedback requires v4") | |
| 40 | - | } | |
| 41 | - | syncManager := drmsyncobj.NewWpLinuxDrmSyncobjManager(d.Context()) | |
| 42 | - | bind(drmsyncobj.WpLinuxDrmSyncobjManagerInterface, 1, syncManager) | |
| 43 | - | dataManager := core.NewDataDeviceManager(d.Context()) | |
| 44 | - | dataVersion := bind(core.DataDeviceManagerInterface, 4, dataManager) | |
| 45 | - | vp := viewporter.NewWpViewporter(d.Context()) | |
| 46 | - | bind(viewporter.WpViewporterInterface, 1, vp) | |
| 47 | - | if g, ok := d.Registry().FindGlobal(fractionalscale.WpFractionalScaleManagerInterface); ok { | |
| 48 | - | fs := fractionalscale.NewWpFractionalScaleManager(d.Context()) | |
| 49 | - | v := bind(g.Interface, 1, fs) | |
| 50 | - | if v != 1 { | |
| 51 | - | t.Fatalf("fractional scale version %d", v) | |
| 52 | - | } | |
| 53 | - | noerr(t, fs.Destroy()) | |
| 54 | - | } else { | |
| 55 | - | t.Log("fractional scale absent") | |
| 56 | - | } | |
| 57 | - | surface, e := compositor.CreateSurface() | |
| 58 | - | noerr(t, e) | |
| 59 | - | xs, e := wm.GetXdgSurface(surface) | |
| 60 | - | noerr(t, e) | |
| 61 | - | top, e := xs.GetToplevel() | |
| 62 | - | noerr(t, e) | |
| 63 | - | feedback, e := dm.GetSurfaceFeedback(surface) | |
| 64 | - | noerr(t, e) | |
| 65 | - | ss, e := syncManager.GetSurface(surface) | |
| 66 | - | noerr(t, e) | |
| 67 | - | configured, done, mainDevice, tableOK := false, false, false, false | |
| 68 | - | top.OnConfigure(func(w, h int32, states []byte) { t.Logf("xdg_toplevel.configure %dx%d", w, h) }) | |
| 69 | - | xs.OnConfigure(func(serial uint32) { | |
| 70 | - | noerr(t, xs.AckConfigure(serial)) | |
| 71 | - | configured = true | |
| 72 | - | t.Logf("xdg_surface.configure ack=%d", serial) | |
| 73 | - | }) | |
| 74 | - | feedback.OnMainDevice(func(b []byte) { mainDevice = len(b) == 8; t.Logf("main_device=%x", b) }) | |
| 75 | - | feedback.OnFormatTable(func(fd *wlturbo.OwnedFD, size uint32) { | |
| 76 | - | entries, e := linuxdmabuf.ReadFormatTable(fd, size) | |
| 77 | - | if e != nil { | |
| 78 | - | t.Errorf("format table: %v", e) | |
| 79 | - | } else { | |
| 80 | - | tableOK = len(entries) > 0 | |
| 81 | - | t.Logf("format-table entries=%d", len(entries)) | |
| 82 | - | } | |
| 83 | - | }) | |
| 84 | - | feedback.OnDone(func() { done = true }) | |
| 85 | - | // Initial empty commit requests xdg configure; no buffer or window is shown. | |
| 86 | - | noerr(t, surface.Commit()) | |
| 87 | - | for (!configured || !done) && ctx.Err() == nil { | |
| 88 | - | if e := d.Dispatch(); e != nil { | |
| 89 | - | t.Fatalf("dispatch: %v\n%s", e, h.Log()) | |
| 90 | - | } | |
| 91 | - | } | |
| 92 | - | if !configured || !done || !mainDevice || !tableOK { | |
| 93 | - | t.Fatalf("configure=%t feedback=%t main_device=%t table=%t: %v\n%s", configured, done, mainDevice, tableOK, ctx.Err(), h.Log()) | |
| 94 | - | } | |
| 95 | - | noerr(t, surface.Commit()) | |
| 96 | - | // Drop all child objects while their parents are still alive. | |
| 97 | - | noerr(t, ss.Destroy()) | |
| 98 | - | noerr(t, feedback.Destroy()) | |
| 99 | - | noerr(t, top.Destroy()) | |
| 100 | - | noerr(t, xs.Destroy()) | |
| 101 | - | noerr(t, surface.Destroy()) | |
| 102 | - | noerr(t, vp.Destroy()) | |
| 103 | - | if dataVersion >= 4 { | |
| 104 | - | noerr(t, dataManager.Release()) | |
| 105 | - | } | |
| 106 | - | noerr(t, syncManager.Destroy()) | |
| 107 | - | noerr(t, dm.Destroy()) | |
| 108 | - | noerr(t, wm.Destroy()) | |
| 109 | - | noerr(t, d.Close()) | |
| 110 | - | } | |
| 111 | - | ||
| 112 | - | // headlessInstance is one isolated NeferWL process with its own runtime, | |
| 113 | - | // config, data and state directories. Cleanup kills the whole process group | |
| 114 | - | // and reaps it. ctx expires at the test deadline or when the process exits, so | |
| 115 | - | // a blocking Dispatch on a connection made by connect always returns. | |
| 116 | - | type headlessInstance struct { | |
| 117 | - | ctx context.Context | |
| 118 | - | socket string | |
| 119 | - | logf *os.File | |
| 120 | - | done chan struct{} // closed after the process is reaped | |
| 121 | - | waitErr error // valid once done is closed | |
| 122 | - | } | |
| 123 | - | ||
| 124 | - | // startHeadless launches WLTURBO_HEADLESS or skips the test when it is unset. | |
| 125 | - | // It returns once the compositor socket exists, or fails with the process log | |
| 126 | - | // if the process exits early or the 18s test deadline expires. | |
| 127 | - | func startHeadless(t *testing.T) *headlessInstance { | |
| 128 | - | t.Helper() | |
| 129 | - | binary := os.Getenv("WLTURBO_HEADLESS") | |
| 130 | - | if binary == "" { | |
| 131 | - | t.Skip("set WLTURBO_HEADLESS to a NeferWL binary") | |
| 132 | - | } | |
| 133 | - | binary, e := filepath.Abs(binary) | |
| 134 | - | noerr(t, e) | |
| 135 | - | root := t.TempDir() | |
| 136 | - | dirs := map[string]string{} | |
| 137 | - | for _, name := range []string{"run", "config", "data", "state"} { | |
| 138 | - | dirs[name] = filepath.Join(root, name) | |
| 139 | - | noerr(t, os.Mkdir(dirs[name], 0700)) | |
| 140 | - | } | |
| 141 | - | ctx, cancel := context.WithTimeout(context.Background(), 18*time.Second) | |
| 142 | - | t.Cleanup(cancel) | |
| 143 | - | logf, e := os.Create(filepath.Join(root, "neferwl.log")) | |
| 144 | - | noerr(t, e) | |
| 145 | - | t.Cleanup(func() { _ = logf.Close() }) | |
| 146 | - | h := &headlessInstance{logf: logf, done: make(chan struct{})} | |
| 147 | - | // Watch the runtime directory before starting so the socket creation cannot be missed. | |
| 148 | - | // Non-blocking makes os.File use the poller, so Close unblocks the reader goroutine. | |
| 149 | - | ifd, e := unix.InotifyInit1(unix.IN_NONBLOCK | unix.IN_CLOEXEC) | |
| 150 | - | noerr(t, e) | |
| 151 | - | watch := os.NewFile(uintptr(ifd), "inotify") | |
| 152 | - | t.Cleanup(func() { _ = watch.Close() }) | |
| 153 | - | _, e = unix.InotifyAddWatch(ifd, dirs["run"], unix.IN_CREATE|unix.IN_ATTRIB) | |
| 154 | - | noerr(t, e) | |
| 155 | - | cmd := exec.Command(binary, "--backend=headless", "--no-terminal", "--no-xwayland", "--size", "640x480", "--timeout", "20s") | |
| 156 | - | cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} | |
| 157 | - | cmd.Env = append(cleanDisplayEnv(os.Environ()), | |
| 158 | - | "XDG_RUNTIME_DIR="+dirs["run"], "XDG_CONFIG_HOME="+dirs["config"], | |
| 159 | - | "XDG_DATA_HOME="+dirs["data"], "XDG_STATE_HOME="+dirs["state"]) | |
| 160 | - | cmd.Stdout = logf | |
| 161 | - | cmd.Stderr = logf | |
| 162 | - | noerr(t, cmd.Start()) | |
| 163 | - | // A failed startup must still terminate the process group and reap it. | |
| 164 | - | t.Cleanup(func() { | |
| 165 | - | _ = syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL) | |
| 166 | - | <-h.done | |
| 167 | - | }) | |
| 168 | - | // Process exit cancels ctx, which also unblocks any Dispatch (see connect). | |
| 169 | - | ctx, stopCtx := context.WithCancel(ctx) | |
| 170 | - | t.Cleanup(stopCtx) | |
| 171 | - | h.ctx = ctx | |
| 172 | - | go func() { | |
| 173 | - | h.waitErr = cmd.Wait() | |
| 174 | - | close(h.done) | |
| 175 | - | stopCtx() | |
| 176 | - | }() | |
| 177 | - | events := make(chan struct{}, 1) | |
| 178 | - | go func() { | |
| 179 | - | buf := make([]byte, 4096) | |
| 180 | - | for { | |
| 181 | - | if _, e := watch.Read(buf); e != nil { | |
| 182 | - | return | |
| 183 | - | } | |
| 184 | - | select { | |
| 185 | - | case events <- struct{}{}: | |
| 186 | - | default: | |
| 187 | - | } | |
| 188 | - | } | |
| 189 | - | }() | |
| 190 | - | find := func() string { | |
| 191 | - | paths, _ := filepath.Glob(filepath.Join(dirs["run"], "wayland-*")) | |
| 192 | - | for _, path := range paths { | |
| 193 | - | if info, e := os.Stat(path); e == nil && info.Mode()&os.ModeSocket != 0 { | |
| 194 | - | return path | |
| 195 | - | } | |
| 196 | - | } | |
| 197 | - | return "" | |
| 198 | - | } | |
| 199 | - | for h.socket = find(); h.socket == ""; h.socket = find() { | |
| 200 | - | select { | |
| 201 | - | case <-events: | |
| 202 | - | case <-h.done: | |
| 203 | - | t.Fatalf("neferwl exited before serving: %v\n%s", h.waitErr, h.Log()) | |
| 204 | - | case <-ctx.Done(): | |
| 205 | - | t.Fatalf("headless socket timeout: %v\n%s", ctx.Err(), h.Log()) | |
| 206 | - | } | |
| 207 | - | } | |
| 208 | - | return h | |
| 209 | - | } | |
| 210 | - | ||
| 211 | - | // Log returns the tail of the compositor output. | |
| 212 | - | func (h *headlessInstance) Log() string { return headlessLog(h.logf) } | |
| 213 | - | ||
| 214 | - | // connect dials the compositor and completes the initial registry roundtrip. | |
| 215 | - | // The instance context closes the connection when the test deadline expires or | |
| 216 | - | // the compositor exits, so a blocking Dispatch returns instead of hanging. | |
| 217 | - | func (h *headlessInstance) connect(t *testing.T) *wlturbo.Display { | |
| 218 | - | t.Helper() | |
| 219 | - | var conn net.Conn | |
| 220 | - | for { | |
| 221 | - | var e error | |
| 222 | - | conn, e = (&net.Dialer{Timeout: time.Second}).DialContext(h.ctx, "unix", h.socket) | |
| 223 | - | if e == nil { | |
| 224 | - | break | |
| 225 | - | } | |
| 226 | - | // The socket file appears at bind(); listen() follows immediately, so | |
| 227 | - | // a refused dial is transient unless the compositor is gone. | |
| 228 | - | if !errors.Is(e, syscall.ECONNREFUSED) { | |
| 229 | - | t.Fatalf("dial: %v\n%s", e, h.Log()) | |
| 230 | - | } | |
| 231 | - | select { | |
| 232 | - | case <-h.done: | |
| 233 | - | t.Fatalf("neferwl exited before accepting: %v\n%s", h.waitErr, h.Log()) | |
| 234 | - | case <-h.ctx.Done(): | |
| 235 | - | t.Fatalf("dial timeout: %v\n%s", h.ctx.Err(), h.Log()) | |
| 236 | - | case <-time.After(5 * time.Millisecond): | |
| 237 | - | } | |
| 238 | - | } | |
| 239 | - | d, e := wlturbo.ConnectFromConn(conn) | |
| 240 | - | if e != nil { | |
| 241 | - | _ = conn.Close() | |
| 242 | - | t.Fatal(e) | |
| 243 | - | } | |
| 244 | - | t.Cleanup(func() { _ = d.Close() }) | |
| 245 | - | stop := context.AfterFunc(h.ctx, func() { _ = d.Close() }) | |
| 246 | - | t.Cleanup(func() { stop() }) | |
| 247 | - | h.sync(t, d, "registry roundtrip") | |
| 248 | - | return d | |
| 249 | - | } | |
| 250 | - | ||
| 251 | - | // binder returns a bind function that fails the test with the compositor log. | |
| 252 | - | func (h *headlessInstance) binder(t *testing.T, d *wlturbo.Display) func(string, uint32, wlturbo.Proxy) uint32 { | |
| 253 | - | return func(iface string, supported uint32, proxy wlturbo.Proxy) uint32 { | |
| 254 | - | t.Helper() | |
| 255 | - | v, err := d.Registry().BindNegotiated(iface, supported, proxy) | |
| 256 | - | if err != nil { | |
| 257 | - | t.Fatalf("bind %s: %v\n%s", iface, err, h.Log()) | |
| 258 | - | } | |
| 259 | - | t.Logf("%s negotiated=%d", iface, v) | |
| 260 | - | return v | |
| 261 | - | } | |
| 262 | - | } | |
| 263 | - | ||
| 264 | - | // sync completes a roundtrip, reporting compositor protocol errors with its log. | |
| 265 | - | func (h *headlessInstance) sync(t *testing.T, d *wlturbo.Display, what string) { | |
| 266 | - | t.Helper() | |
| 267 | - | if e := d.Roundtrip(); e != nil { | |
| 268 | - | t.Fatalf("%s: %v (ctx %v)\n%s", what, e, h.ctx.Err(), h.Log()) | |
| 269 | - | } | |
| 270 | - | } | |
| 271 | - | ||
| 272 | - | // headlessEnvDrop lists the environment prefixes the child must not inherit: | |
| 273 | - | // anything that could attach it to, or make it act on, the caller's session, | |
| 274 | - | // plus NeferWL's own configuration. The test client's own environment is not | |
| 275 | - | // changed; only the child process is isolated. | |
| 276 | - | var headlessEnvDrop = []string{"DISPLAY=", "WAYLAND_DISPLAY=", "WAYLAND_SOCKET=", "NOTIFY_SOCKET=", "DBUS_SESSION_BUS_ADDRESS=", | |
| 277 | - | "XDG_RUNTIME_DIR=", "XDG_CONFIG_HOME=", "XDG_DATA_HOME=", "XDG_STATE_HOME=", "XDG_SESSION_", "XDG_VTNR=", "XDG_SEAT=", | |
| 278 | - | "XDG_CURRENT_DESKTOP=", "NIRI_SOCKET=", "SWAYSOCK=", "HYPRLAND_INSTANCE_SIGNATURE=", "NEFERWL_"} | |
| 279 | - | ||
| 280 | - | func cleanDisplayEnv(in []string) []string { | |
| 281 | - | out := make([]string, 0, len(in)) | |
| 282 | - | next: | |
| 283 | - | for _, e := range in { | |
| 284 | - | for _, p := range headlessEnvDrop { | |
| 285 | - | if strings.HasPrefix(e, p) { | |
| 286 | - | continue next | |
| 287 | - | } | |
| 288 | - | } | |
| 289 | - | out = append(out, e) | |
| 290 | - | } | |
| 291 | - | return out | |
| 292 | - | } | |
| 293 | - | ||
| 294 | - | func TestCleanDisplayEnv(t *testing.T) { | |
| 295 | - | keep := []string{"PATH=/bin", "HOME=/h", "DISPLAYS=x", "XDG_DATA_DIRS=/d", "MY_NEFERWL_X=1"} | |
| 296 | - | in := append([]string(nil), keep...) | |
| 297 | - | for _, p := range headlessEnvDrop { | |
| 298 | - | e := p + "placeholder" | |
| 299 | - | if !strings.HasSuffix(p, "=") { | |
| 300 | - | e += "=1" // a prefix such as XDG_SESSION_ names a family of variables | |
| 301 | - | } | |
| 302 | - | in = append(in, e) | |
| 303 | - | } | |
| 304 | - | got := cleanDisplayEnv(in) | |
| 305 | - | if strings.Join(got, "\n") != strings.Join(keep, "\n") { | |
| 306 | - | t.Fatalf("cleanDisplayEnv = %q, want %q", got, keep) | |
| 307 | - | } | |
| 308 | - | } | |
| 309 | - | ||
| 310 | - | func headlessLog(f *os.File) string { | |
| 311 | - | b, e := os.ReadFile(f.Name()) | |
| 312 | - | if e != nil { | |
| 313 | - | return fmt.Sprint(e) | |
| 314 | - | } | |
| 315 | - | if len(b) > 8192 { | |
| 316 | - | b = b[len(b)-8192:] | |
| 317 | - | } | |
| 318 | - | return string(b) | |
| 319 | - | } | |
D protocol/idleinhibit/generate.go +0 -3
| @@ -1,3 +0,0 @@ | |||
| 1 | - | package idleinhibit | |
| 2 | - | ||
| 3 | - | //go:generate go run ../../cmd/wlturbo-scanner -p idleinhibit -o idle-inhibit-unstable-v1_generated.go -import wl_surface=github.com/bnema/wlturbo/protocol/core idle-inhibit-unstable-v1.xml | |
D protocol/idleinhibit/idle-inhibit-unstable-v1.xml +0 -83
| @@ -1,83 +0,0 @@ | |||
| 1 | - | <?xml version="1.0" encoding="UTF-8"?> | |
| 2 | - | <protocol name="idle_inhibit_unstable_v1"> | |
| 3 | - | ||
| 4 | - | <copyright> | |
| 5 | - | Copyright © 2015 Samsung Electronics Co., Ltd | |
| 6 | - | ||
| 7 | - | Permission is hereby granted, free of charge, to any person obtaining a | |
| 8 | - | copy of this software and associated documentation files (the "Software"), | |
| 9 | - | to deal in the Software without restriction, including without limitation | |
| 10 | - | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 11 | - | and/or sell copies of the Software, and to permit persons to whom the | |
| 12 | - | Software is furnished to do so, subject to the following conditions: | |
| 13 | - | ||
| 14 | - | The above copyright notice and this permission notice (including the next | |
| 15 | - | paragraph) shall be included in all copies or substantial portions of the | |
| 16 | - | Software. | |
| 17 | - | ||
| 18 | - | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 19 | - | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 20 | - | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 21 | - | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 22 | - | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 23 | - | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
| 24 | - | DEALINGS IN THE SOFTWARE. | |
| 25 | - | </copyright> | |
| 26 | - | ||
| 27 | - | <interface name="zwp_idle_inhibit_manager_v1" version="1"> | |
| 28 | - | <description summary="control behavior when display idles"> | |
| 29 | - | This interface permits inhibiting the idle behavior such as screen | |
| 30 | - | blanking, locking, and screensaving. The client binds the idle manager | |
| 31 | - | globally, then creates idle-inhibitor objects for each surface. | |
| 32 | - | ||
| 33 | - | Warning! The protocol described in this file is experimental and | |
| 34 | - | backward incompatible changes may be made. Backward compatible changes | |
| 35 | - | may be added together with the corresponding interface version bump. | |
| 36 | - | Backward incompatible changes are done by bumping the version number in | |
| 37 | - | the protocol and interface names and resetting the interface version. | |
| 38 | - | Once the protocol is to be declared stable, the 'z' prefix and the | |
| 39 | - | version number in the protocol and interface names are removed and the | |
| 40 | - | interface version number is reset. | |
| 41 | - | </description> | |
| 42 | - | ||
| 43 | - | <request name="destroy" type="destructor"> | |
| 44 | - | <description summary="destroy the idle inhibitor object"> | |
| 45 | - | Destroy the inhibit manager. | |
| 46 | - | </description> | |
| 47 | - | </request> | |
| 48 | - | ||
| 49 | - | <request name="create_inhibitor"> | |
| 50 | - | <description summary="create a new inhibitor object"> | |
| 51 | - | Create a new inhibitor object associated with the given surface. | |
| 52 | - | </description> | |
| 53 | - | <arg name="id" type="new_id" interface="zwp_idle_inhibitor_v1"/> | |
| 54 | - | <arg name="surface" type="object" interface="wl_surface" | |
| 55 | - | summary="the surface that inhibits the idle behavior"/> | |
| 56 | - | </request> | |
| 57 | - | ||
| 58 | - | </interface> | |
| 59 | - | ||
| 60 | - | <interface name="zwp_idle_inhibitor_v1" version="1"> | |
| 61 | - | <description summary="context object for inhibiting idle behavior"> | |
| 62 | - | An idle inhibitor prevents the output that the associated surface is | |
| 63 | - | visible on from being set to a state where it is not visually usable due | |
| 64 | - | to lack of user interaction (e.g. blanked, dimmed, locked, set to power | |
| 65 | - | save, etc.) Any screensaver processes are also blocked from displaying. | |
| 66 | - | ||
| 67 | - | If the surface is destroyed, unmapped, becomes occluded, loses | |
| 68 | - | visibility, or otherwise becomes not visually relevant for the user, the | |
| 69 | - | idle inhibitor will not be honored by the compositor; if the surface | |
| 70 | - | subsequently regains visibility the inhibitor takes effect once again. | |
| 71 | - | Likewise, the inhibitor isn't honored if the system was already idled at | |
| 72 | - | the time the inhibitor was established, although if the system later | |
| 73 | - | de-idles and re-idles the inhibitor will take effect. | |
| 74 | - | </description> | |
| 75 | - | ||
| 76 | - | <request name="destroy" type="destructor"> | |
| 77 | - | <description summary="destroy the idle inhibitor object"> | |
| 78 | - | Remove the inhibitor effect from the associated wl_surface. | |
| 79 | - | </description> | |
| 80 | - | </request> | |
| 81 | - | ||
| 82 | - | </interface> | |
| 83 | - | </protocol> | |
D protocol/idleinhibit/idle-inhibit-unstable-v1_generated.go +0 -124
| @@ -1,124 +0,0 @@ | |||
| 1 | - | // Code generated by wlturbo-scanner. DO NOT EDIT. | |
| 2 | - | // Protocol: idle_inhibit_unstable_v1 | |
| 3 | - | // Source: idle-inhibit-unstable-v1.xml | |
| 4 | - | ||
| 5 | - | // Upstream protocol copyright and license: | |
| 6 | - | // Copyright © 2015 Samsung Electronics Co., Ltd | |
| 7 | - | // | |
| 8 | - | // Permission is hereby granted, free of charge, to any person obtaining a | |
| 9 | - | // copy of this software and associated documentation files (the "Software"), | |
| 10 | - | // to deal in the Software without restriction, including without limitation | |
| 11 | - | // the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 12 | - | // and/or sell copies of the Software, and to permit persons to whom the | |
| 13 | - | // Software is furnished to do so, subject to the following conditions: | |
| 14 | - | // | |
| 15 | - | // The above copyright notice and this permission notice (including the next | |
| 16 | - | // paragraph) shall be included in all copies or substantial portions of the | |
| 17 | - | // Software. | |
| 18 | - | // | |
| 19 | - | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 20 | - | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 21 | - | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 22 | - | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 23 | - | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 24 | - | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
| 25 | - | // DEALINGS IN THE SOFTWARE. | |
| 26 | - | ||
| 27 | - | package idleinhibit | |
| 28 | - | ||
| 29 | - | import ( | |
| 30 | - | cross_wl_surface "github.com/bnema/wlturbo/protocol/core" | |
| 31 | - | "github.com/bnema/wlturbo/wl" | |
| 32 | - | ) | |
| 33 | - | ||
| 34 | - | // IdleInhibitManagerInterface is the protocol interface name. | |
| 35 | - | const IdleInhibitManagerInterface = "zwp_idle_inhibit_manager_v1" | |
| 36 | - | ||
| 37 | - | // IdleInhibitManager is the generated binding for zwp_idle_inhibit_manager_v1 version 1. | |
| 38 | - | type IdleInhibitManager struct { | |
| 39 | - | wl.BaseProxy | |
| 40 | - | } | |
| 41 | - | ||
| 42 | - | // NewIdleInhibitManager returns an unbound IdleInhibitManager. | |
| 43 | - | func NewIdleInhibitManager(ctx *wl.Context) *IdleInhibitManager { | |
| 44 | - | obj := &IdleInhibitManager{} | |
| 45 | - | obj.SetContext(ctx) | |
| 46 | - | ctx.Register(obj) | |
| 47 | - | return obj | |
| 48 | - | } | |
| 49 | - | ||
| 50 | - | // Destroy the inhibit manager. | |
| 51 | - | func (o *IdleInhibitManager) Destroy() error { | |
| 52 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "zwp_idle_inhibit_manager_v1.destroy", Destructor: true}); err != nil { | |
| 53 | - | return err | |
| 54 | - | } | |
| 55 | - | return nil | |
| 56 | - | } | |
| 57 | - | ||
| 58 | - | // Create a new inhibitor object associated with the given surface. | |
| 59 | - | func (o *IdleInhibitManager) CreateInhibitor(surface *cross_wl_surface.Surface) (*IdleInhibitor, error) { | |
| 60 | - | var arg1 wl.Object | |
| 61 | - | if surface != nil { | |
| 62 | - | arg1 = surface | |
| 63 | - | } | |
| 64 | - | child := &IdleInhibitor{} | |
| 65 | - | child.SetContext(o.Context()) | |
| 66 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "zwp_idle_inhibit_manager_v1.create_inhibitor", Child: child}, wl.ArgObject(child), wl.ArgObject(arg1)); err != nil { | |
| 67 | - | return nil, err | |
| 68 | - | } | |
| 69 | - | return child, nil | |
| 70 | - | } | |
| 71 | - | ||
| 72 | - | // EventSignature returns the declared event argument types in wire order. | |
| 73 | - | func (o *IdleInhibitManager) EventSignature(opcode uint16) (string, bool) { | |
| 74 | - | switch opcode { | |
| 75 | - | default: | |
| 76 | - | return "", false | |
| 77 | - | } | |
| 78 | - | } | |
| 79 | - | ||
| 80 | - | // Dispatch decodes one event on zwp_idle_inhibit_manager_v1 and calls the registered handlers. | |
| 81 | - | func (o *IdleInhibitManager) Dispatch(event *wl.Event) { | |
| 82 | - | switch event.Opcode { | |
| 83 | - | default: | |
| 84 | - | } | |
| 85 | - | } | |
| 86 | - | ||
| 87 | - | // IdleInhibitorInterface is the protocol interface name. | |
| 88 | - | const IdleInhibitorInterface = "zwp_idle_inhibitor_v1" | |
| 89 | - | ||
| 90 | - | // IdleInhibitor is the generated binding for zwp_idle_inhibitor_v1 version 1. | |
| 91 | - | type IdleInhibitor struct { | |
| 92 | - | wl.BaseProxy | |
| 93 | - | } | |
| 94 | - | ||
| 95 | - | // NewIdleInhibitor returns an unbound IdleInhibitor. | |
| 96 | - | func NewIdleInhibitor(ctx *wl.Context) *IdleInhibitor { | |
| 97 | - | obj := &IdleInhibitor{} | |
| 98 | - | obj.SetContext(ctx) | |
| 99 | - | ctx.Register(obj) | |
| 100 | - | return obj | |
| 101 | - | } | |
| 102 | - | ||
| 103 | - | // Remove the inhibitor effect from the associated wl_surface. | |
| 104 | - | func (o *IdleInhibitor) Destroy() error { | |
| 105 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "zwp_idle_inhibitor_v1.destroy", Destructor: true}); err != nil { | |
| 106 | - | return err | |
| 107 | - | } | |
| 108 | - | return nil | |
| 109 | - | } | |
| 110 | - | ||
| 111 | - | // EventSignature returns the declared event argument types in wire order. | |
| 112 | - | func (o *IdleInhibitor) EventSignature(opcode uint16) (string, bool) { | |
| 113 | - | switch opcode { | |
| 114 | - | default: | |
| 115 | - | return "", false | |
| 116 | - | } | |
| 117 | - | } | |
| 118 | - | ||
| 119 | - | // Dispatch decodes one event on zwp_idle_inhibitor_v1 and calls the registered handlers. | |
| 120 | - | func (o *IdleInhibitor) Dispatch(event *wl.Event) { | |
| 121 | - | switch event.Opcode { | |
| 122 | - | default: | |
| 123 | - | } | |
| 124 | - | } | |
D protocol/idlenotify/ext-idle-notify-v1.xml +0 -131
| @@ -1,131 +0,0 @@ | |||
| 1 | - | <?xml version="1.0" encoding="UTF-8"?> | |
| 2 | - | <protocol name="ext_idle_notify_v1"> | |
| 3 | - | <copyright> | |
| 4 | - | Copyright © 2015 Martin Gräßlin | |
| 5 | - | Copyright © 2022 Simon Ser | |
| 6 | - | ||
| 7 | - | Permission is hereby granted, free of charge, to any person obtaining a | |
| 8 | - | copy of this software and associated documentation files (the "Software"), | |
| 9 | - | to deal in the Software without restriction, including without limitation | |
| 10 | - | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 11 | - | and/or sell copies of the Software, and to permit persons to whom the | |
| 12 | - | Software is furnished to do so, subject to the following conditions: | |
| 13 | - | ||
| 14 | - | The above copyright notice and this permission notice (including the next | |
| 15 | - | paragraph) shall be included in all copies or substantial portions of the | |
| 16 | - | Software. | |
| 17 | - | ||
| 18 | - | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 19 | - | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 20 | - | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 21 | - | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 22 | - | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 23 | - | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
| 24 | - | DEALINGS IN THE SOFTWARE. | |
| 25 | - | </copyright> | |
| 26 | - | ||
| 27 | - | <interface name="ext_idle_notifier_v1" version="2"> | |
| 28 | - | <description summary="idle notification manager"> | |
| 29 | - | This interface allows clients to monitor user idle status. | |
| 30 | - | ||
| 31 | - | After binding to this global, clients can create ext_idle_notification_v1 | |
| 32 | - | objects to get notified when the user is idle for a given amount of time. | |
| 33 | - | </description> | |
| 34 | - | ||
| 35 | - | <request name="destroy" type="destructor"> | |
| 36 | - | <description summary="destroy the manager"> | |
| 37 | - | Destroy the manager object. All objects created via this interface | |
| 38 | - | remain valid. | |
| 39 | - | </description> | |
| 40 | - | </request> | |
| 41 | - | ||
| 42 | - | <request name="get_idle_notification"> | |
| 43 | - | <description summary="create a notification object"> | |
| 44 | - | Create a new idle notification object. | |
| 45 | - | ||
| 46 | - | The notification object has a minimum timeout duration and is tied to a | |
| 47 | - | seat. The client will be notified if the seat is inactive for at least | |
| 48 | - | the provided timeout. See ext_idle_notification_v1 for more details. | |
| 49 | - | ||
| 50 | - | A zero timeout is valid and means the client wants to be notified as | |
| 51 | - | soon as possible when the seat is inactive. | |
| 52 | - | </description> | |
| 53 | - | <arg name="id" type="new_id" interface="ext_idle_notification_v1"/> | |
| 54 | - | <arg name="timeout" type="uint" summary="minimum idle timeout in msec"/> | |
| 55 | - | <arg name="seat" type="object" interface="wl_seat"/> | |
| 56 | - | </request> | |
| 57 | - | ||
| 58 | - | <!-- Version 2 additions --> | |
| 59 | - | ||
| 60 | - | <request name="get_input_idle_notification" since="2"> | |
| 61 | - | <description summary="create a notification object"> | |
| 62 | - | Create a new idle notification object to track input from the | |
| 63 | - | user, such as keyboard and mouse movement. Because this object is | |
| 64 | - | meant to track user input alone, it ignores idle inhibitors. | |
| 65 | - | ||
| 66 | - | The notification object has a minimum timeout duration and is tied to a | |
| 67 | - | seat. The client will be notified if the seat is inactive for at least | |
| 68 | - | the provided timeout. See ext_idle_notification_v1 for more details. | |
| 69 | - | ||
| 70 | - | A zero timeout is valid and means the client wants to be notified as | |
| 71 | - | soon as possible when the seat is inactive. | |
| 72 | - | </description> | |
| 73 | - | <arg name="id" type="new_id" interface="ext_idle_notification_v1"/> | |
| 74 | - | <arg name="timeout" type="uint" summary="minimum idle timeout in msec"/> | |
| 75 | - | <arg name="seat" type="object" interface="wl_seat"/> | |
| 76 | - | </request> | |
| 77 | - | ||
| 78 | - | </interface> | |
| 79 | - | ||
| 80 | - | <interface name="ext_idle_notification_v1" version="2"> | |
| 81 | - | <description summary="idle notification"> | |
| 82 | - | This interface is used by the compositor to send idle notification events | |
| 83 | - | to clients. | |
| 84 | - | ||
| 85 | - | Initially the notification object is not idle. The notification object | |
| 86 | - | becomes idle when no user activity has happened for at least the timeout | |
| 87 | - | duration, starting from the creation of the notification object. User | |
| 88 | - | activity may include input events or a presence sensor, but is | |
| 89 | - | compositor-specific. | |
| 90 | - | ||
| 91 | - | How this notification responds to idle inhibitors depends on how | |
| 92 | - | it was constructed. If constructed from the | |
| 93 | - | get_idle_notification request, then if an idle inhibitor is | |
| 94 | - | active (e.g. another client has created a zwp_idle_inhibitor_v1 | |
| 95 | - | on a visible surface), the compositor must not make the | |
| 96 | - | notification object idle. However, if constructed from the | |
| 97 | - | get_input_idle_notification request, then idle inhibitors are | |
| 98 | - | ignored, and only input from the user, e.g. from a keyboard or | |
| 99 | - | mouse, counts as activity. | |
| 100 | - | ||
| 101 | - | When the notification object becomes idle, an idled event is sent. When | |
| 102 | - | user activity starts again, the notification object stops being idle, | |
| 103 | - | a resumed event is sent and the timeout is restarted. | |
| 104 | - | </description> | |
| 105 | - | ||
| 106 | - | <request name="destroy" type="destructor"> | |
| 107 | - | <description summary="destroy the notification object"> | |
| 108 | - | Destroy the notification object. | |
| 109 | - | </description> | |
| 110 | - | </request> | |
| 111 | - | ||
| 112 | - | <event name="idled"> | |
| 113 | - | <description summary="notification object is idle"> | |
| 114 | - | This event is sent when the notification object becomes idle. | |
| 115 | - | ||
| 116 | - | It's a compositor protocol error to send this event twice without a | |
| 117 | - | resumed event in-between. | |
| 118 | - | </description> | |
| 119 | - | </event> | |
| 120 | - | ||
| 121 | - | <event name="resumed"> | |
| 122 | - | <description summary="notification object is no longer idle"> | |
| 123 | - | This event is sent when the notification object stops being idle. | |
| 124 | - | ||
| 125 | - | It's a compositor protocol error to send this event twice without an | |
| 126 | - | idled event in-between. It's a compositor protocol error to send this | |
| 127 | - | event prior to any idled event. | |
| 128 | - | </description> | |
| 129 | - | </event> | |
| 130 | - | </interface> | |
| 131 | - | </protocol> | |
D protocol/idlenotify/ext-idle-notify-v1_generated.go +0 -206
| @@ -1,206 +0,0 @@ | |||
| 1 | - | // Code generated by wlturbo-scanner. DO NOT EDIT. | |
| 2 | - | // Protocol: ext_idle_notify_v1 | |
| 3 | - | // Source: ext-idle-notify-v1.xml | |
| 4 | - | ||
| 5 | - | // Upstream protocol copyright and license: | |
| 6 | - | // Copyright © 2015 Martin Gräßlin | |
| 7 | - | // Copyright © 2022 Simon Ser | |
| 8 | - | // | |
| 9 | - | // Permission is hereby granted, free of charge, to any person obtaining a | |
| 10 | - | // copy of this software and associated documentation files (the "Software"), | |
| 11 | - | // to deal in the Software without restriction, including without limitation | |
| 12 | - | // the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 13 | - | // and/or sell copies of the Software, and to permit persons to whom the | |
| 14 | - | // Software is furnished to do so, subject to the following conditions: | |
| 15 | - | // | |
| 16 | - | // The above copyright notice and this permission notice (including the next | |
| 17 | - | // paragraph) shall be included in all copies or substantial portions of the | |
| 18 | - | // Software. | |
| 19 | - | // | |
| 20 | - | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 21 | - | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 22 | - | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 23 | - | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 24 | - | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 25 | - | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
| 26 | - | // DEALINGS IN THE SOFTWARE. | |
| 27 | - | ||
| 28 | - | package idlenotify | |
| 29 | - | ||
| 30 | - | import ( | |
| 31 | - | "sync" | |
| 32 | - | ||
| 33 | - | cross_wl_seat "github.com/bnema/wlturbo/protocol/core" | |
| 34 | - | "github.com/bnema/wlturbo/wl" | |
| 35 | - | ) | |
| 36 | - | ||
| 37 | - | // ExtIdleNotifierInterface is the protocol interface name. | |
| 38 | - | const ExtIdleNotifierInterface = "ext_idle_notifier_v1" | |
| 39 | - | ||
| 40 | - | // ExtIdleNotifier is the generated binding for ext_idle_notifier_v1 version 2. | |
| 41 | - | type ExtIdleNotifier struct { | |
| 42 | - | wl.BaseProxy | |
| 43 | - | } | |
| 44 | - | ||
| 45 | - | // NewExtIdleNotifier returns an unbound ExtIdleNotifier. | |
| 46 | - | func NewExtIdleNotifier(ctx *wl.Context) *ExtIdleNotifier { | |
| 47 | - | obj := &ExtIdleNotifier{} | |
| 48 | - | obj.SetContext(ctx) | |
| 49 | - | ctx.Register(obj) | |
| 50 | - | return obj | |
| 51 | - | } | |
| 52 | - | ||
| 53 | - | // Destroy the manager object. All objects created via this interface remain valid. | |
| 54 | - | func (o *ExtIdleNotifier) Destroy() error { | |
| 55 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "ext_idle_notifier_v1.destroy", Destructor: true}); err != nil { | |
| 56 | - | return err | |
| 57 | - | } | |
| 58 | - | return nil | |
| 59 | - | } | |
| 60 | - | ||
| 61 | - | // 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. | |
| 62 | - | func (o *ExtIdleNotifier) GetIdleNotification(timeout uint32, seat *cross_wl_seat.Seat) (*ExtIdleNotification, error) { | |
| 63 | - | var arg2 wl.Object | |
| 64 | - | if seat != nil { | |
| 65 | - | arg2 = seat | |
| 66 | - | } | |
| 67 | - | child := &ExtIdleNotification{} | |
| 68 | - | child.SetContext(o.Context()) | |
| 69 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "ext_idle_notifier_v1.get_idle_notification", Child: child}, wl.ArgObject(child), wl.ArgUint(timeout), wl.ArgObject(arg2)); err != nil { | |
| 70 | - | return nil, err | |
| 71 | - | } | |
| 72 | - | return child, nil | |
| 73 | - | } | |
| 74 | - | ||
| 75 | - | // Create a new idle notification object to track input from the user, such as keyboard and mouse movement. Because this object is meant to track user input alone, it ignores idle inhibitors. 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. | |
| 76 | - | func (o *ExtIdleNotifier) GetInputIdleNotification(timeout uint32, seat *cross_wl_seat.Seat) (*ExtIdleNotification, error) { | |
| 77 | - | var arg2 wl.Object | |
| 78 | - | if seat != nil { | |
| 79 | - | arg2 = seat | |
| 80 | - | } | |
| 81 | - | child := &ExtIdleNotification{} | |
| 82 | - | child.SetContext(o.Context()) | |
| 83 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 2, Name: "ext_idle_notifier_v1.get_input_idle_notification", Since: 2, Child: child}, wl.ArgObject(child), wl.ArgUint(timeout), wl.ArgObject(arg2)); err != nil { | |
| 84 | - | return nil, err | |
| 85 | - | } | |
| 86 | - | return child, nil | |
| 87 | - | } | |
| 88 | - | ||
| 89 | - | // EventSignature returns the declared event argument types in wire order. | |
| 90 | - | func (o *ExtIdleNotifier) EventSignature(opcode uint16) (string, bool) { | |
| 91 | - | switch opcode { | |
| 92 | - | default: | |
| 93 | - | return "", false | |
| 94 | - | } | |
| 95 | - | } | |
| 96 | - | ||
| 97 | - | // Dispatch decodes one event on ext_idle_notifier_v1 and calls the registered handlers. | |
| 98 | - | func (o *ExtIdleNotifier) Dispatch(event *wl.Event) { | |
| 99 | - | switch event.Opcode { | |
| 100 | - | default: | |
| 101 | - | } | |
| 102 | - | } | |
| 103 | - | ||
| 104 | - | // ExtIdleNotificationInterface is the protocol interface name. | |
| 105 | - | const ExtIdleNotificationInterface = "ext_idle_notification_v1" | |
| 106 | - | ||
| 107 | - | // ExtIdleNotification is the generated binding for ext_idle_notification_v1 version 2. | |
| 108 | - | type ExtIdleNotification struct { | |
| 109 | - | wl.BaseProxy | |
| 110 | - | // handlersMu guards the handler slices: a client may register or replace | |
| 111 | - | // handlers while another goroutine dispatches events. | |
| 112 | - | handlersMu sync.Mutex | |
| 113 | - | onIdled []func() | |
| 114 | - | onResumed []func() | |
| 115 | - | } | |
| 116 | - | ||
| 117 | - | // NewExtIdleNotification returns an unbound ExtIdleNotification. | |
| 118 | - | func NewExtIdleNotification(ctx *wl.Context) *ExtIdleNotification { | |
| 119 | - | obj := &ExtIdleNotification{} | |
| 120 | - | obj.SetContext(ctx) | |
| 121 | - | ctx.Register(obj) | |
| 122 | - | return obj | |
| 123 | - | } | |
| 124 | - | ||
| 125 | - | // Destroy the notification object. | |
| 126 | - | func (o *ExtIdleNotification) Destroy() error { | |
| 127 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "ext_idle_notification_v1.destroy", Destructor: true}); err != nil { | |
| 128 | - | return err | |
| 129 | - | } | |
| 130 | - | return nil | |
| 131 | - | } | |
| 132 | - | ||
| 133 | - | // OnIdled registers a handler for the idled event. | |
| 134 | - | // | |
| 135 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 136 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 137 | - | func (o *ExtIdleNotification) OnIdled(handler func()) { | |
| 138 | - | if handler == nil { | |
| 139 | - | return | |
| 140 | - | } | |
| 141 | - | o.handlersMu.Lock() | |
| 142 | - | defer o.handlersMu.Unlock() | |
| 143 | - | o.onIdled = append(o.onIdled, handler) | |
| 144 | - | } | |
| 145 | - | ||
| 146 | - | // handlersForIdled returns the handlers registered for idled, taken | |
| 147 | - | // under the lock so a handler may register another handler while events are | |
| 148 | - | // being dispatched. | |
| 149 | - | func (o *ExtIdleNotification) handlersForIdled() []func() { | |
| 150 | - | o.handlersMu.Lock() | |
| 151 | - | defer o.handlersMu.Unlock() | |
| 152 | - | return o.onIdled | |
| 153 | - | } | |
| 154 | - | ||
| 155 | - | // OnResumed registers a handler for the resumed event. | |
| 156 | - | // | |
| 157 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 158 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 159 | - | func (o *ExtIdleNotification) OnResumed(handler func()) { | |
| 160 | - | if handler == nil { | |
| 161 | - | return | |
| 162 | - | } | |
| 163 | - | o.handlersMu.Lock() | |
| 164 | - | defer o.handlersMu.Unlock() | |
| 165 | - | o.onResumed = append(o.onResumed, handler) | |
| 166 | - | } | |
| 167 | - | ||
| 168 | - | // handlersForResumed returns the handlers registered for resumed, taken | |
| 169 | - | // under the lock so a handler may register another handler while events are | |
| 170 | - | // being dispatched. | |
| 171 | - | func (o *ExtIdleNotification) handlersForResumed() []func() { | |
| 172 | - | o.handlersMu.Lock() | |
| 173 | - | defer o.handlersMu.Unlock() | |
| 174 | - | return o.onResumed | |
| 175 | - | } | |
| 176 | - | ||
| 177 | - | // EventSignature returns the declared event argument types in wire order. | |
| 178 | - | func (o *ExtIdleNotification) EventSignature(opcode uint16) (string, bool) { | |
| 179 | - | switch opcode { | |
| 180 | - | case 0: | |
| 181 | - | return "", true | |
| 182 | - | case 1: | |
| 183 | - | return "", true | |
| 184 | - | default: | |
| 185 | - | return "", false | |
| 186 | - | } | |
| 187 | - | } | |
| 188 | - | ||
| 189 | - | // Dispatch decodes one event on ext_idle_notification_v1 and calls the registered handlers. | |
| 190 | - | func (o *ExtIdleNotification) Dispatch(event *wl.Event) { | |
| 191 | - | switch event.Opcode { | |
| 192 | - | case 0: // idled | |
| 193 | - | ||
| 194 | - | for i, handler := range o.handlersForIdled() { | |
| 195 | - | _ = i | |
| 196 | - | handler() | |
| 197 | - | } | |
| 198 | - | case 1: // resumed | |
| 199 | - | ||
| 200 | - | for i, handler := range o.handlersForResumed() { | |
| 201 | - | _ = i | |
| 202 | - | handler() | |
| 203 | - | } | |
| 204 | - | default: | |
| 205 | - | } | |
| 206 | - | } | |
D protocol/idlenotify/generate.go +0 -3
| @@ -1,3 +0,0 @@ | |||
| 1 | - | package idlenotify | |
| 2 | - | ||
| 3 | - | //go:generate go run ../../cmd/wlturbo-scanner -p idlenotify -o ext-idle-notify-v1_generated.go -import wl_seat=github.com/bnema/wlturbo/protocol/core ext-idle-notify-v1.xml | |
D protocol/imagecapturesource/ext-image-capture-source-v1.xml +0 -109
| @@ -1,109 +0,0 @@ | |||
| 1 | - | <?xml version="1.0" encoding="UTF-8"?> | |
| 2 | - | <protocol name="ext_image_capture_source_v1"> | |
| 3 | - | <copyright> | |
| 4 | - | Copyright © 2022 Andri Yngvason | |
| 5 | - | Copyright © 2024 Simon Ser | |
| 6 | - | ||
| 7 | - | Permission is hereby granted, free of charge, to any person obtaining a | |
| 8 | - | copy of this software and associated documentation files (the "Software"), | |
| 9 | - | to deal in the Software without restriction, including without limitation | |
| 10 | - | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 11 | - | and/or sell copies of the Software, and to permit persons to whom the | |
| 12 | - | Software is furnished to do so, subject to the following conditions: | |
| 13 | - | ||
| 14 | - | The above copyright notice and this permission notice (including the next | |
| 15 | - | paragraph) shall be included in all copies or substantial portions of the | |
| 16 | - | Software. | |
| 17 | - | ||
| 18 | - | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 19 | - | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 20 | - | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 21 | - | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 22 | - | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 23 | - | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
| 24 | - | DEALINGS IN THE SOFTWARE. | |
| 25 | - | </copyright> | |
| 26 | - | ||
| 27 | - | <description summary="opaque image capture source objects"> | |
| 28 | - | This protocol serves as an intermediary between capturing protocols and | |
| 29 | - | potential image capture sources such as outputs and toplevels. | |
| 30 | - | ||
| 31 | - | This protocol may be extended to support more image capture sources in the | |
| 32 | - | future, thereby adding those image capture sources to other protocols that | |
| 33 | - | use the image capture source object without having to modify those | |
| 34 | - | protocols. | |
| 35 | - | ||
| 36 | - | Warning! The protocol described in this file is currently in the testing | |
| 37 | - | phase. Backward compatible changes may be added together with the | |
| 38 | - | corresponding interface version bump. Backward incompatible changes can | |
| 39 | - | only be done by creating a new major version of the extension. | |
| 40 | - | </description> | |
| 41 | - | ||
| 42 | - | <interface name="ext_image_capture_source_v1" version="1" frozen="true"> | |
| 43 | - | <description summary="opaque image capture source object"> | |
| 44 | - | The image capture source object is an opaque descriptor for a capturable | |
| 45 | - | resource. This resource may be any sort of entity from which an image | |
| 46 | - | may be derived. | |
| 47 | - | ||
| 48 | - | Note, because ext_image_capture_source_v1 objects are created from multiple | |
| 49 | - | independent factory interfaces, the ext_image_capture_source_v1 interface is | |
| 50 | - | frozen at version 1. | |
| 51 | - | </description> | |
| 52 | - | ||
| 53 | - | <request name="destroy" type="destructor"> | |
| 54 | - | <description summary="delete this object"> | |
| 55 | - | Destroys the image capture source. This request may be sent at any time | |
| 56 | - | by the client. | |
| 57 | - | </description> | |
| 58 | - | </request> | |
| 59 | - | </interface> | |
| 60 | - | ||
| 61 | - | <interface name="ext_output_image_capture_source_manager_v1" version="1"> | |
| 62 | - | <description summary="image capture source manager for outputs"> | |
| 63 | - | A manager for creating image capture source objects for wl_output objects. | |
| 64 | - | </description> | |
| 65 | - | ||
| 66 | - | <request name="create_source"> | |
| 67 | - | <description summary="create source object for output"> | |
| 68 | - | Creates a source object for an output. Images captured from this source | |
| 69 | - | will show the same content as the output. Some elements may be omitted, | |
| 70 | - | such as cursors and overlays that have been marked as transparent to | |
| 71 | - | capturing. | |
| 72 | - | </description> | |
| 73 | - | <arg name="source" type="new_id" interface="ext_image_capture_source_v1"/> | |
| 74 | - | <arg name="output" type="object" interface="wl_output"/> | |
| 75 | - | </request> | |
| 76 | - | ||
| 77 | - | <request name="destroy" type="destructor"> | |
| 78 | - | <description summary="delete this object"> | |
| 79 | - | Destroys the manager. This request may be sent at any time by the client | |
| 80 | - | and objects created by the manager will remain valid after its | |
| 81 | - | destruction. | |
| 82 | - | </description> | |
| 83 | - | </request> | |
| 84 | - | </interface> | |
| 85 | - | ||
| 86 | - | <interface name="ext_foreign_toplevel_image_capture_source_manager_v1" version="1"> | |
| 87 | - | <description summary="image capture source manager for foreign toplevels"> | |
| 88 | - | A manager for creating image capture source objects for | |
| 89 | - | ext_foreign_toplevel_handle_v1 objects. | |
| 90 | - | </description> | |
| 91 | - | ||
| 92 | - | <request name="create_source"> | |
| 93 | - | <description summary="create source object for foreign toplevel"> | |
| 94 | - | Creates a source object for a foreign toplevel handle. Images captured | |
| 95 | - | from this source will show the same content as the toplevel. | |
| 96 | - | </description> | |
| 97 | - | <arg name="source" type="new_id" interface="ext_image_capture_source_v1"/> | |
| 98 | - | <arg name="toplevel_handle" type="object" interface="ext_foreign_toplevel_handle_v1"/> | |
| 99 | - | </request> | |
| 100 | - | ||
| 101 | - | <request name="destroy" type="destructor"> | |
| 102 | - | <description summary="delete this object"> | |
| 103 | - | Destroys the manager. This request may be sent at any time by the client | |
| 104 | - | and objects created by the manager will remain valid after its | |
| 105 | - | destruction. | |
| 106 | - | </description> | |
| 107 | - | </request> | |
| 108 | - | </interface> | |
| 109 | - | </protocol> | |
D protocol/imagecapturesource/ext-image-capture-source-v1_generated.go +0 -179
| @@ -1,179 +0,0 @@ | |||
| 1 | - | // Code generated by wlturbo-scanner. DO NOT EDIT. | |
| 2 | - | // Protocol: ext_image_capture_source_v1 | |
| 3 | - | // Source: ext-image-capture-source-v1.xml | |
| 4 | - | ||
| 5 | - | // Upstream protocol copyright and license: | |
| 6 | - | // Copyright © 2022 Andri Yngvason | |
| 7 | - | // Copyright © 2024 Simon Ser | |
| 8 | - | // | |
| 9 | - | // Permission is hereby granted, free of charge, to any person obtaining a | |
| 10 | - | // copy of this software and associated documentation files (the "Software"), | |
| 11 | - | // to deal in the Software without restriction, including without limitation | |
| 12 | - | // the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 13 | - | // and/or sell copies of the Software, and to permit persons to whom the | |
| 14 | - | // Software is furnished to do so, subject to the following conditions: | |
| 15 | - | // | |
| 16 | - | // The above copyright notice and this permission notice (including the next | |
| 17 | - | // paragraph) shall be included in all copies or substantial portions of the | |
| 18 | - | // Software. | |
| 19 | - | // | |
| 20 | - | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 21 | - | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 22 | - | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 23 | - | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 24 | - | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 25 | - | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
| 26 | - | // DEALINGS IN THE SOFTWARE. | |
| 27 | - | ||
| 28 | - | package imagecapturesource | |
| 29 | - | ||
| 30 | - | import ( | |
| 31 | - | cross_wl_output "github.com/bnema/wlturbo/protocol/core" | |
| 32 | - | cross_ext_foreign_toplevel_handle_v1 "github.com/bnema/wlturbo/protocol/extforeigntoplevel" | |
| 33 | - | "github.com/bnema/wlturbo/wl" | |
| 34 | - | ) | |
| 35 | - | ||
| 36 | - | // ExtImageCaptureSourceInterface is the protocol interface name. | |
| 37 | - | const ExtImageCaptureSourceInterface = "ext_image_capture_source_v1" | |
| 38 | - | ||
| 39 | - | // ExtImageCaptureSource is the generated binding for ext_image_capture_source_v1 version 1. | |
| 40 | - | type ExtImageCaptureSource struct { | |
| 41 | - | wl.BaseProxy | |
| 42 | - | } | |
| 43 | - | ||
| 44 | - | // NewExtImageCaptureSource returns an unbound ExtImageCaptureSource. | |
| 45 | - | func NewExtImageCaptureSource(ctx *wl.Context) *ExtImageCaptureSource { | |
| 46 | - | obj := &ExtImageCaptureSource{} | |
| 47 | - | obj.SetContext(ctx) | |
| 48 | - | ctx.Register(obj) | |
| 49 | - | return obj | |
| 50 | - | } | |
| 51 | - | ||
| 52 | - | // Destroys the image capture source. This request may be sent at any time by the client. | |
| 53 | - | func (o *ExtImageCaptureSource) Destroy() error { | |
| 54 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "ext_image_capture_source_v1.destroy", Destructor: true}); err != nil { | |
| 55 | - | return err | |
| 56 | - | } | |
| 57 | - | return nil | |
| 58 | - | } | |
| 59 | - | ||
| 60 | - | // EventSignature returns the declared event argument types in wire order. | |
| 61 | - | func (o *ExtImageCaptureSource) EventSignature(opcode uint16) (string, bool) { | |
| 62 | - | switch opcode { | |
| 63 | - | default: | |
| 64 | - | return "", false | |
| 65 | - | } | |
| 66 | - | } | |
| 67 | - | ||
| 68 | - | // Dispatch decodes one event on ext_image_capture_source_v1 and calls the registered handlers. | |
| 69 | - | func (o *ExtImageCaptureSource) Dispatch(event *wl.Event) { | |
| 70 | - | switch event.Opcode { | |
| 71 | - | default: | |
| 72 | - | } | |
| 73 | - | } | |
| 74 | - | ||
| 75 | - | // ExtOutputImageCaptureSourceManagerInterface is the protocol interface name. | |
| 76 | - | const ExtOutputImageCaptureSourceManagerInterface = "ext_output_image_capture_source_manager_v1" | |
| 77 | - | ||
| 78 | - | // ExtOutputImageCaptureSourceManager is the generated binding for ext_output_image_capture_source_manager_v1 version 1. | |
| 79 | - | type ExtOutputImageCaptureSourceManager struct { | |
| 80 | - | wl.BaseProxy | |
| 81 | - | } | |
| 82 | - | ||
| 83 | - | // NewExtOutputImageCaptureSourceManager returns an unbound ExtOutputImageCaptureSourceManager. | |
| 84 | - | func NewExtOutputImageCaptureSourceManager(ctx *wl.Context) *ExtOutputImageCaptureSourceManager { | |
| 85 | - | obj := &ExtOutputImageCaptureSourceManager{} | |
| 86 | - | obj.SetContext(ctx) | |
| 87 | - | ctx.Register(obj) | |
| 88 | - | return obj | |
| 89 | - | } | |
| 90 | - | ||
| 91 | - | // Creates a source object for an output. Images captured from this source will show the same content as the output. Some elements may be omitted, such as cursors and overlays that have been marked as transparent to capturing. | |
| 92 | - | func (o *ExtOutputImageCaptureSourceManager) CreateSource(output *cross_wl_output.Output) (*ExtImageCaptureSource, error) { | |
| 93 | - | var arg1 wl.Object | |
| 94 | - | if output != nil { | |
| 95 | - | arg1 = output | |
| 96 | - | } | |
| 97 | - | child := &ExtImageCaptureSource{} | |
| 98 | - | child.SetContext(o.Context()) | |
| 99 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "ext_output_image_capture_source_manager_v1.create_source", Child: child}, wl.ArgObject(child), wl.ArgObject(arg1)); err != nil { | |
| 100 | - | return nil, err | |
| 101 | - | } | |
| 102 | - | return child, nil | |
| 103 | - | } | |
| 104 | - | ||
| 105 | - | // Destroys the manager. This request may be sent at any time by the client and objects created by the manager will remain valid after its destruction. | |
| 106 | - | func (o *ExtOutputImageCaptureSourceManager) Destroy() error { | |
| 107 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "ext_output_image_capture_source_manager_v1.destroy", Destructor: true}); err != nil { | |
| 108 | - | return err | |
| 109 | - | } | |
| 110 | - | return nil | |
| 111 | - | } | |
| 112 | - | ||
| 113 | - | // EventSignature returns the declared event argument types in wire order. | |
| 114 | - | func (o *ExtOutputImageCaptureSourceManager) EventSignature(opcode uint16) (string, bool) { | |
| 115 | - | switch opcode { | |
| 116 | - | default: | |
| 117 | - | return "", false | |
| 118 | - | } | |
| 119 | - | } | |
| 120 | - | ||
| 121 | - | // Dispatch decodes one event on ext_output_image_capture_source_manager_v1 and calls the registered handlers. | |
| 122 | - | func (o *ExtOutputImageCaptureSourceManager) Dispatch(event *wl.Event) { | |
| 123 | - | switch event.Opcode { | |
| 124 | - | default: | |
| 125 | - | } | |
| 126 | - | } | |
| 127 | - | ||
| 128 | - | // ExtForeignToplevelImageCaptureSourceManagerInterface is the protocol interface name. | |
| 129 | - | const ExtForeignToplevelImageCaptureSourceManagerInterface = "ext_foreign_toplevel_image_capture_source_manager_v1" | |
| 130 | - | ||
| 131 | - | // ExtForeignToplevelImageCaptureSourceManager is the generated binding for ext_foreign_toplevel_image_capture_source_manager_v1 version 1. | |
| 132 | - | type ExtForeignToplevelImageCaptureSourceManager struct { | |
| 133 | - | wl.BaseProxy | |
| 134 | - | } | |
| 135 | - | ||
| 136 | - | // NewExtForeignToplevelImageCaptureSourceManager returns an unbound ExtForeignToplevelImageCaptureSourceManager. | |
| 137 | - | func NewExtForeignToplevelImageCaptureSourceManager(ctx *wl.Context) *ExtForeignToplevelImageCaptureSourceManager { | |
| 138 | - | obj := &ExtForeignToplevelImageCaptureSourceManager{} | |
| 139 | - | obj.SetContext(ctx) | |
| 140 | - | ctx.Register(obj) | |
| 141 | - | return obj | |
| 142 | - | } | |
| 143 | - | ||
| 144 | - | // Creates a source object for a foreign toplevel handle. Images captured from this source will show the same content as the toplevel. | |
| 145 | - | func (o *ExtForeignToplevelImageCaptureSourceManager) CreateSource(toplevelHandle *cross_ext_foreign_toplevel_handle_v1.ExtForeignToplevelHandle) (*ExtImageCaptureSource, error) { | |
| 146 | - | var arg1 wl.Object | |
| 147 | - | if toplevelHandle != nil { | |
| 148 | - | arg1 = toplevelHandle | |
| 149 | - | } | |
| 150 | - | child := &ExtImageCaptureSource{} | |
| 151 | - | child.SetContext(o.Context()) | |
| 152 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "ext_foreign_toplevel_image_capture_source_manager_v1.create_source", Child: child}, wl.ArgObject(child), wl.ArgObject(arg1)); err != nil { | |
| 153 | - | return nil, err | |
| 154 | - | } | |
| 155 | - | return child, nil | |
| 156 | - | } | |
| 157 | - | ||
| 158 | - | // Destroys the manager. This request may be sent at any time by the client and objects created by the manager will remain valid after its destruction. | |
| 159 | - | func (o *ExtForeignToplevelImageCaptureSourceManager) Destroy() error { | |
| 160 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "ext_foreign_toplevel_image_capture_source_manager_v1.destroy", Destructor: true}); err != nil { | |
| 161 | - | return err | |
| 162 | - | } | |
| 163 | - | return nil | |
| 164 | - | } | |
| 165 | - | ||
| 166 | - | // EventSignature returns the declared event argument types in wire order. | |
| 167 | - | func (o *ExtForeignToplevelImageCaptureSourceManager) EventSignature(opcode uint16) (string, bool) { | |
| 168 | - | switch opcode { | |
| 169 | - | default: | |
| 170 | - | return "", false | |
| 171 | - | } | |
| 172 | - | } | |
| 173 | - | ||
| 174 | - | // Dispatch decodes one event on ext_foreign_toplevel_image_capture_source_manager_v1 and calls the registered handlers. | |
| 175 | - | func (o *ExtForeignToplevelImageCaptureSourceManager) Dispatch(event *wl.Event) { | |
| 176 | - | switch event.Opcode { | |
| 177 | - | default: | |
| 178 | - | } | |
| 179 | - | } | |
D protocol/imagecapturesource/generate.go +0 -3
| @@ -1,3 +0,0 @@ | |||
| 1 | - | package imagecapturesource | |
| 2 | - | ||
| 3 | - | //go:generate go run ../../cmd/wlturbo-scanner -p imagecapturesource -import ext_foreign_toplevel_handle_v1=github.com/bnema/wlturbo/protocol/extforeigntoplevel -o ext-image-capture-source-v1_generated.go -import wl_output=github.com/bnema/wlturbo/protocol/core ext-image-capture-source-v1.xml | |
D protocol/imagecopycapture/ext-image-copy-capture-v1.xml +0 -456
| @@ -1,456 +0,0 @@ | |||
| 1 | - | <?xml version="1.0" encoding="UTF-8"?> | |
| 2 | - | <protocol name="ext_image_copy_capture_v1"> | |
| 3 | - | <copyright> | |
| 4 | - | Copyright © 2021-2023 Andri Yngvason | |
| 5 | - | Copyright © 2024 Simon Ser | |
| 6 | - | ||
| 7 | - | Permission is hereby granted, free of charge, to any person obtaining a | |
| 8 | - | copy of this software and associated documentation files (the "Software"), | |
| 9 | - | to deal in the Software without restriction, including without limitation | |
| 10 | - | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 11 | - | and/or sell copies of the Software, and to permit persons to whom the | |
| 12 | - | Software is furnished to do so, subject to the following conditions: | |
| 13 | - | ||
| 14 | - | The above copyright notice and this permission notice (including the next | |
| 15 | - | paragraph) shall be included in all copies or substantial portions of the | |
| 16 | - | Software. | |
| 17 | - | ||
| 18 | - | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 19 | - | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 20 | - | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 21 | - | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 22 | - | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 23 | - | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
| 24 | - | DEALINGS IN THE SOFTWARE. | |
| 25 | - | </copyright> | |
| 26 | - | ||
| 27 | - | <description summary="image capturing into client buffers"> | |
| 28 | - | This protocol allows clients to ask the compositor to capture image sources | |
| 29 | - | such as outputs and toplevels into user submitted buffers. | |
| 30 | - | ||
| 31 | - | Warning! The protocol described in this file is currently in the testing | |
| 32 | - | phase. Backward compatible changes may be added together with the | |
| 33 | - | corresponding interface version bump. Backward incompatible changes can | |
| 34 | - | only be done by creating a new major version of the extension. | |
| 35 | - | </description> | |
| 36 | - | ||
| 37 | - | <interface name="ext_image_copy_capture_manager_v1" version="1"> | |
| 38 | - | <description summary="manager to inform clients and begin capturing"> | |
| 39 | - | This object is a manager which offers requests to start capturing from a | |
| 40 | - | source. | |
| 41 | - | </description> | |
| 42 | - | ||
| 43 | - | <enum name="error"> | |
| 44 | - | <entry name="invalid_option" value="1" summary="invalid option flag"/> | |
| 45 | - | </enum> | |
| 46 | - | ||
| 47 | - | <enum name="options" bitfield="true"> | |
| 48 | - | <entry name="paint_cursors" value="1" summary="paint cursors onto captured frames"/> | |
| 49 | - | </enum> | |
| 50 | - | ||
| 51 | - | <request name="create_session"> | |
| 52 | - | <description summary="capture an image capture source"> | |
| 53 | - | Create a capturing session for an image capture source. | |
| 54 | - | ||
| 55 | - | If the paint_cursors option is set, cursors shall be composited onto | |
| 56 | - | the captured frame. The cursor must not be composited onto the frame | |
| 57 | - | if this flag is not set. | |
| 58 | - | ||
| 59 | - | If the options bitfield is invalid, the invalid_option protocol error | |
| 60 | - | is sent. | |
| 61 | - | </description> | |
| 62 | - | <arg name="session" type="new_id" interface="ext_image_copy_capture_session_v1"/> | |
| 63 | - | <arg name="source" type="object" interface="ext_image_capture_source_v1"/> | |
| 64 | - | <arg name="options" type="uint" enum="options"/> | |
| 65 | - | </request> | |
| 66 | - | ||
| 67 | - | <request name="create_pointer_cursor_session"> | |
| 68 | - | <description summary="capture the pointer cursor of an image capture source"> | |
| 69 | - | Create a cursor capturing session for the pointer of an image capture | |
| 70 | - | source. | |
| 71 | - | </description> | |
| 72 | - | <arg name="session" type="new_id" interface="ext_image_copy_capture_cursor_session_v1"/> | |
| 73 | - | <arg name="source" type="object" interface="ext_image_capture_source_v1"/> | |
| 74 | - | <arg name="pointer" type="object" interface="wl_pointer"/> | |
| 75 | - | </request> | |
| 76 | - | ||
| 77 | - | <request name="destroy" type="destructor"> | |
| 78 | - | <description summary="destroy the manager"> | |
| 79 | - | Destroy the manager object. | |
| 80 | - | ||
| 81 | - | Other objects created via this interface are unaffected. | |
| 82 | - | </description> | |
| 83 | - | </request> | |
| 84 | - | </interface> | |
| 85 | - | ||
| 86 | - | <interface name="ext_image_copy_capture_session_v1" version="1"> | |
| 87 | - | <description summary="image copy capture session"> | |
| 88 | - | This object represents an active image copy capture session. | |
| 89 | - | ||
| 90 | - | After a capture session is created, buffer constraint events will be | |
| 91 | - | emitted from the compositor to tell the client which buffer types and | |
| 92 | - | formats are supported for reading from the session. The compositor may | |
| 93 | - | re-send buffer constraint events whenever they change. | |
| 94 | - | ||
| 95 | - | To advertise buffer constraints, the compositor must send in no | |
| 96 | - | particular order: zero or more shm_format and dmabuf_format events, zero | |
| 97 | - | or one dmabuf_device event, and exactly one buffer_size event. Then the | |
| 98 | - | compositor must send a done event. | |
| 99 | - | ||
| 100 | - | When the client has received all the buffer constraints, it can create a | |
| 101 | - | buffer accordingly, attach it to the capture session using the | |
| 102 | - | attach_buffer request, set the buffer damage using the damage_buffer | |
| 103 | - | request and then send the capture request. | |
| 104 | - | </description> | |
| 105 | - | ||
| 106 | - | <enum name="error"> | |
| 107 | - | <entry name="duplicate_frame" value="1" | |
| 108 | - | summary="create_frame sent before destroying previous frame"/> | |
| 109 | - | </enum> | |
| 110 | - | ||
| 111 | - | <event name="buffer_size"> | |
| 112 | - | <description summary="image capture source dimensions"> | |
| 113 | - | Provides the dimensions of the source image in buffer pixel coordinates. | |
| 114 | - | ||
| 115 | - | The client must attach buffers that match this size. | |
| 116 | - | </description> | |
| 117 | - | <arg name="width" type="uint" summary="buffer width"/> | |
| 118 | - | <arg name="height" type="uint" summary="buffer height"/> | |
| 119 | - | </event> | |
| 120 | - | ||
| 121 | - | <event name="shm_format"> | |
| 122 | - | <description summary="shm buffer format"> | |
| 123 | - | Provides the format that must be used for shared-memory buffers. | |
| 124 | - | ||
| 125 | - | This event may be emitted multiple times, in which case the client may | |
| 126 | - | choose any given format. | |
| 127 | - | </description> | |
| 128 | - | <arg name="format" type="uint" enum="wl_shm.format" summary="shm format"/> | |
| 129 | - | </event> | |
| 130 | - | ||
| 131 | - | <event name="dmabuf_device"> | |
| 132 | - | <description summary="dma-buf device"> | |
| 133 | - | This event advertises the device buffers must be allocated on for | |
| 134 | - | dma-buf buffers. | |
| 135 | - | ||
| 136 | - | In general the device is a DRM node. The DRM node type (primary vs. | |
| 137 | - | render) is unspecified. Clients must not rely on the compositor sending | |
| 138 | - | a particular node type. Clients cannot check two devices for equality | |
| 139 | - | by comparing the dev_t value. | |
| 140 | - | </description> | |
| 141 | - | <arg name="device" type="array" summary="device dev_t value"/> | |
| 142 | - | </event> | |
| 143 | - | ||
| 144 | - | <event name="dmabuf_format"> | |
| 145 | - | <description summary="dma-buf format"> | |
| 146 | - | Provides the format that must be used for dma-buf buffers. | |
| 147 | - | ||
| 148 | - | The client may choose any of the modifiers advertised in the array of | |
| 149 | - | 64-bit unsigned integers. | |
| 150 | - | ||
| 151 | - | This event may be emitted multiple times, in which case the client may | |
| 152 | - | choose any given format. | |
| 153 | - | </description> | |
| 154 | - | <arg name="format" type="uint" summary="drm format code"/> | |
| 155 | - | <arg name="modifiers" type="array" summary="drm format modifiers"/> | |
| 156 | - | </event> | |
| 157 | - | ||
| 158 | - | <event name="done"> | |
| 159 | - | <description summary="all constraints have been sent"> | |
| 160 | - | This event is sent once when all buffer constraint events have been | |
| 161 | - | sent. | |
| 162 | - | ||
| 163 | - | The compositor must always end a batch of buffer constraint events with | |
| 164 | - | this event, regardless of whether it sends the initial constraints or | |
| 165 | - | an update. | |
| 166 | - | </description> | |
| 167 | - | </event> | |
| 168 | - | ||
| 169 | - | <event name="stopped"> | |
| 170 | - | <description summary="session is no longer available"> | |
| 171 | - | This event indicates that the capture session has stopped and is no | |
| 172 | - | longer available. This can happen in a number of cases, e.g. when the | |
| 173 | - | underlying source is destroyed, if the user decides to end the image | |
| 174 | - | capture, or if an unrecoverable runtime error has occurred. | |
| 175 | - | ||
| 176 | - | The client should destroy the session after receiving this event. | |
| 177 | - | </description> | |
| 178 | - | </event> | |
| 179 | - | ||
| 180 | - | <request name="create_frame"> | |
| 181 | - | <description summary="create a frame"> | |
| 182 | - | Create a capture frame for this session. | |
| 183 | - | ||
| 184 | - | At most one frame object can exist for a given session at any time. If | |
| 185 | - | a client sends a create_frame request before a previous frame object | |
| 186 | - | has been destroyed, the duplicate_frame protocol error is raised. | |
| 187 | - | </description> | |
| 188 | - | <arg name="frame" type="new_id" interface="ext_image_copy_capture_frame_v1"/> | |
| 189 | - | </request> | |
| 190 | - | ||
| 191 | - | <request name="destroy" type="destructor"> | |
| 192 | - | <description summary="delete this object"> | |
| 193 | - | Destroys the session. This request can be sent at any time by the | |
| 194 | - | client. | |
| 195 | - | ||
| 196 | - | This request doesn't affect ext_image_copy_capture_frame_v1 objects created by | |
| 197 | - | this object. | |
| 198 | - | </description> | |
| 199 | - | </request> | |
| 200 | - | </interface> | |
| 201 | - | ||
| 202 | - | <interface name="ext_image_copy_capture_frame_v1" version="1"> | |
| 203 | - | <description summary="image capture frame"> | |
| 204 | - | This object represents an image capture frame. | |
| 205 | - | ||
| 206 | - | The client should attach a buffer, damage the buffer, and then send a | |
| 207 | - | capture request. | |
| 208 | - | ||
| 209 | - | If the capture is successful, the compositor must send the frame metadata | |
| 210 | - | (transform, damage, presentation_time in any order) followed by the ready | |
| 211 | - | event. | |
| 212 | - | ||
| 213 | - | If the capture fails, the compositor must send the failed event. | |
| 214 | - | </description> | |
| 215 | - | ||
| 216 | - | <enum name="error"> | |
| 217 | - | <entry name="no_buffer" value="1" summary="capture sent without attach_buffer"/> | |
| 218 | - | <entry name="invalid_buffer_damage" value="2" summary="invalid buffer damage"/> | |
| 219 | - | <entry name="already_captured" value="3" summary="capture request has been sent"/> | |
| 220 | - | </enum> | |
| 221 | - | ||
| 222 | - | <request name="destroy" type="destructor"> | |
| 223 | - | <description summary="destroy this object"> | |
| 224 | - | Destroys the frame. This request can be sent at any time by the | |
| 225 | - | client. | |
| 226 | - | </description> | |
| 227 | - | </request> | |
| 228 | - | ||
| 229 | - | <request name="attach_buffer"> | |
| 230 | - | <description summary="attach buffer to session"> | |
| 231 | - | Attach a buffer to the session. | |
| 232 | - | ||
| 233 | - | The wl_buffer.release request is unused. | |
| 234 | - | ||
| 235 | - | The new buffer replaces any previously attached buffer. | |
| 236 | - | ||
| 237 | - | This request must not be sent after capture, or else the | |
| 238 | - | already_captured protocol error is raised. | |
| 239 | - | </description> | |
| 240 | - | <arg name="buffer" type="object" interface="wl_buffer"/> | |
| 241 | - | </request> | |
| 242 | - | ||
| 243 | - | <request name="damage_buffer"> | |
| 244 | - | <description summary="damage buffer"> | |
| 245 | - | Apply damage to the buffer which is to be captured next. This request | |
| 246 | - | may be sent multiple times to describe a region. | |
| 247 | - | ||
| 248 | - | The client indicates the accumulated damage since this wl_buffer was | |
| 249 | - | last captured. During capture, the compositor will update the buffer | |
| 250 | - | with at least the union of the region passed by the client and the | |
| 251 | - | region advertised by ext_image_copy_capture_frame_v1.damage. | |
| 252 | - | ||
| 253 | - | When a wl_buffer is captured for the first time, or when the client | |
| 254 | - | doesn't track damage, the client must damage the whole buffer. | |
| 255 | - | ||
| 256 | - | This is for optimisation purposes. The compositor may use this | |
| 257 | - | information to reduce copying. | |
| 258 | - | ||
| 259 | - | These coordinates originate from the upper left corner of the buffer. | |
| 260 | - | ||
| 261 | - | If x or y are strictly negative, or if width or height are negative or | |
| 262 | - | zero, the invalid_buffer_damage protocol error is raised. | |
| 263 | - | ||
| 264 | - | This request must not be sent after capture, or else the | |
| 265 | - | already_captured protocol error is raised. | |
| 266 | - | </description> | |
| 267 | - | <arg name="x" type="int" summary="region x coordinate"/> | |
| 268 | - | <arg name="y" type="int" summary="region y coordinate"/> | |
| 269 | - | <arg name="width" type="int" summary="region width"/> | |
| 270 | - | <arg name="height" type="int" summary="region height"/> | |
| 271 | - | </request> | |
| 272 | - | ||
| 273 | - | <request name="capture"> | |
| 274 | - | <description summary="capture a frame"> | |
| 275 | - | Capture a frame. | |
| 276 | - | ||
| 277 | - | Unless this is the first successful captured frame performed in this | |
| 278 | - | session, the compositor may wait an indefinite amount of time for the | |
| 279 | - | source content to change before performing the copy. | |
| 280 | - | ||
| 281 | - | This request may only be sent once, or else the already_captured | |
| 282 | - | protocol error is raised. A buffer must be attached before this request | |
| 283 | - | is sent, or else the no_buffer protocol error is raised. | |
| 284 | - | </description> | |
| 285 | - | </request> | |
| 286 | - | ||
| 287 | - | <event name="transform"> | |
| 288 | - | <description summary="buffer transform"> | |
| 289 | - | This event is sent before the ready event and holds the transform that | |
| 290 | - | the compositor has applied to the buffer contents. | |
| 291 | - | </description> | |
| 292 | - | <arg name="transform" type="uint" enum="wl_output.transform"/> | |
| 293 | - | </event> | |
| 294 | - | ||
| 295 | - | <event name="damage"> | |
| 296 | - | <description summary="buffer damaged region"> | |
| 297 | - | This event is sent before the ready event. It may be generated multiple | |
| 298 | - | times to describe a region. | |
| 299 | - | ||
| 300 | - | The first captured frame in a session will always carry full damage. | |
| 301 | - | Subsequent frames' damaged regions describe which parts of the buffer | |
| 302 | - | have changed since the last ready event. | |
| 303 | - | ||
| 304 | - | These coordinates originate in the upper left corner of the buffer. | |
| 305 | - | </description> | |
| 306 | - | <arg name="x" type="int" summary="damage x coordinate"/> | |
| 307 | - | <arg name="y" type="int" summary="damage y coordinate"/> | |
| 308 | - | <arg name="width" type="int" summary="damage width"/> | |
| 309 | - | <arg name="height" type="int" summary="damage height"/> | |
| 310 | - | </event> | |
| 311 | - | ||
| 312 | - | <event name="presentation_time"> | |
| 313 | - | <description summary="presentation time of the frame"> | |
| 314 | - | This event indicates the time at which the frame is presented to the | |
| 315 | - | output in system monotonic time. This event is sent before the ready | |
| 316 | - | event. | |
| 317 | - | ||
| 318 | - | The timestamp is expressed as tv_sec_hi, tv_sec_lo, tv_nsec triples, | |
| 319 | - | each component being an unsigned 32-bit value. Whole seconds are in | |
| 320 | - | tv_sec which is a 64-bit value combined from tv_sec_hi and tv_sec_lo, | |
| 321 | - | and the additional fractional part in tv_nsec as nanoseconds. Hence, | |
| 322 | - | for valid timestamps tv_nsec must be in [0, 999999999]. | |
| 323 | - | </description> | |
| 324 | - | <arg name="tv_sec_hi" type="uint" | |
| 325 | - | summary="high 32 bits of the seconds part of the timestamp"/> | |
| 326 | - | <arg name="tv_sec_lo" type="uint" | |
| 327 | - | summary="low 32 bits of the seconds part of the timestamp"/> | |
| 328 | - | <arg name="tv_nsec" type="uint" | |
| 329 | - | summary="nanoseconds part of the timestamp"/> | |
| 330 | - | </event> | |
| 331 | - | ||
| 332 | - | <event name="ready"> | |
| 333 | - | <description summary="frame is available for reading"> | |
| 334 | - | Called as soon as the frame is copied, indicating it is available | |
| 335 | - | for reading. | |
| 336 | - | ||
| 337 | - | The buffer may be re-used by the client after this event. | |
| 338 | - | ||
| 339 | - | After receiving this event, the client must destroy the object. | |
| 340 | - | </description> | |
| 341 | - | </event> | |
| 342 | - | ||
| 343 | - | <enum name="failure_reason"> | |
| 344 | - | <entry name="unknown" value="0"> | |
| 345 | - | <description summary="unknown runtime error"> | |
| 346 | - | An unspecified runtime error has occurred. The client may retry. | |
| 347 | - | </description> | |
| 348 | - | </entry> | |
| 349 | - | <entry name="buffer_constraints" value="1"> | |
| 350 | - | <description summary="buffer constraints mismatch"> | |
| 351 | - | The buffer submitted by the client doesn't match the latest session | |
| 352 | - | constraints. The client should re-allocate its buffers and retry. | |
| 353 | - | </description> | |
| 354 | - | </entry> | |
| 355 | - | <entry name="stopped" value="2"> | |
| 356 | - | <description summary="session is no longer available"> | |
| 357 | - | The session has stopped. See ext_image_copy_capture_session_v1.stopped. | |
| 358 | - | </description> | |
| 359 | - | </entry> | |
| 360 | - | </enum> | |
| 361 | - | ||
| 362 | - | <event name="failed"> | |
| 363 | - | <description summary="capture failed"> | |
| 364 | - | This event indicates that the attempted frame copy has failed. | |
| 365 | - | ||
| 366 | - | After receiving this event, the client must destroy the object. | |
| 367 | - | </description> | |
| 368 | - | <arg name="reason" type="uint" enum="failure_reason"/> | |
| 369 | - | </event> | |
| 370 | - | </interface> | |
| 371 | - | ||
| 372 | - | <interface name="ext_image_copy_capture_cursor_session_v1" version="1"> | |
| 373 | - | <description summary="cursor capture session"> | |
| 374 | - | This object represents a cursor capture session. It extends the base | |
| 375 | - | capture session with cursor-specific metadata. | |
| 376 | - | </description> | |
| 377 | - | ||
| 378 | - | <enum name="error"> | |
| 379 | - | <entry name="duplicate_session" value="1" summary="get_capture_session sent twice"/> | |
| 380 | - | </enum> | |
| 381 | - | ||
| 382 | - | <request name="destroy" type="destructor"> | |
| 383 | - | <description summary="delete this object"> | |
| 384 | - | Destroys the session. This request can be sent at any time by the | |
| 385 | - | client. | |
| 386 | - | ||
| 387 | - | This request doesn't affect ext_image_copy_capture_frame_v1 objects created by | |
| 388 | - | this object. | |
| 389 | - | </description> | |
| 390 | - | </request> | |
| 391 | - | ||
| 392 | - | <request name="get_capture_session"> | |
| 393 | - | <description summary="get image copy capturer session"> | |
| 394 | - | Gets the image copy capture session for this cursor session. | |
| 395 | - | ||
| 396 | - | The session will produce frames of the cursor image. The compositor may | |
| 397 | - | pause the session when the cursor leaves the captured area. | |
| 398 | - | ||
| 399 | - | This request must not be sent more than once, or else the | |
| 400 | - | duplicate_session protocol error is raised. | |
| 401 | - | </description> | |
| 402 | - | <arg name="session" type="new_id" interface="ext_image_copy_capture_session_v1"/> | |
| 403 | - | </request> | |
| 404 | - | ||
| 405 | - | <event name="enter"> | |
| 406 | - | <description summary="cursor entered captured area"> | |
| 407 | - | Sent when a cursor enters the captured area. It shall be generated | |
| 408 | - | before the "position" and "hotspot" events when and only when a cursor | |
| 409 | - | enters the area. | |
| 410 | - | ||
| 411 | - | The cursor enters the captured area when the cursor image intersects | |
| 412 | - | with the captured area. Note, this is different from e.g. | |
| 413 | - | wl_pointer.enter. | |
| 414 | - | </description> | |
| 415 | - | </event> | |
| 416 | - | ||
| 417 | - | <event name="leave"> | |
| 418 | - | <description summary="cursor left captured area"> | |
| 419 | - | Sent when a cursor leaves the captured area. No "position" or "hotspot" | |
| 420 | - | event is generated for the cursor until the cursor enters the captured | |
| 421 | - | area again. | |
| 422 | - | </description> | |
| 423 | - | </event> | |
| 424 | - | ||
| 425 | - | <event name="position"> | |
| 426 | - | <description summary="position changed"> | |
| 427 | - | Cursors outside the image capture source do not get captured and no | |
| 428 | - | event will be generated for them. | |
| 429 | - | ||
| 430 | - | The given position is the position of the cursor's hotspot and it is | |
| 431 | - | relative to the main buffer's top left corner in transformed buffer | |
| 432 | - | pixel coordinates. The coordinates may be negative or greater than the | |
| 433 | - | main buffer size. | |
| 434 | - | </description> | |
| 435 | - | <arg name="x" type="int" summary="position x coordinates"/> | |
| 436 | - | <arg name="y" type="int" summary="position y coordinates"/> | |
| 437 | - | </event> | |
| 438 | - | ||
| 439 | - | <event name="hotspot"> | |
| 440 | - | <description summary="hotspot changed"> | |
| 441 | - | The hotspot describes the offset between the cursor image and the | |
| 442 | - | position of the input device. | |
| 443 | - | ||
| 444 | - | The given coordinates are the hotspot's offset from the origin in | |
| 445 | - | buffer coordinates. | |
| 446 | - | ||
| 447 | - | Clients should not apply the hotspot immediately: the hotspot becomes | |
| 448 | - | effective when the next ext_image_copy_capture_frame_v1.ready event is received. | |
| 449 | - | ||
| 450 | - | Compositors may delay this event until the client captures a new frame. | |
| 451 | - | </description> | |
| 452 | - | <arg name="x" type="int" summary="hotspot x coordinates"/> | |
| 453 | - | <arg name="y" type="int" summary="hotspot y coordinates"/> | |
| 454 | - | </event> | |
| 455 | - | </interface> | |
| 456 | - | </protocol> | |
D protocol/imagecopycapture/ext-image-copy-capture-v1_generated.go +0 -796
| @@ -1,796 +0,0 @@ | |||
| 1 | - | // Code generated by wlturbo-scanner. DO NOT EDIT. | |
| 2 | - | // Protocol: ext_image_copy_capture_v1 | |
| 3 | - | // Source: ext-image-copy-capture-v1.xml | |
| 4 | - | ||
| 5 | - | // Upstream protocol copyright and license: | |
| 6 | - | // Copyright © 2021-2023 Andri Yngvason | |
| 7 | - | // Copyright © 2024 Simon Ser | |
| 8 | - | // | |
| 9 | - | // Permission is hereby granted, free of charge, to any person obtaining a | |
| 10 | - | // copy of this software and associated documentation files (the "Software"), | |
| 11 | - | // to deal in the Software without restriction, including without limitation | |
| 12 | - | // the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 13 | - | // and/or sell copies of the Software, and to permit persons to whom the | |
| 14 | - | // Software is furnished to do so, subject to the following conditions: | |
| 15 | - | // | |
| 16 | - | // The above copyright notice and this permission notice (including the next | |
| 17 | - | // paragraph) shall be included in all copies or substantial portions of the | |
| 18 | - | // Software. | |
| 19 | - | // | |
| 20 | - | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 21 | - | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 22 | - | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 23 | - | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 24 | - | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 25 | - | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
| 26 | - | // DEALINGS IN THE SOFTWARE. | |
| 27 | - | ||
| 28 | - | package imagecopycapture | |
| 29 | - | ||
| 30 | - | import ( | |
| 31 | - | "sync" | |
| 32 | - | ||
| 33 | - | cross_wl_buffer "github.com/bnema/wlturbo/protocol/core" | |
| 34 | - | cross_wl_pointer "github.com/bnema/wlturbo/protocol/core" | |
| 35 | - | cross_ext_image_capture_source_v1 "github.com/bnema/wlturbo/protocol/imagecapturesource" | |
| 36 | - | "github.com/bnema/wlturbo/wl" | |
| 37 | - | ) | |
| 38 | - | ||
| 39 | - | // ERROR_INVALID_OPTION is the error invalid_option value. | |
| 40 | - | const ERROR_INVALID_OPTION = 1 | |
| 41 | - | ||
| 42 | - | // OPTIONS_PAINT_CURSORS is the options paint_cursors value. | |
| 43 | - | const OPTIONS_PAINT_CURSORS = 1 | |
| 44 | - | ||
| 45 | - | // ERROR_DUPLICATE_FRAME is the error duplicate_frame value. | |
| 46 | - | const ERROR_DUPLICATE_FRAME = 1 | |
| 47 | - | ||
| 48 | - | // ERROR_NO_BUFFER is the error no_buffer value. | |
| 49 | - | const ERROR_NO_BUFFER = 1 | |
| 50 | - | ||
| 51 | - | // ERROR_INVALID_BUFFER_DAMAGE is the error invalid_buffer_damage value. | |
| 52 | - | const ERROR_INVALID_BUFFER_DAMAGE = 2 | |
| 53 | - | ||
| 54 | - | // ERROR_ALREADY_CAPTURED is the error already_captured value. | |
| 55 | - | const ERROR_ALREADY_CAPTURED = 3 | |
| 56 | - | ||
| 57 | - | // FAILURE_REASON_UNKNOWN is the failure_reason unknown value. | |
| 58 | - | const FAILURE_REASON_UNKNOWN = 0 | |
| 59 | - | ||
| 60 | - | // FAILURE_REASON_BUFFER_CONSTRAINTS is the failure_reason buffer_constraints value. | |
| 61 | - | const FAILURE_REASON_BUFFER_CONSTRAINTS = 1 | |
| 62 | - | ||
| 63 | - | // FAILURE_REASON_STOPPED is the failure_reason stopped value. | |
| 64 | - | const FAILURE_REASON_STOPPED = 2 | |
| 65 | - | ||
| 66 | - | // ERROR_DUPLICATE_SESSION is the error duplicate_session value. | |
| 67 | - | const ERROR_DUPLICATE_SESSION = 1 | |
| 68 | - | ||
| 69 | - | // ExtImageCopyCaptureManagerInterface is the protocol interface name. | |
| 70 | - | const ExtImageCopyCaptureManagerInterface = "ext_image_copy_capture_manager_v1" | |
| 71 | - | ||
| 72 | - | // ExtImageCopyCaptureManager is the generated binding for ext_image_copy_capture_manager_v1 version 1. | |
| 73 | - | type ExtImageCopyCaptureManager struct { | |
| 74 | - | wl.BaseProxy | |
| 75 | - | } | |
| 76 | - | ||
| 77 | - | // NewExtImageCopyCaptureManager returns an unbound ExtImageCopyCaptureManager. | |
| 78 | - | func NewExtImageCopyCaptureManager(ctx *wl.Context) *ExtImageCopyCaptureManager { | |
| 79 | - | obj := &ExtImageCopyCaptureManager{} | |
| 80 | - | obj.SetContext(ctx) | |
| 81 | - | ctx.Register(obj) | |
| 82 | - | return obj | |
| 83 | - | } | |
| 84 | - | ||
| 85 | - | // Create a capturing session for an image capture source. If the paint_cursors option is set, cursors shall be composited onto the captured frame. The cursor must not be composited onto the frame if this flag is not set. If the options bitfield is invalid, the invalid_option protocol error is sent. | |
| 86 | - | func (o *ExtImageCopyCaptureManager) CreateSession(source *cross_ext_image_capture_source_v1.ExtImageCaptureSource, options uint32) (*ExtImageCopyCaptureSession, error) { | |
| 87 | - | var arg1 wl.Object | |
| 88 | - | if source != nil { | |
| 89 | - | arg1 = source | |
| 90 | - | } | |
| 91 | - | child := &ExtImageCopyCaptureSession{} | |
| 92 | - | child.SetContext(o.Context()) | |
| 93 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "ext_image_copy_capture_manager_v1.create_session", Child: child}, wl.ArgObject(child), wl.ArgObject(arg1), wl.ArgUint(options)); err != nil { | |
| 94 | - | return nil, err | |
| 95 | - | } | |
| 96 | - | return child, nil | |
| 97 | - | } | |
| 98 | - | ||
| 99 | - | // Create a cursor capturing session for the pointer of an image capture source. | |
| 100 | - | func (o *ExtImageCopyCaptureManager) CreatePointerCursorSession(source *cross_ext_image_capture_source_v1.ExtImageCaptureSource, pointer *cross_wl_pointer.Pointer) (*ExtImageCopyCaptureCursorSession, error) { | |
| 101 | - | var arg1 wl.Object | |
| 102 | - | if source != nil { | |
| 103 | - | arg1 = source | |
| 104 | - | } | |
| 105 | - | var arg2 wl.Object | |
| 106 | - | if pointer != nil { | |
| 107 | - | arg2 = pointer | |
| 108 | - | } | |
| 109 | - | child := &ExtImageCopyCaptureCursorSession{} | |
| 110 | - | child.SetContext(o.Context()) | |
| 111 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "ext_image_copy_capture_manager_v1.create_pointer_cursor_session", Child: child}, wl.ArgObject(child), wl.ArgObject(arg1), wl.ArgObject(arg2)); err != nil { | |
| 112 | - | return nil, err | |
| 113 | - | } | |
| 114 | - | return child, nil | |
| 115 | - | } | |
| 116 | - | ||
| 117 | - | // Destroy the manager object. Other objects created via this interface are unaffected. | |
| 118 | - | func (o *ExtImageCopyCaptureManager) Destroy() error { | |
| 119 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 2, Name: "ext_image_copy_capture_manager_v1.destroy", Destructor: true}); err != nil { | |
| 120 | - | return err | |
| 121 | - | } | |
| 122 | - | return nil | |
| 123 | - | } | |
| 124 | - | ||
| 125 | - | // EventSignature returns the declared event argument types in wire order. | |
| 126 | - | func (o *ExtImageCopyCaptureManager) EventSignature(opcode uint16) (string, bool) { | |
| 127 | - | switch opcode { | |
| 128 | - | default: | |
| 129 | - | return "", false | |
| 130 | - | } | |
| 131 | - | } | |
| 132 | - | ||
| 133 | - | // Dispatch decodes one event on ext_image_copy_capture_manager_v1 and calls the registered handlers. | |
| 134 | - | func (o *ExtImageCopyCaptureManager) Dispatch(event *wl.Event) { | |
| 135 | - | switch event.Opcode { | |
| 136 | - | default: | |
| 137 | - | } | |
| 138 | - | } | |
| 139 | - | ||
| 140 | - | // ExtImageCopyCaptureSessionInterface is the protocol interface name. | |
| 141 | - | const ExtImageCopyCaptureSessionInterface = "ext_image_copy_capture_session_v1" | |
| 142 | - | ||
| 143 | - | // ExtImageCopyCaptureSession is the generated binding for ext_image_copy_capture_session_v1 version 1. | |
| 144 | - | type ExtImageCopyCaptureSession struct { | |
| 145 | - | wl.BaseProxy | |
| 146 | - | // handlersMu guards the handler slices: a client may register or replace | |
| 147 | - | // handlers while another goroutine dispatches events. | |
| 148 | - | handlersMu sync.Mutex | |
| 149 | - | onBufferSize []func(width uint32, height uint32) | |
| 150 | - | onShmFormat []func(format uint32) | |
| 151 | - | onDmabufDevice []func(device []byte) | |
| 152 | - | onDmabufFormat []func(format uint32, modifiers []byte) | |
| 153 | - | onDone []func() | |
| 154 | - | onStopped []func() | |
| 155 | - | } | |
| 156 | - | ||
| 157 | - | // NewExtImageCopyCaptureSession returns an unbound ExtImageCopyCaptureSession. | |
| 158 | - | func NewExtImageCopyCaptureSession(ctx *wl.Context) *ExtImageCopyCaptureSession { | |
| 159 | - | obj := &ExtImageCopyCaptureSession{} | |
| 160 | - | obj.SetContext(ctx) | |
| 161 | - | ctx.Register(obj) | |
| 162 | - | return obj | |
| 163 | - | } | |
| 164 | - | ||
| 165 | - | // Create a capture frame for this session. At most one frame object can exist for a given session at any time. If a client sends a create_frame request before a previous frame object has been destroyed, the duplicate_frame protocol error is raised. | |
| 166 | - | func (o *ExtImageCopyCaptureSession) CreateFrame() (*ExtImageCopyCaptureFrame, error) { | |
| 167 | - | child := &ExtImageCopyCaptureFrame{} | |
| 168 | - | child.SetContext(o.Context()) | |
| 169 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "ext_image_copy_capture_session_v1.create_frame", Child: child}, wl.ArgObject(child)); err != nil { | |
| 170 | - | return nil, err | |
| 171 | - | } | |
| 172 | - | return child, nil | |
| 173 | - | } | |
| 174 | - | ||
| 175 | - | // Destroys the session. This request can be sent at any time by the client. This request doesn't affect ext_image_copy_capture_frame_v1 objects created by this object. | |
| 176 | - | func (o *ExtImageCopyCaptureSession) Destroy() error { | |
| 177 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "ext_image_copy_capture_session_v1.destroy", Destructor: true}); err != nil { | |
| 178 | - | return err | |
| 179 | - | } | |
| 180 | - | return nil | |
| 181 | - | } | |
| 182 | - | ||
| 183 | - | // OnBufferSize registers a handler for the buffer_size event. | |
| 184 | - | // | |
| 185 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 186 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 187 | - | func (o *ExtImageCopyCaptureSession) OnBufferSize(handler func(width uint32, height uint32)) { | |
| 188 | - | if handler == nil { | |
| 189 | - | return | |
| 190 | - | } | |
| 191 | - | o.handlersMu.Lock() | |
| 192 | - | defer o.handlersMu.Unlock() | |
| 193 | - | o.onBufferSize = append(o.onBufferSize, handler) | |
| 194 | - | } | |
| 195 | - | ||
| 196 | - | // handlersForBufferSize returns the handlers registered for buffer_size, taken | |
| 197 | - | // under the lock so a handler may register another handler while events are | |
| 198 | - | // being dispatched. | |
| 199 | - | func (o *ExtImageCopyCaptureSession) handlersForBufferSize() []func(width uint32, height uint32) { | |
| 200 | - | o.handlersMu.Lock() | |
| 201 | - | defer o.handlersMu.Unlock() | |
| 202 | - | return o.onBufferSize | |
| 203 | - | } | |
| 204 | - | ||
| 205 | - | // OnShmFormat registers a handler for the shm_format event. | |
| 206 | - | // | |
| 207 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 208 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 209 | - | func (o *ExtImageCopyCaptureSession) OnShmFormat(handler func(format uint32)) { | |
| 210 | - | if handler == nil { | |
| 211 | - | return | |
| 212 | - | } | |
| 213 | - | o.handlersMu.Lock() | |
| 214 | - | defer o.handlersMu.Unlock() | |
| 215 | - | o.onShmFormat = append(o.onShmFormat, handler) | |
| 216 | - | } | |
| 217 | - | ||
| 218 | - | // handlersForShmFormat returns the handlers registered for shm_format, taken | |
| 219 | - | // under the lock so a handler may register another handler while events are | |
| 220 | - | // being dispatched. | |
| 221 | - | func (o *ExtImageCopyCaptureSession) handlersForShmFormat() []func(format uint32) { | |
| 222 | - | o.handlersMu.Lock() | |
| 223 | - | defer o.handlersMu.Unlock() | |
| 224 | - | return o.onShmFormat | |
| 225 | - | } | |
| 226 | - | ||
| 227 | - | // OnDmabufDevice registers a handler for the dmabuf_device event. | |
| 228 | - | // | |
| 229 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 230 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 231 | - | func (o *ExtImageCopyCaptureSession) OnDmabufDevice(handler func(device []byte)) { | |
| 232 | - | if handler == nil { | |
| 233 | - | return | |
| 234 | - | } | |
| 235 | - | o.handlersMu.Lock() | |
| 236 | - | defer o.handlersMu.Unlock() | |
| 237 | - | o.onDmabufDevice = append(o.onDmabufDevice, handler) | |
| 238 | - | } | |
| 239 | - | ||
| 240 | - | // handlersForDmabufDevice returns the handlers registered for dmabuf_device, taken | |
| 241 | - | // under the lock so a handler may register another handler while events are | |
| 242 | - | // being dispatched. | |
| 243 | - | func (o *ExtImageCopyCaptureSession) handlersForDmabufDevice() []func(device []byte) { | |
| 244 | - | o.handlersMu.Lock() | |
| 245 | - | defer o.handlersMu.Unlock() | |
| 246 | - | return o.onDmabufDevice | |
| 247 | - | } | |
| 248 | - | ||
| 249 | - | // OnDmabufFormat registers a handler for the dmabuf_format event. | |
| 250 | - | // | |
| 251 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 252 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 253 | - | func (o *ExtImageCopyCaptureSession) OnDmabufFormat(handler func(format uint32, modifiers []byte)) { | |
| 254 | - | if handler == nil { | |
| 255 | - | return | |
| 256 | - | } | |
| 257 | - | o.handlersMu.Lock() | |
| 258 | - | defer o.handlersMu.Unlock() | |
| 259 | - | o.onDmabufFormat = append(o.onDmabufFormat, handler) | |
| 260 | - | } | |
| 261 | - | ||
| 262 | - | // handlersForDmabufFormat returns the handlers registered for dmabuf_format, taken | |
| 263 | - | // under the lock so a handler may register another handler while events are | |
| 264 | - | // being dispatched. | |
| 265 | - | func (o *ExtImageCopyCaptureSession) handlersForDmabufFormat() []func(format uint32, modifiers []byte) { | |
| 266 | - | o.handlersMu.Lock() | |
| 267 | - | defer o.handlersMu.Unlock() | |
| 268 | - | return o.onDmabufFormat | |
| 269 | - | } | |
| 270 | - | ||
| 271 | - | // OnDone registers a handler for the done event. | |
| 272 | - | // | |
| 273 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 274 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 275 | - | func (o *ExtImageCopyCaptureSession) OnDone(handler func()) { | |
| 276 | - | if handler == nil { | |
| 277 | - | return | |
| 278 | - | } | |
| 279 | - | o.handlersMu.Lock() | |
| 280 | - | defer o.handlersMu.Unlock() | |
| 281 | - | o.onDone = append(o.onDone, handler) | |
| 282 | - | } | |
| 283 | - | ||
| 284 | - | // handlersForDone returns the handlers registered for done, taken | |
| 285 | - | // under the lock so a handler may register another handler while events are | |
| 286 | - | // being dispatched. | |
| 287 | - | func (o *ExtImageCopyCaptureSession) handlersForDone() []func() { | |
| 288 | - | o.handlersMu.Lock() | |
| 289 | - | defer o.handlersMu.Unlock() | |
| 290 | - | return o.onDone | |
| 291 | - | } | |
| 292 | - | ||
| 293 | - | // OnStopped registers a handler for the stopped event. | |
| 294 | - | // | |
| 295 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 296 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 297 | - | func (o *ExtImageCopyCaptureSession) OnStopped(handler func()) { | |
| 298 | - | if handler == nil { | |
| 299 | - | return | |
| 300 | - | } | |
| 301 | - | o.handlersMu.Lock() | |
| 302 | - | defer o.handlersMu.Unlock() | |
| 303 | - | o.onStopped = append(o.onStopped, handler) | |
| 304 | - | } | |
| 305 | - | ||
| 306 | - | // handlersForStopped returns the handlers registered for stopped, taken | |
| 307 | - | // under the lock so a handler may register another handler while events are | |
| 308 | - | // being dispatched. | |
| 309 | - | func (o *ExtImageCopyCaptureSession) handlersForStopped() []func() { | |
| 310 | - | o.handlersMu.Lock() | |
| 311 | - | defer o.handlersMu.Unlock() | |
| 312 | - | return o.onStopped | |
| 313 | - | } | |
| 314 | - | ||
| 315 | - | // EventSignature returns the declared event argument types in wire order. | |
| 316 | - | func (o *ExtImageCopyCaptureSession) EventSignature(opcode uint16) (string, bool) { | |
| 317 | - | switch opcode { | |
| 318 | - | case 0: | |
| 319 | - | return "uint,uint,", true | |
| 320 | - | case 1: | |
| 321 | - | return "uint,", true | |
| 322 | - | case 2: | |
| 323 | - | return "array,", true | |
| 324 | - | case 3: | |
| 325 | - | return "uint,array,", true | |
| 326 | - | case 4: | |
| 327 | - | return "", true | |
| 328 | - | case 5: | |
| 329 | - | return "", true | |
| 330 | - | default: | |
| 331 | - | return "", false | |
| 332 | - | } | |
| 333 | - | } | |
| 334 | - | ||
| 335 | - | // Dispatch decodes one event on ext_image_copy_capture_session_v1 and calls the registered handlers. | |
| 336 | - | func (o *ExtImageCopyCaptureSession) Dispatch(event *wl.Event) { | |
| 337 | - | switch event.Opcode { | |
| 338 | - | case 0: // buffer_size | |
| 339 | - | width := event.Uint32() | |
| 340 | - | height := event.Uint32() | |
| 341 | - | ||
| 342 | - | for i, handler := range o.handlersForBufferSize() { | |
| 343 | - | _ = i | |
| 344 | - | handler(width, height) | |
| 345 | - | } | |
| 346 | - | case 1: // shm_format | |
| 347 | - | format := event.Uint32() | |
| 348 | - | ||
| 349 | - | for i, handler := range o.handlersForShmFormat() { | |
| 350 | - | _ = i | |
| 351 | - | handler(format) | |
| 352 | - | } | |
| 353 | - | case 2: // dmabuf_device | |
| 354 | - | device := event.Array() | |
| 355 | - | ||
| 356 | - | for i, handler := range o.handlersForDmabufDevice() { | |
| 357 | - | _ = i | |
| 358 | - | handler(device) | |
| 359 | - | } | |
| 360 | - | case 3: // dmabuf_format | |
| 361 | - | format := event.Uint32() | |
| 362 | - | modifiers := event.Array() | |
| 363 | - | ||
| 364 | - | for i, handler := range o.handlersForDmabufFormat() { | |
| 365 | - | _ = i | |
| 366 | - | handler(format, modifiers) | |
| 367 | - | } | |
| 368 | - | case 4: // done | |
| 369 | - | ||
| 370 | - | for i, handler := range o.handlersForDone() { | |
| 371 | - | _ = i | |
| 372 | - | handler() | |
| 373 | - | } | |
| 374 | - | case 5: // stopped | |
| 375 | - | ||
| 376 | - | for i, handler := range o.handlersForStopped() { | |
| 377 | - | _ = i | |
| 378 | - | handler() | |
| 379 | - | } | |
| 380 | - | default: | |
| 381 | - | } | |
| 382 | - | } | |
| 383 | - | ||
| 384 | - | // ExtImageCopyCaptureFrameInterface is the protocol interface name. | |
| 385 | - | const ExtImageCopyCaptureFrameInterface = "ext_image_copy_capture_frame_v1" | |
| 386 | - | ||
| 387 | - | // ExtImageCopyCaptureFrame is the generated binding for ext_image_copy_capture_frame_v1 version 1. | |
| 388 | - | type ExtImageCopyCaptureFrame struct { | |
| 389 | - | wl.BaseProxy | |
| 390 | - | // handlersMu guards the handler slices: a client may register or replace | |
| 391 | - | // handlers while another goroutine dispatches events. | |
| 392 | - | handlersMu sync.Mutex | |
| 393 | - | onTransform []func(transform uint32) | |
| 394 | - | onDamage []func(x int32, y int32, width int32, height int32) | |
| 395 | - | onPresentationTime []func(tvSecHi uint32, tvSecLo uint32, tvNsec uint32) | |
| 396 | - | onReady []func() | |
| 397 | - | onFailed []func(reason uint32) | |
| 398 | - | } | |
| 399 | - | ||
| 400 | - | // NewExtImageCopyCaptureFrame returns an unbound ExtImageCopyCaptureFrame. | |
| 401 | - | func NewExtImageCopyCaptureFrame(ctx *wl.Context) *ExtImageCopyCaptureFrame { | |
| 402 | - | obj := &ExtImageCopyCaptureFrame{} | |
| 403 | - | obj.SetContext(ctx) | |
| 404 | - | ctx.Register(obj) | |
| 405 | - | return obj | |
| 406 | - | } | |
| 407 | - | ||
| 408 | - | // Destroys the frame. This request can be sent at any time by the client. | |
| 409 | - | func (o *ExtImageCopyCaptureFrame) Destroy() error { | |
| 410 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "ext_image_copy_capture_frame_v1.destroy", Destructor: true}); err != nil { | |
| 411 | - | return err | |
| 412 | - | } | |
| 413 | - | return nil | |
| 414 | - | } | |
| 415 | - | ||
| 416 | - | // Attach a buffer to the session. The wl_buffer.release request is unused. The new buffer replaces any previously attached buffer. This request must not be sent after capture, or else the already_captured protocol error is raised. | |
| 417 | - | func (o *ExtImageCopyCaptureFrame) AttachBuffer(buffer *cross_wl_buffer.Buffer) error { | |
| 418 | - | var arg0 wl.Object | |
| 419 | - | if buffer != nil { | |
| 420 | - | arg0 = buffer | |
| 421 | - | } | |
| 422 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "ext_image_copy_capture_frame_v1.attach_buffer"}, wl.ArgObject(arg0)); err != nil { | |
| 423 | - | return err | |
| 424 | - | } | |
| 425 | - | return nil | |
| 426 | - | } | |
| 427 | - | ||
| 428 | - | // Apply damage to the buffer which is to be captured next. This request may be sent multiple times to describe a region. The client indicates the accumulated damage since this wl_buffer was last captured. During capture, the compositor will update the buffer with at least the union of the region passed by the client and the region advertised by ext_image_copy_capture_frame_v1.damage. When a wl_buffer is captured for the first time, or when the client doesn't track damage, the client must damage the whole buffer. This is for optimisation purposes. The compositor may use this information to reduce copying. These coordinates originate from the upper left corner of the buffer. If x or y are strictly negative, or if width or height are negative or zero, the invalid_buffer_damage protocol error is raised. This request must not be sent after capture, or else the already_captured protocol error is raised. | |
| 429 | - | func (o *ExtImageCopyCaptureFrame) DamageBuffer(x int32, y int32, width int32, height int32) error { | |
| 430 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 2, Name: "ext_image_copy_capture_frame_v1.damage_buffer"}, wl.ArgInt(x), wl.ArgInt(y), wl.ArgInt(width), wl.ArgInt(height)); err != nil { | |
| 431 | - | return err | |
| 432 | - | } | |
| 433 | - | return nil | |
| 434 | - | } | |
| 435 | - | ||
| 436 | - | // Capture a frame. Unless this is the first successful captured frame performed in this session, the compositor may wait an indefinite amount of time for the source content to change before performing the copy. This request may only be sent once, or else the already_captured protocol error is raised. A buffer must be attached before this request is sent, or else the no_buffer protocol error is raised. | |
| 437 | - | func (o *ExtImageCopyCaptureFrame) Capture() error { | |
| 438 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 3, Name: "ext_image_copy_capture_frame_v1.capture"}); err != nil { | |
| 439 | - | return err | |
| 440 | - | } | |
| 441 | - | return nil | |
| 442 | - | } | |
| 443 | - | ||
| 444 | - | // OnTransform registers a handler for the transform event. | |
| 445 | - | // | |
| 446 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 447 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 448 | - | func (o *ExtImageCopyCaptureFrame) OnTransform(handler func(transform uint32)) { | |
| 449 | - | if handler == nil { | |
| 450 | - | return | |
| 451 | - | } | |
| 452 | - | o.handlersMu.Lock() | |
| 453 | - | defer o.handlersMu.Unlock() | |
| 454 | - | o.onTransform = append(o.onTransform, handler) | |
| 455 | - | } | |
| 456 | - | ||
| 457 | - | // handlersForTransform returns the handlers registered for transform, taken | |
| 458 | - | // under the lock so a handler may register another handler while events are | |
| 459 | - | // being dispatched. | |
| 460 | - | func (o *ExtImageCopyCaptureFrame) handlersForTransform() []func(transform uint32) { | |
| 461 | - | o.handlersMu.Lock() | |
| 462 | - | defer o.handlersMu.Unlock() | |
| 463 | - | return o.onTransform | |
| 464 | - | } | |
| 465 | - | ||
| 466 | - | // OnDamage registers a handler for the damage event. | |
| 467 | - | // | |
| 468 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 469 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 470 | - | func (o *ExtImageCopyCaptureFrame) OnDamage(handler func(x int32, y int32, width int32, height int32)) { | |
| 471 | - | if handler == nil { | |
| 472 | - | return | |
| 473 | - | } | |
| 474 | - | o.handlersMu.Lock() | |
| 475 | - | defer o.handlersMu.Unlock() | |
| 476 | - | o.onDamage = append(o.onDamage, handler) | |
| 477 | - | } | |
| 478 | - | ||
| 479 | - | // handlersForDamage returns the handlers registered for damage, taken | |
| 480 | - | // under the lock so a handler may register another handler while events are | |
| 481 | - | // being dispatched. | |
| 482 | - | func (o *ExtImageCopyCaptureFrame) handlersForDamage() []func(x int32, y int32, width int32, height int32) { | |
| 483 | - | o.handlersMu.Lock() | |
| 484 | - | defer o.handlersMu.Unlock() | |
| 485 | - | return o.onDamage | |
| 486 | - | } | |
| 487 | - | ||
| 488 | - | // OnPresentationTime registers a handler for the presentation_time event. | |
| 489 | - | // | |
| 490 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 491 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 492 | - | func (o *ExtImageCopyCaptureFrame) OnPresentationTime(handler func(tvSecHi uint32, tvSecLo uint32, tvNsec uint32)) { | |
| 493 | - | if handler == nil { | |
| 494 | - | return | |
| 495 | - | } | |
| 496 | - | o.handlersMu.Lock() | |
| 497 | - | defer o.handlersMu.Unlock() | |
| 498 | - | o.onPresentationTime = append(o.onPresentationTime, handler) | |
| 499 | - | } | |
| 500 | - | ||
| 501 | - | // handlersForPresentationTime returns the handlers registered for presentation_time, taken | |
| 502 | - | // under the lock so a handler may register another handler while events are | |
| 503 | - | // being dispatched. | |
| 504 | - | func (o *ExtImageCopyCaptureFrame) handlersForPresentationTime() []func(tvSecHi uint32, tvSecLo uint32, tvNsec uint32) { | |
| 505 | - | o.handlersMu.Lock() | |
| 506 | - | defer o.handlersMu.Unlock() | |
| 507 | - | return o.onPresentationTime | |
| 508 | - | } | |
| 509 | - | ||
| 510 | - | // OnReady registers a handler for the ready event. | |
| 511 | - | // | |
| 512 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 513 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 514 | - | func (o *ExtImageCopyCaptureFrame) OnReady(handler func()) { | |
| 515 | - | if handler == nil { | |
| 516 | - | return | |
| 517 | - | } | |
| 518 | - | o.handlersMu.Lock() | |
| 519 | - | defer o.handlersMu.Unlock() | |
| 520 | - | o.onReady = append(o.onReady, handler) | |
| 521 | - | } | |
| 522 | - | ||
| 523 | - | // handlersForReady returns the handlers registered for ready, taken | |
| 524 | - | // under the lock so a handler may register another handler while events are | |
| 525 | - | // being dispatched. | |
| 526 | - | func (o *ExtImageCopyCaptureFrame) handlersForReady() []func() { | |
| 527 | - | o.handlersMu.Lock() | |
| 528 | - | defer o.handlersMu.Unlock() | |
| 529 | - | return o.onReady | |
| 530 | - | } | |
| 531 | - | ||
| 532 | - | // OnFailed registers a handler for the failed event. | |
| 533 | - | // | |
| 534 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 535 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 536 | - | func (o *ExtImageCopyCaptureFrame) OnFailed(handler func(reason uint32)) { | |
| 537 | - | if handler == nil { | |
| 538 | - | return | |
| 539 | - | } | |
| 540 | - | o.handlersMu.Lock() | |
| 541 | - | defer o.handlersMu.Unlock() | |
| 542 | - | o.onFailed = append(o.onFailed, handler) | |
| 543 | - | } | |
| 544 | - | ||
| 545 | - | // handlersForFailed returns the handlers registered for failed, taken | |
| 546 | - | // under the lock so a handler may register another handler while events are | |
| 547 | - | // being dispatched. | |
| 548 | - | func (o *ExtImageCopyCaptureFrame) handlersForFailed() []func(reason uint32) { | |
| 549 | - | o.handlersMu.Lock() | |
| 550 | - | defer o.handlersMu.Unlock() | |
| 551 | - | return o.onFailed | |
| 552 | - | } | |
| 553 | - | ||
| 554 | - | // EventSignature returns the declared event argument types in wire order. | |
| 555 | - | func (o *ExtImageCopyCaptureFrame) EventSignature(opcode uint16) (string, bool) { | |
| 556 | - | switch opcode { | |
| 557 | - | case 0: | |
| 558 | - | return "uint,", true | |
| 559 | - | case 1: | |
| 560 | - | return "int,int,int,int,", true | |
| 561 | - | case 2: | |
| 562 | - | return "uint,uint,uint,", true | |
| 563 | - | case 3: | |
| 564 | - | return "", true | |
| 565 | - | case 4: | |
| 566 | - | return "uint,", true | |
| 567 | - | default: | |
| 568 | - | return "", false | |
| 569 | - | } | |
| 570 | - | } | |
| 571 | - | ||
| 572 | - | // Dispatch decodes one event on ext_image_copy_capture_frame_v1 and calls the registered handlers. | |
| 573 | - | func (o *ExtImageCopyCaptureFrame) Dispatch(event *wl.Event) { | |
| 574 | - | switch event.Opcode { | |
| 575 | - | case 0: // transform | |
| 576 | - | transform := event.Uint32() | |
| 577 | - | ||
| 578 | - | for i, handler := range o.handlersForTransform() { | |
| 579 | - | _ = i | |
| 580 | - | handler(transform) | |
| 581 | - | } | |
| 582 | - | case 1: // damage | |
| 583 | - | x := event.Int32() | |
| 584 | - | y := event.Int32() | |
| 585 | - | width := event.Int32() | |
| 586 | - | height := event.Int32() | |
| 587 | - | ||
| 588 | - | for i, handler := range o.handlersForDamage() { | |
| 589 | - | _ = i | |
| 590 | - | handler(x, y, width, height) | |
| 591 | - | } | |
| 592 | - | case 2: // presentation_time | |
| 593 | - | tvSecHi := event.Uint32() | |
| 594 | - | tvSecLo := event.Uint32() | |
| 595 | - | tvNsec := event.Uint32() | |
| 596 | - | ||
| 597 | - | for i, handler := range o.handlersForPresentationTime() { | |
| 598 | - | _ = i | |
| 599 | - | handler(tvSecHi, tvSecLo, tvNsec) | |
| 600 | - | } | |
| 601 | - | case 3: // ready | |
| 602 | - | ||
| 603 | - | for i, handler := range o.handlersForReady() { | |
| 604 | - | _ = i | |
| 605 | - | handler() | |
| 606 | - | } | |
| 607 | - | case 4: // failed | |
| 608 | - | reason := event.Uint32() | |
| 609 | - | ||
| 610 | - | for i, handler := range o.handlersForFailed() { | |
| 611 | - | _ = i | |
| 612 | - | handler(reason) | |
| 613 | - | } | |
| 614 | - | default: | |
| 615 | - | } | |
| 616 | - | } | |
| 617 | - | ||
| 618 | - | // ExtImageCopyCaptureCursorSessionInterface is the protocol interface name. | |
| 619 | - | const ExtImageCopyCaptureCursorSessionInterface = "ext_image_copy_capture_cursor_session_v1" | |
| 620 | - | ||
| 621 | - | // ExtImageCopyCaptureCursorSession is the generated binding for ext_image_copy_capture_cursor_session_v1 version 1. | |
| 622 | - | type ExtImageCopyCaptureCursorSession struct { | |
| 623 | - | wl.BaseProxy | |
| 624 | - | // handlersMu guards the handler slices: a client may register or replace | |
| 625 | - | // handlers while another goroutine dispatches events. | |
| 626 | - | handlersMu sync.Mutex | |
| 627 | - | onEnter []func() | |
| 628 | - | onLeave []func() | |
| 629 | - | onPosition []func(x int32, y int32) | |
| 630 | - | onHotspot []func(x int32, y int32) | |
| 631 | - | } | |
| 632 | - | ||
| 633 | - | // NewExtImageCopyCaptureCursorSession returns an unbound ExtImageCopyCaptureCursorSession. | |
| 634 | - | func NewExtImageCopyCaptureCursorSession(ctx *wl.Context) *ExtImageCopyCaptureCursorSession { | |
| 635 | - | obj := &ExtImageCopyCaptureCursorSession{} | |
| 636 | - | obj.SetContext(ctx) | |
| 637 | - | ctx.Register(obj) | |
| 638 | - | return obj | |
| 639 | - | } | |
| 640 | - | ||
| 641 | - | // Destroys the session. This request can be sent at any time by the client. This request doesn't affect ext_image_copy_capture_frame_v1 objects created by this object. | |
| 642 | - | func (o *ExtImageCopyCaptureCursorSession) Destroy() error { | |
| 643 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "ext_image_copy_capture_cursor_session_v1.destroy", Destructor: true}); err != nil { | |
| 644 | - | return err | |
| 645 | - | } | |
| 646 | - | return nil | |
| 647 | - | } | |
| 648 | - | ||
| 649 | - | // Gets the image copy capture session for this cursor session. The session will produce frames of the cursor image. The compositor may pause the session when the cursor leaves the captured area. This request must not be sent more than once, or else the duplicate_session protocol error is raised. | |
| 650 | - | func (o *ExtImageCopyCaptureCursorSession) GetCaptureSession() (*ExtImageCopyCaptureSession, error) { | |
| 651 | - | child := &ExtImageCopyCaptureSession{} | |
| 652 | - | child.SetContext(o.Context()) | |
| 653 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "ext_image_copy_capture_cursor_session_v1.get_capture_session", Child: child}, wl.ArgObject(child)); err != nil { | |
| 654 | - | return nil, err | |
| 655 | - | } | |
| 656 | - | return child, nil | |
| 657 | - | } | |
| 658 | - | ||
| 659 | - | // OnEnter registers a handler for the enter event. | |
| 660 | - | // | |
| 661 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 662 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 663 | - | func (o *ExtImageCopyCaptureCursorSession) OnEnter(handler func()) { | |
| 664 | - | if handler == nil { | |
| 665 | - | return | |
| 666 | - | } | |
| 667 | - | o.handlersMu.Lock() | |
| 668 | - | defer o.handlersMu.Unlock() | |
| 669 | - | o.onEnter = append(o.onEnter, handler) | |
| 670 | - | } | |
| 671 | - | ||
| 672 | - | // handlersForEnter returns the handlers registered for enter, taken | |
| 673 | - | // under the lock so a handler may register another handler while events are | |
| 674 | - | // being dispatched. | |
| 675 | - | func (o *ExtImageCopyCaptureCursorSession) handlersForEnter() []func() { | |
| 676 | - | o.handlersMu.Lock() | |
| 677 | - | defer o.handlersMu.Unlock() | |
| 678 | - | return o.onEnter | |
| 679 | - | } | |
| 680 | - | ||
| 681 | - | // OnLeave registers a handler for the leave event. | |
| 682 | - | // | |
| 683 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 684 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 685 | - | func (o *ExtImageCopyCaptureCursorSession) OnLeave(handler func()) { | |
| 686 | - | if handler == nil { | |
| 687 | - | return | |
| 688 | - | } | |
| 689 | - | o.handlersMu.Lock() | |
| 690 | - | defer o.handlersMu.Unlock() | |
| 691 | - | o.onLeave = append(o.onLeave, handler) | |
| 692 | - | } | |
| 693 | - | ||
| 694 | - | // handlersForLeave returns the handlers registered for leave, taken | |
| 695 | - | // under the lock so a handler may register another handler while events are | |
| 696 | - | // being dispatched. | |
| 697 | - | func (o *ExtImageCopyCaptureCursorSession) handlersForLeave() []func() { | |
| 698 | - | o.handlersMu.Lock() | |
| 699 | - | defer o.handlersMu.Unlock() | |
| 700 | - | return o.onLeave | |
| 701 | - | } | |
| 702 | - | ||
| 703 | - | // OnPosition registers a handler for the position event. | |
| 704 | - | // | |
| 705 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 706 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 707 | - | func (o *ExtImageCopyCaptureCursorSession) OnPosition(handler func(x int32, y int32)) { | |
| 708 | - | if handler == nil { | |
| 709 | - | return | |
| 710 | - | } | |
| 711 | - | o.handlersMu.Lock() | |
| 712 | - | defer o.handlersMu.Unlock() | |
| 713 | - | o.onPosition = append(o.onPosition, handler) | |
| 714 | - | } | |
| 715 | - | ||
| 716 | - | // handlersForPosition returns the handlers registered for position, taken | |
| 717 | - | // under the lock so a handler may register another handler while events are | |
| 718 | - | // being dispatched. | |
| 719 | - | func (o *ExtImageCopyCaptureCursorSession) handlersForPosition() []func(x int32, y int32) { | |
| 720 | - | o.handlersMu.Lock() | |
| 721 | - | defer o.handlersMu.Unlock() | |
| 722 | - | return o.onPosition | |
| 723 | - | } | |
| 724 | - | ||
| 725 | - | // OnHotspot registers a handler for the hotspot event. | |
| 726 | - | // | |
| 727 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 728 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 729 | - | func (o *ExtImageCopyCaptureCursorSession) OnHotspot(handler func(x int32, y int32)) { | |
| 730 | - | if handler == nil { | |
| 731 | - | return | |
| 732 | - | } | |
| 733 | - | o.handlersMu.Lock() | |
| 734 | - | defer o.handlersMu.Unlock() | |
| 735 | - | o.onHotspot = append(o.onHotspot, handler) | |
| 736 | - | } | |
| 737 | - | ||
| 738 | - | // handlersForHotspot returns the handlers registered for hotspot, taken | |
| 739 | - | // under the lock so a handler may register another handler while events are | |
| 740 | - | // being dispatched. | |
| 741 | - | func (o *ExtImageCopyCaptureCursorSession) handlersForHotspot() []func(x int32, y int32) { | |
| 742 | - | o.handlersMu.Lock() | |
| 743 | - | defer o.handlersMu.Unlock() | |
| 744 | - | return o.onHotspot | |
| 745 | - | } | |
| 746 | - | ||
| 747 | - | // EventSignature returns the declared event argument types in wire order. | |
| 748 | - | func (o *ExtImageCopyCaptureCursorSession) EventSignature(opcode uint16) (string, bool) { | |
| 749 | - | switch opcode { | |
| 750 | - | case 0: | |
| 751 | - | return "", true | |
| 752 | - | case 1: | |
| 753 | - | return "", true | |
| 754 | - | case 2: | |
| 755 | - | return "int,int,", true | |
| 756 | - | case 3: | |
| 757 | - | return "int,int,", true | |
| 758 | - | default: | |
| 759 | - | return "", false | |
| 760 | - | } | |
| 761 | - | } | |
| 762 | - | ||
| 763 | - | // Dispatch decodes one event on ext_image_copy_capture_cursor_session_v1 and calls the registered handlers. | |
| 764 | - | func (o *ExtImageCopyCaptureCursorSession) Dispatch(event *wl.Event) { | |
| 765 | - | switch event.Opcode { | |
| 766 | - | case 0: // enter | |
| 767 | - | ||
| 768 | - | for i, handler := range o.handlersForEnter() { | |
| 769 | - | _ = i | |
| 770 | - | handler() | |
| 771 | - | } | |
| 772 | - | case 1: // leave | |
| 773 | - | ||
| 774 | - | for i, handler := range o.handlersForLeave() { | |
| 775 | - | _ = i | |
| 776 | - | handler() | |
| 777 | - | } | |
| 778 | - | case 2: // position | |
| 779 | - | x := event.Int32() | |
| 780 | - | y := event.Int32() | |
| 781 | - | ||
| 782 | - | for i, handler := range o.handlersForPosition() { | |
| 783 | - | _ = i | |
| 784 | - | handler(x, y) | |
| 785 | - | } | |
| 786 | - | case 3: // hotspot | |
| 787 | - | x := event.Int32() | |
| 788 | - | y := event.Int32() | |
| 789 | - | ||
| 790 | - | for i, handler := range o.handlersForHotspot() { | |
| 791 | - | _ = i | |
| 792 | - | handler(x, y) | |
| 793 | - | } | |
| 794 | - | default: | |
| 795 | - | } | |
| 796 | - | } | |
D protocol/imagecopycapture/generate.go +0 -3
| @@ -1,3 +0,0 @@ | |||
| 1 | - | package imagecopycapture | |
| 2 | - | ||
| 3 | - | //go:generate go run ../../cmd/wlturbo-scanner -p imagecopycapture -o ext-image-copy-capture-v1_generated.go -import ext_image_capture_source_v1=github.com/bnema/wlturbo/protocol/imagecapturesource -import wl_buffer=github.com/bnema/wlturbo/protocol/core -import wl_pointer=github.com/bnema/wlturbo/protocol/core ext-image-copy-capture-v1.xml | |
D protocol/input_desktop_extensions_test.go +0 -726
| @@ -1,726 +0,0 @@ | |||
| 1 | - | //go:build linux | |
| 2 | - | ||
| 3 | - | package protocol_test | |
| 4 | - | ||
| 5 | - | import ( | |
| 6 | - | "encoding/binary" | |
| 7 | - | "errors" | |
| 8 | - | "os" | |
| 9 | - | "reflect" | |
| 10 | - | "testing" | |
| 11 | - | "time" | |
| 12 | - | ||
| 13 | - | "github.com/bnema/wlturbo" | |
| 14 | - | "github.com/bnema/wlturbo/protocol/datacontrol" | |
| 15 | - | "github.com/bnema/wlturbo/protocol/extforeigntoplevel" | |
| 16 | - | "github.com/bnema/wlturbo/protocol/idleinhibit" | |
| 17 | - | "github.com/bnema/wlturbo/protocol/idlenotify" | |
| 18 | - | "github.com/bnema/wlturbo/protocol/imagecapturesource" | |
| 19 | - | "github.com/bnema/wlturbo/protocol/imagecopycapture" | |
| 20 | - | "github.com/bnema/wlturbo/protocol/pointerconstraints" | |
| 21 | - | "github.com/bnema/wlturbo/protocol/primaryselection" | |
| 22 | - | "github.com/bnema/wlturbo/protocol/relativepointer" | |
| 23 | - | "github.com/bnema/wlturbo/protocol/shortcutsinhibit" | |
| 24 | - | "github.com/bnema/wlturbo/protocol/workspace" | |
| 25 | - | "github.com/bnema/wlturbo/protocol/xdgdecoration" | |
| 26 | - | "github.com/bnema/wlturbo/protocol/xdgoutput" | |
| 27 | - | "github.com/bnema/wlturbo/protocol/xdgshell" | |
| 28 | - | "golang.org/x/sys/unix" | |
| 29 | - | ) | |
| 30 | - | ||
| 31 | - | func TestRelativePointerMotionDecode(t *testing.T) { | |
| 32 | - | s := newWireEnv(t) | |
| 33 | - | ptr := s.pointer() | |
| 34 | - | mgr := relativepointer.NewRelativePointerManager(s.d.Context()) | |
| 35 | - | s.bind(1, relativepointer.RelativePointerManagerInterface, 1, 1, mgr) | |
| 36 | - | rp, e := mgr.GetRelativePointer(ptr) | |
| 37 | - | noerr(t, e) | |
| 38 | - | wantWords(t, "get_relative_pointer", s.req(mgr.ID(), 1), rp.ID(), ptr.ID()) | |
| 39 | - | ||
| 40 | - | type motion struct { | |
| 41 | - | hi, lo uint32 | |
| 42 | - | dx, dy, ux, uy wlturbo.Fixed | |
| 43 | - | } | |
| 44 | - | var got []motion | |
| 45 | - | rp.OnRelativeMotion(func(hi, lo uint32, dx, dy, ux, uy wlturbo.Fixed) { | |
| 46 | - | got = append(got, motion{hi, lo, dx, dy, ux, uy}) | |
| 47 | - | }) | |
| 48 | - | // 64-bit microsecond timestamp split in two words; negative deltas must | |
| 49 | - | // keep their sign through the 24.8 fixed-point decode. | |
| 50 | - | want := motion{1, 0x89abcdef, wlturbo.NewFixed(-1.5), wlturbo.NewFixed(2.25), wlturbo.NewFixed(-3), wlturbo.NewFixed(0.5)} | |
| 51 | - | s.event(rp.ID(), 0, wordBytes(want.hi, want.lo, uint32(want.dx), uint32(want.dy), uint32(want.ux), uint32(want.uy))...) | |
| 52 | - | if len(got) != 1 || got[0] != want { | |
| 53 | - | t.Fatalf("motion %+v, want %+v", got, want) | |
| 54 | - | } | |
| 55 | - | if got[0].dx.Float64() != -1.5 || got[0].dy.Float64() != 2.25 { | |
| 56 | - | t.Fatalf("fixed decode %v %v", got[0].dx.Float64(), got[0].dy.Float64()) | |
| 57 | - | } | |
| 58 | - | // Two handlers are both called, in registration order. | |
| 59 | - | var order []int | |
| 60 | - | rp.OnRelativeMotion(func(_, _ uint32, _, _, _, _ wlturbo.Fixed) { order = append(order, 1) }) | |
| 61 | - | rp.OnRelativeMotion(func(_, _ uint32, _, _, _, _ wlturbo.Fixed) { order = append(order, 2) }) | |
| 62 | - | s.event(rp.ID(), 0, wordBytes(0, 1, 0, 0, 0, 0)...) | |
| 63 | - | if !reflect.DeepEqual(order, []int{1, 2}) || len(got) != 2 { | |
| 64 | - | t.Fatalf("handlers order=%v motions=%d", order, len(got)) | |
| 65 | - | } | |
| 66 | - | noerr(t, rp.Destroy()) | |
| 67 | - | s.req(rp.ID(), 0) | |
| 68 | - | noerr(t, mgr.Destroy()) | |
| 69 | - | s.req(mgr.ID(), 0) | |
| 70 | - | } | |
| 71 | - | ||
| 72 | - | func TestPointerConstraintsNullableRegion(t *testing.T) { | |
| 73 | - | s := newWireEnv(t) | |
| 74 | - | surf, ptr := s.surface(), s.pointer() | |
| 75 | - | pc := pointerconstraints.NewPointerConstraints(s.d.Context()) | |
| 76 | - | s.bind(1, pointerconstraints.PointerConstraintsInterface, 1, 1, pc) | |
| 77 | - | ||
| 78 | - | // A null region means "use the surface input region" and is wire id 0. | |
| 79 | - | lock, e := pc.LockPointer(surf, ptr, nil, pointerconstraints.LIFETIME_PERSISTENT) | |
| 80 | - | noerr(t, e) | |
| 81 | - | wantWords(t, "lock_pointer(nil)", s.req(pc.ID(), 1), lock.ID(), surf.ID(), ptr.ID(), 0, pointerconstraints.LIFETIME_PERSISTENT) | |
| 82 | - | ||
| 83 | - | reg := s.region() | |
| 84 | - | conf, e := pc.ConfinePointer(surf, ptr, reg, pointerconstraints.LIFETIME_ONESHOT) | |
| 85 | - | noerr(t, e) | |
| 86 | - | wantWords(t, "confine_pointer(region)", s.req(pc.ID(), 2), conf.ID(), surf.ID(), ptr.ID(), reg.ID(), pointerconstraints.LIFETIME_ONESHOT) | |
| 87 | - | ||
| 88 | - | noerr(t, lock.SetCursorPositionHint(wlturbo.NewFixed(10.5), wlturbo.NewFixed(-2))) | |
| 89 | - | wantWords(t, "set_cursor_position_hint", s.req(lock.ID(), 1), uint32(wlturbo.NewFixed(10.5)), uint32(wlturbo.NewFixed(-2))) | |
| 90 | - | noerr(t, lock.SetRegion(nil)) | |
| 91 | - | wantWords(t, "locked.set_region(nil)", s.req(lock.ID(), 2), 0) | |
| 92 | - | noerr(t, lock.SetRegion(reg)) | |
| 93 | - | wantWords(t, "locked.set_region", s.req(lock.ID(), 2), reg.ID()) | |
| 94 | - | noerr(t, conf.SetRegion(nil)) | |
| 95 | - | wantWords(t, "confined.set_region(nil)", s.req(conf.ID(), 1), 0) | |
| 96 | - | ||
| 97 | - | var seq []string | |
| 98 | - | lock.OnLocked(func() { seq = append(seq, "locked") }) | |
| 99 | - | lock.OnUnlocked(func() { seq = append(seq, "unlocked") }) | |
| 100 | - | conf.OnConfined(func() { seq = append(seq, "confined") }) | |
| 101 | - | conf.OnUnconfined(func() { seq = append(seq, "unconfined") }) | |
| 102 | - | s.event(lock.ID(), 0) | |
| 103 | - | s.event(lock.ID(), 1) | |
| 104 | - | s.event(conf.ID(), 0) | |
| 105 | - | s.event(conf.ID(), 1) | |
| 106 | - | if !reflect.DeepEqual(seq, []string{"locked", "unlocked", "confined", "unconfined"}) { | |
| 107 | - | t.Fatal(seq) | |
| 108 | - | } | |
| 109 | - | noerr(t, lock.Destroy()) | |
| 110 | - | s.req(lock.ID(), 0) | |
| 111 | - | noerr(t, conf.Destroy()) | |
| 112 | - | s.req(conf.ID(), 0) | |
| 113 | - | noerr(t, pc.Destroy()) | |
| 114 | - | s.req(pc.ID(), 0) | |
| 115 | - | } | |
| 116 | - | ||
| 117 | - | // rawPipe returns a pipe as plain descriptors. An *os.File would close a reused | |
| 118 | - | // descriptor number on Close after the binding already closed the original. | |
| 119 | - | func rawPipe(t *testing.T) (*os.File, int) { | |
| 120 | - | t.Helper() | |
| 121 | - | var fds [2]int | |
| 122 | - | noerr(t, unix.Pipe2(fds[:], unix.O_CLOEXEC)) | |
| 123 | - | r := os.NewFile(uintptr(fds[0]), "pipe-r") | |
| 124 | - | t.Cleanup(func() { r.Close() }) | |
| 125 | - | return r, fds[1] | |
| 126 | - | } | |
| 127 | - | ||
| 128 | - | func TestPrimarySelectionNewIDAndFDOwnership(t *testing.T) { | |
| 129 | - | s := newWireEnv(t) | |
| 130 | - | seat := s.seat() | |
| 131 | - | mgr := primaryselection.NewPrimarySelectionDeviceManager(s.d.Context()) | |
| 132 | - | s.bind(1, primaryselection.PrimarySelectionDeviceManagerInterface, 1, 1, mgr) | |
| 133 | - | dev, e := mgr.GetDevice(seat) | |
| 134 | - | noerr(t, e) | |
| 135 | - | wantWords(t, "get_device", s.req(mgr.ID(), 1), dev.ID(), seat.ID()) | |
| 136 | - | src, e := mgr.CreateSource() | |
| 137 | - | noerr(t, e) | |
| 138 | - | wantWords(t, "create_source", s.req(mgr.ID(), 0), src.ID()) | |
| 139 | - | noerr(t, src.Offer("text/plain")) | |
| 140 | - | s.req(src.ID(), 0) | |
| 141 | - | noerr(t, dev.SetSelection(src, 77)) | |
| 142 | - | wantWords(t, "set_selection", s.req(dev.ID(), 0), src.ID(), 77) | |
| 143 | - | noerr(t, dev.SetSelection(nil, 78)) | |
| 144 | - | wantWords(t, "set_selection(nil)", s.req(dev.ID(), 0), 0, 78) | |
| 145 | - | ||
| 146 | - | // data_offer carries a server-allocated new_id which must come back as a | |
| 147 | - | // typed, registered child inheriting the device version. | |
| 148 | - | var offer *primaryselection.PrimarySelectionOffer | |
| 149 | - | var mimes []string | |
| 150 | - | dev.OnDataOffer(func(o *primaryselection.PrimarySelectionOffer) { | |
| 151 | - | offer = o | |
| 152 | - | o.OnOffer(func(m string) { mimes = append(mimes, m) }) | |
| 153 | - | }) | |
| 154 | - | var selected []uint32 | |
| 155 | - | dev.OnSelection(func(id uint32) { selected = append(selected, id) }) | |
| 156 | - | s.event(dev.ID(), 0, wordBytes(serverID+1)...) | |
| 157 | - | if offer == nil || offer.ID() != serverID+1 || offer.Version() != dev.Version() { | |
| 158 | - | t.Fatalf("offer %+v", offer) | |
| 159 | - | } | |
| 160 | - | s.event(offer.ID(), 0, str("text/plain")...) | |
| 161 | - | s.event(dev.ID(), 1, wordBytes(offer.ID())...) | |
| 162 | - | s.event(dev.ID(), 1, wordBytes(0)...) // null selection | |
| 163 | - | if !reflect.DeepEqual(mimes, []string{"text/plain"}) || !reflect.DeepEqual(selected, []uint32{offer.ID(), 0}) { | |
| 164 | - | t.Fatalf("mimes=%v selected=%v", mimes, selected) | |
| 165 | - | } | |
| 166 | - | ||
| 167 | - | // Client -> compositor: the sent descriptor is duplicated by the kernel and | |
| 168 | - | // the client's copy is closed by the binding. | |
| 169 | - | r, w := rawPipe(t) | |
| 170 | - | noerr(t, offer.Receive("text/plain", w)) | |
| 171 | - | // Check before reading the request: the received duplicate may reuse the | |
| 172 | - | // number of the descriptor the client just closed. | |
| 173 | - | requireFDClosed(t, w) | |
| 174 | - | body, fd := s.reqFD(offer.ID(), 0) | |
| 175 | - | // Closed explicitly below; the guard covers early t.Fatal paths only. | |
| 176 | - | defer func() { | |
| 177 | - | if fd >= 0 { | |
| 178 | - | unix.Close(fd) | |
| 179 | - | } | |
| 180 | - | }() | |
| 181 | - | if len(body) < 4 { | |
| 182 | - | t.Fatalf("receive body %x", body) | |
| 183 | - | } | |
| 184 | - | _, e = unix.Write(fd, []byte("payload")) | |
| 185 | - | noerr(t, e) | |
| 186 | - | noerr(t, unix.Close(fd)) | |
| 187 | - | fd = -1 | |
| 188 | - | buf := make([]byte, 16) | |
| 189 | - | n, e := r.Read(buf) | |
| 190 | - | noerr(t, e) | |
| 191 | - | if string(buf[:n]) != "payload" { | |
| 192 | - | t.Fatalf("payload %q", buf[:n]) | |
| 193 | - | } | |
| 194 | - | ||
| 195 | - | // Compositor -> client: source.send hands over an owned descriptor. | |
| 196 | - | var taken, ignored *wlturbo.OwnedFD | |
| 197 | - | var sendMimes []string | |
| 198 | - | src.OnSend(func(m string, f *wlturbo.OwnedFD) { | |
| 199 | - | sendMimes = append(sendMimes, m) | |
| 200 | - | if taken == nil { | |
| 201 | - | taken = f | |
| 202 | - | n, e := f.Take() | |
| 203 | - | noerr(t, e) | |
| 204 | - | _, e = unix.Write(n, []byte("from-client")) | |
| 205 | - | noerr(t, e) | |
| 206 | - | unix.Close(n) | |
| 207 | - | return | |
| 208 | - | } | |
| 209 | - | ignored = f // deliberately neither taken nor closed | |
| 210 | - | }) | |
| 211 | - | sr, sw, e := os.Pipe() | |
| 212 | - | noerr(t, e) | |
| 213 | - | send(t, s.p, payload(src.ID(), 0, str("text/plain")...), int(sw.Fd())) | |
| 214 | - | s.dispatch() | |
| 215 | - | sw.Close() | |
| 216 | - | n, e = sr.Read(buf) | |
| 217 | - | noerr(t, e) | |
| 218 | - | if string(buf[:n]) != "from-client" { | |
| 219 | - | t.Fatalf("source payload %q", buf[:n]) | |
| 220 | - | } | |
| 221 | - | if _, e := taken.Take(); e == nil { | |
| 222 | - | t.Fatal("second Take on a taken descriptor must fail") | |
| 223 | - | } | |
| 224 | - | sr.Close() | |
| 225 | - | // An unclaimed descriptor is closed by the transport when dispatch ends, | |
| 226 | - | // so the pipe reader sees EOF although the handler never closed it. | |
| 227 | - | pr, pw, e := os.Pipe() | |
| 228 | - | noerr(t, e) | |
| 229 | - | defer pr.Close() | |
| 230 | - | send(t, s.p, payload(src.ID(), 0, str("text/html")...), int(pw.Fd())) | |
| 231 | - | pw.Close() // only the in-flight duplicate keeps the write end alive | |
| 232 | - | s.dispatch() | |
| 233 | - | if ignored == nil || len(sendMimes) != 2 { | |
| 234 | - | t.Fatalf("send events %v", sendMimes) | |
| 235 | - | } | |
| 236 | - | if _, e := ignored.Take(); e == nil { | |
| 237 | - | t.Fatal("unclaimed descriptor must be closed after dispatch, but Take succeeded") | |
| 238 | - | } | |
| 239 | - | pr.SetReadDeadline(time.Now().Add(2 * time.Second)) | |
| 240 | - | if n, e := pr.Read(buf); n != 0 || e == nil { | |
| 241 | - | t.Fatalf("unclaimed descriptor still open: n=%d err=%v", n, e) | |
| 242 | - | } | |
| 243 | - | var cancelled bool | |
| 244 | - | src.OnCancelled(func() { cancelled = true }) | |
| 245 | - | s.event(src.ID(), 1) | |
| 246 | - | if !cancelled { | |
| 247 | - | t.Fatal("cancelled not delivered") | |
| 248 | - | } | |
| 249 | - | noerr(t, offer.Destroy()) | |
| 250 | - | s.req(offer.ID(), 1) | |
| 251 | - | noerr(t, src.Destroy()) | |
| 252 | - | s.req(src.ID(), 1) | |
| 253 | - | noerr(t, dev.Destroy()) | |
| 254 | - | s.req(dev.ID(), 1) | |
| 255 | - | noerr(t, mgr.Destroy()) | |
| 256 | - | s.req(mgr.ID(), 2) | |
| 257 | - | } | |
| 258 | - | ||
| 259 | - | func TestDataControlNewIDAndFDOwnership(t *testing.T) { | |
| 260 | - | s := newWireEnv(t) | |
| 261 | - | seat := s.seat() | |
| 262 | - | mgr := datacontrol.NewExtDataControlManager(s.d.Context()) | |
| 263 | - | s.bind(1, datacontrol.ExtDataControlManagerInterface, 1, 1, mgr) | |
| 264 | - | dev, e := mgr.GetDataDevice(seat) | |
| 265 | - | noerr(t, e) | |
| 266 | - | wantWords(t, "get_data_device", s.req(mgr.ID(), 1), dev.ID(), seat.ID()) | |
| 267 | - | src, e := mgr.CreateDataSource() | |
| 268 | - | noerr(t, e) | |
| 269 | - | wantWords(t, "create_data_source", s.req(mgr.ID(), 0), src.ID()) | |
| 270 | - | noerr(t, dev.SetSelection(src)) | |
| 271 | - | wantWords(t, "set_selection", s.req(dev.ID(), 0), src.ID()) | |
| 272 | - | noerr(t, dev.SetPrimarySelection(nil)) | |
| 273 | - | wantWords(t, "set_primary_selection(nil)", s.req(dev.ID(), 2), 0) | |
| 274 | - | ||
| 275 | - | var offers []*datacontrol.ExtDataControlOffer | |
| 276 | - | dev.OnDataOffer(func(o *datacontrol.ExtDataControlOffer) { offers = append(offers, o) }) | |
| 277 | - | var sel, primary []uint32 | |
| 278 | - | dev.OnSelection(func(id uint32) { sel = append(sel, id) }) | |
| 279 | - | dev.OnPrimarySelection(func(id uint32) { primary = append(primary, id) }) | |
| 280 | - | var finished bool | |
| 281 | - | dev.OnFinished(func() { finished = true }) | |
| 282 | - | s.event(dev.ID(), 0, wordBytes(serverID+1)...) | |
| 283 | - | s.event(dev.ID(), 0, wordBytes(serverID+2)...) | |
| 284 | - | if len(offers) != 2 || offers[0].ID() != serverID+1 || offers[1].ID() != serverID+2 { | |
| 285 | - | t.Fatalf("offers %+v", offers) | |
| 286 | - | } | |
| 287 | - | s.event(dev.ID(), 1, wordBytes(serverID+1)...) | |
| 288 | - | s.event(dev.ID(), 3, wordBytes(serverID+2)...) | |
| 289 | - | s.event(dev.ID(), 3, wordBytes(0)...) | |
| 290 | - | if !reflect.DeepEqual(sel, []uint32{serverID + 1}) || !reflect.DeepEqual(primary, []uint32{serverID + 2, 0}) { | |
| 291 | - | t.Fatalf("sel=%v primary=%v", sel, primary) | |
| 292 | - | } | |
| 293 | - | var mime string | |
| 294 | - | offers[0].OnOffer(func(m string) { mime = m }) | |
| 295 | - | s.event(offers[0].ID(), 0, str("text/uri-list")...) | |
| 296 | - | if mime != "text/uri-list" { | |
| 297 | - | t.Fatal(mime) | |
| 298 | - | } | |
| 299 | - | ||
| 300 | - | r, w := rawPipe(t) | |
| 301 | - | noerr(t, offers[0].Receive("text/uri-list", w)) | |
| 302 | - | requireFDClosed(t, w) | |
| 303 | - | _, fd := s.reqFD(offers[0].ID(), 0) | |
| 304 | - | unix.Close(fd) | |
| 305 | - | buf := make([]byte, 8) | |
| 306 | - | if n, e := r.Read(buf); n != 0 || e == nil { | |
| 307 | - | t.Fatalf("expected EOF once both write ends closed, n=%d err=%v", n, e) | |
| 308 | - | } | |
| 309 | - | ||
| 310 | - | // source.send: the handler owns the descriptor and can Close it early. | |
| 311 | - | var closedByHandler bool | |
| 312 | - | src.OnSend(func(m string, f *wlturbo.OwnedFD) { | |
| 313 | - | noerr(t, f.Close()) | |
| 314 | - | noerr(t, f.Close()) // idempotent | |
| 315 | - | if _, e := f.Take(); e == nil { | |
| 316 | - | t.Error("Take after Close must fail") | |
| 317 | - | } | |
| 318 | - | closedByHandler = true | |
| 319 | - | }) | |
| 320 | - | pr, pw, e := os.Pipe() | |
| 321 | - | noerr(t, e) | |
| 322 | - | defer pr.Close() | |
| 323 | - | send(t, s.p, payload(src.ID(), 0, str("text/plain")...), int(pw.Fd())) | |
| 324 | - | pw.Close() | |
| 325 | - | s.dispatch() | |
| 326 | - | pr.SetReadDeadline(time.Now().Add(2 * time.Second)) | |
| 327 | - | if n, e := pr.Read(buf); !closedByHandler || n != 0 || e == nil { | |
| 328 | - | t.Fatalf("closed=%v n=%d err=%v", closedByHandler, n, e) | |
| 329 | - | } | |
| 330 | - | s.event(dev.ID(), 2) | |
| 331 | - | if !finished { | |
| 332 | - | t.Fatal("finished not delivered") | |
| 333 | - | } | |
| 334 | - | noerr(t, src.Offer("text/plain")) | |
| 335 | - | s.req(src.ID(), 0) | |
| 336 | - | noerr(t, offers[0].Destroy()) | |
| 337 | - | s.req(offers[0].ID(), 1) | |
| 338 | - | noerr(t, src.Destroy()) | |
| 339 | - | s.req(src.ID(), 1) | |
| 340 | - | noerr(t, dev.Destroy()) | |
| 341 | - | s.req(dev.ID(), 1) | |
| 342 | - | noerr(t, mgr.Destroy()) | |
| 343 | - | s.req(mgr.ID(), 2) | |
| 344 | - | } | |
| 345 | - | ||
| 346 | - | func TestWorkspaceLifecycle(t *testing.T) { | |
| 347 | - | s := newWireEnv(t) | |
| 348 | - | out := s.output() | |
| 349 | - | mgr := workspace.NewExtWorkspaceManager(s.d.Context()) | |
| 350 | - | s.bind(1, workspace.ExtWorkspaceManagerInterface, 1, 1, mgr) | |
| 351 | - | ||
| 352 | - | var groups []*workspace.ExtWorkspaceGroupHandle | |
| 353 | - | var spaces []*workspace.ExtWorkspaceHandle | |
| 354 | - | var log []string | |
| 355 | - | mgr.OnWorkspaceGroup(func(g *workspace.ExtWorkspaceGroupHandle) { groups = append(groups, g) }) | |
| 356 | - | mgr.OnWorkspace(func(w *workspace.ExtWorkspaceHandle) { spaces = append(spaces, w) }) | |
| 357 | - | mgr.OnDone(func() { log = append(log, "done") }) | |
| 358 | - | mgr.OnFinished(func() { log = append(log, "finished") }) | |
| 359 | - | ||
| 360 | - | s.event(mgr.ID(), 0, wordBytes(serverID+1)...) | |
| 361 | - | s.event(mgr.ID(), 1, wordBytes(serverID+2)...) | |
| 362 | - | if len(groups) != 1 || len(spaces) != 1 || groups[0].ID() != serverID+1 || spaces[0].ID() != serverID+2 { | |
| 363 | - | t.Fatal("typed children missing") | |
| 364 | - | } | |
| 365 | - | g, w := groups[0], spaces[0] | |
| 366 | - | var gcaps, wcaps, state uint32 | |
| 367 | - | var outs, entered []uint32 | |
| 368 | - | var id, name string | |
| 369 | - | var coords []byte | |
| 370 | - | g.OnCapabilities(func(c uint32) { gcaps = c }) | |
| 371 | - | g.OnOutputEnter(func(o uint32) { outs = append(outs, o) }) | |
| 372 | - | g.OnWorkspaceEnter(func(x uint32) { entered = append(entered, x) }) | |
| 373 | - | g.OnRemoved(func() { log = append(log, "group-removed") }) | |
| 374 | - | w.OnId(func(v string) { id = v }) | |
| 375 | - | w.OnName(func(v string) { name = v }) | |
| 376 | - | w.OnCoordinates(func(c []byte) { coords = c }) | |
| 377 | - | w.OnState(func(v uint32) { state = v }) | |
| 378 | - | w.OnCapabilities(func(v uint32) { wcaps = v }) | |
| 379 | - | w.OnRemoved(func() { log = append(log, "workspace-removed") }) | |
| 380 | - | ||
| 381 | - | s.event(g.ID(), 0, wordBytes(workspace.GROUP_CAPABILITIES_CREATE_WORKSPACE)...) | |
| 382 | - | s.event(g.ID(), 1, wordBytes(out.ID())...) | |
| 383 | - | s.event(g.ID(), 3, wordBytes(w.ID())...) | |
| 384 | - | s.event(w.ID(), 0, str("ws-1")...) | |
| 385 | - | s.event(w.ID(), 1, str("Workspace é")...) | |
| 386 | - | s.event(w.ID(), 2, arr(wordBytes(1, 2))...) | |
| 387 | - | s.event(w.ID(), 3, wordBytes(workspace.STATE_ACTIVE|workspace.STATE_URGENT)...) | |
| 388 | - | s.event(w.ID(), 4, wordBytes(workspace.WORKSPACE_CAPABILITIES_ACTIVATE|workspace.WORKSPACE_CAPABILITIES_ASSIGN)...) | |
| 389 | - | s.event(mgr.ID(), 2) | |
| 390 | - | if gcaps != workspace.GROUP_CAPABILITIES_CREATE_WORKSPACE || !reflect.DeepEqual(outs, []uint32{out.ID()}) || !reflect.DeepEqual(entered, []uint32{w.ID()}) || | |
| 391 | - | id != "ws-1" || name != "Workspace é" || !reflect.DeepEqual(decodeWords(coords), []uint32{1, 2}) || | |
| 392 | - | state != 3 || wcaps != 9 || !reflect.DeepEqual(log, []string{"done"}) { | |
| 393 | - | t.Fatalf("state gcaps=%d outs=%v entered=%v id=%q name=%q coords=%v state=%d wcaps=%d log=%v", gcaps, outs, entered, id, name, coords, state, wcaps, log) | |
| 394 | - | } | |
| 395 | - | ||
| 396 | - | // Requests are only transactional after commit, so the wire order is | |
| 397 | - | // request, request, commit. | |
| 398 | - | noerr(t, w.Activate()) | |
| 399 | - | s.req(w.ID(), 1) | |
| 400 | - | noerr(t, w.Assign(g)) | |
| 401 | - | wantWords(t, "assign", s.req(w.ID(), 3), g.ID()) | |
| 402 | - | noerr(t, g.CreateWorkspace("new")) | |
| 403 | - | if b := s.req(g.ID(), 0); binary.NativeEndian.Uint32(b) != 4 || string(b[4:7]) != "new" { | |
| 404 | - | t.Fatalf("create_workspace %x", b) | |
| 405 | - | } | |
| 406 | - | noerr(t, w.Deactivate()) | |
| 407 | - | s.req(w.ID(), 2) | |
| 408 | - | noerr(t, w.Remove()) | |
| 409 | - | s.req(w.ID(), 4) | |
| 410 | - | noerr(t, mgr.Commit()) | |
| 411 | - | s.req(mgr.ID(), 0) | |
| 412 | - | ||
| 413 | - | // Removal: the compositor sends removed, the client answers with destroy. | |
| 414 | - | s.event(w.ID(), 5) | |
| 415 | - | s.event(g.ID(), 5) | |
| 416 | - | noerr(t, w.Destroy()) | |
| 417 | - | s.req(w.ID(), 0) | |
| 418 | - | noerr(t, g.Destroy()) | |
| 419 | - | s.req(g.ID(), 1) | |
| 420 | - | // stop is answered by finished, which is the final event. | |
| 421 | - | noerr(t, mgr.Stop()) | |
| 422 | - | s.req(mgr.ID(), 1) | |
| 423 | - | s.event(mgr.ID(), 3) | |
| 424 | - | if !reflect.DeepEqual(log, []string{"done", "workspace-removed", "group-removed", "finished"}) { | |
| 425 | - | t.Fatal(log) | |
| 426 | - | } | |
| 427 | - | // finished is a destructor event: the manager is dead and must not | |
| 428 | - | // reach the compositor any more. | |
| 429 | - | if e := mgr.Commit(); e == nil { | |
| 430 | - | t.Fatal("Commit after finished must fail") | |
| 431 | - | } | |
| 432 | - | s.noRequest() | |
| 433 | - | } | |
| 434 | - | ||
| 435 | - | func TestIdleNotifyVersionGate(t *testing.T) { | |
| 436 | - | s := newWireEnv(t) | |
| 437 | - | seat := s.seat() | |
| 438 | - | old := idlenotify.NewExtIdleNotifier(s.d.Context()) | |
| 439 | - | s.bind(1, idlenotify.ExtIdleNotifierInterface, 2, 1, old) // negotiated v1 | |
| 440 | - | if _, e := old.GetInputIdleNotification(1000, seat); !errors.Is(e, wlturbo.ErrVersionTooLow) { | |
| 441 | - | t.Fatalf("v1 get_input_idle_notification = %v, want ErrVersionTooLow", e) | |
| 442 | - | } | |
| 443 | - | s.noRequest() // refused locally, nothing reaches the compositor | |
| 444 | - | n, e := old.GetIdleNotification(1000, seat) | |
| 445 | - | noerr(t, e) | |
| 446 | - | wantWords(t, "get_idle_notification", s.req(old.ID(), 1), n.ID(), 1000, seat.ID()) | |
| 447 | - | ||
| 448 | - | send(t, s.p, msg(s.d.Registry().ID(), 1, 1)) // global_remove for the v1 bind | |
| 449 | - | s.dispatch() | |
| 450 | - | cur := idlenotify.NewExtIdleNotifier(s.d.Context()) | |
| 451 | - | s.bind(2, idlenotify.ExtIdleNotifierInterface, 2, 2, cur) | |
| 452 | - | in, e := cur.GetInputIdleNotification(0, seat) // zero timeout is valid | |
| 453 | - | noerr(t, e) | |
| 454 | - | wantWords(t, "get_input_idle_notification", s.req(cur.ID(), 2), in.ID(), 0, seat.ID()) | |
| 455 | - | var seq []string | |
| 456 | - | in.OnIdled(func() { seq = append(seq, "idled") }) | |
| 457 | - | in.OnResumed(func() { seq = append(seq, "resumed") }) | |
| 458 | - | s.event(in.ID(), 0) | |
| 459 | - | s.event(in.ID(), 1) | |
| 460 | - | if !reflect.DeepEqual(seq, []string{"idled", "resumed"}) { | |
| 461 | - | t.Fatal(seq) | |
| 462 | - | } | |
| 463 | - | noerr(t, in.Destroy()) | |
| 464 | - | s.req(in.ID(), 0) | |
| 465 | - | noerr(t, n.Destroy()) | |
| 466 | - | s.req(n.ID(), 0) | |
| 467 | - | } | |
| 468 | - | ||
| 469 | - | func TestInhibitAndDesktopHintsWire(t *testing.T) { | |
| 470 | - | s := newWireEnv(t) | |
| 471 | - | surf, seat, out := s.surface(), s.seat(), s.output() | |
| 472 | - | ||
| 473 | - | ii := idleinhibit.NewIdleInhibitManager(s.d.Context()) | |
| 474 | - | s.bind(1, idleinhibit.IdleInhibitManagerInterface, 1, 1, ii) | |
| 475 | - | inh, e := ii.CreateInhibitor(surf) | |
| 476 | - | noerr(t, e) | |
| 477 | - | wantWords(t, "create_inhibitor", s.req(ii.ID(), 1), inh.ID(), surf.ID()) | |
| 478 | - | noerr(t, inh.Destroy()) | |
| 479 | - | s.req(inh.ID(), 0) | |
| 480 | - | noerr(t, ii.Destroy()) | |
| 481 | - | s.req(ii.ID(), 0) | |
| 482 | - | ||
| 483 | - | ks := shortcutsinhibit.NewKeyboardShortcutsInhibitManager(s.d.Context()) | |
| 484 | - | s.bind(2, shortcutsinhibit.KeyboardShortcutsInhibitManagerInterface, 1, 1, ks) | |
| 485 | - | k, e := ks.InhibitShortcuts(surf, seat) | |
| 486 | - | noerr(t, e) | |
| 487 | - | wantWords(t, "inhibit_shortcuts", s.req(ks.ID(), 1), k.ID(), surf.ID(), seat.ID()) | |
| 488 | - | var seq []string | |
| 489 | - | k.OnActive(func() { seq = append(seq, "active") }) | |
| 490 | - | k.OnInactive(func() { seq = append(seq, "inactive") }) | |
| 491 | - | s.event(k.ID(), 0) | |
| 492 | - | s.event(k.ID(), 1) | |
| 493 | - | if !reflect.DeepEqual(seq, []string{"active", "inactive"}) { | |
| 494 | - | t.Fatal(seq) | |
| 495 | - | } | |
| 496 | - | noerr(t, k.Destroy()) | |
| 497 | - | s.req(k.ID(), 0) | |
| 498 | - | noerr(t, ks.Destroy()) | |
| 499 | - | s.req(ks.ID(), 0) | |
| 500 | - | ||
| 501 | - | xo := xdgoutput.NewZxdgOutputManager(s.d.Context()) | |
| 502 | - | s.bind(3, xdgoutput.ZxdgOutputManagerInterface, 3, 3, xo) | |
| 503 | - | o, e := xo.GetXdgOutput(out) | |
| 504 | - | noerr(t, e) | |
| 505 | - | wantWords(t, "get_xdg_output", s.req(xo.ID(), 1), o.ID(), out.ID()) | |
| 506 | - | var pos, size [2]int32 | |
| 507 | - | var name string | |
| 508 | - | o.OnLogicalPosition(func(x, y int32) { pos = [2]int32{x, y} }) | |
| 509 | - | o.OnLogicalSize(func(w, h int32) { size = [2]int32{w, h} }) | |
| 510 | - | o.OnName(func(n string) { name = n }) | |
| 511 | - | s.event(o.ID(), 0, wordBytes(uint32(0xfffffff6), 20)...) // -10, 20 | |
| 512 | - | s.event(o.ID(), 1, wordBytes(1920, 1080)...) | |
| 513 | - | s.event(o.ID(), 3, str("DP-1")...) | |
| 514 | - | if pos != [2]int32{-10, 20} || size != [2]int32{1920, 1080} || name != "DP-1" { | |
| 515 | - | t.Fatal(pos, size, name) | |
| 516 | - | } | |
| 517 | - | noerr(t, o.Destroy()) | |
| 518 | - | s.req(o.ID(), 0) | |
| 519 | - | noerr(t, xo.Destroy()) | |
| 520 | - | s.req(xo.ID(), 0) | |
| 521 | - | } | |
| 522 | - | ||
| 523 | - | func TestXdgDecorationCrossPackageToplevel(t *testing.T) { | |
| 524 | - | s := newWireEnv(t) | |
| 525 | - | surf := s.surface() | |
| 526 | - | wm := xdgshell.NewXdgWmBase(s.d.Context()) | |
| 527 | - | s.bind(1, xdgshell.XdgWmBaseInterface, 6, 6, wm) | |
| 528 | - | xs, e := wm.GetXdgSurface(surf) | |
| 529 | - | noerr(t, e) | |
| 530 | - | s.req(wm.ID(), 2) | |
| 531 | - | top, e := xs.GetToplevel() | |
| 532 | - | noerr(t, e) | |
| 533 | - | s.req(xs.ID(), 1) | |
| 534 | - | ||
| 535 | - | dm := xdgdecoration.NewZxdgDecorationManager(s.d.Context()) | |
| 536 | - | s.bind(2, xdgdecoration.ZxdgDecorationManagerInterface, 2, 2, dm) | |
| 537 | - | dec, e := dm.GetToplevelDecoration(top) | |
| 538 | - | noerr(t, e) | |
| 539 | - | wantWords(t, "get_toplevel_decoration", s.req(dm.ID(), 1), dec.ID(), top.ID()) | |
| 540 | - | noerr(t, dec.SetMode(xdgdecoration.MODE_SERVER_SIDE)) | |
| 541 | - | wantWords(t, "set_mode", s.req(dec.ID(), 1), xdgdecoration.MODE_SERVER_SIDE) | |
| 542 | - | var modes []uint32 | |
| 543 | - | dec.OnConfigure(func(m uint32) { modes = append(modes, m) }) | |
| 544 | - | s.event(dec.ID(), 0, wordBytes(xdgdecoration.MODE_CLIENT_SIDE)...) | |
| 545 | - | if !reflect.DeepEqual(modes, []uint32{xdgdecoration.MODE_CLIENT_SIDE}) { | |
| 546 | - | t.Fatal(modes) | |
| 547 | - | } | |
| 548 | - | noerr(t, dec.UnsetMode()) | |
| 549 | - | s.req(dec.ID(), 2) | |
| 550 | - | noerr(t, dec.Destroy()) | |
| 551 | - | s.req(dec.ID(), 0) | |
| 552 | - | noerr(t, dm.Destroy()) | |
| 553 | - | s.req(dm.ID(), 0) | |
| 554 | - | } | |
| 555 | - | ||
| 556 | - | func TestImageCaptureCrossPackageChildren(t *testing.T) { | |
| 557 | - | s := newWireEnv(t) | |
| 558 | - | out, ptr := s.output(), s.pointer() | |
| 559 | - | ||
| 560 | - | // Foreign toplevel handles come from ext-foreign-toplevel-list and are | |
| 561 | - | // consumed by a different package (imagecapturesource). | |
| 562 | - | list := extforeigntoplevel.NewExtForeignToplevelList(s.d.Context()) | |
| 563 | - | s.bind(1, extforeigntoplevel.ExtForeignToplevelListInterface, 1, 1, list) | |
| 564 | - | var handle *extforeigntoplevel.ExtForeignToplevelHandle | |
| 565 | - | list.OnToplevel(func(h *extforeigntoplevel.ExtForeignToplevelHandle) { handle = h }) | |
| 566 | - | s.event(list.ID(), 0, wordBytes(serverID+1)...) | |
| 567 | - | if handle == nil || handle.ID() != serverID+1 { | |
| 568 | - | t.Fatal("toplevel handle missing") | |
| 569 | - | } | |
| 570 | - | var title, appID, ident string | |
| 571 | - | handle.OnTitle(func(v string) { title = v }) | |
| 572 | - | handle.OnAppId(func(v string) { appID = v }) | |
| 573 | - | handle.OnIdentifier(func(v string) { ident = v }) | |
| 574 | - | s.event(handle.ID(), 2, str("term")...) | |
| 575 | - | s.event(handle.ID(), 3, str("org.example.term")...) | |
| 576 | - | s.event(handle.ID(), 4, str("id-1")...) | |
| 577 | - | if title != "term" || appID != "org.example.term" || ident != "id-1" { | |
| 578 | - | t.Fatal(title, appID, ident) | |
| 579 | - | } | |
| 580 | - | ||
| 581 | - | om := imagecapturesource.NewExtOutputImageCaptureSourceManager(s.d.Context()) | |
| 582 | - | s.bind(2, imagecapturesource.ExtOutputImageCaptureSourceManagerInterface, 1, 1, om) | |
| 583 | - | fm := imagecapturesource.NewExtForeignToplevelImageCaptureSourceManager(s.d.Context()) | |
| 584 | - | s.bind(3, imagecapturesource.ExtForeignToplevelImageCaptureSourceManagerInterface, 1, 1, fm) | |
| 585 | - | outSrc, e := om.CreateSource(out) | |
| 586 | - | noerr(t, e) | |
| 587 | - | wantWords(t, "output create_source", s.req(om.ID(), 0), outSrc.ID(), out.ID()) | |
| 588 | - | topSrc, e := fm.CreateSource(handle) | |
| 589 | - | noerr(t, e) | |
| 590 | - | wantWords(t, "toplevel create_source", s.req(fm.ID(), 0), topSrc.ID(), handle.ID()) | |
| 591 | - | ||
| 592 | - | cm := imagecopycapture.NewExtImageCopyCaptureManager(s.d.Context()) | |
| 593 | - | s.bind(4, imagecopycapture.ExtImageCopyCaptureManagerInterface, 1, 1, cm) | |
| 594 | - | sess, e := cm.CreateSession(topSrc, imagecopycapture.OPTIONS_PAINT_CURSORS) | |
| 595 | - | noerr(t, e) | |
| 596 | - | wantWords(t, "create_session", s.req(cm.ID(), 0), sess.ID(), topSrc.ID(), imagecopycapture.OPTIONS_PAINT_CURSORS) | |
| 597 | - | cur, e := cm.CreatePointerCursorSession(outSrc, ptr) | |
| 598 | - | noerr(t, e) | |
| 599 | - | wantWords(t, "create_pointer_cursor_session", s.req(cm.ID(), 1), cur.ID(), outSrc.ID(), ptr.ID()) | |
| 600 | - | ||
| 601 | - | // Session constraints: advertised before done, arrays decoded. | |
| 602 | - | var log []string | |
| 603 | - | var size [2]uint32 | |
| 604 | - | var dev []byte | |
| 605 | - | var dmaFormat uint32 | |
| 606 | - | var mods []byte | |
| 607 | - | sess.OnBufferSize(func(w, h uint32) { size = [2]uint32{w, h}; log = append(log, "size") }) | |
| 608 | - | var shm []uint32 | |
| 609 | - | sess.OnShmFormat(func(f uint32) { shm = append(shm, f); log = append(log, "shm") }) | |
| 610 | - | sess.OnDmabufDevice(func(d []byte) { dev = d; log = append(log, "dev") }) | |
| 611 | - | sess.OnDmabufFormat(func(f uint32, m []byte) { dmaFormat, mods = f, m; log = append(log, "dmabuf") }) | |
| 612 | - | sess.OnDone(func() { log = append(log, "done") }) | |
| 613 | - | sess.OnStopped(func() { log = append(log, "stopped") }) | |
| 614 | - | s.event(sess.ID(), 0, wordBytes(1280, 720)...) | |
| 615 | - | s.event(sess.ID(), 1, wordBytes(1)...) // wl_shm.format xrgb8888 | |
| 616 | - | s.event(sess.ID(), 2, arr(make([]byte, 8))...) | |
| 617 | - | s.event(sess.ID(), 3, cat(wordBytes(0x34325258), arr(wordBytes(0, 0, 1, 0)))...) | |
| 618 | - | s.event(sess.ID(), 4) | |
| 619 | - | if !reflect.DeepEqual(shm, []uint32{1}) { | |
| 620 | - | t.Fatalf("shm formats %v", shm) | |
| 621 | - | } | |
| 622 | - | if size != [2]uint32{1280, 720} || len(dev) != 8 || dmaFormat != 0x34325258 || len(mods) != 16 || | |
| 623 | - | !reflect.DeepEqual(log, []string{"size", "shm", "dev", "dmabuf", "done"}) { | |
| 624 | - | t.Fatal(size, dev, dmaFormat, mods, log) | |
| 625 | - | } | |
| 626 | - | ||
| 627 | - | frame, e := sess.CreateFrame() | |
| 628 | - | noerr(t, e) | |
| 629 | - | wantWords(t, "create_frame", s.req(sess.ID(), 0), frame.ID()) | |
| 630 | - | buf := s.buffer() | |
| 631 | - | noerr(t, frame.AttachBuffer(buf)) | |
| 632 | - | wantWords(t, "attach_buffer", s.req(frame.ID(), 1), buf.ID()) | |
| 633 | - | noerr(t, frame.DamageBuffer(0, 0, 1280, 720)) | |
| 634 | - | wantWords(t, "damage_buffer", s.req(frame.ID(), 2), 0, 0, 1280, 720) | |
| 635 | - | noerr(t, frame.Capture()) | |
| 636 | - | s.req(frame.ID(), 3) | |
| 637 | - | ||
| 638 | - | var fl []string | |
| 639 | - | var damage [4]int32 | |
| 640 | - | var tv [3]uint32 | |
| 641 | - | frame.OnTransform(func(v uint32) { fl = append(fl, "transform") }) | |
| 642 | - | frame.OnDamage(func(x, y, w, h int32) { damage = [4]int32{x, y, w, h}; fl = append(fl, "damage") }) | |
| 643 | - | frame.OnPresentationTime(func(hi, lo, ns uint32) { tv = [3]uint32{hi, lo, ns}; fl = append(fl, "time") }) | |
| 644 | - | frame.OnReady(func() { fl = append(fl, "ready") }) | |
| 645 | - | frame.OnFailed(func(uint32) { fl = append(fl, "failed") }) | |
| 646 | - | s.event(frame.ID(), 0, wordBytes(0)...) | |
| 647 | - | s.event(frame.ID(), 1, wordBytes(1, 2, 3, 4)...) | |
| 648 | - | s.event(frame.ID(), 2, wordBytes(0, 1700000000, 999)...) | |
| 649 | - | s.event(frame.ID(), 3) | |
| 650 | - | if damage != [4]int32{1, 2, 3, 4} || tv != [3]uint32{0, 1700000000, 999} || | |
| 651 | - | !reflect.DeepEqual(fl, []string{"transform", "damage", "time", "ready"}) { | |
| 652 | - | t.Fatal(damage, tv, fl) | |
| 653 | - | } | |
| 654 | - | // ready is terminal for a frame, and a session allows one frame at a time | |
| 655 | - | // even after ready, so destroy it before creating the frame that fails. | |
| 656 | - | noerr(t, frame.Destroy()) | |
| 657 | - | s.req(frame.ID(), 0) | |
| 658 | - | failing, e := sess.CreateFrame() | |
| 659 | - | noerr(t, e) | |
| 660 | - | wantWords(t, "create_frame(2)", s.req(sess.ID(), 0), failing.ID()) | |
| 661 | - | noerr(t, failing.AttachBuffer(buf)) | |
| 662 | - | s.req(failing.ID(), 1) | |
| 663 | - | noerr(t, failing.Capture()) | |
| 664 | - | s.req(failing.ID(), 3) | |
| 665 | - | var reasons []uint32 | |
| 666 | - | failing.OnReady(func() { t.Error("failed frame must not become ready") }) | |
| 667 | - | failing.OnFailed(func(r uint32) { reasons = append(reasons, r) }) | |
| 668 | - | s.event(failing.ID(), 4, wordBytes(imagecopycapture.FAILURE_REASON_BUFFER_CONSTRAINTS)...) | |
| 669 | - | if !reflect.DeepEqual(reasons, []uint32{imagecopycapture.FAILURE_REASON_BUFFER_CONSTRAINTS}) { | |
| 670 | - | t.Fatal(reasons) | |
| 671 | - | } | |
| 672 | - | ||
| 673 | - | // Cursor session: get_capture_session is a typed child too. | |
| 674 | - | var cl []string | |
| 675 | - | var pos, hot [2]int32 | |
| 676 | - | cur.OnEnter(func() { cl = append(cl, "enter") }) | |
| 677 | - | cur.OnLeave(func() { cl = append(cl, "leave") }) | |
| 678 | - | cur.OnPosition(func(x, y int32) { pos = [2]int32{x, y} }) | |
| 679 | - | cur.OnHotspot(func(x, y int32) { hot = [2]int32{x, y} }) | |
| 680 | - | s.event(cur.ID(), 0) | |
| 681 | - | s.event(cur.ID(), 2, wordBytes(uint32(0xfffffffb), 9)...) // -5, 9 | |
| 682 | - | s.event(cur.ID(), 3, wordBytes(4, 6)...) | |
| 683 | - | s.event(cur.ID(), 1) | |
| 684 | - | if pos != [2]int32{-5, 9} || hot != [2]int32{4, 6} || !reflect.DeepEqual(cl, []string{"enter", "leave"}) { | |
| 685 | - | t.Fatal(pos, hot, cl) | |
| 686 | - | } | |
| 687 | - | csess, e := cur.GetCaptureSession() | |
| 688 | - | noerr(t, e) | |
| 689 | - | wantWords(t, "get_capture_session", s.req(cur.ID(), 1), csess.ID()) | |
| 690 | - | if csess.Version() != cur.Version() { | |
| 691 | - | t.Fatalf("child version %d, parent %d", csess.Version(), cur.Version()) | |
| 692 | - | } | |
| 693 | - | ||
| 694 | - | // destroy order: children, sources, managers, toplevel handle. | |
| 695 | - | for _, c := range []struct { | |
| 696 | - | name string | |
| 697 | - | id uint32 | |
| 698 | - | op uint16 | |
| 699 | - | fn func() error | |
| 700 | - | }{ | |
| 701 | - | {"failed frame", failing.ID(), 0, failing.Destroy}, | |
| 702 | - | {"capture session", csess.ID(), 1, csess.Destroy}, | |
| 703 | - | {"session", sess.ID(), 1, sess.Destroy}, | |
| 704 | - | {"cursor", cur.ID(), 0, cur.Destroy}, | |
| 705 | - | {"output source", outSrc.ID(), 0, outSrc.Destroy}, | |
| 706 | - | {"toplevel source", topSrc.ID(), 0, topSrc.Destroy}, | |
| 707 | - | {"copy manager", cm.ID(), 2, cm.Destroy}, | |
| 708 | - | {"output manager", om.ID(), 1, om.Destroy}, | |
| 709 | - | {"toplevel manager", fm.ID(), 1, fm.Destroy}, | |
| 710 | - | {"handle", handle.ID(), 0, handle.Destroy}, | |
| 711 | - | } { | |
| 712 | - | // Subtests run serially (no t.Parallel): the wire order of destroy | |
| 713 | - | // requests on the shared socketpair is part of what is asserted. | |
| 714 | - | ok := t.Run(c.name, func(t *testing.T) { | |
| 715 | - | ss := *s | |
| 716 | - | ss.t = t | |
| 717 | - | noerr(t, c.fn()) | |
| 718 | - | ss.req(c.id, c.op) | |
| 719 | - | }) | |
| 720 | - | if !ok { | |
| 721 | - | // A failed step leaves unread bytes on the socket; carrying on | |
| 722 | - | // would misattribute them to later destroys. | |
| 723 | - | t.FailNow() | |
| 724 | - | } | |
| 725 | - | } | |
| 726 | - | } | |
D protocol/inputmethod/generate.go +0 -3
| @@ -1,3 +0,0 @@ | |||
| 1 | - | package inputmethod | |
| 2 | - | ||
| 3 | - | //go:generate go run ../../cmd/wlturbo-scanner -p inputmethod -o input-method-unstable-v2_generated.go -import wl_seat=github.com/bnema/wlturbo/protocol/core -import wl_surface=github.com/bnema/wlturbo/protocol/core input-method-unstable-v2.xml | |
D protocol/inputmethod/input-method-unstable-v2.xml +0 -494
| @@ -1,494 +0,0 @@ | |||
| 1 | - | <?xml version="1.0" encoding="UTF-8"?> | |
| 2 | - | <protocol name="input_method_unstable_v2"> | |
| 3 | - | ||
| 4 | - | <copyright> | |
| 5 | - | Copyright © 2008-2011 Kristian Høgsberg | |
| 6 | - | Copyright © 2010-2011 Intel Corporation | |
| 7 | - | Copyright © 2012-2013 Collabora, Ltd. | |
| 8 | - | Copyright © 2012, 2013 Intel Corporation | |
| 9 | - | Copyright © 2015, 2016 Jan Arne Petersen | |
| 10 | - | Copyright © 2017, 2018 Red Hat, Inc. | |
| 11 | - | Copyright © 2018 Purism SPC | |
| 12 | - | ||
| 13 | - | Permission is hereby granted, free of charge, to any person obtaining a | |
| 14 | - | copy of this software and associated documentation files (the "Software"), | |
| 15 | - | to deal in the Software without restriction, including without limitation | |
| 16 | - | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 17 | - | and/or sell copies of the Software, and to permit persons to whom the | |
| 18 | - | Software is furnished to do so, subject to the following conditions: | |
| 19 | - | ||
| 20 | - | The above copyright notice and this permission notice (including the next | |
| 21 | - | paragraph) shall be included in all copies or substantial portions of the | |
| 22 | - | Software. | |
| 23 | - | ||
| 24 | - | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 25 | - | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 26 | - | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 27 | - | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 28 | - | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 29 | - | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
| 30 | - | DEALINGS IN THE SOFTWARE. | |
| 31 | - | </copyright> | |
| 32 | - | ||
| 33 | - | <description summary="Protocol for creating input methods"> | |
| 34 | - | This protocol allows applications to act as input methods for compositors. | |
| 35 | - | ||
| 36 | - | An input method context is used to manage the state of the input method. | |
| 37 | - | ||
| 38 | - | Text strings are UTF-8 encoded, their indices and lengths are in bytes. | |
| 39 | - | ||
| 40 | - | This document adheres to the RFC 2119 when using words like "must", | |
| 41 | - | "should", "may", etc. | |
| 42 | - | ||
| 43 | - | Warning! The protocol described in this file is experimental and | |
| 44 | - | backward incompatible changes may be made. Backward compatible changes | |
| 45 | - | may be added together with the corresponding interface version bump. | |
| 46 | - | Backward incompatible changes are done by bumping the version number in | |
| 47 | - | the protocol and interface names and resetting the interface version. | |
| 48 | - | Once the protocol is to be declared stable, the 'z' prefix and the | |
| 49 | - | version number in the protocol and interface names are removed and the | |
| 50 | - | interface version number is reset. | |
| 51 | - | </description> | |
| 52 | - | ||
| 53 | - | <interface name="zwp_input_method_v2" version="1"> | |
| 54 | - | <description summary="input method"> | |
| 55 | - | An input method object allows for clients to compose text. | |
| 56 | - | ||
| 57 | - | The objects connects the client to a text input in an application, and | |
| 58 | - | lets the client to serve as an input method for a seat. | |
| 59 | - | ||
| 60 | - | The zwp_input_method_v2 object can occupy two distinct states: active and | |
| 61 | - | inactive. In the active state, the object is associated to and | |
| 62 | - | communicates with a text input. In the inactive state, there is no | |
| 63 | - | associated text input, and the only communication is with the compositor. | |
| 64 | - | Initially, the input method is in the inactive state. | |
| 65 | - | ||
| 66 | - | Requests issued in the inactive state must be accepted by the compositor. | |
| 67 | - | Because of the serial mechanism, and the state reset on activate event, | |
| 68 | - | they will not have any effect on the state of the next text input. | |
| 69 | - | ||
| 70 | - | There must be no more than one input method object per seat. | |
| 71 | - | </description> | |
| 72 | - | ||
| 73 | - | <enum name="error"> | |
| 74 | - | <entry name="role" value="0" summary="wl_surface has another role"/> | |
| 75 | - | </enum> | |
| 76 | - | ||
| 77 | - | <event name="activate"> | |
| 78 | - | <description summary="input method has been requested"> | |
| 79 | - | Notification that a text input focused on this seat requested the input | |
| 80 | - | method to be activated. | |
| 81 | - | ||
| 82 | - | This event serves the purpose of providing the compositor with an | |
| 83 | - | active input method. | |
| 84 | - | ||
| 85 | - | This event resets all state associated with previous enable, disable, | |
| 86 | - | surrounding_text, text_change_cause, and content_type events, as well | |
| 87 | - | as the state associated with set_preedit_string, commit_string, and | |
| 88 | - | delete_surrounding_text requests. In addition, it marks the | |
| 89 | - | zwp_input_method_v2 object as active, and makes any existing | |
| 90 | - | zwp_input_popup_surface_v2 objects visible. | |
| 91 | - | ||
| 92 | - | The surrounding_text, and content_type events must follow before the | |
| 93 | - | next done event if the text input supports the respective | |
| 94 | - | functionality. | |
| 95 | - | ||
| 96 | - | State set with this event is double-buffered. It will get applied on | |
| 97 | - | the next zwp_input_method_v2.done event, and stay valid until changed. | |
| 98 | - | </description> | |
| 99 | - | </event> | |
| 100 | - | ||
| 101 | - | <event name="deactivate"> | |
| 102 | - | <description summary="deactivate event"> | |
| 103 | - | Notification that no focused text input currently needs an active | |
| 104 | - | input method on this seat. | |
| 105 | - | ||
| 106 | - | This event marks the zwp_input_method_v2 object as inactive. The | |
| 107 | - | compositor must make all existing zwp_input_popup_surface_v2 objects | |
| 108 | - | invisible until the next activate event. | |
| 109 | - | ||
| 110 | - | State set with this event is double-buffered. It will get applied on | |
| 111 | - | the next zwp_input_method_v2.done event, and stay valid until changed. | |
| 112 | - | </description> | |
| 113 | - | </event> | |
| 114 | - | ||
| 115 | - | <event name="surrounding_text"> | |
| 116 | - | <description summary="surrounding text event"> | |
| 117 | - | Updates the surrounding plain text around the cursor, excluding the | |
| 118 | - | preedit text. | |
| 119 | - | ||
| 120 | - | If any preedit text is present, it is replaced with the cursor for the | |
| 121 | - | purpose of this event. | |
| 122 | - | ||
| 123 | - | The argument text is a buffer containing the preedit string, and must | |
| 124 | - | include the cursor position, and the complete selection. It should | |
| 125 | - | contain additional characters before and after these. There is a | |
| 126 | - | maximum length of wayland messages, so text can not be longer than 4000 | |
| 127 | - | bytes. | |
| 128 | - | ||
| 129 | - | cursor is the byte offset of the cursor within the text buffer. | |
| 130 | - | ||
| 131 | - | anchor is the byte offset of the selection anchor within the text | |
| 132 | - | buffer. If there is no selected text, anchor must be the same as | |
| 133 | - | cursor. | |
| 134 | - | ||
| 135 | - | If this event does not arrive before the first done event, the input | |
| 136 | - | method may assume that the text input does not support this | |
| 137 | - | functionality and ignore following surrounding_text events. | |
| 138 | - | ||
| 139 | - | Values set with this event are double-buffered. They will get applied | |
| 140 | - | and set to initial values on the next zwp_input_method_v2.done | |
| 141 | - | event. | |
| 142 | - | ||
| 143 | - | The initial state for affected fields is empty, meaning that the text | |
| 144 | - | input does not support sending surrounding text. If the empty values | |
| 145 | - | get applied, subsequent attempts to change them may have no effect. | |
| 146 | - | </description> | |
| 147 | - | <arg name="text" type="string"/> | |
| 148 | - | <arg name="cursor" type="uint"/> | |
| 149 | - | <arg name="anchor" type="uint"/> | |
| 150 | - | </event> | |
| 151 | - | ||
| 152 | - | <event name="text_change_cause"> | |
| 153 | - | <description summary="indicates the cause of surrounding text change"> | |
| 154 | - | Tells the input method why the text surrounding the cursor changed. | |
| 155 | - | ||
| 156 | - | Whenever the client detects an external change in text, cursor, or | |
| 157 | - | anchor position, it must issue this request to the compositor. This | |
| 158 | - | request is intended to give the input method a chance to update the | |
| 159 | - | preedit text in an appropriate way, e.g. by removing it when the user | |
| 160 | - | starts typing with a keyboard. | |
| 161 | - | ||
| 162 | - | cause describes the source of the change. | |
| 163 | - | ||
| 164 | - | The value set with this event is double-buffered. It will get applied | |
| 165 | - | and set to its initial value on the next zwp_input_method_v2.done | |
| 166 | - | event. | |
| 167 | - | ||
| 168 | - | The initial value of cause is input_method. | |
| 169 | - | </description> | |
| 170 | - | <arg name="cause" type="uint" enum="zwp_text_input_v3.change_cause"/> | |
| 171 | - | </event> | |
| 172 | - | ||
| 173 | - | <event name="content_type"> | |
| 174 | - | <description summary="content purpose and hint"> | |
| 175 | - | Indicates the content type and hint for the current | |
| 176 | - | zwp_input_method_v2 instance. | |
| 177 | - | ||
| 178 | - | Values set with this event are double-buffered. They will get applied | |
| 179 | - | on the next zwp_input_method_v2.done event. | |
| 180 | - | ||
| 181 | - | The initial value for hint is none, and the initial value for purpose | |
| 182 | - | is normal. | |
| 183 | - | </description> | |
| 184 | - | <arg name="hint" type="uint" enum="zwp_text_input_v3.content_hint"/> | |
| 185 | - | <arg name="purpose" type="uint" enum="zwp_text_input_v3.content_purpose"/> | |
| 186 | - | </event> | |
| 187 | - | ||
| 188 | - | <event name="done"> | |
| 189 | - | <description summary="apply state"> | |
| 190 | - | Atomically applies state changes recently sent to the client. | |
| 191 | - | ||
| 192 | - | The done event establishes and updates the state of the client, and | |
| 193 | - | must be issued after any changes to apply them. | |
| 194 | - | ||
| 195 | - | Text input state (content purpose, content hint, surrounding text, and | |
| 196 | - | change cause) is conceptually double-buffered within an input method | |
| 197 | - | context. | |
| 198 | - | ||
| 199 | - | Events modify the pending state, as opposed to the current state in use | |
| 200 | - | by the input method. A done event atomically applies all pending state, | |
| 201 | - | replacing the current state. After done, the new pending state is as | |
| 202 | - | documented for each related request. | |
| 203 | - | ||
| 204 | - | Events must be applied in the order of arrival. | |
| 205 | - | ||
| 206 | - | Neither current nor pending state are modified unless noted otherwise. | |
| 207 | - | </description> | |
| 208 | - | </event> | |
| 209 | - | ||
| 210 | - | <request name="commit_string"> | |
| 211 | - | <description summary="commit string"> | |
| 212 | - | Send the commit string text for insertion to the application. | |
| 213 | - | ||
| 214 | - | Inserts a string at current cursor position (see commit event | |
| 215 | - | sequence). The string to commit could be either just a single character | |
| 216 | - | after a key press or the result of some composing. | |
| 217 | - | ||
| 218 | - | The argument text is a buffer containing the string to insert. There is | |
| 219 | - | a maximum length of wayland messages, so text can not be longer than | |
| 220 | - | 4000 bytes. | |
| 221 | - | ||
| 222 | - | Values set with this event are double-buffered. They must be applied | |
| 223 | - | and reset to initial on the next zwp_text_input_v3.commit request. | |
| 224 | - | ||
| 225 | - | The initial value of text is an empty string. | |
| 226 | - | </description> | |
| 227 | - | <arg name="text" type="string"/> | |
| 228 | - | </request> | |
| 229 | - | ||
| 230 | - | <request name="set_preedit_string"> | |
| 231 | - | <description summary="pre-edit string"> | |
| 232 | - | Send the pre-edit string text to the application text input. | |
| 233 | - | ||
| 234 | - | Place a new composing text (pre-edit) at the current cursor position. | |
| 235 | - | Any previously set composing text must be removed. Any previously | |
| 236 | - | existing selected text must be removed. The cursor is moved to a new | |
| 237 | - | position within the preedit string. | |
| 238 | - | ||
| 239 | - | The argument text is a buffer containing the preedit string. There is | |
| 240 | - | a maximum length of wayland messages, so text can not be longer than | |
| 241 | - | 4000 bytes. | |
| 242 | - | ||
| 243 | - | The arguments cursor_begin and cursor_end are counted in bytes relative | |
| 244 | - | to the beginning of the submitted string buffer. Cursor should be | |
| 245 | - | hidden by the text input when both are equal to -1. | |
| 246 | - | ||
| 247 | - | cursor_begin indicates the beginning of the cursor. cursor_end | |
| 248 | - | indicates the end of the cursor. It may be equal or different than | |
| 249 | - | cursor_begin. | |
| 250 | - | ||
| 251 | - | Values set with this event are double-buffered. They must be applied on | |
| 252 | - | the next zwp_input_method_v2.commit event. | |
| 253 | - | ||
| 254 | - | The initial value of text is an empty string. The initial value of | |
| 255 | - | cursor_begin, and cursor_end are both 0. | |
| 256 | - | </description> | |
| 257 | - | <arg name="text" type="string"/> | |
| 258 | - | <arg name="cursor_begin" type="int"/> | |
| 259 | - | <arg name="cursor_end" type="int"/> | |
| 260 | - | </request> | |
| 261 | - | ||
| 262 | - | <request name="delete_surrounding_text"> | |
| 263 | - | <description summary="delete text"> | |
| 264 | - | Remove the surrounding text. | |
| 265 | - | ||
| 266 | - | before_length and after_length are the number of bytes before and after | |
| 267 | - | the current cursor index (excluding the preedit text) to delete. | |
| 268 | - | ||
| 269 | - | If any preedit text is present, it is replaced with the cursor for the | |
| 270 | - | purpose of this event. In effect before_length is counted from the | |
| 271 | - | beginning of preedit text, and after_length from its end (see commit | |
| 272 | - | event sequence). | |
| 273 | - | ||
| 274 | - | Values set with this event are double-buffered. They must be applied | |
| 275 | - | and reset to initial on the next zwp_input_method_v2.commit request. | |
| 276 | - | ||
| 277 | - | The initial values of both before_length and after_length are 0. | |
| 278 | - | </description> | |
| 279 | - | <arg name="before_length" type="uint"/> | |
| 280 | - | <arg name="after_length" type="uint"/> | |
| 281 | - | </request> | |
| 282 | - | ||
| 283 | - | <request name="commit"> | |
| 284 | - | <description summary="apply state"> | |
| 285 | - | Apply state changes from commit_string, set_preedit_string and | |
| 286 | - | delete_surrounding_text requests. | |
| 287 | - | ||
| 288 | - | The state relating to these events is double-buffered, and each one | |
| 289 | - | modifies the pending state. This request replaces the current state | |
| 290 | - | with the pending state. | |
| 291 | - | ||
| 292 | - | The connected text input is expected to proceed by evaluating the | |
| 293 | - | changes in the following order: | |
| 294 | - | ||
| 295 | - | 1. Replace existing preedit string with the cursor. | |
| 296 | - | 2. Delete requested surrounding text. | |
| 297 | - | 3. Insert commit string with the cursor at its end. | |
| 298 | - | 4. Calculate surrounding text to send. | |
| 299 | - | 5. Insert new preedit text in cursor position. | |
| 300 | - | 6. Place cursor inside preedit text. | |
| 301 | - | ||
| 302 | - | The serial number reflects the last state of the zwp_input_method_v2 | |
| 303 | - | object known to the client. The value of the serial argument must be | |
| 304 | - | equal to the number of done events already issued by that object. When | |
| 305 | - | the compositor receives a commit request with a serial different than | |
| 306 | - | the number of past done events, it must proceed as normal, except it | |
| 307 | - | should not change the current state of the zwp_input_method_v2 object. | |
| 308 | - | </description> | |
| 309 | - | <arg name="serial" type="uint"/> | |
| 310 | - | </request> | |
| 311 | - | ||
| 312 | - | <request name="get_input_popup_surface"> | |
| 313 | - | <description summary="create popup surface"> | |
| 314 | - | Creates a new zwp_input_popup_surface_v2 object wrapping a given | |
| 315 | - | surface. | |
| 316 | - | ||
| 317 | - | The surface gets assigned the "input_popup" role. If the surface | |
| 318 | - | already has an assigned role, the compositor must issue a protocol | |
| 319 | - | error. | |
| 320 | - | </description> | |
| 321 | - | <arg name="id" type="new_id" interface="zwp_input_popup_surface_v2"/> | |
| 322 | - | <arg name="surface" type="object" interface="wl_surface"/> | |
| 323 | - | </request> | |
| 324 | - | ||
| 325 | - | <request name="grab_keyboard"> | |
| 326 | - | <description summary="grab hardware keyboard"> | |
| 327 | - | Allow an input method to receive hardware keyboard input and process | |
| 328 | - | key events to generate text events (with pre-edit) over the wire. This | |
| 329 | - | allows input methods which compose multiple key events for inputting | |
| 330 | - | text like it is done for CJK languages. | |
| 331 | - | ||
| 332 | - | The compositor should send all keyboard events on the seat to the grab | |
| 333 | - | holder via the returned wl_keyboard object. Nevertheless, the | |
| 334 | - | compositor may decide not to forward any particular event. The | |
| 335 | - | compositor must not further process any event after it has been | |
| 336 | - | forwarded to the grab holder. | |
| 337 | - | ||
| 338 | - | Releasing the resulting wl_keyboard object releases the grab. | |
| 339 | - | </description> | |
| 340 | - | <arg name="keyboard" type="new_id" | |
| 341 | - | interface="zwp_input_method_keyboard_grab_v2"/> | |
| 342 | - | </request> | |
| 343 | - | ||
| 344 | - | <event name="unavailable"> | |
| 345 | - | <description summary="input method unavailable"> | |
| 346 | - | The input method ceased to be available. | |
| 347 | - | ||
| 348 | - | The compositor must issue this event as the only event on the object if | |
| 349 | - | there was another input_method object associated with the same seat at | |
| 350 | - | the time of its creation. | |
| 351 | - | ||
| 352 | - | The compositor must issue this request when the object is no longer | |
| 353 | - | usable, e.g. due to seat removal. | |
| 354 | - | ||
| 355 | - | The input method context becomes inert and should be destroyed after | |
| 356 | - | deactivation is handled. Any further requests and events except for the | |
| 357 | - | destroy request must be ignored. | |
| 358 | - | </description> | |
| 359 | - | </event> | |
| 360 | - | ||
| 361 | - | <request name="destroy" type="destructor"> | |
| 362 | - | <description summary="destroy the text input"> | |
| 363 | - | Destroys the zwp_text_input_v2 object and any associated child | |
| 364 | - | objects, i.e. zwp_input_popup_surface_v2 and | |
| 365 | - | zwp_input_method_keyboard_grab_v2. | |
| 366 | - | </description> | |
| 367 | - | </request> | |
| 368 | - | </interface> | |
| 369 | - | ||
| 370 | - | <interface name="zwp_input_popup_surface_v2" version="1"> | |
| 371 | - | <description summary="popup surface"> | |
| 372 | - | This interface marks a surface as a popup for interacting with an input | |
| 373 | - | method. | |
| 374 | - | ||
| 375 | - | The compositor should place it near the active text input area. It must | |
| 376 | - | be visible if and only if the input method is in the active state. | |
| 377 | - | ||
| 378 | - | The client must not destroy the underlying wl_surface while the | |
| 379 | - | zwp_input_popup_surface_v2 object exists. | |
| 380 | - | </description> | |
| 381 | - | ||
| 382 | - | <event name="text_input_rectangle"> | |
| 383 | - | <description summary="set text input area position"> | |
| 384 | - | Notify about the position of the area of the text input expressed as a | |
| 385 | - | rectangle in surface local coordinates. | |
| 386 | - | ||
| 387 | - | This is a hint to the input method telling it the relative position of | |
| 388 | - | the text being entered. | |
| 389 | - | </description> | |
| 390 | - | <arg name="x" type="int"/> | |
| 391 | - | <arg name="y" type="int"/> | |
| 392 | - | <arg name="width" type="int"/> | |
| 393 | - | <arg name="height" type="int"/> | |
| 394 | - | </event> | |
| 395 | - | ||
| 396 | - | <request name="destroy" type="destructor"/> | |
| 397 | - | </interface> | |
| 398 | - | ||
| 399 | - | <interface name="zwp_input_method_keyboard_grab_v2" version="1"> | |
| 400 | - | <!-- Closely follows wl_keyboard version 6 --> | |
| 401 | - | <description summary="keyboard grab"> | |
| 402 | - | The zwp_input_method_keyboard_grab_v2 interface represents an exclusive | |
| 403 | - | grab of the wl_keyboard interface associated with the seat. | |
| 404 | - | </description> | |
| 405 | - | ||
| 406 | - | <event name="keymap"> | |
| 407 | - | <description summary="keyboard mapping"> | |
| 408 | - | This event provides a file descriptor to the client which can be | |
| 409 | - | memory-mapped to provide a keyboard mapping description. | |
| 410 | - | </description> | |
| 411 | - | <arg name="format" type="uint" enum="wl_keyboard.keymap_format" | |
| 412 | - | summary="keymap format"/> | |
| 413 | - | <arg name="fd" type="fd" summary="keymap file descriptor"/> | |
| 414 | - | <arg name="size" type="uint" summary="keymap size, in bytes"/> | |
| 415 | - | </event> | |
| 416 | - | ||
| 417 | - | <event name="key"> | |
| 418 | - | <description summary="key event"> | |
| 419 | - | A key was pressed or released. | |
| 420 | - | The time argument is a timestamp with millisecond granularity, with an | |
| 421 | - | undefined base. | |
| 422 | - | </description> | |
| 423 | - | <arg name="serial" type="uint" summary="serial number of the key event"/> | |
| 424 | - | <arg name="time" type="uint" summary="timestamp with millisecond granularity"/> | |
| 425 | - | <arg name="key" type="uint" summary="key that produced the event"/> | |
| 426 | - | <arg name="state" type="uint" enum="wl_keyboard.key_state" | |
| 427 | - | summary="physical state of the key"/> | |
| 428 | - | </event> | |
| 429 | - | ||
| 430 | - | <event name="modifiers"> | |
| 431 | - | <description summary="modifier and group state"> | |
| 432 | - | Notifies clients that the modifier and/or group state has changed, and | |
| 433 | - | it should update its local state. | |
| 434 | - | </description> | |
| 435 | - | <arg name="serial" type="uint" summary="serial number of the modifiers event"/> | |
| 436 | - | <arg name="mods_depressed" type="uint" summary="depressed modifiers"/> | |
| 437 | - | <arg name="mods_latched" type="uint" summary="latched modifiers"/> | |
| 438 | - | <arg name="mods_locked" type="uint" summary="locked modifiers"/> | |
| 439 | - | <arg name="group" type="uint" summary="keyboard layout"/> | |
| 440 | - | </event> | |
| 441 | - | ||
| 442 | - | <request name="release" type="destructor"> | |
| 443 | - | <description summary="release the grab object"/> | |
| 444 | - | </request> | |
| 445 | - | ||
| 446 | - | <event name="repeat_info"> | |
| 447 | - | <description summary="repeat rate and delay"> | |
| 448 | - | Informs the client about the keyboard's repeat rate and delay. | |
| 449 | - | ||
| 450 | - | This event is sent as soon as the zwp_input_method_keyboard_grab_v2 | |
| 451 | - | object has been created, and is guaranteed to be received by the | |
| 452 | - | client before any key press event. | |
| 453 | - | ||
| 454 | - | Negative values for either rate or delay are illegal. A rate of zero | |
| 455 | - | will disable any repeating (regardless of the value of delay). | |
| 456 | - | ||
| 457 | - | This event can be sent later on as well with a new value if necessary, | |
| 458 | - | so clients should continue listening for the event past the creation | |
| 459 | - | of zwp_input_method_keyboard_grab_v2. | |
| 460 | - | </description> | |
| 461 | - | <arg name="rate" type="int" | |
| 462 | - | summary="the rate of repeating keys in characters per second"/> | |
| 463 | - | <arg name="delay" type="int" | |
| 464 | - | summary="delay in milliseconds since key down until repeating starts"/> | |
| 465 | - | </event> | |
| 466 | - | </interface> | |
| 467 | - | ||
| 468 | - | <interface name="zwp_input_method_manager_v2" version="1"> | |
| 469 | - | <description summary="input method manager"> | |
| 470 | - | The input method manager allows the client to become the input method on | |
| 471 | - | a chosen seat. | |
| 472 | - | ||
| 473 | - | No more than one input method must be associated with any seat at any | |
| 474 | - | given time. | |
| 475 | - | </description> | |
| 476 | - | ||
| 477 | - | <request name="get_input_method"> | |
| 478 | - | <description summary="request an input method object"> | |
| 479 | - | Request a new input zwp_input_method_v2 object associated with a given | |
| 480 | - | seat. | |
| 481 | - | </description> | |
| 482 | - | <arg name="seat" type="object" interface="wl_seat"/> | |
| 483 | - | <arg name="input_method" type="new_id" interface="zwp_input_method_v2"/> | |
| 484 | - | </request> | |
| 485 | - | ||
| 486 | - | <request name="destroy" type="destructor"> | |
| 487 | - | <description summary="destroy the input method manager"> | |
| 488 | - | Destroys the zwp_input_method_manager_v2 object. | |
| 489 | - | ||
| 490 | - | The zwp_input_method_v2 objects originating from it remain valid. | |
| 491 | - | </description> | |
| 492 | - | </request> | |
| 493 | - | </interface> | |
| 494 | - | </protocol> | |
D protocol/inputmethod/input-method-unstable-v2_generated.go +0 -677
| @@ -1,677 +0,0 @@ | |||
| 1 | - | // Code generated by wlturbo-scanner. DO NOT EDIT. | |
| 2 | - | // Protocol: input_method_unstable_v2 | |
| 3 | - | // Source: input-method-unstable-v2.xml | |
| 4 | - | ||
| 5 | - | // Upstream protocol copyright and license: | |
| 6 | - | // Copyright © 2008-2011 Kristian Høgsberg | |
| 7 | - | // Copyright © 2010-2011 Intel Corporation | |
| 8 | - | // Copyright © 2012-2013 Collabora, Ltd. | |
| 9 | - | // Copyright © 2012, 2013 Intel Corporation | |
| 10 | - | // Copyright © 2015, 2016 Jan Arne Petersen | |
| 11 | - | // Copyright © 2017, 2018 Red Hat, Inc. | |
| 12 | - | // Copyright © 2018 Purism SPC | |
| 13 | - | // | |
| 14 | - | // Permission is hereby granted, free of charge, to any person obtaining a | |
| 15 | - | // copy of this software and associated documentation files (the "Software"), | |
| 16 | - | // to deal in the Software without restriction, including without limitation | |
| 17 | - | // the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 18 | - | // and/or sell copies of the Software, and to permit persons to whom the | |
| 19 | - | // Software is furnished to do so, subject to the following conditions: | |
| 20 | - | // | |
| 21 | - | // The above copyright notice and this permission notice (including the next | |
| 22 | - | // paragraph) shall be included in all copies or substantial portions of the | |
| 23 | - | // Software. | |
| 24 | - | // | |
| 25 | - | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 26 | - | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 27 | - | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 28 | - | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 29 | - | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 30 | - | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
| 31 | - | // DEALINGS IN THE SOFTWARE. | |
| 32 | - | ||
| 33 | - | package inputmethod | |
| 34 | - | ||
| 35 | - | import ( | |
| 36 | - | "sync" | |
| 37 | - | ||
| 38 | - | cross_wl_seat "github.com/bnema/wlturbo/protocol/core" | |
| 39 | - | cross_wl_surface "github.com/bnema/wlturbo/protocol/core" | |
| 40 | - | "github.com/bnema/wlturbo/wl" | |
| 41 | - | ) | |
| 42 | - | ||
| 43 | - | // ERROR_ROLE is the error role value. | |
| 44 | - | const ERROR_ROLE = 0 | |
| 45 | - | ||
| 46 | - | // InputMethodInterface is the protocol interface name. | |
| 47 | - | const InputMethodInterface = "zwp_input_method_v2" | |
| 48 | - | ||
| 49 | - | // InputMethod is the generated binding for zwp_input_method_v2 version 1. | |
| 50 | - | type InputMethod struct { | |
| 51 | - | wl.BaseProxy | |
| 52 | - | // handlersMu guards the handler slices: a client may register or replace | |
| 53 | - | // handlers while another goroutine dispatches events. | |
| 54 | - | handlersMu sync.Mutex | |
| 55 | - | onActivate []func() | |
| 56 | - | onDeactivate []func() | |
| 57 | - | onSurroundingText []func(text string, cursor uint32, anchor uint32) | |
| 58 | - | onTextChangeCause []func(cause uint32) | |
| 59 | - | onContentType []func(hint uint32, purpose uint32) | |
| 60 | - | onDone []func() | |
| 61 | - | onUnavailable []func() | |
| 62 | - | } | |
| 63 | - | ||
| 64 | - | // NewInputMethod returns an unbound InputMethod. | |
| 65 | - | func NewInputMethod(ctx *wl.Context) *InputMethod { | |
| 66 | - | obj := &InputMethod{} | |
| 67 | - | obj.SetContext(ctx) | |
| 68 | - | ctx.Register(obj) | |
| 69 | - | return obj | |
| 70 | - | } | |
| 71 | - | ||
| 72 | - | // Send the commit string text for insertion to the application. Inserts a string at current cursor position (see commit event sequence). The string to commit could be either just a single character after a key press or the result of some composing. The argument text is a buffer containing the string to insert. There is a maximum length of wayland messages, so text can not be longer than 4000 bytes. Values set with this event are double-buffered. They must be applied and reset to initial on the next zwp_text_input_v3.commit request. The initial value of text is an empty string. | |
| 73 | - | func (o *InputMethod) CommitString(text string) error { | |
| 74 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "zwp_input_method_v2.commit_string"}, wl.ArgString(text)); err != nil { | |
| 75 | - | return err | |
| 76 | - | } | |
| 77 | - | return nil | |
| 78 | - | } | |
| 79 | - | ||
| 80 | - | // Send the pre-edit string text to the application text input. Place a new composing text (pre-edit) at the current cursor position. Any previously set composing text must be removed. Any previously existing selected text must be removed. The cursor is moved to a new position within the preedit string. The argument text is a buffer containing the preedit string. There is a maximum length of wayland messages, so text can not be longer than 4000 bytes. The arguments cursor_begin and cursor_end are counted in bytes relative to the beginning of the submitted string buffer. Cursor should be hidden by the text input when both are equal to -1. cursor_begin indicates the beginning of the cursor. cursor_end indicates the end of the cursor. It may be equal or different than cursor_begin. Values set with this event are double-buffered. They must be applied on the next zwp_input_method_v2.commit event. The initial value of text is an empty string. The initial value of cursor_begin, and cursor_end are both 0. | |
| 81 | - | func (o *InputMethod) SetPreeditString(text string, cursorBegin int32, cursorEnd int32) error { | |
| 82 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "zwp_input_method_v2.set_preedit_string"}, wl.ArgString(text), wl.ArgInt(cursorBegin), wl.ArgInt(cursorEnd)); err != nil { | |
| 83 | - | return err | |
| 84 | - | } | |
| 85 | - | return nil | |
| 86 | - | } | |
| 87 | - | ||
| 88 | - | // Remove the surrounding text. before_length and after_length are the number of bytes before and after the current cursor index (excluding the preedit text) to delete. If any preedit text is present, it is replaced with the cursor for the purpose of this event. In effect before_length is counted from the beginning of preedit text, and after_length from its end (see commit event sequence). Values set with this event are double-buffered. They must be applied and reset to initial on the next zwp_input_method_v2.commit request. The initial values of both before_length and after_length are 0. | |
| 89 | - | func (o *InputMethod) DeleteSurroundingText(beforeLength uint32, afterLength uint32) error { | |
| 90 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 2, Name: "zwp_input_method_v2.delete_surrounding_text"}, wl.ArgUint(beforeLength), wl.ArgUint(afterLength)); err != nil { | |
| 91 | - | return err | |
| 92 | - | } | |
| 93 | - | return nil | |
| 94 | - | } | |
| 95 | - | ||
| 96 | - | // Apply state changes from commit_string, set_preedit_string and delete_surrounding_text requests. The state relating to these events is double-buffered, and each one modifies the pending state. This request replaces the current state with the pending state. The connected text input is expected to 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_input_method_v2 object known to the client. The value of the serial argument must be equal to the number of done events already issued by that object. When the compositor receives a commit request with a serial different than the number of past done events, it must proceed as normal, except it should not change the current state of the zwp_input_method_v2 object. | |
| 97 | - | func (o *InputMethod) Commit(serial uint32) error { | |
| 98 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 3, Name: "zwp_input_method_v2.commit"}, wl.ArgUint(serial)); err != nil { | |
| 99 | - | return err | |
| 100 | - | } | |
| 101 | - | return nil | |
| 102 | - | } | |
| 103 | - | ||
| 104 | - | // Creates a new zwp_input_popup_surface_v2 object wrapping a given surface. The surface gets assigned the "input_popup" role. If the surface already has an assigned role, the compositor must issue a protocol error. | |
| 105 | - | func (o *InputMethod) GetInputPopupSurface(surface *cross_wl_surface.Surface) (*InputPopupSurface, error) { | |
| 106 | - | var arg1 wl.Object | |
| 107 | - | if surface != nil { | |
| 108 | - | arg1 = surface | |
| 109 | - | } | |
| 110 | - | child := &InputPopupSurface{} | |
| 111 | - | child.SetContext(o.Context()) | |
| 112 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 4, Name: "zwp_input_method_v2.get_input_popup_surface", Child: child}, wl.ArgObject(child), wl.ArgObject(arg1)); err != nil { | |
| 113 | - | return nil, err | |
| 114 | - | } | |
| 115 | - | return child, nil | |
| 116 | - | } | |
| 117 | - | ||
| 118 | - | // 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. The compositor should send all keyboard events on the seat to the grab holder via the returned wl_keyboard object. Nevertheless, the compositor may decide not to forward any particular event. The compositor must not further process any event after it has been forwarded to the grab holder. Releasing the resulting wl_keyboard object releases the grab. | |
| 119 | - | func (o *InputMethod) GrabKeyboard() (*InputMethodKeyboardGrab, error) { | |
| 120 | - | child := &InputMethodKeyboardGrab{} | |
| 121 | - | child.SetContext(o.Context()) | |
| 122 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 5, Name: "zwp_input_method_v2.grab_keyboard", Child: child}, wl.ArgObject(child)); err != nil { | |
| 123 | - | return nil, err | |
| 124 | - | } | |
| 125 | - | return child, nil | |
| 126 | - | } | |
| 127 | - | ||
| 128 | - | // Destroys the zwp_text_input_v2 object and any associated child objects, i.e. zwp_input_popup_surface_v2 and zwp_input_method_keyboard_grab_v2. | |
| 129 | - | func (o *InputMethod) Destroy() error { | |
| 130 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 6, Name: "zwp_input_method_v2.destroy", Destructor: true}); err != nil { | |
| 131 | - | return err | |
| 132 | - | } | |
| 133 | - | return nil | |
| 134 | - | } | |
| 135 | - | ||
| 136 | - | // OnActivate registers a handler for the activate event. | |
| 137 | - | // | |
| 138 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 139 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 140 | - | func (o *InputMethod) OnActivate(handler func()) { | |
| 141 | - | if handler == nil { | |
| 142 | - | return | |
| 143 | - | } | |
| 144 | - | o.handlersMu.Lock() | |
| 145 | - | defer o.handlersMu.Unlock() | |
| 146 | - | o.onActivate = append(o.onActivate, handler) | |
| 147 | - | } | |
| 148 | - | ||
| 149 | - | // handlersForActivate returns the handlers registered for activate, taken | |
| 150 | - | // under the lock so a handler may register another handler while events are | |
| 151 | - | // being dispatched. | |
| 152 | - | func (o *InputMethod) handlersForActivate() []func() { | |
| 153 | - | o.handlersMu.Lock() | |
| 154 | - | defer o.handlersMu.Unlock() | |
| 155 | - | return o.onActivate | |
| 156 | - | } | |
| 157 | - | ||
| 158 | - | // OnDeactivate registers a handler for the deactivate event. | |
| 159 | - | // | |
| 160 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 161 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 162 | - | func (o *InputMethod) OnDeactivate(handler func()) { | |
| 163 | - | if handler == nil { | |
| 164 | - | return | |
| 165 | - | } | |
| 166 | - | o.handlersMu.Lock() | |
| 167 | - | defer o.handlersMu.Unlock() | |
| 168 | - | o.onDeactivate = append(o.onDeactivate, handler) | |
| 169 | - | } | |
| 170 | - | ||
| 171 | - | // handlersForDeactivate returns the handlers registered for deactivate, taken | |
| 172 | - | // under the lock so a handler may register another handler while events are | |
| 173 | - | // being dispatched. | |
| 174 | - | func (o *InputMethod) handlersForDeactivate() []func() { | |
| 175 | - | o.handlersMu.Lock() | |
| 176 | - | defer o.handlersMu.Unlock() | |
| 177 | - | return o.onDeactivate | |
| 178 | - | } | |
| 179 | - | ||
| 180 | - | // OnSurroundingText registers a handler for the surrounding_text event. | |
| 181 | - | // | |
| 182 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 183 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 184 | - | func (o *InputMethod) OnSurroundingText(handler func(text string, cursor uint32, anchor uint32)) { | |
| 185 | - | if handler == nil { | |
| 186 | - | return | |
| 187 | - | } | |
| 188 | - | o.handlersMu.Lock() | |
| 189 | - | defer o.handlersMu.Unlock() | |
| 190 | - | o.onSurroundingText = append(o.onSurroundingText, handler) | |
| 191 | - | } | |
| 192 | - | ||
| 193 | - | // handlersForSurroundingText returns the handlers registered for surrounding_text, taken | |
| 194 | - | // under the lock so a handler may register another handler while events are | |
| 195 | - | // being dispatched. | |
| 196 | - | func (o *InputMethod) handlersForSurroundingText() []func(text string, cursor uint32, anchor uint32) { | |
| 197 | - | o.handlersMu.Lock() | |
| 198 | - | defer o.handlersMu.Unlock() | |
| 199 | - | return o.onSurroundingText | |
| 200 | - | } | |
| 201 | - | ||
| 202 | - | // OnTextChangeCause registers a handler for the text_change_cause event. | |
| 203 | - | // | |
| 204 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 205 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 206 | - | func (o *InputMethod) OnTextChangeCause(handler func(cause uint32)) { | |
| 207 | - | if handler == nil { | |
| 208 | - | return | |
| 209 | - | } | |
| 210 | - | o.handlersMu.Lock() | |
| 211 | - | defer o.handlersMu.Unlock() | |
| 212 | - | o.onTextChangeCause = append(o.onTextChangeCause, handler) | |
| 213 | - | } | |
| 214 | - | ||
| 215 | - | // handlersForTextChangeCause returns the handlers registered for text_change_cause, taken | |
| 216 | - | // under the lock so a handler may register another handler while events are | |
| 217 | - | // being dispatched. | |
| 218 | - | func (o *InputMethod) handlersForTextChangeCause() []func(cause uint32) { | |
| 219 | - | o.handlersMu.Lock() | |
| 220 | - | defer o.handlersMu.Unlock() | |
| 221 | - | return o.onTextChangeCause | |
| 222 | - | } | |
| 223 | - | ||
| 224 | - | // OnContentType registers a handler for the content_type event. | |
| 225 | - | // | |
| 226 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 227 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 228 | - | func (o *InputMethod) OnContentType(handler func(hint uint32, purpose uint32)) { | |
| 229 | - | if handler == nil { | |
| 230 | - | return | |
| 231 | - | } | |
| 232 | - | o.handlersMu.Lock() | |
| 233 | - | defer o.handlersMu.Unlock() | |
| 234 | - | o.onContentType = append(o.onContentType, handler) | |
| 235 | - | } | |
| 236 | - | ||
| 237 | - | // handlersForContentType returns the handlers registered for content_type, taken | |
| 238 | - | // under the lock so a handler may register another handler while events are | |
| 239 | - | // being dispatched. | |
| 240 | - | func (o *InputMethod) handlersForContentType() []func(hint uint32, purpose uint32) { | |
| 241 | - | o.handlersMu.Lock() | |
| 242 | - | defer o.handlersMu.Unlock() | |
| 243 | - | return o.onContentType | |
| 244 | - | } | |
| 245 | - | ||
| 246 | - | // OnDone registers a handler for the done event. | |
| 247 | - | // | |
| 248 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 249 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 250 | - | func (o *InputMethod) OnDone(handler func()) { | |
| 251 | - | if handler == nil { | |
| 252 | - | return | |
| 253 | - | } | |
| 254 | - | o.handlersMu.Lock() | |
| 255 | - | defer o.handlersMu.Unlock() | |
| 256 | - | o.onDone = append(o.onDone, handler) | |
| 257 | - | } | |
| 258 | - | ||
| 259 | - | // handlersForDone returns the handlers registered for done, taken | |
| 260 | - | // under the lock so a handler may register another handler while events are | |
| 261 | - | // being dispatched. | |
| 262 | - | func (o *InputMethod) handlersForDone() []func() { | |
| 263 | - | o.handlersMu.Lock() | |
| 264 | - | defer o.handlersMu.Unlock() | |
| 265 | - | return o.onDone | |
| 266 | - | } | |
| 267 | - | ||
| 268 | - | // OnUnavailable registers a handler for the unavailable event. | |
| 269 | - | // | |
| 270 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 271 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 272 | - | func (o *InputMethod) OnUnavailable(handler func()) { | |
| 273 | - | if handler == nil { | |
| 274 | - | return | |
| 275 | - | } | |
| 276 | - | o.handlersMu.Lock() | |
| 277 | - | defer o.handlersMu.Unlock() | |
| 278 | - | o.onUnavailable = append(o.onUnavailable, handler) | |
| 279 | - | } | |
| 280 | - | ||
| 281 | - | // handlersForUnavailable returns the handlers registered for unavailable, taken | |
| 282 | - | // under the lock so a handler may register another handler while events are | |
| 283 | - | // being dispatched. | |
| 284 | - | func (o *InputMethod) handlersForUnavailable() []func() { | |
| 285 | - | o.handlersMu.Lock() | |
| 286 | - | defer o.handlersMu.Unlock() | |
| 287 | - | return o.onUnavailable | |
| 288 | - | } | |
| 289 | - | ||
| 290 | - | // EventSignature returns the declared event argument types in wire order. | |
| 291 | - | func (o *InputMethod) EventSignature(opcode uint16) (string, bool) { | |
| 292 | - | switch opcode { | |
| 293 | - | case 0: | |
| 294 | - | return "", true | |
| 295 | - | case 1: | |
| 296 | - | return "", true | |
| 297 | - | case 2: | |
| 298 | - | return "string,uint,uint,", true | |
| 299 | - | case 3: | |
| 300 | - | return "uint,", true | |
| 301 | - | case 4: | |
| 302 | - | return "uint,uint,", true | |
| 303 | - | case 5: | |
| 304 | - | return "", true | |
| 305 | - | case 6: | |
| 306 | - | return "", true | |
| 307 | - | default: | |
| 308 | - | return "", false | |
| 309 | - | } | |
| 310 | - | } | |
| 311 | - | ||
| 312 | - | // Dispatch decodes one event on zwp_input_method_v2 and calls the registered handlers. | |
| 313 | - | func (o *InputMethod) Dispatch(event *wl.Event) { | |
| 314 | - | switch event.Opcode { | |
| 315 | - | case 0: // activate | |
| 316 | - | ||
| 317 | - | for i, handler := range o.handlersForActivate() { | |
| 318 | - | _ = i | |
| 319 | - | handler() | |
| 320 | - | } | |
| 321 | - | case 1: // deactivate | |
| 322 | - | ||
| 323 | - | for i, handler := range o.handlersForDeactivate() { | |
| 324 | - | _ = i | |
| 325 | - | handler() | |
| 326 | - | } | |
| 327 | - | case 2: // surrounding_text | |
| 328 | - | text := event.String() | |
| 329 | - | cursor := event.Uint32() | |
| 330 | - | anchor := event.Uint32() | |
| 331 | - | ||
| 332 | - | for i, handler := range o.handlersForSurroundingText() { | |
| 333 | - | _ = i | |
| 334 | - | handler(text, cursor, anchor) | |
| 335 | - | } | |
| 336 | - | case 3: // text_change_cause | |
| 337 | - | cause := event.Uint32() | |
| 338 | - | ||
| 339 | - | for i, handler := range o.handlersForTextChangeCause() { | |
| 340 | - | _ = i | |
| 341 | - | handler(cause) | |
| 342 | - | } | |
| 343 | - | case 4: // content_type | |
| 344 | - | hint := event.Uint32() | |
| 345 | - | purpose := event.Uint32() | |
| 346 | - | ||
| 347 | - | for i, handler := range o.handlersForContentType() { | |
| 348 | - | _ = i | |
| 349 | - | handler(hint, purpose) | |
| 350 | - | } | |
| 351 | - | case 5: // done | |
| 352 | - | ||
| 353 | - | for i, handler := range o.handlersForDone() { | |
| 354 | - | _ = i | |
| 355 | - | handler() | |
| 356 | - | } | |
| 357 | - | case 6: // unavailable | |
| 358 | - | ||
| 359 | - | for i, handler := range o.handlersForUnavailable() { | |
| 360 | - | _ = i | |
| 361 | - | handler() | |
| 362 | - | } | |
| 363 | - | default: | |
| 364 | - | } | |
| 365 | - | } | |
| 366 | - | ||
| 367 | - | // InputPopupSurfaceInterface is the protocol interface name. | |
| 368 | - | const InputPopupSurfaceInterface = "zwp_input_popup_surface_v2" | |
| 369 | - | ||
| 370 | - | // InputPopupSurface is the generated binding for zwp_input_popup_surface_v2 version 1. | |
| 371 | - | type InputPopupSurface struct { | |
| 372 | - | wl.BaseProxy | |
| 373 | - | // handlersMu guards the handler slices: a client may register or replace | |
| 374 | - | // handlers while another goroutine dispatches events. | |
| 375 | - | handlersMu sync.Mutex | |
| 376 | - | onTextInputRectangle []func(x int32, y int32, width int32, height int32) | |
| 377 | - | } | |
| 378 | - | ||
| 379 | - | // NewInputPopupSurface returns an unbound InputPopupSurface. | |
| 380 | - | func NewInputPopupSurface(ctx *wl.Context) *InputPopupSurface { | |
| 381 | - | obj := &InputPopupSurface{} | |
| 382 | - | obj.SetContext(ctx) | |
| 383 | - | ctx.Register(obj) | |
| 384 | - | return obj | |
| 385 | - | } | |
| 386 | - | func (o *InputPopupSurface) Destroy() error { | |
| 387 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "zwp_input_popup_surface_v2.destroy", Destructor: true}); err != nil { | |
| 388 | - | return err | |
| 389 | - | } | |
| 390 | - | return nil | |
| 391 | - | } | |
| 392 | - | ||
| 393 | - | // OnTextInputRectangle registers a handler for the text_input_rectangle event. | |
| 394 | - | // | |
| 395 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 396 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 397 | - | func (o *InputPopupSurface) OnTextInputRectangle(handler func(x int32, y int32, width int32, height int32)) { | |
| 398 | - | if handler == nil { | |
| 399 | - | return | |
| 400 | - | } | |
| 401 | - | o.handlersMu.Lock() | |
| 402 | - | defer o.handlersMu.Unlock() | |
| 403 | - | o.onTextInputRectangle = append(o.onTextInputRectangle, handler) | |
| 404 | - | } | |
| 405 | - | ||
| 406 | - | // handlersForTextInputRectangle returns the handlers registered for text_input_rectangle, taken | |
| 407 | - | // under the lock so a handler may register another handler while events are | |
| 408 | - | // being dispatched. | |
| 409 | - | func (o *InputPopupSurface) handlersForTextInputRectangle() []func(x int32, y int32, width int32, height int32) { | |
| 410 | - | o.handlersMu.Lock() | |
| 411 | - | defer o.handlersMu.Unlock() | |
| 412 | - | return o.onTextInputRectangle | |
| 413 | - | } | |
| 414 | - | ||
| 415 | - | // EventSignature returns the declared event argument types in wire order. | |
| 416 | - | func (o *InputPopupSurface) EventSignature(opcode uint16) (string, bool) { | |
| 417 | - | switch opcode { | |
| 418 | - | case 0: | |
| 419 | - | return "int,int,int,int,", true | |
| 420 | - | default: | |
| 421 | - | return "", false | |
| 422 | - | } | |
| 423 | - | } | |
| 424 | - | ||
| 425 | - | // Dispatch decodes one event on zwp_input_popup_surface_v2 and calls the registered handlers. | |
| 426 | - | func (o *InputPopupSurface) Dispatch(event *wl.Event) { | |
| 427 | - | switch event.Opcode { | |
| 428 | - | case 0: // text_input_rectangle | |
| 429 | - | x := event.Int32() | |
| 430 | - | y := event.Int32() | |
| 431 | - | width := event.Int32() | |
| 432 | - | height := event.Int32() | |
| 433 | - | ||
| 434 | - | for i, handler := range o.handlersForTextInputRectangle() { | |
| 435 | - | _ = i | |
| 436 | - | handler(x, y, width, height) | |
| 437 | - | } | |
| 438 | - | default: | |
| 439 | - | } | |
| 440 | - | } | |
| 441 | - | ||
| 442 | - | // InputMethodKeyboardGrabInterface is the protocol interface name. | |
| 443 | - | const InputMethodKeyboardGrabInterface = "zwp_input_method_keyboard_grab_v2" | |
| 444 | - | ||
| 445 | - | // InputMethodKeyboardGrab is the generated binding for zwp_input_method_keyboard_grab_v2 version 1. | |
| 446 | - | type InputMethodKeyboardGrab struct { | |
| 447 | - | wl.BaseProxy | |
| 448 | - | // handlersMu guards the handler slices: a client may register or replace | |
| 449 | - | // handlers while another goroutine dispatches events. | |
| 450 | - | handlersMu sync.Mutex | |
| 451 | - | onKeymap []func(format uint32, fd *wl.OwnedFD, size uint32) | |
| 452 | - | onKey []func(serial uint32, time uint32, key uint32, state uint32) | |
| 453 | - | onModifiers []func(serial uint32, modsDepressed uint32, modsLatched uint32, modsLocked uint32, group uint32) | |
| 454 | - | onRepeatInfo []func(rate int32, delay int32) | |
| 455 | - | } | |
| 456 | - | ||
| 457 | - | // NewInputMethodKeyboardGrab returns an unbound InputMethodKeyboardGrab. | |
| 458 | - | func NewInputMethodKeyboardGrab(ctx *wl.Context) *InputMethodKeyboardGrab { | |
| 459 | - | obj := &InputMethodKeyboardGrab{} | |
| 460 | - | obj.SetContext(ctx) | |
| 461 | - | ctx.Register(obj) | |
| 462 | - | return obj | |
| 463 | - | } | |
| 464 | - | ||
| 465 | - | // release the grab object | |
| 466 | - | func (o *InputMethodKeyboardGrab) Release() error { | |
| 467 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "zwp_input_method_keyboard_grab_v2.release", Destructor: true}); err != nil { | |
| 468 | - | return err | |
| 469 | - | } | |
| 470 | - | return nil | |
| 471 | - | } | |
| 472 | - | ||
| 473 | - | // OnKeymap registers a handler for the keymap event. | |
| 474 | - | // | |
| 475 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 476 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 477 | - | func (o *InputMethodKeyboardGrab) OnKeymap(handler func(format uint32, fd *wl.OwnedFD, size uint32)) { | |
| 478 | - | if handler == nil { | |
| 479 | - | return | |
| 480 | - | } | |
| 481 | - | o.handlersMu.Lock() | |
| 482 | - | defer o.handlersMu.Unlock() | |
| 483 | - | o.onKeymap = append(o.onKeymap, handler) | |
| 484 | - | } | |
| 485 | - | ||
| 486 | - | // handlersForKeymap returns the handlers registered for keymap, taken | |
| 487 | - | // under the lock so a handler may register another handler while events are | |
| 488 | - | // being dispatched. | |
| 489 | - | func (o *InputMethodKeyboardGrab) handlersForKeymap() []func(format uint32, fd *wl.OwnedFD, size uint32) { | |
| 490 | - | o.handlersMu.Lock() | |
| 491 | - | defer o.handlersMu.Unlock() | |
| 492 | - | return o.onKeymap | |
| 493 | - | } | |
| 494 | - | ||
| 495 | - | // OnKey registers a handler for the key event. | |
| 496 | - | // | |
| 497 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 498 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 499 | - | func (o *InputMethodKeyboardGrab) OnKey(handler func(serial uint32, time uint32, key uint32, state uint32)) { | |
| 500 | - | if handler == nil { | |
| 501 | - | return | |
| 502 | - | } | |
| 503 | - | o.handlersMu.Lock() | |
| 504 | - | defer o.handlersMu.Unlock() | |
| 505 | - | o.onKey = append(o.onKey, handler) | |
| 506 | - | } | |
| 507 | - | ||
| 508 | - | // handlersForKey returns the handlers registered for key, taken | |
| 509 | - | // under the lock so a handler may register another handler while events are | |
| 510 | - | // being dispatched. | |
| 511 | - | func (o *InputMethodKeyboardGrab) handlersForKey() []func(serial uint32, time uint32, key uint32, state uint32) { | |
| 512 | - | o.handlersMu.Lock() | |
| 513 | - | defer o.handlersMu.Unlock() | |
| 514 | - | return o.onKey | |
| 515 | - | } | |
| 516 | - | ||
| 517 | - | // OnModifiers registers a handler for the modifiers event. | |
| 518 | - | // | |
| 519 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 520 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 521 | - | func (o *InputMethodKeyboardGrab) OnModifiers(handler func(serial uint32, modsDepressed uint32, modsLatched uint32, modsLocked uint32, group uint32)) { | |
| 522 | - | if handler == nil { | |
| 523 | - | return | |
| 524 | - | } | |
| 525 | - | o.handlersMu.Lock() | |
| 526 | - | defer o.handlersMu.Unlock() | |
| 527 | - | o.onModifiers = append(o.onModifiers, handler) | |
| 528 | - | } | |
| 529 | - | ||
| 530 | - | // handlersForModifiers returns the handlers registered for modifiers, taken | |
| 531 | - | // under the lock so a handler may register another handler while events are | |
| 532 | - | // being dispatched. | |
| 533 | - | func (o *InputMethodKeyboardGrab) handlersForModifiers() []func(serial uint32, modsDepressed uint32, modsLatched uint32, modsLocked uint32, group uint32) { | |
| 534 | - | o.handlersMu.Lock() | |
| 535 | - | defer o.handlersMu.Unlock() | |
| 536 | - | return o.onModifiers | |
| 537 | - | } | |
| 538 | - | ||
| 539 | - | // OnRepeatInfo registers a handler for the repeat_info event. | |
| 540 | - | // | |
| 541 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 542 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 543 | - | func (o *InputMethodKeyboardGrab) OnRepeatInfo(handler func(rate int32, delay int32)) { | |
| 544 | - | if handler == nil { | |
| 545 | - | return | |
| 546 | - | } | |
| 547 | - | o.handlersMu.Lock() | |
| 548 | - | defer o.handlersMu.Unlock() | |
| 549 | - | o.onRepeatInfo = append(o.onRepeatInfo, handler) | |
| 550 | - | } | |
| 551 | - | ||
| 552 | - | // handlersForRepeatInfo returns the handlers registered for repeat_info, taken | |
| 553 | - | // under the lock so a handler may register another handler while events are | |
| 554 | - | // being dispatched. | |
| 555 | - | func (o *InputMethodKeyboardGrab) handlersForRepeatInfo() []func(rate int32, delay int32) { | |
| 556 | - | o.handlersMu.Lock() | |
| 557 | - | defer o.handlersMu.Unlock() | |
| 558 | - | return o.onRepeatInfo | |
| 559 | - | } | |
| 560 | - | ||
| 561 | - | // EventSignature returns the declared event argument types in wire order. | |
| 562 | - | func (o *InputMethodKeyboardGrab) EventSignature(opcode uint16) (string, bool) { | |
| 563 | - | switch opcode { | |
| 564 | - | case 0: | |
| 565 | - | return "uint,fd,uint,", true | |
| 566 | - | case 1: | |
| 567 | - | return "uint,uint,uint,uint,", true | |
| 568 | - | case 2: | |
| 569 | - | return "uint,uint,uint,uint,uint,", true | |
| 570 | - | case 3: | |
| 571 | - | return "int,int,", true | |
| 572 | - | default: | |
| 573 | - | return "", false | |
| 574 | - | } | |
| 575 | - | } | |
| 576 | - | ||
| 577 | - | // Dispatch decodes one event on zwp_input_method_keyboard_grab_v2 and calls the registered handlers. | |
| 578 | - | func (o *InputMethodKeyboardGrab) Dispatch(event *wl.Event) { | |
| 579 | - | switch event.Opcode { | |
| 580 | - | case 0: // keymap | |
| 581 | - | format := event.Uint32() | |
| 582 | - | fd := event.FD() | |
| 583 | - | size := event.Uint32() | |
| 584 | - | ownedfd := fd | |
| 585 | - | defer ownedfd.Close() | |
| 586 | - | ||
| 587 | - | for i, handler := range o.handlersForKeymap() { | |
| 588 | - | if i > 0 { | |
| 589 | - | fd = nil | |
| 590 | - | } | |
| 591 | - | handler(format, fd, size) | |
| 592 | - | } | |
| 593 | - | case 1: // key | |
| 594 | - | serial := event.Uint32() | |
| 595 | - | time := event.Uint32() | |
| 596 | - | key := event.Uint32() | |
| 597 | - | state := event.Uint32() | |
| 598 | - | ||
| 599 | - | for i, handler := range o.handlersForKey() { | |
| 600 | - | _ = i | |
| 601 | - | handler(serial, time, key, state) | |
| 602 | - | } | |
| 603 | - | case 2: // modifiers | |
| 604 | - | serial := event.Uint32() | |
| 605 | - | modsDepressed := event.Uint32() | |
| 606 | - | modsLatched := event.Uint32() | |
| 607 | - | modsLocked := event.Uint32() | |
| 608 | - | group := event.Uint32() | |
| 609 | - | ||
| 610 | - | for i, handler := range o.handlersForModifiers() { | |
| 611 | - | _ = i | |
| 612 | - | handler(serial, modsDepressed, modsLatched, modsLocked, group) | |
| 613 | - | } | |
| 614 | - | case 3: // repeat_info | |
| 615 | - | rate := event.Int32() | |
| 616 | - | delay := event.Int32() | |
| 617 | - | ||
| 618 | - | for i, handler := range o.handlersForRepeatInfo() { | |
| 619 | - | _ = i | |
| 620 | - | handler(rate, delay) | |
| 621 | - | } | |
| 622 | - | default: | |
| 623 | - | } | |
| 624 | - | } | |
| 625 | - | ||
| 626 | - | // InputMethodManagerInterface is the protocol interface name. | |
| 627 | - | const InputMethodManagerInterface = "zwp_input_method_manager_v2" | |
| 628 | - | ||
| 629 | - | // InputMethodManager is the generated binding for zwp_input_method_manager_v2 version 1. | |
| 630 | - | type InputMethodManager struct { | |
| 631 | - | wl.BaseProxy | |
| 632 | - | } | |
| 633 | - | ||
| 634 | - | // NewInputMethodManager returns an unbound InputMethodManager. | |
| 635 | - | func NewInputMethodManager(ctx *wl.Context) *InputMethodManager { | |
| 636 | - | obj := &InputMethodManager{} | |
| 637 | - | obj.SetContext(ctx) | |
| 638 | - | ctx.Register(obj) | |
| 639 | - | return obj | |
| 640 | - | } | |
| 641 | - | ||
| 642 | - | // Request a new input zwp_input_method_v2 object associated with a given seat. | |
| 643 | - | func (o *InputMethodManager) GetInputMethod(seat *cross_wl_seat.Seat) (*InputMethod, error) { | |
| 644 | - | var arg0 wl.Object | |
| 645 | - | if seat != nil { | |
| 646 | - | arg0 = seat | |
| 647 | - | } | |
| 648 | - | child := &InputMethod{} | |
| 649 | - | child.SetContext(o.Context()) | |
| 650 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "zwp_input_method_manager_v2.get_input_method", Child: child}, wl.ArgObject(arg0), wl.ArgObject(child)); err != nil { | |
| 651 | - | return nil, err | |
| 652 | - | } | |
| 653 | - | return child, nil | |
| 654 | - | } | |
| 655 | - | ||
| 656 | - | // Destroys the zwp_input_method_manager_v2 object. The zwp_input_method_v2 objects originating from it remain valid. | |
| 657 | - | func (o *InputMethodManager) Destroy() error { | |
| 658 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "zwp_input_method_manager_v2.destroy", Destructor: true}); err != nil { | |
| 659 | - | return err | |
| 660 | - | } | |
| 661 | - | return nil | |
| 662 | - | } | |
| 663 | - | ||
| 664 | - | // EventSignature returns the declared event argument types in wire order. | |
| 665 | - | func (o *InputMethodManager) EventSignature(opcode uint16) (string, bool) { | |
| 666 | - | switch opcode { | |
| 667 | - | default: | |
| 668 | - | return "", false | |
| 669 | - | } | |
| 670 | - | } | |
| 671 | - | ||
| 672 | - | // Dispatch decodes one event on zwp_input_method_manager_v2 and calls the registered handlers. | |
| 673 | - | func (o *InputMethodManager) Dispatch(event *wl.Event) { | |
| 674 | - | switch event.Opcode { | |
| 675 | - | default: | |
| 676 | - | } | |
| 677 | - | } | |
D protocol/kdeserverdecoration/generate.go +0 -3
| @@ -1,3 +0,0 @@ | |||
| 1 | - | package kdeserverdecoration | |
| 2 | - | ||
| 3 | - | //go:generate go run ../../cmd/wlturbo-scanner -p kdeserverdecoration -o server-decoration_generated.go -import wl_surface=github.com/bnema/wlturbo/protocol/core server-decoration.xml | |
D protocol/kdeserverdecoration/server-decoration.xml +0 -85
| @@ -1,85 +0,0 @@ | |||
| 1 | - | <?xml version="1.0" encoding="UTF-8"?> | |
| 2 | - | <protocol name="server_decoration"> | |
| 3 | - | <copyright><![CDATA[ | |
| 4 | - | SPDX-FileCopyrightText: 2015 Martin Gräßlin | |
| 5 | - | ||
| 6 | - | SPDX-License-Identifier: LGPL-2.1-or-later | |
| 7 | - | ]]></copyright> | |
| 8 | - | <interface name="org_kde_kwin_server_decoration_manager" version="1"> | |
| 9 | - | <description summary="Server side window decoration manager"> | |
| 10 | - | This interface allows to coordinate whether the server should create | |
| 11 | - | a server-side window decoration around a wl_surface representing a | |
| 12 | - | shell surface (wl_shell_surface or similar). By announcing support | |
| 13 | - | for this interface the server indicates that it supports server | |
| 14 | - | side decorations. | |
| 15 | - | ||
| 16 | - | Use in conjunction with zxdg_decoration_manager_v1 is undefined. | |
| 17 | - | </description> | |
| 18 | - | <request name="create"> | |
| 19 | - | <description summary="Create a server-side decoration object for a given surface"> | |
| 20 | - | When a client creates a server-side decoration object it indicates | |
| 21 | - | that it supports the protocol. The client is supposed to tell the | |
| 22 | - | server whether it wants server-side decorations or will provide | |
| 23 | - | client-side decorations. | |
| 24 | - | ||
| 25 | - | If the client does not create a server-side decoration object for | |
| 26 | - | a surface the server interprets this as lack of support for this | |
| 27 | - | protocol and considers it as client-side decorated. Nevertheless a | |
| 28 | - | client-side decorated surface should use this protocol to indicate | |
| 29 | - | to the server that it does not want a server-side deco. | |
| 30 | - | </description> | |
| 31 | - | <arg name="id" type="new_id" interface="org_kde_kwin_server_decoration"/> | |
| 32 | - | <arg name="surface" type="object" interface="wl_surface"/> | |
| 33 | - | </request> | |
| 34 | - | <enum name="mode"> | |
| 35 | - | <description summary="Possible values to use in request_mode and the event mode."/> | |
| 36 | - | <entry name="None" value="0" summary="Undecorated: The surface is not decorated at all, neither server nor client-side. An example is a popup surface which should not be decorated."/> | |
| 37 | - | <entry name="Client" value="1" summary="Client-side decoration: The decoration is part of the surface and the client."/> | |
| 38 | - | <entry name="Server" value="2" summary="Server-side decoration: The server embeds the surface into a decoration frame."/> | |
| 39 | - | </enum> | |
| 40 | - | <event name="default_mode"> | |
| 41 | - | <description summary="The default mode used on the server"> | |
| 42 | - | This event is emitted directly after binding the interface. It contains | |
| 43 | - | the default mode for the decoration. When a new server decoration object | |
| 44 | - | is created this new object will be in the default mode until the first | |
| 45 | - | request_mode is requested. | |
| 46 | - | ||
| 47 | - | The server may change the default mode at any time. | |
| 48 | - | </description> | |
| 49 | - | <arg name="mode" type="uint" summary="The default decoration mode applied to newly created server decorations."/> | |
| 50 | - | </event> | |
| 51 | - | </interface> | |
| 52 | - | <interface name="org_kde_kwin_server_decoration" version="1"> | |
| 53 | - | <request name="release" type="destructor"> | |
| 54 | - | <description summary="release the server decoration object"/> | |
| 55 | - | </request> | |
| 56 | - | <enum name="mode"> | |
| 57 | - | <description summary="Possible values to use in request_mode and the event mode."/> | |
| 58 | - | <entry name="None" value="0" summary="Undecorated: The surface is not decorated at all, neither server nor client-side. An example is a popup surface which should not be decorated."/> | |
| 59 | - | <entry name="Client" value="1" summary="Client-side decoration: The decoration is part of the surface and the client."/> | |
| 60 | - | <entry name="Server" value="2" summary="Server-side decoration: The server embeds the surface into a decoration frame."/> | |
| 61 | - | </enum> | |
| 62 | - | <request name="request_mode"> | |
| 63 | - | <description summary="The decoration mode the surface wants to use."/> | |
| 64 | - | <arg name="mode" type="uint" summary="The mode this surface wants to use."/> | |
| 65 | - | </request> | |
| 66 | - | <event name="mode"> | |
| 67 | - | <description summary="The new decoration mode applied by the server"> | |
| 68 | - | This event is emitted directly after the decoration is created and | |
| 69 | - | represents the base decoration policy by the server. E.g. a server | |
| 70 | - | which wants all surfaces to be client-side decorated will send Client, | |
| 71 | - | a server which wants server-side decoration will send Server. | |
| 72 | - | ||
| 73 | - | The client can request a different mode through the decoration request. | |
| 74 | - | The server will acknowledge this by another event with the same mode. So | |
| 75 | - | even if a server prefers server-side decoration it's possible to force a | |
| 76 | - | client-side decoration. | |
| 77 | - | ||
| 78 | - | The server may emit this event at any time. In this case the client can | |
| 79 | - | again request a different mode. It's the responsibility of the server to | |
| 80 | - | prevent a feedback loop. | |
| 81 | - | </description> | |
| 82 | - | <arg name="mode" type="uint" summary="The decoration mode applied to the surface by the server."/> | |
| 83 | - | </event> | |
| 84 | - | </interface> | |
| 85 | - | </protocol> | |
D protocol/kdeserverdecoration/server-decoration_generated.go +0 -197
| @@ -1,197 +0,0 @@ | |||
| 1 | - | // Code generated by wlturbo-scanner. DO NOT EDIT. | |
| 2 | - | // Protocol: server_decoration | |
| 3 | - | // Source: server-decoration.xml | |
| 4 | - | ||
| 5 | - | // Upstream protocol copyright and license: | |
| 6 | - | // SPDX-FileCopyrightText: 2015 Martin Gräßlin | |
| 7 | - | // | |
| 8 | - | // SPDX-License-Identifier: LGPL-2.1-or-later | |
| 9 | - | ||
| 10 | - | package kdeserverdecoration | |
| 11 | - | ||
| 12 | - | import ( | |
| 13 | - | "sync" | |
| 14 | - | ||
| 15 | - | cross_wl_surface "github.com/bnema/wlturbo/protocol/core" | |
| 16 | - | "github.com/bnema/wlturbo/wl" | |
| 17 | - | ) | |
| 18 | - | ||
| 19 | - | // ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_NONE is the mode None value. | |
| 20 | - | const ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_NONE = 0 | |
| 21 | - | ||
| 22 | - | // ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_CLIENT is the mode Client value. | |
| 23 | - | const ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_CLIENT = 1 | |
| 24 | - | ||
| 25 | - | // ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_SERVER is the mode Server value. | |
| 26 | - | const ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_SERVER = 2 | |
| 27 | - | ||
| 28 | - | // ORG_KDE_KWIN_SERVER_DECORATION_MODE_NONE is the mode None value. | |
| 29 | - | const ORG_KDE_KWIN_SERVER_DECORATION_MODE_NONE = 0 | |
| 30 | - | ||
| 31 | - | // ORG_KDE_KWIN_SERVER_DECORATION_MODE_CLIENT is the mode Client value. | |
| 32 | - | const ORG_KDE_KWIN_SERVER_DECORATION_MODE_CLIENT = 1 | |
| 33 | - | ||
| 34 | - | // ORG_KDE_KWIN_SERVER_DECORATION_MODE_SERVER is the mode Server value. | |
| 35 | - | const ORG_KDE_KWIN_SERVER_DECORATION_MODE_SERVER = 2 | |
| 36 | - | ||
| 37 | - | // OrgKdeKwinServerDecorationManagerInterface is the protocol interface name. | |
| 38 | - | const OrgKdeKwinServerDecorationManagerInterface = "org_kde_kwin_server_decoration_manager" | |
| 39 | - | ||
| 40 | - | // OrgKdeKwinServerDecorationManager is the generated binding for org_kde_kwin_server_decoration_manager version 1. | |
| 41 | - | type OrgKdeKwinServerDecorationManager struct { | |
| 42 | - | wl.BaseProxy | |
| 43 | - | // handlersMu guards the handler slices: a client may register or replace | |
| 44 | - | // handlers while another goroutine dispatches events. | |
| 45 | - | handlersMu sync.Mutex | |
| 46 | - | onDefaultMode []func(mode uint32) | |
| 47 | - | } | |
| 48 | - | ||
| 49 | - | // NewOrgKdeKwinServerDecorationManager returns an unbound OrgKdeKwinServerDecorationManager. | |
| 50 | - | func NewOrgKdeKwinServerDecorationManager(ctx *wl.Context) *OrgKdeKwinServerDecorationManager { | |
| 51 | - | obj := &OrgKdeKwinServerDecorationManager{} | |
| 52 | - | obj.SetContext(ctx) | |
| 53 | - | ctx.Register(obj) | |
| 54 | - | return obj | |
| 55 | - | } | |
| 56 | - | ||
| 57 | - | // When a client creates a server-side decoration object it indicates that it supports the protocol. The client is supposed to tell the server whether it wants server-side decorations or will provide client-side decorations. If the client does not create a server-side decoration object for a surface the server interprets this as lack of support for this protocol and considers it as client-side decorated. Nevertheless a client-side decorated surface should use this protocol to indicate to the server that it does not want a server-side deco. | |
| 58 | - | func (o *OrgKdeKwinServerDecorationManager) Create(surface *cross_wl_surface.Surface) (*OrgKdeKwinServerDecoration, error) { | |
| 59 | - | var arg1 wl.Object | |
| 60 | - | if surface != nil { | |
| 61 | - | arg1 = surface | |
| 62 | - | } | |
| 63 | - | child := &OrgKdeKwinServerDecoration{} | |
| 64 | - | child.SetContext(o.Context()) | |
| 65 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "org_kde_kwin_server_decoration_manager.create", Child: child}, wl.ArgObject(child), wl.ArgObject(arg1)); err != nil { | |
| 66 | - | return nil, err | |
| 67 | - | } | |
| 68 | - | return child, nil | |
| 69 | - | } | |
| 70 | - | ||
| 71 | - | // OnDefaultMode registers a handler for the default_mode event. | |
| 72 | - | // | |
| 73 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 74 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 75 | - | func (o *OrgKdeKwinServerDecorationManager) OnDefaultMode(handler func(mode uint32)) { | |
| 76 | - | if handler == nil { | |
| 77 | - | return | |
| 78 | - | } | |
| 79 | - | o.handlersMu.Lock() | |
| 80 | - | defer o.handlersMu.Unlock() | |
| 81 | - | o.onDefaultMode = append(o.onDefaultMode, handler) | |
| 82 | - | } | |
| 83 | - | ||
| 84 | - | // handlersForDefaultMode returns the handlers registered for default_mode, taken | |
| 85 | - | // under the lock so a handler may register another handler while events are | |
| 86 | - | // being dispatched. | |
| 87 | - | func (o *OrgKdeKwinServerDecorationManager) handlersForDefaultMode() []func(mode uint32) { | |
| 88 | - | o.handlersMu.Lock() | |
| 89 | - | defer o.handlersMu.Unlock() | |
| 90 | - | return o.onDefaultMode | |
| 91 | - | } | |
| 92 | - | ||
| 93 | - | // EventSignature returns the declared event argument types in wire order. | |
| 94 | - | func (o *OrgKdeKwinServerDecorationManager) EventSignature(opcode uint16) (string, bool) { | |
| 95 | - | switch opcode { | |
| 96 | - | case 0: | |
| 97 | - | return "uint,", true | |
| 98 | - | default: | |
| 99 | - | return "", false | |
| 100 | - | } | |
| 101 | - | } | |
| 102 | - | ||
| 103 | - | // Dispatch decodes one event on org_kde_kwin_server_decoration_manager and calls the registered handlers. | |
| 104 | - | func (o *OrgKdeKwinServerDecorationManager) Dispatch(event *wl.Event) { | |
| 105 | - | switch event.Opcode { | |
| 106 | - | case 0: // default_mode | |
| 107 | - | mode := event.Uint32() | |
| 108 | - | ||
| 109 | - | for i, handler := range o.handlersForDefaultMode() { | |
| 110 | - | _ = i | |
| 111 | - | handler(mode) | |
| 112 | - | } | |
| 113 | - | default: | |
| 114 | - | } | |
| 115 | - | } | |
| 116 | - | ||
| 117 | - | // OrgKdeKwinServerDecorationInterface is the protocol interface name. | |
| 118 | - | const OrgKdeKwinServerDecorationInterface = "org_kde_kwin_server_decoration" | |
| 119 | - | ||
| 120 | - | // OrgKdeKwinServerDecoration is the generated binding for org_kde_kwin_server_decoration version 1. | |
| 121 | - | type OrgKdeKwinServerDecoration struct { | |
| 122 | - | wl.BaseProxy | |
| 123 | - | // handlersMu guards the handler slices: a client may register or replace | |
| 124 | - | // handlers while another goroutine dispatches events. | |
| 125 | - | handlersMu sync.Mutex | |
| 126 | - | onMode []func(mode uint32) | |
| 127 | - | } | |
| 128 | - | ||
| 129 | - | // NewOrgKdeKwinServerDecoration returns an unbound OrgKdeKwinServerDecoration. | |
| 130 | - | func NewOrgKdeKwinServerDecoration(ctx *wl.Context) *OrgKdeKwinServerDecoration { | |
| 131 | - | obj := &OrgKdeKwinServerDecoration{} | |
| 132 | - | obj.SetContext(ctx) | |
| 133 | - | ctx.Register(obj) | |
| 134 | - | return obj | |
| 135 | - | } | |
| 136 | - | ||
| 137 | - | // release the server decoration object | |
| 138 | - | func (o *OrgKdeKwinServerDecoration) Release() error { | |
| 139 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "org_kde_kwin_server_decoration.release", Destructor: true}); err != nil { | |
| 140 | - | return err | |
| 141 | - | } | |
| 142 | - | return nil | |
| 143 | - | } | |
| 144 | - | ||
| 145 | - | // The decoration mode the surface wants to use. | |
| 146 | - | func (o *OrgKdeKwinServerDecoration) RequestMode(mode uint32) error { | |
| 147 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "org_kde_kwin_server_decoration.request_mode"}, wl.ArgUint(mode)); err != nil { | |
| 148 | - | return err | |
| 149 | - | } | |
| 150 | - | return nil | |
| 151 | - | } | |
| 152 | - | ||
| 153 | - | // OnMode registers a handler for the mode event. | |
| 154 | - | // | |
| 155 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 156 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 157 | - | func (o *OrgKdeKwinServerDecoration) OnMode(handler func(mode uint32)) { | |
| 158 | - | if handler == nil { | |
| 159 | - | return | |
| 160 | - | } | |
| 161 | - | o.handlersMu.Lock() | |
| 162 | - | defer o.handlersMu.Unlock() | |
| 163 | - | o.onMode = append(o.onMode, handler) | |
| 164 | - | } | |
| 165 | - | ||
| 166 | - | // handlersForMode returns the handlers registered for mode, taken | |
| 167 | - | // under the lock so a handler may register another handler while events are | |
| 168 | - | // being dispatched. | |
| 169 | - | func (o *OrgKdeKwinServerDecoration) handlersForMode() []func(mode uint32) { | |
| 170 | - | o.handlersMu.Lock() | |
| 171 | - | defer o.handlersMu.Unlock() | |
| 172 | - | return o.onMode | |
| 173 | - | } | |
| 174 | - | ||
| 175 | - | // EventSignature returns the declared event argument types in wire order. | |
| 176 | - | func (o *OrgKdeKwinServerDecoration) EventSignature(opcode uint16) (string, bool) { | |
| 177 | - | switch opcode { | |
| 178 | - | case 0: | |
| 179 | - | return "uint,", true | |
| 180 | - | default: | |
| 181 | - | return "", false | |
| 182 | - | } | |
| 183 | - | } | |
| 184 | - | ||
| 185 | - | // Dispatch decodes one event on org_kde_kwin_server_decoration and calls the registered handlers. | |
| 186 | - | func (o *OrgKdeKwinServerDecoration) Dispatch(event *wl.Event) { | |
| 187 | - | switch event.Opcode { | |
| 188 | - | case 0: // mode | |
| 189 | - | mode := event.Uint32() | |
| 190 | - | ||
| 191 | - | for i, handler := range o.handlersForMode() { | |
| 192 | - | _ = i | |
| 193 | - | handler(mode) | |
| 194 | - | } | |
| 195 | - | default: | |
| 196 | - | } | |
| 197 | - | } | |
D protocol/layershell/generate.go +0 -3
| @@ -1,3 +0,0 @@ | |||
| 1 | - | package layershell | |
| 2 | - | ||
| 3 | - | //go:generate go run ../../cmd/wlturbo-scanner -p layershell -o wlr-layer-shell-unstable-v1_generated.go -import wl_surface=github.com/bnema/wlturbo/protocol/core -import wl_output=github.com/bnema/wlturbo/protocol/core -import xdg_popup=github.com/bnema/wlturbo/protocol/xdgshell wlr-layer-shell-unstable-v1.xml | |
D protocol/layershell/wlr-layer-shell-unstable-v1.xml +0 -407
| @@ -1,407 +0,0 @@ | |||
| 1 | - | <?xml version="1.0" encoding="UTF-8"?> | |
| 2 | - | <protocol name="wlr_layer_shell_unstable_v1"> | |
| 3 | - | <copyright> | |
| 4 | - | Copyright © 2017 Drew DeVault | |
| 5 | - | ||
| 6 | - | Permission to use, copy, modify, distribute, and sell this | |
| 7 | - | software and its documentation for any purpose is hereby granted | |
| 8 | - | without fee, provided that the above copyright notice appear in | |
| 9 | - | all copies and that both that copyright notice and this permission | |
| 10 | - | notice appear in supporting documentation, and that the name of | |
| 11 | - | the copyright holders not be used in advertising or publicity | |
| 12 | - | pertaining to distribution of the software without specific, | |
| 13 | - | written prior permission. The copyright holders make no | |
| 14 | - | representations about the suitability of this software for any | |
| 15 | - | purpose. It is provided "as is" without express or implied | |
| 16 | - | warranty. | |
| 17 | - | ||
| 18 | - | THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS | |
| 19 | - | SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | |
| 20 | - | FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY | |
| 21 | - | SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
| 22 | - | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN | |
| 23 | - | AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | |
| 24 | - | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF | |
| 25 | - | THIS SOFTWARE. | |
| 26 | - | </copyright> | |
| 27 | - | ||
| 28 | - | <interface name="zwlr_layer_shell_v1" version="5"> | |
| 29 | - | <description summary="create surfaces that are layers of the desktop"> | |
| 30 | - | Clients can use this interface to assign the surface_layer role to | |
| 31 | - | wl_surfaces. Such surfaces are assigned to a "layer" of the output and | |
| 32 | - | rendered with a defined z-depth respective to each other. They may also be | |
| 33 | - | anchored to the edges and corners of a screen and specify input handling | |
| 34 | - | semantics. This interface should be suitable for the implementation of | |
| 35 | - | many desktop shell components, and a broad number of other applications | |
| 36 | - | that interact with the desktop. | |
| 37 | - | </description> | |
| 38 | - | ||
| 39 | - | <request name="get_layer_surface"> | |
| 40 | - | <description summary="create a layer_surface from a surface"> | |
| 41 | - | Create a layer surface for an existing surface. This assigns the role of | |
| 42 | - | layer_surface, or raises a protocol error if another role is already | |
| 43 | - | assigned. | |
| 44 | - | ||
| 45 | - | Creating a layer surface from a wl_surface which has a buffer attached | |
| 46 | - | or committed is a client error, and any attempts by a client to attach | |
| 47 | - | or manipulate a buffer prior to the first layer_surface.configure call | |
| 48 | - | must also be treated as errors. | |
| 49 | - | ||
| 50 | - | After creating a layer_surface object and setting it up, the client | |
| 51 | - | must perform an initial commit without any buffer attached. | |
| 52 | - | The compositor will reply with a layer_surface.configure event. | |
| 53 | - | The client must acknowledge it and is then allowed to attach a buffer | |
| 54 | - | to map the surface. | |
| 55 | - | ||
| 56 | - | You may pass NULL for output to allow the compositor to decide which | |
| 57 | - | output to use. Generally this will be the one that the user most | |
| 58 | - | recently interacted with. | |
| 59 | - | ||
| 60 | - | Clients can specify a namespace that defines the purpose of the layer | |
| 61 | - | surface. | |
| 62 | - | </description> | |
| 63 | - | <arg name="id" type="new_id" interface="zwlr_layer_surface_v1"/> | |
| 64 | - | <arg name="surface" type="object" interface="wl_surface"/> | |
| 65 | - | <arg name="output" type="object" interface="wl_output" allow-null="true"/> | |
| 66 | - | <arg name="layer" type="uint" enum="layer" summary="layer to add this surface to"/> | |
| 67 | - | <arg name="namespace" type="string" summary="namespace for the layer surface"/> | |
| 68 | - | </request> | |
| 69 | - | ||
| 70 | - | <enum name="error"> | |
| 71 | - | <entry name="role" value="0" summary="wl_surface has another role"/> | |
| 72 | - | <entry name="invalid_layer" value="1" summary="layer value is invalid"/> | |
| 73 | - | <entry name="already_constructed" value="2" summary="wl_surface has a buffer attached or committed"/> | |
| 74 | - | </enum> | |
| 75 | - | ||
| 76 | - | <enum name="layer"> | |
| 77 | - | <description summary="available layers for surfaces"> | |
| 78 | - | These values indicate which layers a surface can be rendered in. They | |
| 79 | - | are ordered by z depth, bottom-most first. Traditional shell surfaces | |
| 80 | - | will typically be rendered between the bottom and top layers. | |
| 81 | - | Fullscreen shell surfaces are typically rendered at the top layer. | |
| 82 | - | Multiple surfaces can share a single layer, and ordering within a | |
| 83 | - | single layer is undefined. | |
| 84 | - | </description> | |
| 85 | - | ||
| 86 | - | <entry name="background" value="0"/> | |
| 87 | - | <entry name="bottom" value="1"/> | |
| 88 | - | <entry name="top" value="2"/> | |
| 89 | - | <entry name="overlay" value="3"/> | |
| 90 | - | </enum> | |
| 91 | - | ||
| 92 | - | <!-- Version 3 additions --> | |
| 93 | - | ||
| 94 | - | <request name="destroy" type="destructor" since="3"> | |
| 95 | - | <description summary="destroy the layer_shell object"> | |
| 96 | - | This request indicates that the client will not use the layer_shell | |
| 97 | - | object any more. Objects that have been created through this instance | |
| 98 | - | are not affected. | |
| 99 | - | </description> | |
| 100 | - | </request> | |
| 101 | - | </interface> | |
| 102 | - | ||
| 103 | - | <interface name="zwlr_layer_surface_v1" version="5"> | |
| 104 | - | <description summary="layer metadata interface"> | |
| 105 | - | An interface that may be implemented by a wl_surface, for surfaces that | |
| 106 | - | are designed to be rendered as a layer of a stacked desktop-like | |
| 107 | - | environment. | |
| 108 | - | ||
| 109 | - | Layer surface state (layer, size, anchor, exclusive zone, | |
| 110 | - | margin, interactivity) is double-buffered, and will be applied at the | |
| 111 | - | time wl_surface.commit of the corresponding wl_surface is called. | |
| 112 | - | ||
| 113 | - | Attaching a null buffer to a layer surface unmaps it. | |
| 114 | - | ||
| 115 | - | Unmapping a layer_surface means that the surface cannot be shown by the | |
| 116 | - | compositor until it is explicitly mapped again. The layer_surface | |
| 117 | - | returns to the state it had right after layer_shell.get_layer_surface. | |
| 118 | - | The client can re-map the surface by performing a commit without any | |
| 119 | - | buffer attached, waiting for a configure event and handling it as usual. | |
| 120 | - | </description> | |
| 121 | - | ||
| 122 | - | <request name="set_size"> | |
| 123 | - | <description summary="sets the size of the surface"> | |
| 124 | - | Sets the size of the surface in surface-local coordinates. The | |
| 125 | - | compositor will display the surface centered with respect to its | |
| 126 | - | anchors. | |
| 127 | - | ||
| 128 | - | If you pass 0 for either value, the compositor will assign it and | |
| 129 | - | inform you of the assignment in the configure event. You must set your | |
| 130 | - | anchor to opposite edges in the dimensions you omit; not doing so is a | |
| 131 | - | protocol error. Both values are 0 by default. | |
| 132 | - | ||
| 133 | - | Size is double-buffered, see wl_surface.commit. | |
| 134 | - | </description> | |
| 135 | - | <arg name="width" type="uint"/> | |
| 136 | - | <arg name="height" type="uint"/> | |
| 137 | - | </request> | |
| 138 | - | ||
| 139 | - | <request name="set_anchor"> | |
| 140 | - | <description summary="configures the anchor point of the surface"> | |
| 141 | - | Requests that the compositor anchor the surface to the specified edges | |
| 142 | - | and corners. If two orthogonal edges are specified (e.g. 'top' and | |
| 143 | - | 'left'), then the anchor point will be the intersection of the edges | |
| 144 | - | (e.g. the top left corner of the output); otherwise the anchor point | |
| 145 | - | will be centered on that edge, or in the center if none is specified. | |
| 146 | - | ||
| 147 | - | Anchor is double-buffered, see wl_surface.commit. | |
| 148 | - | </description> | |
| 149 | - | <arg name="anchor" type="uint" enum="anchor"/> | |
| 150 | - | </request> | |
| 151 | - | ||
| 152 | - | <request name="set_exclusive_zone"> | |
| 153 | - | <description summary="configures the exclusive geometry of this surface"> | |
| 154 | - | Requests that the compositor avoids occluding an area with other | |
| 155 | - | surfaces. The compositor's use of this information is | |
| 156 | - | implementation-dependent - do not assume that this region will not | |
| 157 | - | actually be occluded. | |
| 158 | - | ||
| 159 | - | A positive value is only meaningful if the surface is anchored to one | |
| 160 | - | edge or an edge and both perpendicular edges. If the surface is not | |
| 161 | - | anchored, anchored to only two perpendicular edges (a corner), anchored | |
| 162 | - | to only two parallel edges or anchored to all edges, a positive value | |
| 163 | - | will be treated the same as zero. | |
| 164 | - | ||
| 165 | - | A positive zone is the distance from the edge in surface-local | |
| 166 | - | coordinates to consider exclusive. | |
| 167 | - | ||
| 168 | - | Surfaces that do not wish to have an exclusive zone may instead specify | |
| 169 | - | how they should interact with surfaces that do. If set to zero, the | |
| 170 | - | surface indicates that it would like to be moved to avoid occluding | |
| 171 | - | surfaces with a positive exclusive zone. If set to -1, the surface | |
| 172 | - | indicates that it would not like to be moved to accommodate for other | |
| 173 | - | surfaces, and the compositor should extend it all the way to the edges | |
| 174 | - | it is anchored to. | |
| 175 | - | ||
| 176 | - | For example, a panel might set its exclusive zone to 10, so that | |
| 177 | - | maximized shell surfaces are not shown on top of it. A notification | |
| 178 | - | might set its exclusive zone to 0, so that it is moved to avoid | |
| 179 | - | occluding the panel, but shell surfaces are shown underneath it. A | |
| 180 | - | wallpaper or lock screen might set their exclusive zone to -1, so that | |
| 181 | - | they stretch below or over the panel. | |
| 182 | - | ||
| 183 | - | The default value is 0. | |
| 184 | - | ||
| 185 | - | Exclusive zone is double-buffered, see wl_surface.commit. | |
| 186 | - | </description> | |
| 187 | - | <arg name="zone" type="int"/> | |
| 188 | - | </request> | |
| 189 | - | ||
| 190 | - | <request name="set_margin"> | |
| 191 | - | <description summary="sets a margin from the anchor point"> | |
| 192 | - | Requests that the surface be placed some distance away from the anchor | |
| 193 | - | point on the output, in surface-local coordinates. Setting this value | |
| 194 | - | for edges you are not anchored to has no effect. | |
| 195 | - | ||
| 196 | - | The exclusive zone includes the margin. | |
| 197 | - | ||
| 198 | - | Margin is double-buffered, see wl_surface.commit. | |
| 199 | - | </description> | |
| 200 | - | <arg name="top" type="int"/> | |
| 201 | - | <arg name="right" type="int"/> | |
| 202 | - | <arg name="bottom" type="int"/> | |
| 203 | - | <arg name="left" type="int"/> | |
| 204 | - | </request> | |
| 205 | - | ||
| 206 | - | <enum name="keyboard_interactivity"> | |
| 207 | - | <description summary="types of keyboard interaction possible for a layer shell surface"> | |
| 208 | - | Types of keyboard interaction possible for layer shell surfaces. The | |
| 209 | - | rationale for this is twofold: (1) some applications are not interested | |
| 210 | - | in keyboard events and not allowing them to be focused can improve the | |
| 211 | - | desktop experience; (2) some applications will want to take exclusive | |
| 212 | - | keyboard focus. | |
| 213 | - | </description> | |
| 214 | - | ||
| 215 | - | <entry name="none" value="0"> | |
| 216 | - | <description summary="no keyboard focus is possible"> | |
| 217 | - | This value indicates that this surface is not interested in keyboard | |
| 218 | - | events and the compositor should never assign it the keyboard focus. | |
| 219 | - | ||
| 220 | - | This is the default value, set for newly created layer shell surfaces. | |
| 221 | - | ||
| 222 | - | This is useful for e.g. desktop widgets that display information or | |
| 223 | - | only have interaction with non-keyboard input devices. | |
| 224 | - | </description> | |
| 225 | - | </entry> | |
| 226 | - | <entry name="exclusive" value="1"> | |
| 227 | - | <description summary="request exclusive keyboard focus"> | |
| 228 | - | Request exclusive keyboard focus if this surface is above the shell surface layer. | |
| 229 | - | ||
| 230 | - | For the top and overlay layers, the seat will always give | |
| 231 | - | exclusive keyboard focus to the top-most layer which has keyboard | |
| 232 | - | interactivity set to exclusive. If this layer contains multiple | |
| 233 | - | surfaces with keyboard interactivity set to exclusive, the compositor | |
| 234 | - | determines the one receiving keyboard events in an implementation- | |
| 235 | - | defined manner. In this case, no guarantee is made when this surface | |
| 236 | - | will receive keyboard focus (if ever). | |
| 237 | - | ||
| 238 | - | For the bottom and background layers, the compositor is allowed to use | |
| 239 | - | normal focus semantics. | |
| 240 | - | ||
| 241 | - | This setting is mainly intended for applications that need to ensure | |
| 242 | - | they receive all keyboard events, such as a lock screen or a password | |
| 243 | - | prompt. | |
| 244 | - | </description> | |
| 245 | - | </entry> | |
| 246 | - | <entry name="on_demand" value="2" since="4"> | |
| 247 | - | <description summary="request regular keyboard focus semantics"> | |
| 248 | - | This requests the compositor to allow this surface to be focused and | |
| 249 | - | unfocused by the user in an implementation-defined manner. The user | |
| 250 | - | should be able to unfocus this surface even regardless of the layer | |
| 251 | - | it is on. | |
| 252 | - | ||
| 253 | - | Typically, the compositor will want to use its normal mechanism to | |
| 254 | - | manage keyboard focus between layer shell surfaces with this setting | |
| 255 | - | and regular toplevels on the desktop layer (e.g. click to focus). | |
| 256 | - | Nevertheless, it is possible for a compositor to require a special | |
| 257 | - | interaction to focus or unfocus layer shell surfaces (e.g. requiring | |
| 258 | - | a click even if focus follows the mouse normally, or providing a | |
| 259 | - | keybinding to switch focus between layers). | |
| 260 | - | ||
| 261 | - | This setting is mainly intended for desktop shell components (e.g. | |
| 262 | - | panels) that allow keyboard interaction. Using this option can allow | |
| 263 | - | implementing a desktop shell that can be fully usable without the | |
| 264 | - | mouse. | |
| 265 | - | </description> | |
| 266 | - | </entry> | |
| 267 | - | </enum> | |
| 268 | - | ||
| 269 | - | <request name="set_keyboard_interactivity"> | |
| 270 | - | <description summary="requests keyboard events"> | |
| 271 | - | Set how keyboard events are delivered to this surface. By default, | |
| 272 | - | layer shell surfaces do not receive keyboard events; this request can | |
| 273 | - | be used to change this. | |
| 274 | - | ||
| 275 | - | This setting is inherited by child surfaces set by the get_popup | |
| 276 | - | request. | |
| 277 | - | ||
| 278 | - | Layer surfaces receive pointer, touch, and tablet events normally. If | |
| 279 | - | you do not want to receive them, set the input region on your surface | |
| 280 | - | to an empty region. | |
| 281 | - | ||
| 282 | - | Keyboard interactivity is double-buffered, see wl_surface.commit. | |
| 283 | - | </description> | |
| 284 | - | <arg name="keyboard_interactivity" type="uint" enum="keyboard_interactivity"/> | |
| 285 | - | </request> | |
| 286 | - | ||
| 287 | - | <request name="get_popup"> | |
| 288 | - | <description summary="assign this layer_surface as an xdg_popup parent"> | |
| 289 | - | This assigns an xdg_popup's parent to this layer_surface. This popup | |
| 290 | - | should have been created via xdg_surface::get_popup with the parent set | |
| 291 | - | to NULL, and this request must be invoked before committing the popup's | |
| 292 | - | initial state. | |
| 293 | - | ||
| 294 | - | See the documentation of xdg_popup for more details about what an | |
| 295 | - | xdg_popup is and how it is used. | |
| 296 | - | </description> | |
| 297 | - | <arg name="popup" type="object" interface="xdg_popup"/> | |
| 298 | - | </request> | |
| 299 | - | ||
| 300 | - | <request name="ack_configure"> | |
| 301 | - | <description summary="ack a configure event"> | |
| 302 | - | When a configure event is received, if a client commits the | |
| 303 | - | surface in response to the configure event, then the client | |
| 304 | - | must make an ack_configure request sometime before the commit | |
| 305 | - | request, passing along the serial of the configure event. | |
| 306 | - | ||
| 307 | - | If the client receives multiple configure events before it | |
| 308 | - | can respond to one, it only has to ack the last configure event. | |
| 309 | - | ||
| 310 | - | A client is not required to commit immediately after sending | |
| 311 | - | an ack_configure request - it may even ack_configure several times | |
| 312 | - | before its next surface commit. | |
| 313 | - | ||
| 314 | - | A client may send multiple ack_configure requests before committing, but | |
| 315 | - | only the last request sent before a commit indicates which configure | |
| 316 | - | event the client really is responding to. | |
| 317 | - | </description> | |
| 318 | - | <arg name="serial" type="uint" summary="the serial from the configure event"/> | |
| 319 | - | </request> | |
| 320 | - | ||
| 321 | - | <request name="destroy" type="destructor"> | |
| 322 | - | <description summary="destroy the layer_surface"> | |
| 323 | - | This request destroys the layer surface. | |
| 324 | - | </description> | |
| 325 | - | </request> | |
| 326 | - | ||
| 327 | - | <event name="configure"> | |
| 328 | - | <description summary="suggest a surface change"> | |
| 329 | - | The configure event asks the client to resize its surface. | |
| 330 | - | ||
| 331 | - | Clients should arrange their surface for the new states, and then send | |
| 332 | - | an ack_configure request with the serial sent in this configure event at | |
| 333 | - | some point before committing the new surface. | |
| 334 | - | ||
| 335 | - | The client is free to dismiss all but the last configure event it | |
| 336 | - | received. | |
| 337 | - | ||
| 338 | - | The width and height arguments specify the size of the window in | |
| 339 | - | surface-local coordinates. | |
| 340 | - | ||
| 341 | - | The size is a hint, in the sense that the client is free to ignore it if | |
| 342 | - | it doesn't resize, pick a smaller size (to satisfy aspect ratio or | |
| 343 | - | resize in steps of NxM pixels). If the client picks a smaller size and | |
| 344 | - | is anchored to two opposite anchors (e.g. 'top' and 'bottom'), the | |
| 345 | - | surface will be centered on this axis. | |
| 346 | - | ||
| 347 | - | If the width or height arguments are zero, it means the client should | |
| 348 | - | decide its own window dimension. | |
| 349 | - | </description> | |
| 350 | - | <arg name="serial" type="uint"/> | |
| 351 | - | <arg name="width" type="uint"/> | |
| 352 | - | <arg name="height" type="uint"/> | |
| 353 | - | </event> | |
| 354 | - | ||
| 355 | - | <event name="closed"> | |
| 356 | - | <description summary="surface should be closed"> | |
| 357 | - | The closed event is sent by the compositor when the surface will no | |
| 358 | - | longer be shown. The output may have been destroyed or the user may | |
| 359 | - | have asked for it to be removed. Further changes to the surface will be | |
| 360 | - | ignored. The client should destroy the resource after receiving this | |
| 361 | - | event, and create a new surface if they so choose. | |
| 362 | - | </description> | |
| 363 | - | </event> | |
| 364 | - | ||
| 365 | - | <enum name="error"> | |
| 366 | - | <entry name="invalid_surface_state" value="0" summary="provided surface state is invalid"/> | |
| 367 | - | <entry name="invalid_size" value="1" summary="size is invalid"/> | |
| 368 | - | <entry name="invalid_anchor" value="2" summary="anchor bitfield is invalid"/> | |
| 369 | - | <entry name="invalid_keyboard_interactivity" value="3" summary="keyboard interactivity is invalid"/> | |
| 370 | - | <entry name="invalid_exclusive_edge" value="4" summary="exclusive edge is invalid given the surface anchors"/> | |
| 371 | - | </enum> | |
| 372 | - | ||
| 373 | - | <enum name="anchor" bitfield="true"> | |
| 374 | - | <entry name="top" value="1" summary="the top edge of the anchor rectangle"/> | |
| 375 | - | <entry name="bottom" value="2" summary="the bottom edge of the anchor rectangle"/> | |
| 376 | - | <entry name="left" value="4" summary="the left edge of the anchor rectangle"/> | |
| 377 | - | <entry name="right" value="8" summary="the right edge of the anchor rectangle"/> | |
| 378 | - | </enum> | |
| 379 | - | ||
| 380 | - | <!-- Version 2 additions --> | |
| 381 | - | ||
| 382 | - | <request name="set_layer" since="2"> | |
| 383 | - | <description summary="change the layer of the surface"> | |
| 384 | - | Change the layer that the surface is rendered on. | |
| 385 | - | ||
| 386 | - | Layer is double-buffered, see wl_surface.commit. | |
| 387 | - | </description> | |
| 388 | - | <arg name="layer" type="uint" enum="zwlr_layer_shell_v1.layer" summary="layer to move this surface to"/> | |
| 389 | - | </request> | |
| 390 | - | ||
| 391 | - | <!-- Version 5 additions --> | |
| 392 | - | ||
| 393 | - | <request name="set_exclusive_edge" since="5"> | |
| 394 | - | <description summary="set the edge the exclusive zone will be applied to"> | |
| 395 | - | Requests an edge for the exclusive zone to apply. The exclusive | |
| 396 | - | edge will be automatically deduced from anchor points when possible, | |
| 397 | - | but when the surface is anchored to a corner, it will be necessary | |
| 398 | - | to set it explicitly to disambiguate, as it is not possible to deduce | |
| 399 | - | which one of the two corner edges should be used. | |
| 400 | - | ||
| 401 | - | The edge must be one the surface is anchored to, otherwise the | |
| 402 | - | invalid_exclusive_edge protocol error will be raised. | |
| 403 | - | </description> | |
| 404 | - | <arg name="edge" type="uint" enum="anchor"/> | |
| 405 | - | </request> | |
| 406 | - | </interface> | |
| 407 | - | </protocol> | |
D protocol/layershell/wlr-layer-shell-unstable-v1_generated.go +0 -335
| @@ -1,335 +0,0 @@ | |||
| 1 | - | // Code generated by wlturbo-scanner. DO NOT EDIT. | |
| 2 | - | // Protocol: wlr_layer_shell_unstable_v1 | |
| 3 | - | // Source: wlr-layer-shell-unstable-v1.xml | |
| 4 | - | ||
| 5 | - | // Upstream protocol copyright and license: | |
| 6 | - | // Copyright © 2017 Drew DeVault | |
| 7 | - | // | |
| 8 | - | // Permission to use, copy, modify, distribute, and sell this | |
| 9 | - | // software and its documentation for any purpose is hereby granted | |
| 10 | - | // without fee, provided that the above copyright notice appear in | |
| 11 | - | // all copies and that both that copyright notice and this permission | |
| 12 | - | // notice appear in supporting documentation, and that the name of | |
| 13 | - | // the copyright holders not be used in advertising or publicity | |
| 14 | - | // pertaining to distribution of the software without specific, | |
| 15 | - | // written prior permission. The copyright holders make no | |
| 16 | - | // representations about the suitability of this software for any | |
| 17 | - | // purpose. It is provided "as is" without express or implied | |
| 18 | - | // warranty. | |
| 19 | - | // | |
| 20 | - | // THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS | |
| 21 | - | // SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | |
| 22 | - | // FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY | |
| 23 | - | // SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
| 24 | - | // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN | |
| 25 | - | // AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | |
| 26 | - | // ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF | |
| 27 | - | // THIS SOFTWARE. | |
| 28 | - | ||
| 29 | - | package layershell | |
| 30 | - | ||
| 31 | - | import ( | |
| 32 | - | "sync" | |
| 33 | - | ||
| 34 | - | cross_wl_output "github.com/bnema/wlturbo/protocol/core" | |
| 35 | - | cross_wl_surface "github.com/bnema/wlturbo/protocol/core" | |
| 36 | - | cross_xdg_popup "github.com/bnema/wlturbo/protocol/xdgshell" | |
| 37 | - | "github.com/bnema/wlturbo/wl" | |
| 38 | - | ) | |
| 39 | - | ||
| 40 | - | // ERROR_ROLE is the error role value. | |
| 41 | - | const ERROR_ROLE = 0 | |
| 42 | - | ||
| 43 | - | // ERROR_INVALID_LAYER is the error invalid_layer value. | |
| 44 | - | const ERROR_INVALID_LAYER = 1 | |
| 45 | - | ||
| 46 | - | // ERROR_ALREADY_CONSTRUCTED is the error already_constructed value. | |
| 47 | - | const ERROR_ALREADY_CONSTRUCTED = 2 | |
| 48 | - | ||
| 49 | - | // LAYER_BACKGROUND is the layer background value. | |
| 50 | - | const LAYER_BACKGROUND = 0 | |
| 51 | - | ||
| 52 | - | // LAYER_BOTTOM is the layer bottom value. | |
| 53 | - | const LAYER_BOTTOM = 1 | |
| 54 | - | ||
| 55 | - | // LAYER_TOP is the layer top value. | |
| 56 | - | const LAYER_TOP = 2 | |
| 57 | - | ||
| 58 | - | // LAYER_OVERLAY is the layer overlay value. | |
| 59 | - | const LAYER_OVERLAY = 3 | |
| 60 | - | ||
| 61 | - | // KEYBOARD_INTERACTIVITY_NONE is the keyboard_interactivity none value. | |
| 62 | - | const KEYBOARD_INTERACTIVITY_NONE = 0 | |
| 63 | - | ||
| 64 | - | // KEYBOARD_INTERACTIVITY_EXCLUSIVE is the keyboard_interactivity exclusive value. | |
| 65 | - | const KEYBOARD_INTERACTIVITY_EXCLUSIVE = 1 | |
| 66 | - | ||
| 67 | - | // KEYBOARD_INTERACTIVITY_ON_DEMAND is the keyboard_interactivity on_demand value. | |
| 68 | - | const KEYBOARD_INTERACTIVITY_ON_DEMAND = 2 | |
| 69 | - | ||
| 70 | - | // ERROR_INVALID_SURFACE_STATE is the error invalid_surface_state value. | |
| 71 | - | const ERROR_INVALID_SURFACE_STATE = 0 | |
| 72 | - | ||
| 73 | - | // ERROR_INVALID_SIZE is the error invalid_size value. | |
| 74 | - | const ERROR_INVALID_SIZE = 1 | |
| 75 | - | ||
| 76 | - | // ERROR_INVALID_ANCHOR is the error invalid_anchor value. | |
| 77 | - | const ERROR_INVALID_ANCHOR = 2 | |
| 78 | - | ||
| 79 | - | // ERROR_INVALID_KEYBOARD_INTERACTIVITY is the error invalid_keyboard_interactivity value. | |
| 80 | - | const ERROR_INVALID_KEYBOARD_INTERACTIVITY = 3 | |
| 81 | - | ||
| 82 | - | // ERROR_INVALID_EXCLUSIVE_EDGE is the error invalid_exclusive_edge value. | |
| 83 | - | const ERROR_INVALID_EXCLUSIVE_EDGE = 4 | |
| 84 | - | ||
| 85 | - | // ANCHOR_TOP is the anchor top value. | |
| 86 | - | const ANCHOR_TOP = 1 | |
| 87 | - | ||
| 88 | - | // ANCHOR_BOTTOM is the anchor bottom value. | |
| 89 | - | const ANCHOR_BOTTOM = 2 | |
| 90 | - | ||
| 91 | - | // ANCHOR_LEFT is the anchor left value. | |
| 92 | - | const ANCHOR_LEFT = 4 | |
| 93 | - | ||
| 94 | - | // ANCHOR_RIGHT is the anchor right value. | |
| 95 | - | const ANCHOR_RIGHT = 8 | |
| 96 | - | ||
| 97 | - | // LayerShellInterface is the protocol interface name. | |
| 98 | - | const LayerShellInterface = "zwlr_layer_shell_v1" | |
| 99 | - | ||
| 100 | - | // LayerShell is the generated binding for zwlr_layer_shell_v1 version 5. | |
| 101 | - | type LayerShell struct { | |
| 102 | - | wl.BaseProxy | |
| 103 | - | } | |
| 104 | - | ||
| 105 | - | // NewLayerShell returns an unbound LayerShell. | |
| 106 | - | func NewLayerShell(ctx *wl.Context) *LayerShell { | |
| 107 | - | obj := &LayerShell{} | |
| 108 | - | obj.SetContext(ctx) | |
| 109 | - | ctx.Register(obj) | |
| 110 | - | return obj | |
| 111 | - | } | |
| 112 | - | ||
| 113 | - | // 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. | |
| 114 | - | func (o *LayerShell) GetLayerSurface(surface *cross_wl_surface.Surface, output *cross_wl_output.Output, layer uint32, namespace string) (*LayerSurface, error) { | |
| 115 | - | var arg1 wl.Object | |
| 116 | - | if surface != nil { | |
| 117 | - | arg1 = surface | |
| 118 | - | } | |
| 119 | - | var arg2 wl.Object | |
| 120 | - | if output != nil { | |
| 121 | - | arg2 = output | |
| 122 | - | } | |
| 123 | - | child := &LayerSurface{} | |
| 124 | - | child.SetContext(o.Context()) | |
| 125 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "zwlr_layer_shell_v1.get_layer_surface", Child: child}, wl.ArgObject(child), wl.ArgObject(arg1), wl.ArgObject(arg2), wl.ArgUint(layer), wl.ArgString(namespace)); err != nil { | |
| 126 | - | return nil, err | |
| 127 | - | } | |
| 128 | - | return child, nil | |
| 129 | - | } | |
| 130 | - | ||
| 131 | - | // 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. | |
| 132 | - | func (o *LayerShell) Destroy() error { | |
| 133 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "zwlr_layer_shell_v1.destroy", Since: 3, Destructor: true}); err != nil { | |
| 134 | - | return err | |
| 135 | - | } | |
| 136 | - | return nil | |
| 137 | - | } | |
| 138 | - | ||
| 139 | - | // EventSignature returns the declared event argument types in wire order. | |
| 140 | - | func (o *LayerShell) EventSignature(opcode uint16) (string, bool) { | |
| 141 | - | switch opcode { | |
| 142 | - | default: | |
| 143 | - | return "", false | |
| 144 | - | } | |
| 145 | - | } | |
| 146 | - | ||
| 147 | - | // Dispatch decodes one event on zwlr_layer_shell_v1 and calls the registered handlers. | |
| 148 | - | func (o *LayerShell) Dispatch(event *wl.Event) { | |
| 149 | - | switch event.Opcode { | |
| 150 | - | default: | |
| 151 | - | } | |
| 152 | - | } | |
| 153 | - | ||
| 154 | - | // LayerSurfaceInterface is the protocol interface name. | |
| 155 | - | const LayerSurfaceInterface = "zwlr_layer_surface_v1" | |
| 156 | - | ||
| 157 | - | // LayerSurface is the generated binding for zwlr_layer_surface_v1 version 5. | |
| 158 | - | type LayerSurface struct { | |
| 159 | - | wl.BaseProxy | |
| 160 | - | // handlersMu guards the handler slices: a client may register or replace | |
| 161 | - | // handlers while another goroutine dispatches events. | |
| 162 | - | handlersMu sync.Mutex | |
| 163 | - | onConfigure []func(serial uint32, width uint32, height uint32) | |
| 164 | - | onClosed []func() | |
| 165 | - | } | |
| 166 | - | ||
| 167 | - | // NewLayerSurface returns an unbound LayerSurface. | |
| 168 | - | func NewLayerSurface(ctx *wl.Context) *LayerSurface { | |
| 169 | - | obj := &LayerSurface{} | |
| 170 | - | obj.SetContext(ctx) | |
| 171 | - | ctx.Register(obj) | |
| 172 | - | return obj | |
| 173 | - | } | |
| 174 | - | ||
| 175 | - | // 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. | |
| 176 | - | func (o *LayerSurface) SetSize(width uint32, height uint32) error { | |
| 177 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "zwlr_layer_surface_v1.set_size"}, wl.ArgUint(width), wl.ArgUint(height)); err != nil { | |
| 178 | - | return err | |
| 179 | - | } | |
| 180 | - | return nil | |
| 181 | - | } | |
| 182 | - | ||
| 183 | - | // 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. | |
| 184 | - | func (o *LayerSurface) SetAnchor(anchor uint32) error { | |
| 185 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "zwlr_layer_surface_v1.set_anchor"}, wl.ArgUint(anchor)); err != nil { | |
| 186 | - | return err | |
| 187 | - | } | |
| 188 | - | return nil | |
| 189 | - | } | |
| 190 | - | ||
| 191 | - | // 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. | |
| 192 | - | func (o *LayerSurface) SetExclusiveZone(zone int32) error { | |
| 193 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 2, Name: "zwlr_layer_surface_v1.set_exclusive_zone"}, wl.ArgInt(zone)); err != nil { | |
| 194 | - | return err | |
| 195 | - | } | |
| 196 | - | return nil | |
| 197 | - | } | |
| 198 | - | ||
| 199 | - | // 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. | |
| 200 | - | func (o *LayerSurface) SetMargin(top int32, right int32, bottom int32, left int32) error { | |
| 201 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 3, Name: "zwlr_layer_surface_v1.set_margin"}, wl.ArgInt(top), wl.ArgInt(right), wl.ArgInt(bottom), wl.ArgInt(left)); err != nil { | |
| 202 | - | return err | |
| 203 | - | } | |
| 204 | - | return nil | |
| 205 | - | } | |
| 206 | - | ||
| 207 | - | // 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. | |
| 208 | - | func (o *LayerSurface) SetKeyboardInteractivity(keyboardInteractivity uint32) error { | |
| 209 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 4, Name: "zwlr_layer_surface_v1.set_keyboard_interactivity"}, wl.ArgUint(keyboardInteractivity)); err != nil { | |
| 210 | - | return err | |
| 211 | - | } | |
| 212 | - | return nil | |
| 213 | - | } | |
| 214 | - | ||
| 215 | - | // 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. | |
| 216 | - | func (o *LayerSurface) GetPopup(popup *cross_xdg_popup.XdgPopup) error { | |
| 217 | - | var arg0 wl.Object | |
| 218 | - | if popup != nil { | |
| 219 | - | arg0 = popup | |
| 220 | - | } | |
| 221 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 5, Name: "zwlr_layer_surface_v1.get_popup"}, wl.ArgObject(arg0)); err != nil { | |
| 222 | - | return err | |
| 223 | - | } | |
| 224 | - | return nil | |
| 225 | - | } | |
| 226 | - | ||
| 227 | - | // 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. | |
| 228 | - | func (o *LayerSurface) AckConfigure(serial uint32) error { | |
| 229 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 6, Name: "zwlr_layer_surface_v1.ack_configure"}, wl.ArgUint(serial)); err != nil { | |
| 230 | - | return err | |
| 231 | - | } | |
| 232 | - | return nil | |
| 233 | - | } | |
| 234 | - | ||
| 235 | - | // This request destroys the layer surface. | |
| 236 | - | func (o *LayerSurface) Destroy() error { | |
| 237 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 7, Name: "zwlr_layer_surface_v1.destroy", Destructor: true}); err != nil { | |
| 238 | - | return err | |
| 239 | - | } | |
| 240 | - | return nil | |
| 241 | - | } | |
| 242 | - | ||
| 243 | - | // Change the layer that the surface is rendered on. Layer is double-buffered, see wl_surface.commit. | |
| 244 | - | func (o *LayerSurface) SetLayer(layer uint32) error { | |
| 245 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 8, Name: "zwlr_layer_surface_v1.set_layer", Since: 2}, wl.ArgUint(layer)); err != nil { | |
| 246 | - | return err | |
| 247 | - | } | |
| 248 | - | return nil | |
| 249 | - | } | |
| 250 | - | ||
| 251 | - | // Requests an edge for the exclusive zone to apply. The exclusive edge will be automatically deduced from anchor points when possible, but when the surface is anchored to a corner, it will be necessary to set it explicitly to disambiguate, as it is not possible to deduce which one of the two corner edges should be used. The edge must be one the surface is anchored to, otherwise the invalid_exclusive_edge protocol error will be raised. | |
| 252 | - | func (o *LayerSurface) SetExclusiveEdge(edge uint32) error { | |
| 253 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 9, Name: "zwlr_layer_surface_v1.set_exclusive_edge", Since: 5}, wl.ArgUint(edge)); err != nil { | |
| 254 | - | return err | |
| 255 | - | } | |
| 256 | - | return nil | |
| 257 | - | } | |
| 258 | - | ||
| 259 | - | // OnConfigure registers a handler for the configure event. | |
| 260 | - | // | |
| 261 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 262 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 263 | - | func (o *LayerSurface) OnConfigure(handler func(serial uint32, width uint32, height uint32)) { | |
| 264 | - | if handler == nil { | |
| 265 | - | return | |
| 266 | - | } | |
| 267 | - | o.handlersMu.Lock() | |
| 268 | - | defer o.handlersMu.Unlock() | |
| 269 | - | o.onConfigure = append(o.onConfigure, handler) | |
| 270 | - | } | |
| 271 | - | ||
| 272 | - | // handlersForConfigure returns the handlers registered for configure, taken | |
| 273 | - | // under the lock so a handler may register another handler while events are | |
| 274 | - | // being dispatched. | |
| 275 | - | func (o *LayerSurface) handlersForConfigure() []func(serial uint32, width uint32, height uint32) { | |
| 276 | - | o.handlersMu.Lock() | |
| 277 | - | defer o.handlersMu.Unlock() | |
| 278 | - | return o.onConfigure | |
| 279 | - | } | |
| 280 | - | ||
| 281 | - | // OnClosed registers a handler for the closed event. | |
| 282 | - | // | |
| 283 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 284 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 285 | - | func (o *LayerSurface) OnClosed(handler func()) { | |
| 286 | - | if handler == nil { | |
| 287 | - | return | |
| 288 | - | } | |
| 289 | - | o.handlersMu.Lock() | |
| 290 | - | defer o.handlersMu.Unlock() | |
| 291 | - | o.onClosed = append(o.onClosed, handler) | |
| 292 | - | } | |
| 293 | - | ||
| 294 | - | // handlersForClosed returns the handlers registered for closed, taken | |
| 295 | - | // under the lock so a handler may register another handler while events are | |
| 296 | - | // being dispatched. | |
| 297 | - | func (o *LayerSurface) handlersForClosed() []func() { | |
| 298 | - | o.handlersMu.Lock() | |
| 299 | - | defer o.handlersMu.Unlock() | |
| 300 | - | return o.onClosed | |
| 301 | - | } | |
| 302 | - | ||
| 303 | - | // EventSignature returns the declared event argument types in wire order. | |
| 304 | - | func (o *LayerSurface) EventSignature(opcode uint16) (string, bool) { | |
| 305 | - | switch opcode { | |
| 306 | - | case 0: | |
| 307 | - | return "uint,uint,uint,", true | |
| 308 | - | case 1: | |
| 309 | - | return "", true | |
| 310 | - | default: | |
| 311 | - | return "", false | |
| 312 | - | } | |
| 313 | - | } | |
| 314 | - | ||
| 315 | - | // Dispatch decodes one event on zwlr_layer_surface_v1 and calls the registered handlers. | |
| 316 | - | func (o *LayerSurface) Dispatch(event *wl.Event) { | |
| 317 | - | switch event.Opcode { | |
| 318 | - | case 0: // configure | |
| 319 | - | serial := event.Uint32() | |
| 320 | - | width := event.Uint32() | |
| 321 | - | height := event.Uint32() | |
| 322 | - | ||
| 323 | - | for i, handler := range o.handlersForConfigure() { | |
| 324 | - | _ = i | |
| 325 | - | handler(serial, width, height) | |
| 326 | - | } | |
| 327 | - | case 1: // closed | |
| 328 | - | ||
| 329 | - | for i, handler := range o.handlersForClosed() { | |
| 330 | - | _ = i | |
| 331 | - | handler() | |
| 332 | - | } | |
| 333 | - | default: | |
| 334 | - | } | |
| 335 | - | } | |
D protocol/linuxdmabuf/linux-dmabuf-v1.xml +0 -623 collapsed to keep the page light
D protocol/linuxdmabuf/linux-dmabuf-v1_generated.go +0 -630 collapsed to keep the page light
D protocol/linuxdmabuf/table.go +0 -68
| @@ -1,68 +0,0 @@ | |||
| 1 | - | package linuxdmabuf | |
| 2 | - | ||
| 3 | - | import ( | |
| 4 | - | "encoding/binary" | |
| 5 | - | "fmt" | |
| 6 | - | "io" | |
| 7 | - | ||
| 8 | - | "github.com/bnema/wlturbo/wl" | |
| 9 | - | "golang.org/x/sys/unix" | |
| 10 | - | ) | |
| 11 | - | ||
| 12 | - | // FormatEntry is one 16-byte format-table record. Padding is ignored. | |
| 13 | - | type FormatEntry struct { | |
| 14 | - | Format uint32 | |
| 15 | - | Modifier uint64 | |
| 16 | - | } | |
| 17 | - | ||
| 18 | - | // ReadFormatTable consumes an owned format_table descriptor, even on error. | |
| 19 | - | // It reads a bounded snapshot with pread rather than mapping compositor-owned | |
| 20 | - | // memory, avoiding SIGBUS if the backing file is unexpectedly truncated. | |
| 21 | - | func ReadFormatTable(fd *wl.OwnedFD, size uint32) ([]FormatEntry, error) { | |
| 22 | - | if fd == nil { | |
| 23 | - | return nil, fmt.Errorf("missing format table descriptor") | |
| 24 | - | } | |
| 25 | - | n, err := fd.Take() | |
| 26 | - | if err != nil { | |
| 27 | - | return nil, err | |
| 28 | - | } | |
| 29 | - | defer unix.Close(n) | |
| 30 | - | if size%16 != 0 || size > 16<<20 { | |
| 31 | - | return nil, fmt.Errorf("invalid format table size %d", size) | |
| 32 | - | } | |
| 33 | - | b := make([]byte, size) | |
| 34 | - | for off := 0; off < len(b); { | |
| 35 | - | read, e := unix.Pread(n, b[off:], int64(off)) | |
| 36 | - | off += read | |
| 37 | - | if e == unix.EINTR { | |
| 38 | - | continue | |
| 39 | - | } | |
| 40 | - | if e != nil { | |
| 41 | - | return nil, e | |
| 42 | - | } | |
| 43 | - | if read == 0 { | |
| 44 | - | return nil, io.ErrUnexpectedEOF | |
| 45 | - | } | |
| 46 | - | } | |
| 47 | - | entries := make([]FormatEntry, size/16) | |
| 48 | - | for i := range entries { | |
| 49 | - | off := i * 16 | |
| 50 | - | entries[i] = FormatEntry{binary.NativeEndian.Uint32(b[off:]), binary.NativeEndian.Uint64(b[off+8:])} | |
| 51 | - | } | |
| 52 | - | return entries, nil | |
| 53 | - | } | |
| 54 | - | ||
| 55 | - | // TrancheIndices decodes the uint16 indices into a format table. | |
| 56 | - | func TrancheIndices(data []byte, count int) ([]uint16, error) { | |
| 57 | - | if len(data)%2 != 0 { | |
| 58 | - | return nil, fmt.Errorf("odd tranche indices length") | |
| 59 | - | } | |
| 60 | - | indices := make([]uint16, len(data)/2) | |
| 61 | - | for i := range indices { | |
| 62 | - | indices[i] = binary.NativeEndian.Uint16(data[i*2:]) | |
| 63 | - | if int(indices[i]) >= count { | |
| 64 | - | return nil, fmt.Errorf("format table index %d out of range", indices[i]) | |
| 65 | - | } | |
| 66 | - | } | |
| 67 | - | return indices, nil | |
| 68 | - | } | |
D protocol/linuxdmabuf/table_test.go +0 -28
| @@ -1,28 +0,0 @@ | |||
| 1 | - | //go:build linux | |
| 2 | - | ||
| 3 | - | package linuxdmabuf_test | |
| 4 | - | ||
| 5 | - | import ( | |
| 6 | - | "encoding/binary" | |
| 7 | - | "github.com/bnema/wlturbo/protocol/linuxdmabuf" | |
| 8 | - | "testing" | |
| 9 | - | ) | |
| 10 | - | ||
| 11 | - | func TestTrancheIndices(t *testing.T) { | |
| 12 | - | b := make([]byte, 4) | |
| 13 | - | binary.NativeEndian.PutUint16(b, 1) | |
| 14 | - | binary.NativeEndian.PutUint16(b[2:], 0) | |
| 15 | - | got, e := linuxdmabuf.TrancheIndices(b, 2) | |
| 16 | - | if e != nil || len(got) != 2 || got[0] != 1 || got[1] != 0 { | |
| 17 | - | t.Fatalf("indices %v %v", got, e) | |
| 18 | - | } | |
| 19 | - | if _, e = linuxdmabuf.TrancheIndices(b, 1); e == nil { | |
| 20 | - | t.Fatal("out of range accepted") | |
| 21 | - | } | |
| 22 | - | if _, e = linuxdmabuf.TrancheIndices(b[:3], 2); e == nil { | |
| 23 | - | t.Fatal("odd length accepted") | |
| 24 | - | } | |
| 25 | - | if _, e = linuxdmabuf.ReadFormatTable(nil, 0); e == nil { | |
| 26 | - | t.Fatal("missing fd accepted") | |
| 27 | - | } | |
| 28 | - | } | |
D protocol/negotiation_test.go +0 -50
| @@ -1,50 +0,0 @@ | |||
| 1 | - | //go:build linux | |
| 2 | - | ||
| 3 | - | package protocol_test | |
| 4 | - | ||
| 5 | - | import ( | |
| 6 | - | "encoding/binary" | |
| 7 | - | "errors" | |
| 8 | - | "testing" | |
| 9 | - | ||
| 10 | - | "github.com/bnema/wlturbo" | |
| 11 | - | "github.com/bnema/wlturbo/protocol/xdgshell" | |
| 12 | - | ) | |
| 13 | - | ||
| 14 | - | func TestAnnouncedVersionNegotiation(t *testing.T) { | |
| 15 | - | c, p := pair(t) | |
| 16 | - | d, e := wlturbo.ConnectFromConn(c) | |
| 17 | - | noerr(t, e) | |
| 18 | - | defer d.Close() | |
| 19 | - | request(t, p) | |
| 20 | - | iface := xdgshell.XdgWmBaseInterface | |
| 21 | - | if v, e := d.Registry().BindNegotiated(iface, 6, xdgshell.NewXdgWmBase(d.Context())); v != 0 || !errors.Is(e, wlturbo.ErrGlobalNotFound) { | |
| 22 | - | t.Fatalf("missing: %d %v", v, e) | |
| 23 | - | } | |
| 24 | - | if v, e := d.Registry().BindNegotiated(iface, 0, xdgshell.NewXdgWmBase(d.Context())); v != 0 || e == nil || errors.Is(e, wlturbo.ErrGlobalNotFound) { | |
| 25 | - | t.Fatalf("unsupported zero: %d %v", v, e) | |
| 26 | - | } | |
| 27 | - | for i, version := range []uint32{2, 9} { | |
| 28 | - | name := uint32(30 + i) | |
| 29 | - | announcement := append(msg(0, 0, name)[8:], str(iface)...) | |
| 30 | - | announcement = append(announcement, msg(0, 0, version)[8:]...) | |
| 31 | - | send(t, p, payload(d.Registry().ID(), 0, announcement...)) | |
| 32 | - | noerr(t, d.Dispatch()) | |
| 33 | - | proxy := xdgshell.NewXdgWmBase(d.Context()) | |
| 34 | - | if v, e := d.Registry().BindNegotiated(iface, 0, proxy); v != 0 || e == nil || errors.Is(e, wlturbo.ErrGlobalNotFound) { | |
| 35 | - | t.Fatalf("supported zero with global: %d %v", v, e) | |
| 36 | - | } | |
| 37 | - | negotiated, e := d.Registry().BindNegotiated(iface, 6, proxy) | |
| 38 | - | noerr(t, e) | |
| 39 | - | want := version | |
| 40 | - | if want > 6 { | |
| 41 | - | want = 6 | |
| 42 | - | } | |
| 43 | - | _, op, body := request(t, p) | |
| 44 | - | if op != 0 || negotiated != want || binary.NativeEndian.Uint32(body) != name || binary.NativeEndian.Uint32(body[len(body)-8:]) != want || binary.NativeEndian.Uint32(body[len(body)-4:]) != proxy.ID() { | |
| 45 | - | t.Fatalf("server=%d negotiated=%d wire=%x", version, negotiated, body) | |
| 46 | - | } | |
| 47 | - | send(t, p, msg(d.Registry().ID(), 1, name)) | |
| 48 | - | noerr(t, d.Dispatch()) | |
| 49 | - | } | |
| 50 | - | } | |
D protocol/outputmanagement/generate.go +0 -3
| @@ -1,3 +0,0 @@ | |||
| 1 | - | package outputmanagement | |
| 2 | - | ||
| 3 | - | //go:generate go run ../../cmd/wlturbo-scanner -p outputmanagement -o wlr-output-management-unstable-v1_generated.go wlr-output-management-unstable-v1.xml | |
D protocol/outputmanagement/wlr-output-management-unstable-v1.xml +0 -611 collapsed to keep the page light
D protocol/outputmanagement/wlr-output-management-unstable-v1_generated.go +0 -1146 collapsed to keep the page light
D protocol/outputpower/generate.go +0 -3
| @@ -1,3 +0,0 @@ | |||
| 1 | - | package outputpower | |
| 2 | - | ||
| 3 | - | //go:generate go run ../../cmd/wlturbo-scanner -p outputpower -o wlr-output-power-management-unstable-v1_generated.go -import wl_output=github.com/bnema/wlturbo/protocol/core wlr-output-power-management-unstable-v1.xml | |
D protocol/outputpower/wlr-output-power-management-unstable-v1.xml +0 -128
| @@ -1,128 +0,0 @@ | |||
| 1 | - | <?xml version="1.0" encoding="UTF-8"?> | |
| 2 | - | <protocol name="wlr_output_power_management_unstable_v1"> | |
| 3 | - | <copyright> | |
| 4 | - | Copyright © 2019 Purism SPC | |
| 5 | - | ||
| 6 | - | Permission is hereby granted, free of charge, to any person obtaining a | |
| 7 | - | copy of this software and associated documentation files (the "Software"), | |
| 8 | - | to deal in the Software without restriction, including without limitation | |
| 9 | - | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 10 | - | and/or sell copies of the Software, and to permit persons to whom the | |
| 11 | - | Software is furnished to do so, subject to the following conditions: | |
| 12 | - | ||
| 13 | - | The above copyright notice and this permission notice (including the next | |
| 14 | - | paragraph) shall be included in all copies or substantial portions of the | |
| 15 | - | Software. | |
| 16 | - | ||
| 17 | - | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 18 | - | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 19 | - | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 20 | - | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 21 | - | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 22 | - | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
| 23 | - | DEALINGS IN THE SOFTWARE. | |
| 24 | - | </copyright> | |
| 25 | - | ||
| 26 | - | <description summary="Control power management modes of outputs"> | |
| 27 | - | This protocol allows clients to control power management modes | |
| 28 | - | of outputs that are currently part of the compositor space. The | |
| 29 | - | intent is to allow special clients like desktop shells to power | |
| 30 | - | down outputs when the system is idle. | |
| 31 | - | ||
| 32 | - | To modify outputs not currently part of the compositor space see | |
| 33 | - | wlr-output-management. | |
| 34 | - | ||
| 35 | - | Warning! The protocol described in this file is experimental and | |
| 36 | - | backward incompatible changes may be made. Backward compatible changes | |
| 37 | - | may be added together with the corresponding interface version bump. | |
| 38 | - | Backward incompatible changes are done by bumping the version number in | |
| 39 | - | the protocol and interface names and resetting the interface version. | |
| 40 | - | Once the protocol is to be declared stable, the 'z' prefix and the | |
| 41 | - | version number in the protocol and interface names are removed and the | |
| 42 | - | interface version number is reset. | |
| 43 | - | </description> | |
| 44 | - | ||
| 45 | - | <interface name="zwlr_output_power_manager_v1" version="1"> | |
| 46 | - | <description summary="manager to create per-output power management"> | |
| 47 | - | This interface is a manager that allows creating per-output power | |
| 48 | - | management mode controls. | |
| 49 | - | </description> | |
| 50 | - | ||
| 51 | - | <request name="get_output_power"> | |
| 52 | - | <description summary="get a power management for an output"> | |
| 53 | - | Create an output power management mode control that can be used to | |
| 54 | - | adjust the power management mode for a given output. | |
| 55 | - | </description> | |
| 56 | - | <arg name="id" type="new_id" interface="zwlr_output_power_v1"/> | |
| 57 | - | <arg name="output" type="object" interface="wl_output"/> | |
| 58 | - | </request> | |
| 59 | - | ||
| 60 | - | <request name="destroy" type="destructor"> | |
| 61 | - | <description summary="destroy the manager"> | |
| 62 | - | All objects created by the manager will still remain valid, until their | |
| 63 | - | appropriate destroy request has been called. | |
| 64 | - | </description> | |
| 65 | - | </request> | |
| 66 | - | </interface> | |
| 67 | - | ||
| 68 | - | <interface name="zwlr_output_power_v1" version="1"> | |
| 69 | - | <description summary="adjust power management mode for an output"> | |
| 70 | - | This object offers requests to set the power management mode of | |
| 71 | - | an output. | |
| 72 | - | </description> | |
| 73 | - | ||
| 74 | - | <enum name="mode"> | |
| 75 | - | <entry name="off" value="0" | |
| 76 | - | summary="Output is turned off."/> | |
| 77 | - | <entry name="on" value="1" | |
| 78 | - | summary="Output is turned on, no power saving"/> | |
| 79 | - | </enum> | |
| 80 | - | ||
| 81 | - | <enum name="error"> | |
| 82 | - | <entry name="invalid_mode" value="1" summary="nonexistent power save mode"/> | |
| 83 | - | </enum> | |
| 84 | - | ||
| 85 | - | <request name="set_mode"> | |
| 86 | - | <description summary="Set an outputs power save mode"> | |
| 87 | - | Set an output's power save mode to the given mode. The mode change | |
| 88 | - | is effective immediately. If the output does not support the given | |
| 89 | - | mode a failed event is sent. | |
| 90 | - | </description> | |
| 91 | - | <arg name="mode" type="uint" enum="mode" summary="the power save mode to set"/> | |
| 92 | - | </request> | |
| 93 | - | ||
| 94 | - | <event name="mode"> | |
| 95 | - | <description summary="Report a power management mode change"> | |
| 96 | - | Report the power management mode change of an output. | |
| 97 | - | ||
| 98 | - | The mode event is sent after an output changed its power | |
| 99 | - | management mode. The reason can be a client using set_mode or the | |
| 100 | - | compositor deciding to change an output's mode. | |
| 101 | - | This event is also sent immediately when the object is created | |
| 102 | - | so the client is informed about the current power management mode. | |
| 103 | - | </description> | |
| 104 | - | <arg name="mode" type="uint" enum="mode" | |
| 105 | - | summary="the output's new power management mode"/> | |
| 106 | - | </event> | |
| 107 | - | ||
| 108 | - | <event name="failed"> | |
| 109 | - | <description summary="object no longer valid"> | |
| 110 | - | This event indicates that the output power management mode control | |
| 111 | - | is no longer valid. This can happen for a number of reasons, | |
| 112 | - | including: | |
| 113 | - | - The output doesn't support power management | |
| 114 | - | - Another client already has exclusive power management mode control | |
| 115 | - | for this output | |
| 116 | - | - The output disappeared | |
| 117 | - | ||
| 118 | - | Upon receiving this event, the client should destroy this object. | |
| 119 | - | </description> | |
| 120 | - | </event> | |
| 121 | - | ||
| 122 | - | <request name="destroy" type="destructor"> | |
| 123 | - | <description summary="destroy this power management"> | |
| 124 | - | Destroys the output power management mode control object. | |
| 125 | - | </description> | |
| 126 | - | </request> | |
| 127 | - | </interface> | |
| 128 | - | </protocol> | |
D protocol/outputpower/wlr-output-power-management-unstable-v1_generated.go +0 -209
| @@ -1,209 +0,0 @@ | |||
| 1 | - | // Code generated by wlturbo-scanner. DO NOT EDIT. | |
| 2 | - | // Protocol: wlr_output_power_management_unstable_v1 | |
| 3 | - | // Source: wlr-output-power-management-unstable-v1.xml | |
| 4 | - | ||
| 5 | - | // Upstream protocol copyright and license: | |
| 6 | - | // Copyright © 2019 Purism SPC | |
| 7 | - | // | |
| 8 | - | // Permission is hereby granted, free of charge, to any person obtaining a | |
| 9 | - | // copy of this software and associated documentation files (the "Software"), | |
| 10 | - | // to deal in the Software without restriction, including without limitation | |
| 11 | - | // the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 12 | - | // and/or sell copies of the Software, and to permit persons to whom the | |
| 13 | - | // Software is furnished to do so, subject to the following conditions: | |
| 14 | - | // | |
| 15 | - | // The above copyright notice and this permission notice (including the next | |
| 16 | - | // paragraph) shall be included in all copies or substantial portions of the | |
| 17 | - | // Software. | |
| 18 | - | // | |
| 19 | - | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 20 | - | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 21 | - | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 22 | - | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 23 | - | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 24 | - | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
| 25 | - | // DEALINGS IN THE SOFTWARE. | |
| 26 | - | ||
| 27 | - | package outputpower | |
| 28 | - | ||
| 29 | - | import ( | |
| 30 | - | "sync" | |
| 31 | - | ||
| 32 | - | cross_wl_output "github.com/bnema/wlturbo/protocol/core" | |
| 33 | - | "github.com/bnema/wlturbo/wl" | |
| 34 | - | ) | |
| 35 | - | ||
| 36 | - | // MODE_OFF is the mode off value. | |
| 37 | - | const MODE_OFF = 0 | |
| 38 | - | ||
| 39 | - | // MODE_ON is the mode on value. | |
| 40 | - | const MODE_ON = 1 | |
| 41 | - | ||
| 42 | - | // ERROR_INVALID_MODE is the error invalid_mode value. | |
| 43 | - | const ERROR_INVALID_MODE = 1 | |
| 44 | - | ||
| 45 | - | // OutputPowerManagerInterface is the protocol interface name. | |
| 46 | - | const OutputPowerManagerInterface = "zwlr_output_power_manager_v1" | |
| 47 | - | ||
| 48 | - | // OutputPowerManager is the generated binding for zwlr_output_power_manager_v1 version 1. | |
| 49 | - | type OutputPowerManager struct { | |
| 50 | - | wl.BaseProxy | |
| 51 | - | } | |
| 52 | - | ||
| 53 | - | // NewOutputPowerManager returns an unbound OutputPowerManager. | |
| 54 | - | func NewOutputPowerManager(ctx *wl.Context) *OutputPowerManager { | |
| 55 | - | obj := &OutputPowerManager{} | |
| 56 | - | obj.SetContext(ctx) | |
| 57 | - | ctx.Register(obj) | |
| 58 | - | return obj | |
| 59 | - | } | |
| 60 | - | ||
| 61 | - | // Create an output power management mode control that can be used to adjust the power management mode for a given output. | |
| 62 | - | func (o *OutputPowerManager) GetOutputPower(output *cross_wl_output.Output) (*OutputPower, error) { | |
| 63 | - | var arg1 wl.Object | |
| 64 | - | if output != nil { | |
| 65 | - | arg1 = output | |
| 66 | - | } | |
| 67 | - | child := &OutputPower{} | |
| 68 | - | child.SetContext(o.Context()) | |
| 69 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "zwlr_output_power_manager_v1.get_output_power", Child: child}, wl.ArgObject(child), wl.ArgObject(arg1)); err != nil { | |
| 70 | - | return nil, err | |
| 71 | - | } | |
| 72 | - | return child, nil | |
| 73 | - | } | |
| 74 | - | ||
| 75 | - | // All objects created by the manager will still remain valid, until their appropriate destroy request has been called. | |
| 76 | - | func (o *OutputPowerManager) Destroy() error { | |
| 77 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "zwlr_output_power_manager_v1.destroy", Destructor: true}); err != nil { | |
| 78 | - | return err | |
| 79 | - | } | |
| 80 | - | return nil | |
| 81 | - | } | |
| 82 | - | ||
| 83 | - | // EventSignature returns the declared event argument types in wire order. | |
| 84 | - | func (o *OutputPowerManager) EventSignature(opcode uint16) (string, bool) { | |
| 85 | - | switch opcode { | |
| 86 | - | default: | |
| 87 | - | return "", false | |
| 88 | - | } | |
| 89 | - | } | |
| 90 | - | ||
| 91 | - | // Dispatch decodes one event on zwlr_output_power_manager_v1 and calls the registered handlers. | |
| 92 | - | func (o *OutputPowerManager) Dispatch(event *wl.Event) { | |
| 93 | - | switch event.Opcode { | |
| 94 | - | default: | |
| 95 | - | } | |
| 96 | - | } | |
| 97 | - | ||
| 98 | - | // OutputPowerInterface is the protocol interface name. | |
| 99 | - | const OutputPowerInterface = "zwlr_output_power_v1" | |
| 100 | - | ||
| 101 | - | // OutputPower is the generated binding for zwlr_output_power_v1 version 1. | |
| 102 | - | type OutputPower struct { | |
| 103 | - | wl.BaseProxy | |
| 104 | - | // handlersMu guards the handler slices: a client may register or replace | |
| 105 | - | // handlers while another goroutine dispatches events. | |
| 106 | - | handlersMu sync.Mutex | |
| 107 | - | onMode []func(mode uint32) | |
| 108 | - | onFailed []func() | |
| 109 | - | } | |
| 110 | - | ||
| 111 | - | // NewOutputPower returns an unbound OutputPower. | |
| 112 | - | func NewOutputPower(ctx *wl.Context) *OutputPower { | |
| 113 | - | obj := &OutputPower{} | |
| 114 | - | obj.SetContext(ctx) | |
| 115 | - | ctx.Register(obj) | |
| 116 | - | return obj | |
| 117 | - | } | |
| 118 | - | ||
| 119 | - | // 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. | |
| 120 | - | func (o *OutputPower) SetMode(mode uint32) error { | |
| 121 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "zwlr_output_power_v1.set_mode"}, wl.ArgUint(mode)); err != nil { | |
| 122 | - | return err | |
| 123 | - | } | |
| 124 | - | return nil | |
| 125 | - | } | |
| 126 | - | ||
| 127 | - | // Destroys the output power management mode control object. | |
| 128 | - | func (o *OutputPower) Destroy() error { | |
| 129 | - | if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "zwlr_output_power_v1.destroy", Destructor: true}); err != nil { | |
| 130 | - | return err | |
| 131 | - | } | |
| 132 | - | return nil | |
| 133 | - | } | |
| 134 | - | ||
| 135 | - | // OnMode registers a handler for the mode event. | |
| 136 | - | // | |
| 137 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 138 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 139 | - | func (o *OutputPower) OnMode(handler func(mode uint32)) { | |
| 140 | - | if handler == nil { | |
| 141 | - | return | |
| 142 | - | } | |
| 143 | - | o.handlersMu.Lock() | |
| 144 | - | defer o.handlersMu.Unlock() | |
| 145 | - | o.onMode = append(o.onMode, handler) | |
| 146 | - | } | |
| 147 | - | ||
| 148 | - | // handlersForMode returns the handlers registered for mode, taken | |
| 149 | - | // under the lock so a handler may register another handler while events are | |
| 150 | - | // being dispatched. | |
| 151 | - | func (o *OutputPower) handlersForMode() []func(mode uint32) { | |
| 152 | - | o.handlersMu.Lock() | |
| 153 | - | defer o.handlersMu.Unlock() | |
| 154 | - | return o.onMode | |
| 155 | - | } | |
| 156 | - | ||
| 157 | - | // OnFailed registers a handler for the failed event. | |
| 158 | - | // | |
| 159 | - | // Handlers are appended, so a second call adds another handler rather than | |
| 160 | - | // replacing the first. Registration is safe while another goroutine dispatches. | |
| 161 | - | func (o *OutputPower) OnFailed(handler func()) { | |
| 162 | - | if handler == nil { | |
| 163 | - | return | |
| 164 | - | } | |
| 165 | - | o.handlersMu.Lock() | |
| 166 | - | defer o.handlersMu.Unlock() | |
| 167 | - | o.onFailed = append(o.onFailed, handler) | |
| 168 | - | } | |
| 169 | - | ||
| 170 | - | // handlersForFailed returns the handlers registered for failed, taken | |
| 171 | - | // under the lock so a handler may register another handler while events are | |
| 172 | - | // being dispatched. | |
| 173 | - | func (o *OutputPower) handlersForFailed() []func() { | |
| 174 | - | o.handlersMu.Lock() | |
| 175 | - | defer o.handlersMu.Unlock() | |
| 176 | - | return o.onFailed | |
| 177 | - | } | |
| 178 | - | ||
| 179 | - | // EventSignature returns the declared event argument types in wire order. | |
| 180 | - | func (o *OutputPower) EventSignature(opcode uint16) (string, bool) { | |
| 181 | - | switch opcode { | |
| 182 | - | case 0: | |
| 183 | - | return "uint,", true | |
| 184 | - | case 1: | |
| 185 | - | return "", true | |
| 186 | - | default: | |
| 187 | - | return "", false | |
| 188 | - | } | |
| 189 | - | } | |
| 190 | - | ||
| 191 | - | // Dispatch decodes one event on zwlr_output_power_v1 and calls the registered handlers. | |
| 192 | - | func (o *OutputPower) Dispatch(event *wl.Event) { | |
| 193 | - | switch event.Opcode { | |
| 194 | - | case 0: // mode | |
| 195 | - | mode := event.Uint32() | |
| 196 | - | ||
| 197 | - | for i, handler := range o.handlersForMode() { | |
| 198 | - | _ = i | |
| 199 | - | handler(mode) | |
| 200 | - | } | |
| 201 | - | case 1: // failed | |
| 202 | - | ||
| 203 | - | for i, handler := range o.handlersForFailed() { | |
| 204 | - | _ = i | |
| 205 | - | handler() | |
| 206 | - | } | |
| 207 | - | default: | |
| 208 | - | } | |
| 209 | - | } | |
D protocol/performance_test.go +0 -393 collapsed to keep the page light
D protocol/pointerconstraints/generate.go +0 -3
| @@ -1,3 +0,0 @@ | |||
| 1 | - | package pointerconstraints | |
| 2 | - | ||
| 3 | - | //go:generate go run ../../cmd/wlturbo-scanner -p pointerconstraints -o pointer-constraints-unstable-v1_generated.go -import wl_pointer=github.com/bnema/wlturbo/protocol/core -import wl_region=github.com/bnema/wlturbo/protocol/core -import wl_surface=github.com/bnema/wlturbo/protocol/core pointer-constraints-unstable-v1.xml | |
D protocol/pointerconstraints/pointer-constraints-unstable-v1.xml +0 -334 collapsed to keep the page light
D protocol/pointerconstraints/pointer-constraints-unstable-v1_generated.go +0 -369 collapsed to keep the page light
D protocol/pointerwarp/generate.go +0 -3
| @@ -1,3 +0,0 @@ | |||
| 1 | - | package pointerwarp | |
| 2 | - | ||
| 3 | - | //go:generate go run ../../cmd/wlturbo-scanner -p pointerwarp -o pointer-warp-v1_generated.go -import wl_surface=github.com/bnema/wlturbo/protocol/core -import wl_pointer=github.com/bnema/wlturbo/protocol/core pointer-warp-v1.xml | |
D protocol/pointerwarp/pointer-warp-v1.xml +0 -72
| @@ -1,72 +0,0 @@ | |||
| 1 | - | <?xml version="1.0" encoding="UTF-8"?> | |
| 2 | - | <protocol name="pointer_warp_v1"> | |
| 3 | - | <copyright> | |
| 4 | - | Copyright © 2024 Neal Gompa | |
| 5 | - | Copyright © 2024 Xaver Hugl | |
| 6 | - | Copyright © 2024 Matthias Klumpp | |
| 7 | - | Copyright © 2024 Vlad Zahorodnii | |
| 8 | - | ||
| 9 | - | Permission is hereby granted, free of charge, to any person obtaining a | |
| 10 | - | copy of this software and associated documentation files (the "Software"), | |
| 11 | - | to deal in the Software without restriction, including without limitation | |
| 12 | - | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 13 | - | and/or sell copies of the Software, and to permit persons to whom the | |
| 14 | - | Software is furnished to do so, subject to the following conditions: | |
| 15 | - | The above copyright notice and this permission notice (including the next | |
| 16 | - | paragraph) shall be included in all copies or substantial portions of the | |
| 17 | - | Software. | |
| 18 | - | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 19 | - | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 20 | - | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 21 | - | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 22 | - | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 23 | - | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
| 24 | - | DEALINGS IN THE SOFTWARE. | |
| 25 | - | </copyright> | |
| 26 | - | ||
| 27 | - | <interface name="wp_pointer_warp_v1" version="1"> | |
| 28 | - | <description summary="reposition the pointer to a location on a surface"> | |
| 29 | - | This global interface allows applications to request the pointer to be | |
| 30 | - | moved to a position relative to a wl_surface. | |
| 31 | - | ||
| 32 | - | Note that if the desired behavior is to constrain the pointer to an area | |
| 33 | - | or lock it to a position, this protocol does not provide a reliable way | |
| 34 | - | to do that. The pointer constraint and pointer lock protocols should be | |
| 35 | - | used for those use cases instead. | |
| 36 | - | ||
| 37 | - | Warning! The protocol described in this file is currently in the testing | |
| 38 | - | phase. Backward compatible changes may be added together with the | |
| 39 | - | corresponding interface version bump. Backward incompatible changes can | |
| 40 | - | only be done by creating a new major version of the extension. | |
| 41 | - | </description> | |
| 42 | - | ||
| 43 | - | <request name="destroy" type="destructor"> | |
| 44 | - | <description summary="destroy the warp manager"> | |
| 45 | - | Destroy the pointer warp manager. | |
| 46 | - | </description> | |
| 47 | - | </request> | |
| 48 | - | ||
| 49 | - | <request name="warp_pointer"> | |
| 50 | - | <description summary="reposition the pointer"> | |
| 51 | - | Request the compositor to move the pointer to a surface-local position. | |
| 52 | - | Whether or not the compositor honors the request is implementation defined, | |
| 53 | - | but it should | |
| 54 | - | - honor it if the surface has pointer focus, including | |
| 55 | - | when it has an implicit pointer grab | |
| 56 | - | - reject it if the enter serial is incorrect | |
| 57 | - | - reject it if the requested position is outside of the surface | |
| 58 | - | ||
| 59 | - | Note that the enter serial is valid for any surface of the client, | |
| 60 | - | and does not have to be from the surface the pointer is warped to. | |
| 61 | - | ||
| 62 | - | </description> | |
| 63 | - | <arg name="surface" type="object" interface="wl_surface" | |
| 64 | - | summary="surface to position the pointer on"/> | |
| 65 | - | <arg name="pointer" type="object" interface="wl_pointer" | |
| 66 | - | summary="the pointer that should be repositioned"/> | |
| 67 | - | <arg name="x" type="fixed"/> | |
| 68 | - | <arg name="y" type="fixed"/> | |
| 69 | - | <arg name="serial" type="uint" summary="serial number of the enter event"/> | |
| 70 | - | </request> | |
| 71 | - | </interface> | |
| 72 | - | </protocol> | |
D protocol/pointerwarp/pointer-warp-v1_generated.go +0 -89 collapsed to keep the page light
D protocol/presentation/generate.go +0 -3
| @@ -1,3 +0,0 @@ | |||
| 1 | - | package presentation | |
| 2 | - | ||
| 3 | - | //go:generate go run ../../cmd/wlturbo-scanner -p presentation -o presentation-time_generated.go -import wl_surface=github.com/bnema/wlturbo/protocol/core -import wl_output=github.com/bnema/wlturbo/protocol/core presentation-time.xml | |
D protocol/presentation/presentation-time.xml +0 -268 collapsed to keep the page light
D protocol/presentation/presentation-time_generated.go +0 -277 collapsed to keep the page light
D protocol/primaryselection/generate.go +0 -3
| @@ -1,3 +0,0 @@ | |||
| 1 | - | package primaryselection | |
| 2 | - | ||
| 3 | - | //go:generate go run ../../cmd/wlturbo-scanner -p primaryselection -o primary-selection-unstable-v1_generated.go -import wl_seat=github.com/bnema/wlturbo/protocol/core primary-selection-unstable-v1.xml | |
D protocol/primaryselection/primary-selection-unstable-v1.xml +0 -225 collapsed to keep the page light
D protocol/primaryselection/primary-selection-unstable-v1_generated.go +0 -420 collapsed to keep the page light
D protocol/relativepointer/generate.go +0 -3
| @@ -1,3 +0,0 @@ | |||
| 1 | - | package relativepointer | |
| 2 | - | ||
| 3 | - | //go:generate go run ../../cmd/wlturbo-scanner -p relativepointer -o relative-pointer-unstable-v1_generated.go -import wl_pointer=github.com/bnema/wlturbo/protocol/core relative-pointer-unstable-v1.xml | |
D protocol/relativepointer/relative-pointer-unstable-v1.xml +0 -136 collapsed to keep the page light
D protocol/relativepointer/relative-pointer-unstable-v1_generated.go +0 -167 collapsed to keep the page light
D protocol/render_extensions_test.go +0 -864 collapsed to keep the page light
D protocol/screencopy/generate.go +0 -3
| @@ -1,3 +0,0 @@ | |||
| 1 | - | package screencopy | |
| 2 | - | ||
| 3 | - | //go:generate go run ../../cmd/wlturbo-scanner -p screencopy -o wlr-screencopy-unstable-v1_generated.go -import wl_output=github.com/bnema/wlturbo/protocol/core -import wl_buffer=github.com/bnema/wlturbo/protocol/core wlr-screencopy-unstable-v1.xml | |
D protocol/screencopy/wlr-screencopy-unstable-v1.xml +0 -234 collapsed to keep the page light
D protocol/screencopy/wlr-screencopy-unstable-v1_generated.go +0 -410 collapsed to keep the page light
D protocol/session_lock_test.go +0 -222 collapsed to keep the page light
D protocol/shortcutsinhibit/generate.go +0 -3
| @@ -1,3 +0,0 @@ | |||
| 1 | - | package shortcutsinhibit | |
| 2 | - | ||
| 3 | - | //go:generate go run ../../cmd/wlturbo-scanner -p shortcutsinhibit -o keyboard-shortcuts-inhibit-unstable-v1_generated.go -import wl_seat=github.com/bnema/wlturbo/protocol/core -import wl_surface=github.com/bnema/wlturbo/protocol/core keyboard-shortcuts-inhibit-unstable-v1.xml | |
D protocol/shortcutsinhibit/keyboard-shortcuts-inhibit-unstable-v1.xml +0 -143 collapsed to keep the page light
D protocol/shortcutsinhibit/keyboard-shortcuts-inhibit-unstable-v1_generated.go +0 -199 collapsed to keep the page light
D protocol/tablet/tablet-v2.xml +0 -1297 collapsed to keep the page light
D protocol/tablet/tablet-v2_generated.go +0 -2286 large diff (2286 lines changed): collapsed
D protocol/tearingcontrol/generate.go +0 -3
| @@ -1,3 +0,0 @@ | |||
| 1 | - | package tearingcontrol | |
| 2 | - | ||
| 3 | - | //go:generate go run ../../cmd/wlturbo-scanner -p tearingcontrol -o tearing-control-v1_generated.go -import wl_surface=github.com/bnema/wlturbo/protocol/core tearing-control-v1.xml | |
D protocol/tearingcontrol/tearing-control-v1.xml +0 -123 collapsed to keep the page light
D protocol/tearingcontrol/tearing-control-v1_generated.go +0 -141 collapsed to keep the page light
D protocol/textinput/text-input-unstable-v3.xml +0 -604 collapsed to keep the page light
D protocol/textinput/text-input-unstable-v3_generated.go +0 -628 collapsed to keep the page light
D protocol/viewporter/viewporter.xml +0 -177 collapsed to keep the page light
D protocol/viewporter/viewporter_generated.go +0 -155 collapsed to keep the page light
D protocol/virtualkeyboard/generate.go +0 -3
| @@ -1,3 +0,0 @@ | |||
| 1 | - | package virtualkeyboard | |
| 2 | - | ||
| 3 | - | //go:generate go run ../../cmd/wlturbo-scanner -p virtualkeyboard -o virtual-keyboard-unstable-v1_generated.go -import wl_seat=github.com/bnema/wlturbo/protocol/core virtual-keyboard-unstable-v1.xml | |
D protocol/virtualkeyboard/virtual-keyboard-unstable-v1.xml +0 -113 collapsed to keep the page light
D protocol/virtualkeyboard/virtual-keyboard-unstable-v1_generated.go +0 -149 collapsed to keep the page light
D protocol/wayland.xml +0 -3442
| @@ -1,3442 +0,0 @@ | |||
| 1 | - | <?xml version="1.0" encoding="UTF-8"?> | |
| 2 | - | <protocol name="wayland"> | |
| 3 | - | ||
| 4 | - | <copyright> | |
| 5 | - | Copyright © 2008-2011 Kristian Høgsberg | |
| 6 | - | Copyright © 2010-2011 Intel Corporation | |
| 7 | - | Copyright © 2012-2013 Collabora, Ltd. | |
| 8 | - | ||
| 9 | - | Permission is hereby granted, free of charge, to any person | |
| 10 | - | obtaining a copy of this software and associated documentation files | |
| 11 | - | (the "Software"), to deal in the Software without restriction, | |
| 12 | - | including without limitation the rights to use, copy, modify, merge, | |
| 13 | - | publish, distribute, sublicense, and/or sell copies of the Software, | |
| 14 | - | and to permit persons to whom the Software is furnished to do so, | |
| 15 | - | subject to the following conditions: | |
| 16 | - | ||
| 17 | - | The above copyright notice and this permission notice (including the | |
| 18 | - | next paragraph) shall be included in all copies or substantial | |
| 19 | - | portions of the Software. | |
| 20 | - | ||
| 21 | - | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
| 22 | - | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
| 23 | - | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
| 24 | - | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | |
| 25 | - | BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | |
| 26 | - | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |
| 27 | - | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
| 28 | - | SOFTWARE. | |
| 29 | - | </copyright> | |
| 30 | - | ||
| 31 | - | <interface name="wl_display" version="1"> | |
| 32 | - | <description summary="core global object"> | |
| 33 | - | The core global object. This is a special singleton object. It | |
| 34 | - | is used for internal Wayland protocol features. | |
| 35 | - | </description> | |
| 36 | - | ||
| 37 | - | <request name="sync"> | |
| 38 | - | <description summary="asynchronous roundtrip"> | |
| 39 | - | The sync request asks the server to emit the 'done' event | |
| 40 | - | on the returned wl_callback object. Since requests are | |
| 41 | - | handled in-order and events are delivered in-order, this can | |
| 42 | - | be used as a barrier to ensure all previous requests and the | |
| 43 | - | resulting events have been handled. | |
| 44 | - | ||
| 45 | - | The object returned by this request will be destroyed by the | |
| 46 | - | compositor after the callback is fired and as such the client must not | |
| 47 | - | attempt to use it after that point. | |
| 48 | - | ||
| 49 | - | The callback_data passed in the callback is undefined and should be ignored. | |
| 50 | - | </description> | |
| 51 | - | <arg name="callback" type="new_id" interface="wl_callback" | |
| 52 | - | summary="callback object for the sync request"/> | |
| 53 | - | </request> | |
| 54 | - | ||
| 55 | - | <request name="get_registry"> | |
| 56 | - | <description summary="get global registry object"> | |
| 57 | - | This request creates a registry object that allows the client | |
| 58 | - | to list and bind the global objects available from the | |
| 59 | - | compositor. | |
| 60 | - | ||
| 61 | - | It should be noted that the server side resources consumed in | |
| 62 | - | response to a get_registry request can only be released when the | |
| 63 | - | client disconnects, not when the client side proxy is destroyed. | |
| 64 | - | Therefore, clients should invoke get_registry as infrequently as | |
| 65 | - | possible to avoid wasting memory. | |
| 66 | - | </description> | |
| 67 | - | <arg name="registry" type="new_id" interface="wl_registry" | |
| 68 | - | summary="global registry object"/> | |
| 69 | - | </request> | |
| 70 | - | ||
| 71 | - | <event name="error"> | |
| 72 | - | <description summary="fatal error event"> | |
| 73 | - | The error event is sent out when a fatal (non-recoverable) | |
| 74 | - | error has occurred. The object_id argument is the object | |
| 75 | - | where the error occurred, most often in response to a request | |
| 76 | - | to that object. The code identifies the error and is defined | |
| 77 | - | by the object interface. As such, each interface defines its | |
| 78 | - | own set of error codes. The message is a brief description | |
| 79 | - | of the error, for (debugging) convenience. | |
| 80 | - | </description> | |
| 81 | - | <arg name="object_id" type="object" summary="object where the error occurred"/> | |
| 82 | - | <arg name="code" type="uint" summary="error code"/> | |
| 83 | - | <arg name="message" type="string" summary="error description"/> | |
| 84 | - | </event> | |
| 85 | - | ||
| 86 | - | <enum name="error"> | |
| 87 | - | <description summary="global error values"> | |
| 88 | - | These errors are global and can be emitted in response to any | |
| 89 | - | server request. | |
| 90 | - | </description> | |
| 91 | - | <entry name="invalid_object" value="0" | |
| 92 | - | summary="server couldn't find object"/> | |
| 93 | - | <entry name="invalid_method" value="1" | |
| 94 | - | summary="method doesn't exist on the specified interface or malformed request"/> | |
| 95 | - | <entry name="no_memory" value="2" | |
| 96 | - | summary="server is out of memory"/> | |
| 97 | - | <entry name="implementation" value="3" | |
| 98 | - | summary="implementation error in compositor"/> | |
| 99 | - | </enum> | |
| 100 | - | ||
| 101 | - | <event name="delete_id"> | |
| 102 | - | <description summary="acknowledge object ID deletion"> | |
| 103 | - | This event is used internally by the object ID management logic. | |
| 104 | - | ||
| 105 | - | When the server stops using an object created by the client, the server | |
| 106 | - | sends this event. In particular, after sending this event, the server | |
| 107 | - | will no longer send any events that contain the object as the receiver | |
| 108 | - | or as an argument. | |
| 109 | - | ||
| 110 | - | When the client receives this event, it knows that it can reuse the | |
| 111 | - | object ID. | |
| 112 | - | </description> | |
| 113 | - | <arg name="id" type="uint" summary="deleted object ID"/> | |
| 114 | - | </event> | |
| 115 | - | </interface> | |
| 116 | - | ||
| 117 | - | <interface name="wl_registry" version="1"> | |
| 118 | - | <description summary="global registry object"> | |
| 119 | - | The singleton global registry object. The server has a number of | |
| 120 | - | global objects that are available to all clients. These objects | |
| 121 | - | typically represent an actual object in the server (for example, | |
| 122 | - | an input device) or they are singleton objects that provide | |
| 123 | - | extension functionality. | |
| 124 | - | ||
| 125 | - | When a client creates a registry object, the registry object | |
| 126 | - | will emit a global event for each global currently in the | |
| 127 | - | registry. Globals come and go as a result of device or | |
| 128 | - | monitor hotplugs, reconfiguration or other events, and the | |
| 129 | - | registry will send out global and global_remove events to | |
| 130 | - | keep the client up to date with the changes. To mark the end | |
| 131 | - | of the initial burst of events, the client can use the | |
| 132 | - | wl_display.sync request immediately after calling | |
| 133 | - | wl_display.get_registry. | |
| 134 | - | ||
| 135 | - | A client can bind to a global object by using the bind | |
| 136 | - | request. This creates a client-side handle that lets the object | |
| 137 | - | emit events to the client and lets the client invoke requests on | |
| 138 | - | the object. | |
| 139 | - | </description> | |
| 140 | - | ||
| 141 | - | <request name="bind"> | |
| 142 | - | <description summary="bind an object to the display"> | |
| 143 | - | Binds a new, client-created object to the server using the | |
| 144 | - | specified name as the identifier. | |
| 145 | - | </description> | |
| 146 | - | <arg name="name" type="uint" summary="unique numeric name of the object"/> | |
| 147 | - | <arg name="id" type="new_id" summary="bound object"/> | |
| 148 | - | </request> | |
| 149 | - | ||
| 150 | - | <event name="global"> | |
| 151 | - | <description summary="announce global object"> | |
| 152 | - | Notify the client of global objects. | |
| 153 | - | ||
| 154 | - | The event notifies the client that a global object with | |
| 155 | - | the given name is now available, and it implements the | |
| 156 | - | given version of the given interface. | |
| 157 | - | </description> | |
| 158 | - | <arg name="name" type="uint" summary="numeric name of the global object"/> | |
| 159 | - | <arg name="interface" type="string" summary="interface implemented by the object"/> | |
| 160 | - | <arg name="version" type="uint" summary="interface version"/> | |
| 161 | - | </event> | |
| 162 | - | ||
| 163 | - | <event name="global_remove"> | |
| 164 | - | <description summary="announce removal of global object"> | |
| 165 | - | Notify the client of removed global objects. | |
| 166 | - | ||
| 167 | - | This event notifies the client that the global identified | |
| 168 | - | by name is no longer available. If the client bound to | |
| 169 | - | the global using the bind request, the client should now | |
| 170 | - | destroy that object. | |
| 171 | - | ||
| 172 | - | The object remains valid and requests to the object will be | |
| 173 | - | ignored until the client destroys it, to avoid races between | |
| 174 | - | the global going away and a client sending a request to it. | |
| 175 | - | </description> | |
| 176 | - | <arg name="name" type="uint" summary="numeric name of the global object"/> | |
| 177 | - | </event> | |
| 178 | - | </interface> | |
| 179 | - | ||
| 180 | - | <interface name="wl_callback" version="1" frozen="true"> | |
| 181 | - | <description summary="callback object"> | |
| 182 | - | Clients can handle the 'done' event to get notified when | |
| 183 | - | the related request is done. | |
| 184 | - | ||
| 185 | - | Note, because wl_callback objects are created from multiple independent | |
| 186 | - | factory interfaces, the wl_callback interface is frozen at version 1. | |
| 187 | - | </description> | |
| 188 | - | ||
| 189 | - | <event name="done" type="destructor"> | |
| 190 | - | <description summary="done event"> | |
| 191 | - | Notify the client when the related request is done. | |
| 192 | - | </description> | |
| 193 | - | <arg name="callback_data" type="uint" summary="request-specific data for the callback"/> | |
| 194 | - | </event> | |
| 195 | - | </interface> | |
| 196 | - | ||
| 197 | - | <interface name="wl_compositor" version="7"> | |
| 198 | - | <description summary="the compositor singleton"> | |
| 199 | - | A compositor. This object is a singleton global. The | |
| 200 | - | compositor is in charge of combining the contents of multiple | |
| 201 | - | surfaces into one displayable output. | |
| 202 | - | </description> | |
| 203 | - | ||
| 204 | - | <request name="create_surface"> | |
| 205 | - | <description summary="create new surface"> | |
| 206 | - | Ask the compositor to create a new surface. | |
| 207 | - | </description> | |
| 208 | - | <arg name="id" type="new_id" interface="wl_surface" summary="the new surface"/> | |
| 209 | - | </request> | |
| 210 | - | ||
| 211 | - | <request name="create_region"> | |
| 212 | - | <description summary="create new region"> | |
| 213 | - | Ask the compositor to create a new region. | |
| 214 | - | </description> | |
| 215 | - | <arg name="id" type="new_id" interface="wl_region" summary="the new region"/> | |
| 216 | - | </request> | |
| 217 | - | ||
| 218 | - | <!-- Version 7 additions --> | |
| 219 | - | ||
| 220 | - | <request name="release" type="destructor" since="7"> | |
| 221 | - | <description summary="destroy wl_compositor"> | |
| 222 | - | This request destroys the wl_compositor. This has no effect on any other objects. | |
| 223 | - | </description> | |
| 224 | - | </request> | |
| 225 | - | </interface> | |
| 226 | - | ||
| 227 | - | <interface name="wl_shm_pool" version="3"> | |
| 228 | - | <description summary="a shared memory pool"> | |
| 229 | - | The wl_shm_pool object encapsulates a piece of memory shared | |
| 230 | - | between the compositor and client. Through the wl_shm_pool | |
| 231 | - | object, the client can allocate shared memory wl_buffer objects. | |
| 232 | - | All objects created through the same pool share the same | |
| 233 | - | underlying mapped memory. Reusing the mapped memory avoids the | |
| 234 | - | setup/teardown overhead and is useful when interactively resizing | |
| 235 | - | a surface or for many small buffers. | |
| 236 | - | </description> | |
| 237 | - | ||
| 238 | - | <enum name="error" since="3"> | |
| 239 | - | <description summary="wl_shm_pool error values"> | |
| 240 | - | These errors can be emitted in response to wl_shm_pool requests. | |
| 241 | - | </description> | |
| 242 | - | <entry name="invalid_format" value="0" summary="buffer format is not known"/> | |
| 243 | - | <entry name="invalid_stride" value="1" summary="invalid size or stride during buffer creation"/> | |
| 244 | - | </enum> | |
| 245 | - | ||
| 246 | - | <request name="create_buffer"> | |
| 247 | - | <description summary="create a buffer from the pool"> | |
| 248 | - | Create a wl_buffer object from the pool. | |
| 249 | - | ||
| 250 | - | The buffer is created offset bytes into the pool and has | |
| 251 | - | width and height as specified. The stride argument specifies | |
| 252 | - | the number of bytes from the beginning of one row to the beginning | |
| 253 | - | of the next. The format is the pixel format of the buffer and | |
| 254 | - | must be one of those advertised through the wl_shm.format event. | |
| 255 | - | ||
| 256 | - | A buffer will keep a reference to the pool it was created from | |
| 257 | - | so it is valid to destroy the pool immediately after creating | |
| 258 | - | a buffer from it. | |
| 259 | - | </description> | |
| 260 | - | <arg name="id" type="new_id" interface="wl_buffer" summary="buffer to create"/> | |
| 261 | - | <arg name="offset" type="int" summary="buffer byte offset within the pool"/> | |
| 262 | - | <arg name="width" type="int" summary="buffer width, in pixels"/> | |
| 263 | - | <arg name="height" type="int" summary="buffer height, in pixels"/> | |
| 264 | - | <arg name="stride" type="int" summary="number of bytes from the beginning of one row to the beginning of the next row"/> | |
| 265 | - | <arg name="format" type="uint" enum="wl_shm.format" summary="buffer pixel format"/> | |
| 266 | - | </request> | |
| 267 | - | ||
| 268 | - | <request name="destroy" type="destructor"> | |
| 269 | - | <description summary="destroy the pool"> | |
| 270 | - | Destroy the shared memory pool. | |
| 271 | - | ||
| 272 | - | The mmapped memory will be released when all | |
| 273 | - | buffers that have been created from this pool | |
| 274 | - | are gone. | |
| 275 | - | </description> | |
| 276 | - | </request> | |
| 277 | - | ||
| 278 | - | <request name="resize"> | |
| 279 | - | <description summary="change the size of the pool mapping"> | |
| 280 | - | This request will cause the server to remap the backing memory | |
| 281 | - | for the pool from the file descriptor passed when the pool was | |
| 282 | - | created, but using the new size. This request can only be | |
| 283 | - | used to make the pool bigger. | |
| 284 | - | ||
| 285 | - | This request only changes the amount of bytes that are mmapped | |
| 286 | - | by the server and does not touch the file corresponding to the | |
| 287 | - | file descriptor passed at creation time. It is the client's | |
| 288 | - | responsibility to ensure that the file is at least as big as | |
| 289 | - | the new pool size. | |
| 290 | - | </description> | |
| 291 | - | <arg name="size" type="int" summary="new size of the pool, in bytes"/> | |
| 292 | - | </request> | |
| 293 | - | </interface> | |
| 294 | - | ||
| 295 | - | <interface name="wl_shm" version="3"> | |
| 296 | - | <description summary="shared memory support"> | |
| 297 | - | A singleton global object that provides support for shared | |
| 298 | - | memory. | |
| 299 | - | ||
| 300 | - | Clients can create wl_shm_pool objects using the create_pool | |
| 301 | - | request. | |
| 302 | - | ||
| 303 | - | On binding the wl_shm object one or more format events | |
| 304 | - | are emitted to inform clients about the valid pixel formats | |
| 305 | - | that can be used for buffers. | |
| 306 | - | </description> | |
| 307 | - | ||
| 308 | - | <enum name="error" since="3"> | |
| 309 | - | <description summary="wl_shm error values"> | |
| 310 | - | These errors can be emitted in response to wl_shm requests. | |
| 311 | - | </description> | |
| 312 | - | <entry name="invalid_format" value="0" summary="buffer format is not known" deprecated-since="3"/> | |
| 313 | - | <entry name="invalid_stride" value="1" summary="invalid size or stride during pool creation"/> | |
| 314 | - | <entry name="invalid_fd" value="2" summary="mmapping the file descriptor failed"/> | |
| 315 | - | </enum> | |
| 316 | - | ||
| 317 | - | <enum name="format"> | |
| 318 | - | <description summary="pixel formats"> | |
| 319 | - | This describes the memory layout of an individual pixel. | |
| 320 | - | ||
| 321 | - | All renderers should support argb8888 and xrgb8888 but any other | |
| 322 | - | formats are optional and may not be supported by the particular | |
| 323 | - | renderer in use. | |
| 324 | - | ||
| 325 | - | The drm format codes match the macros defined in drm_fourcc.h, except | |
| 326 | - | argb8888 and xrgb8888. The formats actually supported by the compositor | |
| 327 | - | will be reported by the format event. See drm_fourcc.h for more detailed | |
| 328 | - | format descriptions. | |
| 329 | - | ||
| 330 | - | For all wl_shm formats and unless specified in another protocol | |
| 331 | - | extension, pre-multiplied alpha is used for pixel values. | |
| 332 | - | </description> | |
| 333 | - | <!-- Note to protocol writers: don't update this list manually, instead | |
| 334 | - | run the automated script that keeps it in sync with drm_fourcc.h. --> | |
| 335 | - | <entry name="argb8888" value="0" summary="32-bit ARGB format, [31:0] A:R:G:B 8:8:8:8 little endian"/> | |
| 336 | - | <entry name="xrgb8888" value="1" summary="32-bit RGB format, [31:0] x:R:G:B 8:8:8:8 little endian"/> | |
| 337 | - | <entry name="c8" value="0x20203843" summary="8-bit color index format, [7:0] C"/> | |
| 338 | - | <entry name="rgb332" value="0x38424752" summary="8-bit RGB format, [7:0] R:G:B 3:3:2"/> | |
| 339 | - | <entry name="bgr233" value="0x38524742" summary="8-bit BGR format, [7:0] B:G:R 2:3:3"/> | |
| 340 | - | <entry name="xrgb4444" value="0x32315258" summary="16-bit xRGB format, [15:0] x:R:G:B 4:4:4:4 little endian"/> | |
| 341 | - | <entry name="xbgr4444" value="0x32314258" summary="16-bit xBGR format, [15:0] x:B:G:R 4:4:4:4 little endian"/> | |
| 342 | - | <entry name="rgbx4444" value="0x32315852" summary="16-bit RGBx format, [15:0] R:G:B:x 4:4:4:4 little endian"/> | |
| 343 | - | <entry name="bgrx4444" value="0x32315842" summary="16-bit BGRx format, [15:0] B:G:R:x 4:4:4:4 little endian"/> | |
| 344 | - | <entry name="argb4444" value="0x32315241" summary="16-bit ARGB format, [15:0] A:R:G:B 4:4:4:4 little endian"/> | |
| 345 | - | <entry name="abgr4444" value="0x32314241" summary="16-bit ABGR format, [15:0] A:B:G:R 4:4:4:4 little endian"/> | |
| 346 | - | <entry name="rgba4444" value="0x32314152" summary="16-bit RGBA format, [15:0] R:G:B:A 4:4:4:4 little endian"/> | |
| 347 | - | <entry name="bgra4444" value="0x32314142" summary="16-bit BGRA format, [15:0] B:G:R:A 4:4:4:4 little endian"/> | |
| 348 | - | <entry name="xrgb1555" value="0x35315258" summary="16-bit xRGB format, [15:0] x:R:G:B 1:5:5:5 little endian"/> | |
| 349 | - | <entry name="xbgr1555" value="0x35314258" summary="16-bit xBGR 1555 format, [15:0] x:B:G:R 1:5:5:5 little endian"/> | |
| 350 | - | <entry name="rgbx5551" value="0x35315852" summary="16-bit RGBx 5551 format, [15:0] R:G:B:x 5:5:5:1 little endian"/> | |
| 351 | - | <entry name="bgrx5551" value="0x35315842" summary="16-bit BGRx 5551 format, [15:0] B:G:R:x 5:5:5:1 little endian"/> | |
| 352 | - | <entry name="argb1555" value="0x35315241" summary="16-bit ARGB 1555 format, [15:0] A:R:G:B 1:5:5:5 little endian"/> | |
| 353 | - | <entry name="abgr1555" value="0x35314241" summary="16-bit ABGR 1555 format, [15:0] A:B:G:R 1:5:5:5 little endian"/> | |
| 354 | - | <entry name="rgba5551" value="0x35314152" summary="16-bit RGBA 5551 format, [15:0] R:G:B:A 5:5:5:1 little endian"/> | |
| 355 | - | <entry name="bgra5551" value="0x35314142" summary="16-bit BGRA 5551 format, [15:0] B:G:R:A 5:5:5:1 little endian"/> | |
| 356 | - | <entry name="rgb565" value="0x36314752" summary="16-bit RGB 565 format, [15:0] R:G:B 5:6:5 little endian"/> | |
| 357 | - | <entry name="bgr565" value="0x36314742" summary="16-bit BGR 565 format, [15:0] B:G:R 5:6:5 little endian"/> | |
| 358 | - | <entry name="rgb888" value="0x34324752" summary="24-bit RGB format, [23:0] R:G:B little endian"/> | |
| 359 | - | <entry name="bgr888" value="0x34324742" summary="24-bit BGR format, [23:0] B:G:R little endian"/> | |
| 360 | - | <entry name="xbgr8888" value="0x34324258" summary="32-bit xBGR format, [31:0] x:B:G:R 8:8:8:8 little endian"/> | |
| 361 | - | <entry name="rgbx8888" value="0x34325852" summary="32-bit RGBx format, [31:0] R:G:B:x 8:8:8:8 little endian"/> | |
| 362 | - | <entry name="bgrx8888" value="0x34325842" summary="32-bit BGRx format, [31:0] B:G:R:x 8:8:8:8 little endian"/> | |
| 363 | - | <entry name="abgr8888" value="0x34324241" summary="32-bit ABGR format, [31:0] A:B:G:R 8:8:8:8 little endian"/> | |
| 364 | - | <entry name="rgba8888" value="0x34324152" summary="32-bit RGBA format, [31:0] R:G:B:A 8:8:8:8 little endian"/> | |
| 365 | - | <entry name="bgra8888" value="0x34324142" summary="32-bit BGRA format, [31:0] B:G:R:A 8:8:8:8 little endian"/> | |
| 366 | - | <entry name="xrgb2101010" value="0x30335258" summary="32-bit xRGB format, [31:0] x:R:G:B 2:10:10:10 little endian"/> | |
| 367 | - | <entry name="xbgr2101010" value="0x30334258" summary="32-bit xBGR format, [31:0] x:B:G:R 2:10:10:10 little endian"/> | |
| 368 | - | <entry name="rgbx1010102" value="0x30335852" summary="32-bit RGBx format, [31:0] R:G:B:x 10:10:10:2 little endian"/> | |
| 369 | - | <entry name="bgrx1010102" value="0x30335842" summary="32-bit BGRx format, [31:0] B:G:R:x 10:10:10:2 little endian"/> | |
| 370 | - | <entry name="argb2101010" value="0x30335241" summary="32-bit ARGB format, [31:0] A:R:G:B 2:10:10:10 little endian"/> | |
| 371 | - | <entry name="abgr2101010" value="0x30334241" summary="32-bit ABGR format, [31:0] A:B:G:R 2:10:10:10 little endian"/> | |
| 372 | - | <entry name="rgba1010102" value="0x30334152" summary="32-bit RGBA format, [31:0] R:G:B:A 10:10:10:2 little endian"/> | |
| 373 | - | <entry name="bgra1010102" value="0x30334142" summary="32-bit BGRA format, [31:0] B:G:R:A 10:10:10:2 little endian"/> | |
| 374 | - | <entry name="yuyv" value="0x56595559" summary="packed YCbCr format, [31:0] Cr0:Y1:Cb0:Y0 8:8:8:8 little endian"/> | |
| 375 | - | <entry name="yvyu" value="0x55595659" summary="packed YCbCr format, [31:0] Cb0:Y1:Cr0:Y0 8:8:8:8 little endian"/> | |
| 376 | - | <entry name="uyvy" value="0x59565955" summary="packed YCbCr format, [31:0] Y1:Cr0:Y0:Cb0 8:8:8:8 little endian"/> | |
| 377 | - | <entry name="vyuy" value="0x59555956" summary="packed YCbCr format, [31:0] Y1:Cb0:Y0:Cr0 8:8:8:8 little endian"/> | |
| 378 | - | <entry name="ayuv" value="0x56555941" summary="packed AYCbCr format, [31:0] A:Y:Cb:Cr 8:8:8:8 little endian"/> | |
| 379 | - | <entry name="nv12" value="0x3231564e" summary="2 plane YCbCr Cr:Cb format, 2x2 subsampled Cr:Cb plane"/> | |
| 380 | - | <entry name="nv21" value="0x3132564e" summary="2 plane YCbCr Cb:Cr format, 2x2 subsampled Cb:Cr plane"/> | |
| 381 | - | <entry name="nv16" value="0x3631564e" summary="2 plane YCbCr Cr:Cb format, 2x1 subsampled Cr:Cb plane"/> | |
| 382 | - | <entry name="nv61" value="0x3136564e" summary="2 plane YCbCr Cb:Cr format, 2x1 subsampled Cb:Cr plane"/> | |
| 383 | - | <entry name="yuv410" value="0x39565559" summary="3 plane YCbCr format, 4x4 subsampled Cb (1) and Cr (2) planes"/> | |
| 384 | - | <entry name="yvu410" value="0x39555659" summary="3 plane YCbCr format, 4x4 subsampled Cr (1) and Cb (2) planes"/> | |
| 385 | - | <entry name="yuv411" value="0x31315559" summary="3 plane YCbCr format, 4x1 subsampled Cb (1) and Cr (2) planes"/> | |
| 386 | - | <entry name="yvu411" value="0x31315659" summary="3 plane YCbCr format, 4x1 subsampled Cr (1) and Cb (2) planes"/> | |
| 387 | - | <entry name="yuv420" value="0x32315559" summary="3 plane YCbCr format, 2x2 subsampled Cb (1) and Cr (2) planes"/> | |
| 388 | - | <entry name="yvu420" value="0x32315659" summary="3 plane YCbCr format, 2x2 subsampled Cr (1) and Cb (2) planes"/> | |
| 389 | - | <entry name="yuv422" value="0x36315559" summary="3 plane YCbCr format, 2x1 subsampled Cb (1) and Cr (2) planes"/> | |
| 390 | - | <entry name="yvu422" value="0x36315659" summary="3 plane YCbCr format, 2x1 subsampled Cr (1) and Cb (2) planes"/> | |
| 391 | - | <entry name="yuv444" value="0x34325559" summary="3 plane YCbCr format, non-subsampled Cb (1) and Cr (2) planes"/> | |
| 392 | - | <entry name="yvu444" value="0x34325659" summary="3 plane YCbCr format, non-subsampled Cr (1) and Cb (2) planes"/> | |
| 393 | - | <entry name="r8" value="0x20203852" summary="[7:0] R"/> | |
| 394 | - | <entry name="r16" value="0x20363152" summary="[15:0] R little endian"/> | |
| 395 | - | <entry name="rg88" value="0x38384752" summary="[15:0] R:G 8:8 little endian"/> | |
| 396 | - | <entry name="gr88" value="0x38385247" summary="[15:0] G:R 8:8 little endian"/> | |
| 397 | - | <entry name="rg1616" value="0x32334752" summary="[31:0] R:G 16:16 little endian"/> | |
| 398 | - | <entry name="gr1616" value="0x32335247" summary="[31:0] G:R 16:16 little endian"/> | |
| 399 | - | <entry name="xrgb16161616f" value="0x48345258" summary="[63:0] x:R:G:B 16:16:16:16 little endian"/> | |
| 400 | - | <entry name="xbgr16161616f" value="0x48344258" summary="[63:0] x:B:G:R 16:16:16:16 little endian"/> | |
| 401 | - | <entry name="argb16161616f" value="0x48345241" summary="[63:0] A:R:G:B 16:16:16:16 little endian"/> | |
| 402 | - | <entry name="abgr16161616f" value="0x48344241" summary="[63:0] A:B:G:R 16:16:16:16 little endian"/> | |
| 403 | - | <entry name="xyuv8888" value="0x56555958" summary="[31:0] X:Y:Cb:Cr 8:8:8:8 little endian"/> | |
| 404 | - | <entry name="vuy888" value="0x34325556" summary="[23:0] Cr:Cb:Y 8:8:8 little endian"/> | |
| 405 | - | <entry name="vuy101010" value="0x30335556" summary="Y followed by U then V, 10:10:10. Non-linear modifier only"/> | |
| 406 | - | <entry name="y210" value="0x30313259" summary="[63:0] Cr0:0:Y1:0:Cb0:0:Y0:0 10:6:10:6:10:6:10:6 little endian per 2 Y pixels"/> | |
| 407 | - | <entry name="y212" value="0x32313259" summary="[63:0] Cr0:0:Y1:0:Cb0:0:Y0:0 12:4:12:4:12:4:12:4 little endian per 2 Y pixels"/> | |
| 408 | - | <entry name="y216" value="0x36313259" summary="[63:0] Cr0:Y1:Cb0:Y0 16:16:16:16 little endian per 2 Y pixels"/> | |
| 409 | - | <entry name="y410" value="0x30313459" summary="[31:0] A:Cr:Y:Cb 2:10:10:10 little endian"/> | |
| 410 | - | <entry name="y412" value="0x32313459" summary="[63:0] A:0:Cr:0:Y:0:Cb:0 12:4:12:4:12:4:12:4 little endian"/> | |
| 411 | - | <entry name="y416" value="0x36313459" summary="[63:0] A:Cr:Y:Cb 16:16:16:16 little endian"/> | |
| 412 | - | <entry name="xvyu2101010" value="0x30335658" summary="[31:0] X:Cr:Y:Cb 2:10:10:10 little endian"/> | |
| 413 | - | <entry name="xvyu12_16161616" value="0x36335658" summary="[63:0] X:0:Cr:0:Y:0:Cb:0 12:4:12:4:12:4:12:4 little endian"/> | |
| 414 | - | <entry name="xvyu16161616" value="0x38345658" summary="[63:0] X:Cr:Y:Cb 16:16:16:16 little endian"/> | |
| 415 | - | <entry name="y0l0" value="0x304c3059" summary="[63:0] A3:A2:Y3:0:Cr0:0:Y2:0:A1:A0:Y1:0:Cb0:0:Y0:0 1:1:8:2:8:2:8:2:1:1:8:2:8:2:8:2 little endian"/> | |
| 416 | - | <entry name="x0l0" value="0x304c3058" summary="[63:0] X3:X2:Y3:0:Cr0:0:Y2:0:X1:X0:Y1:0:Cb0:0:Y0:0 1:1:8:2:8:2:8:2:1:1:8:2:8:2:8:2 little endian"/> | |
| 417 | - | <entry name="y0l2" value="0x324c3059" summary="[63:0] A3:A2:Y3:Cr0:Y2:A1:A0:Y1:Cb0:Y0 1:1:10:10:10:1:1:10:10:10 little endian"/> | |
| 418 | - | <entry name="x0l2" value="0x324c3058" summary="[63:0] X3:X2:Y3:Cr0:Y2:X1:X0:Y1:Cb0:Y0 1:1:10:10:10:1:1:10:10:10 little endian"/> | |
| 419 | - | <entry name="yuv420_8bit" value="0x38305559"/> | |
| 420 | - | <entry name="yuv420_10bit" value="0x30315559"/> | |
| 421 | - | <entry name="xrgb8888_a8" value="0x38415258"/> | |
| 422 | - | <entry name="xbgr8888_a8" value="0x38414258"/> | |
| 423 | - | <entry name="rgbx8888_a8" value="0x38415852"/> | |
| 424 | - | <entry name="bgrx8888_a8" value="0x38415842"/> | |
| 425 | - | <entry name="rgb888_a8" value="0x38413852"/> | |
| 426 | - | <entry name="bgr888_a8" value="0x38413842"/> | |
| 427 | - | <entry name="rgb565_a8" value="0x38413552"/> | |
| 428 | - | <entry name="bgr565_a8" value="0x38413542"/> | |
| 429 | - | <entry name="nv24" value="0x3432564e" summary="non-subsampled Cr:Cb plane"/> | |
| 430 | - | <entry name="nv42" value="0x3234564e" summary="non-subsampled Cb:Cr plane"/> | |
| 431 | - | <entry name="p210" value="0x30313250" summary="2x1 subsampled Cr:Cb plane, 10 bit per channel"/> | |
| 432 | - | <entry name="p010" value="0x30313050" summary="2x2 subsampled Cr:Cb plane 10 bits per channel"/> | |
| 433 | - | <entry name="p012" value="0x32313050" summary="2x2 subsampled Cr:Cb plane 12 bits per channel"/> | |
| 434 | - | <entry name="p016" value="0x36313050" summary="2x2 subsampled Cr:Cb plane 16 bits per channel"/> | |
| 435 | - | <entry name="axbxgxrx106106106106" value="0x30314241" summary="[63:0] A:x:B:x:G:x:R:x 10:6:10:6:10:6:10:6 little endian"/> | |
| 436 | - | <entry name="nv15" value="0x3531564e" summary="2x2 subsampled Cr:Cb plane"/> | |
| 437 | - | <entry name="q410" value="0x30313451"/> | |
| 438 | - | <entry name="q401" value="0x31303451"/> | |
| 439 | - | <entry name="xrgb16161616" value="0x38345258" summary="[63:0] x:R:G:B 16:16:16:16 little endian"/> | |
| 440 | - | <entry name="xbgr16161616" value="0x38344258" summary="[63:0] x:B:G:R 16:16:16:16 little endian"/> | |
| 441 | - | <entry name="argb16161616" value="0x38345241" summary="[63:0] A:R:G:B 16:16:16:16 little endian"/> | |
| 442 | - | <entry name="abgr16161616" value="0x38344241" summary="[63:0] A:B:G:R 16:16:16:16 little endian"/> | |
| 443 | - | <entry name="c1" value="0x20203143" summary="[7:0] C0:C1:C2:C3:C4:C5:C6:C7 1:1:1:1:1:1:1:1 eight pixels/byte"/> | |
| 444 | - | <entry name="c2" value="0x20203243" summary="[7:0] C0:C1:C2:C3 2:2:2:2 four pixels/byte"/> | |
| 445 | - | <entry name="c4" value="0x20203443" summary="[7:0] C0:C1 4:4 two pixels/byte"/> | |
| 446 | - | <entry name="d1" value="0x20203144" summary="[7:0] D0:D1:D2:D3:D4:D5:D6:D7 1:1:1:1:1:1:1:1 eight pixels/byte"/> | |
| 447 | - | <entry name="d2" value="0x20203244" summary="[7:0] D0:D1:D2:D3 2:2:2:2 four pixels/byte"/> | |
| 448 | - | <entry name="d4" value="0x20203444" summary="[7:0] D0:D1 4:4 two pixels/byte"/> | |
| 449 | - | <entry name="d8" value="0x20203844" summary="[7:0] D"/> | |
| 450 | - | <entry name="r1" value="0x20203152" summary="[7:0] R0:R1:R2:R3:R4:R5:R6:R7 1:1:1:1:1:1:1:1 eight pixels/byte"/> | |
| 451 | - | <entry name="r2" value="0x20203252" summary="[7:0] R0:R1:R2:R3 2:2:2:2 four pixels/byte"/> | |
| 452 | - | <entry name="r4" value="0x20203452" summary="[7:0] R0:R1 4:4 two pixels/byte"/> | |
| 453 | - | <entry name="r10" value="0x20303152" summary="[15:0] x:R 6:10 little endian"/> | |
| 454 | - | <entry name="r12" value="0x20323152" summary="[15:0] x:R 4:12 little endian"/> | |
| 455 | - | <entry name="avuy8888" value="0x59555641" summary="[31:0] A:Cr:Cb:Y 8:8:8:8 little endian"/> | |
| 456 | - | <entry name="xvuy8888" value="0x59555658" summary="[31:0] X:Cr:Cb:Y 8:8:8:8 little endian"/> | |
| 457 | - | <entry name="p030" value="0x30333050" summary="2x2 subsampled Cr:Cb plane 10 bits per channel packed"/> | |
| 458 | - | <entry name="rgb161616" value="0x38344752" summary="[47:0] R:G:B 16:16:16 little endian"/> | |
| 459 | - | <entry name="bgr161616" value="0x38344742" summary="[47:0] B:G:R 16:16:16 little endian"/> | |
| 460 | - | <entry name="r16f" value="0x48202052" summary="[15:0] R 16 little endian"/> | |
| 461 | - | <entry name="gr1616f" value="0x48205247" summary="[31:0] G:R 16:16 little endian"/> | |
| 462 | - | <entry name="bgr161616f" value="0x48524742" summary="[47:0] B:G:R 16:16:16 little endian"/> | |
| 463 | - | <entry name="r32f" value="0x46202052" summary="[31:0] R 32 little endian"/> | |
| 464 | - | <entry name="gr3232f" value="0x46205247" summary="[63:0] G:R 32:32 little endian"/> | |
| 465 | - | <entry name="bgr323232f" value="0x46524742" summary="[95:0] B:G:R 32:32:32 little endian"/> | |
| 466 | - | <entry name="abgr32323232f" value="0x46384241" summary="[127:0] A:B:G:R 32:32:32:32 little endian"/> | |
| 467 | - | <entry name="nv20" value="0x3032564e" summary="2x1 subsampled Cr:Cb plane"/> | |
| 468 | - | <entry name="nv30" value="0x3033564e" summary="non-subsampled Cr:Cb plane"/> | |
| 469 | - | <entry name="s010" value="0x30313053" summary="2x2 subsampled Cb (1) and Cr (2) planes 10 bits per channel"/> | |
| 470 | - | <entry name="s210" value="0x30313253" summary="2x1 subsampled Cb (1) and Cr (2) planes 10 bits per channel"/> | |
| 471 | - | <entry name="s410" value="0x30313453" summary="non-subsampled Cb (1) and Cr (2) planes 10 bits per channel"/> | |
| 472 | - | <entry name="s012" value="0x32313053" summary="2x2 subsampled Cb (1) and Cr (2) planes 12 bits per channel"/> | |
| 473 | - | <entry name="s212" value="0x32313253" summary="2x1 subsampled Cb (1) and Cr (2) planes 12 bits per channel"/> | |
| 474 | - | <entry name="s412" value="0x32313453" summary="non-subsampled Cb (1) and Cr (2) planes 12 bits per channel"/> | |
| 475 | - | <entry name="s016" value="0x36313053" summary="2x2 subsampled Cb (1) and Cr (2) planes 16 bits per channel"/> | |
| 476 | - | <entry name="s216" value="0x36313253" summary="2x1 subsampled Cb (1) and Cr (2) planes 16 bits per channel"/> | |
| 477 | - | <entry name="s416" value="0x36313453" summary="non-subsampled Cb (1) and Cr (2) planes 16 bits per channel"/> | |
| 478 | - | <entry name="xvuy2101010" value="0x30335958" summary="[31:0] x:Cr:Cb:Y 2:10:10:10 little endian"/> | |
| 479 | - | <entry name="p230" value="0x30333250" summary="2x1 subsampled Cr:Cb plane 10 bits per channel packed"/> | |
| 480 | - | <entry name="t430" value="0x30333454"/> | |
| 481 | - | <entry name="y8" value="0x59455247" summary="8-bit Y-only"/> | |
| 482 | - | <entry name="xyyy2101010" value="0x34415059" summary="[31:0] x:Y2:Y1:Y0 2:10:10:10 little endian"/> | |
| 483 | - | </enum> | |
| 484 | - | ||
| 485 | - | <request name="create_pool"> | |
| 486 | - | <description summary="create a shm pool"> | |
| 487 | - | Create a new wl_shm_pool object. | |
| 488 | - | ||
| 489 | - | The pool can be used to create shared memory based buffer | |
| 490 | - | objects. The server will mmap size bytes of the passed file | |
| 491 | - | descriptor, to use as backing memory for the pool. | |
| 492 | - | </description> | |
| 493 | - | <arg name="id" type="new_id" interface="wl_shm_pool" summary="pool to create"/> | |
| 494 | - | <arg name="fd" type="fd" summary="file descriptor for the pool"/> | |
| 495 | - | <arg name="size" type="int" summary="pool size, in bytes"/> | |
| 496 | - | </request> | |
| 497 | - | ||
| 498 | - | <event name="format"> | |
| 499 | - | <description summary="pixel format description"> | |
| 500 | - | Informs the client about a valid pixel format that | |
| 501 | - | can be used for buffers. Known formats include | |
| 502 | - | argb8888 and xrgb8888. | |
| 503 | - | ||
| 504 | - | Extensions to drm_fourcc.h (or the format enum) do not require | |
| 505 | - | increasing the wl_shm version; as a result, clients may receive format | |
| 506 | - | codes which were not in the list at the time the client was made. | |
| 507 | - | </description> | |
| 508 | - | <arg name="format" type="uint" enum="format" summary="buffer pixel format"/> | |
| 509 | - | </event> | |
| 510 | - | ||
| 511 | - | <!-- Version 2 additions --> | |
| 512 | - | ||
| 513 | - | <request name="release" type="destructor" since="2"> | |
| 514 | - | <description summary="release the shm object"> | |
| 515 | - | Using this request a client can tell the server that it is not going to | |
| 516 | - | use the shm object anymore. | |
| 517 | - | ||
| 518 | - | Objects created via this interface remain unaffected. | |
| 519 | - | </description> | |
| 520 | - | </request> | |
| 521 | - | </interface> | |
| 522 | - | ||
| 523 | - | <interface name="wl_buffer" version="1" frozen="true"> | |
| 524 | - | <description summary="content for a wl_surface"> | |
| 525 | - | A buffer provides the content for a wl_surface. Buffers are | |
| 526 | - | created through factory interfaces such as wl_shm, wp_linux_buffer_params | |
| 527 | - | (from the linux-dmabuf protocol extension) or similar. It has a width and | |
| 528 | - | a height and can be attached to a wl_surface, but the mechanism by which a | |
| 529 | - | client provides and updates the contents is defined by the buffer factory | |
| 530 | - | interface. | |
| 531 | - | ||
| 532 | - | Color channels are assumed to be electrical rather than optical (in other | |
| 533 | - | words, encoded with a transfer function) unless otherwise specified. If | |
| 534 | - | the buffer uses a format that has an alpha channel, the alpha channel is | |
| 535 | - | assumed to be premultiplied into the electrical color channel values | |
| 536 | - | (after transfer function encoding) unless otherwise specified. | |
| 537 | - | ||
| 538 | - | Note, because wl_buffer objects are created from multiple independent | |
| 539 | - | factory interfaces, the wl_buffer interface is frozen at version 1. | |
| 540 | - | </description> | |
| 541 | - | ||
| 542 | - | <request name="destroy" type="destructor"> | |
| 543 | - | <description summary="destroy a buffer"> | |
| 544 | - | Destroy a buffer. If and how you need to release the backing | |
| 545 | - | storage is defined by the buffer factory interface. | |
| 546 | - | ||
| 547 | - | For possible side-effects to a surface, see wl_surface.attach. | |
| 548 | - | </description> | |
| 549 | - | </request> | |
| 550 | - | ||
| 551 | - | <event name="release"> | |
| 552 | - | <description summary="compositor releases buffer"> | |
| 553 | - | Sent when this wl_buffer is no longer used by the compositor. | |
| 554 | - | ||
| 555 | - | For more information on when release events may or may not be sent, | |
| 556 | - | and what consequences it has, please see the description of | |
| 557 | - | wl_surface.attach. | |
| 558 | - | ||
| 559 | - | If a client receives a release event before the frame callback | |
| 560 | - | requested in the same wl_surface.commit that attaches this | |
| 561 | - | wl_buffer to a surface, then the client is immediately free to | |
| 562 | - | reuse the buffer and its backing storage, and does not need a | |
| 563 | - | second buffer for the next surface content update. Typically | |
| 564 | - | this is possible, when the compositor maintains a copy of the | |
| 565 | - | wl_surface contents, e.g. as a GL texture. This is an important | |
| 566 | - | optimization for GL(ES) compositors with wl_shm clients. | |
| 567 | - | </description> | |
| 568 | - | </event> | |
| 569 | - | </interface> | |
| 570 | - | ||
| 571 | - | <interface name="wl_data_offer" version="4"> | |
| 572 | - | <description summary="offer to transfer data"> | |
| 573 | - | A wl_data_offer represents a piece of data offered for transfer | |
| 574 | - | by another client (the source client). It is used by the | |
| 575 | - | copy-and-paste and drag-and-drop mechanisms. The offer | |
| 576 | - | describes the different mime types that the data can be | |
| 577 | - | converted to and provides the mechanism for transferring the | |
| 578 | - | data directly from the source client. | |
| 579 | - | </description> | |
| 580 | - | ||
| 581 | - | <enum name="error"> | |
| 582 | - | <entry name="invalid_finish" value="0" | |
| 583 | - | summary="finish request was called untimely"/> | |
| 584 | - | <entry name="invalid_action_mask" value="1" | |
| 585 | - | summary="action mask contains invalid values"/> | |
| 586 | - | <entry name="invalid_action" value="2" | |
| 587 | - | summary="action argument has an invalid value"/> | |
| 588 | - | <entry name="invalid_offer" value="3" | |
| 589 | - | summary="offer doesn't accept this request"/> | |
| 590 | - | </enum> | |
| 591 | - | ||
| 592 | - | <request name="accept"> | |
| 593 | - | <description summary="accept one of the offered mime types"> | |
| 594 | - | Indicate that the client can accept the given mime type, or | |
| 595 | - | NULL for not accepted. | |
| 596 | - | ||
| 597 | - | For objects of version 2 or older, this request is used by the | |
| 598 | - | client to give feedback whether the client can receive the given | |
| 599 | - | mime type, or NULL if none is accepted; the feedback does not | |
| 600 | - | determine whether the drag-and-drop operation succeeds or not. | |
| 601 | - | ||
| 602 | - | For objects of version 3 or newer, this request determines the | |
| 603 | - | final result of the drag-and-drop operation. If the end result | |
| 604 | - | is that no mime types were accepted, the drag-and-drop operation | |
| 605 | - | will be cancelled and the corresponding drag source will receive | |
| 606 | - | wl_data_source.cancelled. Clients may still use this event in | |
| 607 | - | conjunction with wl_data_source.action for feedback. | |
| 608 | - | </description> | |
| 609 | - | <arg name="serial" type="uint" summary="serial number of the accept request"/> | |
| 610 | - | <arg name="mime_type" type="string" allow-null="true" summary="mime type accepted by the client"/> | |
| 611 | - | </request> | |
| 612 | - | ||
| 613 | - | <request name="receive"> | |
| 614 | - | <description summary="request that the data is transferred"> | |
| 615 | - | To transfer the offered data, the client issues this request | |
| 616 | - | and indicates the mime type it wants to receive. The transfer | |
| 617 | - | happens through the passed file descriptor (typically created | |
| 618 | - | with the pipe system call). The source client writes the data | |
| 619 | - | in the mime type representation requested and then closes the | |
| 620 | - | file descriptor. | |
| 621 | - | ||
| 622 | - | The receiving client reads from the read end of the pipe until | |
| 623 | - | EOF and then closes its end, at which point the transfer is | |
| 624 | - | complete. | |
| 625 | - | ||
| 626 | - | This request may happen multiple times for different mime types, | |
| 627 | - | both before and after wl_data_device.drop. Drag-and-drop destination | |
| 628 | - | clients may preemptively fetch data or examine it more closely to | |
| 629 | - | determine acceptance. | |
| 630 | - | </description> | |
| 631 | - | <arg name="mime_type" type="string" summary="mime type desired by receiver"/> | |
| 632 | - | <arg name="fd" type="fd" summary="file descriptor for data transfer"/> | |
| 633 | - | </request> | |
| 634 | - | ||
| 635 | - | <request name="destroy" type="destructor"> | |
| 636 | - | <description summary="destroy data offer"> | |
| 637 | - | Destroy the data offer. | |
| 638 | - | </description> | |
| 639 | - | </request> | |
| 640 | - | ||
| 641 | - | <event name="offer"> | |
| 642 | - | <description summary="advertise offered mime type"> | |
| 643 | - | Sent immediately after creating the wl_data_offer object. One | |
| 644 | - | event per offered mime type. | |
| 645 | - | </description> | |
| 646 | - | <arg name="mime_type" type="string" summary="offered mime type"/> | |
| 647 | - | </event> | |
| 648 | - | ||
| 649 | - | <!-- Version 3 additions --> | |
| 650 | - | ||
| 651 | - | <request name="finish" since="3"> | |
| 652 | - | <description summary="the offer will no longer be used"> | |
| 653 | - | Notifies the compositor that the drag destination successfully | |
| 654 | - | finished the drag-and-drop operation. | |
| 655 | - | ||
| 656 | - | Upon receiving this request, the compositor will emit | |
| 657 | - | wl_data_source.dnd_finished on the drag source client. | |
| 658 | - | ||
| 659 | - | It is a client error to perform other requests than | |
| 660 | - | wl_data_offer.destroy after this one. It is also an error to perform | |
| 661 | - | this request after a NULL mime type has been set in | |
| 662 | - | wl_data_offer.accept or no action was received through | |
| 663 | - | wl_data_offer.action. | |
| 664 | - | ||
| 665 | - | If wl_data_offer.finish request is received for a non drag and drop | |
| 666 | - | operation, the invalid_finish protocol error is raised. | |
| 667 | - | </description> | |
| 668 | - | </request> | |
| 669 | - | ||
| 670 | - | <request name="set_actions" since="3"> | |
| 671 | - | <description summary="set the available/preferred drag-and-drop actions"> | |
| 672 | - | Sets the actions that the destination side client supports for | |
| 673 | - | this operation. This request may trigger the emission of | |
| 674 | - | wl_data_source.action and wl_data_offer.action events if the compositor | |
| 675 | - | needs to change the selected action. | |
| 676 | - | ||
| 677 | - | This request can be called multiple times throughout the | |
| 678 | - | drag-and-drop operation, typically in response to wl_data_device.enter | |
| 679 | - | or wl_data_device.motion events. | |
| 680 | - | ||
| 681 | - | This request determines the final result of the drag-and-drop | |
| 682 | - | operation. If the end result is that no action is accepted, | |
| 683 | - | the drag source will receive wl_data_source.cancelled. | |
| 684 | - | ||
| 685 | - | The dnd_actions argument must contain only values expressed in the | |
| 686 | - | wl_data_device_manager.dnd_actions enum, and the preferred_action | |
| 687 | - | argument must only contain one of those values set, otherwise it | |
| 688 | - | will result in a protocol error. | |
| 689 | - | ||
| 690 | - | While managing an "ask" action, the destination drag-and-drop client | |
| 691 | - | may perform further wl_data_offer.receive requests, and is expected | |
| 692 | - | to perform one last wl_data_offer.set_actions request with a preferred | |
| 693 | - | action other than "ask" (and optionally wl_data_offer.accept) before | |
| 694 | - | requesting wl_data_offer.finish, in order to convey the action selected | |
| 695 | - | by the user. If the preferred action is not in the | |
| 696 | - | wl_data_offer.source_actions mask, an error will be raised. | |
| 697 | - | ||
| 698 | - | If the "ask" action is dismissed (e.g. user cancellation), the client | |
| 699 | - | is expected to perform wl_data_offer.destroy right away. | |
| 700 | - | ||
| 701 | - | This request can only be made on drag-and-drop offers, a protocol error | |
| 702 | - | will be raised otherwise. | |
| 703 | - | </description> | |
| 704 | - | <arg name="dnd_actions" type="uint" summary="actions supported by the destination client" | |
| 705 | - | enum="wl_data_device_manager.dnd_action"/> | |
| 706 | - | <arg name="preferred_action" type="uint" summary="action preferred by the destination client" | |
| 707 | - | enum="wl_data_device_manager.dnd_action"/> | |
| 708 | - | </request> | |
| 709 | - | ||
| 710 | - | <event name="source_actions" since="3"> | |
| 711 | - | <description summary="notify the source-side available actions"> | |
| 712 | - | This event indicates the actions offered by the data source. It | |
| 713 | - | will be sent immediately after creating the wl_data_offer object, | |
| 714 | - | or anytime the source side changes its offered actions through | |
| 715 | - | wl_data_source.set_actions. | |
| 716 | - | </description> | |
| 717 | - | <arg name="source_actions" type="uint" summary="actions offered by the data source" | |
| 718 | - | enum="wl_data_device_manager.dnd_action"/> | |
| 719 | - | </event> | |
| 720 | - | ||
| 721 | - | <event name="action" since="3"> | |
| 722 | - | <description summary="notify the selected action"> | |
| 723 | - | This event indicates the action selected by the compositor after | |
| 724 | - | matching the source/destination side actions. Only one action (or | |
| 725 | - | none) will be offered here. | |
| 726 | - | ||
| 727 | - | This event can be emitted multiple times during the drag-and-drop | |
| 728 | - | operation in response to destination side action changes through | |
| 729 | - | wl_data_offer.set_actions. | |
| 730 | - | ||
| 731 | - | This event will no longer be emitted after wl_data_device.drop | |
| 732 | - | happened on the drag-and-drop destination, the client must | |
| 733 | - | honor the last action received, or the last preferred one set | |
| 734 | - | through wl_data_offer.set_actions when handling an "ask" action. | |
| 735 | - | ||
| 736 | - | Compositors may also change the selected action on the fly, mainly | |
| 737 | - | in response to keyboard modifier changes during the drag-and-drop | |
| 738 | - | operation. | |
| 739 | - | ||
| 740 | - | The most recent action received is always the valid one. Prior to | |
| 741 | - | receiving wl_data_device.drop, the chosen action may change (e.g. | |
| 742 | - | due to keyboard modifiers being pressed). At the time of receiving | |
| 743 | - | wl_data_device.drop the drag-and-drop destination must honor the | |
| 744 | - | last action received. | |
| 745 | - | ||
| 746 | - | Action changes may still happen after wl_data_device.drop, | |
| 747 | - | especially on "ask" actions, where the drag-and-drop destination | |
| 748 | - | may choose another action afterwards. Action changes happening | |
| 749 | - | at this stage are always the result of inter-client negotiation, the | |
| 750 | - | compositor shall no longer be able to induce a different action. | |
| 751 | - | ||
| 752 | - | Upon "ask" actions, it is expected that the drag-and-drop destination | |
| 753 | - | may potentially choose a different action and/or mime type, | |
| 754 | - | based on wl_data_offer.source_actions and finally chosen by the | |
| 755 | - | user (e.g. popping up a menu with the available options). The | |
| 756 | - | final wl_data_offer.set_actions and wl_data_offer.accept requests | |
| 757 | - | must happen before the call to wl_data_offer.finish. | |
| 758 | - | </description> | |
| 759 | - | <arg name="dnd_action" type="uint" summary="action selected by the compositor" | |
| 760 | - | enum="wl_data_device_manager.dnd_action"/> | |
| 761 | - | </event> | |
| 762 | - | </interface> | |
| 763 | - | ||
| 764 | - | <interface name="wl_data_source" version="4"> | |
| 765 | - | <description summary="offer to transfer data"> | |
| 766 | - | The wl_data_source object is the source side of a wl_data_offer. | |
| 767 | - | It is created by the source client in a data transfer and | |
| 768 | - | provides a way to describe the offered data and a way to respond | |
| 769 | - | to requests to transfer the data. | |
| 770 | - | </description> | |
| 771 | - | ||
| 772 | - | <enum name="error"> | |
| 773 | - | <entry name="invalid_action_mask" value="0" | |
| 774 | - | summary="action mask contains invalid values"/> | |
| 775 | - | <entry name="invalid_source" value="1" | |
| 776 | - | summary="source doesn't accept this request"/> | |
| 777 | - | </enum> | |
| 778 | - | ||
| 779 | - | <request name="offer"> | |
| 780 | - | <description summary="add an offered mime type"> | |
| 781 | - | This request adds a mime type to the set of mime types | |
| 782 | - | advertised to targets. Can be called several times to offer | |
| 783 | - | multiple types. | |
| 784 | - | </description> | |
| 785 | - | <arg name="mime_type" type="string" summary="mime type offered by the data source"/> | |
| 786 | - | </request> | |
| 787 | - | ||
| 788 | - | <request name="destroy" type="destructor"> | |
| 789 | - | <description summary="destroy the data source"> | |
| 790 | - | Destroy the data source. | |
| 791 | - | </description> | |
| 792 | - | </request> | |
| 793 | - | ||
| 794 | - | <event name="target"> | |
| 795 | - | <description summary="a target accepts an offered mime type"> | |
| 796 | - | Sent when a target accepts pointer_focus or motion events. If | |
| 797 | - | a target does not accept any of the offered types, type is NULL. | |
| 798 | - | ||
| 799 | - | Used for feedback during drag-and-drop. | |
| 800 | - | </description> | |
| 801 | - | <arg name="mime_type" type="string" allow-null="true" summary="mime type accepted by the target"/> | |
| 802 | - | </event> | |
| 803 | - | ||
| 804 | - | <event name="send"> | |
| 805 | - | <description summary="send the data"> | |
| 806 | - | Request for data from the client. Send the data as the | |
| 807 | - | specified mime type over the passed file descriptor, then | |
| 808 | - | close it. | |
| 809 | - | </description> | |
| 810 | - | <arg name="mime_type" type="string" summary="mime type for the data"/> | |
| 811 | - | <arg name="fd" type="fd" summary="file descriptor for the data"/> | |
| 812 | - | </event> | |
| 813 | - | ||
| 814 | - | <event name="cancelled"> | |
| 815 | - | <description summary="selection was cancelled"> | |
| 816 | - | This data source is no longer valid. There are several reasons why | |
| 817 | - | this could happen: | |
| 818 | - | ||
| 819 | - | - The data source has been replaced by another data source. | |
| 820 | - | - The drag-and-drop operation was performed, but the drop destination | |
| 821 | - | did not accept any of the mime types offered through | |
| 822 | - | wl_data_source.target. | |
| 823 | - | - The drag-and-drop operation was performed, but the drop destination | |
| 824 | - | did not select any of the actions present in the mask offered through | |
| 825 | - | wl_data_source.action. | |
| 826 | - | - The drag-and-drop operation was performed but didn't happen over a | |
| 827 | - | surface. | |
| 828 | - | - The compositor cancelled the drag-and-drop operation (e.g. compositor | |
| 829 | - | dependent timeouts to avoid stale drag-and-drop transfers). | |
| 830 | - | ||
| 831 | - | The client should clean up and destroy this data source. | |
| 832 | - | ||
| 833 | - | For objects of version 2 or older, wl_data_source.cancelled will | |
| 834 | - | only be emitted if the data source was replaced by another data | |
| 835 | - | source. | |
| 836 | - | </description> | |
| 837 | - | </event> | |
| 838 | - | ||
| 839 | - | <!-- Version 3 additions --> | |
| 840 | - | ||
| 841 | - | <request name="set_actions" since="3"> | |
| 842 | - | <description summary="set the available drag-and-drop actions"> | |
| 843 | - | Sets the actions that the source side client supports for this | |
| 844 | - | operation. This request may trigger wl_data_source.action and | |
| 845 | - | wl_data_offer.action events if the compositor needs to change the | |
| 846 | - | selected action. | |
| 847 | - | ||
| 848 | - | The dnd_actions argument must contain only values expressed in the | |
| 849 | - | wl_data_device_manager.dnd_actions enum, otherwise it will result | |
| 850 | - | in a protocol error. | |
| 851 | - | ||
| 852 | - | This request must be made once only, and can only be made on sources | |
| 853 | - | used in drag-and-drop, so it must be performed before | |
| 854 | - | wl_data_device.start_drag. Attempting to use the source other than | |
| 855 | - | for drag-and-drop will raise a protocol error. | |
| 856 | - | </description> | |
| 857 | - | <arg name="dnd_actions" type="uint" summary="actions supported by the data source" | |
| 858 | - | enum="wl_data_device_manager.dnd_action"/> | |
| 859 | - | </request> | |
| 860 | - | ||
| 861 | - | <event name="dnd_drop_performed" since="3"> | |
| 862 | - | <description summary="the drag-and-drop operation physically finished"> | |
| 863 | - | The user performed the drop action. This event does not indicate | |
| 864 | - | acceptance, wl_data_source.cancelled may still be emitted afterwards | |
| 865 | - | if the drop destination does not accept any mime type. | |
| 866 | - | ||
| 867 | - | However, this event might not be received if the compositor cancelled | |
| 868 | - | the drag-and-drop operation before this event could happen. | |
| 869 | - | ||
| 870 | - | Note that the data_source may still be used in the future and should | |
| 871 | - | not be destroyed here. | |
| 872 | - | </description> | |
| 873 | - | </event> | |
| 874 | - | ||
| 875 | - | <event name="dnd_finished" since="3"> | |
| 876 | - | <description summary="the drag-and-drop operation concluded"> | |
| 877 | - | The drop destination finished interoperating with this data | |
| 878 | - | source, so the client is now free to destroy this data source and | |
| 879 | - | free all associated data. | |
| 880 | - | ||
| 881 | - | If the action used to perform the operation was "move", the | |
| 882 | - | source can now delete the transferred data. | |
| 883 | - | </description> | |
| 884 | - | </event> | |
| 885 | - | ||
| 886 | - | <event name="action" since="3"> | |
| 887 | - | <description summary="notify the selected action"> | |
| 888 | - | This event indicates the action selected by the compositor after | |
| 889 | - | matching the source/destination side actions. Only one action (or | |
| 890 | - | none) will be offered here. | |
| 891 | - | ||
| 892 | - | This event can be emitted multiple times during the drag-and-drop | |
| 893 | - | operation, mainly in response to destination side changes through | |
| 894 | - | wl_data_offer.set_actions, and as the data device enters/leaves | |
| 895 | - | surfaces. | |
| 896 | - | ||
| 897 | - | It is only possible to receive this event after | |
| 898 | - | wl_data_source.dnd_drop_performed if the drag-and-drop operation | |
| 899 | - | ended in an "ask" action, in which case the final wl_data_source.action | |
| 900 | - | event will happen immediately before wl_data_source.dnd_finished. | |
| 901 | - | ||
| 902 | - | Compositors may also change the selected action on the fly, mainly | |
| 903 | - | in response to keyboard modifier changes during the drag-and-drop | |
| 904 | - | operation. | |
| 905 | - | ||
| 906 | - | The most recent action received is always the valid one. The chosen | |
| 907 | - | action may change alongside negotiation (e.g. an "ask" action can turn | |
| 908 | - | into a "move" operation), so the effects of the final action must | |
| 909 | - | always be applied in wl_data_source.dnd_finished. | |
| 910 | - | ||
| 911 | - | Clients can trigger cursor surface changes from this point, so | |
| 912 | - | they reflect the current action. | |
| 913 | - | </description> | |
| 914 | - | <arg name="dnd_action" type="uint" summary="action selected by the compositor" | |
| 915 | - | enum="wl_data_device_manager.dnd_action"/> | |
| 916 | - | </event> | |
| 917 | - | </interface> | |
| 918 | - | ||
| 919 | - | <interface name="wl_data_device" version="4"> | |
| 920 | - | <description summary="data transfer device"> | |
| 921 | - | There is one wl_data_device per seat which can be obtained | |
| 922 | - | from the global wl_data_device_manager singleton. | |
| 923 | - | ||
| 924 | - | A wl_data_device provides access to inter-client data transfer | |
| 925 | - | mechanisms such as copy-and-paste and drag-and-drop. | |
| 926 | - | </description> | |
| 927 | - | ||
| 928 | - | <enum name="error"> | |
| 929 | - | <entry name="role" value="0" summary="given wl_surface has another role"/> | |
| 930 | - | <entry name="used_source" value="1" summary="source has already been used"/> | |
| 931 | - | </enum> | |
| 932 | - | ||
| 933 | - | <request name="start_drag"> | |
| 934 | - | <description summary="start drag-and-drop operation"> | |
| 935 | - | This request asks the compositor to start a drag-and-drop | |
| 936 | - | operation on behalf of the client. | |
| 937 | - | ||
| 938 | - | The source argument is the data source that provides the data | |
| 939 | - | for the eventual data transfer. If source is NULL, enter, leave | |
| 940 | - | and motion events are sent only to the client that initiated the | |
| 941 | - | drag and the client is expected to handle the data passing | |
| 942 | - | internally. If source is destroyed, the drag-and-drop session will be | |
| 943 | - | cancelled. | |
| 944 | - | ||
| 945 | - | The origin surface is the surface where the drag originates and | |
| 946 | - | the client must have an active implicit grab that matches the | |
| 947 | - | serial. | |
| 948 | - | ||
| 949 | - | The icon surface is an optional (can be NULL) surface that | |
| 950 | - | provides an icon to be moved around with the cursor. Initially, | |
| 951 | - | the top-left corner of the icon surface is placed at the cursor | |
| 952 | - | hotspot, but subsequent wl_surface.offset requests can move the | |
| 953 | - | relative position. Attach requests must be confirmed with | |
| 954 | - | wl_surface.commit as usual. The icon surface is given the role of | |
| 955 | - | a drag-and-drop icon. If the icon surface already has another role, | |
| 956 | - | it raises a protocol error. | |
| 957 | - | ||
| 958 | - | The input region is ignored for wl_surfaces with the role of a | |
| 959 | - | drag-and-drop icon. | |
| 960 | - | ||
| 961 | - | The given source may not be used in any further set_selection or | |
| 962 | - | start_drag requests. Attempting to reuse a previously-used source | |
| 963 | - | may send a used_source error. | |
| 964 | - | </description> | |
| 965 | - | <arg name="source" type="object" interface="wl_data_source" allow-null="true" summary="data source for the eventual transfer"/> | |
| 966 | - | <arg name="origin" type="object" interface="wl_surface" summary="surface where the drag originates"/> | |
| 967 | - | <arg name="icon" type="object" interface="wl_surface" allow-null="true" summary="drag-and-drop icon surface"/> | |
| 968 | - | <arg name="serial" type="uint" summary="serial number of the implicit grab on the origin"/> | |
| 969 | - | </request> | |
| 970 | - | ||
| 971 | - | <request name="set_selection"> | |
| 972 | - | <description summary="copy data to the selection"> | |
| 973 | - | This request asks the compositor to set the selection | |
| 974 | - | to the data from the source on behalf of the client. | |
| 975 | - | ||
| 976 | - | To unset the selection, set the source to NULL. | |
| 977 | - | ||
| 978 | - | The given source may not be used in any further set_selection or | |
| 979 | - | start_drag requests. Attempting to reuse a previously-used source | |
| 980 | - | may send a used_source error. | |
| 981 | - | </description> | |
| 982 | - | <arg name="source" type="object" interface="wl_data_source" allow-null="true" summary="data source for the selection"/> | |
| 983 | - | <arg name="serial" type="uint" summary="serial number of the event that triggered this request"/> | |
| 984 | - | </request> | |
| 985 | - | ||
| 986 | - | <event name="data_offer"> | |
| 987 | - | <description summary="introduce a new wl_data_offer"> | |
| 988 | - | The data_offer event introduces a new wl_data_offer object, | |
| 989 | - | which will subsequently be used in either the | |
| 990 | - | data_device.enter event (for drag-and-drop) or the | |
| 991 | - | data_device.selection event (for selections). Immediately | |
| 992 | - | following the data_device.data_offer event, the new data_offer | |
| 993 | - | object will send out data_offer.offer events to describe the | |
| 994 | - | mime types it offers. | |
| 995 | - | </description> | |
| 996 | - | <arg name="id" type="new_id" interface="wl_data_offer" summary="the new data_offer object"/> | |
| 997 | - | </event> | |
| 998 | - | ||
| 999 | - | <event name="enter"> | |
| 1000 | - | <description summary="initiate drag-and-drop session"> | |
| 1001 | - | This event is sent when an active drag-and-drop pointer enters | |
| 1002 | - | a surface owned by the client. The position of the pointer at | |
| 1003 | - | enter time is provided by the x and y arguments, in surface-local | |
| 1004 | - | coordinates. | |
| 1005 | - | </description> | |
| 1006 | - | <arg name="serial" type="uint" summary="serial number of the enter event"/> | |
| 1007 | - | <arg name="surface" type="object" interface="wl_surface" summary="client surface entered"/> | |
| 1008 | - | <arg name="x" type="fixed" summary="surface-local x coordinate"/> | |
| 1009 | - | <arg name="y" type="fixed" summary="surface-local y coordinate"/> | |
| 1010 | - | <arg name="id" type="object" interface="wl_data_offer" allow-null="true" | |
| 1011 | - | summary="source data_offer object"/> | |
| 1012 | - | </event> | |
| 1013 | - | ||
| 1014 | - | <event name="leave"> | |
| 1015 | - | <description summary="end drag-and-drop session"> | |
| 1016 | - | This event is sent when the drag-and-drop pointer leaves the | |
| 1017 | - | surface and the session ends. The client must destroy the | |
| 1018 | - | wl_data_offer introduced at enter time at this point. | |
| 1019 | - | </description> | |
| 1020 | - | </event> | |
| 1021 | - | ||
| 1022 | - | <event name="motion"> | |
| 1023 | - | <description summary="drag-and-drop session motion"> | |
| 1024 | - | This event is sent when the drag-and-drop pointer moves within | |
| 1025 | - | the currently focused surface. The new position of the pointer | |
| 1026 | - | is provided by the x and y arguments, in surface-local | |
| 1027 | - | coordinates. | |
| 1028 | - | </description> | |
| 1029 | - | <arg name="time" type="uint" summary="timestamp with millisecond granularity"/> | |
| 1030 | - | <arg name="x" type="fixed" summary="surface-local x coordinate"/> | |
| 1031 | - | <arg name="y" type="fixed" summary="surface-local y coordinate"/> | |
| 1032 | - | </event> | |
| 1033 | - | ||
| 1034 | - | <event name="drop"> | |
| 1035 | - | <description summary="end drag-and-drop session successfully"> | |
| 1036 | - | The event is sent when a drag-and-drop operation is ended | |
| 1037 | - | because the implicit grab is removed. | |
| 1038 | - | ||
| 1039 | - | The drag-and-drop destination is expected to honor the last action | |
| 1040 | - | received through wl_data_offer.action, if the resulting action is | |
| 1041 | - | "copy" or "move", the destination can still perform | |
| 1042 | - | wl_data_offer.receive requests, and is expected to end all | |
| 1043 | - | transfers with a wl_data_offer.finish request. | |
| 1044 | - | ||
| 1045 | - | If the resulting action is "ask", the action will not be considered | |
| 1046 | - | final. The drag-and-drop destination is expected to perform one last | |
| 1047 | - | wl_data_offer.set_actions request, or wl_data_offer.destroy in order | |
| 1048 | - | to cancel the operation. | |
| 1049 | - | </description> | |
| 1050 | - | </event> | |
| 1051 | - | ||
| 1052 | - | <event name="selection"> | |
| 1053 | - | <description summary="advertise new selection"> | |
| 1054 | - | The selection event is sent out to notify the client of a new | |
| 1055 | - | wl_data_offer for the selection for this device. The | |
| 1056 | - | data_device.data_offer and the data_offer.offer events are | |
| 1057 | - | sent out immediately before this event to introduce the data | |
| 1058 | - | offer object. The selection event is sent to a client | |
| 1059 | - | immediately before receiving keyboard focus and when a new | |
| 1060 | - | selection is set while the client has keyboard focus. The | |
| 1061 | - | data_offer is valid until a new data_offer or NULL is received | |
| 1062 | - | or until the client loses keyboard focus. Switching surface with | |
| 1063 | - | keyboard focus within the same client doesn't mean a new selection | |
| 1064 | - | will be sent. The client must destroy the previous selection | |
| 1065 | - | data_offer, if any, upon receiving this event. | |
| 1066 | - | </description> | |
| 1067 | - | <arg name="id" type="object" interface="wl_data_offer" allow-null="true" | |
| 1068 | - | summary="selection data_offer object"/> | |
| 1069 | - | </event> | |
| 1070 | - | ||
| 1071 | - | <!-- Version 2 additions --> | |
| 1072 | - | ||
| 1073 | - | <request name="release" type="destructor" since="2"> | |
| 1074 | - | <description summary="destroy data device"> | |
| 1075 | - | This request destroys the data device. | |
| 1076 | - | </description> | |
| 1077 | - | </request> | |
| 1078 | - | </interface> | |
| 1079 | - | ||
| 1080 | - | <interface name="wl_data_device_manager" version="4"> | |
| 1081 | - | <description summary="data transfer interface"> | |
| 1082 | - | The wl_data_device_manager is a singleton global object that | |
| 1083 | - | provides access to inter-client data transfer mechanisms such as | |
| 1084 | - | copy-and-paste and drag-and-drop. These mechanisms are tied to | |
| 1085 | - | a wl_seat and this interface lets a client get a wl_data_device | |
| 1086 | - | corresponding to a wl_seat. | |
| 1087 | - | ||
| 1088 | - | Depending on the version bound, the objects created from the bound | |
| 1089 | - | wl_data_device_manager object will have different requirements for | |
| 1090 | - | functioning properly. See wl_data_source.set_actions, | |
| 1091 | - | wl_data_offer.accept and wl_data_offer.finish for details. | |
| 1092 | - | </description> | |
| 1093 | - | ||
| 1094 | - | <request name="create_data_source"> | |
| 1095 | - | <description summary="create a new data source"> | |
| 1096 | - | Create a new data source. | |
| 1097 | - | </description> | |
| 1098 | - | <arg name="id" type="new_id" interface="wl_data_source" summary="data source to create"/> | |
| 1099 | - | </request> | |
| 1100 | - | ||
| 1101 | - | <request name="get_data_device"> | |
| 1102 | - | <description summary="create a new data device"> | |
| 1103 | - | Create a new data device for a given seat. | |
| 1104 | - | </description> | |
| 1105 | - | <arg name="id" type="new_id" interface="wl_data_device" summary="data device to create"/> | |
| 1106 | - | <arg name="seat" type="object" interface="wl_seat" summary="seat associated with the data device"/> | |
| 1107 | - | </request> | |
| 1108 | - | ||
| 1109 | - | <!-- Version 3 additions --> | |
| 1110 | - | ||
| 1111 | - | <enum name="dnd_action" bitfield="true" since="3"> | |
| 1112 | - | <description summary="drag and drop actions"> | |
| 1113 | - | This is a bitmask of the available/preferred actions in a | |
| 1114 | - | drag-and-drop operation. | |
| 1115 | - | ||
| 1116 | - | In the compositor, the selected action is a result of matching the | |
| 1117 | - | actions offered by the source and destination sides. "action" events | |
| 1118 | - | with a "none" action will be sent to both source and destination if | |
| 1119 | - | there is no match. All further checks will effectively happen on | |
| 1120 | - | (source actions ∩ destination actions). | |
| 1121 | - | ||
| 1122 | - | In addition, compositors may also pick different actions in | |
| 1123 | - | reaction to key modifiers being pressed. One common design that | |
| 1124 | - | is used in major toolkits (and the behavior recommended for | |
| 1125 | - | compositors) is: | |
| 1126 | - | ||
| 1127 | - | - If no modifiers are pressed, the first match (in bit order) | |
| 1128 | - | will be used. | |
| 1129 | - | - Pressing Shift selects "move", if enabled in the mask. | |
| 1130 | - | - Pressing Control selects "copy", if enabled in the mask. | |
| 1131 | - | ||
| 1132 | - | Behavior beyond that is considered implementation-dependent. | |
| 1133 | - | Compositors may for example bind other modifiers (like Alt/Meta) | |
| 1134 | - | or drags initiated with other buttons than BTN_LEFT to specific | |
| 1135 | - | actions (e.g. "ask"). | |
| 1136 | - | </description> | |
| 1137 | - | <entry name="none" value="0" summary="no action"/> | |
| 1138 | - | <entry name="copy" value="1" summary="copy action"/> | |
| 1139 | - | <entry name="move" value="2" summary="move action"/> | |
| 1140 | - | <entry name="ask" value="4" summary="ask action"/> | |
| 1141 | - | </enum> | |
| 1142 | - | ||
| 1143 | - | <!-- Version 4 additions --> | |
| 1144 | - | ||
| 1145 | - | <request name="release" type="destructor" since="4"> | |
| 1146 | - | <description summary="destroy wl_data_device_manager"> | |
| 1147 | - | This request destroys the wl_data_device_manager. This has no effect on any other | |
| 1148 | - | objects. | |
| 1149 | - | </description> | |
| 1150 | - | </request> | |
| 1151 | - | </interface> | |
| 1152 | - | ||
| 1153 | - | <interface name="wl_shell" version="1"> | |
| 1154 | - | <description summary="create desktop-style surfaces"> | |
| 1155 | - | This interface is implemented by servers that provide | |
| 1156 | - | desktop-style user interfaces. | |
| 1157 | - | ||
| 1158 | - | It allows clients to associate a wl_shell_surface with | |
| 1159 | - | a basic surface. | |
| 1160 | - | ||
| 1161 | - | Note! This protocol is deprecated and not intended for production use. | |
| 1162 | - | For desktop-style user interfaces, use xdg_shell. Compositors and clients | |
| 1163 | - | should not implement this interface. | |
| 1164 | - | </description> | |
| 1165 | - | ||
| 1166 | - | <enum name="error"> | |
| 1167 | - | <entry name="role" value="0" summary="given wl_surface has another role"/> | |
| 1168 | - | </enum> | |
| 1169 | - | ||
| 1170 | - | <request name="get_shell_surface"> | |
| 1171 | - | <description summary="create a shell surface from a surface"> | |
| 1172 | - | Create a shell surface for an existing surface. This gives | |
| 1173 | - | the wl_surface the role of a shell surface. If the wl_surface | |
| 1174 | - | already has another role, it raises a protocol error. | |
| 1175 | - | ||
| 1176 | - | Only one shell surface can be associated with a given surface. | |
| 1177 | - | </description> | |
| 1178 | - | <arg name="id" type="new_id" interface="wl_shell_surface" summary="shell surface to create"/> | |
| 1179 | - | <arg name="surface" type="object" interface="wl_surface" summary="surface to be given the shell surface role"/> | |
| 1180 | - | </request> | |
| 1181 | - | </interface> | |
| 1182 | - | ||
| 1183 | - | <interface name="wl_shell_surface" version="1"> | |
| 1184 | - | <description summary="desktop-style metadata interface"> | |
| 1185 | - | An interface that may be implemented by a wl_surface, for | |
| 1186 | - | implementations that provide a desktop-style user interface. | |
| 1187 | - | ||
| 1188 | - | It provides requests to treat surfaces like toplevel, fullscreen | |
| 1189 | - | or popup windows, move, resize or maximize them, associate | |
| 1190 | - | metadata like title and class, etc. | |
| 1191 | - | ||
| 1192 | - | On the server side the object is automatically destroyed when | |
| 1193 | - | the related wl_surface is destroyed. On the client side, | |
| 1194 | - | wl_shell_surface_destroy() must be called before destroying | |
| 1195 | - | the wl_surface object. | |
| 1196 | - | </description> | |
| 1197 | - | ||
| 1198 | - | <request name="pong"> | |
| 1199 | - | <description summary="respond to a ping event"> | |
| 1200 | - | A client must respond to a ping event with a pong request or | |
| 1201 | - | the client may be deemed unresponsive. | |
| 1202 | - | </description> | |
| 1203 | - | <arg name="serial" type="uint" summary="serial number of the ping event"/> | |
| 1204 | - | </request> | |
| 1205 | - | ||
| 1206 | - | <request name="move"> | |
| 1207 | - | <description summary="start an interactive move"> | |
| 1208 | - | Start a pointer-driven move of the surface. | |
| 1209 | - | ||
| 1210 | - | This request must be used in response to a button press event. | |
| 1211 | - | The server may ignore move requests depending on the state of | |
| 1212 | - | the surface (e.g. fullscreen or maximized). | |
| 1213 | - | </description> | |
| 1214 | - | <arg name="seat" type="object" interface="wl_seat" summary="seat whose pointer is used"/> | |
| 1215 | - | <arg name="serial" type="uint" summary="serial number of the implicit grab on the pointer"/> | |
| 1216 | - | </request> | |
| 1217 | - | ||
| 1218 | - | <enum name="resize" bitfield="true"> | |
| 1219 | - | <description summary="edge values for resizing"> | |
| 1220 | - | These values are used to indicate which edge of a surface | |
| 1221 | - | is being dragged in a resize operation. The server may | |
| 1222 | - | use this information to adapt its behavior, e.g. choose | |
| 1223 | - | an appropriate cursor image. | |
| 1224 | - | </description> | |
| 1225 | - | <entry name="none" value="0" summary="no edge"/> | |
| 1226 | - | <entry name="top" value="1" summary="top edge"/> | |
| 1227 | - | <entry name="bottom" value="2" summary="bottom edge"/> | |
| 1228 | - | <entry name="left" value="4" summary="left edge"/> | |
| 1229 | - | <entry name="top_left" value="5" summary="top and left edges"/> | |
| 1230 | - | <entry name="bottom_left" value="6" summary="bottom and left edges"/> | |
| 1231 | - | <entry name="right" value="8" summary="right edge"/> | |
| 1232 | - | <entry name="top_right" value="9" summary="top and right edges"/> | |
| 1233 | - | <entry name="bottom_right" value="10" summary="bottom and right edges"/> | |
| 1234 | - | </enum> | |
| 1235 | - | ||
| 1236 | - | <request name="resize"> | |
| 1237 | - | <description summary="start an interactive resize"> | |
| 1238 | - | Start a pointer-driven resizing of the surface. | |
| 1239 | - | ||
| 1240 | - | This request must be used in response to a button press event. | |
| 1241 | - | The server may ignore resize requests depending on the state of | |
| 1242 | - | the surface (e.g. fullscreen or maximized). | |
| 1243 | - | </description> | |
| 1244 | - | <arg name="seat" type="object" interface="wl_seat" summary="seat whose pointer is used"/> | |
| 1245 | - | <arg name="serial" type="uint" summary="serial number of the implicit grab on the pointer"/> | |
| 1246 | - | <arg name="edges" type="uint" enum="resize" summary="which edge or corner is being dragged"/> | |
| 1247 | - | </request> | |
| 1248 | - | ||
| 1249 | - | <request name="set_toplevel"> | |
| 1250 | - | <description summary="make the surface a toplevel surface"> | |
| 1251 | - | Map the surface as a toplevel surface. | |
| 1252 | - | ||
| 1253 | - | A toplevel surface is not fullscreen, maximized or transient. | |
| 1254 | - | </description> | |
| 1255 | - | </request> | |
| 1256 | - | ||
| 1257 | - | <enum name="transient" bitfield="true"> | |
| 1258 | - | <description summary="details of transient behaviour"> | |
| 1259 | - | These flags specify details of the expected behaviour | |
| 1260 | - | of transient surfaces. Used in the set_transient request. | |
| 1261 | - | </description> | |
| 1262 | - | <entry name="inactive" value="0x1" summary="do not set keyboard focus"/> | |
| 1263 | - | </enum> | |
| 1264 | - | ||
| 1265 | - | <request name="set_transient"> | |
| 1266 | - | <description summary="make the surface a transient surface"> | |
| 1267 | - | Map the surface relative to an existing surface. | |
| 1268 | - | ||
| 1269 | - | The x and y arguments specify the location of the upper left | |
| 1270 | - | corner of the surface relative to the upper left corner of the | |
| 1271 | - | parent surface, in surface-local coordinates. | |
| 1272 | - | ||
| 1273 | - | The flags argument controls details of the transient behaviour. | |
| 1274 | - | </description> | |
| 1275 | - | <arg name="parent" type="object" interface="wl_surface" summary="parent surface"/> | |
| 1276 | - | <arg name="x" type="int" summary="surface-local x coordinate"/> | |
| 1277 | - | <arg name="y" type="int" summary="surface-local y coordinate"/> | |
| 1278 | - | <arg name="flags" type="uint" enum="transient" summary="transient surface behavior"/> | |
| 1279 | - | </request> | |
| 1280 | - | ||
| 1281 | - | <enum name="fullscreen_method"> | |
| 1282 | - | <description summary="different method to set the surface fullscreen"> | |
| 1283 | - | Hints to indicate to the compositor how to deal with a conflict | |
| 1284 | - | between the dimensions of the surface and the dimensions of the | |
| 1285 | - | output. The compositor is free to ignore this parameter. | |
| 1286 | - | </description> | |
| 1287 | - | <entry name="default" value="0" summary="no preference, apply default policy"/> | |
| 1288 | - | <entry name="scale" value="1" summary="scale, preserve the surface's aspect ratio and center on output"/> | |
| 1289 | - | <entry name="driver" value="2" summary="switch output mode to the smallest mode that can fit the surface, add black borders to compensate size mismatch"/> | |
| 1290 | - | <entry name="fill" value="3" summary="no upscaling, center on output and add black borders to compensate size mismatch"/> | |
| 1291 | - | </enum> | |
| 1292 | - | ||
| 1293 | - | <request name="set_fullscreen"> | |
| 1294 | - | <description summary="make the surface a fullscreen surface"> | |
| 1295 | - | Map the surface as a fullscreen surface. | |
| 1296 | - | ||
| 1297 | - | If an output parameter is given then the surface will be made | |
| 1298 | - | fullscreen on that output. If the client does not specify the | |
| 1299 | - | output then the compositor will apply its policy - usually | |
| 1300 | - | choosing the output on which the surface has the biggest surface | |
| 1301 | - | area. | |
| 1302 | - | ||
| 1303 | - | The client may specify a method to resolve a size conflict | |
| 1304 | - | between the output size and the surface size - this is provided | |
| 1305 | - | through the method parameter. | |
| 1306 | - | ||
| 1307 | - | The framerate parameter is used only when the method is set | |
| 1308 | - | to "driver", to indicate the preferred framerate. A value of 0 | |
| 1309 | - | indicates that the client does not care about framerate. The | |
| 1310 | - | framerate is specified in mHz, that is framerate of 60000 is 60Hz. | |
| 1311 | - | ||
| 1312 | - | A method of "scale" or "driver" implies a scaling operation of | |
| 1313 | - | the surface, either via a direct scaling operation or a change of | |
| 1314 | - | the output mode. This will override any kind of output scaling, so | |
| 1315 | - | that mapping a surface with a buffer size equal to the mode can | |
| 1316 | - | fill the screen independent of buffer_scale. | |
| 1317 | - | ||
| 1318 | - | A method of "fill" means we don't scale up the buffer, however | |
| 1319 | - | any output scale is applied. This means that you may run into | |
| 1320 | - | an edge case where the application maps a buffer with the same | |
| 1321 | - | size of the output mode but buffer_scale 1 (thus making a | |
| 1322 | - | surface larger than the output). In this case it is allowed to | |
| 1323 | - | downscale the results to fit the screen. | |
| 1324 | - | ||
| 1325 | - | The compositor must reply to this request with a configure event | |
| 1326 | - | with the dimensions for the output on which the surface will | |
| 1327 | - | be made fullscreen. | |
| 1328 | - | </description> | |
| 1329 | - | <arg name="method" type="uint" enum="fullscreen_method" summary="method for resolving size conflict"/> | |
| 1330 | - | <arg name="framerate" type="uint" summary="framerate in mHz"/> | |
| 1331 | - | <arg name="output" type="object" interface="wl_output" allow-null="true" | |
| 1332 | - | summary="output on which the surface is to be fullscreen"/> | |
| 1333 | - | </request> | |
| 1334 | - | ||
| 1335 | - | <request name="set_popup"> | |
| 1336 | - | <description summary="make the surface a popup surface"> | |
| 1337 | - | Map the surface as a popup. | |
| 1338 | - | ||
| 1339 | - | A popup surface is a transient surface with an added pointer | |
| 1340 | - | grab. | |
| 1341 | - | ||
| 1342 | - | An existing implicit grab will be changed to owner-events mode, | |
| 1343 | - | and the popup grab will continue after the implicit grab ends | |
| 1344 | - | (i.e. releasing the mouse button does not cause the popup to | |
| 1345 | - | be unmapped). | |
| 1346 | - | ||
| 1347 | - | The popup grab continues until the window is destroyed or a | |
| 1348 | - | mouse button is pressed in any other client's window. A click | |
| 1349 | - | in any of the client's surfaces is reported as normal, however, | |
| 1350 | - | clicks in other clients' surfaces will be discarded and trigger | |
| 1351 | - | the callback. | |
| 1352 | - | ||
| 1353 | - | The x and y arguments specify the location of the upper left | |
| 1354 | - | corner of the surface relative to the upper left corner of the | |
| 1355 | - | parent surface, in surface-local coordinates. | |
| 1356 | - | </description> | |
| 1357 | - | <arg name="seat" type="object" interface="wl_seat" summary="seat whose pointer is used"/> | |
| 1358 | - | <arg name="serial" type="uint" summary="serial number of the implicit grab on the pointer"/> | |
| 1359 | - | <arg name="parent" type="object" interface="wl_surface" summary="parent surface"/> | |
| 1360 | - | <arg name="x" type="int" summary="surface-local x coordinate"/> | |
| 1361 | - | <arg name="y" type="int" summary="surface-local y coordinate"/> | |
| 1362 | - | <arg name="flags" type="uint" enum="transient" summary="transient surface behavior"/> | |
| 1363 | - | </request> | |
| 1364 | - | ||
| 1365 | - | <request name="set_maximized"> | |
| 1366 | - | <description summary="make the surface a maximized surface"> | |
| 1367 | - | Map the surface as a maximized surface. | |
| 1368 | - | ||
| 1369 | - | If an output parameter is given then the surface will be | |
| 1370 | - | maximized on that output. If the client does not specify the | |
| 1371 | - | output then the compositor will apply its policy - usually | |
| 1372 | - | choosing the output on which the surface has the biggest surface | |
| 1373 | - | area. | |
| 1374 | - | ||
| 1375 | - | The compositor will reply with a configure event telling | |
| 1376 | - | the expected new surface size. The operation is completed | |
| 1377 | - | on the next buffer attach to this surface. | |
| 1378 | - | ||
| 1379 | - | A maximized surface typically fills the entire output it is | |
| 1380 | - | bound to, except for desktop elements such as panels. This is | |
| 1381 | - | the main difference between a maximized shell surface and a | |
| 1382 | - | fullscreen shell surface. | |
| 1383 | - | ||
| 1384 | - | The details depend on the compositor implementation. | |
| 1385 | - | </description> | |
| 1386 | - | <arg name="output" type="object" interface="wl_output" allow-null="true" | |
| 1387 | - | summary="output on which the surface is to be maximized"/> | |
| 1388 | - | </request> | |
| 1389 | - | ||
| 1390 | - | <request name="set_title"> | |
| 1391 | - | <description summary="set surface title"> | |
| 1392 | - | Set a short title for the surface. | |
| 1393 | - | ||
| 1394 | - | This string may be used to identify the surface in a task bar, | |
| 1395 | - | window list, or other user interface elements provided by the | |
| 1396 | - | compositor. | |
| 1397 | - | ||
| 1398 | - | The string must be encoded in UTF-8. | |
| 1399 | - | </description> | |
| 1400 | - | <arg name="title" type="string" summary="surface title"/> | |
| 1401 | - | </request> | |
| 1402 | - | ||
| 1403 | - | <request name="set_class"> | |
| 1404 | - | <description summary="set surface class"> | |
| 1405 | - | Set a class for the surface. | |
| 1406 | - | ||
| 1407 | - | The surface class identifies the general class of applications | |
| 1408 | - | to which the surface belongs. A common convention is to use the | |
| 1409 | - | file name (or the full path if it is a non-standard location) of | |
| 1410 | - | the application's .desktop file as the class. | |
| 1411 | - | </description> | |
| 1412 | - | <arg name="class_" type="string" summary="surface class"/> | |
| 1413 | - | </request> | |
| 1414 | - | ||
| 1415 | - | <event name="ping"> | |
| 1416 | - | <description summary="ping client"> | |
| 1417 | - | Ping a client to check if it is receiving events and sending | |
| 1418 | - | requests. A client is expected to reply with a pong request. | |
| 1419 | - | </description> | |
| 1420 | - | <arg name="serial" type="uint" summary="serial number of the ping"/> | |
| 1421 | - | </event> | |
| 1422 | - | ||
| 1423 | - | <event name="configure"> | |
| 1424 | - | <description summary="suggest resize"> | |
| 1425 | - | The configure event asks the client to resize its surface. | |
| 1426 | - | ||
| 1427 | - | The size is a hint, in the sense that the client is free to | |
| 1428 | - | ignore it if it doesn't resize, pick a smaller size (to | |
| 1429 | - | satisfy aspect ratio or resize in steps of NxM pixels). | |
| 1430 | - | ||
| 1431 | - | The edges parameter provides a hint about how the surface | |
| 1432 | - | was resized. The client may use this information to decide | |
| 1433 | - | how to adjust its content to the new size (e.g. a scrolling | |
| 1434 | - | area might adjust its content position to leave the viewable | |
| 1435 | - | content unmoved). | |
| 1436 | - | ||
| 1437 | - | The client is free to dismiss all but the last configure | |
| 1438 | - | event it received. | |
| 1439 | - | ||
| 1440 | - | The width and height arguments specify the size of the window | |
| 1441 | - | in surface-local coordinates. | |
| 1442 | - | </description> | |
| 1443 | - | <arg name="edges" type="uint" enum="resize" summary="how the surface was resized"/> | |
| 1444 | - | <arg name="width" type="int" summary="new width of the surface"/> | |
| 1445 | - | <arg name="height" type="int" summary="new height of the surface"/> | |
| 1446 | - | </event> | |
| 1447 | - | ||
| 1448 | - | <event name="popup_done"> | |
| 1449 | - | <description summary="popup interaction is done"> | |
| 1450 | - | The popup_done event is sent out when a popup grab is broken, | |
| 1451 | - | that is, when the user clicks a surface that doesn't belong | |
| 1452 | - | to the client owning the popup surface. | |
| 1453 | - | </description> | |
| 1454 | - | </event> | |
| 1455 | - | </interface> | |
| 1456 | - | ||
| 1457 | - | <interface name="wl_surface" version="7"> | |
| 1458 | - | <description summary="an onscreen surface"> | |
| 1459 | - | A surface is a rectangular area that may be displayed on zero | |
| 1460 | - | or more outputs, and shown any number of times at the compositor's | |
| 1461 | - | discretion. They can present wl_buffers, receive user input, and | |
| 1462 | - | define a local coordinate system. | |
| 1463 | - | ||
| 1464 | - | The size of a surface (and relative positions on it) is described | |
| 1465 | - | in surface-local coordinates, which may differ from the buffer | |
| 1466 | - | coordinates of the pixel content, in case a buffer_transform | |
| 1467 | - | or a buffer_scale is used. | |
| 1468 | - | ||
| 1469 | - | A surface without a "role" is fairly useless: a compositor does | |
| 1470 | - | not know where, when or how to present it. The role is the | |
| 1471 | - | purpose of a wl_surface. Examples of roles are a cursor for a | |
| 1472 | - | pointer (as set by wl_pointer.set_cursor), a drag icon | |
| 1473 | - | (wl_data_device.start_drag), a sub-surface | |
| 1474 | - | (wl_subcompositor.get_subsurface), and a window as defined by a | |
| 1475 | - | shell protocol (e.g. wl_shell.get_shell_surface). | |
| 1476 | - | ||
| 1477 | - | A surface can have only one role at a time. Initially a | |
| 1478 | - | wl_surface does not have a role. Once a wl_surface is given a | |
| 1479 | - | role, it is set permanently for the whole lifetime of the | |
| 1480 | - | wl_surface object. Giving the current role again is allowed, | |
| 1481 | - | unless explicitly forbidden by the relevant interface | |
| 1482 | - | specification. | |
| 1483 | - | ||
| 1484 | - | Surface roles are given by requests in other interfaces such as | |
| 1485 | - | wl_pointer.set_cursor. The request should explicitly mention | |
| 1486 | - | that this request gives a role to a wl_surface. Often, this | |
| 1487 | - | request also creates a new protocol object that represents the | |
| 1488 | - | role and adds additional functionality to wl_surface. When a | |
| 1489 | - | client wants to destroy a wl_surface, they must destroy this role | |
| 1490 | - | object before the wl_surface, otherwise a defunct_role_object error is | |
| 1491 | - | sent. | |
| 1492 | - | ||
| 1493 | - | Destroying the role object does not remove the role from the | |
| 1494 | - | wl_surface, but it may stop the wl_surface from "playing the role". | |
| 1495 | - | For instance, if a wl_subsurface object is destroyed, the wl_surface | |
| 1496 | - | it was created for will be unmapped and forget its position and | |
| 1497 | - | z-order. It is allowed to create a wl_subsurface for the same | |
| 1498 | - | wl_surface again, but it is not allowed to use the wl_surface as | |
| 1499 | - | a cursor (cursor is a different role than sub-surface, and role | |
| 1500 | - | switching is not allowed). | |
| 1501 | - | </description> | |
| 1502 | - | ||
| 1503 | - | <enum name="error"> | |
| 1504 | - | <description summary="wl_surface error values"> | |
| 1505 | - | These errors can be emitted in response to wl_surface requests. | |
| 1506 | - | </description> | |
| 1507 | - | <entry name="invalid_scale" value="0" summary="buffer scale value is invalid"/> | |
| 1508 | - | <entry name="invalid_transform" value="1" summary="buffer transform value is invalid"/> | |
| 1509 | - | <entry name="invalid_size" value="2" summary="buffer size is invalid"/> | |
| 1510 | - | <entry name="invalid_offset" value="3" summary="buffer offset is invalid"/> | |
| 1511 | - | <entry name="defunct_role_object" value="4" | |
| 1512 | - | summary="surface was destroyed before its role object"/> | |
| 1513 | - | <entry name="no_buffer" value="5" summary="no buffer was attached"/> | |
| 1514 | - | </enum> | |
| 1515 | - | ||
| 1516 | - | <request name="destroy" type="destructor"> | |
| 1517 | - | <description summary="delete surface"> | |
| 1518 | - | Deletes the surface and invalidates its object ID. | |
| 1519 | - | </description> | |
| 1520 | - | </request> | |
| 1521 | - | ||
| 1522 | - | <request name="attach"> | |
| 1523 | - | <description summary="set the surface contents"> | |
| 1524 | - | Set a buffer as the content of this surface. | |
| 1525 | - | ||
| 1526 | - | The new size of the surface is calculated based on the buffer | |
| 1527 | - | size transformed by the inverse buffer_transform and the | |
| 1528 | - | inverse buffer_scale. This means that at commit time the supplied | |
| 1529 | - | buffer size must be an integer multiple of the buffer_scale. If | |
| 1530 | - | that's not the case, an invalid_size error is sent. | |
| 1531 | - | ||
| 1532 | - | The x and y arguments specify the location of the new pending | |
| 1533 | - | buffer's upper left corner, relative to the current buffer's upper | |
| 1534 | - | left corner, in surface-local coordinates. In other words, the | |
| 1535 | - | x and y, combined with the new surface size define in which | |
| 1536 | - | directions the surface's size changes. Setting anything other than 0 | |
| 1537 | - | as x and y arguments is discouraged, and should instead be replaced | |
| 1538 | - | with using the separate wl_surface.offset request. | |
| 1539 | - | ||
| 1540 | - | When the bound wl_surface version is 5 or higher, passing any | |
| 1541 | - | non-zero x or y is a protocol violation, and will result in an | |
| 1542 | - | 'invalid_offset' error being raised. The x and y arguments are ignored | |
| 1543 | - | and do not change the pending state. To achieve equivalent semantics, | |
| 1544 | - | use wl_surface.offset. | |
| 1545 | - | ||
| 1546 | - | Surface contents are double-buffered state, see wl_surface.commit. | |
| 1547 | - | ||
| 1548 | - | The initial surface contents are void; there is no content. | |
| 1549 | - | wl_surface.attach assigns the given wl_buffer as the pending | |
| 1550 | - | wl_buffer. wl_surface.commit makes the pending wl_buffer the new | |
| 1551 | - | surface contents, and the size of the surface becomes the size | |
| 1552 | - | calculated from the wl_buffer, as described above. After commit, | |
| 1553 | - | there is no pending buffer until the next attach. | |
| 1554 | - | ||
| 1555 | - | Committing a pending wl_buffer allows the compositor to read the | |
| 1556 | - | pixels in the wl_buffer. The compositor may access the pixels at | |
| 1557 | - | any time after the wl_surface.commit request. When the compositor | |
| 1558 | - | will not access the pixels anymore, it will send the | |
| 1559 | - | wl_buffer.release event. Only after receiving wl_buffer.release, | |
| 1560 | - | the client may reuse the wl_buffer. A wl_buffer that has been | |
| 1561 | - | attached and then replaced by another attach instead of committed | |
| 1562 | - | will not receive a release event, and is not used by the | |
| 1563 | - | compositor. | |
| 1564 | - | ||
| 1565 | - | If a pending wl_buffer has been committed to more than one wl_surface, | |
| 1566 | - | the delivery of wl_buffer.release events becomes undefined. A well | |
| 1567 | - | behaved client should not rely on wl_buffer.release events in this | |
| 1568 | - | case. Instead, clients hitting this case should use | |
| 1569 | - | wl_surface.get_release or use a protocol extension providing per-commit | |
| 1570 | - | release notifications (if none of these options are available, a | |
| 1571 | - | fallback can be implemented by creating multiple wl_buffer objects from | |
| 1572 | - | the same backing storage). | |
| 1573 | - | ||
| 1574 | - | Destroying the wl_buffer after wl_buffer.release does not change | |
| 1575 | - | the surface contents. Destroying the wl_buffer before wl_buffer.release | |
| 1576 | - | is allowed as long as the underlying buffer storage isn't re-used (this | |
| 1577 | - | can happen e.g. on client process termination). However, if the client | |
| 1578 | - | destroys the wl_buffer before receiving the wl_buffer.release event and | |
| 1579 | - | mutates the underlying buffer storage, the surface contents become | |
| 1580 | - | undefined immediately. | |
| 1581 | - | ||
| 1582 | - | If wl_surface.attach is sent with a NULL wl_buffer, the | |
| 1583 | - | following wl_surface.commit will remove the surface content. | |
| 1584 | - | ||
| 1585 | - | If a pending wl_buffer has been destroyed, the result is not specified. | |
| 1586 | - | Many compositors are known to remove the surface content on the following | |
| 1587 | - | wl_surface.commit, but this behaviour is not universal. Clients seeking to | |
| 1588 | - | maximise compatibility should not destroy pending buffers and should | |
| 1589 | - | ensure that they explicitly remove content from surfaces, even after | |
| 1590 | - | destroying buffers. | |
| 1591 | - | </description> | |
| 1592 | - | <arg name="buffer" type="object" interface="wl_buffer" allow-null="true" | |
| 1593 | - | summary="buffer of surface contents"/> | |
| 1594 | - | <arg name="x" type="int" summary="surface-local x coordinate"/> | |
| 1595 | - | <arg name="y" type="int" summary="surface-local y coordinate"/> | |
| 1596 | - | </request> | |
| 1597 | - | ||
| 1598 | - | <request name="damage"> | |
| 1599 | - | <description summary="mark part of the surface damaged"> | |
| 1600 | - | This request is used to describe the regions where the pending | |
| 1601 | - | buffer is different from the current surface contents, and where | |
| 1602 | - | the surface therefore needs to be repainted. The compositor | |
| 1603 | - | ignores the parts of the damage that fall outside of the surface. | |
| 1604 | - | ||
| 1605 | - | Damage is double-buffered state, see wl_surface.commit. | |
| 1606 | - | ||
| 1607 | - | The damage rectangle is specified in surface-local coordinates, | |
| 1608 | - | where x and y specify the upper left corner of the damage rectangle. | |
| 1609 | - | ||
| 1610 | - | The initial value for pending damage is empty: no damage. | |
| 1611 | - | wl_surface.damage adds pending damage: the new pending damage | |
| 1612 | - | is the union of old pending damage and the given rectangle. | |
| 1613 | - | ||
| 1614 | - | wl_surface.commit assigns pending damage as the current damage, | |
| 1615 | - | and clears pending damage. The server will clear the current | |
| 1616 | - | damage as it repaints the surface. | |
| 1617 | - | ||
| 1618 | - | Note! New clients should not use this request. Instead damage can be | |
| 1619 | - | posted with wl_surface.damage_buffer which uses buffer coordinates | |
| 1620 | - | instead of surface coordinates. | |
| 1621 | - | </description> | |
| 1622 | - | <arg name="x" type="int" summary="surface-local x coordinate"/> | |
| 1623 | - | <arg name="y" type="int" summary="surface-local y coordinate"/> | |
| 1624 | - | <arg name="width" type="int" summary="width of damage rectangle"/> | |
| 1625 | - | <arg name="height" type="int" summary="height of damage rectangle"/> | |
| 1626 | - | </request> | |
| 1627 | - | ||
| 1628 | - | <request name="frame"> | |
| 1629 | - | <description summary="request a frame throttling hint"> | |
| 1630 | - | Request a notification when it is a good time to start drawing a new | |
| 1631 | - | frame, by creating a frame callback. This is useful for throttling | |
| 1632 | - | redrawing operations, and driving animations. | |
| 1633 | - | ||
| 1634 | - | When a client is animating on a wl_surface, it can use the 'frame' | |
| 1635 | - | request to get notified when it is a good time to draw and commit the | |
| 1636 | - | next frame of animation. If the client commits an update earlier than | |
| 1637 | - | that, it is likely that some updates will not make it to the display, | |
| 1638 | - | and the client is wasting resources by drawing too often. | |
| 1639 | - | ||
| 1640 | - | The frame request will take effect on the next wl_surface.commit. | |
| 1641 | - | The notification will only be posted for one frame unless | |
| 1642 | - | requested again. For a wl_surface, the notifications are posted in | |
| 1643 | - | the order the frame requests were committed. | |
| 1644 | - | ||
| 1645 | - | The server must send the notifications so that a client | |
| 1646 | - | will not send excessive updates, while still allowing | |
| 1647 | - | the highest possible update rate for clients that wait for the reply | |
| 1648 | - | before drawing again. The server should give some time for the client | |
| 1649 | - | to draw and commit after sending the frame callback events to let it | |
| 1650 | - | hit the next output refresh. | |
| 1651 | - | ||
| 1652 | - | A server should avoid signaling the frame callbacks if the | |
| 1653 | - | surface is not visible in any way, e.g. the surface is off-screen, | |
| 1654 | - | or completely obscured by other opaque surfaces. | |
| 1655 | - | ||
| 1656 | - | The object returned by this request will be destroyed by the | |
| 1657 | - | compositor after the callback is fired and as such the client must not | |
| 1658 | - | attempt to use it after that point. | |
| 1659 | - | ||
| 1660 | - | The callback_data passed in the callback is the current time, in | |
| 1661 | - | milliseconds, with an undefined base. | |
| 1662 | - | </description> | |
| 1663 | - | <arg name="callback" type="new_id" interface="wl_callback" summary="callback object for the frame request"/> | |
| 1664 | - | </request> | |
| 1665 | - | ||
| 1666 | - | <request name="set_opaque_region"> | |
| 1667 | - | <description summary="set opaque region"> | |
| 1668 | - | This request sets the region of the surface that contains | |
| 1669 | - | opaque content. | |
| 1670 | - | ||
| 1671 | - | The opaque region is an optimization hint for the compositor | |
| 1672 | - | that lets it optimize the redrawing of content behind opaque | |
| 1673 | - | regions. Setting an opaque region is not required for correct | |
| 1674 | - | behaviour, but marking transparent content as opaque will result | |
| 1675 | - | in repaint artifacts. | |
| 1676 | - | ||
| 1677 | - | The opaque region is specified in surface-local coordinates. | |
| 1678 | - | ||
| 1679 | - | The compositor ignores the parts of the opaque region that fall | |
| 1680 | - | outside of the surface. | |
| 1681 | - | ||
| 1682 | - | Opaque region is double-buffered state, see wl_surface.commit. | |
| 1683 | - | ||
| 1684 | - | wl_surface.set_opaque_region changes the pending opaque region. | |
| 1685 | - | wl_surface.commit copies the pending region to the current region. | |
| 1686 | - | Otherwise, the pending and current regions are never changed. | |
| 1687 | - | ||
| 1688 | - | The initial value for an opaque region is empty. Setting the pending | |
| 1689 | - | opaque region has copy semantics, and the wl_region object can be | |
| 1690 | - | destroyed immediately. A NULL wl_region causes the pending opaque | |
| 1691 | - | region to be set to empty. | |
| 1692 | - | </description> | |
| 1693 | - | <arg name="region" type="object" interface="wl_region" allow-null="true" | |
| 1694 | - | summary="opaque region of the surface"/> | |
| 1695 | - | </request> | |
| 1696 | - | ||
| 1697 | - | <request name="set_input_region"> | |
| 1698 | - | <description summary="set input region"> | |
| 1699 | - | This request sets the region of the surface that can receive | |
| 1700 | - | pointer and touch events. | |
| 1701 | - | ||
| 1702 | - | Input events happening outside of this region will try the next | |
| 1703 | - | surface in the server surface stack. The compositor ignores the | |
| 1704 | - | parts of the input region that fall outside of the surface. | |
| 1705 | - | ||
| 1706 | - | The input region is specified in surface-local coordinates. | |
| 1707 | - | ||
| 1708 | - | Input region is double-buffered state, see wl_surface.commit. | |
| 1709 | - | ||
| 1710 | - | wl_surface.set_input_region changes the pending input region. | |
| 1711 | - | wl_surface.commit copies the pending region to the current region. | |
| 1712 | - | Otherwise the pending and current regions are never changed, | |
| 1713 | - | except cursor and icon surfaces are special cases, see | |
| 1714 | - | wl_pointer.set_cursor and wl_data_device.start_drag. | |
| 1715 | - | ||
| 1716 | - | The initial value for an input region is infinite. That means the | |
| 1717 | - | whole surface will accept input. Setting the pending input region | |
| 1718 | - | has copy semantics, and the wl_region object can be destroyed | |
| 1719 | - | immediately. A NULL wl_region causes the input region to be set | |
| 1720 | - | to infinite. | |
| 1721 | - | </description> | |
| 1722 | - | <arg name="region" type="object" interface="wl_region" allow-null="true" | |
| 1723 | - | summary="input region of the surface"/> | |
| 1724 | - | </request> | |
| 1725 | - | ||
| 1726 | - | <request name="commit"> | |
| 1727 | - | <description summary="commit pending surface state"> | |
| 1728 | - | Surface state (input, opaque, and damage regions, attached buffers, | |
| 1729 | - | etc.) is double-buffered. Protocol requests modify the pending state, | |
| 1730 | - | as opposed to the active state in use by the compositor. | |
| 1731 | - | ||
| 1732 | - | All requests that need a commit to become effective are documented | |
| 1733 | - | to affect double-buffered state. | |
| 1734 | - | ||
| 1735 | - | Other interfaces may add further double-buffered surface state. | |
| 1736 | - | ||
| 1737 | - | A commit request atomically creates a Content Update (CU) from the | |
| 1738 | - | pending state, even if the pending state has not been touched. The | |
| 1739 | - | content update is placed at the end of a per-surface queue until it | |
| 1740 | - | becomes active. After commit, the new pending state is as documented for | |
| 1741 | - | each related request. | |
| 1742 | - | ||
| 1743 | - | A CU is either a Desync Content Update (DCU) or a Sync Content Update | |
| 1744 | - | (SCU). If the surface is effectively synchronized at the commit request, | |
| 1745 | - | it is a SCU, otherwise a DCU. | |
| 1746 | - | ||
| 1747 | - | When a surface transitions from effectively synchronized to effectively | |
| 1748 | - | desynchronized, all SCUs in its queue which are not reachable by any | |
| 1749 | - | DCU become DCUs and dependency edges from outside the queue to these CUs | |
| 1750 | - | are removed. | |
| 1751 | - | ||
| 1752 | - | See wl_subsurface for the definition of 'effectively synchronized' and | |
| 1753 | - | 'effectively desynchronized'. | |
| 1754 | - | ||
| 1755 | - | When a CU is placed in the queue, the CU has a dependency on the CU in | |
| 1756 | - | front of it and to the SCU at end of the queue of every direct child | |
| 1757 | - | surface if that SCU exists and does not have another dependent. This can | |
| 1758 | - | form a directed acyclic graph of CUs with dependencies as edges. | |
| 1759 | - | ||
| 1760 | - | In addition to surface state, the CU can have constraints that must be | |
| 1761 | - | satisfied before it can be applied. Other interfaces may add CU | |
| 1762 | - | constraints. | |
| 1763 | - | ||
| 1764 | - | All DCUs which do not have a SCU in front of themselves in their queue, | |
| 1765 | - | are candidates. If the graph that's reachable by a candidate does not | |
| 1766 | - | have any unsatisfied constraints, the entire graph must be applied | |
| 1767 | - | atomically. | |
| 1768 | - | ||
| 1769 | - | When a CU is applied, the wl_buffer is applied before all other state. | |
| 1770 | - | This means that all coordinates in double-buffered state are relative to | |
| 1771 | - | the newly attached wl_buffers, except for wl_surface.attach itself. If | |
| 1772 | - | there is no newly attached wl_buffer, the coordinates are relative to | |
| 1773 | - | the previous content update. | |
| 1774 | - | </description> | |
| 1775 | - | </request> | |
| 1776 | - | ||
| 1777 | - | <event name="enter"> | |
| 1778 | - | <description summary="surface enters an output"> | |
| 1779 | - | This is emitted whenever a surface's creation, movement, or resizing | |
| 1780 | - | results in some part of it being within the scanout region of an | |
| 1781 | - | output. | |
| 1782 | - | ||
| 1783 | - | Note that a surface may be overlapping with zero or more outputs. | |
| 1784 | - | </description> | |
| 1785 | - | <arg name="output" type="object" interface="wl_output" summary="output entered by the surface"/> | |
| 1786 | - | </event> | |
| 1787 | - | ||
| 1788 | - | <event name="leave"> | |
| 1789 | - | <description summary="surface leaves an output"> | |
| 1790 | - | This is emitted whenever a surface's creation, movement, or resizing | |
| 1791 | - | results in it no longer having any part of it within the scanout region | |
| 1792 | - | of an output. | |
| 1793 | - | ||
| 1794 | - | Clients should not use the number of outputs the surface is on for frame | |
| 1795 | - | throttling purposes. The surface might be hidden even if no leave event | |
| 1796 | - | has been sent, and the compositor might expect new surface content | |
| 1797 | - | updates even if no enter event has been sent. The frame event should be | |
| 1798 | - | used instead. | |
| 1799 | - | </description> | |
| 1800 | - | <arg name="output" type="object" interface="wl_output" summary="output left by the surface"/> | |
| 1801 | - | </event> | |
| 1802 | - | ||
| 1803 | - | <!-- Version 2 additions --> | |
| 1804 | - | ||
| 1805 | - | <request name="set_buffer_transform" since="2"> | |
| 1806 | - | <description summary="sets the buffer transformation"> | |
| 1807 | - | This request sets the transformation that the client has already applied | |
| 1808 | - | to the content of the buffer. The accepted values for the transform | |
| 1809 | - | parameter are the values for wl_output.transform. | |
| 1810 | - | ||
| 1811 | - | The compositor applies the inverse of this transformation whenever it | |
| 1812 | - | uses the buffer contents. | |
| 1813 | - | ||
| 1814 | - | Buffer transform is double-buffered state, see wl_surface.commit. | |
| 1815 | - | ||
| 1816 | - | A newly created surface has its buffer transformation set to normal. | |
| 1817 | - | ||
| 1818 | - | wl_surface.set_buffer_transform changes the pending buffer | |
| 1819 | - | transformation. wl_surface.commit copies the pending buffer | |
| 1820 | - | transformation to the current one. Otherwise, the pending and current | |
| 1821 | - | values are never changed. | |
| 1822 | - | ||
| 1823 | - | The purpose of this request is to allow clients to render content | |
| 1824 | - | according to the output transform, thus permitting the compositor to | |
| 1825 | - | use certain optimizations even if the display is rotated. Using | |
| 1826 | - | hardware overlays and scanning out a client buffer for fullscreen | |
| 1827 | - | surfaces are examples of such optimizations. Those optimizations are | |
| 1828 | - | highly dependent on the compositor implementation, so the use of this | |
| 1829 | - | request should be considered on a case-by-case basis. | |
| 1830 | - | ||
| 1831 | - | Note that if the transform value includes 90 or 270 degree rotation, | |
| 1832 | - | the width of the buffer will become the surface height and the height | |
| 1833 | - | of the buffer will become the surface width. | |
| 1834 | - | ||
| 1835 | - | If transform is not one of the values from the | |
| 1836 | - | wl_output.transform enum the invalid_transform protocol error | |
| 1837 | - | is raised. | |
| 1838 | - | </description> | |
| 1839 | - | <arg name="transform" type="int" enum="wl_output.transform" | |
| 1840 | - | summary="transform for interpreting buffer contents"/> | |
| 1841 | - | </request> | |
| 1842 | - | ||
| 1843 | - | <!-- Version 3 additions --> | |
| 1844 | - | ||
| 1845 | - | <request name="set_buffer_scale" since="3"> | |
| 1846 | - | <description summary="sets the buffer scaling factor"> | |
| 1847 | - | This request sets an optional scaling factor on how the compositor | |
| 1848 | - | interprets the contents of the buffer attached to the window. | |
| 1849 | - | ||
| 1850 | - | Buffer scale is double-buffered state, see wl_surface.commit. | |
| 1851 | - | ||
| 1852 | - | A newly created surface has its buffer scale set to 1. | |
| 1853 | - | ||
| 1854 | - | wl_surface.set_buffer_scale changes the pending buffer scale. | |
| 1855 | - | wl_surface.commit copies the pending buffer scale to the current one. | |
| 1856 | - | Otherwise, the pending and current values are never changed. | |
| 1857 | - | ||
| 1858 | - | The purpose of this request is to allow clients to supply higher | |
| 1859 | - | resolution buffer data for use on high resolution outputs. It is | |
| 1860 | - | intended that you pick the same buffer scale as the scale of the | |
| 1861 | - | output that the surface is displayed on. This means the compositor | |
| 1862 | - | can avoid scaling when rendering the surface on that output. | |
| 1863 | - | ||
| 1864 | - | Note that if the scale is larger than 1, then you have to attach | |
| 1865 | - | a buffer that is larger (by a factor of scale in each dimension) | |
| 1866 | - | than the desired surface size. | |
| 1867 | - | ||
| 1868 | - | If scale is not greater than 0 the invalid_scale protocol error is | |
| 1869 | - | raised. | |
| 1870 | - | </description> | |
| 1871 | - | <arg name="scale" type="int" | |
| 1872 | - | summary="scale for interpreting buffer contents"/> | |
| 1873 | - | </request> | |
| 1874 | - | ||
| 1875 | - | <!-- Version 4 additions --> | |
| 1876 | - | <request name="damage_buffer" since="4"> | |
| 1877 | - | <description summary="mark part of the surface damaged using buffer coordinates"> | |
| 1878 | - | This request is used to describe the regions where the pending | |
| 1879 | - | buffer is different from the current surface contents, and where | |
| 1880 | - | the surface therefore needs to be repainted. The compositor | |
| 1881 | - | ignores the parts of the damage that fall outside of the surface. | |
| 1882 | - | ||
| 1883 | - | Damage is double-buffered state, see wl_surface.commit. | |
| 1884 | - | ||
| 1885 | - | The damage rectangle is specified in buffer coordinates, | |
| 1886 | - | where x and y specify the upper left corner of the damage rectangle. | |
| 1887 | - | ||
| 1888 | - | The initial value for pending damage is empty: no damage. | |
| 1889 | - | wl_surface.damage_buffer adds pending damage: the new pending | |
| 1890 | - | damage is the union of old pending damage and the given rectangle. | |
| 1891 | - | ||
| 1892 | - | wl_surface.commit assigns pending damage as the current damage, | |
| 1893 | - | and clears pending damage. The server will clear the current | |
| 1894 | - | damage as it repaints the surface. | |
| 1895 | - | ||
| 1896 | - | This request differs from wl_surface.damage in only one way - it | |
| 1897 | - | takes damage in buffer coordinates instead of surface-local | |
| 1898 | - | coordinates. While this generally is more intuitive than surface | |
| 1899 | - | coordinates, it is especially desirable when using wp_viewport | |
| 1900 | - | or when a drawing library (like EGL) is unaware of buffer scale | |
| 1901 | - | and buffer transform. | |
| 1902 | - | ||
| 1903 | - | Note: Because buffer transformation changes and damage requests may | |
| 1904 | - | be interleaved in the protocol stream, it is impossible to determine | |
| 1905 | - | the actual mapping between surface and buffer damage until | |
| 1906 | - | wl_surface.commit time. Therefore, compositors wishing to take both | |
| 1907 | - | kinds of damage into account will have to accumulate damage from the | |
| 1908 | - | two requests separately and only transform from one to the other | |
| 1909 | - | after receiving the wl_surface.commit. | |
| 1910 | - | </description> | |
| 1911 | - | <arg name="x" type="int" summary="buffer-local x coordinate"/> | |
| 1912 | - | <arg name="y" type="int" summary="buffer-local y coordinate"/> | |
| 1913 | - | <arg name="width" type="int" summary="width of damage rectangle"/> | |
| 1914 | - | <arg name="height" type="int" summary="height of damage rectangle"/> | |
| 1915 | - | </request> | |
| 1916 | - | ||
| 1917 | - | <!-- Version 5 additions --> | |
| 1918 | - | ||
| 1919 | - | <request name="offset" since="5"> | |
| 1920 | - | <description summary="set the surface contents offset"> | |
| 1921 | - | The x and y arguments specify the location of the new pending | |
| 1922 | - | buffer's upper left corner, relative to the current buffer's upper | |
| 1923 | - | left corner, in surface-local coordinates. In other words, the | |
| 1924 | - | x and y, combined with the new surface size define in which | |
| 1925 | - | directions the surface's size changes. | |
| 1926 | - | ||
| 1927 | - | The exact semantics of wl_surface.offset are role-specific. Refer to | |
| 1928 | - | the documentation of specific roles for more information. | |
| 1929 | - | ||
| 1930 | - | Surface location offset is double-buffered state, see | |
| 1931 | - | wl_surface.commit. | |
| 1932 | - | ||
| 1933 | - | This request is semantically equivalent to and the replaces the x and y | |
| 1934 | - | arguments in the wl_surface.attach request in wl_surface versions prior | |
| 1935 | - | to 5. See wl_surface.attach for details. | |
| 1936 | - | </description> | |
| 1937 | - | <arg name="x" type="int" summary="surface-local x coordinate"/> | |
| 1938 | - | <arg name="y" type="int" summary="surface-local y coordinate"/> | |
| 1939 | - | </request> | |
| 1940 | - | ||
| 1941 | - | <!-- Version 6 additions --> | |
| 1942 | - | ||
| 1943 | - | <event name="preferred_buffer_scale" since="6"> | |
| 1944 | - | <description summary="preferred buffer scale for the surface"> | |
| 1945 | - | This event indicates the preferred buffer scale for this surface. It is | |
| 1946 | - | sent whenever the compositor's preference changes. | |
| 1947 | - | ||
| 1948 | - | Before receiving this event the preferred buffer scale for this surface | |
| 1949 | - | is 1. | |
| 1950 | - | ||
| 1951 | - | It is intended that scaling aware clients use this event to scale their | |
| 1952 | - | content and use wl_surface.set_buffer_scale to indicate the scale they | |
| 1953 | - | have rendered with. This allows clients to supply a higher detail | |
| 1954 | - | buffer. | |
| 1955 | - | ||
| 1956 | - | The compositor shall emit a scale value greater than 0. | |
| 1957 | - | </description> | |
| 1958 | - | <arg name="factor" type="int" summary="preferred scaling factor"/> | |
| 1959 | - | </event> | |
| 1960 | - | ||
| 1961 | - | <event name="preferred_buffer_transform" since="6"> | |
| 1962 | - | <description summary="preferred buffer transform for the surface"> | |
| 1963 | - | This event indicates the preferred buffer transform for this surface. | |
| 1964 | - | It is sent whenever the compositor's preference changes. | |
| 1965 | - | ||
| 1966 | - | Before receiving this event the preferred buffer transform for this | |
| 1967 | - | surface is normal. | |
| 1968 | - | ||
| 1969 | - | Applying this transformation to the surface buffer contents and using | |
| 1970 | - | wl_surface.set_buffer_transform might allow the compositor to use the | |
| 1971 | - | surface buffer more efficiently. | |
| 1972 | - | </description> | |
| 1973 | - | <arg name="transform" type="uint" enum="wl_output.transform" | |
| 1974 | - | summary="preferred transform"/> | |
| 1975 | - | </event> | |
| 1976 | - | ||
| 1977 | - | <!-- Version 7 additions --> | |
| 1978 | - | ||
| 1979 | - | <request name="get_release" since="7"> | |
| 1980 | - | <description summary="get a release callback"> | |
| 1981 | - | Create a callback for the release of the buffer attached by the client | |
| 1982 | - | with wl_surface.attach. | |
| 1983 | - | ||
| 1984 | - | The compositor will release the buffer when it has finished its usage of | |
| 1985 | - | the underlying storage for the relevant commit. Once the client receives | |
| 1986 | - | this event, and assuming the associated buffer is not pending release | |
| 1987 | - | from other wl_surface.commit requests, the client can safely re-use the | |
| 1988 | - | buffer. | |
| 1989 | - | ||
| 1990 | - | Release callbacks are double-buffered state, and will be associated | |
| 1991 | - | with the pending buffer at wl_surface.commit time. | |
| 1992 | - | ||
| 1993 | - | The callback_data passed in the wl_callback.done event is unused and | |
| 1994 | - | is always zero. | |
| 1995 | - | ||
| 1996 | - | Sending this request without attaching a non-null buffer in the same | |
| 1997 | - | content update is a protocol error. The compositor will send the | |
| 1998 | - | no_buffer error in this case. | |
| 1999 | - | </description> | |
| 2000 | - | <arg name="callback" type="new_id" interface="wl_callback" summary="callback object for the release"/> | |
| 2001 | - | </request> | |
| 2002 | - | </interface> | |
| 2003 | - | ||
| 2004 | - | <interface name="wl_seat" version="11"> | |
| 2005 | - | <description summary="group of input devices"> | |
| 2006 | - | A seat is a group of keyboards, pointer and touch devices. This | |
| 2007 | - | object is published as a global during start up, or when such a | |
| 2008 | - | device is hot plugged. A seat typically has a pointer and | |
| 2009 | - | maintains a keyboard focus and a pointer focus. | |
| 2010 | - | </description> | |
| 2011 | - | ||
| 2012 | - | <enum name="capability" bitfield="true"> | |
| 2013 | - | <description summary="seat capability bitmask"> | |
| 2014 | - | This is a bitmask of capabilities this seat has; if a member is | |
| 2015 | - | set, then it is present on the seat. | |
| 2016 | - | </description> | |
| 2017 | - | <entry name="pointer" value="1" summary="the seat has pointer devices"/> | |
| 2018 | - | <entry name="keyboard" value="2" summary="the seat has one or more keyboards"/> | |
| 2019 | - | <entry name="touch" value="4" summary="the seat has touch devices"/> | |
| 2020 | - | </enum> | |
| 2021 | - | ||
| 2022 | - | <enum name="error"> | |
| 2023 | - | <description summary="wl_seat error values"> | |
| 2024 | - | These errors can be emitted in response to wl_seat requests. | |
| 2025 | - | </description> | |
| 2026 | - | <entry name="missing_capability" value="0" | |
| 2027 | - | summary="get_pointer, get_keyboard or get_touch called on seat without the matching capability"/> | |
| 2028 | - | </enum> | |
| 2029 | - | ||
| 2030 | - | <event name="capabilities"> | |
| 2031 | - | <description summary="seat capabilities changed"> | |
| 2032 | - | This is sent on binding to the seat global or whenever a seat gains | |
| 2033 | - | or loses the pointer, keyboard or touch capabilities. | |
| 2034 | - | The argument is a capability enum containing the complete set of | |
| 2035 | - | capabilities this seat has. | |
| 2036 | - | ||
| 2037 | - | When the pointer capability is added, a client may create a | |
| 2038 | - | wl_pointer object using the wl_seat.get_pointer request. This object | |
| 2039 | - | will receive pointer events until the capability is removed in the | |
| 2040 | - | future. | |
| 2041 | - | ||
| 2042 | - | When the pointer capability is removed, a client should destroy the | |
| 2043 | - | wl_pointer objects associated with the seat where the capability was | |
| 2044 | - | removed, using the wl_pointer.release request. No further pointer | |
| 2045 | - | events will be received on these objects. | |
| 2046 | - | ||
| 2047 | - | In some compositors, if a seat regains the pointer capability and a | |
| 2048 | - | client has a previously obtained wl_pointer object of version 4 or | |
| 2049 | - | less, that object may start sending pointer events again. This | |
| 2050 | - | behavior is considered a misinterpretation of the intended behavior | |
| 2051 | - | and must not be relied upon by the client. wl_pointer objects of | |
| 2052 | - | version 5 or later must not send events if created before the most | |
| 2053 | - | recent event notifying the client of an added pointer capability. | |
| 2054 | - | ||
| 2055 | - | The above behavior also applies to wl_keyboard and wl_touch with the | |
| 2056 | - | keyboard and touch capabilities, respectively. | |
| 2057 | - | </description> | |
| 2058 | - | <arg name="capabilities" type="uint" enum="capability" summary="capabilities of the seat"/> | |
| 2059 | - | </event> | |
| 2060 | - | ||
| 2061 | - | <request name="get_pointer"> | |
| 2062 | - | <description summary="return pointer object"> | |
| 2063 | - | The ID provided will be initialized to the wl_pointer interface | |
| 2064 | - | for this seat. | |
| 2065 | - | ||
| 2066 | - | This request only takes effect if the seat has the pointer | |
| 2067 | - | capability, or has had the pointer capability in the past. | |
| 2068 | - | It is a protocol violation to issue this request on a seat that has | |
| 2069 | - | never had the pointer capability. The missing_capability error will | |
| 2070 | - | be sent in this case. | |
| 2071 | - | </description> | |
| 2072 | - | <arg name="id" type="new_id" interface="wl_pointer" summary="seat pointer"/> | |
| 2073 | - | </request> | |
| 2074 | - | ||
| 2075 | - | <request name="get_keyboard"> | |
| 2076 | - | <description summary="return keyboard object"> | |
| 2077 | - | The ID provided will be initialized to the wl_keyboard interface | |
| 2078 | - | for this seat. | |
| 2079 | - | ||
| 2080 | - | This request only takes effect if the seat has the keyboard | |
| 2081 | - | capability, or has had the keyboard capability in the past. | |
| 2082 | - | It is a protocol violation to issue this request on a seat that has | |
| 2083 | - | never had the keyboard capability. The missing_capability error will | |
| 2084 | - | be sent in this case. | |
| 2085 | - | </description> | |
| 2086 | - | <arg name="id" type="new_id" interface="wl_keyboard" summary="seat keyboard"/> | |
| 2087 | - | </request> | |
| 2088 | - | ||
| 2089 | - | <request name="get_touch"> | |
| 2090 | - | <description summary="return touch object"> | |
| 2091 | - | The ID provided will be initialized to the wl_touch interface | |
| 2092 | - | for this seat. | |
| 2093 | - | ||
| 2094 | - | This request only takes effect if the seat has the touch | |
| 2095 | - | capability, or has had the touch capability in the past. | |
| 2096 | - | It is a protocol violation to issue this request on a seat that has | |
| 2097 | - | never had the touch capability. The missing_capability error will | |
| 2098 | - | be sent in this case. | |
| 2099 | - | </description> | |
| 2100 | - | <arg name="id" type="new_id" interface="wl_touch" summary="seat touch interface"/> | |
| 2101 | - | </request> | |
| 2102 | - | ||
| 2103 | - | <!-- Version 2 additions --> | |
| 2104 | - | ||
| 2105 | - | <event name="name" since="2"> | |
| 2106 | - | <description summary="unique identifier for this seat"> | |
| 2107 | - | In a multi-seat configuration the seat name can be used by clients to | |
| 2108 | - | help identify which physical devices the seat represents. | |
| 2109 | - | ||
| 2110 | - | The seat name is a UTF-8 string with no convention defined for its | |
| 2111 | - | contents. Each name is unique among all wl_seat globals. The name is | |
| 2112 | - | only guaranteed to be unique for the current compositor instance. | |
| 2113 | - | ||
| 2114 | - | The same seat names are used for all clients. Thus, the name can be | |
| 2115 | - | shared across processes to refer to a specific wl_seat global. | |
| 2116 | - | ||
| 2117 | - | The name event is sent after binding to the seat global, and should be sent | |
| 2118 | - | before announcing capabilities. This event is only sent once per seat object, | |
| 2119 | - | and the name does not change over the lifetime of the wl_seat global. | |
| 2120 | - | ||
| 2121 | - | Compositors may re-use the same seat name if the wl_seat global is | |
| 2122 | - | destroyed and re-created later. | |
| 2123 | - | </description> | |
| 2124 | - | <arg name="name" type="string" summary="seat identifier"/> | |
| 2125 | - | </event> | |
| 2126 | - | ||
| 2127 | - | <!-- Version 5 additions --> | |
| 2128 | - | ||
| 2129 | - | <request name="release" type="destructor" since="5"> | |
| 2130 | - | <description summary="release the seat object"> | |
| 2131 | - | Using this request a client can tell the server that it is not going to | |
| 2132 | - | use the seat object anymore. | |
| 2133 | - | </description> | |
| 2134 | - | </request> | |
| 2135 | - | ||
| 2136 | - | </interface> | |
| 2137 | - | ||
| 2138 | - | <interface name="wl_pointer" version="11"> | |
| 2139 | - | <description summary="pointer input device"> | |
| 2140 | - | The wl_pointer interface represents one or more input devices, | |
| 2141 | - | such as mice, which control the pointer location and pointer_focus | |
| 2142 | - | of a seat. | |
| 2143 | - | ||
| 2144 | - | The wl_pointer interface generates motion, enter and leave | |
| 2145 | - | events for the surfaces that the pointer is located over, | |
| 2146 | - | and button and axis events for button presses, button releases | |
| 2147 | - | and scrolling. | |
| 2148 | - | </description> | |
| 2149 | - | ||
| 2150 | - | <enum name="error"> | |
| 2151 | - | <entry name="role" value="0" summary="given wl_surface has another role"/> | |
| 2152 | - | </enum> | |
| 2153 | - | ||
| 2154 | - | <request name="set_cursor"> | |
| 2155 | - | <description summary="set the pointer surface"> | |
| 2156 | - | Set the pointer surface, i.e., the surface that contains the | |
| 2157 | - | pointer image (cursor). This request gives the surface the role | |
| 2158 | - | of a cursor. If the surface already has another role, it raises | |
| 2159 | - | a protocol error. | |
| 2160 | - | ||
| 2161 | - | The cursor actually changes only if the pointer | |
| 2162 | - | focus for this device is one of the requesting client's surfaces | |
| 2163 | - | or the surface parameter is the current pointer surface. If | |
| 2164 | - | there was a previous surface set with this request it is | |
| 2165 | - | replaced. If surface is NULL, the pointer image is hidden. | |
| 2166 | - | ||
| 2167 | - | The parameters hotspot_x and hotspot_y define the position of | |
| 2168 | - | the pointer surface relative to the pointer location. Its | |
| 2169 | - | top-left corner is always at (x, y) - (hotspot_x, hotspot_y), | |
| 2170 | - | where (x, y) are the coordinates of the pointer location, in | |
| 2171 | - | surface-local coordinates. | |
| 2172 | - | ||
| 2173 | - | On wl_surface.offset requests to the pointer surface, hotspot_x | |
| 2174 | - | and hotspot_y are decremented by the x and y parameters | |
| 2175 | - | passed to the request. The offset must be applied by | |
| 2176 | - | wl_surface.commit as usual. | |
| 2177 | - | ||
| 2178 | - | The hotspot can also be updated by passing the currently set | |
| 2179 | - | pointer surface to this request with new values for hotspot_x | |
| 2180 | - | and hotspot_y. | |
| 2181 | - | ||
| 2182 | - | The input region is ignored for wl_surfaces with the role of | |
| 2183 | - | a cursor. When the use as a cursor ends, the wl_surface is | |
| 2184 | - | unmapped. | |
| 2185 | - | ||
| 2186 | - | The serial parameter must match the latest wl_pointer.enter | |
| 2187 | - | serial number sent to the client. Otherwise the request will be | |
| 2188 | - | ignored. | |
| 2189 | - | </description> | |
| 2190 | - | <arg name="serial" type="uint" summary="serial number of the enter event"/> | |
| 2191 | - | <arg name="surface" type="object" interface="wl_surface" allow-null="true" | |
| 2192 | - | summary="pointer surface"/> | |
| 2193 | - | <arg name="hotspot_x" type="int" summary="surface-local x coordinate"/> | |
| 2194 | - | <arg name="hotspot_y" type="int" summary="surface-local y coordinate"/> | |
| 2195 | - | </request> | |
| 2196 | - | ||
| 2197 | - | <event name="enter"> | |
| 2198 | - | <description summary="enter event"> | |
| 2199 | - | Notification that this seat's pointer is focused on a certain | |
| 2200 | - | surface. | |
| 2201 | - | ||
| 2202 | - | When a seat's focus enters a surface, the pointer image | |
| 2203 | - | is undefined and a client should respond to this event by setting | |
| 2204 | - | an appropriate pointer image with the set_cursor request. | |
| 2205 | - | </description> | |
| 2206 | - | <arg name="serial" type="uint" summary="serial number of the enter event"/> | |
| 2207 | - | <arg name="surface" type="object" interface="wl_surface" summary="surface entered by the pointer"/> | |
| 2208 | - | <arg name="surface_x" type="fixed" summary="surface-local x coordinate"/> | |
| 2209 | - | <arg name="surface_y" type="fixed" summary="surface-local y coordinate"/> | |
| 2210 | - | </event> | |
| 2211 | - | ||
| 2212 | - | <event name="leave"> | |
| 2213 | - | <description summary="leave event"> | |
| 2214 | - | Notification that this seat's pointer is no longer focused on | |
| 2215 | - | a certain surface. | |
| 2216 | - | ||
| 2217 | - | The leave notification is sent before the enter notification | |
| 2218 | - | for the new focus. | |
| 2219 | - | </description> | |
| 2220 | - | <arg name="serial" type="uint" summary="serial number of the leave event"/> | |
| 2221 | - | <arg name="surface" type="object" interface="wl_surface" summary="surface left by the pointer"/> | |
| 2222 | - | </event> | |
| 2223 | - | ||
| 2224 | - | <event name="motion"> | |
| 2225 | - | <description summary="pointer motion event"> | |
| 2226 | - | Notification of pointer location change. The arguments | |
| 2227 | - | surface_x and surface_y are the location relative to the | |
| 2228 | - | focused surface. | |
| 2229 | - | </description> | |
| 2230 | - | <arg name="time" type="uint" summary="timestamp with millisecond granularity"/> | |
| 2231 | - | <arg name="surface_x" type="fixed" summary="surface-local x coordinate"/> | |
| 2232 | - | <arg name="surface_y" type="fixed" summary="surface-local y coordinate"/> | |
| 2233 | - | </event> | |
| 2234 | - | ||
| 2235 | - | <enum name="button_state"> | |
| 2236 | - | <description summary="physical button state"> | |
| 2237 | - | Describes the physical state of a button that produced the button | |
| 2238 | - | event. | |
| 2239 | - | </description> | |
| 2240 | - | <entry name="released" value="0" summary="the button is not pressed"/> | |
| 2241 | - | <entry name="pressed" value="1" summary="the button is pressed"/> | |
| 2242 | - | </enum> | |
| 2243 | - | ||
| 2244 | - | <event name="button"> | |
| 2245 | - | <description summary="pointer button event"> | |
| 2246 | - | Mouse button click and release notifications. | |
| 2247 | - | ||
| 2248 | - | The location of the click is given by the last motion, warp or | |
| 2249 | - | enter event. | |
| 2250 | - | The time argument is a timestamp with millisecond | |
| 2251 | - | granularity, with an undefined base. | |
| 2252 | - | ||
| 2253 | - | The button is a button code as defined in the Linux kernel's | |
| 2254 | - | linux/input-event-codes.h header file, e.g. BTN_LEFT. | |
| 2255 | - | ||
| 2256 | - | Any 16-bit button code value is reserved for future additions to the | |
| 2257 | - | kernel's event code list. All other button codes above 0xFFFF are | |
| 2258 | - | currently undefined but may be used in future versions of this | |
| 2259 | - | protocol. | |
| 2260 | - | </description> | |
| 2261 | - | <arg name="serial" type="uint" summary="serial number of the button event"/> | |
| 2262 | - | <arg name="time" type="uint" summary="timestamp with millisecond granularity"/> | |
| 2263 | - | <arg name="button" type="uint" summary="button that produced the event"/> | |
| 2264 | - | <arg name="state" type="uint" enum="button_state" summary="physical state of the button"/> | |
| 2265 | - | </event> | |
| 2266 | - | ||
| 2267 | - | <enum name="axis"> | |
| 2268 | - | <description summary="axis types"> | |
| 2269 | - | Describes the axis types of scroll events. | |
| 2270 | - | </description> | |
| 2271 | - | <entry name="vertical_scroll" value="0" summary="vertical axis"/> | |
| 2272 | - | <entry name="horizontal_scroll" value="1" summary="horizontal axis"/> | |
| 2273 | - | </enum> | |
| 2274 | - | ||
| 2275 | - | <event name="axis"> | |
| 2276 | - | <description summary="axis event"> | |
| 2277 | - | Scroll and other axis notifications. | |
| 2278 | - | ||
| 2279 | - | For scroll events (vertical and horizontal scroll axes), the | |
| 2280 | - | value parameter is the length of a vector along the specified | |
| 2281 | - | axis in a coordinate space identical to those of motion events, | |
| 2282 | - | representing a relative movement along the specified axis. | |
| 2283 | - | ||
| 2284 | - | For devices that support movements non-parallel to axes multiple | |
| 2285 | - | axis events will be emitted. | |
| 2286 | - | ||
| 2287 | - | When applicable, for example for touch pads, the server can | |
| 2288 | - | choose to emit scroll events where the motion vector is | |
| 2289 | - | equivalent to a motion event vector. | |
| 2290 | - | ||
| 2291 | - | When applicable, a client can transform its content relative to the | |
| 2292 | - | scroll distance. | |
| 2293 | - | </description> | |
| 2294 | - | <arg name="time" type="uint" summary="timestamp with millisecond granularity"/> | |
| 2295 | - | <arg name="axis" type="uint" enum="axis" summary="axis type"/> | |
| 2296 | - | <arg name="value" type="fixed" summary="length of vector in surface-local coordinate space"/> | |
| 2297 | - | </event> | |
| 2298 | - | ||
| 2299 | - | <!-- Version 3 additions --> | |
| 2300 | - | ||
| 2301 | - | <request name="release" type="destructor" since="3"> | |
| 2302 | - | <description summary="release the pointer object"> | |
| 2303 | - | Using this request a client can tell the server that it is not going to | |
| 2304 | - | use the pointer object anymore. | |
| 2305 | - | ||
| 2306 | - | This request destroys the pointer proxy object, so clients must not call | |
| 2307 | - | wl_pointer_destroy() after using this request. | |
| 2308 | - | </description> | |
| 2309 | - | </request> | |
| 2310 | - | ||
| 2311 | - | <!-- Version 5 additions --> | |
| 2312 | - | ||
| 2313 | - | <event name="frame" since="5"> | |
| 2314 | - | <description summary="end of a pointer event sequence"> | |
| 2315 | - | Indicates the end of a set of events that logically belong together. | |
| 2316 | - | A client is expected to accumulate the data in all events within the | |
| 2317 | - | frame before proceeding. | |
| 2318 | - | ||
| 2319 | - | All wl_pointer events before a wl_pointer.frame event belong | |
| 2320 | - | logically together. For example, in a diagonal scroll motion the | |
| 2321 | - | compositor will send an optional wl_pointer.axis_source event, two | |
| 2322 | - | wl_pointer.axis events (horizontal and vertical) and finally a | |
| 2323 | - | wl_pointer.frame event. The client may use this information to | |
| 2324 | - | calculate a diagonal vector for scrolling. | |
| 2325 | - | ||
| 2326 | - | When multiple wl_pointer.axis events occur within the same frame, | |
| 2327 | - | the motion vector is the combined motion of all events. | |
| 2328 | - | When a wl_pointer.axis and a wl_pointer.axis_stop event occur within | |
| 2329 | - | the same frame, this indicates that axis movement in one axis has | |
| 2330 | - | stopped but continues in the other axis. | |
| 2331 | - | When multiple wl_pointer.axis_stop events occur within the same | |
| 2332 | - | frame, this indicates that these axes stopped in the same instance. | |
| 2333 | - | ||
| 2334 | - | A wl_pointer.frame event is sent for every logical event group, | |
| 2335 | - | even if the group only contains a single wl_pointer event. | |
| 2336 | - | Specifically, a client may get a sequence: motion, frame, button, | |
| 2337 | - | frame, axis, frame, axis_stop, frame. | |
| 2338 | - | ||
| 2339 | - | The wl_pointer.enter and wl_pointer.leave events are logical events | |
| 2340 | - | generated by the compositor and not the hardware. These events are | |
| 2341 | - | also grouped by a wl_pointer.frame. When a pointer moves from one | |
| 2342 | - | surface to another, a compositor should group the | |
| 2343 | - | wl_pointer.leave event within the same wl_pointer.frame. | |
| 2344 | - | However, a client must not rely on wl_pointer.leave and | |
| 2345 | - | wl_pointer.enter being in the same wl_pointer.frame. | |
| 2346 | - | Compositor-specific policies may require the wl_pointer.leave and | |
| 2347 | - | wl_pointer.enter event being split across multiple wl_pointer.frame | |
| 2348 | - | groups. | |
| 2349 | - | </description> | |
| 2350 | - | </event> | |
| 2351 | - | ||
| 2352 | - | <enum name="axis_source"> | |
| 2353 | - | <description summary="axis source types"> | |
| 2354 | - | Describes the source types for axis events. This indicates to the | |
| 2355 | - | client how an axis event was physically generated; a client may | |
| 2356 | - | adjust the user interface accordingly. For example, scroll events | |
| 2357 | - | from a "finger" source may be in a smooth coordinate space with | |
| 2358 | - | kinetic scrolling whereas a "wheel" source may be in discrete steps | |
| 2359 | - | of a number of lines. | |
| 2360 | - | ||
| 2361 | - | The "continuous" axis source is a device generating events in a | |
| 2362 | - | continuous coordinate space, but using something other than a | |
| 2363 | - | finger. One example for this source is button-based scrolling where | |
| 2364 | - | the vertical motion of a device is converted to scroll events while | |
| 2365 | - | a button is held down. | |
| 2366 | - | ||
| 2367 | - | The "wheel tilt" axis source indicates that the actual device is a | |
| 2368 | - | wheel but the scroll event is not caused by a rotation but a | |
| 2369 | - | (usually sideways) tilt of the wheel. | |
| 2370 | - | </description> | |
| 2371 | - | <entry name="wheel" value="0" summary="a physical wheel rotation" /> | |
| 2372 | - | <entry name="finger" value="1" summary="finger on a touch surface" /> | |
| 2373 | - | <entry name="continuous" value="2" summary="continuous coordinate space"/> | |
| 2374 | - | <entry name="wheel_tilt" value="3" summary="a physical wheel tilt" since="6"/> | |
| 2375 | - | </enum> | |
| 2376 | - | ||
| 2377 | - | <event name="axis_source" since="5"> | |
| 2378 | - | <description summary="axis source event"> | |
| 2379 | - | Source information for scroll and other axes. | |
| 2380 | - | ||
| 2381 | - | This event does not occur on its own. It is sent before a | |
| 2382 | - | wl_pointer.frame event and carries the source information for | |
| 2383 | - | all events within that frame. | |
| 2384 | - | ||
| 2385 | - | The source specifies how this event was generated. If the source is | |
| 2386 | - | wl_pointer.axis_source.finger, a wl_pointer.axis_stop event will be | |
| 2387 | - | sent when the user lifts the finger off the device. | |
| 2388 | - | ||
| 2389 | - | If the source is wl_pointer.axis_source.wheel, | |
| 2390 | - | wl_pointer.axis_source.wheel_tilt or | |
| 2391 | - | wl_pointer.axis_source.continuous, a wl_pointer.axis_stop event may | |
| 2392 | - | or may not be sent. Whether a compositor sends an axis_stop event | |
| 2393 | - | for these sources is hardware-specific and implementation-dependent; | |
| 2394 | - | clients must not rely on receiving an axis_stop event for these | |
| 2395 | - | scroll sources and should treat scroll sequences from these scroll | |
| 2396 | - | sources as unterminated by default. | |
| 2397 | - | ||
| 2398 | - | This event is optional. If the source is unknown for a particular | |
| 2399 | - | axis event sequence, no event is sent. | |
| 2400 | - | Only one wl_pointer.axis_source event is permitted per frame. | |
| 2401 | - | ||
| 2402 | - | The order of wl_pointer.axis_discrete and wl_pointer.axis_source is | |
| 2403 | - | not guaranteed. | |
| 2404 | - | </description> | |
| 2405 | - | <arg name="axis_source" type="uint" enum="axis_source" summary="source of the axis event"/> | |
| 2406 | - | </event> | |
| 2407 | - | ||
| 2408 | - | <event name="axis_stop" since="5"> | |
| 2409 | - | <description summary="axis stop event"> | |
| 2410 | - | Stop notification for scroll and other axes. | |
| 2411 | - | ||
| 2412 | - | For some wl_pointer.axis_source types, a wl_pointer.axis_stop event | |
| 2413 | - | is sent to notify a client that the axis sequence has terminated. | |
| 2414 | - | This enables the client to implement kinetic scrolling. | |
| 2415 | - | See the wl_pointer.axis_source documentation for information on when | |
| 2416 | - | this event may be generated. | |
| 2417 | - | ||
| 2418 | - | Any wl_pointer.axis events with the same axis_source after this | |
| 2419 | - | event should be considered as the start of a new axis motion. | |
| 2420 | - | ||
| 2421 | - | The timestamp is to be interpreted identical to the timestamp in the | |
| 2422 | - | wl_pointer.axis event. The timestamp value may be the same as a | |
| 2423 | - | preceding wl_pointer.axis event. | |
| 2424 | - | </description> | |
| 2425 | - | <arg name="time" type="uint" summary="timestamp with millisecond granularity"/> | |
| 2426 | - | <arg name="axis" type="uint" enum="axis" summary="the axis stopped with this event"/> | |
| 2427 | - | </event> | |
| 2428 | - | ||
| 2429 | - | <event name="axis_discrete" since="5" deprecated-since="8"> | |
| 2430 | - | <description summary="axis click event"> | |
| 2431 | - | Discrete step information for scroll and other axes. | |
| 2432 | - | ||
| 2433 | - | This event carries the axis value of the wl_pointer.axis event in | |
| 2434 | - | discrete steps (e.g. mouse wheel clicks). | |
| 2435 | - | ||
| 2436 | - | This event is deprecated with wl_pointer version 8 - this event is not | |
| 2437 | - | sent to clients supporting version 8 or later. | |
| 2438 | - | ||
| 2439 | - | This event does not occur on its own, it is coupled with a | |
| 2440 | - | wl_pointer.axis event that represents this axis value on a | |
| 2441 | - | continuous scale. The protocol guarantees that each axis_discrete | |
| 2442 | - | event is always followed by exactly one axis event with the same | |
| 2443 | - | axis number within the same wl_pointer.frame. Note that the protocol | |
| 2444 | - | allows for other events to occur between the axis_discrete and | |
| 2445 | - | its coupled axis event, including other axis_discrete or axis | |
| 2446 | - | events. A wl_pointer.frame must not contain more than one axis_discrete | |
| 2447 | - | event per axis type. | |
| 2448 | - | ||
| 2449 | - | This event is optional; continuous scrolling devices | |
| 2450 | - | like two-finger scrolling on touchpads do not have discrete | |
| 2451 | - | steps and do not generate this event. | |
| 2452 | - | ||
| 2453 | - | The discrete value carries the directional information. e.g. a value | |
| 2454 | - | of -2 is two steps towards the negative direction of this axis. | |
| 2455 | - | ||
| 2456 | - | The axis number is identical to the axis number in the associated | |
| 2457 | - | axis event. | |
| 2458 | - | ||
| 2459 | - | The order of wl_pointer.axis_discrete and wl_pointer.axis_source is | |
| 2460 | - | not guaranteed. | |
| 2461 | - | </description> | |
| 2462 | - | <arg name="axis" type="uint" enum="axis" summary="axis type"/> | |
| 2463 | - | <arg name="discrete" type="int" summary="number of steps"/> | |
| 2464 | - | </event> | |
| 2465 | - | ||
| 2466 | - | <event name="axis_value120" since="8"> | |
| 2467 | - | <description summary="axis high-resolution scroll event"> | |
| 2468 | - | Discrete high-resolution scroll information. | |
| 2469 | - | ||
| 2470 | - | This event carries high-resolution wheel scroll information, | |
| 2471 | - | with each multiple of 120 representing one logical scroll step | |
| 2472 | - | (a wheel detent). For example, an axis_value120 of 30 is one quarter of | |
| 2473 | - | a logical scroll step in the positive direction, a value120 of | |
| 2474 | - | -240 are two logical scroll steps in the negative direction within the | |
| 2475 | - | same hardware event. | |
| 2476 | - | Clients that rely on discrete scrolling should accumulate the | |
| 2477 | - | value120 to multiples of 120 before processing the event. | |
| 2478 | - | ||
| 2479 | - | The value120 must not be zero. | |
| 2480 | - | ||
| 2481 | - | This event replaces the wl_pointer.axis_discrete event in clients | |
| 2482 | - | supporting wl_pointer version 8 or later. | |
| 2483 | - | ||
| 2484 | - | Where a wl_pointer.axis_source event occurs in the same | |
| 2485 | - | wl_pointer.frame, the axis source applies to this event. | |
| 2486 | - | ||
| 2487 | - | The order of wl_pointer.axis_value120 and wl_pointer.axis_source is | |
| 2488 | - | not guaranteed. | |
| 2489 | - | </description> | |
| 2490 | - | <arg name="axis" type="uint" enum="axis" summary="axis type"/> | |
| 2491 | - | <arg name="value120" type="int" summary="scroll distance as fraction of 120"/> | |
| 2492 | - | </event> | |
| 2493 | - | ||
| 2494 | - | <!-- Version 9 additions --> | |
| 2495 | - | ||
| 2496 | - | <enum name="axis_relative_direction"> | |
| 2497 | - | <description summary="axis relative direction"> | |
| 2498 | - | This specifies the direction of the physical motion that caused a | |
| 2499 | - | wl_pointer.axis event, relative to the wl_pointer.axis direction. | |
| 2500 | - | </description> | |
| 2501 | - | <entry name="identical" value="0" | |
| 2502 | - | summary="physical motion matches axis direction"/> | |
| 2503 | - | <entry name="inverted" value="1" | |
| 2504 | - | summary="physical motion is the inverse of the axis direction"/> | |
| 2505 | - | </enum> | |
| 2506 | - | ||
| 2507 | - | <event name="axis_relative_direction" since="9"> | |
| 2508 | - | <description summary="axis relative physical direction event"> | |
| 2509 | - | Relative directional information of the entity causing the axis | |
| 2510 | - | motion. | |
| 2511 | - | ||
| 2512 | - | For a wl_pointer.axis event, the wl_pointer.axis_relative_direction | |
| 2513 | - | event specifies the movement direction of the entity causing the | |
| 2514 | - | wl_pointer.axis event. For example: | |
| 2515 | - | - if a user's fingers on a touchpad move down and this | |
| 2516 | - | causes a wl_pointer.axis vertical_scroll down event, the physical | |
| 2517 | - | direction is 'identical' | |
| 2518 | - | - if a user's fingers on a touchpad move down and this causes a | |
| 2519 | - | wl_pointer.axis vertical_scroll up scroll up event ('natural | |
| 2520 | - | scrolling'), the physical direction is 'inverted'. | |
| 2521 | - | ||
| 2522 | - | A client may use this information to adjust scroll motion of | |
| 2523 | - | components. Specifically, enabling natural scrolling causes the | |
| 2524 | - | content to change direction compared to traditional scrolling. | |
| 2525 | - | Some widgets like volume control sliders should usually match the | |
| 2526 | - | physical direction regardless of whether natural scrolling is | |
| 2527 | - | active. This event enables clients to match the scroll direction of | |
| 2528 | - | a widget to the physical direction. | |
| 2529 | - | ||
| 2530 | - | This event does not occur on its own, it is coupled with a | |
| 2531 | - | wl_pointer.axis event that represents this axis value. | |
| 2532 | - | The protocol guarantees that each axis_relative_direction event is | |
| 2533 | - | always followed by exactly one axis event with the same | |
| 2534 | - | axis number within the same wl_pointer.frame. Note that the protocol | |
| 2535 | - | allows for other events to occur between the axis_relative_direction | |
| 2536 | - | and its coupled axis event. | |
| 2537 | - | ||
| 2538 | - | The axis number is identical to the axis number in the associated | |
| 2539 | - | axis event. | |
| 2540 | - | ||
| 2541 | - | The order of wl_pointer.axis_relative_direction, | |
| 2542 | - | wl_pointer.axis_discrete and wl_pointer.axis_source is not | |
| 2543 | - | guaranteed. | |
| 2544 | - | </description> | |
| 2545 | - | <arg name="axis" type="uint" enum="axis" summary="axis type"/> | |
| 2546 | - | <arg name="direction" type="uint" enum="axis_relative_direction" | |
| 2547 | - | summary="physical direction relative to axis motion"/> | |
| 2548 | - | </event> | |
| 2549 | - | ||
| 2550 | - | <!-- Version 11 additions --> | |
| 2551 | - | ||
| 2552 | - | <event name="warp" since="11"> | |
| 2553 | - | <description summary="pointer warp event"> | |
| 2554 | - | Notification of pointer location change within a surface. | |
| 2555 | - | ||
| 2556 | - | This location change is not due to events on the input device, | |
| 2557 | - | but because either the surface under the pointer was moved and | |
| 2558 | - | thus the relative position of the pointer changed, or because | |
| 2559 | - | the compositor changed the pointer position in response to an | |
| 2560 | - | event like pointer confinement being exited. | |
| 2561 | - | ||
| 2562 | - | The arguments surface_x and surface_y are the location relative to | |
| 2563 | - | the focused surface. | |
| 2564 | - | ||
| 2565 | - | This event must not occur in the same wl_pointer.frame as a | |
| 2566 | - | wl_pointer.enter or wl_pointer.motion event. | |
| 2567 | - | </description> | |
| 2568 | - | <arg name="surface_x" type="fixed" summary="surface-local x coordinate"/> | |
| 2569 | - | <arg name="surface_y" type="fixed" summary="surface-local y coordinate"/> | |
| 2570 | - | </event> | |
| 2571 | - | </interface> | |
| 2572 | - | ||
| 2573 | - | <interface name="wl_keyboard" version="11"> | |
| 2574 | - | <description summary="keyboard input device"> | |
| 2575 | - | The wl_keyboard interface represents one or more keyboards | |
| 2576 | - | associated with a seat. | |
| 2577 | - | ||
| 2578 | - | Each wl_keyboard has the following logical state: | |
| 2579 | - | ||
| 2580 | - | - an active surface (possibly null), | |
| 2581 | - | - the keys currently logically down, | |
| 2582 | - | - the active modifiers, | |
| 2583 | - | - the active group. | |
| 2584 | - | ||
| 2585 | - | By default, the active surface is null, the keys currently logically down | |
| 2586 | - | are empty, the active modifiers and the active group are 0. | |
| 2587 | - | </description> | |
| 2588 | - | ||
| 2589 | - | <enum name="keymap_format"> | |
| 2590 | - | <description summary="keyboard mapping format"> | |
| 2591 | - | This specifies the format of the keymap provided to the | |
| 2592 | - | client with the wl_keyboard.keymap event. | |
| 2593 | - | </description> | |
| 2594 | - | <entry name="no_keymap" value="0" | |
| 2595 | - | summary="no keymap; client must understand how to interpret the raw keycode"/> | |
| 2596 | - | <entry name="xkb_v1" value="1" | |
| 2597 | - | summary="libxkbcommon compatible, null-terminated string; to determine the xkb keycode, clients must add 8 to the key event keycode"/> | |
| 2598 | - | </enum> | |
| 2599 | - | ||
| 2600 | - | <event name="keymap"> | |
| 2601 | - | <description summary="keyboard mapping"> | |
| 2602 | - | This event provides a file descriptor to the client which can be | |
| 2603 | - | memory-mapped in read-only mode to provide a keyboard mapping | |
| 2604 | - | description. | |
| 2605 | - | ||
| 2606 | - | From version 7 onwards, the fd must be mapped with MAP_PRIVATE by | |
| 2607 | - | the recipient, as MAP_SHARED may fail. | |
| 2608 | - | </description> | |
| 2609 | - | <arg name="format" type="uint" enum="keymap_format" summary="keymap format"/> | |
| 2610 | - | <arg name="fd" type="fd" summary="keymap file descriptor"/> | |
| 2611 | - | <arg name="size" type="uint" summary="keymap size, in bytes"/> | |
| 2612 | - | </event> | |
| 2613 | - | ||
| 2614 | - | <event name="enter"> | |
| 2615 | - | <description summary="enter event"> | |
| 2616 | - | Notification that this seat's keyboard focus is on a certain | |
| 2617 | - | surface. | |
| 2618 | - | ||
| 2619 | - | The compositor must send the wl_keyboard.modifiers event after this | |
| 2620 | - | event. | |
| 2621 | - | ||
| 2622 | - | In the wl_keyboard logical state, this event sets the active surface to | |
| 2623 | - | the surface argument and the keys currently logically down to the keys | |
| 2624 | - | in the keys argument. The compositor must not send this event if the | |
| 2625 | - | wl_keyboard already had an active surface immediately before this event. | |
| 2626 | - | ||
| 2627 | - | Clients should not use the list of pressed keys to emulate key-press | |
| 2628 | - | events. The order of keys in the list is unspecified. | |
| 2629 | - | </description> | |
| 2630 | - | <arg name="serial" type="uint" summary="serial number of the enter event"/> | |
| 2631 | - | <arg name="surface" type="object" interface="wl_surface" summary="surface gaining keyboard focus"/> | |
| 2632 | - | <arg name="keys" type="array" summary="the keys currently logically down"/> | |
| 2633 | - | </event> | |
| 2634 | - | ||
| 2635 | - | <event name="leave"> | |
| 2636 | - | <description summary="leave event"> | |
| 2637 | - | Notification that this seat's keyboard focus is no longer on | |
| 2638 | - | a certain surface. | |
| 2639 | - | ||
| 2640 | - | The leave notification is sent before the enter notification | |
| 2641 | - | for the new focus. | |
| 2642 | - | ||
| 2643 | - | In the wl_keyboard logical state, this event resets all values to their | |
| 2644 | - | defaults. The compositor must not send this event if the active surface | |
| 2645 | - | of the wl_keyboard was not equal to the surface argument immediately | |
| 2646 | - | before this event. | |
| 2647 | - | </description> | |
| 2648 | - | <arg name="serial" type="uint" summary="serial number of the leave event"/> | |
| 2649 | - | <arg name="surface" type="object" interface="wl_surface" summary="surface that lost keyboard focus"/> | |
| 2650 | - | </event> | |
| 2651 | - | ||
| 2652 | - | <enum name="key_state"> | |
| 2653 | - | <description summary="physical key state"> | |
| 2654 | - | Describes the physical state of a key that produced the key event. | |
| 2655 | - | ||
| 2656 | - | Since version 10, the key can be in a "repeated" pseudo-state which | |
| 2657 | - | means the same as "pressed", but is used to signal repetition in the | |
| 2658 | - | key event. | |
| 2659 | - | ||
| 2660 | - | The key may only enter the repeated state after entering the pressed | |
| 2661 | - | state and before entering the released state. This event may be | |
| 2662 | - | generated multiple times while the key is down. | |
| 2663 | - | </description> | |
| 2664 | - | <entry name="released" value="0" summary="key is not pressed"/> | |
| 2665 | - | <entry name="pressed" value="1" summary="key is pressed"/> | |
| 2666 | - | <entry name="repeated" value="2" summary="key was repeated" since="10"/> | |
| 2667 | - | </enum> | |
| 2668 | - | ||
| 2669 | - | <event name="key"> | |
| 2670 | - | <description summary="key event"> | |
| 2671 | - | A key was pressed or released. | |
| 2672 | - | The time argument is a timestamp with millisecond | |
| 2673 | - | granularity, with an undefined base. | |
| 2674 | - | ||
| 2675 | - | The key is a platform-specific key code that can be interpreted | |
| 2676 | - | by feeding it to the keyboard mapping (see the keymap event). | |
| 2677 | - | ||
| 2678 | - | If this event produces a change in modifiers, then the resulting | |
| 2679 | - | wl_keyboard.modifiers event must be sent after this event. | |
| 2680 | - | ||
| 2681 | - | In the wl_keyboard logical state, this event adds the key to the keys | |
| 2682 | - | currently logically down (if the state argument is pressed) or removes | |
| 2683 | - | the key from the keys currently logically down (if the state argument is | |
| 2684 | - | released). The compositor must not send this event if the wl_keyboard | |
| 2685 | - | did not have an active surface immediately before this event. The | |
| 2686 | - | compositor must not send this event if state is pressed (resp. released) | |
| 2687 | - | and the key was already logically down (resp. was not logically down) | |
| 2688 | - | immediately before this event. | |
| 2689 | - | ||
| 2690 | - | Since version 10, compositors may send key events with the "repeated" | |
| 2691 | - | key state when a wl_keyboard.repeat_info event with a rate argument of | |
| 2692 | - | 0 has been received. This allows the compositor to take over the | |
| 2693 | - | responsibility of key repetition. | |
| 2694 | - | </description> | |
| 2695 | - | <arg name="serial" type="uint" summary="serial number of the key event"/> | |
| 2696 | - | <arg name="time" type="uint" summary="timestamp with millisecond granularity"/> | |
| 2697 | - | <arg name="key" type="uint" summary="key that produced the event"/> | |
| 2698 | - | <arg name="state" type="uint" enum="key_state" summary="physical state of the key"/> | |
| 2699 | - | </event> | |
| 2700 | - | ||
| 2701 | - | <event name="modifiers"> | |
| 2702 | - | <description summary="modifier and group state"> | |
| 2703 | - | Notifies clients that the modifier and/or group state has | |
| 2704 | - | changed, and it should update its local state. | |
| 2705 | - | ||
| 2706 | - | The compositor may send this event without a surface of the client | |
| 2707 | - | having keyboard focus, for example to tie modifier information to | |
| 2708 | - | pointer focus instead. If a modifier event with pressed modifiers is sent | |
| 2709 | - | without a prior enter event, the client can assume the modifier state is | |
| 2710 | - | valid until it receives the next wl_keyboard.modifiers event. In order to | |
| 2711 | - | reset the modifier state again, the compositor can send a | |
| 2712 | - | wl_keyboard.modifiers event with no pressed modifiers. | |
| 2713 | - | ||
| 2714 | - | In the wl_keyboard logical state, this event updates the modifiers and | |
| 2715 | - | group. | |
| 2716 | - | </description> | |
| 2717 | - | <arg name="serial" type="uint" summary="serial number of the modifiers event"/> | |
| 2718 | - | <arg name="mods_depressed" type="uint" summary="depressed modifiers"/> | |
| 2719 | - | <arg name="mods_latched" type="uint" summary="latched modifiers"/> | |
| 2720 | - | <arg name="mods_locked" type="uint" summary="locked modifiers"/> | |
| 2721 | - | <arg name="group" type="uint" summary="keyboard layout"/> | |
| 2722 | - | </event> | |
| 2723 | - | ||
| 2724 | - | <!-- Version 3 additions --> | |
| 2725 | - | ||
| 2726 | - | <request name="release" type="destructor" since="3"> | |
| 2727 | - | <description summary="release the keyboard object"/> | |
| 2728 | - | </request> | |
| 2729 | - | ||
| 2730 | - | <!-- Version 4 additions --> | |
| 2731 | - | ||
| 2732 | - | <event name="repeat_info" since="4"> | |
| 2733 | - | <description summary="repeat rate and delay"> | |
| 2734 | - | Informs the client about the keyboard's repeat rate and delay. | |
| 2735 | - | ||
| 2736 | - | This event is sent as soon as the wl_keyboard object has been created, | |
| 2737 | - | and is guaranteed to be received by the client before any key press | |
| 2738 | - | event. | |
| 2739 | - | ||
| 2740 | - | Negative values for either rate or delay are illegal. A rate of zero | |
| 2741 | - | will disable any repeating (regardless of the value of delay). | |
| 2742 | - | ||
| 2743 | - | This event can be sent later on as well with a new value if necessary, | |
| 2744 | - | so clients should continue listening for the event past the creation | |
| 2745 | - | of wl_keyboard. | |
| 2746 | - | </description> | |
| 2747 | - | <arg name="rate" type="int" | |
| 2748 | - | summary="the rate of repeating keys in characters per second"/> | |
| 2749 | - | <arg name="delay" type="int" | |
| 2750 | - | summary="delay in milliseconds since key down until repeating starts"/> | |
| 2751 | - | </event> | |
| 2752 | - | </interface> | |
| 2753 | - | ||
| 2754 | - | <interface name="wl_touch" version="11"> | |
| 2755 | - | <description summary="touchscreen input device"> | |
| 2756 | - | The wl_touch interface represents a touchscreen | |
| 2757 | - | associated with a seat. | |
| 2758 | - | ||
| 2759 | - | Touch interactions can consist of one or more contacts. | |
| 2760 | - | For each contact, a series of events is generated, starting | |
| 2761 | - | with a down event, followed by zero or more motion events, | |
| 2762 | - | and ending with an up event. Events relating to the same | |
| 2763 | - | contact point can be identified by the ID of the sequence. | |
| 2764 | - | </description> | |
| 2765 | - | ||
| 2766 | - | <event name="down"> | |
| 2767 | - | <description summary="touch down event and beginning of a touch sequence"> | |
| 2768 | - | A new touch point has appeared on the surface. This touch point is | |
| 2769 | - | assigned a unique ID. Future events from this touch point reference | |
| 2770 | - | this ID. The ID ceases to be valid after a touch up event and may be | |
| 2771 | - | reused in the future. | |
| 2772 | - | </description> | |
| 2773 | - | <arg name="serial" type="uint" summary="serial number of the touch down event"/> | |
| 2774 | - | <arg name="time" type="uint" summary="timestamp with millisecond granularity"/> | |
| 2775 | - | <arg name="surface" type="object" interface="wl_surface" summary="surface touched"/> | |
| 2776 | - | <arg name="id" type="int" summary="the unique ID of this touch point"/> | |
| 2777 | - | <arg name="x" type="fixed" summary="surface-local x coordinate"/> | |
| 2778 | - | <arg name="y" type="fixed" summary="surface-local y coordinate"/> | |
| 2779 | - | </event> | |
| 2780 | - | ||
| 2781 | - | <event name="up"> | |
| 2782 | - | <description summary="end of a touch event sequence"> | |
| 2783 | - | The touch point has disappeared. No further events will be sent for | |
| 2784 | - | this touch point and the touch point's ID is released and may be | |
| 2785 | - | reused in a future touch down event. | |
| 2786 | - | </description> | |
| 2787 | - | <arg name="serial" type="uint" summary="serial number of the touch up event"/> | |
| 2788 | - | <arg name="time" type="uint" summary="timestamp with millisecond granularity"/> | |
| 2789 | - | <arg name="id" type="int" summary="the unique ID of this touch point"/> | |
| 2790 | - | </event> | |
| 2791 | - | ||
| 2792 | - | <event name="motion"> | |
| 2793 | - | <description summary="update of touch point coordinates"> | |
| 2794 | - | A touch point has changed coordinates. | |
| 2795 | - | </description> | |
| 2796 | - | <arg name="time" type="uint" summary="timestamp with millisecond granularity"/> | |
| 2797 | - | <arg name="id" type="int" summary="the unique ID of this touch point"/> | |
| 2798 | - | <arg name="x" type="fixed" summary="surface-local x coordinate"/> | |
| 2799 | - | <arg name="y" type="fixed" summary="surface-local y coordinate"/> | |
| 2800 | - | </event> | |
| 2801 | - | ||
| 2802 | - | <event name="frame"> | |
| 2803 | - | <description summary="end of touch frame event"> | |
| 2804 | - | Indicates the end of a set of events that logically belong together. | |
| 2805 | - | A client is expected to accumulate the data in all events within the | |
| 2806 | - | frame before proceeding. | |
| 2807 | - | ||
| 2808 | - | A wl_touch.frame terminates at least one event but otherwise no | |
| 2809 | - | guarantee is provided about the set of events within a frame. A client | |
| 2810 | - | must assume that any state not updated in a frame is unchanged from the | |
| 2811 | - | previously known state. | |
| 2812 | - | </description> | |
| 2813 | - | </event> | |
| 2814 | - | ||
| 2815 | - | <event name="cancel"> | |
| 2816 | - | <description summary="touch session cancelled"> | |
| 2817 | - | Sent if the compositor decides the touch stream is a global | |
| 2818 | - | gesture. No further events are sent to the clients from that | |
| 2819 | - | particular gesture. Touch cancellation applies to all touch points | |
| 2820 | - | currently active on this client's surface. The client is | |
| 2821 | - | responsible for finalizing the touch points, future touch points on | |
| 2822 | - | this surface may reuse the touch point ID. | |
| 2823 | - | ||
| 2824 | - | No frame event is required after the cancel event. | |
| 2825 | - | </description> | |
| 2826 | - | </event> | |
| 2827 | - | ||
| 2828 | - | <!-- Version 3 additions --> | |
| 2829 | - | ||
| 2830 | - | <request name="release" type="destructor" since="3"> | |
| 2831 | - | <description summary="release the touch object"/> | |
| 2832 | - | </request> | |
| 2833 | - | ||
| 2834 | - | <!-- Version 6 additions --> | |
| 2835 | - | ||
| 2836 | - | <event name="shape" since="6"> | |
| 2837 | - | <description summary="update shape of touch point"> | |
| 2838 | - | Sent when a touchpoint has changed its shape. | |
| 2839 | - | ||
| 2840 | - | This event does not occur on its own. It is sent before a | |
| 2841 | - | wl_touch.frame event and carries the new shape information for | |
| 2842 | - | any previously reported, or new touch points of that frame. | |
| 2843 | - | ||
| 2844 | - | Other events describing the touch point such as wl_touch.down, | |
| 2845 | - | wl_touch.motion or wl_touch.orientation may be sent within the | |
| 2846 | - | same wl_touch.frame. A client should treat these events as a single | |
| 2847 | - | logical touch point update. The order of wl_touch.shape, | |
| 2848 | - | wl_touch.orientation and wl_touch.motion is not guaranteed. | |
| 2849 | - | A wl_touch.down event is guaranteed to occur before the first | |
| 2850 | - | wl_touch.shape event for this touch ID but both events may occur within | |
| 2851 | - | the same wl_touch.frame. | |
| 2852 | - | ||
| 2853 | - | A touchpoint shape is approximated by an ellipse through the major and | |
| 2854 | - | minor axis length. The major axis length describes the longer diameter | |
| 2855 | - | of the ellipse, while the minor axis length describes the shorter | |
| 2856 | - | diameter. Major and minor are orthogonal and both are specified in | |
| 2857 | - | surface-local coordinates. The center of the ellipse is always at the | |
| 2858 | - | touchpoint location as reported by wl_touch.down or wl_touch.motion. | |
| 2859 | - | ||
| 2860 | - | This event is only sent by the compositor if the touch device supports | |
| 2861 | - | shape reports. The client has to make reasonable assumptions about the | |
| 2862 | - | shape if it did not receive this event. | |
| 2863 | - | </description> | |
| 2864 | - | <arg name="id" type="int" summary="the unique ID of this touch point"/> | |
| 2865 | - | <arg name="major" type="fixed" summary="length of the major axis in surface-local coordinates"/> | |
| 2866 | - | <arg name="minor" type="fixed" summary="length of the minor axis in surface-local coordinates"/> | |
| 2867 | - | </event> | |
| 2868 | - | ||
| 2869 | - | <event name="orientation" since="6"> | |
| 2870 | - | <description summary="update orientation of touch point"> | |
| 2871 | - | Sent when a touchpoint has changed its orientation. | |
| 2872 | - | ||
| 2873 | - | This event does not occur on its own. It is sent before a | |
| 2874 | - | wl_touch.frame event and carries the new shape information for | |
| 2875 | - | any previously reported, or new touch points of that frame. | |
| 2876 | - | ||
| 2877 | - | Other events describing the touch point such as wl_touch.down, | |
| 2878 | - | wl_touch.motion or wl_touch.shape may be sent within the | |
| 2879 | - | same wl_touch.frame. A client should treat these events as a single | |
| 2880 | - | logical touch point update. The order of wl_touch.shape, | |
| 2881 | - | wl_touch.orientation and wl_touch.motion is not guaranteed. | |
| 2882 | - | A wl_touch.down event is guaranteed to occur before the first | |
| 2883 | - | wl_touch.orientation event for this touch ID but both events may occur | |
| 2884 | - | within the same wl_touch.frame. | |
| 2885 | - | ||
| 2886 | - | The orientation describes the clockwise angle of a touchpoint's major | |
| 2887 | - | axis to the positive surface y-axis and is normalized to the -180 to | |
| 2888 | - | +180 degree range. The granularity of orientation depends on the touch | |
| 2889 | - | device, some devices only support binary rotation values between 0 and | |
| 2890 | - | 90 degrees. | |
| 2891 | - | ||
| 2892 | - | This event is only sent by the compositor if the touch device supports | |
| 2893 | - | orientation reports. | |
| 2894 | - | </description> | |
| 2895 | - | <arg name="id" type="int" summary="the unique ID of this touch point"/> | |
| 2896 | - | <arg name="orientation" type="fixed" summary="angle between major axis and positive surface y-axis in degrees"/> | |
| 2897 | - | </event> | |
| 2898 | - | </interface> | |
| 2899 | - | ||
| 2900 | - | <interface name="wl_output" version="4"> | |
| 2901 | - | <description summary="compositor output region"> | |
| 2902 | - | An output describes part of the compositor geometry. The | |
| 2903 | - | compositor works in the 'compositor coordinate system' and an | |
| 2904 | - | output corresponds to a rectangular area in that space that is | |
| 2905 | - | actually visible. This typically corresponds to a monitor that | |
| 2906 | - | displays part of the compositor space. This object is published | |
| 2907 | - | as global during start up, or when a monitor is hotplugged. | |
| 2908 | - | </description> | |
| 2909 | - | ||
| 2910 | - | <enum name="subpixel"> | |
| 2911 | - | <description summary="subpixel geometry information"> | |
| 2912 | - | This enumeration describes how the physical | |
| 2913 | - | pixels on an output are laid out. | |
| 2914 | - | </description> | |
| 2915 | - | <entry name="unknown" value="0" summary="unknown geometry"/> | |
| 2916 | - | <entry name="none" value="1" summary="no geometry"/> | |
| 2917 | - | <entry name="horizontal_rgb" value="2" summary="horizontal RGB"/> | |
| 2918 | - | <entry name="horizontal_bgr" value="3" summary="horizontal BGR"/> | |
| 2919 | - | <entry name="vertical_rgb" value="4" summary="vertical RGB"/> | |
| 2920 | - | <entry name="vertical_bgr" value="5" summary="vertical BGR"/> | |
| 2921 | - | </enum> | |
| 2922 | - | ||
| 2923 | - | <enum name="transform"> | |
| 2924 | - | <description summary="transformation applied to buffer contents"> | |
| 2925 | - | This describes transformations that clients and compositors apply to | |
| 2926 | - | buffer contents. | |
| 2927 | - | ||
| 2928 | - | The flipped values correspond to an initial flip around a | |
| 2929 | - | vertical axis followed by rotation. | |
| 2930 | - | ||
| 2931 | - | The purpose is mainly to allow clients to render accordingly and | |
| 2932 | - | tell the compositor, so that for fullscreen surfaces, the | |
| 2933 | - | compositor will still be able to scan out directly from client | |
| 2934 | - | surfaces. | |
| 2935 | - | </description> | |
| 2936 | - | <entry name="normal" value="0" summary="no transform"/> | |
| 2937 | - | <entry name="90" value="1" summary="90 degrees counter-clockwise"/> | |
| 2938 | - | <entry name="180" value="2" summary="180 degrees counter-clockwise"/> | |
| 2939 | - | <entry name="270" value="3" summary="270 degrees counter-clockwise"/> | |
| 2940 | - | <entry name="flipped" value="4" summary="180 degree flip around a vertical axis"/> | |
| 2941 | - | <entry name="flipped_90" value="5" summary="flip and rotate 90 degrees counter-clockwise"/> | |
| 2942 | - | <entry name="flipped_180" value="6" summary="flip and rotate 180 degrees counter-clockwise"/> | |
| 2943 | - | <entry name="flipped_270" value="7" summary="flip and rotate 270 degrees counter-clockwise"/> | |
| 2944 | - | </enum> | |
| 2945 | - | ||
| 2946 | - | <event name="geometry"> | |
| 2947 | - | <description summary="properties of the output"> | |
| 2948 | - | The geometry event describes geometric properties of the output. | |
| 2949 | - | The event is sent when binding to the output object and whenever | |
| 2950 | - | any of the properties change. | |
| 2951 | - | ||
| 2952 | - | The physical size can be set to zero if it doesn't make sense for this | |
| 2953 | - | output (e.g. for projectors or virtual outputs). | |
| 2954 | - | ||
| 2955 | - | The geometry event will be followed by a done event (starting from | |
| 2956 | - | version 2). | |
| 2957 | - | ||
| 2958 | - | Clients should use wl_surface.preferred_buffer_transform instead of the | |
| 2959 | - | transform advertised by this event to find the preferred buffer | |
| 2960 | - | transform to use for a surface. | |
| 2961 | - | ||
| 2962 | - | Note: wl_output only advertises partial information about the output | |
| 2963 | - | position and identification. Some compositors, for instance those not | |
| 2964 | - | implementing a desktop-style output layout or those exposing virtual | |
| 2965 | - | outputs, might fake this information. Instead of using x and y, clients | |
| 2966 | - | should use xdg_output.logical_position. Instead of using make and model, | |
| 2967 | - | clients should use name and description. | |
| 2968 | - | </description> | |
| 2969 | - | <arg name="x" type="int" | |
| 2970 | - | summary="x position within the global compositor space"/> | |
| 2971 | - | <arg name="y" type="int" | |
| 2972 | - | summary="y position within the global compositor space"/> | |
| 2973 | - | <arg name="physical_width" type="int" | |
| 2974 | - | summary="width in millimeters of the output"/> | |
| 2975 | - | <arg name="physical_height" type="int" | |
| 2976 | - | summary="height in millimeters of the output"/> | |
| 2977 | - | <arg name="subpixel" type="int" enum="subpixel" | |
| 2978 | - | summary="subpixel orientation of the output"/> | |
| 2979 | - | <arg name="make" type="string" | |
| 2980 | - | summary="textual description of the manufacturer"/> | |
| 2981 | - | <arg name="model" type="string" | |
| 2982 | - | summary="textual description of the model"/> | |
| 2983 | - | <arg name="transform" type="int" enum="transform" | |
| 2984 | - | summary="additional transformation applied to buffer contents during presentation"/> | |
| 2985 | - | </event> | |
| 2986 | - | ||
| 2987 | - | <enum name="mode" bitfield="true"> | |
| 2988 | - | <description summary="mode information"> | |
| 2989 | - | These flags describe properties of an output mode. | |
| 2990 | - | They are used in the flags bitfield of the mode event. | |
| 2991 | - | </description> | |
| 2992 | - | <entry name="current" value="0x1" | |
| 2993 | - | summary="indicates this is the current mode"/> | |
| 2994 | - | <entry name="preferred" value="0x2" | |
| 2995 | - | summary="indicates this is the preferred mode"/> | |
| 2996 | - | </enum> | |
| 2997 | - | ||
| 2998 | - | <event name="mode"> | |
| 2999 | - | <description summary="advertise available modes for the output"> | |
| 3000 | - | The mode event describes an available mode for the output. | |
| 3001 | - | ||
| 3002 | - | The event is sent when binding to the output object and there | |
| 3003 | - | will always be one mode, the current mode. The event is sent | |
| 3004 | - | again if an output changes mode, for the mode that is now | |
| 3005 | - | current. In other words, the current mode is always the last | |
| 3006 | - | mode that was received with the current flag set. | |
| 3007 | - | ||
| 3008 | - | Non-current modes are deprecated. A compositor can decide to only | |
| 3009 | - | advertise the current mode and never send other modes. Clients | |
| 3010 | - | should not rely on non-current modes. | |
| 3011 | - | ||
| 3012 | - | The size of a mode is given in physical hardware units of | |
| 3013 | - | the output device. This is not necessarily the same as | |
| 3014 | - | the output size in the global compositor space. For instance, | |
| 3015 | - | the output may be scaled, as described in wl_output.scale, | |
| 3016 | - | or transformed, as described in wl_output.transform. Clients | |
| 3017 | - | willing to retrieve the output size in the global compositor | |
| 3018 | - | space should use xdg_output.logical_size instead. | |
| 3019 | - | ||
| 3020 | - | The vertical refresh rate can be set to zero if it doesn't make | |
| 3021 | - | sense for this output (e.g. for virtual outputs). | |
| 3022 | - | ||
| 3023 | - | The mode event will be followed by a done event (starting from | |
| 3024 | - | version 2). | |
| 3025 | - | ||
| 3026 | - | Clients should not use the refresh rate to schedule frames. Instead, | |
| 3027 | - | they should use the wl_surface.frame event or the presentation-time | |
| 3028 | - | protocol. | |
| 3029 | - | ||
| 3030 | - | Note: this information is not always meaningful for all outputs. Some | |
| 3031 | - | compositors, such as those exposing virtual outputs, might fake the | |
| 3032 | - | refresh rate or the size. | |
| 3033 | - | </description> | |
| 3034 | - | <arg name="flags" type="uint" enum="mode" summary="bitfield of mode flags"/> | |
| 3035 | - | <arg name="width" type="int" summary="width of the mode in hardware units"/> | |
| 3036 | - | <arg name="height" type="int" summary="height of the mode in hardware units"/> | |
| 3037 | - | <arg name="refresh" type="int" summary="vertical refresh rate in mHz"/> | |
| 3038 | - | </event> | |
| 3039 | - | ||
| 3040 | - | <!-- Version 2 additions --> | |
| 3041 | - | ||
| 3042 | - | <event name="done" since="2"> | |
| 3043 | - | <description summary="sent all information about output"> | |
| 3044 | - | This event is sent after all other properties have been | |
| 3045 | - | sent after binding to the output object and after any | |
| 3046 | - | other property changes done after that. This allows | |
| 3047 | - | changes to the output properties to be seen as | |
| 3048 | - | atomic, even if they happen via multiple events. | |
| 3049 | - | </description> | |
| 3050 | - | </event> | |
| 3051 | - | ||
| 3052 | - | <event name="scale" since="2"> | |
| 3053 | - | <description summary="output scaling properties"> | |
| 3054 | - | This event contains scaling geometry information | |
| 3055 | - | that is not in the geometry event. It may be sent after | |
| 3056 | - | binding the output object or if the output scale changes | |
| 3057 | - | later. The compositor will emit a non-zero, positive | |
| 3058 | - | value for scale. If it is not sent, the client should | |
| 3059 | - | assume a scale of 1. | |
| 3060 | - | ||
| 3061 | - | A scale larger than 1 means that the compositor will | |
| 3062 | - | automatically scale surface buffers by this amount | |
| 3063 | - | when rendering. This is used for very high resolution | |
| 3064 | - | displays where applications rendering at the native | |
| 3065 | - | resolution would be too small to be legible. | |
| 3066 | - | ||
| 3067 | - | Clients should use wl_surface.preferred_buffer_scale | |
| 3068 | - | instead of this event to find the preferred buffer | |
| 3069 | - | scale to use for a surface. | |
| 3070 | - | ||
| 3071 | - | The scale event will be followed by a done event. | |
| 3072 | - | </description> | |
| 3073 | - | <arg name="factor" type="int" summary="scaling factor of output"/> | |
| 3074 | - | </event> | |
| 3075 | - | ||
| 3076 | - | <!-- Version 3 additions --> | |
| 3077 | - | ||
| 3078 | - | <request name="release" type="destructor" since="3"> | |
| 3079 | - | <description summary="release the output object"> | |
| 3080 | - | Using this request a client can tell the server that it is not going to | |
| 3081 | - | use the output object anymore. | |
| 3082 | - | </description> | |
| 3083 | - | </request> | |
| 3084 | - | ||
| 3085 | - | <!-- Version 4 additions --> | |
| 3086 | - | ||
| 3087 | - | <event name="name" since="4"> | |
| 3088 | - | <description summary="name of this output"> | |
| 3089 | - | Many compositors will assign user-friendly names to their outputs, show | |
| 3090 | - | them to the user, allow the user to refer to an output, etc. The client | |
| 3091 | - | may wish to know this name as well to offer the user similar behaviors. | |
| 3092 | - | ||
| 3093 | - | The name is a UTF-8 string with no convention defined for its contents. | |
| 3094 | - | Each name is unique among all wl_output globals. The name is only | |
| 3095 | - | guaranteed to be unique for the compositor instance. | |
| 3096 | - | ||
| 3097 | - | The same output name is used for all clients for a given wl_output | |
| 3098 | - | global. Thus, the name can be shared across processes to refer to a | |
| 3099 | - | specific wl_output global. | |
| 3100 | - | ||
| 3101 | - | The name is not guaranteed to be persistent across sessions, thus cannot | |
| 3102 | - | be used to reliably identify an output in e.g. configuration files. | |
| 3103 | - | ||
| 3104 | - | Examples of names include 'HDMI-A-1', 'WL-1', 'X11-1', etc. However, do | |
| 3105 | - | not assume that the name is a reflection of an underlying DRM connector, | |
| 3106 | - | X11 connection, etc. | |
| 3107 | - | ||
| 3108 | - | The name event is sent after binding the output object. This event is | |
| 3109 | - | only sent once per output object, and the name does not change over the | |
| 3110 | - | lifetime of the wl_output global. | |
| 3111 | - | ||
| 3112 | - | Compositors may re-use the same output name if the wl_output global is | |
| 3113 | - | destroyed and re-created later. Compositors should avoid re-using the | |
| 3114 | - | same name if possible. | |
| 3115 | - | ||
| 3116 | - | The name event will be followed by a done event. | |
| 3117 | - | </description> | |
| 3118 | - | <arg name="name" type="string" summary="output name"/> | |
| 3119 | - | </event> | |
| 3120 | - | ||
| 3121 | - | <event name="description" since="4"> | |
| 3122 | - | <description summary="human-readable description of this output"> | |
| 3123 | - | Many compositors can produce human-readable descriptions of their | |
| 3124 | - | outputs. The client may wish to know this description as well, e.g. for | |
| 3125 | - | output selection purposes. | |
| 3126 | - | ||
| 3127 | - | The description is a UTF-8 string with no convention defined for its | |
| 3128 | - | contents. The description is not guaranteed to be unique among all | |
| 3129 | - | wl_output globals. Examples might include 'Foocorp 11" Display' or | |
| 3130 | - | 'Virtual X11 output via :1'. | |
| 3131 | - | ||
| 3132 | - | The description event is sent after binding the output object and | |
| 3133 | - | whenever the description changes. The description is optional, and may | |
| 3134 | - | not be sent at all. | |
| 3135 | - | ||
| 3136 | - | The description event will be followed by a done event. | |
| 3137 | - | </description> | |
| 3138 | - | <arg name="description" type="string" summary="output description"/> | |
| 3139 | - | </event> | |
| 3140 | - | </interface> | |
| 3141 | - | ||
| 3142 | - | <interface name="wl_region" version="7"> | |
| 3143 | - | <description summary="region interface"> | |
| 3144 | - | A region object describes an area. | |
| 3145 | - | ||
| 3146 | - | Region objects are used to describe the opaque and input | |
| 3147 | - | regions of a surface. | |
| 3148 | - | </description> | |
| 3149 | - | ||
| 3150 | - | <request name="destroy" type="destructor"> | |
| 3151 | - | <description summary="destroy region"> | |
| 3152 | - | Destroy the region. This will invalidate the object ID. | |
| 3153 | - | </description> | |
| 3154 | - | </request> | |
| 3155 | - | ||
| 3156 | - | <request name="add"> | |
| 3157 | - | <description summary="add rectangle to region"> | |
| 3158 | - | Add the specified rectangle to the region. | |
| 3159 | - | </description> | |
| 3160 | - | <arg name="x" type="int" summary="region-local x coordinate"/> | |
| 3161 | - | <arg name="y" type="int" summary="region-local y coordinate"/> | |
| 3162 | - | <arg name="width" type="int" summary="rectangle width"/> | |
| 3163 | - | <arg name="height" type="int" summary="rectangle height"/> | |
| 3164 | - | </request> | |
| 3165 | - | ||
| 3166 | - | <request name="subtract"> | |
| 3167 | - | <description summary="subtract rectangle from region"> | |
| 3168 | - | Subtract the specified rectangle from the region. | |
| 3169 | - | </description> | |
| 3170 | - | <arg name="x" type="int" summary="region-local x coordinate"/> | |
| 3171 | - | <arg name="y" type="int" summary="region-local y coordinate"/> | |
| 3172 | - | <arg name="width" type="int" summary="rectangle width"/> | |
| 3173 | - | <arg name="height" type="int" summary="rectangle height"/> | |
| 3174 | - | </request> | |
| 3175 | - | </interface> | |
| 3176 | - | ||
| 3177 | - | <interface name="wl_subcompositor" version="1"> | |
| 3178 | - | <description summary="sub-surface compositing"> | |
| 3179 | - | The global interface exposing sub-surface compositing capabilities. | |
| 3180 | - | A wl_surface, that has sub-surfaces associated, is called the | |
| 3181 | - | parent surface. Sub-surfaces can be arbitrarily nested and create | |
| 3182 | - | a tree of sub-surfaces. | |
| 3183 | - | ||
| 3184 | - | The root surface in a tree of sub-surfaces is the main | |
| 3185 | - | surface. The main surface cannot be a sub-surface, because | |
| 3186 | - | sub-surfaces must always have a parent. | |
| 3187 | - | ||
| 3188 | - | A main surface with its sub-surfaces forms a (compound) window. | |
| 3189 | - | For window management purposes, this set of wl_surface objects is | |
| 3190 | - | to be considered as a single window, and it should also behave as | |
| 3191 | - | such. | |
| 3192 | - | ||
| 3193 | - | The aim of sub-surfaces is to offload some of the compositing work | |
| 3194 | - | within a window from clients to the compositor. A prime example is | |
| 3195 | - | a video player with decorations and video in separate wl_surface | |
| 3196 | - | objects. This should allow the compositor to pass YUV video buffer | |
| 3197 | - | processing to dedicated overlay hardware when possible. | |
| 3198 | - | </description> | |
| 3199 | - | ||
| 3200 | - | <request name="destroy" type="destructor"> | |
| 3201 | - | <description summary="unbind from the subcompositor interface"> | |
| 3202 | - | Informs the server that the client will not be using this | |
| 3203 | - | protocol object anymore. This does not affect any other | |
| 3204 | - | objects, wl_subsurface objects included. | |
| 3205 | - | </description> | |
| 3206 | - | </request> | |
| 3207 | - | ||
| 3208 | - | <enum name="error"> | |
| 3209 | - | <entry name="bad_surface" value="0" | |
| 3210 | - | summary="the to-be sub-surface is invalid"/> | |
| 3211 | - | <entry name="bad_parent" value="1" | |
| 3212 | - | summary="the to-be sub-surface parent is invalid"/> | |
| 3213 | - | </enum> | |
| 3214 | - | ||
| 3215 | - | <request name="get_subsurface"> | |
| 3216 | - | <description summary="give a surface the role sub-surface"> | |
| 3217 | - | Create a sub-surface interface for the given surface, and | |
| 3218 | - | associate it with the given parent surface. This turns a | |
| 3219 | - | plain wl_surface into a sub-surface. | |
| 3220 | - | ||
| 3221 | - | The to-be sub-surface must not already have another role, and it | |
| 3222 | - | must not have an existing wl_subsurface object. Otherwise the | |
| 3223 | - | bad_surface protocol error is raised. | |
| 3224 | - | ||
| 3225 | - | Adding sub-surfaces to a parent is a double-buffered operation on the | |
| 3226 | - | parent (see wl_surface.commit). The effect of adding a sub-surface | |
| 3227 | - | becomes visible on the next time the state of the parent surface is | |
| 3228 | - | applied. | |
| 3229 | - | ||
| 3230 | - | The parent surface must not be one of the child surface's descendants, | |
| 3231 | - | and the parent must be different from the child surface, otherwise the | |
| 3232 | - | bad_parent protocol error is raised. | |
| 3233 | - | ||
| 3234 | - | This request modifies the behaviour of wl_surface.commit request on | |
| 3235 | - | the sub-surface, see the documentation on wl_subsurface interface. | |
| 3236 | - | </description> | |
| 3237 | - | <arg name="id" type="new_id" interface="wl_subsurface" | |
| 3238 | - | summary="the new sub-surface object ID"/> | |
| 3239 | - | <arg name="surface" type="object" interface="wl_surface" | |
| 3240 | - | summary="the surface to be turned into a sub-surface"/> | |
| 3241 | - | <arg name="parent" type="object" interface="wl_surface" | |
| 3242 | - | summary="the parent surface"/> | |
| 3243 | - | </request> | |
| 3244 | - | </interface> | |
| 3245 | - | ||
| 3246 | - | <interface name="wl_subsurface" version="1"> | |
| 3247 | - | <description summary="sub-surface interface to a wl_surface"> | |
| 3248 | - | An additional interface to a wl_surface object, which has been | |
| 3249 | - | made a sub-surface. A sub-surface has one parent surface. A | |
| 3250 | - | sub-surface's size and position are not limited to that of the parent. | |
| 3251 | - | Particularly, a sub-surface is not automatically clipped to its | |
| 3252 | - | parent's area. | |
| 3253 | - | ||
| 3254 | - | A sub-surface becomes mapped, when a non-NULL wl_buffer is applied | |
| 3255 | - | and the parent surface is mapped. The order of which one happens | |
| 3256 | - | first is irrelevant. A sub-surface is hidden if the parent becomes | |
| 3257 | - | hidden, or if a NULL wl_buffer is applied. These rules apply | |
| 3258 | - | recursively through the tree of surfaces. | |
| 3259 | - | ||
| 3260 | - | A sub-surface can be in one of two modes. The possible modes are | |
| 3261 | - | synchronized and desynchronized, see methods wl_subsurface.set_sync and | |
| 3262 | - | wl_subsurface.set_desync. | |
| 3263 | - | ||
| 3264 | - | The main surface can be thought to be always in desynchronized mode, | |
| 3265 | - | since it does not have a parent in the sub-surfaces sense. | |
| 3266 | - | ||
| 3267 | - | Even if a sub-surface is in desynchronized mode, it will behave as | |
| 3268 | - | in synchronized mode, if its parent surface behaves as in | |
| 3269 | - | synchronized mode. This rule is applied recursively throughout the | |
| 3270 | - | tree of surfaces. This means, that one can set a sub-surface into | |
| 3271 | - | synchronized mode, and then assume that all its child and grand-child | |
| 3272 | - | sub-surfaces are synchronized, too, without explicitly setting them. | |
| 3273 | - | ||
| 3274 | - | If a surface behaves as in synchronized mode, it is effectively | |
| 3275 | - | synchronized, otherwise it is effectively desynchronized. | |
| 3276 | - | ||
| 3277 | - | A sub-surface is initially in the synchronized mode. | |
| 3278 | - | ||
| 3279 | - | The wl_subsurface interface has requests which modify double-buffered | |
| 3280 | - | state of the parent surface (wl_subsurface.set_position, .place_above and | |
| 3281 | - | .place_below). | |
| 3282 | - | ||
| 3283 | - | Destroying a sub-surface takes effect immediately. If you need to | |
| 3284 | - | synchronize the removal of a sub-surface to the parent surface update, | |
| 3285 | - | unmap the sub-surface first by attaching a NULL wl_buffer, update parent, | |
| 3286 | - | and then destroy the sub-surface. | |
| 3287 | - | ||
| 3288 | - | If the parent wl_surface object is destroyed, the sub-surface is | |
| 3289 | - | unmapped. | |
| 3290 | - | ||
| 3291 | - | A sub-surface never has the keyboard focus of any seat. | |
| 3292 | - | ||
| 3293 | - | The wl_surface.offset request is ignored: clients must use set_position | |
| 3294 | - | instead to move the sub-surface. | |
| 3295 | - | </description> | |
| 3296 | - | ||
| 3297 | - | <request name="destroy" type="destructor"> | |
| 3298 | - | <description summary="remove sub-surface interface"> | |
| 3299 | - | The sub-surface interface is removed from the wl_surface object | |
| 3300 | - | that was turned into a sub-surface with a | |
| 3301 | - | wl_subcompositor.get_subsurface request. The wl_surface's association | |
| 3302 | - | to the parent is deleted. The wl_surface is unmapped immediately. | |
| 3303 | - | </description> | |
| 3304 | - | </request> | |
| 3305 | - | ||
| 3306 | - | <enum name="error"> | |
| 3307 | - | <entry name="bad_surface" value="0" | |
| 3308 | - | summary="wl_surface is not a sibling or the parent"/> | |
| 3309 | - | </enum> | |
| 3310 | - | ||
| 3311 | - | <request name="set_position"> | |
| 3312 | - | <description summary="reposition the sub-surface"> | |
| 3313 | - | This sets the position of the sub-surface, relative to the parent | |
| 3314 | - | surface. | |
| 3315 | - | ||
| 3316 | - | The sub-surface will be moved so that its origin (top left | |
| 3317 | - | corner pixel) will be at the location x, y of the parent surface | |
| 3318 | - | coordinate system. The coordinates are not restricted to the parent | |
| 3319 | - | surface area. Negative values are allowed. | |
| 3320 | - | ||
| 3321 | - | The initial position is 0, 0. | |
| 3322 | - | ||
| 3323 | - | Position is double-buffered state on the parent surface, see | |
| 3324 | - | wl_subsurface and wl_surface.commit for more information. | |
| 3325 | - | </description> | |
| 3326 | - | <arg name="x" type="int" summary="x coordinate in the parent surface"/> | |
| 3327 | - | <arg name="y" type="int" summary="y coordinate in the parent surface"/> | |
| 3328 | - | </request> | |
| 3329 | - | ||
| 3330 | - | <request name="place_above"> | |
| 3331 | - | <description summary="restack the sub-surface"> | |
| 3332 | - | This sub-surface is taken from the stack, and put back just | |
| 3333 | - | above the reference surface, changing the z-order of the sub-surfaces. | |
| 3334 | - | The reference surface must be one of the sibling surfaces, or the | |
| 3335 | - | parent surface. Using any other surface, including this sub-surface, | |
| 3336 | - | will cause a protocol error. | |
| 3337 | - | ||
| 3338 | - | A new sub-surface is initially added as the top-most in the stack | |
| 3339 | - | of its siblings and parent. | |
| 3340 | - | ||
| 3341 | - | Z-order is double-buffered state on the parent surface, see | |
| 3342 | - | wl_subsurface and wl_surface.commit for more information. | |
| 3343 | - | </description> | |
| 3344 | - | <arg name="sibling" type="object" interface="wl_surface" | |
| 3345 | - | summary="the reference surface"/> | |
| 3346 | - | </request> | |
| 3347 | - | ||
| 3348 | - | <request name="place_below"> | |
| 3349 | - | <description summary="restack the sub-surface"> | |
| 3350 | - | The sub-surface is placed just below the reference surface. | |
| 3351 | - | ||
| 3352 | - | See wl_subsurface.place_above. | |
| 3353 | - | </description> | |
| 3354 | - | <arg name="sibling" type="object" interface="wl_surface" | |
| 3355 | - | summary="the reference surface"/> | |
| 3356 | - | </request> | |
| 3357 | - | ||
| 3358 | - | <request name="set_sync"> | |
| 3359 | - | <description summary="set sub-surface to synchronized mode"> | |
| 3360 | - | Change the commit behaviour of the sub-surface to synchronized | |
| 3361 | - | mode. | |
| 3362 | - | ||
| 3363 | - | See wl_subsurface and wl_surface.commit for more information. | |
| 3364 | - | </description> | |
| 3365 | - | </request> | |
| 3366 | - | ||
| 3367 | - | <request name="set_desync"> | |
| 3368 | - | <description summary="set sub-surface to desynchronized mode"> | |
| 3369 | - | Change the commit behaviour of the sub-surface to desynchronized | |
| 3370 | - | mode. | |
| 3371 | - | ||
| 3372 | - | See wl_subsurface and wl_surface.commit for more information. | |
| 3373 | - | </description> | |
| 3374 | - | </request> | |
| 3375 | - | </interface> | |
| 3376 | - | ||
| 3377 | - | <interface name="wl_fixes" version="2"> | |
| 3378 | - | <description summary="wayland protocol fixes"> | |
| 3379 | - | This global fixes problems with other core-protocol interfaces that | |
| 3380 | - | cannot be fixed in these interfaces themselves. | |
| 3381 | - | </description> | |
| 3382 | - | ||
| 3383 | - | <enum name="error"> | |
| 3384 | - | <description summary="wl_fixes error values"> | |
| 3385 | - | These errors can be emitted in response to wl_fixes requests. | |
| 3386 | - | </description> | |
| 3387 | - | <entry name="invalid_ack_remove" value="0" | |
| 3388 | - | summary="unknown global or the global is not removed"/> | |
| 3389 | - | </enum> | |
| 3390 | - | ||
| 3391 | - | <request name="destroy" type="destructor"> | |
| 3392 | - | <description summary="destroys this object"/> | |
| 3393 | - | </request> | |
| 3394 | - | ||
| 3395 | - | <request name="destroy_registry"> | |
| 3396 | - | <description summary="destroy a wl_registry"> | |
| 3397 | - | This request destroys a wl_registry object. | |
| 3398 | - | ||
| 3399 | - | The client should no longer use the wl_registry after making this | |
| 3400 | - | request. | |
| 3401 | - | ||
| 3402 | - | The compositor will emit a wl_display.delete_id event with the object ID | |
| 3403 | - | of the registry and will no longer emit any events on the registry. The | |
| 3404 | - | client should re-use the object ID once it receives the | |
| 3405 | - | wl_display.delete_id event. | |
| 3406 | - | </description> | |
| 3407 | - | <arg name="registry" type="object" interface="wl_registry" | |
| 3408 | - | summary="the registry to destroy"/> | |
| 3409 | - | </request> | |
| 3410 | - | ||
| 3411 | - | <request name="ack_global_remove" since="2"> | |
| 3412 | - | <description summary="acknowledge global removal"> | |
| 3413 | - | Acknowledge the removal of the specified global. | |
| 3414 | - | ||
| 3415 | - | If no global with the specified name exists or the global is not removed, | |
| 3416 | - | the wl_fixes.invalid_ack_remove protocol error will be posted. | |
| 3417 | - | ||
| 3418 | - | Due to the Wayland protocol being asynchronous, the wl_global objects | |
| 3419 | - | cannot be destroyed immediately. For example, if a wl_global is removed | |
| 3420 | - | and a client attempts to bind that global around same time, it can | |
| 3421 | - | result in a protocol error due to an unknown global name in the bind | |
| 3422 | - | request. | |
| 3423 | - | ||
| 3424 | - | In order to avoid crashing clients, the compositor should remove the | |
| 3425 | - | wl_global once it is guaranteed that no more bind requests will come. | |
| 3426 | - | ||
| 3427 | - | The wl_fixes.ack_global_remove() request is used to signal to the | |
| 3428 | - | compositor that the client will not bind the given global anymore. After | |
| 3429 | - | all clients acknowledge the removal of the global, the compositor can | |
| 3430 | - | safely destroy it. | |
| 3431 | - | ||
| 3432 | - | The client must call the wl_fixes.ack_global_remove() request in | |
| 3433 | - | response to a wl_registry.global_remove() event even if it did not bind | |
| 3434 | - | the corresponding global. | |
| 3435 | - | </description> | |
| 3436 | - | <arg name="registry" type="object" interface="wl_registry" | |
| 3437 | - | summary="the registry object"/> | |
| 3438 | - | <arg name="name" type="uint" summary="unique name of the global"/> | |
| 3439 | - | </request> | |
| 3440 | - | </interface> | |
| 3441 | - | ||
| 3442 | - | </protocol> | |
D protocol/wlr_extensions_test.go +0 -652 collapsed to keep the page light
D protocol/workspace/ext-workspace-v1.xml +0 -422 collapsed to keep the page light
D protocol/workspace/ext-workspace-v1_generated.go +0 -758 collapsed to keep the page light
D protocol/workspace/generate.go +0 -3
| @@ -1,3 +0,0 @@ | |||
| 1 | - | package workspace | |
| 2 | - | ||
| 3 | - | //go:generate go run ../../cmd/wlturbo-scanner -p workspace -o ext-workspace-v1_generated.go -import wl_output=github.com/bnema/wlturbo/protocol/core ext-workspace-v1.xml | |
D protocol/xdgactivation/generate.go +0 -3
| @@ -1,3 +0,0 @@ | |||
| 1 | - | package xdgactivation | |
| 2 | - | ||
| 3 | - | //go:generate go run ../../cmd/wlturbo-scanner -p xdgactivation -o xdg-activation-v1_generated.go -import wl_surface=github.com/bnema/wlturbo/protocol/core -import wl_seat=github.com/bnema/wlturbo/protocol/core xdg-activation-v1.xml | |
D protocol/xdgactivation/xdg-activation-v1.xml +0 -200 collapsed to keep the page light
D protocol/xdgactivation/xdg-activation-v1_generated.go +0 -214 collapsed to keep the page light
D protocol/xdgdecoration/generate.go +0 -3
| @@ -1,3 +0,0 @@ | |||
| 1 | - | package xdgdecoration | |
| 2 | - | ||
| 3 | - | //go:generate go run ../../cmd/wlturbo-scanner -p xdgdecoration -o xdg-decoration-unstable-v1_generated.go -import xdg_toplevel=github.com/bnema/wlturbo/protocol/xdgshell xdg-decoration-unstable-v1.xml | |