detached d9b2fda

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 VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · 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 @@
11 # WLTurbo - Wayland Client Library for Go
22
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.
44
55 ## Overview
66
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)).
88
99 ## Architecture
1010
1111 WLTurbo provides the foundational Wayland client infrastructure:
1212
13-- **Core Protocol Objects**: Display, Registry, Compositor, Surface, Seat, Region
13+- **Bootstrap Objects**: Display and Registry
1414 - **Event Dispatching**: Efficient routing of Wayland events to handlers
1515 - **Connection Management**: Unix socket communication with the compositor
1616 - **Memory Management**: Shared memory support via file descriptor passing
1717
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.
1919
20-## Generated protocols
20+## Protocol bindings
2121
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`:
2323
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+```
3427
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.
3629
3730 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.
3831
@@ -41,8 +34,8 @@ After `display.Roundtrip()` discovers globals, call `display.Registry().BindNego
4134 - **Stream framing**: messages split across or coalesced within socket reads are framed exactly; event bodies are not copied.
4235 - **Descriptor ownership**: received FDs belong to the event that declares them and are closed if a handler does not take them.
4336 - **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.
4639
4740 ## Quick Start
4841
@@ -76,22 +69,13 @@ For higher-level device control, [libwldevices-go](https://github.com/bnema/libw
7669 ## Development checks
7770
7871 ```sh
79-GOWORK=off go generate ./...
8072 GOWORK=off go test ./...
8173 GOWORK=off go test -race ./...
8274 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
9276 ```
9377
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.
9579
9680 ## Requirements
9781
@@ -101,16 +85,12 @@ The tests start a separate compositor with temporary runtime/config directories
10185
10286 ## License
10387
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).
10989
11090 ## Contributing
11191
11292 Contributions welcome! Areas of focus:
11393 - Performance improvements
114-- Additional protocol object support
94+- Transport correctness and hardening
11595 - Documentation and examples
11696 - Benchmark suite⏎̸
M client.go +2 -2
@@ -1,6 +1,6 @@
11 // 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/).
44 package wlturbo
55
66 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 &amp; 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 large diff (3442 lines changed): collapsed
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
@@ -1,758 +0,0 @@
1-// Code generated by wlturbo-scanner. DO NOT EDIT.
2-// Protocol: ext_workspace_v1
3-// Source: ext-workspace-v1.xml
4-
5-// Upstream protocol copyright and license:
6-// Copyright © 2019 Christopher Billington
7-// Copyright © 2020 Ilia Bozhinov
8-// Copyright © 2022 Victoria Brekenfeld
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 workspace
32-
33-import (
34- "sync"
35-
36- "github.com/bnema/wlturbo/wl"
37-)
38-
39-// GROUP_CAPABILITIES_CREATE_WORKSPACE is the group_capabilities create_workspace value.
40-const GROUP_CAPABILITIES_CREATE_WORKSPACE = 1
41-
42-// STATE_ACTIVE is the state active value.
43-const STATE_ACTIVE = 1
44-
45-// STATE_URGENT is the state urgent value.
46-const STATE_URGENT = 2
47-
48-// STATE_HIDDEN is the state hidden value.
49-const STATE_HIDDEN = 4
50-
51-// WORKSPACE_CAPABILITIES_ACTIVATE is the workspace_capabilities activate value.
52-const WORKSPACE_CAPABILITIES_ACTIVATE = 1
53-
54-// WORKSPACE_CAPABILITIES_DEACTIVATE is the workspace_capabilities deactivate value.
55-const WORKSPACE_CAPABILITIES_DEACTIVATE = 2
56-
57-// WORKSPACE_CAPABILITIES_REMOVE is the workspace_capabilities remove value.
58-const WORKSPACE_CAPABILITIES_REMOVE = 4
59-
60-// WORKSPACE_CAPABILITIES_ASSIGN is the workspace_capabilities assign value.
61-const WORKSPACE_CAPABILITIES_ASSIGN = 8
62-
63-// ExtWorkspaceManagerInterface is the protocol interface name.
64-const ExtWorkspaceManagerInterface = "ext_workspace_manager_v1"
65-
66-// ExtWorkspaceManager is the generated binding for ext_workspace_manager_v1 version 1.
67-type ExtWorkspaceManager struct {
68- wl.BaseProxy
69- // handlersMu guards the handler slices: a client may register or replace
70- // handlers while another goroutine dispatches events.
71- handlersMu sync.Mutex
72- onWorkspaceGroup []func(workspaceGroupObject *ExtWorkspaceGroupHandle)
73- onWorkspace []func(workspaceObject *ExtWorkspaceHandle)
74- onDone []func()
75- onFinished []func()
76-}
77-
78-// NewExtWorkspaceManager returns an unbound ExtWorkspaceManager.
79-func NewExtWorkspaceManager(ctx *wl.Context) *ExtWorkspaceManager {
80- obj := &ExtWorkspaceManager{}
81- obj.SetContext(ctx)
82- ctx.Register(obj)
83- return obj
84-}
85-
86-// The client must send this request after it has finished sending other requests. The compositor must process a series of requests preceding a commit request atomically. This allows changes to the workspace properties to be seen as atomic, even if they happen via multiple events, and even if they involve multiple ext_workspace_handle_v1 objects, for example, deactivating one workspace and activating another.
87-func (o *ExtWorkspaceManager) Commit() error {
88- if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "ext_workspace_manager_v1.commit"}); err != nil {
89- return err
90- }
91- return nil
92-}
93-
94-// Indicates the client no longer wishes to receive events for new workspace groups. However the compositor may emit further workspace events, until the finished event is emitted. The compositor is expected to send the finished event eventually once the stop request has been processed. The client must not send any requests after this one, doing so will raise a wl_display invalid_object error.
95-func (o *ExtWorkspaceManager) Stop() error {
96- if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "ext_workspace_manager_v1.stop"}); err != nil {
97- return err
98- }
99- return nil
100-}
101-
102-// OnWorkspaceGroup registers a handler for the workspace_group event.
103-//
104-// Handlers are appended, so a second call adds another handler rather than
105-// replacing the first. Registration is safe while another goroutine dispatches.
106-func (o *ExtWorkspaceManager) OnWorkspaceGroup(handler func(workspaceGroupObject *ExtWorkspaceGroupHandle)) {
107- if handler == nil {
108- return
109- }
110- o.handlersMu.Lock()
111- defer o.handlersMu.Unlock()
112- o.onWorkspaceGroup = append(o.onWorkspaceGroup, handler)
113-}
114-
115-// handlersForWorkspaceGroup returns the handlers registered for workspace_group, taken
116-// under the lock so a handler may register another handler while events are
117-// being dispatched.
118-func (o *ExtWorkspaceManager) handlersForWorkspaceGroup() []func(workspaceGroupObject *ExtWorkspaceGroupHandle) {
119- o.handlersMu.Lock()
120- defer o.handlersMu.Unlock()
121- return o.onWorkspaceGroup
122-}
123-
124-// OnWorkspace registers a handler for the workspace event.
125-//
126-// Handlers are appended, so a second call adds another handler rather than
127-// replacing the first. Registration is safe while another goroutine dispatches.
128-func (o *ExtWorkspaceManager) OnWorkspace(handler func(workspaceObject *ExtWorkspaceHandle)) {
129- if handler == nil {
130- return
131- }
132- o.handlersMu.Lock()
133- defer o.handlersMu.Unlock()
134- o.onWorkspace = append(o.onWorkspace, handler)
135-}
136-
137-// handlersForWorkspace returns the handlers registered for workspace, taken
138-// under the lock so a handler may register another handler while events are
139-// being dispatched.
140-func (o *ExtWorkspaceManager) handlersForWorkspace() []func(workspaceObject *ExtWorkspaceHandle) {
141- o.handlersMu.Lock()
142- defer o.handlersMu.Unlock()
143- return o.onWorkspace
144-}
145-
146-// OnDone registers a handler for the done event.
147-//
148-// Handlers are appended, so a second call adds another handler rather than
149-// replacing the first. Registration is safe while another goroutine dispatches.
150-func (o *ExtWorkspaceManager) OnDone(handler func()) {
151- if handler == nil {
152- return
153- }
154- o.handlersMu.Lock()
155- defer o.handlersMu.Unlock()
156- o.onDone = append(o.onDone, handler)
157-}
158-
159-// handlersForDone returns the handlers registered for done, taken
160-// under the lock so a handler may register another handler while events are
161-// being dispatched.
162-func (o *ExtWorkspaceManager) handlersForDone() []func() {
163- o.handlersMu.Lock()
164- defer o.handlersMu.Unlock()
165- return o.onDone
166-}
167-
168-// OnFinished registers a handler for the finished event.
169-//
170-// Handlers are appended, so a second call adds another handler rather than
171-// replacing the first. Registration is safe while another goroutine dispatches.
172-func (o *ExtWorkspaceManager) OnFinished(handler func()) {
173- if handler == nil {
174- return
175- }
176- o.handlersMu.Lock()
177- defer o.handlersMu.Unlock()
178- o.onFinished = append(o.onFinished, handler)
179-}
180-
181-// handlersForFinished returns the handlers registered for finished, taken
182-// under the lock so a handler may register another handler while events are
183-// being dispatched.
184-func (o *ExtWorkspaceManager) handlersForFinished() []func() {
185- o.handlersMu.Lock()
186- defer o.handlersMu.Unlock()
187- return o.onFinished
188-}
189-
190-// EventSignature returns the declared event argument types in wire order.
191-func (o *ExtWorkspaceManager) EventSignature(opcode uint16) (string, bool) {
192- switch opcode {
193- case 0:
194- return "new_id,", true
195- case 1:
196- return "new_id,", true
197- case 2:
198- return "", true
199- case 3:
200- return "", true
201- default:
202- return "", false
203- }
204-}
205-
206-// Dispatch decodes one event on ext_workspace_manager_v1 and calls the registered handlers.
207-func (o *ExtWorkspaceManager) Dispatch(event *wl.Event) {
208- switch event.Opcode {
209- case 0: // workspace_group
210- workspaceGroupID := event.Uint32()
211- workspaceGroupObject := &ExtWorkspaceGroupHandle{}
212- workspaceGroupObject.SetContext(o.Context())
213- workspaceGroupObject.SetID(workspaceGroupID)
214- workspaceGroupObject.SetVersion(o.Version())
215- o.Context().Register(workspaceGroupObject)
216-
217- for i, handler := range o.handlersForWorkspaceGroup() {
218- _ = i
219- handler(workspaceGroupObject)
220- }
221- case 1: // workspace
222- workspaceID := event.Uint32()
223- workspaceObject := &ExtWorkspaceHandle{}
224- workspaceObject.SetContext(o.Context())
225- workspaceObject.SetID(workspaceID)
226- workspaceObject.SetVersion(o.Version())
227- o.Context().Register(workspaceObject)
228-
229- for i, handler := range o.handlersForWorkspace() {
230- _ = i
231- handler(workspaceObject)
232- }
233- case 2: // done
234-
235- for i, handler := range o.handlersForDone() {
236- _ = i
237- handler()
238- }
239- case 3: // finished
240-
241- for i, handler := range o.handlersForFinished() {
242- _ = i
243- handler()
244- }
245- o.Context().Unregister(o)
246- default:
247- }
248-}
249-
250-// ExtWorkspaceGroupHandleInterface is the protocol interface name.
251-const ExtWorkspaceGroupHandleInterface = "ext_workspace_group_handle_v1"
252-
253-// ExtWorkspaceGroupHandle is the generated binding for ext_workspace_group_handle_v1 version 1.
254-type ExtWorkspaceGroupHandle struct {
255- wl.BaseProxy
256- // handlersMu guards the handler slices: a client may register or replace
257- // handlers while another goroutine dispatches events.
258- handlersMu sync.Mutex
259- onCapabilities []func(capabilities uint32)
260- onOutputEnter []func(outputID uint32)
261- onOutputLeave []func(outputID uint32)
262- onWorkspaceEnter []func(workspaceID uint32)
263- onWorkspaceLeave []func(workspaceID uint32)
264- onRemoved []func()
265-}
266-
267-// NewExtWorkspaceGroupHandle returns an unbound ExtWorkspaceGroupHandle.
268-func NewExtWorkspaceGroupHandle(ctx *wl.Context) *ExtWorkspaceGroupHandle {
269- obj := &ExtWorkspaceGroupHandle{}
270- obj.SetContext(ctx)
271- ctx.Register(obj)
272- return obj
273-}
274-
275-// Request that the compositor create a new workspace with the given name and assign it to this group. There is no guarantee that the compositor will create a new workspace, or that the created workspace will have the provided name.
276-func (o *ExtWorkspaceGroupHandle) CreateWorkspace(workspace string) error {
277- if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "ext_workspace_group_handle_v1.create_workspace"}, wl.ArgString(workspace)); err != nil {
278- return err
279- }
280- return nil
281-}
282-
283-// Destroys the ext_workspace_group_handle_v1 object. This request should be send either when the client does not want to use the workspace group object any more or after the removed event to finalize the destruction of the object.
284-func (o *ExtWorkspaceGroupHandle) Destroy() error {
285- if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "ext_workspace_group_handle_v1.destroy", Destructor: true}); err != nil {
286- return err
287- }
288- return nil
289-}
290-
291-// OnCapabilities registers a handler for the capabilities event.
292-//
293-// Handlers are appended, so a second call adds another handler rather than
294-// replacing the first. Registration is safe while another goroutine dispatches.
295-func (o *ExtWorkspaceGroupHandle) OnCapabilities(handler func(capabilities uint32)) {
296- if handler == nil {
297- return
298- }
299- o.handlersMu.Lock()
300- defer o.handlersMu.Unlock()
301- o.onCapabilities = append(o.onCapabilities, handler)
302-}
303-
304-// handlersForCapabilities returns the handlers registered for capabilities, taken
305-// under the lock so a handler may register another handler while events are
306-// being dispatched.
307-func (o *ExtWorkspaceGroupHandle) handlersForCapabilities() []func(capabilities uint32) {
308- o.handlersMu.Lock()
309- defer o.handlersMu.Unlock()
310- return o.onCapabilities
311-}
312-
313-// OnOutputEnter registers a handler for the output_enter event.
314-//
315-// Handlers are appended, so a second call adds another handler rather than
316-// replacing the first. Registration is safe while another goroutine dispatches.
317-func (o *ExtWorkspaceGroupHandle) OnOutputEnter(handler func(outputID uint32)) {
318- if handler == nil {
319- return
320- }
321- o.handlersMu.Lock()
322- defer o.handlersMu.Unlock()
323- o.onOutputEnter = append(o.onOutputEnter, handler)
324-}
325-
326-// handlersForOutputEnter returns the handlers registered for output_enter, taken
327-// under the lock so a handler may register another handler while events are
328-// being dispatched.
329-func (o *ExtWorkspaceGroupHandle) handlersForOutputEnter() []func(outputID uint32) {
330- o.handlersMu.Lock()
331- defer o.handlersMu.Unlock()
332- return o.onOutputEnter
333-}
334-
335-// OnOutputLeave registers a handler for the output_leave event.
336-//
337-// Handlers are appended, so a second call adds another handler rather than
338-// replacing the first. Registration is safe while another goroutine dispatches.
339-func (o *ExtWorkspaceGroupHandle) OnOutputLeave(handler func(outputID uint32)) {
340- if handler == nil {
341- return
342- }
343- o.handlersMu.Lock()
344- defer o.handlersMu.Unlock()
345- o.onOutputLeave = append(o.onOutputLeave, handler)
346-}
347-
348-// handlersForOutputLeave returns the handlers registered for output_leave, taken
349-// under the lock so a handler may register another handler while events are
350-// being dispatched.
351-func (o *ExtWorkspaceGroupHandle) handlersForOutputLeave() []func(outputID uint32) {
352- o.handlersMu.Lock()
353- defer o.handlersMu.Unlock()
354- return o.onOutputLeave
355-}
356-
357-// OnWorkspaceEnter registers a handler for the workspace_enter event.
358-//
359-// Handlers are appended, so a second call adds another handler rather than
360-// replacing the first. Registration is safe while another goroutine dispatches.
361-func (o *ExtWorkspaceGroupHandle) OnWorkspaceEnter(handler func(workspaceID uint32)) {
362- if handler == nil {
363- return
364- }
365- o.handlersMu.Lock()
366- defer o.handlersMu.Unlock()
367- o.onWorkspaceEnter = append(o.onWorkspaceEnter, handler)
368-}
369-
370-// handlersForWorkspaceEnter returns the handlers registered for workspace_enter, taken
371-// under the lock so a handler may register another handler while events are
372-// being dispatched.
373-func (o *ExtWorkspaceGroupHandle) handlersForWorkspaceEnter() []func(workspaceID uint32) {
374- o.handlersMu.Lock()
375- defer o.handlersMu.Unlock()
376- return o.onWorkspaceEnter
377-}
378-
379-// OnWorkspaceLeave registers a handler for the workspace_leave event.
380-//
381-// Handlers are appended, so a second call adds another handler rather than
382-// replacing the first. Registration is safe while another goroutine dispatches.
383-func (o *ExtWorkspaceGroupHandle) OnWorkspaceLeave(handler func(workspaceID uint32)) {
384- if handler == nil {
385- return
386- }
387- o.handlersMu.Lock()
388- defer o.handlersMu.Unlock()
389- o.onWorkspaceLeave = append(o.onWorkspaceLeave, handler)
390-}
391-
392-// handlersForWorkspaceLeave returns the handlers registered for workspace_leave, taken
393-// under the lock so a handler may register another handler while events are
394-// being dispatched.
395-func (o *ExtWorkspaceGroupHandle) handlersForWorkspaceLeave() []func(workspaceID uint32) {
396- o.handlersMu.Lock()
397- defer o.handlersMu.Unlock()
398- return o.onWorkspaceLeave
399-}
400-
401-// OnRemoved registers a handler for the removed event.
402-//
403-// Handlers are appended, so a second call adds another handler rather than
404-// replacing the first. Registration is safe while another goroutine dispatches.
405-func (o *ExtWorkspaceGroupHandle) OnRemoved(handler func()) {
406- if handler == nil {
407- return
408- }
409- o.handlersMu.Lock()
410- defer o.handlersMu.Unlock()
411- o.onRemoved = append(o.onRemoved, handler)
412-}
413-
414-// handlersForRemoved returns the handlers registered for removed, taken
415-// under the lock so a handler may register another handler while events are
416-// being dispatched.
417-func (o *ExtWorkspaceGroupHandle) handlersForRemoved() []func() {
418- o.handlersMu.Lock()
419- defer o.handlersMu.Unlock()
420- return o.onRemoved
421-}
422-
423-// EventSignature returns the declared event argument types in wire order.
424-func (o *ExtWorkspaceGroupHandle) EventSignature(opcode uint16) (string, bool) {
425- switch opcode {
426- case 0:
427- return "uint,", true
428- case 1:
429- return "object,", true
430- case 2:
431- return "object,", true
432- case 3:
433- return "object,", true
434- case 4:
435- return "object,", true
436- case 5:
437- return "", true
438- default:
439- return "", false
440- }
441-}
442-
443-// Dispatch decodes one event on ext_workspace_group_handle_v1 and calls the registered handlers.
444-func (o *ExtWorkspaceGroupHandle) Dispatch(event *wl.Event) {
445- switch event.Opcode {
446- case 0: // capabilities
447- capabilities := event.Uint32()
448-
449- for i, handler := range o.handlersForCapabilities() {
450- _ = i
451- handler(capabilities)
452- }
453- case 1: // output_enter
454- outputID := event.Uint32()
455-
456- for i, handler := range o.handlersForOutputEnter() {
457- _ = i
458- handler(outputID)
459- }
460- case 2: // output_leave
461- outputID := event.Uint32()
462-
463- for i, handler := range o.handlersForOutputLeave() {
464- _ = i
465- handler(outputID)
466- }
467- case 3: // workspace_enter
468- workspaceID := event.Uint32()
469-
470- for i, handler := range o.handlersForWorkspaceEnter() {
471- _ = i
472- handler(workspaceID)
473- }
474- case 4: // workspace_leave
475- workspaceID := event.Uint32()
476-
477- for i, handler := range o.handlersForWorkspaceLeave() {
478- _ = i
479- handler(workspaceID)
480- }
481- case 5: // removed
482-
483- for i, handler := range o.handlersForRemoved() {
484- _ = i
485- handler()
486- }
487- default:
488- }
489-}
490-
491-// ExtWorkspaceHandleInterface is the protocol interface name.
492-const ExtWorkspaceHandleInterface = "ext_workspace_handle_v1"
493-
494-// ExtWorkspaceHandle is the generated binding for ext_workspace_handle_v1 version 1.
495-type ExtWorkspaceHandle struct {
496- wl.BaseProxy
497- // handlersMu guards the handler slices: a client may register or replace
498- // handlers while another goroutine dispatches events.
499- handlersMu sync.Mutex
500- onId []func(id string)
501- onName []func(name string)
502- onCoordinates []func(coordinates []byte)
503- onState []func(state uint32)
504- onCapabilities []func(capabilities uint32)
505- onRemoved []func()
506-}
507-
508-// NewExtWorkspaceHandle returns an unbound ExtWorkspaceHandle.
509-func NewExtWorkspaceHandle(ctx *wl.Context) *ExtWorkspaceHandle {
510- obj := &ExtWorkspaceHandle{}
511- obj.SetContext(ctx)
512- ctx.Register(obj)
513- return obj
514-}
515-
516-// Destroys the ext_workspace_handle_v1 object. This request should be made either when the client does not want to use the workspace object any more or after the remove event to finalize the destruction of the object.
517-func (o *ExtWorkspaceHandle) Destroy() error {
518- if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 0, Name: "ext_workspace_handle_v1.destroy", Destructor: true}); err != nil {
519- return err
520- }
521- return nil
522-}
523-
524-// Request that this workspace be activated. There is no guarantee the workspace will be actually activated, and behaviour may be compositor-dependent. For example, activating a workspace may or may not deactivate all other workspaces in the same group.
525-func (o *ExtWorkspaceHandle) Activate() error {
526- if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 1, Name: "ext_workspace_handle_v1.activate"}); err != nil {
527- return err
528- }
529- return nil
530-}
531-
532-// Request that this workspace be deactivated. There is no guarantee the workspace will be actually deactivated.
533-func (o *ExtWorkspaceHandle) Deactivate() error {
534- if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 2, Name: "ext_workspace_handle_v1.deactivate"}); err != nil {
535- return err
536- }
537- return nil
538-}
539-
540-// Requests that this workspace is assigned to the given workspace group. There is no guarantee the workspace will be assigned.
541-func (o *ExtWorkspaceHandle) Assign(workspaceGroup *ExtWorkspaceGroupHandle) error {
542- var arg0 wl.Object
543- if workspaceGroup != nil {
544- arg0 = workspaceGroup
545- }
546- if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 3, Name: "ext_workspace_handle_v1.assign"}, wl.ArgObject(arg0)); err != nil {
547- return err
548- }
549- return nil
550-}
551-
552-// Request that this workspace be removed. There is no guarantee the workspace will be actually removed.
553-func (o *ExtWorkspaceHandle) Remove() error {
554- if err := o.Context().RequestArgs(wl.Request{Proxy: o, Opcode: 4, Name: "ext_workspace_handle_v1.remove"}); err != nil {
555- return err
556- }
557- return nil
558-}
559-
560-// OnId registers a handler for the id event.
561-//
562-// Handlers are appended, so a second call adds another handler rather than
563-// replacing the first. Registration is safe while another goroutine dispatches.
564-func (o *ExtWorkspaceHandle) OnId(handler func(id string)) {
565- if handler == nil {
566- return
567- }
568- o.handlersMu.Lock()
569- defer o.handlersMu.Unlock()
570- o.onId = append(o.onId, handler)
571-}
572-
573-// handlersForId returns the handlers registered for id, taken
574-// under the lock so a handler may register another handler while events are
575-// being dispatched.
576-func (o *ExtWorkspaceHandle) handlersForId() []func(id string) {
577- o.handlersMu.Lock()
578- defer o.handlersMu.Unlock()
579- return o.onId
580-}
581-
582-// OnName registers a handler for the name event.
583-//
584-// Handlers are appended, so a second call adds another handler rather than
585-// replacing the first. Registration is safe while another goroutine dispatches.
586-func (o *ExtWorkspaceHandle) OnName(handler func(name string)) {
587- if handler == nil {
588- return
589- }
590- o.handlersMu.Lock()
591- defer o.handlersMu.Unlock()
592- o.onName = append(o.onName, handler)
593-}
594-
595-// handlersForName returns the handlers registered for name, taken
596-// under the lock so a handler may register another handler while events are
597-// being dispatched.
598-func (o *ExtWorkspaceHandle) handlersForName() []func(name string) {
599- o.handlersMu.Lock()
600- defer o.handlersMu.Unlock()
601- return o.onName
602-}
603-
604-// OnCoordinates registers a handler for the coordinates event.
605-//
606-// Handlers are appended, so a second call adds another handler rather than
607-// replacing the first. Registration is safe while another goroutine dispatches.
608-func (o *ExtWorkspaceHandle) OnCoordinates(handler func(coordinates []byte)) {
609- if handler == nil {
610- return
611- }
612- o.handlersMu.Lock()
613- defer o.handlersMu.Unlock()
614- o.onCoordinates = append(o.onCoordinates, handler)
615-}
616-
617-// handlersForCoordinates returns the handlers registered for coordinates, taken
618-// under the lock so a handler may register another handler while events are
619-// being dispatched.
620-func (o *ExtWorkspaceHandle) handlersForCoordinates() []func(coordinates []byte) {
621- o.handlersMu.Lock()
622- defer o.handlersMu.Unlock()
623- return o.onCoordinates
624-}
625-
626-// OnState registers a handler for the state event.
627-//
628-// Handlers are appended, so a second call adds another handler rather than
629-// replacing the first. Registration is safe while another goroutine dispatches.
630-func (o *ExtWorkspaceHandle) OnState(handler func(state uint32)) {
631- if handler == nil {
632- return
633- }
634- o.handlersMu.Lock()
635- defer o.handlersMu.Unlock()
636- o.onState = append(o.onState, handler)
637-}
638-
639-// handlersForState returns the handlers registered for state, taken
640-// under the lock so a handler may register another handler while events are
641-// being dispatched.
642-func (o *ExtWorkspaceHandle) handlersForState() []func(state uint32) {
643- o.handlersMu.Lock()
644- defer o.handlersMu.Unlock()
645- return o.onState
646-}
647-
648-// OnCapabilities registers a handler for the capabilities event.
649-//
650-// Handlers are appended, so a second call adds another handler rather than
651-// replacing the first. Registration is safe while another goroutine dispatches.
652-func (o *ExtWorkspaceHandle) OnCapabilities(handler func(capabilities uint32)) {
653- if handler == nil {
654- return
655- }
656- o.handlersMu.Lock()
657- defer o.handlersMu.Unlock()
658- o.onCapabilities = append(o.onCapabilities, handler)
659-}
660-
661-// handlersForCapabilities returns the handlers registered for capabilities, taken
662-// under the lock so a handler may register another handler while events are
663-// being dispatched.
664-func (o *ExtWorkspaceHandle) handlersForCapabilities() []func(capabilities uint32) {
665- o.handlersMu.Lock()
666- defer o.handlersMu.Unlock()
667- return o.onCapabilities
668-}
669-
670-// OnRemoved registers a handler for the removed event.
671-//
672-// Handlers are appended, so a second call adds another handler rather than
673-// replacing the first. Registration is safe while another goroutine dispatches.
674-func (o *ExtWorkspaceHandle) OnRemoved(handler func()) {
675- if handler == nil {
676- return
677- }
678- o.handlersMu.Lock()
679- defer o.handlersMu.Unlock()
680- o.onRemoved = append(o.onRemoved, handler)
681-}
682-
683-// handlersForRemoved returns the handlers registered for removed, taken
684-// under the lock so a handler may register another handler while events are
685-// being dispatched.
686-func (o *ExtWorkspaceHandle) handlersForRemoved() []func() {
687- o.handlersMu.Lock()
688- defer o.handlersMu.Unlock()
689- return o.onRemoved
690-}
691-
692-// EventSignature returns the declared event argument types in wire order.
693-func (o *ExtWorkspaceHandle) EventSignature(opcode uint16) (string, bool) {
694- switch opcode {
695- case 0:
696- return "string,", true
697- case 1:
698- return "string,", true
699- case 2:
700- return "array,", true
701- case 3:
702- return "uint,", true
703- case 4:
704- return "uint,", true
705- case 5:
706- return "", true
707- default:
708- return "", false
709- }
710-}
711-
712-// Dispatch decodes one event on ext_workspace_handle_v1 and calls the registered handlers.
713-func (o *ExtWorkspaceHandle) Dispatch(event *wl.Event) {
714- switch event.Opcode {
715- case 0: // id
716- id := event.String()
717-
718- for i, handler := range o.handlersForId() {
719- _ = i
720- handler(id)
721- }
722- case 1: // name
723- name := event.String()
724-
725- for i, handler := range o.handlersForName() {
726- _ = i
727- handler(name)
728- }
729- case 2: // coordinates
730- coordinates := event.Array()
731-
732- for i, handler := range o.handlersForCoordinates() {
733- _ = i
734- handler(coordinates)
735- }
736- case 3: // state
737- state := event.Uint32()
738-
739- for i, handler := range o.handlersForState() {
740- _ = i
741- handler(state)
742- }
743- case 4: // capabilities
744- capabilities := event.Uint32()
745-
746- for i, handler := range o.handlersForCapabilities() {
747- _ = i
748- handler(capabilities)
749- }
750- case 5: // removed
751-
752- for i, handler := range o.handlersForRemoved() {
753- _ = i
754- handler()
755- }
756- default:
757- }
758-}
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
D protocol/xdgdecoration/xdg-decoration-unstable-v1.xml +0 -176 collapsed to keep the page light
D protocol/xdgdecoration/xdg-decoration-unstable-v1_generated.go +0 -195 collapsed to keep the page light
D protocol/xdgoutput/generate.go +0 -3 collapsed to keep the page light
D protocol/xdgoutput/xdg-output-unstable-v1.xml +0 -222 collapsed to keep the page light
D protocol/xdgoutput/xdg-output-unstable-v1_generated.go +0 -290 collapsed to keep the page light
D protocol/xdgshell/xdg-shell.xml +0 -1420 collapsed to keep the page light
D protocol/xdgshell/xdg-shell_generated.go +0 -1043 collapsed to keep the page light
A registry_test.go +117 -0 collapsed to keep the page light

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 8

↑↓ moveenter openesc close